├── .gitignore
├── LICENSE
├── README.md
├── example
├── custom.geo.json
├── index.html
├── lambert.html
├── lib
│ ├── proj4js-compressed.js
│ └── proj4leaflet.js
└── mollweide.html
└── leaflet.latlng-graticule.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.pyc
3 |
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) JS Foundation and other contributors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | leaflet.latlng-graticule
2 | ===========================
3 |
4 | Create a Canvas as ImageOverlay to draw the Lat/Lon Graticule,
5 |
6 | and show the grid tick label at the edges of the map.
7 |
8 | Check out the [demo](https://cloudybay.github.io/leaflet.latlng-graticule/example/).
9 |
10 |
11 | ### Usage example
12 |
13 | ```javascript
14 | L.latlngGraticule({
15 | showLabel: true,
16 | dashArray: [5, 5],
17 | zoomInterval: [
18 | {start: 2, end: 3, interval: 30},
19 | {start: 4, end: 4, interval: 10},
20 | {start: 5, end: 7, interval: 5},
21 | {start: 8, end: 10, interval: 1}
22 | ]
23 | }).addTo(map);
24 | ```
25 |
26 |
27 | ### Options
28 | - **showLabel**: Show the grid tick label at the edges of the map. Default `true`
29 | - **opacity**: Opacity of the Graticule and Label. Default `1`
30 | - **weight**: The width of the graticule lines. Default `0.8`
31 | - **color**: The color of the graticule lines. Default `#aaa`
32 | - **font**: Font Style for the tick label. Default `12px Verdana`
33 | - **fontColor**: Color of the tick label. Default `#aaa`
34 | - **dashArray**: Used to achieve dashed lines. Default `[0,0]`
35 | - **sides**: Used to name sides of the world. Default `['N', 'S', 'E', 'W']`
36 | - **zoomInterval**: Use different intervals in different zoom levels. You can set for both latitude and longitude lines as the example, or set different intervals for latitude and longitude like below:
37 | ```javascript
38 | zoomInterval: {
39 | latitude: [
40 | {start: 4, end: 6, interval: 5},
41 | {start: 7, end: 20, interval: 1}
42 | ],
43 | longitude: [
44 | {start: 4, end: 6, interval: 10},
45 | {start: 7, end: 20, interval: 2}
46 | ]
47 | }
48 | ```
49 | - ***Default***:
50 | ```javascript
51 | zoomInterval: [
52 | {start: 2, end: 2, interval: 40},
53 | {start: 3, end: 3, interval: 20},
54 | {start: 4, end: 4, interval: 10},
55 | {start: 5, end: 7, interval: 5},
56 | {start: 8, end: 20, interval: 1}
57 | ]
58 | ```
59 |
60 | #### Special Options
61 | Some of the projections (like Lambert) is no straight line, set those options to draw a polyline graticule.
62 | - **lngLineCurved**: Interval of polyline. Deafult `0`
63 | - **latLineCurved**: Interval of polyline. Deafult `0`
64 |
65 | Check out the [Lambert projection example](https://cloudybay.github.io/leaflet.latlng-graticule/example/lambert.html).
66 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Leaflet Lat/Lon Graticule Demo
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/example/lambert.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Leaflet Graticule
6 |
7 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
73 |
74 |
--------------------------------------------------------------------------------
/example/lib/proj4js-compressed.js:
--------------------------------------------------------------------------------
1 | /*
2 | proj4js.js -- Javascript reprojection library.
3 |
4 | Authors: Mike Adair madairATdmsolutions.ca
5 | Richard Greenwood richATgreenwoodmap.com
6 | Didier Richard didier.richardATign.fr
7 | Stephen Irons stephen.ironsATclear.net.nz
8 | Olivier Terral oterralATgmail.com
9 |
10 | License:
11 | Copyright (c) 2012, Mike Adair, Richard Greenwood, Didier Richard,
12 | Stephen Irons and Olivier Terral
13 |
14 | Permission is hereby granted, free of charge, to any person obtaining a
15 | copy of this software and associated documentation files (the "Software"),
16 | to deal in the Software without restriction, including without limitation
17 | the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 | and/or sell copies of the Software, and to permit persons to whom the
19 | Software is furnished to do so, subject to the following conditions:
20 |
21 | The above copyright notice and this permission notice shall be included
22 | in all copies or substantial portions of the Software.
23 |
24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 | DEALINGS IN THE SOFTWARE.
31 |
32 | Note: This program is an almost direct port of the C library PROJ.4.
33 | */
34 | var Proj4js={defaultDatum:"WGS84",transform:function(a,c,b){if(!a.readyToUse)return this.reportError("Proj4js initialization for:"+a.srsCode+" not yet complete"),b;if(!c.readyToUse)return this.reportError("Proj4js initialization for:"+c.srsCode+" not yet complete"),b;if(a.datum&&c.datum&&((a.datum.datum_type==Proj4js.common.PJD_3PARAM||a.datum.datum_type==Proj4js.common.PJD_7PARAM)&&"WGS84"!=c.datumCode||(c.datum.datum_type==Proj4js.common.PJD_3PARAM||c.datum.datum_type==Proj4js.common.PJD_7PARAM)&&
35 | "WGS84"!=a.datumCode)){var d=Proj4js.WGS84;this.transform(a,d,b);a=d}"enu"!=a.axis&&this.adjust_axis(a,!1,b);"longlat"==a.projName?(b.x*=Proj4js.common.D2R,b.y*=Proj4js.common.D2R):(a.to_meter&&(b.x*=a.to_meter,b.y*=a.to_meter),a.inverse(b));a.from_greenwich&&(b.x+=a.from_greenwich);b=this.datum_transform(a.datum,c.datum,b);c.from_greenwich&&(b.x-=c.from_greenwich);"longlat"==c.projName?(b.x*=Proj4js.common.R2D,b.y*=Proj4js.common.R2D):(c.forward(b),c.to_meter&&(b.x/=c.to_meter,b.y/=c.to_meter));
36 | "enu"!=c.axis&&this.adjust_axis(c,!0,b);return b},datum_transform:function(a,c,b){if(a.compare_datums(c)||a.datum_type==Proj4js.common.PJD_NODATUM||c.datum_type==Proj4js.common.PJD_NODATUM)return b;if(a.es!=c.es||a.a!=c.a||a.datum_type==Proj4js.common.PJD_3PARAM||a.datum_type==Proj4js.common.PJD_7PARAM||c.datum_type==Proj4js.common.PJD_3PARAM||c.datum_type==Proj4js.common.PJD_7PARAM)a.geodetic_to_geocentric(b),(a.datum_type==Proj4js.common.PJD_3PARAM||a.datum_type==Proj4js.common.PJD_7PARAM)&&a.geocentric_to_wgs84(b),
37 | (c.datum_type==Proj4js.common.PJD_3PARAM||c.datum_type==Proj4js.common.PJD_7PARAM)&&c.geocentric_from_wgs84(b),c.geocentric_to_geodetic(b);return b},adjust_axis:function(a,c,b){for(var d=b.x,e=b.y,f=b.z||0,g,i,h=0;3>h;h++)if(!c||!(2==h&&void 0===b.z))switch(0==h?(g=d,i="x"):1==h?(g=e,i="y"):(g=f,i="z"),a.axis[h]){case "e":b[i]=g;break;case "w":b[i]=-g;break;case "n":b[i]=g;break;case "s":b[i]=-g;break;case "u":void 0!==b[i]&&(b.z=g);break;case "d":void 0!==b[i]&&(b.z=-g);break;default:return alert("ERROR: unknow axis ("+
38 | a.axis[h]+") - check definition of "+a.projName),null}return b},reportError:function(){},extend:function(a,c){a=a||{};if(c)for(var b in c){var d=c[b];void 0!==d&&(a[b]=d)}return a},Class:function(){for(var a=function(){this.initialize.apply(this,arguments)},c={},b,d=0;d=f;f++)if(d=a*Math.sin(e),d=this.HALF_PI-2*Math.atan(c*Math.pow((1-d)/(1+d),b))-e,e+=d,1.0E-10>=Math.abs(d))return e;alert("phi2z has NoConvergence");return-9999},qsfnz:function(a,c){var b;return 1.0E-7a?-1:1},adjust_lon:function(a){return a=Math.abs(a)this.HALF_PI)return+Number.NaN;if(c==this.HALF_PI)return Number.POSITIVE_INFINITY;if(c==-1*this.HALF_PI)return-1*Number.POSITIVE_INFINITY;b*=a;return Math.log(Math.tan((this.HALF_PI+c)/2))+a*Math.log((1-b)/(1+b))/2},fL:function(a,c){return 2*Math.atan(a*Math.exp(c))-this.HALF_PI},invlatiso:function(a,c){var b=this.fL(1,c),d=0,e=0;do d=b,e=a*Math.sin(d),b=this.fL(Math.exp(a*Math.log((1+e)/(1-e))/2),c);while(1.0E-12<
62 | Math.abs(b-d));return b},sinh:function(a){a=Math.exp(a);return(a-1/a)/2},cosh:function(a){a=Math.exp(a);return(a+1/a)/2},tanh:function(a){a=Math.exp(a);return(a-1/a)/(a+1/a)},asinh:function(a){return(0<=a?1:-1)*Math.log(Math.abs(a)+Math.sqrt(a*a+1))},acosh:function(a){return 2*Math.log(Math.sqrt((a+1)/2)+Math.sqrt((a-1)/2))},atanh:function(a){return Math.log((a-1)/(a+1))/2},gN:function(a,c,b){c*=b;return a/Math.sqrt(1-c*c)},pj_enfn:function(a){var c=[];c[0]=this.C00-a*(this.C02+a*(this.C04+a*(this.C06+
63 | a*this.C08)));c[1]=a*(this.C22-a*(this.C04+a*(this.C06+a*this.C08)));var b=a*a;c[2]=b*(this.C44-a*(this.C46+a*this.C48));b*=a;c[3]=b*(this.C66-a*this.C68);c[4]=b*a*this.C88;return c},pj_mlfn:function(a,c,b,d){b*=c;c*=c;return d[0]*a-b*(d[1]+c*(d[2]+c*(d[3]+c*d[4])))},pj_inv_mlfn:function(a,c,b){for(var d=1/(1-c),e=a,f=Proj4js.common.MAX_ITER;f;--f){var g=Math.sin(e),i=1-c*g*g,i=(this.pj_mlfn(e,g,Math.cos(e),b)-a)*i*Math.sqrt(i)*d,e=e-i;if(Math.abs(i)-1.001*Proj4js.common.HALF_PI)b=-Proj4js.common.HALF_PI;else if(b>Proj4js.common.HALF_PI&&b<1.001*Proj4js.common.HALF_PI)b=Proj4js.common.HALF_PI;else if(b<-Proj4js.common.HALF_PI||b>Proj4js.common.HALF_PI)return Proj4js.reportError("geocent:lat out of range:"+b),null;c>Proj4js.common.PI&&(c-=2*Proj4js.common.PI);f=Math.sin(b);g=Math.cos(b);e=this.a/Math.sqrt(1-this.es*f*f);b=(e+d)*g*Math.cos(c);
69 | c=(e+d)*g*Math.sin(c);d=(e*(1-this.es)+d)*f;a.x=b;a.y=c;a.z=d;return 0},geocentric_to_geodetic:function(a){var c,b,d,e,f,g,i,h,j,k,l=a.x;d=a.y;var m=a.z?a.z:0;c=Math.sqrt(l*l+d*d);b=Math.sqrt(l*l+d*d+m*m);if(1.0E-12>c/this.a){if(l=0,1.0E-12>b/this.a)return}else l=Math.atan2(d,l);d=m/b;e=c/b;f=1/Math.sqrt(1-this.es*(2-this.es)*e*e);i=e*(1-this.es)*f;h=d*f;k=0;do k++,g=this.a/Math.sqrt(1-this.es*h*h),b=c*i+m*h-g*(1-this.es*h*h),g=this.es*g/(g+b),f=1/Math.sqrt(1-g*(2-g)*e*e),g=e*(1-g)*f,f*=d,j=f*i-g*
70 | h,i=g,h=f;while(1.0E-24k);c=Math.atan(f/Math.abs(g));a.x=l;a.y=c;a.z=b;return a},geocentric_to_geodetic_noniter:function(a){var c=a.x,b=a.y,d=a.z?a.z:0,e,f,g,i,h,c=parseFloat(c),b=parseFloat(b),d=parseFloat(d);h=!1;if(0!=c)e=Math.atan2(b,c);else if(0b)e=-Proj4js.common.HALF_PI;else if(h=!0,e=0,0d)f=-Proj4js.common.HALF_PI;else return;g=c*c+b*b;c=Math.sqrt(g);b=d*Proj4js.common.AD_C;g=Math.sqrt(b*b+g);b/=g;g=c/g;b=
71 | d+this.b*this.ep2*b*b*b;i=c-this.a*this.es*g*g*g;g=Math.sqrt(b*b+i*i);b/=g;g=i/g;i=this.a/Math.sqrt(1-this.es*b*b);d=g>=Proj4js.common.COS_67P5?c/g-i:g<=-Proj4js.common.COS_67P5?c/-g-i:d/b+i*(this.es-1);!1==h&&(f=Math.atan(b/g));a.x=e;a.y=f;a.z=d;return a},geocentric_to_wgs84:function(a){if(this.datum_type==Proj4js.common.PJD_3PARAM)a.x+=this.datum_params[0],a.y+=this.datum_params[1],a.z+=this.datum_params[2];else if(this.datum_type==Proj4js.common.PJD_7PARAM){var c=this.datum_params[3],b=this.datum_params[4],
72 | d=this.datum_params[5],e=this.datum_params[6],f=e*(d*a.x+a.y-c*a.z)+this.datum_params[1],c=e*(-b*a.x+c*a.y+a.z)+this.datum_params[2];a.x=e*(a.x-d*a.y+b*a.z)+this.datum_params[0];a.y=f;a.z=c}},geocentric_from_wgs84:function(a){if(this.datum_type==Proj4js.common.PJD_3PARAM)a.x-=this.datum_params[0],a.y-=this.datum_params[1],a.z-=this.datum_params[2];else if(this.datum_type==Proj4js.common.PJD_7PARAM){var c=this.datum_params[3],b=this.datum_params[4],d=this.datum_params[5],e=this.datum_params[6],f=(a.x-
73 | this.datum_params[0])/e,g=(a.y-this.datum_params[1])/e,e=(a.z-this.datum_params[2])/e;a.x=f+d*g-b*e;a.y=-d*f+g+c*e;a.z=b*f-c*g+e}}});
74 | Proj4js.Point=Proj4js.Class({initialize:function(a,c,b){"object"==typeof a?(this.x=a[0],this.y=a[1],this.z=a[2]||0):"string"==typeof a&&"undefined"==typeof c?(a=a.split(","),this.x=parseFloat(a[0]),this.y=parseFloat(a[1]),this.z=parseFloat(a[2])||0):(this.x=a,this.y=c,this.z=b||0)},clone:function(){return new Proj4js.Point(this.x,this.y,this.z)},toString:function(){return"x="+this.x+",y="+this.y},toShortString:function(){return this.x+", "+this.y}});
75 | Proj4js.PrimeMeridian={greenwich:0,lisbon:-9.131906111111,paris:2.337229166667,bogota:-74.080916666667,madrid:-3.687938888889,rome:12.452333333333,bern:7.439583333333,jakarta:106.807719444444,ferro:-17.666666666667,brussels:4.367975,stockholm:18.058277777778,athens:23.7163375,oslo:10.722916666667};
76 | Proj4js.Ellipsoid={MERIT:{a:6378137,rf:298.257,ellipseName:"MERIT 1983"},SGS85:{a:6378136,rf:298.257,ellipseName:"Soviet Geodetic System 85"},GRS80:{a:6378137,rf:298.257222101,ellipseName:"GRS 1980(IUGG, 1980)"},IAU76:{a:6378140,rf:298.257,ellipseName:"IAU 1976"},airy:{a:6377563.396,b:6356256.91,ellipseName:"Airy 1830"},"APL4.":{a:6378137,rf:298.25,ellipseName:"Appl. Physics. 1965"},NWL9D:{a:6378145,rf:298.25,ellipseName:"Naval Weapons Lab., 1965"},mod_airy:{a:6377340.189,b:6356034.446,ellipseName:"Modified Airy"},
77 | andrae:{a:6377104.43,rf:300,ellipseName:"Andrae 1876 (Den., Iclnd.)"},aust_SA:{a:6378160,rf:298.25,ellipseName:"Australian Natl & S. Amer. 1969"},GRS67:{a:6378160,rf:298.247167427,ellipseName:"GRS 67(IUGG 1967)"},bessel:{a:6377397.155,rf:299.1528128,ellipseName:"Bessel 1841"},bess_nam:{a:6377483.865,rf:299.1528128,ellipseName:"Bessel 1841 (Namibia)"},clrk66:{a:6378206.4,b:6356583.8,ellipseName:"Clarke 1866"},clrk80:{a:6378249.145,rf:293.4663,ellipseName:"Clarke 1880 mod."},CPM:{a:6375738.7,rf:334.29,
78 | ellipseName:"Comm. des Poids et Mesures 1799"},delmbr:{a:6376428,rf:311.5,ellipseName:"Delambre 1810 (Belgium)"},engelis:{a:6378136.05,rf:298.2566,ellipseName:"Engelis 1985"},evrst30:{a:6377276.345,rf:300.8017,ellipseName:"Everest 1830"},evrst48:{a:6377304.063,rf:300.8017,ellipseName:"Everest 1948"},evrst56:{a:6377301.243,rf:300.8017,ellipseName:"Everest 1956"},evrst69:{a:6377295.664,rf:300.8017,ellipseName:"Everest 1969"},evrstSS:{a:6377298.556,rf:300.8017,ellipseName:"Everest (Sabah & Sarawak)"},
79 | fschr60:{a:6378166,rf:298.3,ellipseName:"Fischer (Mercury Datum) 1960"},fschr60m:{a:6378155,rf:298.3,ellipseName:"Fischer 1960"},fschr68:{a:6378150,rf:298.3,ellipseName:"Fischer 1968"},helmert:{a:6378200,rf:298.3,ellipseName:"Helmert 1906"},hough:{a:6378270,rf:297,ellipseName:"Hough"},intl:{a:6378388,rf:297,ellipseName:"International 1909 (Hayford)"},kaula:{a:6378163,rf:298.24,ellipseName:"Kaula 1961"},lerch:{a:6378139,rf:298.257,ellipseName:"Lerch 1979"},mprts:{a:6397300,rf:191,ellipseName:"Maupertius 1738"},
80 | new_intl:{a:6378157.5,b:6356772.2,ellipseName:"New International 1967"},plessis:{a:6376523,rf:6355863,ellipseName:"Plessis 1817 (France)"},krass:{a:6378245,rf:298.3,ellipseName:"Krassovsky, 1942"},SEasia:{a:6378155,b:6356773.3205,ellipseName:"Southeast Asia"},walbeck:{a:6376896,b:6355834.8467,ellipseName:"Walbeck"},WGS60:{a:6378165,rf:298.3,ellipseName:"WGS 60"},WGS66:{a:6378145,rf:298.25,ellipseName:"WGS 66"},WGS72:{a:6378135,rf:298.26,ellipseName:"WGS 72"},WGS84:{a:6378137,rf:298.257223563,ellipseName:"WGS 84"},
81 | sphere:{a:6370997,b:6370997,ellipseName:"Normal Sphere (r=6370997)"}};
82 | Proj4js.Datum={WGS84:{towgs84:"0,0,0",ellipse:"WGS84",datumName:"WGS84"},GGRS87:{towgs84:"-199.87,74.79,246.62",ellipse:"GRS80",datumName:"Greek_Geodetic_Reference_System_1987"},NAD83:{towgs84:"0,0,0",ellipse:"GRS80",datumName:"North_American_Datum_1983"},NAD27:{nadgrids:"@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat",ellipse:"clrk66",datumName:"North_American_Datum_1927"},potsdam:{towgs84:"606.0,23.0,413.0",ellipse:"bessel",datumName:"Potsdam Rauenberg 1950 DHDN"},carthage:{towgs84:"-263.0,6.0,431.0",
83 | ellipse:"clark80",datumName:"Carthage 1934 Tunisia"},hermannskogel:{towgs84:"653.0,-212.0,449.0",ellipse:"bessel",datumName:"Hermannskogel"},ire65:{towgs84:"482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15",ellipse:"mod_airy",datumName:"Ireland 1965"},nzgd49:{towgs84:"59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993",ellipse:"intl",datumName:"New Zealand Geodetic Datum 1949"},OSGB36:{towgs84:"446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894",ellipse:"airy",datumName:"Airy 1830"}};
84 | Proj4js.WGS84=new Proj4js.Proj("WGS84");Proj4js.Datum.OSB36=Proj4js.Datum.OSGB36;Proj4js.wktProjections={"Lambert Tangential Conformal Conic Projection":"lcc",Mercator:"merc","Popular Visualisation Pseudo Mercator":"merc",Mercator_1SP:"merc",Transverse_Mercator:"tmerc","Transverse Mercator":"tmerc","Lambert Azimuthal Equal Area":"laea","Universal Transverse Mercator System":"utm"};
85 | Proj4js.Proj.aea={init:function(){Math.abs(this.lat1+this.lat2)Proj4js.common.EPSLN?(this.ms1*this.ms1-this.ms2*this.ms2)/(this.qs2-this.qs1):this.con,this.c=this.ms1*this.ms1+this.ns0*this.qs1,this.rh=this.a*Math.sqrt(this.c-this.ns0*this.qs0)/
87 | this.ns0)},forward:function(a){var c=a.x,b=a.y;this.sin_phi=Math.sin(b);this.cos_phi=Math.cos(b);var b=Proj4js.common.qsfnz(this.e3,this.sin_phi,this.cos_phi),b=this.a*Math.sqrt(this.c-this.ns0*b)/this.ns0,d=this.ns0*Proj4js.common.adjust_lon(c-this.long0),c=b*Math.sin(d)+this.x0,b=this.rh-b*Math.cos(d)+this.y0;a.x=c;a.y=b;return a},inverse:function(a){var c,b,d;a.x-=this.x0;a.y=this.rh-a.y+this.y0;0<=this.ns0?(c=Math.sqrt(a.x*a.x+a.y*a.y),b=1):(c=-Math.sqrt(a.x*a.x+a.y*a.y),b=-1);d=0;0!=c&&(d=Math.atan2(b*
88 | a.x,b*a.y));b=c*this.ns0/this.a;c=(this.c-b*b)/this.ns0;1.0E-10<=this.e3?(b=1-0.5*(1-this.es)*Math.log((1-this.e3)/(1+this.e3))/this.e3,b=1.0E-10=h;h++)if(b=Math.sin(g),d=Math.cos(g),
89 | e=a*b,f=1-e*e,b=0.5*f*f/d*(c/(1-i)-b/f+0.5/a*Math.log((1-e)/(1+e))),g+=b,1.0E-7>=Math.abs(b))return g;Proj4js.reportError("aea:phi1z:Convergence error");return null}};
90 | Proj4js.Proj.sterea={dependsOn:"gauss",init:function(){Proj4js.Proj.gauss.init.apply(this);this.rc?(this.sinc0=Math.sin(this.phic0),this.cosc0=Math.cos(this.phic0),this.R2=2*this.rc,this.title||(this.title="Oblique Stereographic Alternative")):Proj4js.reportError("sterea:init:E_ERROR_0")},forward:function(a){var c,b,d,e;a.x=Proj4js.common.adjust_lon(a.x-this.long0);Proj4js.Proj.gauss.forward.apply(this,[a]);c=Math.sin(a.y);b=Math.cos(a.y);d=Math.cos(a.x);e=this.k0*this.R2/(1+this.sinc0*c+this.cosc0*
91 | b*d);a.x=e*b*Math.sin(a.x);a.y=e*(this.cosc0*c-this.sinc0*b*d);a.x=this.a*a.x+this.x0;a.y=this.a*a.y+this.y0;return a},inverse:function(a){var c,b,d,e;a.x=(a.x-this.x0)/this.a;a.y=(a.y-this.y0)/this.a;a.x/=this.k0;a.y/=this.k0;(e=Math.sqrt(a.x*a.x+a.y*a.y))?(d=2*Math.atan2(e,this.R2),c=Math.sin(d),b=Math.cos(d),d=Math.asin(b*this.sinc0+a.y*c*this.cosc0/e),c=Math.atan2(a.x*c,e*this.cosc0*b-a.y*this.sinc0*c)):(d=this.phic0,c=0);a.x=c;a.y=d;Proj4js.Proj.gauss.inverse.apply(this,[a]);a.x=Proj4js.common.adjust_lon(a.x+
92 | this.long0);return a}};function phi4z(a,c,b,d,e,f,g,i,h){var j,k,l,m,n,o,h=f;for(o=1;15>=o;o++)if(j=Math.sin(h),l=Math.tan(h),i=l*Math.sqrt(1-a*j*j),k=Math.sin(2*h),m=c*h-b*k+d*Math.sin(4*h)-e*Math.sin(6*h),n=c-2*b*Math.cos(2*h)+4*d*Math.cos(4*h)-6*e*Math.cos(6*h),j=2*m+i*(m*m+g)-2*f*(i*m+1),l=a*k*(m*m+g-2*f*m)/(2*i),i=2*(f-m)*(i*n-2/k)-2*n,j/=l+i,h+=j,1.0E-10>=Math.abs(j))return h;Proj4js.reportError("phi4z: No convergence");return null}
93 | function e4fn(a){var c;c=1+a;a=1-a;return Math.sqrt(Math.pow(c,c)*Math.pow(a,a))}
94 | Proj4js.Proj.poly={init:function(){0==this.lat0&&(this.lat0=90);this.temp=this.b/this.a;this.es=1-Math.pow(this.temp,2);this.e=Math.sqrt(this.es);this.e0=Proj4js.common.e0fn(this.es);this.e1=Proj4js.common.e1fn(this.es);this.e2=Proj4js.common.e2fn(this.es);this.e3=Proj4js.common.e3fn(this.es);this.ml0=Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,this.lat0)},forward:function(a){var c,b,d,e,f;d=a.y;b=Proj4js.common.adjust_lon(a.x-this.long0);1.0E-7>=Math.abs(d)?(f=this.x0+this.a*b,c=this.y0-
95 | this.a*this.ml0):(c=Math.sin(d),b=Math.cos(d),d=Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,d),e=Proj4js.common.msfnz(this.e,c,b),b=c,f=this.x0+this.a*e*Math.sin(b)/c,c=this.y0+this.a*(d-this.ml0+e*(1-Math.cos(b))/c));a.x=f;a.y=c;return a},inverse:function(a){var c,b;a.x-=this.x0;a.y-=this.y0;c=this.ml0+a.y/this.a;if(1.0E-7>=Math.abs(c))c=a.x/this.a+this.long0,b=0;else{c=c*c+a.x/this.a*(a.x/this.a);c=phi4z(this.es,this.e0,this.e1,this.e2,this.e3,this.al,c,void 0,b);if(1!=c)return c;c=Proj4js.common.adjust_lon(Proj4js.common.asinz(NaN*
96 | a.x/this.a)/Math.sin(b)+this.long0)}a.x=c;a.y=b;return a}};
97 | Proj4js.Proj.equi={init:function(){this.x0||(this.x0=0);this.y0||(this.y0=0);this.lat0||(this.lat0=0);this.long0||(this.long0=0)},forward:function(a){var c=a.y,b=this.x0+this.a*Proj4js.common.adjust_lon(a.x-this.long0)*Math.cos(this.lat0),c=this.y0+this.a*c;this.t1=b;this.t2=Math.cos(this.lat0);a.x=b;a.y=c;return a},inverse:function(a){a.x-=this.x0;a.y-=this.y0;var c=a.y/this.a;Math.abs(c)>Proj4js.common.HALF_PI&&Proj4js.reportError("equi:Inv:DataError");var b=Proj4js.common.adjust_lon(this.long0+
98 | a.x/(this.a*Math.cos(this.lat0)));a.x=b;a.y=c}};
99 | Proj4js.Proj.merc={init:function(){this.lat_ts&&(this.k0=this.sphere?Math.cos(this.lat_ts):Proj4js.common.msfnz(this.es,Math.sin(this.lat_ts),Math.cos(this.lat_ts)))},forward:function(a){var c=a.x,b=a.y;if(90b*Proj4js.common.R2D&&180c*Proj4js.common.R2D)return Proj4js.reportError("merc:forward: llInputOutOfRange: "+c+" : "+b),null;if(Math.abs(Math.abs(b)-Proj4js.common.HALF_PI)<=Proj4js.common.EPSLN)return Proj4js.reportError("merc:forward: ll2mAtPoles"),null;
100 | if(this.sphere)c=this.x0+this.a*this.k0*Proj4js.common.adjust_lon(c-this.long0),b=this.y0+this.a*this.k0*Math.log(Math.tan(Proj4js.common.FORTPI+0.5*b));else var d=Math.sin(b),b=Proj4js.common.tsfnz(this.e,b,d),c=this.x0+this.a*this.k0*Proj4js.common.adjust_lon(c-this.long0),b=this.y0-this.a*this.k0*Math.log(b);a.x=c;a.y=b;return a},inverse:function(a){var c=a.x-this.x0,b=a.y-this.y0;if(this.sphere)b=Proj4js.common.HALF_PI-2*Math.atan(Math.exp(-b/this.a*this.k0));else if(b=Math.exp(-b/(this.a*this.k0)),
101 | b=Proj4js.common.phi2z(this.e,b),-9999==b)return Proj4js.reportError("merc:inverse: lat = -9999"),null;c=Proj4js.common.adjust_lon(this.long0+c/(this.a*this.k0));a.x=c;a.y=b;return a}};Proj4js.Proj.utm={dependsOn:"tmerc",init:function(){this.zone?(this.lat0=0,this.long0=(6*Math.abs(this.zone)-183)*Proj4js.common.D2R,this.x0=5E5,this.y0=this.utmSouth?1E7:0,this.k0=0.9996,Proj4js.Proj.tmerc.init.apply(this),this.forward=Proj4js.Proj.tmerc.forward,this.inverse=Proj4js.Proj.tmerc.inverse):Proj4js.reportError("utm:init: zone must be specified for UTM")}};
102 | Proj4js.Proj.eqdc={init:function(){this.mode||(this.mode=0);this.temp=this.b/this.a;this.es=1-Math.pow(this.temp,2);this.e=Math.sqrt(this.es);this.e0=Proj4js.common.e0fn(this.es);this.e1=Proj4js.common.e1fn(this.es);this.e2=Proj4js.common.e2fn(this.es);this.e3=Proj4js.common.e3fn(this.es);this.sinphi=Math.sin(this.lat1);this.cosphi=Math.cos(this.lat1);this.ms1=Proj4js.common.msfnz(this.e,this.sinphi,this.cosphi);this.ml1=Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,this.lat1);0!=this.mode?
103 | (Math.abs(this.lat1+this.lat2)=Proj4js.common.EPSLN?(this.ms1-this.ms2)/(this.ml2-this.ml1):this.sinphi):this.ns=this.sinphi;this.g=this.ml1+this.ms1/this.ns;this.ml0=Proj4js.common.mlfn(this.e0,
104 | this.e1,this.e2,this.e3,this.lat0);this.rh=this.a*(this.g-this.ml0)},forward:function(a){var c=a.x,b=this.a*(this.g-Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,a.y)),d=this.ns*Proj4js.common.adjust_lon(c-this.long0),c=this.x0+b*Math.sin(d),b=this.y0+this.rh-b*Math.cos(d);a.x=c;a.y=b;return a},inverse:function(a){a.x-=this.x0;a.y=this.rh-a.y+this.y0;var c,b;0<=this.ns?(b=Math.sqrt(a.x*a.x+a.y*a.y),c=1):(b=-Math.sqrt(a.x*a.x+a.y*a.y),c=-1);var d=0;0!=b&&(d=Math.atan2(c*a.x,c*a.y));c=this.phi3z(this.g-
105 | b/this.a,this.e0,this.e1,this.e2,this.e3);d=Proj4js.common.adjust_lon(this.long0+d/this.ns);a.x=d;a.y=c;return a},phi3z:function(a,c,b,d,e){var f,g;f=a;for(var i=0;15>i;i++)if(g=(a+b*Math.sin(2*f)-d*Math.sin(4*f)+e*Math.sin(6*f))/c-f,f+=g,1.0E-10>=Math.abs(g))return f;Proj4js.reportError("PHI3Z-CONV:Latitude failed to converge after 15 iterations");return null}};
106 | Proj4js.Proj.tmerc={init:function(){this.e0=Proj4js.common.e0fn(this.es);this.e1=Proj4js.common.e1fn(this.es);this.e2=Proj4js.common.e2fn(this.es);this.e3=Proj4js.common.e3fn(this.es);this.ml0=this.a*Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,this.lat0)},forward:function(a){var c=a.y,b=Proj4js.common.adjust_lon(a.x-this.long0),d,e;d=Math.sin(c);var f=Math.cos(c);if(this.sphere){var g=f*Math.sin(b);if(1.0E-10>Math.abs(Math.abs(g)-1))return Proj4js.reportError("tmerc:forward: Point projects into infinity"),
107 | 93;e=0.5*this.a*this.k0*Math.log((1+g)/(1-g));d=Math.acos(f*Math.cos(b)/Math.sqrt(1-g*g));0>c&&(d=-d);c=this.a*this.k0*(d-this.lat0)}else{e=f*b;var b=Math.pow(e,2),f=this.ep2*Math.pow(f,2),g=Math.tan(c),i=Math.pow(g,2);d=1-this.es*Math.pow(d,2);d=this.a/Math.sqrt(d);c=this.a*Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,c);e=this.k0*d*e*(1+b/6*(1-i+f+b/20*(5-18*i+Math.pow(i,2)+72*f-58*this.ep2)))+this.x0;c=this.k0*(c-this.ml0+d*g*b*(0.5+b/24*(5-i+9*f+4*Math.pow(f,2)+b/30*(61-58*i+Math.pow(i,
108 | 2)+600*f-330*this.ep2))))+this.y0}a.x=e;a.y=c;return a},inverse:function(a){var c,b,d,e;if(this.sphere){b=Math.exp(a.x/(this.a*this.k0));var f=0.5*(b-1/b);d=this.lat0+a.y/(this.a*this.k0);e=Math.cos(d);c=Math.sqrt((1-e*e)/(1+f*f));b=Proj4js.common.asinz(c);0>d&&(b=-b);c=0==f&&0==e?this.long0:Proj4js.common.adjust_lon(Math.atan2(f,e)+this.long0)}else{var f=a.x-this.x0,g=a.y-this.y0;b=c=(this.ml0+g/this.k0)/this.a;for(e=0;;e++){d=(c+this.e1*Math.sin(2*b)-this.e2*Math.sin(4*b)+this.e3*Math.sin(6*b))/
109 | this.e0-b;b+=d;if(Math.abs(d)<=Proj4js.common.EPSLN)break;if(6<=e)return Proj4js.reportError("tmerc:inverse: Latitude failed to converge"),95}if(Math.abs(b)this.a+1.0E-7&&Proj4js.reportError("orthoInvDataError");b=Proj4js.common.asinz(c/this.a);d=Math.sin(b);e=Math.cos(b);b=this.long0;Math.abs(c);d=Proj4js.common.asinz(e*this.sin_p14+a.y*d*this.cos_p14/c);c=Math.abs(this.lat0)-Proj4js.common.HALF_PI;Math.abs(c)<=Proj4js.common.EPSLN&&(b=0<=this.lat0?Proj4js.common.adjust_lon(this.long0+Math.atan2(a.x,-a.y)):Proj4js.common.adjust_lon(this.long0-Math.atan2(-a.x,a.y)));Math.sin(d);a.x=b;a.y=d;return a}};
116 | Proj4js.Proj.krovak={init:function(){this.a=6377397.155;this.es=0.006674372230614;this.e=Math.sqrt(this.es);this.lat0||(this.lat0=0.863937979737193);this.long0||(this.long0=0.4334234309119251);this.k0||(this.k0=0.9999);this.s45=0.785398163397448;this.s90=2*this.s45;this.fi0=this.lat0;this.e2=this.es;this.e=Math.sqrt(this.e2);this.alfa=Math.sqrt(1+this.e2*Math.pow(Math.cos(this.fi0),4)/(1-this.e2));this.uq=1.04216856380474;this.u0=Math.asin(Math.sin(this.fi0)/this.alfa);this.g=Math.pow((1+this.e*Math.sin(this.fi0))/
117 | (1-this.e*Math.sin(this.fi0)),this.alfa*this.e/2);this.k=Math.tan(this.u0/2+this.s45)/Math.pow(Math.tan(this.fi0/2+this.s45),this.alfa)*this.g;this.k1=this.k0;this.n0=this.a*Math.sqrt(1-this.e2)/(1-this.e2*Math.pow(Math.sin(this.fi0),2));this.s0=1.37008346281555;this.n=Math.sin(this.s0);this.ro0=this.k1*this.n0/Math.tan(this.s0);this.ad=this.s90-this.uq},forward:function(a){var c,b,d;b=a.y;d=Proj4js.common.adjust_lon(a.x-this.long0);c=Math.pow((1+this.e*Math.sin(b))/(1-this.e*Math.sin(b)),this.alfa*
118 | this.e/2);c=2*(Math.atan(this.k*Math.pow(Math.tan(b/2+this.s45),this.alfa)/c)-this.s45);b=-d*this.alfa;d=Math.asin(Math.cos(this.ad)*Math.sin(c)+Math.sin(this.ad)*Math.cos(c)*Math.cos(b));c=this.n*Math.asin(Math.cos(c)*Math.sin(b)/Math.cos(d));d=this.ro0*Math.pow(Math.tan(this.s0/2+this.s45),this.n)/Math.pow(Math.tan(d/2+this.s45),this.n);a.y=d*Math.cos(c)/1;a.x=d*Math.sin(c)/1;this.czech&&(a.y*=-1,a.x*=-1);return a},inverse:function(a){var c,b,d;c=a.x;a.x=a.y;a.y=c;this.czech&&(a.y*=-1,a.x*=-1);
119 | c=Math.sqrt(a.x*a.x+a.y*a.y);b=Math.atan2(a.y,a.x)/Math.sin(this.s0);d=2*(Math.atan(Math.pow(this.ro0/c,1/this.n)*Math.tan(this.s0/2+this.s45))-this.s45);c=Math.asin(Math.cos(this.ad)*Math.sin(d)-Math.sin(this.ad)*Math.cos(d)*Math.cos(b));b=Math.asin(Math.cos(d)*Math.sin(b)/Math.cos(c));a.x=this.long0-b/this.alfa;b=c;var e=d=0;do a.y=2*(Math.atan(Math.pow(this.k,-1/this.alfa)*Math.pow(Math.tan(c/2+this.s45),1/this.alfa)*Math.pow((1+this.e*Math.sin(b))/(1-this.e*Math.sin(b)),this.e/2))-this.s45),1.0E-10>
120 | Math.abs(b-a.y)&&(d=1),b=a.y,e+=1;while(0==d&&15>e);return 15<=e?(Proj4js.reportError("PHI3Z-CONV:Latitude failed to converge after 15 iterations"),null):a}};
121 | Proj4js.Proj.somerc={init:function(){var a=this.lat0;this.lambda0=this.long0;var c=Math.sin(a),b=this.a,d=1/this.rf,d=2*d-Math.pow(d,2),e=this.e=Math.sqrt(d);this.R=this.k0*b*Math.sqrt(1-d)/(1-d*Math.pow(c,2));this.alpha=Math.sqrt(1+d/(1-d)*Math.pow(Math.cos(a),4));this.b0=Math.asin(c/this.alpha);this.K=Math.log(Math.tan(Math.PI/4+this.b0/2))-this.alpha*Math.log(Math.tan(Math.PI/4+a/2))+this.alpha*e/2*Math.log((1+e*c)/(1-e*c))},forward:function(a){var c=Math.log(Math.tan(Math.PI/4-a.y/2)),b=this.e/
122 | 2*Math.log((1+this.e*Math.sin(a.y))/(1-this.e*Math.sin(a.y))),b=2*(Math.atan(Math.exp(-this.alpha*(c+b)+this.K))-Math.PI/4),d=this.alpha*(a.x-this.lambda0),c=Math.atan(Math.sin(d)/(Math.sin(this.b0)*Math.tan(b)+Math.cos(this.b0)*Math.cos(d))),b=Math.asin(Math.cos(this.b0)*Math.sin(b)-Math.sin(this.b0)*Math.cos(b)*Math.cos(d));a.y=this.R/2*Math.log((1+Math.sin(b))/(1-Math.sin(b)))+this.y0;a.x=this.R*c+this.x0;return a},inverse:function(a){for(var c=(a.x-this.x0)/this.R,b=2*(Math.atan(Math.exp((a.y-
123 | this.y0)/this.R))-Math.PI/4),d=Math.asin(Math.cos(this.b0)*Math.sin(b)+Math.sin(this.b0)*Math.cos(b)*Math.cos(c)),c=this.lambda0+Math.atan(Math.sin(c)/(Math.cos(this.b0)*Math.cos(c)-Math.sin(this.b0)*Math.tan(b)))/this.alpha,b=0,e=d,f=-1E3,g=0;1.0E-7this.lat0?this.S_POLE:this.N_POLE:a>Proj4js.common.EPSLN?this.OBLIQ:this.EQUIT;this.phits=Math.abs(this.phits);if(this.es){var c;switch(this.mode){case this.N_POLE:case this.S_POLE:Math.abs(this.phits-Proj4js.common.HALF_PI)<
126 | Proj4js.common.EPSLN?this.akm1=2*this.k0/Math.sqrt(Math.pow(1+this.e,1+this.e)*Math.pow(1-this.e,1-this.e)):(a=Math.sin(this.phits),this.akm1=Math.cos(this.phits)/Proj4js.common.tsfnz(this.e,this.phits,a),a*=this.e,this.akm1/=Math.sqrt(1-a*a));break;case this.EQUIT:this.akm1=2*this.k0;break;case this.OBLIQ:a=Math.sin(this.lat0),c=2*Math.atan(this.ssfn_(this.lat0,a,this.e))-Proj4js.common.HALF_PI,a*=this.e,this.akm1=2*this.k0*Math.cos(this.lat0)/Math.sqrt(1-a*a),this.sinX1=Math.sin(c),this.cosX1=Math.cos(c)}}else switch(this.mode){case this.OBLIQ:this.sinph0=
127 | Math.sin(this.lat0),this.cosph0=Math.cos(this.lat0);case this.EQUIT:this.akm1=2*this.k0;break;case this.S_POLE:case this.N_POLE:this.akm1=Math.abs(this.phits-Proj4js.common.HALF_PI)>=Proj4js.common.EPSLN?Math.cos(this.phits)/Math.tan(Proj4js.common.FORTPI-0.5*this.phits):2*this.k0}},forward:function(a){var c=a.x,c=Proj4js.common.adjust_lon(c-this.long0),b=a.y,d,e;if(this.sphere){var f,g,i;f=Math.sin(b);g=Math.cos(b);i=Math.cos(c);c=Math.sin(c);switch(this.mode){case this.EQUIT:e=1+g*i;e<=Proj4js.common.EPSLN&&
128 | Proj4js.reportError("stere:forward:Equit");e=this.akm1/e;d=e*g*c;e*=f;break;case this.OBLIQ:e=1+this.sinph0*f+this.cosph0*g*i;e<=Proj4js.common.EPSLN&&Proj4js.reportError("stere:forward:Obliq");e=this.akm1/e;d=e*g*c;e*=this.cosph0*f-this.sinph0*g*i;break;case this.N_POLE:i=-i,b=-b;case this.S_POLE:Math.abs(b-Proj4js.common.HALF_PI)=f;f++)d*=c,e+=this.A[f]*d;for(var c=e,d=1,g=0,i=0,h=0,f=1;6>=f;f++)e=d*c-g*b,g=g*c+d*b,d=e,i=i+this.B_re[f]*d-this.B_im[f]*g,h=h+this.B_im[f]*d+this.B_re[f]*g;a.x=h*this.a+this.x0;a.y=i*this.a+this.y0;return a},inverse:function(a){for(var c=(a.y-this.y0)/this.a,b=(a.x-this.x0)/this.a,d=1,e=0,f,g=0,i=0,h=1;6>=h;h++)f=
136 | d*c-e*b,e=e*c+d*b,d=f,g=g+this.C_re[h]*d-this.C_im[h]*e,i=i+this.C_im[h]*d+this.C_re[h]*e;for(d=0;d=h;h++)l=j*g-k*i,k=k*g+j*i,j=l,f+=(h-1)*(this.B_re[h]*j-this.B_im[h]*k),e+=(h-1)*(this.B_im[h]*j+this.B_re[h]*k);for(var j=1,k=0,m=this.B_re[1],n=this.B_im[1],h=2;6>=h;h++)l=j*g-k*i,k=k*g+j*i,j=l,m+=h*(this.B_re[h]*j-this.B_im[h]*k),n+=h*(this.B_im[h]*j+this.B_re[h]*k);i=m*m+n*n;g=(f*m+e*n)/i;i=(e*m-f*n)/i}c=g;b=1;g=0;for(h=1;9>=h;h++)b*=c,g+=this.D[h]*
137 | b;h=this.lat0+1E5*g*Proj4js.common.SEC_TO_RAD;a.x=this.long0+i;a.y=h;return a}};Proj4js.Proj.mill={init:function(){},forward:function(a){var c=a.y,b=this.x0+this.a*Proj4js.common.adjust_lon(a.x-this.long0),c=this.y0+1.25*this.a*Math.log(Math.tan(Proj4js.common.PI/4+c/2.5));a.x=b;a.y=c;return a},inverse:function(a){a.x-=this.x0;a.y-=this.y0;var c=Proj4js.common.adjust_lon(this.long0+a.x/this.a),b=2.5*(Math.atan(Math.exp(0.8*a.y/this.a))-Proj4js.common.PI/4);a.x=c;a.y=b;return a}};
138 | Proj4js.Proj.gnom={init:function(){this.sin_p14=Math.sin(this.lat0);this.cos_p14=Math.cos(this.lat0);this.infinity_dist=1E3*this.a;this.rc=1},forward:function(a){var c,b,d,e,f;b=a.y;d=Proj4js.common.adjust_lon(a.x-this.long0);c=Math.sin(b);b=Math.cos(b);e=Math.cos(d);f=this.sin_p14*c+this.cos_p14*b*e;0b&&(f=-f);b=this.x0+f;f=Math.abs(f/(Proj4js.common.PI*this.R));c=0<=c?this.y0+Proj4js.common.PI*this.R*Math.sqrt(1-f*f-2*e*f):this.y0-Proj4js.common.PI*this.R*Math.sqrt(1-f*f-2*e*f);a.x=b;a.y=c;return a},inverse:function(a){var c,b,d,e,f,g,i,h;a.x-=this.x0;a.y-=this.y0;h=Proj4js.common.PI*this.R;c=a.x/h;d=a.y/h;e=c*c+d*d;f=-Math.abs(d)*(1+e);b=f-2*d*d+c*c;g=-2*f+1+2*d*d+e*e;h=d*d/g+(2*b*b*b/g/g/g-9*f*b/g/g)/27;i=(f-b*b/3/g)/g;f=2*Math.sqrt(-i/3);h=3*h/i/f;1Math.abs(b-a.y))break;a.y=b}if(!e)return Proj4js.reportError("gauss:inverse:convergence failed"),null;a.x=c;a.y=b;return a}};
155 | Proj4js.Proj.omerc={init:function(){this.mode||(this.mode=0);this.lon1||(this.lon1=0,this.mode=1);this.lon2||(this.lon2=0);this.lat2||(this.lat2=0);var a=1-Math.pow(this.b/this.a,2);Math.sqrt(a);this.sin_p20=Math.sin(this.lat0);this.cos_p20=Math.cos(this.lat0);this.con=1-this.es*this.sin_p20*this.sin_p20;this.com=Math.sqrt(1-a);this.bl=Math.sqrt(1+this.es*Math.pow(this.cos_p20,4)/(1-a));this.al=this.a*this.bl*this.k0*this.com/this.con;Math.abs(this.lat0)
157 | Proj4js.common.EPSLN&&Math.abs(this.con-Proj4js.common.HALF_PI)>Proj4js.common.EPSLN?(this.singam=Math.sin(this.gama),this.cosgam=Math.cos(this.gama),this.sinaz=Math.sin(this.alpha),this.cosaz=Math.cos(this.alpha),this.u=0<=this.lat0?this.al/this.bl*Math.atan(Math.sqrt(this.d*this.d-1)/this.cosaz):-(this.al/this.bl)*Math.atan(Math.sqrt(this.d*this.d-1)/this.cosaz)):Proj4js.reportError("omerc:Init:DataError")):(this.sinphi=Math.sin(this.at1),this.ts1=Proj4js.common.tsfnz(this.e,this.lat1,this.sinphi),
158 | this.sinphi=Math.sin(this.lat2),this.ts2=Proj4js.common.tsfnz(this.e,this.lat2,this.sinphi),this.h=Math.pow(this.ts1,this.bl),this.l=Math.pow(this.ts2,this.bl),this.f=this.el/this.h,this.g=0.5*(this.f-1/this.f),this.j=(this.el*this.el-this.l*this.h)/(this.el*this.el+this.l*this.h),this.p=(this.l-this.h)/(this.l+this.h),this.dlon=this.lon1-this.lon2,this.dlon<-Proj4js.common.PI&&(this.lon2-=2*Proj4js.common.PI),this.dlon>Proj4js.common.PI&&(this.lon2+=2*Proj4js.common.PI),this.dlon=this.lon1-this.lon2,
159 | this.longc=0.5*(this.lon1+this.lon2)-Math.atan(this.j*Math.tan(0.5*this.bl*this.dlon)/this.p)/this.bl,this.dlon=Proj4js.common.adjust_lon(this.lon1-this.longc),this.gama=Math.atan(Math.sin(this.bl*this.dlon)/this.g),this.alpha=Proj4js.common.asinz(this.d*Math.sin(this.gama)),Math.abs(this.lat1-this.lat2)<=Proj4js.common.EPSLN?Proj4js.reportError("omercInitDataError"):this.con=Math.abs(this.lat1),this.con<=Proj4js.common.EPSLN||Math.abs(this.con-Proj4js.common.HALF_PI)<=Proj4js.common.EPSLN?Proj4js.reportError("omercInitDataError"):
160 | Math.abs(Math.abs(this.lat0)-Proj4js.common.HALF_PI)<=Proj4js.common.EPSLN&&Proj4js.reportError("omercInitDataError"),this.singam=Math.sin(this.gam),this.cosgam=Math.cos(this.gam),this.sinaz=Math.sin(this.alpha),this.cosaz=Math.cos(this.alpha),this.u=0<=this.lat0?this.al/this.bl*Math.atan(Math.sqrt(this.d*this.d-1)/this.cosaz):-(this.al/this.bl)*Math.atan(Math.sqrt(this.d*this.d-1)/this.cosaz))},forward:function(a){var c,b,d,e,f;d=a.x;b=a.y;c=Math.sin(b);e=Proj4js.common.adjust_lon(d-this.longc);
161 | d=Math.sin(this.bl*e);Math.abs(Math.abs(b)-Proj4js.common.HALF_PI)>Proj4js.common.EPSLN?(c=Proj4js.common.tsfnz(this.e,b,c),c=this.el/Math.pow(c,this.bl),f=0.5*(c-1/c),c=(f*this.singam-d*this.cosgam)/(0.5*(c+1/c)),b=Math.cos(this.bl*e),1.0E-7>Math.abs(b)?d=this.al*this.bl*e:(d=this.al*Math.atan((f*this.cosgam+d*this.singam)/b)/this.bl,0>b&&(d+=Proj4js.common.PI*this.al/this.bl))):(c=0<=b?this.singam:-this.singam,d=this.al*b/this.bl);Math.abs(Math.abs(c)-1)<=Proj4js.common.EPSLN&&Proj4js.reportError("omercFwdInfinity");
162 | e=0.5*this.al*Math.log((1-c)/(1+c))/this.bl;d-=this.u;c=this.y0+d*this.cosaz-e*this.sinaz;a.x=this.x0+e*this.cosaz+d*this.sinaz;a.y=c;return a},inverse:function(a){var c,b,d,e;a.x-=this.x0;a.y-=this.y0;c=a.x*this.cosaz-a.y*this.sinaz;d=a.y*this.cosaz+a.x*this.sinaz;d+=this.u;b=Math.exp(-this.bl*c/this.al);c=0.5*(b-1/b);b=0.5*(b+1/b);d=Math.sin(this.bl*d/this.al);e=(d*this.cosgam+c*this.singam)/b;Math.abs(Math.abs(e)-1)<=Proj4js.common.EPSLN?(c=this.longc,e=0<=e?Proj4js.common.HALF_PI:-Proj4js.common.HALF_PI):
163 | (b=1/this.bl,e=Math.pow(this.el/Math.sqrt((1+e)/(1-e)),b),e=Proj4js.common.phi2z(this.e,e),c=this.longc-Math.atan2(c*this.cosgam-d*this.singam,b)/this.bl,c=Proj4js.common.adjust_lon(c));a.x=c;a.y=e;return a}};
164 | Proj4js.Proj.lcc={init:function(){this.lat2||(this.lat2=this.lat0);this.k0||(this.k0=1);if(Math.abs(this.lat1+this.lat2)Proj4js.common.EPSLN?Math.log(c/e)/Math.log(b/d):a;this.f0=c/(this.ns*Math.pow(b,this.ns));this.rh=this.a*this.f0*Math.pow(f,this.ns);this.title||(this.title="Lambert Conformal Conic")}},forward:function(a){var c=a.x,b=a.y;if(!(90>=b&&-90<=b&&180>=c&&-180<=c))return Proj4js.reportError("lcc:forward: llInputOutOfRange: "+c+" : "+b),null;var d=Math.abs(Math.abs(b)-Proj4js.common.HALF_PI);if(d>Proj4js.common.EPSLN)b=Proj4js.common.tsfnz(this.e,
166 | b,Math.sin(b)),b=this.a*this.f0*Math.pow(b,this.ns);else{d=b*this.ns;if(0>=d)return Proj4js.reportError("lcc:forward: No Projection"),null;b=0}c=this.ns*Proj4js.common.adjust_lon(c-this.long0);a.x=this.k0*b*Math.sin(c)+this.x0;a.y=this.k0*(this.rh-b*Math.cos(c))+this.y0;return a},inverse:function(a){var c,b,d,e=(a.x-this.x0)/this.k0,f=this.rh-(a.y-this.y0)/this.k0;0this.lat0?this.S_POLE:this.N_POLE:Math.abs(a)g){Proj4js.reportError("aeqd:Fwd:PointError");return}}else b=Math.acos(g),b/=Math.sin(b);a.x=this.x0+this.a*b*e*Math.sin(c);a.y=this.y0+this.a*b*(this.cos_p12*d-this.sin_p12*e*f);return a},
177 | inverse:function(a){a.x-=this.x0;a.y-=this.y0;var c=Math.sqrt(a.x*a.x+a.y*a.y);if(c>2*Proj4js.common.HALF_PI*this.a)Proj4js.reportError("aeqdInvDataError");else{var b=c/this.a,d=Math.sin(b),b=Math.cos(b),e=this.long0,f;if(Math.abs(c)<=Proj4js.common.EPSLN)f=this.lat0;else{f=Proj4js.common.asinz(b*this.sin_p12+a.y*d*this.cos_p12/c);var g=Math.abs(this.lat0)-Proj4js.common.HALF_PI;Math.abs(g)<=Proj4js.common.EPSLN?e=0<=this.lat0?Proj4js.common.adjust_lon(this.long0+Math.atan2(a.x,-a.y)):Proj4js.common.adjust_lon(this.long0-
178 | Math.atan2(-a.x,a.y)):(g=b-this.sin_p12*Math.sin(f),Math.abs(g)Proj4js.common.PI&&(b=Proj4js.common.PI);c=(2*c+Math.sin(2*c))/Proj4js.common.PI;1 1e-3) {
116 | throw new Error("Projected bounds does not match grid at zoom " + i);
117 | }
118 | }
119 | },
120 |
121 | getTileUrl: function(tilePoint) {
122 | var gridHeight =
123 | Math.round((this.crs.projectedBounds[3] - this.crs.projectedBounds[1]) /
124 | this._projectedTileSize(this._map.getZoom()));
125 |
126 | // TODO: relies on some of TileLayer's internals
127 | return L.Util.template(this._url, L.Util.extend({
128 | s: this._getSubdomain(tilePoint),
129 | z: this._getZoomForUrl(),
130 | x: tilePoint.x,
131 | y: gridHeight - tilePoint.y - 1
132 | }, this.options));
133 | },
134 |
135 | _projectedTileSize: function(zoom) {
136 | return (this.options.tileSize / this.crs.scale(zoom));
137 | }
138 | });
139 |
140 | if (typeof module !== 'undefined') module.exports = L.Proj;
141 |
142 | if (typeof L !== 'undefined' && typeof L.CRS !== 'undefined') {
143 | // This is left here for backwards compatibility
144 | L.CRS.proj4js = (function () {
145 | return function (code, def, transformation, options) {
146 | options = options || {};
147 | if (transformation) options.transformation = transformation;
148 |
149 | return new L.Proj.CRS(code, def, options);
150 | };
151 | }());
152 | }
--------------------------------------------------------------------------------
/example/mollweide.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Leaflet Graticule
6 |
7 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
56 |
57 |
--------------------------------------------------------------------------------
/leaflet.latlng-graticule.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable indent,semi */
2 | /**
3 | * Create a Canvas as ImageOverlay to draw the Lat/Lon Graticule,
4 | * and show the axis tick label on the edge of the map.
5 | * Author: lanwei@cloudybay.com.tw
6 | */
7 |
8 | (function (window, document, undefined) {
9 |
10 | L.LatLngGraticule = L.Layer.extend({
11 | includes: (L.Evented.prototype || L.Mixin.Events),
12 | options: {
13 | showLabel: true,
14 | opacity: 1,
15 | weight: 0.8,
16 | color: '#aaa',
17 | font: '12px Verdana',
18 | dashArray: [0,0],
19 | lngLineCurved: 0,
20 | latLineCurved: 0,
21 | zoomInterval: [
22 | {start: 2, end: 2, interval: 40},
23 | {start: 3, end: 3, interval: 20},
24 | {start: 4, end: 4, interval: 10},
25 | {start: 5, end: 7, interval: 5},
26 | {start: 8, end: 20, interval: 1}
27 | ],
28 | sides: ['N', 'S', 'E', 'W']
29 | },
30 |
31 | initialize: function (options) {
32 | L.setOptions(this, options);
33 |
34 | var defaultFontName = 'Verdana';
35 | var _ff = this.options.font.split(' ');
36 | if (_ff.length < 2) {
37 | this.options.font += ' ' + defaultFontName;
38 | }
39 |
40 | if (!this.options.fontColor) {
41 | this.options.fontColor = this.options.color;
42 | }
43 |
44 | if (this.options.zoomInterval) {
45 | if (this.options.zoomInterval.latitude) {
46 | this.options.latInterval = this.options.zoomInterval.latitude;
47 | if (!this.options.zoomInterval.longitude) {
48 | this.options.lngInterval = this.options.zoomInterval.latitude;
49 | }
50 | }
51 | if (this.options.zoomInterval.longitude) {
52 | this.options.lngInterval = this.options.zoomInterval.longitude;
53 | if (!this.options.zoomInterval.latitude) {
54 | this.options.latInterval = this.options.zoomInterval.longitude;
55 | }
56 | }
57 | if (!this.options.latInterval) {
58 | this.options.latInterval = this.options.zoomInterval;
59 | }
60 | if (!this.options.lngInterval) {
61 | this.options.lngInterval = this.options.zoomInterval;
62 | }
63 | }
64 | },
65 |
66 | onAdd: function (map) {
67 | this._map = map;
68 |
69 | if (!this._canvas) {
70 | this._initCanvas();
71 | }
72 |
73 | map._panes.overlayPane.appendChild(this._canvas);
74 |
75 | map.on('viewreset', this._reset, this);
76 | map.on('move', this._reset, this);
77 | map.on('moveend', this._reset, this);
78 |
79 | if (map.options.zoomAnimation && L.Browser.any3d) {
80 | map.on('zoomanim', this._animateZoom, this);
81 | }
82 |
83 | this._reset();
84 | },
85 |
86 | onRemove: function (map) {
87 | L.DomUtil.remove(this._canvas);
88 |
89 | map.off('viewreset', this._reset, this);
90 | map.off('move', this._reset, this);
91 | map.off('moveend', this._reset, this);
92 |
93 | if (map.options.zoomAnimation) {
94 | map.off('zoomanim', this._animateZoom, this);
95 | }
96 | },
97 |
98 | addTo: function (map) {
99 | map.addLayer(this);
100 | return this;
101 | },
102 |
103 | setOpacity: function (opacity) {
104 | this.options.opacity = opacity;
105 | this._updateOpacity();
106 | return this;
107 | },
108 |
109 | bringToFront: function () {
110 | if (this._canvas) {
111 | //this._map._panes.overlayPane.appendChild(this._canvas);
112 | }
113 | return this;
114 | },
115 |
116 | bringToBack: function () {
117 | var pane = this._map._panes.overlayPane;
118 | if (this._canvas) {
119 | //pane.insertBefore(this._canvas, pane.firstChild);
120 | }
121 | return this;
122 | },
123 |
124 | getAttribution: function () {
125 | return this.options.attribution;
126 | },
127 |
128 | _initCanvas: function () {
129 |
130 | this._canvas = L.DomUtil.create('canvas', '');
131 |
132 | if (this._map.options.zoomAnimation && L.Browser.any3d) {
133 | L.DomUtil.addClass(this._canvas, 'leaflet-zoom-animated');
134 | } else {
135 | L.DomUtil.addClass(this._canvas, 'leaflet-zoom-hide');
136 | }
137 |
138 | this._updateOpacity();
139 |
140 |
141 | L.extend(this._canvas, {
142 | onselectstart: L.Util.falseFn,
143 | onmousemove: L.Util.falseFn,
144 | onload: L.bind(this._onCanvasLoad, this)
145 | });
146 | },
147 |
148 | _animateZoom: function (e) {
149 | var map = this._map,
150 | canvas = this._canvas,
151 | scale = map.getZoomScale(e.zoom),
152 | nw = map.containerPointToLatLng([0, 0]),
153 | se = map.containerPointToLatLng([canvas.width, canvas.height]),
154 | topLeft = map._latLngToNewLayerPoint(nw, e.zoom, e.center),
155 | size = map._latLngToNewLayerPoint(se, e.zoom, e.center)._subtract(topLeft),
156 | origin = topLeft._add(size._multiplyBy((1 / 2) * (1 - 1 / scale)));
157 |
158 | L.DomUtil.setTransform(canvas, origin, scale);
159 | },
160 |
161 | _reset: function () {
162 | var canvas = this._canvas,
163 | size = this._map.getSize(),
164 | lt = this._map.containerPointToLayerPoint([0, 0]);
165 |
166 | L.DomUtil.setPosition(canvas, lt);
167 |
168 | canvas.width = size.x;
169 | canvas.height = size.y;
170 | canvas.style.width = size.x + 'px';
171 | canvas.style.height = size.y + 'px';
172 |
173 | this.__calcInterval();
174 |
175 | this.__draw(true);
176 | },
177 |
178 | _onCanvasLoad: function () {
179 | this.fire('load');
180 | },
181 |
182 | _updateOpacity: function () {
183 | L.DomUtil.setOpacity(this._canvas, this.options.opacity);
184 | },
185 |
186 | __format_lat: function(lat) {
187 | if (this.options.latFormatTickLabel) {
188 | return this.options.latFormatTickLabel(lat);
189 | }
190 |
191 | // todo: format type of float
192 | if (lat < 0) {
193 | return '' + (lat*-1) + this.options.sides[1];
194 | }
195 | else if (lat > 0) {
196 | return '' + lat + this.options.sides[0];
197 | }
198 | return '' + lat;
199 | },
200 |
201 | __format_lng: function(lng) {
202 | if (this.options.lngFormatTickLabel) {
203 | return this.options.lngFormatTickLabel(lng);
204 | }
205 |
206 | // todo: format type of float
207 | if (lng > 180) {
208 | return '' + (360 - lng) + this.options.sides[3];
209 | }
210 | else if (lng > 0 && lng < 180) {
211 | return '' + lng + this.options.sides[2];
212 | }
213 | else if (lng < 0 && lng > -180) {
214 | return '' + (lng*-1) + this.options.sides[3];
215 | }
216 | else if (lng == -180) {
217 | return '' + (lng*-1);
218 | }
219 | else if (lng < -180) {
220 | return '' + (360 + lng) + this.options.sides[3];
221 | }
222 | return '' + lng;
223 | },
224 |
225 | __calcInterval: function() {
226 | var zoom = this._map.getZoom();
227 | if (this._currZoom != zoom) {
228 | this._currLngInterval = 0;
229 | this._currLatInterval = 0;
230 | this._currZoom = zoom;
231 | }
232 |
233 | var interv;
234 |
235 | if (!this._currLngInterval) {
236 | try {
237 | for (var idx in this.options.lngInterval) {
238 | var dict = this.options.lngInterval[idx];
239 | if (dict.start <= zoom) {
240 | if (dict.end && dict.end >= zoom) {
241 | this._currLngInterval = dict.interval;
242 | break;
243 | }
244 | }
245 | }
246 | }
247 | catch(e) {
248 | this._currLngInterval = 0;
249 | }
250 | }
251 |
252 | if (!this._currLatInterval) {
253 | try {
254 | for (var idx in this.options.latInterval) {
255 | var dict = this.options.latInterval[idx];
256 | if (dict.start <= zoom) {
257 | if (dict.end && dict.end >= zoom) {
258 | this._currLatInterval = dict.interval;
259 | break;
260 | }
261 | }
262 | }
263 | }
264 | catch(e) {
265 | this._currLatInterval = 0;
266 | }
267 | }
268 | },
269 |
270 | __draw: function(label) {
271 | function _parse_px_to_int(txt) {
272 | if (txt.length > 2) {
273 | if (txt.charAt(txt.length-2) == 'p') {
274 | txt = txt.substr(0, txt.length-2);
275 | }
276 | }
277 | try {
278 | return parseInt(txt, 10);
279 | }
280 | catch(e) {}
281 | return 0;
282 | };
283 |
284 | var self = this,
285 | canvas = this._canvas,
286 | map = this._map,
287 | curvedLon = this.options.lngLineCurved,
288 | curvedLat = this.options.latLineCurved;
289 |
290 | if (L.Browser.canvas && map) {
291 | if (!this._currLngInterval || !this._currLatInterval) {
292 | this.__calcInterval();
293 | }
294 |
295 | var latInterval = this._currLatInterval,
296 | lngInterval = this._currLngInterval;
297 |
298 | var ctx = canvas.getContext('2d');
299 | ctx.clearRect(0, 0, canvas.width, canvas.height);
300 | ctx.lineWidth = this.options.weight;
301 | ctx.strokeStyle = this.options.color;
302 | ctx.fillStyle = this.options.fontColor;
303 | ctx.setLineDash(this.options.dashArray);
304 |
305 | if (this.options.font) {
306 | ctx.font = this.options.font;
307 | }
308 | var txtWidth = ctx.measureText('0').width;
309 | var txtHeight = 12;
310 | try {
311 | var _font_size = ctx.font.trim().split(' ')[0];
312 | txtHeight = _parse_px_to_int(_font_size);
313 | }
314 | catch(e) {}
315 |
316 | var ww = canvas.width,
317 | hh = canvas.height;
318 |
319 | var lt = map.containerPointToLatLng(L.point(0, 0));
320 | var rt = map.containerPointToLatLng(L.point(ww, 0));
321 | var rb = map.containerPointToLatLng(L.point(ww, hh));
322 |
323 | var _lat_b = rb.lat,
324 | _lat_t = lt.lat;
325 | var _lon_l = lt.lng,
326 | _lon_r = rt.lng;
327 |
328 | var _point_per_lat = (_lat_t - _lat_b) / (hh * 0.2);
329 | if (isNaN(_point_per_lat)) {
330 | return;
331 | }
332 |
333 | if (_point_per_lat < 1) { _point_per_lat = 1; }
334 | if (_lat_b < -90) {
335 | _lat_b = -90;
336 | }
337 | else {
338 | _lat_b = parseInt(_lat_b - _point_per_lat, 10);
339 | }
340 |
341 | if (_lat_t > 90) {
342 | _lat_t = 90;
343 | }
344 | else {
345 | _lat_t = parseInt(_lat_t + _point_per_lat, 10);
346 | }
347 |
348 | var _point_per_lon = (_lon_r - _lon_l) / (ww * 0.2);
349 | if (_point_per_lon < 1) { _point_per_lon = 1; }
350 | if (_lon_l > 0 && _lon_r < 0) {
351 | _lon_r += 360;
352 | }
353 | _lon_r = parseInt(_lon_r + _point_per_lon, 10);
354 | _lon_l = parseInt(_lon_l - _point_per_lon, 10);
355 |
356 | var ll, latstr, lngstr, _lon_delta = 0.5;
357 | function __draw_lat_line(self, lat_tick) {
358 | ll = self._latLngToCanvasPoint(L.latLng(lat_tick, _lon_l));
359 | latstr = self.__format_lat(lat_tick);
360 | txtWidth = ctx.measureText(latstr).width;
361 | var spacer = self.options.showLabel && label ? txtWidth + 10 : 0;
362 |
363 | if (curvedLat) {
364 | if (typeof(curvedLat) == 'number') {
365 | _lon_delta = curvedLat;
366 | }
367 |
368 | var __lon_left = _lon_l, __lon_right = _lon_r;
369 | if (ll.x > 0) {
370 | var __lon_left = map.containerPointToLatLng(L.point(0, ll.y));
371 | __lon_left = __lon_left.lng - _point_per_lon;
372 | ll.x = 0;
373 | }
374 | var rr = self._latLngToCanvasPoint(L.latLng(lat_tick, __lon_right));
375 | if (rr.x < ww) {
376 | __lon_right = map.containerPointToLatLng(L.point(ww, rr.y));
377 | __lon_right = __lon_right.lng + _point_per_lon;
378 | if (__lon_left > 0 && __lon_right < 0) {
379 | __lon_right += 360;
380 | }
381 | }
382 |
383 | ctx.beginPath();
384 | ctx.moveTo(ll.x + spacer, ll.y);
385 | var _prev_p = null;
386 | for (var j=__lon_left; j<=__lon_right; j+=_lon_delta) {
387 | rr = self._latLngToCanvasPoint(L.latLng(lat_tick, j));
388 | ctx.lineTo(rr.x - spacer, rr.y);
389 |
390 | if (self.options.showLabel && label && _prev_p != null) {
391 | if (_prev_p.x < 0 && rr.x >= 0) {
392 | var _s = (rr.x - 0) / (rr.x - _prev_p.x);
393 | var _y = rr.y - ((rr.y - _prev_p.y) * _s);
394 | ctx.fillText(latstr, 0, _y + (txtHeight/2));
395 | }
396 | else if (_prev_p.x <= (ww-txtWidth) && rr.x > (ww-txtWidth)) {
397 | var _s = (rr.x - ww) / (rr.x - _prev_p.x);
398 | var _y = rr.y - ((rr.y - _prev_p.y) * _s);
399 | ctx.fillText(latstr, ww-txtWidth, _y + (txtHeight/2)-2);
400 | }
401 | }
402 |
403 | _prev_p = {x:rr.x, y:rr.y, lon:j, lat:i};
404 | }
405 | ctx.stroke();
406 | }
407 | else {
408 | var __lon_right = _lon_r;
409 | var rr = self._latLngToCanvasPoint(L.latLng(lat_tick, __lon_right));
410 | if (curvedLon) {
411 | __lon_right = map.containerPointToLatLng(L.point(0, rr.y));
412 | __lon_right = __lon_right.lng;
413 | rr = self._latLngToCanvasPoint(L.latLng(lat_tick, __lon_right));
414 |
415 | var __lon_left = map.containerPointToLatLng(L.point(ww, rr.y));
416 | __lon_left = __lon_left.lng;
417 | ll = self._latLngToCanvasPoint(L.latLng(lat_tick, __lon_left));
418 | }
419 |
420 | ctx.beginPath();
421 | ctx.moveTo(1 + spacer, ll.y);
422 | ctx.lineTo(rr.x-1 - spacer, rr.y);
423 | ctx.stroke();
424 | if (self.options.showLabel && label) {
425 | var _yy = ll.y + (txtHeight/2)-2;
426 | ctx.fillText(latstr, 0, _yy);
427 | ctx.fillText(latstr, ww-txtWidth, _yy);
428 | }
429 | }
430 | };
431 |
432 | if (latInterval > 0) {
433 | for (var i=latInterval; i<=_lat_t; i+=latInterval) {
434 | if (i >= _lat_b) {
435 | __draw_lat_line(this, i);
436 | }
437 | }
438 | for (var i=0; i>=_lat_b; i-=latInterval) {
439 | if (i <= _lat_t) {
440 | __draw_lat_line(this, i);
441 | }
442 | }
443 | }
444 |
445 | function __draw_lon_line(self, lon_tick) {
446 | lngstr = self.__format_lng(lon_tick);
447 | txtWidth = ctx.measureText(lngstr).width;
448 | var bb = self._latLngToCanvasPoint(L.latLng(_lat_b, lon_tick));
449 | var spacer = self.options.showLabel && label ? txtHeight + 5 : 0;
450 |
451 | if (curvedLon) {
452 | if (typeof(curvedLon) == 'number') {
453 | _lat_delta = curvedLon;
454 | }
455 |
456 | ctx.beginPath();
457 | ctx.moveTo(bb.x, 5 + spacer);
458 | var _prev_p = null;
459 | for (var j=_lat_b; j<_lat_t; j+=_lat_delta) {
460 | var tt = self._latLngToCanvasPoint(L.latLng(j, lon_tick));
461 | ctx.lineTo(tt.x, tt.y - spacer);
462 |
463 | if (self.options.showLabel && label && _prev_p != null) {
464 | if (_prev_p.y > 8 && tt.y <= 8) {
465 | ctx.fillText(lngstr, tt.x - (txtWidth/2), txtHeight + 5);
466 | }
467 | else if (_prev_p.y >= hh && tt.y < hh) {
468 | ctx.fillText(lngstr, tt.x - (txtWidth/2), hh-2);
469 | }
470 | }
471 |
472 | _prev_p = {x:tt.x, y:tt.y, lon:lon_tick, lat:j};
473 | }
474 | ctx.stroke();
475 | }
476 | else {
477 | var __lat_top = _lat_t;
478 | var tt = self._latLngToCanvasPoint(L.latLng(__lat_top, lon_tick));
479 | if (curvedLat) {
480 | __lat_top = map.containerPointToLatLng(L.point(tt.x, 0));
481 | __lat_top = __lat_top.lat;
482 | if (__lat_top > 90) { __lat_top = 90; }
483 | tt = self._latLngToCanvasPoint(L.latLng(__lat_top, lon_tick));
484 |
485 | var __lat_bottom = map.containerPointToLatLng(L.point(bb.x, hh));
486 | __lat_bottom = __lat_bottom.lat;
487 | if (__lat_bottom < -90) { __lat_bottom = -90; }
488 | bb = self._latLngToCanvasPoint(L.latLng(__lat_bottom, lon_tick));
489 | }
490 |
491 | ctx.beginPath();
492 | ctx.moveTo(tt.x, 5 + spacer);
493 | ctx.lineTo(bb.x, hh-1 - spacer);
494 | ctx.stroke();
495 |
496 | if (self.options.showLabel && label) {
497 | ctx.fillText(lngstr, tt.x - (txtWidth/2), txtHeight+5);
498 | ctx.fillText(lngstr, bb.x - (txtWidth/2), hh-3);
499 | }
500 | }
501 | };
502 |
503 | if (lngInterval > 0) {
504 | for (var i=lngInterval; i<=_lon_r; i+=lngInterval) {
505 | if (i >= _lon_l) {
506 | __draw_lon_line(this, i);
507 | }
508 | }
509 | for (var i=0; i>=_lon_l; i-=lngInterval) {
510 | if (i <= _lon_r) {
511 | __draw_lon_line(this, i);
512 | }
513 | }
514 | }
515 | }
516 | },
517 |
518 | _latLngToCanvasPoint: function(latlng) {
519 | var map = this._map;
520 | var projectedPoint = map.project(L.latLng(latlng));
521 | projectedPoint._subtract(map.getPixelOrigin());
522 | return L.point(projectedPoint).add(map._getMapPanePos());
523 | }
524 |
525 | });
526 |
527 | L.latlngGraticule = function (options) {
528 | return new L.LatLngGraticule(options);
529 | };
530 |
531 |
532 | }(this, document));
533 |
--------------------------------------------------------------------------------