cornflakesuperstar-polymaps 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION.yml +4 -0
- data/lib/country_centers_and_zooms.yml +47 -0
- data/lib/poly_maps.js +191 -0
- data/lib/poly_maps.rb +126 -0
- metadata +58 -0
data/VERSION.yml
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Note: (except for china), the borders polygons are just boxes and not actually accurate ordinates of borders
|
|
2
|
+
"AU":
|
|
3
|
+
google_zoom: 4
|
|
4
|
+
center_latitude: -28.767659
|
|
5
|
+
center_longitude: 133.154297
|
|
6
|
+
borders_polygon: "[[-8.928487062665504, 111.4453125],[-10.487811882056683,158.5546875],[-45.08903556483102,159.08203125],[-43.70759350405294,111.09375]]"
|
|
7
|
+
"CA":
|
|
8
|
+
google_zoom: 3
|
|
9
|
+
center_latitude: 59.355596
|
|
10
|
+
center_longitude: -94.921875
|
|
11
|
+
borders_polygon: "[[38.8225909761771,-151.875],[39.36827914916013,-48.515625],[83.9050579559856,-51.328125],[84.19650681922975,-151.171875]]"
|
|
12
|
+
"CN":
|
|
13
|
+
google_zoom: 4
|
|
14
|
+
center_latitude: 36.385913
|
|
15
|
+
center_longitude: 108.896484
|
|
16
|
+
borders_polygon: "[[56.559482483762245,71.015625],[19.973348786110602,67.1484375],[17.308687886770034,154.3359375],[58.99531118795094,149.4140625]]"
|
|
17
|
+
detailed_borders_polygon: "[[27.32083,88.916929],[27.54243,88.76464],[28.00805,88.83575],[28.1168,88.62435],[27.86605,88.14279],[27.82305,87.19275],[28.11166,86.695269],[27.90888,86.45137],[28.15805,86.19769],[27.88625,86.0054],[28.27916,85.721369],[28.30666,85.11095],[28.59104,85.19518],[28.54444,84.84665],[28.73402,84.48623],[29.26097,84.11651],[29.18902,83.5479],[29.63166,83.19109],[30.06923,82.17525],[30.3344,82.11123],[30.385,81.42623],[30.01194,81.23221],[30.20435,81.02536],[30.57552,80.206999],[30.73374,80.25423],[30.96583,79.86304],[30.95708,79.55429],[31.43729,79.08082],[31.30895,78.76825],[31.96847,78.77075],[32.24304,78.475939],[32.5561,78.40595],[32.63902,78.74623],[32.35083,78.97110],[32.75666,79.52874],[33.09944,79.37511],[33.42863,78.93623],[33.52041,78.813869],[34.06833,78.73581],[34.35001,78.98535],[34.6118,78.33707],[35.28069,78.02305],[35.49902,78.07180],[35.50133,77.82393],[35.6125,76.895259],[35.90665,76.55304],[35.81458,76.18061],[36.07082,75.92887],[36.23751,76.04166],[36.66343,75.85984],[36.73169,75.45179],[36.91156,75.399019],[36.99719,75.14787],[37.02782,74.56543],[37.17,74.39089],[37.23733,74.91574],[37.40659,75.187479],[37.65243,74.9036],[38.47256,74.85442],[38.67438,74.35471],[38.61271,73.81401],[38.88653,73.70818],[38.97256,73.8523],[39.23569,73.62005],[39.45483,73.65569],[39.59965,73.95471],[39.76896,73.8429],[40.04202,73.99096],[40.32792,74.880889],[40.51723,74.8588],[40.45042,75.23394],[40.64452,75.58284],[40.298,75.70374],[40.35324,76.3344],[41.01258,76.87067],[41.04079,78.08083],[41.39286,78.39554],[42.03954,80.24513],[42.19622,80.23402],[42.63245,80.15804],[42.81565,80.25796],[42.88545,80.57226],[43.02906,80.38405],[43.1683,80.81526],[44.1378,80.36887],[44.63580,80.38499],[44.73408,80.51589],[44.90282,79.87106],[45.34970,81.67928],[45.15748,81.94803],[45.13303,82.56638],[45.43581,82.64624],[45.5831,82.32179],[47.20061,83.03443],[46.97332,83.93026],[46.99361,84.67804],[46.8277,84.80318],[47.0591,85.52257],[47.26221,85.70139],[47.93721,85.53707],[48.39333,85.76596],[48.54277,86.59791],[49.1102,86.87602],[49.09262,87.34821],[49.17295,87.8407],[48.98304,87.89291],[48.88103,87.7611],[48.73499,88.05942],[48.56541,87.99194],[48.40582,88.51679],[48.21193,88.61179],[47.99374,89.08514],[47.88791,90.07096],[46.95221,90.91360],[46.57735,91.070269],[46.29694,90.92151],[46.01735,91.02651],[45.57972,90.681929],[45.25305,90.89694],[45.07729,91.56088],[44.95721,93.55470],[44.35499,94.71735],[44.29416,95.41061],[44.019370,95.341089],[43.99311,95.53339],[43.28388,95.879009],[42.73499,96.38206],[42.79583,97.16540],[42.57194,99.51012],[42.67707,100.8425],[42.50972,101.8147],[42.23333,102.0772],[41.88721,103.4164],[41.87721,104.5267],[41.67068,104.5237],[41.58666,105.0065],[42.46624,107.4758],[42.42999,109.3107],[42.64576,110.1064],[43.31694,110.9897],[43.69221,111.9583],[44.37527,111.4214],[45.04944,111.873],[45.08055,112.4272],[44.8461,112.853],[44.74527,113.638],[45.38943,114.5453],[45.4586,115.701],[45.72193,116.2104],[46.29583,116.5855],[46.41888,117.3755],[46.57069,117.425],[46.53645,117.8455],[46.73638,118.3147],[46.59895,119.7068],[46.71513,119.9315],[46.90221,119.9225],[47.66499,119.125],[47.99475,118.5393],[48.01125,117.8046],[47.65741,117.3827],[47.88805,116.8747],[47.87819,116.2624],[47.69186,115.9231],[47.91749,115.5944],[48.14353,115.5491],[48.25249,115.8358],[48.52055,115.8111],[49.83047,116.7114],[49.52058,117.8747],[49.92263,118.5746],[50.09631,119.31],[50.33028,119.36],[50.39027,119.1386],[51.62083,120.0641],[52.115,120.7767],[52.34423,120.6259],[52.54267,120.7122],[52.58805,120.0819],[52.76819,120.0314],[53.26374,120.8307],[53.54361,123.6147],[53.18832,124.4933],[53.05027,125.62],[52.87520,125.6573],[52.75722,126.0968],[52.5761,125.9943],[52.12694,126.555],[51.99437,126.4412],[51.38138,126.9139],[51.26555,126.8176],[51.31923,126.9689],[51.05825,126.9331],[50.74138,127.2919],[50.31472,127.334],[50.20856,127.5861],[49.80588,127.515],[49.58665,127.838],[49.58443,128.7119],[49.34676,129.1118],[49.4158,129.4902],[48.86464,130.2246],[48.86041,130.674],[48.60576,130.5236],[48.3268,130.824],[48.10839,130.6598],[47.68721,130.9922],[47.71027,132.5211],[48.09888,133.0827],[48.06888,133.4843],[48.39112,134.4153],[48.26713,134.7408],[47.99207,134.5576],[47.70027,134.7608],[47.32333,134.1825],[46.64017,133.9977],[46.47888,133.8472],[46.25363,133.9016],[45.8347,133.4761],[45.62458,133.4702],[45.45083,133.1491],[45.05694,133.0253],[45.34582,131.8684],[44.97388,131.4691],[44.83649,130.953],[44.05193,131.298],[43.53624,131.1912],[43.38958,131.3104],[42.91645,131.1285],[42.74485,130.4327],[42.42186,130.6044],[42.71416,130.2468],[42.88794,130.2514],[43.00457,129.9046],[42.43582,129.6955],[42.44624,129.3493],[42.02736,128.9269],[42.00124,128.0566],[41.58284,128.3002],[41.38124,128.1529],[41.47249,127.2708],[41.79222,126.9047],[41.61176,126.5661],[40.89694,126.0118],[40.47037,124.8851],[40.09362,124.3736],[39.82777,124.128],[39.8143,123.2422],[39.67388,123.2167],[38.99638,121.648],[38.8611,121.6982],[38.71909,121.1873],[38.91221,121.0887],[39.09013,121.6794],[39.2186,121.5994],[39.35166,121.7511],[39.52847,121.2283],[39.62322,121.533],[39.81138,121.4683],[40.00305,121.881],[40.50562,122.2987],[40.73874,122.0521],[40.92194,121.1775],[40.1961,120.4468],[39.87242,119.5264],[39.15693,118.9715],[39.04083,118.3273],[39.19846,117.889],[38.67555,117.5364],[38.38666,117.6722],[38.16721,118.0281],[38.1529,118.8378],[37.87832,119.0355],[37.30054,118.9566],[37.14361,119.2328],[37.15138,119.7672],[37.35228,119.8529],[37.83499,120.7371],[37.42458,121.58],[37.55256,122.1282],[37.41833,122.1814],[37.39624,122.5586],[37.20999,122.5972],[37.02583,122.4005],[37.01978,122.5392],[36.89361,122.5047],[36.84298,122.1923],[37.00027,121.9566],[36.75889,121.5944],[36.61666,120.7764],[36.52638,120.96],[36.37582,120.8753],[36.42277,120.7062],[36.0419,120.3436],[36.26345,120.3078],[36.19998,120.0889],[35.95943,120.2378],[35.57893,119.6475],[34.88499,119.1761],[34.31145,120.2487],[32.97499,120.8858],[32.63889,120.8375],[32.42958,121.3348],[32.11333,121.4412],[32.02166,121.7066],[31.67833,121.8275],[31.86639,120.9444],[32.09361,120.6019],[31.94555,120.099],[32.30638,119.8267],[32.26277,119.6317],[31.90388,120.1364],[31.98833,120.7026],[31.81944,120.7196],[31.30889,121.6681],[30.97986,121.8828],[30.85305,121.8469],[30.56889,120.9915],[30.33555,120.8144],[30.39298,120.4586],[30.19694,120.15],[30.31027,120.5082],[30.06465,120.7916],[30.30458,121.2808],[29.96305,121.6778],[29.88211,122.1196],[29.51167,121.4483],[29.58916,121.9744],[29.19527,121.9336],[29.18388,121.8119],[29.37236,121.7969],[29.19729,121.7444],[29.29111,121.5611],[29.1634,121.4135],[29.02194,121.6914],[28.9359,121.4908],[28.72798,121.6113],[28.84215,121.1464],[28.66993,121.4844],[28.34722,121.6417],[28.13889,121.3419],[28.38277,121.1651],[27.98222,120.9353],[28.07944,120.5908],[27.87229,120.84],[27.59319,120.5812],[27.45083,120.6655],[27.20777,120.5075],[27.28278,120.1896],[27.14764,120.4211],[26.89805,120.0332],[26.64465,120.128],[26.51778,119.8603],[26.78823,120.0733],[26.64888,119.8668],[26.79611,119.7879],[26.75625,119.5503],[26.44222,119.8204],[26.47388,119.5775],[26.33861,119.658],[26.36777,119.9489],[25.99694,119.4253],[26.14041,119.0975],[25.93788,119.354],[25.99069,119.7058],[25.67996,119.5807],[25.68222,119.4522],[25.35333,119.6454],[25.60649,119.3149],[25.42097,119.1053],[25.25319,119.3526],[25.17208,119.2726],[25.2426,118.8749],[24.97194,118.9866],[24.88291,118.5729],[24.75673,118.7631],[24.52861,118.5953],[24.53638,118.2397],[24.68194,118.1688],[24.44024,118.0199],[24.46019,117.7947],[24.25875,118.1237],[23.62437,117.1957],[23.65919,116.9179],[23.355,116.7603],[23.42024,116.5322],[23.23666,116.7871],[23.21083,116.5139],[22.93902,116.4817],[22.73916,115.7978],[22.88416,115.6403],[22.65889,115.567],[22.80833,115.1614],[22.70277,114.8889],[22.53305,114.8722],[22.64027,114.718],[22.81402,114.7782],[22.69972,114.5208],[22.50423,114.6136],[22.55004,114.2223],[22.42993,114.3885],[22.26056,114.2961],[22.36736,113.9056],[22.50874,114.0337],[22.47444,113.8608],[22.83458,113.606],[23.05027,113.5253],[23.11724,113.8219],[23.05083,113.4793],[22.87986,113.3629],[22.54944,113.5648],[22.18701,113.5527],[22.56701,113.1687],[22.17965,113.3868],[22.04069,113.2226],[22.20485,113.0848],[21.8693,112.94],[21.96472,112.824],[21.70139,112.2819],[21.91611,111.8921],[21.75139,111.9669],[21.77819,111.6762],[21.61264,111.7832],[21.5268,111.644],[21.52528,111.0285],[21.21138,110.5328],[21.37322,110.3944],[20.84381,110.1594],[20.84083,110.3755],[20.64,110.3239],[20.48618,110.5274],[20.24611,110.2789],[20.2336,109.9244],[20.4318,110.0069],[20.92416,109.6629],[21.44694,109.9411],[21.50569,109.6605],[21.72333,109.5733],[21.49499,109.5344],[21.39666,109.1428],[21.58305,109.1375],[21.61611,108.911],[21.79889,108.8702],[21.59888,108.7403],[21.93562,108.4692],[21.59014,108.5125],[21.68999,108.3336],[21.51444,108.2447],[21.54241,107.99],[21.66694,107.7831],[21.60526,107.3627],[22.03083,106.6933],[22.45682,106.5517],[22.76389,106.7875],[22.86694,106.7029],[22.91253,105.8771],[23.32416,105.3587],[23.18027,104.9075],[22.81805,104.7319],[22.6875,104.3747],[22.79812,104.1113],[22.50387,103.9687],[22.78287,103.6538],[22.58436,103.5224],[22.79451,103.3337],[22.43652,103.0304],[22.77187,102.4744],[22.49777,101.7415],[22.20916,101.5744],[21.83444,101.7653],[21.14451,101.786],[21.17687,101.2919],[21.57264,101.1482],[21.76903,101.099],[21.47694,100.6397],[21.43546,100.2057],[21.72555,99.97763],[22.05018,99.95741],[22.15592,99.16785],[22.93659,99.56484],[23.08204,99.51130],[23.18916,98.92747],[23.97076,98.67991],[24.16007,98.89073],[23.92999,97.54762],[24.26055,97.7593],[24.47666,97.543049],[24.73992,97.55255],[25.61527,98.19109],[25.85597,98.71040],[26.12527,98.56944],[26.18472,98.73109],[26.79166,98.77777],[27.52972,98.69699],[27.6725,98.45888],[27.54014,98.31992],[28.14889,98.14499],[28.54652,97.55887],[28.22277,97.34888],[28.46749,96.65387],[28.35111,96.401929],[28.525,96.34027],[28.79569,96.61373],[29.05666,96.47083],[28.90138,96.17532],[29.05972,96.14888],[29.25757,96.39172],[29.46444,96.08315],[29.03527,95.3877],[29.33346,94.64751],[29.07348,94.23456],[28.6692,93.96172],[28.61876,93.35194],[28.3193,93.22205],[28.1419,92.71044],[27.86194,92.54498],[27.76472,91.65776],[27.945,91.66277],[28.08111,91.30138],[27.96999,91.08693],[28.07958,90.376499],[28.24257,90.38898],[28.32369,89.998189],[28.05777,89.48749],[27.32083,88.916929]]"
|
|
18
|
+
"HK":
|
|
19
|
+
google_zoom: 10
|
|
20
|
+
center_latitude: 22.378015781668722
|
|
21
|
+
center_longitude: 114.15069580078125
|
|
22
|
+
borders_polygon: "[[22.67484735118852,113.77166748046875],[22.057641623615734,113.7744140625],[22.042367498141488,114.49951171875],[22.71032284205226,114.5050048828125]]"
|
|
23
|
+
"IN":
|
|
24
|
+
google_zoom: 4
|
|
25
|
+
center_latitude: 0.79099
|
|
26
|
+
center_longitude: 111.181641
|
|
27
|
+
borders_polygon: "[[-13.06877673435768,142.55859375],[-11.6952727330294,89.296875],[22.917922936146045,87.01171875],[26.27371402440643,141.85546875]]"
|
|
28
|
+
"MY":
|
|
29
|
+
google_zoom: 5
|
|
30
|
+
center_latitude: 4.434044
|
|
31
|
+
center_longitude: 107.578125
|
|
32
|
+
borders_polygon: "[[8.754794702435618,99.140625],[-0.17578097424708533,99.140625],[-0.7031073524364783,121.9921875],[9.535748998133615,121.552734375]]"
|
|
33
|
+
"TW":
|
|
34
|
+
google_zoom: 7
|
|
35
|
+
center_latitude: 23.714954
|
|
36
|
+
center_longitude: 120.849609
|
|
37
|
+
borders_polygon: "[[25.859223554761382,119.3994140625],[21.596150576461437,119.33349609375],[21.391704731036587,122.49755859375],[26.03704188651584,122.58544921875]]"
|
|
38
|
+
"UK":
|
|
39
|
+
google_zoom: 7
|
|
40
|
+
center_latitude: 55.028022
|
|
41
|
+
center_longitude: -3.691406
|
|
42
|
+
borders_polygon: "[[49.468124067331644,2.63671875],[49.55372551347579,-8.96484375],[58.83649009392136,-9.931640625],[64.84893726357947,3.33984375]]"
|
|
43
|
+
"US":
|
|
44
|
+
google_zoom: 4
|
|
45
|
+
center_latitude: 37.0625
|
|
46
|
+
center_longitude: -95.677068
|
|
47
|
+
borders_polygon: "[[72.60712040027555,-173.3203125],[12.211180191503997,-172.6171875],[11.178401873711785,-50.625],[74.01954331150228,-52.3828125]]"
|
data/lib/poly_maps.js
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// http://econym.googlepages.com/inside.htm
|
|
2
|
+
// === A method for testing if a point is inside a polygon
|
|
3
|
+
// === Returns true if poly contains point
|
|
4
|
+
// === Algorithm shamelessly stolen from http://alienryderflex.com/polygon/
|
|
5
|
+
GPolygon.prototype.Contains = function(point) {
|
|
6
|
+
var j=0;
|
|
7
|
+
var oddNodes = false;
|
|
8
|
+
var x = point.lng();
|
|
9
|
+
var y = point.lat();
|
|
10
|
+
for (var i=0; i < this.getVertexCount(); i++) {
|
|
11
|
+
j++;
|
|
12
|
+
if (j == this.getVertexCount()) {j = 0;}
|
|
13
|
+
if (((this.getVertex(i).lat() < y) && (this.getVertex(j).lat() >= y))
|
|
14
|
+
|| ((this.getVertex(j).lat() < y) && (this.getVertex(i).lat() >= y))) {
|
|
15
|
+
if ( this.getVertex(i).lng() + (y - this.getVertex(i).lat())
|
|
16
|
+
/ (this.getVertex(j).lat()-this.getVertex(i).lat())
|
|
17
|
+
* (this.getVertex(j).lng() - this.getVertex(i).lng())<x ) {
|
|
18
|
+
oddNodes = !oddNodes
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return oddNodes;
|
|
23
|
+
}
|
|
24
|
+
// === A method which returns the length of a path in metres ===
|
|
25
|
+
GPolygon.prototype.Distance = function() {
|
|
26
|
+
var dist = 0;
|
|
27
|
+
for (var i=1; i < this.getVertexCount(); i++) {
|
|
28
|
+
dist += this.getVertex(i).distanceFrom(this.getVertex(i-1));
|
|
29
|
+
}
|
|
30
|
+
return dist;
|
|
31
|
+
}
|
|
32
|
+
GPolygon.Shape = function(point,r1,r2,r3,r4,rotation,vertexCount, strokeColour,strokeWeight,Strokepacity,fillColour,fillOpacity,opts,tilt) {
|
|
33
|
+
var rot = -rotation*Math.PI/180;
|
|
34
|
+
var points = [];
|
|
35
|
+
var latConv = point.distanceFrom(new GLatLng(point.lat()+0.1,point.lng()))*10;
|
|
36
|
+
var lngConv = point.distanceFrom(new GLatLng(point.lat(),point.lng()+0.1))*10;
|
|
37
|
+
var step = (360/vertexCount)||10;
|
|
38
|
+
|
|
39
|
+
var flop = -1;
|
|
40
|
+
if (tilt) {
|
|
41
|
+
var I1=180/vertexCount;
|
|
42
|
+
} else {
|
|
43
|
+
var I1=0;
|
|
44
|
+
}
|
|
45
|
+
for(var i=I1; i<=360.001+I1; i+=step) {
|
|
46
|
+
var r1a = flop?r1:r3;
|
|
47
|
+
var r2a = flop?r2:r4;
|
|
48
|
+
flop = -1-flop;
|
|
49
|
+
var y = r1a * Math.cos(i * Math.PI/180);
|
|
50
|
+
var x = r2a * Math.sin(i * Math.PI/180);
|
|
51
|
+
var lng = (x*Math.cos(rot)-y*Math.sin(rot))/lngConv;
|
|
52
|
+
var lat = (y*Math.cos(rot)+x*Math.sin(rot))/latConv;
|
|
53
|
+
|
|
54
|
+
points.push(new GLatLng(point.lat()+lat,point.lng()+lng));
|
|
55
|
+
}
|
|
56
|
+
return (new GPolygon(points,strokeColour,strokeWeight,Strokepacity,fillColour,fillOpacity,opts))
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
GPolygon.Circle = function(point,radius,strokeColour,strokeWeight,Strokepacity,fillColour,fillOpacity,opts) {
|
|
60
|
+
return GPolygon.Shape(point,radius,radius,radius,radius,0,100,strokeColour,strokeWeight,Strokepacity,fillColour,fillOpacity,opts)
|
|
61
|
+
}
|
|
62
|
+
GPolygon.Ellipse = function(point,r1,r2,rotation,strokeColour,strokeWeight,Strokepacity,fillColour,fillOpacity,opts) {
|
|
63
|
+
rotation = rotation||0;
|
|
64
|
+
return GPolygon.Shape(point,r1,r2,r1,r2,rotation,100,strokeColour,strokeWeight,Strokepacity,fillColour,fillOpacity,opts)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
// Copyright 2001, softSurfer (www.softsurfer.com)
|
|
70
|
+
// This code may be freely used and modified for any purpose
|
|
71
|
+
// providing that this copyright notice is included with it.
|
|
72
|
+
// SoftSurfer makes no warranty for this code, and cannot be held
|
|
73
|
+
// liable for any real or imagined damage resulting from its use.
|
|
74
|
+
// Users of this code must verify correctness for their application.
|
|
75
|
+
// http://geometryalgorithms.com/Archive/algorithm_0109/algorithm_0109.htm
|
|
76
|
+
|
|
77
|
+
// Assume that a class is already given for the object:
|
|
78
|
+
// Point with coordinates {float x, y;}
|
|
79
|
+
//===================================================================
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
// isLeft(): tests if a point is Left|On|Right of an infinite line.
|
|
83
|
+
// Input: three points P0, P1, and P2
|
|
84
|
+
// Return: >0 for P2 left of the line through P0 and P1
|
|
85
|
+
// =0 for P2 on the line
|
|
86
|
+
// <0 for P2 right of the line
|
|
87
|
+
// See: the January 2001 Algorithm on Area of Triangles
|
|
88
|
+
function isLeft( P0, P1, P2 )
|
|
89
|
+
{
|
|
90
|
+
return (P1.x - P0.x)*(P2.y - P0.y) - (P2.x - P0.x)*(P1.y - P0.y);
|
|
91
|
+
}
|
|
92
|
+
//===================================================================
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
// chainHull_2D(): Andrew's monotone chain 2D convex hull algorithm
|
|
96
|
+
// Input: P[] = an array of 2D points
|
|
97
|
+
// presorted by increasing x- and y-coordinates
|
|
98
|
+
// n = the number of points in P[]
|
|
99
|
+
// Output: H[] = an array of the convex hull vertices (max is n)
|
|
100
|
+
// Return: the number of points in H[]
|
|
101
|
+
function chainHull_2D( P, n, H )
|
|
102
|
+
{
|
|
103
|
+
// the output array H[] will be used as the stack
|
|
104
|
+
var bot=0, top=(-1); // indices for bottom and top of the stack
|
|
105
|
+
var i; // array scan index
|
|
106
|
+
|
|
107
|
+
// Get the indices of points with min x-coord and min|max y-coord
|
|
108
|
+
var minmin = 0, minmax;
|
|
109
|
+
var xmin = P[0].x;
|
|
110
|
+
for (i=1; i<n; i++)
|
|
111
|
+
if (P[i].x != xmin) break;
|
|
112
|
+
minmax = i-1;
|
|
113
|
+
if (minmax == n-1) { // degenerate case: all x-coords == xmin
|
|
114
|
+
H[++top] = P[minmin];
|
|
115
|
+
if (P[minmax].y != P[minmin].y) // a nontrivial segment
|
|
116
|
+
H[++top] = P[minmax];
|
|
117
|
+
H[++top] = P[minmin]; // add polygon endpoint
|
|
118
|
+
return top+1;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Get the indices of points with max x-coord and min|max y-coord
|
|
122
|
+
var maxmin, maxmax = n-1;
|
|
123
|
+
var xmax = P[n-1].x;
|
|
124
|
+
for (i=n-2; i>=0; i--)
|
|
125
|
+
if (P[i].x != xmax) break;
|
|
126
|
+
maxmin = i+1;
|
|
127
|
+
|
|
128
|
+
// Compute the lower hull on the stack H
|
|
129
|
+
H[++top] = P[minmin]; // push minmin point onto stack
|
|
130
|
+
i = minmax;
|
|
131
|
+
|
|
132
|
+
while (++i <= maxmin)
|
|
133
|
+
{
|
|
134
|
+
// the lower line joins P[minmin] with P[maxmin]
|
|
135
|
+
if (isLeft( P[minmin], P[maxmin], P[i]) >= 0 && i < maxmin)
|
|
136
|
+
continue; // ignore P[i] above or on the lower line
|
|
137
|
+
|
|
138
|
+
while (top > 0) // there are at least 2 points on the stack
|
|
139
|
+
{
|
|
140
|
+
// test if P[i] is left of the line at the stack top
|
|
141
|
+
if (isLeft( H[top-1], H[top], P[i]) > 0)
|
|
142
|
+
break; // P[i] is a new hull vertex
|
|
143
|
+
else
|
|
144
|
+
top--; // pop top point off stack
|
|
145
|
+
}
|
|
146
|
+
H[++top] = P[i]; // push P[i] onto stack
|
|
147
|
+
}
|
|
148
|
+
// Next, compute the upper hull on the stack H above the bottom hull
|
|
149
|
+
if (maxmax != maxmin) // if distinct xmax points
|
|
150
|
+
H[++top] = P[maxmax]; // push maxmax point onto stack
|
|
151
|
+
bot = top; // the bottom point of the upper hull stack
|
|
152
|
+
i = maxmin;
|
|
153
|
+
while (--i >= minmax)
|
|
154
|
+
{
|
|
155
|
+
// the upper line joins P[maxmax] with P[minmax]
|
|
156
|
+
if (isLeft( P[maxmax], P[minmax], P[i]) >= 0 && i > minmax)
|
|
157
|
+
continue; // ignore P[i] below or on the upper line
|
|
158
|
+
|
|
159
|
+
while (top > bot) // at least 2 points on the upper stack
|
|
160
|
+
{
|
|
161
|
+
// test if P[i] is left of the line at the stack top
|
|
162
|
+
if (isLeft( H[top-1], H[top], P[i]) > 0)
|
|
163
|
+
break; // P[i] is a new hull vertex
|
|
164
|
+
else
|
|
165
|
+
top--; // pop top point off stack
|
|
166
|
+
}
|
|
167
|
+
H[++top] = P[i]; // push P[i] onto stack
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (minmax != minmin)
|
|
171
|
+
H[++top] = P[minmin]; // push joining endpoint onto stack
|
|
172
|
+
return top+1;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function sortPointX(a,b) { return a.x - b.x; }
|
|
176
|
+
function sortPointY(a,b) { return a.y - b.y; }
|
|
177
|
+
|
|
178
|
+
function DrawHull(map, points, color) {
|
|
179
|
+
var hullPoints = []
|
|
180
|
+
chainHull_2D( points, points.length, hullPoints );
|
|
181
|
+
var polyline = new GPolygon(hullPoints, color, 2, 0.5, color);
|
|
182
|
+
return polyline;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function calculateConvexHull(map, points, color) {
|
|
186
|
+
points.sort(sortPointY);
|
|
187
|
+
points.sort(sortPointX);
|
|
188
|
+
return DrawHull(map, points, color);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
var mouseover_cursor = function() { this.style.cursor='pointer'; }
|
data/lib/poly_maps.rb
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
module PolyMaps
|
|
2
|
+
|
|
3
|
+
class LegendItem
|
|
4
|
+
attr_accessor :color, :region
|
|
5
|
+
def initialize(color, region)
|
|
6
|
+
@color = color
|
|
7
|
+
@region = region
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class Renderer
|
|
12
|
+
|
|
13
|
+
def js
|
|
14
|
+
@map_js
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def legend_items
|
|
18
|
+
@legend_items
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def library_js
|
|
22
|
+
# Write the neccessary JavaScript library stuff for circles etc.
|
|
23
|
+
IO.read(File.join(File.dirname(__FILE__), '/poly_maps.js'))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def initialize(country_code, regions, relationship_name, onclick_handler, polygon_limit = nil)
|
|
27
|
+
unless (country = YAML.load_file(File.join(File.dirname(__FILE__), '/country_centers_and_zooms.yml'))[country_code])
|
|
28
|
+
puts "Polymaps Unsupported country code: #{country_code}"
|
|
29
|
+
return nil
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
output = ""
|
|
33
|
+
country_zoom = country['google_zoom']
|
|
34
|
+
@legend_items = []
|
|
35
|
+
|
|
36
|
+
# Create a country polygon to check that drawn points are not incorrectly geocoded
|
|
37
|
+
output += "var country_points = #{country['borders_polygon']};\n"
|
|
38
|
+
output += "var pts = [];\n"
|
|
39
|
+
output += "for (var i = 0; i < country_points.length; i++) {\n"
|
|
40
|
+
output += " pts[i] = new GLatLng(country_points[i][0],country_points[i][1]);\n"
|
|
41
|
+
output += "}\n"
|
|
42
|
+
output += "var country_polygon = new GPolygon(pts,\"#000000\",1,1,\"#{country['fill_color']}\",0.5,{clickable:false});\n"
|
|
43
|
+
output += "var country_zoom = #{country_zoom};\n"
|
|
44
|
+
output += "map.setCenter(new GLatLng(#{country['center_latitude']}, #{country['center_longitude']}), country_zoom);\n"
|
|
45
|
+
if country_zoom < 4
|
|
46
|
+
output += "var min_area_sqm = 2000000000;\n"
|
|
47
|
+
output += "var circle_radius = 110000;\n"
|
|
48
|
+
elsif country_zoom < 6
|
|
49
|
+
output += "var min_area_sqm = 1500000000;\n"
|
|
50
|
+
output += "var circle_radius = 50000;\n"
|
|
51
|
+
elsif country_zoom < 9
|
|
52
|
+
output += "var min_area_sqm = 250000000;\n"
|
|
53
|
+
output += "var circle_radius = 7000;\n"
|
|
54
|
+
else
|
|
55
|
+
output += "var min_area_sqm = 1500000;\n"
|
|
56
|
+
output += "var circle_radius = 3000;\n"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Create an array with point locations for all regions
|
|
60
|
+
output += "var regions = ["
|
|
61
|
+
region_js = []
|
|
62
|
+
regions.each_with_index do |region, index|
|
|
63
|
+
points = eval("region.#{relationship_name}")
|
|
64
|
+
next if points.empty?
|
|
65
|
+
@legend_items << LegendItem.new(nil, region)
|
|
66
|
+
next if polygon_limit and index >= polygon_limit
|
|
67
|
+
points_js = []
|
|
68
|
+
points.each do |point|
|
|
69
|
+
points_js << "[#{point.lat},#{point.lng}]"
|
|
70
|
+
end
|
|
71
|
+
onclick = "null"
|
|
72
|
+
unless onclick_handler.nil? or onclick_handler == ""
|
|
73
|
+
js = eval("\"#{onclick_handler}\"")
|
|
74
|
+
onclick = "function() { #{js}; }"
|
|
75
|
+
end
|
|
76
|
+
region_js[region_js.length] = "[#{onclick},[#{points_js.join(',')}]]"
|
|
77
|
+
end
|
|
78
|
+
output += region_js.join(",")
|
|
79
|
+
output += "];\n"
|
|
80
|
+
|
|
81
|
+
# Save the colors used
|
|
82
|
+
hex_colors = ['#3399cc','#669900','#9966cc','#ff3300','#ff00ff','#ff9900','#cc99cc','#ffff00']
|
|
83
|
+
color_index = 0
|
|
84
|
+
@legend_items.each_with_index do |legend_item, index|
|
|
85
|
+
legend_item.color = (polygon_limit and index >= polygon_limit)? "" : hex_colors[color_index]
|
|
86
|
+
color_index = (color_index == hex_colors.length-1)? 0 : color_index + 1
|
|
87
|
+
end
|
|
88
|
+
hex_colors_js = hex_colors.collect{|c| "'#{c}'"}.join(',')
|
|
89
|
+
|
|
90
|
+
# Use JavaScript to loop through each region and add a polygon to the map
|
|
91
|
+
output += "var hex_colors = [#{hex_colors_js}];\n"
|
|
92
|
+
output += "var color_index = 0;\n"
|
|
93
|
+
output += "for(var i = 0; i < regions.length; i++) {\n"
|
|
94
|
+
output += " region = regions[i];\n"
|
|
95
|
+
output += " hex_color = hex_colors[color_index]\n"
|
|
96
|
+
output += " color_index = (color_index == hex_colors.length-1)? 0 : color_index + 1;\n"
|
|
97
|
+
output += " var polygon = null;\n"
|
|
98
|
+
output += " var region_bounds = new GLatLngBounds();\n"
|
|
99
|
+
output += " var points_js = region[1];\n"
|
|
100
|
+
output += " var pts = [];\n"
|
|
101
|
+
output += " for (var j = 0; j < points_js.length; j++) {\n"
|
|
102
|
+
output += " lat_lng = new GLatLng(points_js[j][0],points_js[j][1]);\n"
|
|
103
|
+
output += " if (country_polygon.Contains(lat_lng)) {\n"
|
|
104
|
+
output += " pts[pts.length] = lat_lng;\n"
|
|
105
|
+
output += " region_bounds.extend(lat_lng);\n"
|
|
106
|
+
output += " }\n"
|
|
107
|
+
output += " }\n"
|
|
108
|
+
output += " var region_polygon = new GPolygon(pts,hex_color,1,1,hex_color,0.5);\n"
|
|
109
|
+
output += " if (region_polygon.getArea() < min_area_sqm) {\n"
|
|
110
|
+
output += " polygon = GPolygon.Circle(region_bounds.getCenter(), circle_radius, hex_color, 1, 1, hex_color, 0.5);\n"
|
|
111
|
+
output += " } else {\n"
|
|
112
|
+
output += " polygon = calculateConvexHull(map, pts, hex_color);\n"
|
|
113
|
+
output += " }\n"
|
|
114
|
+
output += " GEvent.addListener(polygon, 'mouseover', mouseover_cursor);\n"
|
|
115
|
+
output += " if (region[0] != null) {\n"
|
|
116
|
+
output += " GEvent.addListener(polygon, 'click', region[0]);\n"
|
|
117
|
+
output += " }\n"
|
|
118
|
+
output += " map.addOverlay(polygon);\n"
|
|
119
|
+
output += "}\n"
|
|
120
|
+
|
|
121
|
+
@map_js = output
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: cornflakesuperstar-polymaps
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- cornflakesuperstar
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2009-02-27 00:00:00 -08:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies: []
|
|
15
|
+
|
|
16
|
+
description: TODO
|
|
17
|
+
email: cornflakesuperstar@hotmail.com
|
|
18
|
+
executables: []
|
|
19
|
+
|
|
20
|
+
extensions: []
|
|
21
|
+
|
|
22
|
+
extra_rdoc_files: []
|
|
23
|
+
|
|
24
|
+
files:
|
|
25
|
+
- VERSION.yml
|
|
26
|
+
- lib/poly_maps.rb
|
|
27
|
+
- lib/poly_maps.js
|
|
28
|
+
- lib/country_centers_and_zooms.yml
|
|
29
|
+
- test/poly_maps_test.rb
|
|
30
|
+
has_rdoc: true
|
|
31
|
+
homepage: http://github.com/cornflakesuperstar/polymaps
|
|
32
|
+
post_install_message:
|
|
33
|
+
rdoc_options:
|
|
34
|
+
- --inline-source
|
|
35
|
+
- --charset=UTF-8
|
|
36
|
+
require_paths:
|
|
37
|
+
- lib
|
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: "0"
|
|
43
|
+
version:
|
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: "0"
|
|
49
|
+
version:
|
|
50
|
+
requirements: []
|
|
51
|
+
|
|
52
|
+
rubyforge_project:
|
|
53
|
+
rubygems_version: 1.2.0
|
|
54
|
+
signing_key:
|
|
55
|
+
specification_version: 2
|
|
56
|
+
summary: Polymaps lets you overlay clickable polygons on top of a google map with your specified geo-coded regions
|
|
57
|
+
test_files: []
|
|
58
|
+
|