From 960d5ddc75b659a802ffc2f01d67d33efa8b9fe5 Mon Sep 17 00:00:00 2001 From: Ryan Kirkman Date: Wed, 20 Feb 2013 14:35:15 +1000 Subject: [PATCH] Added proj4js 1.1.0 closes #933 --- ajax/libs/proj4js/1.1.0/defs/EPSG102067.js | 1 + ajax/libs/proj4js/1.1.0/defs/EPSG102757.js | 1 + ajax/libs/proj4js/1.1.0/defs/EPSG102758.js | 1 + ajax/libs/proj4js/1.1.0/defs/EPSG21781.js | 1 + ajax/libs/proj4js/1.1.0/defs/EPSG26591.js | 1 + ajax/libs/proj4js/1.1.0/defs/EPSG26912.js | 1 + ajax/libs/proj4js/1.1.0/defs/EPSG27200.js | 5 + ajax/libs/proj4js/1.1.0/defs/EPSG27563.js | 1 + ajax/libs/proj4js/1.1.0/defs/EPSG41001.js | 1 + ajax/libs/proj4js/1.1.0/defs/EPSG4139.js | 1 + ajax/libs/proj4js/1.1.0/defs/EPSG4181.js | 1 + ajax/libs/proj4js/1.1.0/defs/EPSG42304.js | 1 + ajax/libs/proj4js/1.1.0/defs/EPSG4272.js | 1 + ajax/libs/proj4js/1.1.0/defs/EPSG4302.js | 2 + ajax/libs/proj4js/1.1.0/defs/EPSG900913.js | 5 + ajax/libs/proj4js/1.1.0/defs/EPSG900913.txt | 11 + ajax/libs/proj4js/1.1.0/defs/GOOGLE.js | 2 + ajax/libs/proj4js/1.1.0/proj4js-combined.js | 5438 +++++++++++++++++ ajax/libs/proj4js/1.1.0/proj4js-compressed.js | 266 + ajax/libs/proj4js/1.1.0/proj4js.js | 1816 ++++++ ajax/libs/proj4js/1.1.0/projCode/aea.js | 149 + ajax/libs/proj4js/1.1.0/projCode/aeqd.js | 75 + ajax/libs/proj4js/1.1.0/projCode/cass.js | 108 + ajax/libs/proj4js/1.1.0/projCode/cea.js | 85 + ajax/libs/proj4js/1.1.0/projCode/eqc.js | 42 + ajax/libs/proj4js/1.1.0/projCode/eqdc.js | 140 + ajax/libs/proj4js/1.1.0/projCode/equi.js | 72 + ajax/libs/proj4js/1.1.0/projCode/gauss.js | 44 + ajax/libs/proj4js/1.1.0/projCode/gnom.js | 117 + ajax/libs/proj4js/1.1.0/projCode/gstmerc.js | 52 + ajax/libs/proj4js/1.1.0/projCode/krovak.js | 135 + ajax/libs/proj4js/1.1.0/projCode/laea.js | 358 ++ ajax/libs/proj4js/1.1.0/projCode/lcc.js | 148 + ajax/libs/proj4js/1.1.0/projCode/merc.js | 115 + ajax/libs/proj4js/1.1.0/projCode/mill.js | 68 + ajax/libs/proj4js/1.1.0/projCode/moll.js | 100 + ajax/libs/proj4js/1.1.0/projCode/nzmg.js | 284 + ajax/libs/proj4js/1.1.0/projCode/omerc.js | 256 + ajax/libs/proj4js/1.1.0/projCode/ortho.js | 110 + ajax/libs/proj4js/1.1.0/projCode/poly.js | 157 + ajax/libs/proj4js/1.1.0/projCode/sinu.js | 121 + ajax/libs/proj4js/1.1.0/projCode/somerc.js | 110 + ajax/libs/proj4js/1.1.0/projCode/stere.js | 247 + ajax/libs/proj4js/1.1.0/projCode/sterea.js | 57 + ajax/libs/proj4js/1.1.0/projCode/tmerc.js | 141 + ajax/libs/proj4js/1.1.0/projCode/utm.js | 43 + ajax/libs/proj4js/1.1.0/projCode/vandg.js | 137 + ajax/libs/proj4js/1.1.0/util/MGRS.js | 950 +++ ajax/libs/proj4js/package.json | 16 + 49 files changed, 11994 insertions(+) create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG102067.js create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG102757.js create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG102758.js create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG21781.js create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG26591.js create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG26912.js create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG27200.js create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG27563.js create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG41001.js create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG4139.js create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG4181.js create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG42304.js create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG4272.js create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG4302.js create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG900913.js create mode 100755 ajax/libs/proj4js/1.1.0/defs/EPSG900913.txt create mode 100755 ajax/libs/proj4js/1.1.0/defs/GOOGLE.js create mode 100755 ajax/libs/proj4js/1.1.0/proj4js-combined.js create mode 100755 ajax/libs/proj4js/1.1.0/proj4js-compressed.js create mode 100755 ajax/libs/proj4js/1.1.0/proj4js.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/aea.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/aeqd.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/cass.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/cea.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/eqc.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/eqdc.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/equi.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/gauss.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/gnom.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/gstmerc.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/krovak.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/laea.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/lcc.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/merc.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/mill.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/moll.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/nzmg.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/omerc.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/ortho.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/poly.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/sinu.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/somerc.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/stere.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/sterea.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/tmerc.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/utm.js create mode 100755 ajax/libs/proj4js/1.1.0/projCode/vandg.js create mode 100755 ajax/libs/proj4js/1.1.0/util/MGRS.js create mode 100755 ajax/libs/proj4js/package.json diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG102067.js b/ajax/libs/proj4js/1.1.0/defs/EPSG102067.js new file mode 100755 index 000000000..2fe1f0547 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG102067.js @@ -0,0 +1 @@ +Proj4js.defs["EPSG:102067"] = "+title=Krovak +proj=krovak +lat_0=49.5 +lon_0=42.5 +alpha=30.28813972222222 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +pm=ferro +units=m +towgs84=570.8,85.7,462.8,4.998,1.587,5.261,3.56 +czech +no_defs"; diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG102757.js b/ajax/libs/proj4js/1.1.0/defs/EPSG102757.js new file mode 100755 index 000000000..4685c2166 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG102757.js @@ -0,0 +1 @@ +Proj4js.defs["EPSG:102757"] = "+title=NAD 1983 StatePlane Wyoming West Central FIPS 4903 Feet +proj=tmerc +lat_0=40.5 +lon_0=-108.75 +x_0=600000.0 +y_0=0 +k=0.999938 +a=6378137.0 +b=6356752.3141403 +to_meter=0.3048006096012192"; diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG102758.js b/ajax/libs/proj4js/1.1.0/defs/EPSG102758.js new file mode 100755 index 000000000..ba07ea238 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG102758.js @@ -0,0 +1 @@ +Proj4js.defs["EPSG:102758"] = "+title=NAD 1983 StatePlane Wyoming West FIPS 4904 Feet +proj=tmerc +lat_0=40.5 +lon_0=-110.0833333333333 +x_0=800000 +y_0=100000 +k=0.999938 +a=6378137.0 +b=6356752.3141403 +to_meter=0.3048006096012192"; diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG21781.js b/ajax/libs/proj4js/1.1.0/defs/EPSG21781.js new file mode 100755 index 000000000..c81c87a76 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG21781.js @@ -0,0 +1 @@ +Proj4js.defs["EPSG:21781"] = "+title=CH1903 / LV03 +proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +x_0=600000 +y_0=200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs"; diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG26591.js b/ajax/libs/proj4js/1.1.0/defs/EPSG26591.js new file mode 100755 index 000000000..1af025566 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG26591.js @@ -0,0 +1 @@ +Proj4js.defs["EPSG:26591"] = "+title= Monte Mario (Rome) / Italy zone 1 EPSG:26591 +proj=tmerc +lat_0=0 +lon_0=-3.45233333333333 +from_greenwich=12.45233333333333 +k=0.999600 +x_0=1500000 +y_0=0 +a=6378388.0, +b=6356911.94612795 +units=m"; diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG26912.js b/ajax/libs/proj4js/1.1.0/defs/EPSG26912.js new file mode 100755 index 000000000..ee8473c82 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG26912.js @@ -0,0 +1 @@ +Proj4js.defs["EPSG26912"] = "+title=NAD83 / UTM zone 12N +proj=utm +zone=12 +a=6378137.0 +b=6356752.3141403"; diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG27200.js b/ajax/libs/proj4js/1.1.0/defs/EPSG27200.js new file mode 100755 index 000000000..5f0ea891c --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG27200.js @@ -0,0 +1,5 @@ +Proj4js.defs["EPSG:27200"] = "+title=New Zealand Map Grid\ + +proj=nzmg \ + +lat_0=-41 +lon_0=173 \ + +x_0=2510000 +y_0=6023150 \ + +ellps=intl +datum=nzgd49 +units=m +no_defs" diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG27563.js b/ajax/libs/proj4js/1.1.0/defs/EPSG27563.js new file mode 100755 index 000000000..d798a14b5 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG27563.js @@ -0,0 +1 @@ +Proj4js.defs["EPSG:27563"]="+title=NTF (Paris)/Lambert Sud France +proj=lcc +lat_1=44.10000000000001 +lat_0=44.10000000000001 +lon_0=0 +k_0=0.9998774990000001 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs "; diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG41001.js b/ajax/libs/proj4js/1.1.0/defs/EPSG41001.js new file mode 100755 index 000000000..65db92196 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG41001.js @@ -0,0 +1 @@ +Proj4js.defs["EPSG:41001"] = "+title=simple mercator EPSG:41001 +proj=merc +lat_ts=0 +lon_0=0 +k=1.000000 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m"; diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG4139.js b/ajax/libs/proj4js/1.1.0/defs/EPSG4139.js new file mode 100755 index 000000000..1f543df39 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG4139.js @@ -0,0 +1 @@ +Proj4js.defs["EPSG:4139"] = "+title=Puerto Rico EPSG:4139 (3 param datum shift) +proj=longlat +towgs84 = 11,72,-101,0,0,0,0 +a=6378206.4 +b=6356583.8"; diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG4181.js b/ajax/libs/proj4js/1.1.0/defs/EPSG4181.js new file mode 100755 index 000000000..5804a3b44 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG4181.js @@ -0,0 +1 @@ +Proj4js.defs["EPSG:4181"] = "+title=Luxembourg 1930 EPSG:4181 (7 param datum shift) +proj=longlat +towgs84=-193,13.7,-39.3,-0.41,-2.933,2.688,0.43 +a=6378388.0, +b=6356911.94612795"; diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG42304.js b/ajax/libs/proj4js/1.1.0/defs/EPSG42304.js new file mode 100755 index 000000000..91a220e11 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG42304.js @@ -0,0 +1 @@ +Proj4js.defs["EPSG:42304"]="+title=Atlas of Canada, LCC +proj=lcc +lat_1=49 +lat_2=77 +lat_0=49 +lon_0=-95 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m +no_defs"; \ No newline at end of file diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG4272.js b/ajax/libs/proj4js/1.1.0/defs/EPSG4272.js new file mode 100755 index 000000000..55cda903e --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG4272.js @@ -0,0 +1 @@ +Proj4js.defs["EPSG:4272"] = "+title=NZGD49 +proj=longlat +ellps=intl +datum=nzgd49 +no_defs "; diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG4302.js b/ajax/libs/proj4js/1.1.0/defs/EPSG4302.js new file mode 100755 index 000000000..4c875dad5 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG4302.js @@ -0,0 +1,2 @@ +Proj4js.defs["EPSG:4302"] = "+title=Trinidad 1903 EPSG:4302 (7 param datum shift) +proj=longlat +a=6378293.63683822 +b=6356617.979337744 +towgs84=-61.702,284.488,472.052,0,0,0,0"; + diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG900913.js b/ajax/libs/proj4js/1.1.0/defs/EPSG900913.js new file mode 100755 index 000000000..d129b480b --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG900913.js @@ -0,0 +1,5 @@ +// Google Mercator projection +// Used in combination with GoogleMercator layer type in OpenLayers +//+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs + +Proj4js.defs["EPSG:900913"]= "+title=GoogleMercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs"; diff --git a/ajax/libs/proj4js/1.1.0/defs/EPSG900913.txt b/ajax/libs/proj4js/1.1.0/defs/EPSG900913.txt new file mode 100755 index 000000000..54016a400 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/EPSG900913.txt @@ -0,0 +1,11 @@ +// Google Mercator projection +// Used in combination with GoogleMercator layer type in OpenLayers +//+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs + +csList.EPSG900913= "\ + +title= Google Mercator EPSG:900913\ + +proj=merc +a=6378137 +b=6378137 \ + +lat_ts=0.0 +lon_0=0.0 \ + +x_0=0.0 +y_0=0 +k=1.0 \ + +units=m +nadgrids=@null +no_defs \ +"; diff --git a/ajax/libs/proj4js/1.1.0/defs/GOOGLE.js b/ajax/libs/proj4js/1.1.0/defs/GOOGLE.js new file mode 100755 index 000000000..cdb075aec --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/defs/GOOGLE.js @@ -0,0 +1,2 @@ +Proj4js.defs["GOOGLE"]="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs"; +Proj4js.defs["EPSG:900913"]=Proj4js.defs["GOOGLE"]; diff --git a/ajax/libs/proj4js/1.1.0/proj4js-combined.js b/ajax/libs/proj4js/1.1.0/proj4js-combined.js new file mode 100755 index 000000000..49a303a4a --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/proj4js-combined.js @@ -0,0 +1,5438 @@ +/* + proj4js.js -- Javascript reprojection library. + + Authors: Mike Adair madairATdmsolutions.ca + Richard Greenwood richATgreenwoodmap.com + Didier Richard didier.richardATign.fr + Stephen Irons stephen.ironsATclear.net.nz + Olivier Terral oterralATgmail.com + + License: + Copyright (c) 2012, Mike Adair, Richard Greenwood, Didier Richard, + Stephen Irons and Olivier Terral + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Note: This program is an almost direct port of the C library PROJ.4. +*/ +/* ====================================================================== + proj4js.js + ====================================================================== */ + +/* +Author: Mike Adair madairATdmsolutions.ca + Richard Greenwood rich@greenwoodmap.com +License: LGPL as per: http://www.gnu.org/copyleft/lesser.html + +$Id: Proj.js 2956 2007-07-09 12:17:52Z steven $ +*/ + +/** + * Namespace: Proj4js + * + * Proj4js is a JavaScript library to transform point coordinates from one + * coordinate system to another, including datum transformations. + * + * This library is a port of both the Proj.4 and GCTCP C libraries to JavaScript. + * Enabling these transformations in the browser allows geographic data stored + * in different projections to be combined in browser-based web mapping + * applications. + * + * Proj4js must have access to coordinate system initialization strings (which + * are the same as for PROJ.4 command line). Thes can be included in your + * application using a + + def is a CS definition in PROJ.4 WKT format, for example: + +proj="tmerc" //longlat, etc. + +a=majorRadius + +b=minorRadius + +lat0=somenumber + +long=somenumber +*/ +Proj4js.defs = { + // These are so widely used, we'll go ahead and throw them in + // without requiring a separate .js file + 'WGS84': "+title=long/lat:WGS84 +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees", + 'EPSG:4326': "+title=long/lat:WGS84 +proj=longlat +a=6378137.0 +b=6356752.31424518 +ellps=WGS84 +datum=WGS84 +units=degrees", + 'EPSG:4269': "+title=long/lat:NAD83 +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees", + 'EPSG:3875': "+title= Google Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs" +}; +Proj4js.defs['EPSG:3785'] = Proj4js.defs['EPSG:3875']; //maintain backward compat, official code is 3875 +Proj4js.defs['GOOGLE'] = Proj4js.defs['EPSG:3875']; +Proj4js.defs['EPSG:900913'] = Proj4js.defs['EPSG:3875']; +Proj4js.defs['EPSG:102113'] = Proj4js.defs['EPSG:3875']; + +Proj4js.common = { + PI : 3.141592653589793238, //Math.PI, + HALF_PI : 1.570796326794896619, //Math.PI*0.5, + TWO_PI : 6.283185307179586477, //Math.PI*2, + FORTPI : 0.78539816339744833, + R2D : 57.29577951308232088, + D2R : 0.01745329251994329577, + SEC_TO_RAD : 4.84813681109535993589914102357e-6, /* SEC_TO_RAD = Pi/180/3600 */ + EPSLN : 1.0e-10, + MAX_ITER : 20, + // following constants from geocent.c + COS_67P5 : 0.38268343236508977, /* cosine of 67.5 degrees */ + AD_C : 1.0026000, /* Toms region 1 constant */ + + /* datum_type values */ + PJD_UNKNOWN : 0, + PJD_3PARAM : 1, + PJD_7PARAM : 2, + PJD_GRIDSHIFT: 3, + PJD_WGS84 : 4, // WGS84 or equivalent + PJD_NODATUM : 5, // WGS84 or equivalent + SRS_WGS84_SEMIMAJOR : 6378137.0, // only used in grid shift transforms + + // ellipoid pj_set_ell.c + SIXTH : .1666666666666666667, /* 1/6 */ + RA4 : .04722222222222222222, /* 17/360 */ + RA6 : .02215608465608465608, /* 67/3024 */ + RV4 : .06944444444444444444, /* 5/72 */ + RV6 : .04243827160493827160, /* 55/1296 */ + +// Function to compute the constant small m which is the radius of +// a parallel of latitude, phi, divided by the semimajor axis. +// ----------------------------------------------------------------- + msfnz : function(eccent, sinphi, cosphi) { + var con = eccent * sinphi; + return cosphi/(Math.sqrt(1.0 - con * con)); + }, + +// Function to compute the constant small t for use in the forward +// computations in the Lambert Conformal Conic and the Polar +// Stereographic projections. +// ----------------------------------------------------------------- + tsfnz : function(eccent, phi, sinphi) { + var con = eccent * sinphi; + var com = .5 * eccent; + con = Math.pow(((1.0 - con) / (1.0 + con)), com); + return (Math.tan(.5 * (this.HALF_PI - phi))/con); + }, + +// Function to compute the latitude angle, phi2, for the inverse of the +// Lambert Conformal Conic and Polar Stereographic projections. +// ---------------------------------------------------------------- + phi2z : function(eccent, ts) { + var eccnth = .5 * eccent; + var con, dphi; + var phi = this.HALF_PI - 2 * Math.atan(ts); + for (var i = 0; i <= 15; i++) { + con = eccent * Math.sin(phi); + dphi = this.HALF_PI - 2 * Math.atan(ts *(Math.pow(((1.0 - con)/(1.0 + con)),eccnth))) - phi; + phi += dphi; + if (Math.abs(dphi) <= .0000000001) return phi; + } + alert("phi2z has NoConvergence"); + return (-9999); + }, + +/* Function to compute constant small q which is the radius of a + parallel of latitude, phi, divided by the semimajor axis. +------------------------------------------------------------*/ + qsfnz : function(eccent,sinphi) { + var con; + if (eccent > 1.0e-7) { + con = eccent * sinphi; + return (( 1.0- eccent * eccent) * (sinphi /(1.0 - con * con) - (.5/eccent)*Math.log((1.0 - con)/(1.0 + con)))); + } else { + return(2.0 * sinphi); + } + }, + +/* Function to eliminate roundoff errors in asin +----------------------------------------------*/ + asinz : function(x) { + if (Math.abs(x)>1.0) { + x=(x>1.0)?1.0:-1.0; + } + return Math.asin(x); + }, + +// following functions from gctpc cproj.c for transverse mercator projections + e0fn : function(x) {return(1.0-0.25*x*(1.0+x/16.0*(3.0+1.25*x)));}, + e1fn : function(x) {return(0.375*x*(1.0+0.25*x*(1.0+0.46875*x)));}, + e2fn : function(x) {return(0.05859375*x*x*(1.0+0.75*x));}, + e3fn : function(x) {return(x*x*x*(35.0/3072.0));}, + mlfn : function(e0,e1,e2,e3,phi) {return(e0*phi-e1*Math.sin(2.0*phi)+e2*Math.sin(4.0*phi)-e3*Math.sin(6.0*phi));}, + + srat : function(esinp, exp) { + return(Math.pow((1.0-esinp)/(1.0+esinp), exp)); + }, + +// Function to return the sign of an argument + sign : function(x) { if (x < 0.0) return(-1); else return(1);}, + +// Function to adjust longitude to -180 to 180; input in radians + adjust_lon : function(x) { + x = (Math.abs(x) < this.PI) ? x: (x - (this.sign(x)*this.TWO_PI) ); + return x; + }, + +// IGNF - DGR : algorithms used by IGN France + +// Function to adjust latitude to -90 to 90; input in radians + adjust_lat : function(x) { + x= (Math.abs(x) < this.HALF_PI) ? x: (x - (this.sign(x)*this.PI) ); + return x; + }, + +// Latitude Isometrique - close to tsfnz ... + latiso : function(eccent, phi, sinphi) { + if (Math.abs(phi) > this.HALF_PI) return +Number.NaN; + if (phi==this.HALF_PI) return Number.POSITIVE_INFINITY; + if (phi==-1.0*this.HALF_PI) return -1.0*Number.POSITIVE_INFINITY; + + var con= eccent*sinphi; + return Math.log(Math.tan((this.HALF_PI+phi)/2.0))+eccent*Math.log((1.0-con)/(1.0+con))/2.0; + }, + + fL : function(x,L) { + return 2.0*Math.atan(x*Math.exp(L)) - this.HALF_PI; + }, + +// Inverse Latitude Isometrique - close to ph2z + invlatiso : function(eccent, ts) { + var phi= this.fL(1.0,ts); + var Iphi= 0.0; + var con= 0.0; + do { + Iphi= phi; + con= eccent*Math.sin(Iphi); + phi= this.fL(Math.exp(eccent*Math.log((1.0+con)/(1.0-con))/2.0),ts) + } while (Math.abs(phi-Iphi)>1.0e-12); + return phi; + }, + +// Needed for Gauss Schreiber +// Original: Denis Makarov (info@binarythings.com) +// Web Site: http://www.binarythings.com + sinh : function(x) + { + var r= Math.exp(x); + r= (r-1.0/r)/2.0; + return r; + }, + + cosh : function(x) + { + var r= Math.exp(x); + r= (r+1.0/r)/2.0; + return r; + }, + + tanh : function(x) + { + var r= Math.exp(x); + r= (r-1.0/r)/(r+1.0/r); + return r; + }, + + asinh : function(x) + { + var s= (x>= 0? 1.0:-1.0); + return s*(Math.log( Math.abs(x) + Math.sqrt(x*x+1.0) )); + }, + + acosh : function(x) + { + return 2.0*Math.log(Math.sqrt((x+1.0)/2.0) + Math.sqrt((x-1.0)/2.0)); + }, + + atanh : function(x) + { + return Math.log((x-1.0)/(x+1.0))/2.0; + }, + +// Grande Normale + gN : function(a,e,sinphi) + { + var temp= e*sinphi; + return a/Math.sqrt(1.0 - temp*temp); + }, + + //code from the PROJ.4 pj_mlfn.c file; this may be useful for other projections + pj_enfn: function(es) { + var en = new Array(); + en[0] = this.C00 - es * (this.C02 + es * (this.C04 + es * (this.C06 + es * this.C08))); + en[1] = es * (this.C22 - es * (this.C04 + es * (this.C06 + es * this.C08))); + var t = es * es; + en[2] = t * (this.C44 - es * (this.C46 + es * this.C48)); + t *= es; + en[3] = t * (this.C66 - es * this.C68); + en[4] = t * es * this.C88; + return en; + }, + + pj_mlfn: function(phi, sphi, cphi, en) { + cphi *= sphi; + sphi *= sphi; + return(en[0] * phi - cphi * (en[1] + sphi*(en[2]+ sphi*(en[3] + sphi*en[4])))); + }, + + pj_inv_mlfn: function(arg, es, en) { + var k = 1./(1.-es); + var phi = arg; + for (var i = Proj4js.common.MAX_ITER; i ; --i) { /* rarely goes over 2 iterations */ + var s = Math.sin(phi); + var t = 1. - es * s * s; + //t = this.pj_mlfn(phi, s, Math.cos(phi), en) - arg; + //phi -= t * (t * Math.sqrt(t)) * k; + t = (this.pj_mlfn(phi, s, Math.cos(phi), en) - arg) * (t * Math.sqrt(t)) * k; + phi -= t; + if (Math.abs(t) < Proj4js.common.EPSLN) + return phi; + } + Proj4js.reportError("cass:pj_inv_mlfn: Convergence error"); + return phi; + }, + +/* meridinal distance for ellipsoid and inverse +** 8th degree - accurate to < 1e-5 meters when used in conjuction +** with typical major axis values. +** Inverse determines phi to EPS (1e-11) radians, about 1e-6 seconds. +*/ + C00: 1.0, + C02: .25, + C04: .046875, + C06: .01953125, + C08: .01068115234375, + C22: .75, + C44: .46875, + C46: .01302083333333333333, + C48: .00712076822916666666, + C66: .36458333333333333333, + C68: .00569661458333333333, + C88: .3076171875 + +}; + +/** datum object +*/ +Proj4js.datum = Proj4js.Class({ + + initialize : function(proj) { + this.datum_type = Proj4js.common.PJD_WGS84; //default setting + if (proj.datumCode && proj.datumCode == 'none') { + this.datum_type = Proj4js.common.PJD_NODATUM; + } + if (proj && proj.datum_params) { + for (var i=0; i 3) { + if (proj.datum_params[3] != 0 || proj.datum_params[4] != 0 || + proj.datum_params[5] != 0 || proj.datum_params[6] != 0 ) { + this.datum_type = Proj4js.common.PJD_7PARAM; + proj.datum_params[3] *= Proj4js.common.SEC_TO_RAD; + proj.datum_params[4] *= Proj4js.common.SEC_TO_RAD; + proj.datum_params[5] *= Proj4js.common.SEC_TO_RAD; + proj.datum_params[6] = (proj.datum_params[6]/1000000.0) + 1.0; + } + } + } + if (proj) { + this.a = proj.a; //datum object also uses these values + this.b = proj.b; + this.es = proj.es; + this.ep2 = proj.ep2; + this.datum_params = proj.datum_params; + } + }, + + /****************************************************************/ + // cs_compare_datums() + // Returns TRUE if the two datums match, otherwise FALSE. + compare_datums : function( dest ) { + if( this.datum_type != dest.datum_type ) { + return false; // false, datums are not equal + } else if( this.a != dest.a || Math.abs(this.es-dest.es) > 0.000000000050 ) { + // the tolerence for es is to ensure that GRS80 and WGS84 + // are considered identical + return false; + } else if( this.datum_type == Proj4js.common.PJD_3PARAM ) { + return (this.datum_params[0] == dest.datum_params[0] + && this.datum_params[1] == dest.datum_params[1] + && this.datum_params[2] == dest.datum_params[2]); + } else if( this.datum_type == Proj4js.common.PJD_7PARAM ) { + return (this.datum_params[0] == dest.datum_params[0] + && this.datum_params[1] == dest.datum_params[1] + && this.datum_params[2] == dest.datum_params[2] + && this.datum_params[3] == dest.datum_params[3] + && this.datum_params[4] == dest.datum_params[4] + && this.datum_params[5] == dest.datum_params[5] + && this.datum_params[6] == dest.datum_params[6]); + } else if ( this.datum_type == Proj4js.common.PJD_GRIDSHIFT || + dest.datum_type == Proj4js.common.PJD_GRIDSHIFT ) { + alert("ERROR: Grid shift transformations are not implemented."); + return false + } else { + return true; // datums are equal + } + }, // cs_compare_datums() + + /* + * The function Convert_Geodetic_To_Geocentric converts geodetic coordinates + * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z), + * according to the current ellipsoid parameters. + * + * Latitude : Geodetic latitude in radians (input) + * Longitude : Geodetic longitude in radians (input) + * Height : Geodetic height, in meters (input) + * X : Calculated Geocentric X coordinate, in meters (output) + * Y : Calculated Geocentric Y coordinate, in meters (output) + * Z : Calculated Geocentric Z coordinate, in meters (output) + * + */ + geodetic_to_geocentric : function(p) { + var Longitude = p.x; + var Latitude = p.y; + var Height = p.z ? p.z : 0; //Z value not always supplied + var X; // output + var Y; + var Z; + + var Error_Code=0; // GEOCENT_NO_ERROR; + var Rn; /* Earth radius at location */ + var Sin_Lat; /* Math.sin(Latitude) */ + var Sin2_Lat; /* Square of Math.sin(Latitude) */ + var Cos_Lat; /* Math.cos(Latitude) */ + + /* + ** Don't blow up if Latitude is just a little out of the value + ** range as it may just be a rounding issue. Also removed longitude + ** test, it should be wrapped by Math.cos() and Math.sin(). NFW for PROJ.4, Sep/2001. + */ + if( Latitude < -Proj4js.common.HALF_PI && Latitude > -1.001 * Proj4js.common.HALF_PI ) { + Latitude = -Proj4js.common.HALF_PI; + } else if( Latitude > Proj4js.common.HALF_PI && Latitude < 1.001 * Proj4js.common.HALF_PI ) { + Latitude = Proj4js.common.HALF_PI; + } else if ((Latitude < -Proj4js.common.HALF_PI) || (Latitude > Proj4js.common.HALF_PI)) { + /* Latitude out of range */ + Proj4js.reportError('geocent:lat out of range:'+Latitude); + return null; + } + + if (Longitude > Proj4js.common.PI) Longitude -= (2*Proj4js.common.PI); + Sin_Lat = Math.sin(Latitude); + Cos_Lat = Math.cos(Latitude); + Sin2_Lat = Sin_Lat * Sin_Lat; + Rn = this.a / (Math.sqrt(1.0e0 - this.es * Sin2_Lat)); + X = (Rn + Height) * Cos_Lat * Math.cos(Longitude); + Y = (Rn + Height) * Cos_Lat * Math.sin(Longitude); + Z = ((Rn * (1 - this.es)) + Height) * Sin_Lat; + + p.x = X; + p.y = Y; + p.z = Z; + return Error_Code; + }, // cs_geodetic_to_geocentric() + + + geocentric_to_geodetic : function (p) { +/* local defintions and variables */ +/* end-criterium of loop, accuracy of sin(Latitude) */ +var genau = 1.E-12; +var genau2 = (genau*genau); +var maxiter = 30; + + var P; /* distance between semi-minor axis and location */ + var RR; /* distance between center and location */ + var CT; /* sin of geocentric latitude */ + var ST; /* cos of geocentric latitude */ + var RX; + var RK; + var RN; /* Earth radius at location */ + var CPHI0; /* cos of start or old geodetic latitude in iterations */ + var SPHI0; /* sin of start or old geodetic latitude in iterations */ + var CPHI; /* cos of searched geodetic latitude */ + var SPHI; /* sin of searched geodetic latitude */ + var SDPHI; /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */ + var At_Pole; /* indicates location is in polar region */ + var iter; /* # of continous iteration, max. 30 is always enough (s.a.) */ + + var X = p.x; + var Y = p.y; + var Z = p.z ? p.z : 0.0; //Z value not always supplied + var Longitude; + var Latitude; + var Height; + + At_Pole = false; + P = Math.sqrt(X*X+Y*Y); + RR = Math.sqrt(X*X+Y*Y+Z*Z); + +/* special cases for latitude and longitude */ + if (P/this.a < genau) { + +/* special case, if P=0. (X=0., Y=0.) */ + At_Pole = true; + Longitude = 0.0; + +/* if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis + * of ellipsoid (=center of mass), Latitude becomes PI/2 */ + if (RR/this.a < genau) { + Latitude = Proj4js.common.HALF_PI; + Height = -this.b; + return; + } + } else { +/* ellipsoidal (geodetic) longitude + * interval: -PI < Longitude <= +PI */ + Longitude=Math.atan2(Y,X); + } + +/* -------------------------------------------------------------- + * Following iterative algorithm was developped by + * "Institut f�r Erdmessung", University of Hannover, July 1988. + * Internet: www.ife.uni-hannover.de + * Iterative computation of CPHI,SPHI and Height. + * Iteration of CPHI and SPHI to 10**-12 radian resp. + * 2*10**-7 arcsec. + * -------------------------------------------------------------- + */ + CT = Z/RR; + ST = P/RR; + RX = 1.0/Math.sqrt(1.0-this.es*(2.0-this.es)*ST*ST); + CPHI0 = ST*(1.0-this.es)*RX; + SPHI0 = CT*RX; + iter = 0; + +/* loop to find sin(Latitude) resp. Latitude + * until |sin(Latitude(iter)-Latitude(iter-1))| < genau */ + do + { + iter++; + RN = this.a/Math.sqrt(1.0-this.es*SPHI0*SPHI0); + +/* ellipsoidal (geodetic) height */ + Height = P*CPHI0+Z*SPHI0-RN*(1.0-this.es*SPHI0*SPHI0); + + RK = this.es*RN/(RN+Height); + RX = 1.0/Math.sqrt(1.0-RK*(2.0-RK)*ST*ST); + CPHI = ST*(1.0-RK)*RX; + SPHI = CT*RX; + SDPHI = SPHI*CPHI0-CPHI*SPHI0; + CPHI0 = CPHI; + SPHI0 = SPHI; + } + while (SDPHI*SDPHI > genau2 && iter < maxiter); + +/* ellipsoidal (geodetic) latitude */ + Latitude=Math.atan(SPHI/Math.abs(CPHI)); + + p.x = Longitude; + p.y = Latitude; + p.z = Height; + return p; + }, // cs_geocentric_to_geodetic() + + /** Convert_Geocentric_To_Geodetic + * The method used here is derived from 'An Improved Algorithm for + * Geocentric to Geodetic Coordinate Conversion', by Ralph Toms, Feb 1996 + */ + geocentric_to_geodetic_noniter : function (p) { + var X = p.x; + var Y = p.y; + var Z = p.z ? p.z : 0; //Z value not always supplied + var Longitude; + var Latitude; + var Height; + + var W; /* distance from Z axis */ + var W2; /* square of distance from Z axis */ + var T0; /* initial estimate of vertical component */ + var T1; /* corrected estimate of vertical component */ + var S0; /* initial estimate of horizontal component */ + var S1; /* corrected estimate of horizontal component */ + var Sin_B0; /* Math.sin(B0), B0 is estimate of Bowring aux variable */ + var Sin3_B0; /* cube of Math.sin(B0) */ + var Cos_B0; /* Math.cos(B0) */ + var Sin_p1; /* Math.sin(phi1), phi1 is estimated latitude */ + var Cos_p1; /* Math.cos(phi1) */ + var Rn; /* Earth radius at location */ + var Sum; /* numerator of Math.cos(phi1) */ + var At_Pole; /* indicates location is in polar region */ + + X = parseFloat(X); // cast from string to float + Y = parseFloat(Y); + Z = parseFloat(Z); + + At_Pole = false; + if (X != 0.0) + { + Longitude = Math.atan2(Y,X); + } + else + { + if (Y > 0) + { + Longitude = Proj4js.common.HALF_PI; + } + else if (Y < 0) + { + Longitude = -Proj4js.common.HALF_PI; + } + else + { + At_Pole = true; + Longitude = 0.0; + if (Z > 0.0) + { /* north pole */ + Latitude = Proj4js.common.HALF_PI; + } + else if (Z < 0.0) + { /* south pole */ + Latitude = -Proj4js.common.HALF_PI; + } + else + { /* center of earth */ + Latitude = Proj4js.common.HALF_PI; + Height = -this.b; + return; + } + } + } + W2 = X*X + Y*Y; + W = Math.sqrt(W2); + T0 = Z * Proj4js.common.AD_C; + S0 = Math.sqrt(T0 * T0 + W2); + Sin_B0 = T0 / S0; + Cos_B0 = W / S0; + Sin3_B0 = Sin_B0 * Sin_B0 * Sin_B0; + T1 = Z + this.b * this.ep2 * Sin3_B0; + Sum = W - this.a * this.es * Cos_B0 * Cos_B0 * Cos_B0; + S1 = Math.sqrt(T1*T1 + Sum * Sum); + Sin_p1 = T1 / S1; + Cos_p1 = Sum / S1; + Rn = this.a / Math.sqrt(1.0 - this.es * Sin_p1 * Sin_p1); + if (Cos_p1 >= Proj4js.common.COS_67P5) + { + Height = W / Cos_p1 - Rn; + } + else if (Cos_p1 <= -Proj4js.common.COS_67P5) + { + Height = W / -Cos_p1 - Rn; + } + else + { + Height = Z / Sin_p1 + Rn * (this.es - 1.0); + } + if (At_Pole == false) + { + Latitude = Math.atan(Sin_p1 / Cos_p1); + } + + p.x = Longitude; + p.y = Latitude; + p.z = Height; + return p; + }, // geocentric_to_geodetic_noniter() + + /****************************************************************/ + // pj_geocentic_to_wgs84( p ) + // p = point to transform in geocentric coordinates (x,y,z) + geocentric_to_wgs84 : function ( p ) { + + if( this.datum_type == Proj4js.common.PJD_3PARAM ) + { + // if( x[io] == HUGE_VAL ) + // continue; + p.x += this.datum_params[0]; + p.y += this.datum_params[1]; + p.z += this.datum_params[2]; + + } + else if (this.datum_type == Proj4js.common.PJD_7PARAM) + { + var Dx_BF =this.datum_params[0]; + var Dy_BF =this.datum_params[1]; + var Dz_BF =this.datum_params[2]; + var Rx_BF =this.datum_params[3]; + var Ry_BF =this.datum_params[4]; + var Rz_BF =this.datum_params[5]; + var M_BF =this.datum_params[6]; + // if( x[io] == HUGE_VAL ) + // continue; + var x_out = M_BF*( p.x - Rz_BF*p.y + Ry_BF*p.z) + Dx_BF; + var y_out = M_BF*( Rz_BF*p.x + p.y - Rx_BF*p.z) + Dy_BF; + var z_out = M_BF*(-Ry_BF*p.x + Rx_BF*p.y + p.z) + Dz_BF; + p.x = x_out; + p.y = y_out; + p.z = z_out; + } + }, // cs_geocentric_to_wgs84 + + /****************************************************************/ + // pj_geocentic_from_wgs84() + // coordinate system definition, + // point to transform in geocentric coordinates (x,y,z) + geocentric_from_wgs84 : function( p ) { + + if( this.datum_type == Proj4js.common.PJD_3PARAM ) + { + //if( x[io] == HUGE_VAL ) + // continue; + p.x -= this.datum_params[0]; + p.y -= this.datum_params[1]; + p.z -= this.datum_params[2]; + + } + else if (this.datum_type == Proj4js.common.PJD_7PARAM) + { + var Dx_BF =this.datum_params[0]; + var Dy_BF =this.datum_params[1]; + var Dz_BF =this.datum_params[2]; + var Rx_BF =this.datum_params[3]; + var Ry_BF =this.datum_params[4]; + var Rz_BF =this.datum_params[5]; + var M_BF =this.datum_params[6]; + var x_tmp = (p.x - Dx_BF) / M_BF; + var y_tmp = (p.y - Dy_BF) / M_BF; + var z_tmp = (p.z - Dz_BF) / M_BF; + //if( x[io] == HUGE_VAL ) + // continue; + + p.x = x_tmp + Rz_BF*y_tmp - Ry_BF*z_tmp; + p.y = -Rz_BF*x_tmp + y_tmp + Rx_BF*z_tmp; + p.z = Ry_BF*x_tmp - Rx_BF*y_tmp + z_tmp; + } //cs_geocentric_from_wgs84() + } +}); + +/** point object, nothing fancy, just allows values to be + passed back and forth by reference rather than by value. + Other point classes may be used as long as they have + x and y properties, which will get modified in the transform method. +*/ +Proj4js.Point = Proj4js.Class({ + + /** + * Constructor: Proj4js.Point + * + * Parameters: + * - x {float} or {Array} either the first coordinates component or + * the full coordinates + * - y {float} the second component + * - z {float} the third component, optional. + */ + initialize : function(x,y,z) { + if (typeof x == 'object') { + this.x = x[0]; + this.y = x[1]; + this.z = x[2] || 0.0; + } else if (typeof x == 'string' && typeof y == 'undefined') { + var coords = x.split(','); + this.x = parseFloat(coords[0]); + this.y = parseFloat(coords[1]); + this.z = parseFloat(coords[2]) || 0.0; + } else { + this.x = x; + this.y = y; + this.z = z || 0.0; + } + }, + + /** + * APIMethod: clone + * Build a copy of a Proj4js.Point object. + * + * Return: + * {Proj4js}.Point the cloned point. + */ + clone : function() { + return new Proj4js.Point(this.x, this.y, this.z); + }, + + /** + * APIMethod: toString + * Return a readable string version of the point + * + * Return: + * {String} String representation of Proj4js.Point object. + * (ex. "x=5,y=42") + */ + toString : function() { + return ("x=" + this.x + ",y=" + this.y); + }, + + /** + * APIMethod: toShortString + * Return a short string version of the point. + * + * Return: + * {String} Shortened String representation of Proj4js.Point object. + * (ex. "5, 42") + */ + toShortString : function() { + return (this.x + ", " + this.y); + } +}); + +Proj4js.PrimeMeridian = { + "greenwich": 0.0, //"0dE", + "lisbon": -9.131906111111, //"9d07'54.862\"W", + "paris": 2.337229166667, //"2d20'14.025\"E", + "bogota": -74.080916666667, //"74d04'51.3\"W", + "madrid": -3.687938888889, //"3d41'16.58\"W", + "rome": 12.452333333333, //"12d27'8.4\"E", + "bern": 7.439583333333, //"7d26'22.5\"E", + "jakarta": 106.807719444444, //"106d48'27.79\"E", + "ferro": -17.666666666667, //"17d40'W", + "brussels": 4.367975, //"4d22'4.71\"E", + "stockholm": 18.058277777778, //"18d3'29.8\"E", + "athens": 23.7163375, //"23d42'58.815\"E", + "oslo": 10.722916666667 //"10d43'22.5\"E" +}; + +Proj4js.Ellipsoid = { + "MERIT": {a:6378137.0, rf:298.257, ellipseName:"MERIT 1983"}, + "SGS85": {a:6378136.0, rf:298.257, ellipseName:"Soviet Geodetic System 85"}, + "GRS80": {a:6378137.0, rf:298.257222101, ellipseName:"GRS 1980(IUGG, 1980)"}, + "IAU76": {a:6378140.0, rf:298.257, ellipseName:"IAU 1976"}, + "airy": {a:6377563.396, b:6356256.910, ellipseName:"Airy 1830"}, + "APL4.": {a:6378137, rf:298.25, ellipseName:"Appl. Physics. 1965"}, + "NWL9D": {a:6378145.0, rf:298.25, ellipseName:"Naval Weapons Lab., 1965"}, + "mod_airy": {a:6377340.189, b:6356034.446, ellipseName:"Modified Airy"}, + "andrae": {a:6377104.43, rf:300.0, ellipseName:"Andrae 1876 (Den., Iclnd.)"}, + "aust_SA": {a:6378160.0, rf:298.25, ellipseName:"Australian Natl & S. Amer. 1969"}, + "GRS67": {a:6378160.0, rf:298.2471674270, 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, ellipseName:"Comm. des Poids et Mesures 1799"}, + "delmbr": {a:6376428.0, 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)"}, + "fschr60": {a:6378166.0, rf:298.3, ellipseName:"Fischer (Mercury Datum) 1960"}, + "fschr60m": {a:6378155.0, rf:298.3, ellipseName:"Fischer 1960"}, + "fschr68": {a:6378150.0, rf:298.3, ellipseName:"Fischer 1968"}, + "helmert": {a:6378200.0, rf:298.3, ellipseName:"Helmert 1906"}, + "hough": {a:6378270.0, rf:297.0, ellipseName:"Hough"}, + "intl": {a:6378388.0, rf:297.0, ellipseName:"International 1909 (Hayford)"}, + "kaula": {a:6378163.0, rf:298.24, ellipseName:"Kaula 1961"}, + "lerch": {a:6378139.0, rf:298.257, ellipseName:"Lerch 1979"}, + "mprts": {a:6397300.0, rf:191.0, ellipseName:"Maupertius 1738"}, + "new_intl": {a:6378157.5, b:6356772.2, ellipseName:"New International 1967"}, + "plessis": {a:6376523.0, rf:6355863.0, ellipseName:"Plessis 1817 (France)"}, + "krass": {a:6378245.0, rf:298.3, ellipseName:"Krassovsky, 1942"}, + "SEasia": {a:6378155.0, b:6356773.3205, ellipseName:"Southeast Asia"}, + "walbeck": {a:6376896.0, b:6355834.8467, ellipseName:"Walbeck"}, + "WGS60": {a:6378165.0, rf:298.3, ellipseName:"WGS 60"}, + "WGS66": {a:6378145.0, rf:298.25, ellipseName:"WGS 66"}, + "WGS72": {a:6378135.0, rf:298.26, ellipseName:"WGS 72"}, + "WGS84": {a:6378137.0, rf:298.257223563, ellipseName:"WGS 84"}, + "sphere": {a:6370997.0, b:6370997.0, ellipseName:"Normal Sphere (r=6370997)"} +}; + +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", 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"} +}; + +Proj4js.WGS84 = new Proj4js.Proj('WGS84'); +Proj4js.Datum['OSB36'] = Proj4js.Datum['OSGB36']; //as returned from spatialreference.org + +//lookup table to go from the projection name in WKT to the Proj4js projection name +//build this out as required +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" +}; + + +/* ====================================================================== + projCode/aea.js + ====================================================================== */ + +/******************************************************************************* +NAME ALBERS CONICAL EQUAL AREA + +PURPOSE: Transforms input longitude and latitude to Easting and Northing + for the Albers Conical Equal Area projection. The longitude + and latitude must be in radians. The Easting and Northing + values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +T. Mittan, Feb, 1992 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + + +Proj4js.Proj.aea = { + init : function() { + + if (Math.abs(this.lat1 + this.lat2) < Proj4js.common.EPSLN) { + Proj4js.reportError("aeaInitEqualLatitudes"); + return; + } + this.temp = this.b / this.a; + this.es = 1.0 - Math.pow(this.temp,2); + this.e3 = Math.sqrt(this.es); + + this.sin_po=Math.sin(this.lat1); + this.cos_po=Math.cos(this.lat1); + this.t1=this.sin_po; + this.con = this.sin_po; + this.ms1 = Proj4js.common.msfnz(this.e3,this.sin_po,this.cos_po); + this.qs1 = Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po); + + this.sin_po=Math.sin(this.lat2); + this.cos_po=Math.cos(this.lat2); + this.t2=this.sin_po; + this.ms2 = Proj4js.common.msfnz(this.e3,this.sin_po,this.cos_po); + this.qs2 = Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po); + + this.sin_po=Math.sin(this.lat0); + this.cos_po=Math.cos(this.lat0); + this.t3=this.sin_po; + this.qs0 = Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po); + + if (Math.abs(this.lat1 - this.lat2) > Proj4js.common.EPSLN) { + this.ns0 = (this.ms1 * this.ms1 - this.ms2 *this.ms2)/ (this.qs2 - this.qs1); + } else { + this.ns0 = this.con; + } + this.c = this.ms1 * this.ms1 + this.ns0 * this.qs1; + this.rh = this.a * Math.sqrt(this.c - this.ns0 * this.qs0)/this.ns0; + }, + +/* Albers Conical Equal Area forward equations--mapping lat,long to x,y + -------------------------------------------------------------------*/ + forward: function(p){ + + var lon=p.x; + var lat=p.y; + + this.sin_phi=Math.sin(lat); + this.cos_phi=Math.cos(lat); + + var qs = Proj4js.common.qsfnz(this.e3,this.sin_phi,this.cos_phi); + var rh1 =this.a * Math.sqrt(this.c - this.ns0 * qs)/this.ns0; + var theta = this.ns0 * Proj4js.common.adjust_lon(lon - this.long0); + var x = rh1 * Math.sin(theta) + this.x0; + var y = this.rh - rh1 * Math.cos(theta) + this.y0; + + p.x = x; + p.y = y; + return p; + }, + + + inverse: function(p) { + var rh1,qs,con,theta,lon,lat; + + p.x -= this.x0; + p.y = this.rh - p.y + this.y0; + if (this.ns0 >= 0) { + rh1 = Math.sqrt(p.x *p.x + p.y * p.y); + con = 1.0; + } else { + rh1 = -Math.sqrt(p.x * p.x + p.y *p.y); + con = -1.0; + } + theta = 0.0; + if (rh1 != 0.0) { + theta = Math.atan2(con * p.x, con * p.y); + } + con = rh1 * this.ns0 / this.a; + qs = (this.c - con * con) / this.ns0; + if (this.e3 >= 1e-10) { + con = 1 - .5 * (1.0 -this.es) * Math.log((1.0 - this.e3) / (1.0 + this.e3))/this.e3; + if (Math.abs(Math.abs(con) - Math.abs(qs)) > .0000000001 ) { + lat = this.phi1z(this.e3,qs); + } else { + if (qs >= 0) { + lat = .5 * Proj4js.common.PI; + } else { + lat = -.5 * Proj4js.common.PI; + } + } + } else { + lat = this.phi1z(this.e3,qs); + } + + lon = Proj4js.common.adjust_lon(theta/this.ns0 + this.long0); + p.x = lon; + p.y = lat; + return p; + }, + +/* Function to compute phi1, the latitude for the inverse of the + Albers Conical Equal-Area projection. +-------------------------------------------*/ + phi1z: function (eccent,qs) { + var sinphi, cosphi, con, com, dphi; + var phi = Proj4js.common.asinz(.5 * qs); + if (eccent < Proj4js.common.EPSLN) return phi; + + var eccnts = eccent * eccent; + for (var i = 1; i <= 25; i++) { + sinphi = Math.sin(phi); + cosphi = Math.cos(phi); + con = eccent * sinphi; + com = 1.0 - con * con; + dphi = .5 * com * com / cosphi * (qs / (1.0 - eccnts) - sinphi / com + .5 / eccent * Math.log((1.0 - con) / (1.0 + con))); + phi = phi + dphi; + if (Math.abs(dphi) <= 1e-7) return phi; + } + Proj4js.reportError("aea:phi1z:Convergence error"); + return null; + } + +}; + + + +/* ====================================================================== + projCode/sterea.js + ====================================================================== */ + + +Proj4js.Proj.sterea = { + dependsOn : 'gauss', + + init : function() { + Proj4js.Proj['gauss'].init.apply(this); + if (!this.rc) { + Proj4js.reportError("sterea:init:E_ERROR_0"); + return; + } + this.sinc0 = Math.sin(this.phic0); + this.cosc0 = Math.cos(this.phic0); + this.R2 = 2.0 * this.rc; + if (!this.title) this.title = "Oblique Stereographic Alternative"; + }, + + forward : function(p) { + var sinc, cosc, cosl, k; + p.x = Proj4js.common.adjust_lon(p.x-this.long0); /* adjust del longitude */ + Proj4js.Proj['gauss'].forward.apply(this, [p]); + sinc = Math.sin(p.y); + cosc = Math.cos(p.y); + cosl = Math.cos(p.x); + k = this.k0 * this.R2 / (1.0 + this.sinc0 * sinc + this.cosc0 * cosc * cosl); + p.x = k * cosc * Math.sin(p.x); + p.y = k * (this.cosc0 * sinc - this.sinc0 * cosc * cosl); + p.x = this.a * p.x + this.x0; + p.y = this.a * p.y + this.y0; + return p; + }, + + inverse : function(p) { + var sinc, cosc, lon, lat, rho; + p.x = (p.x - this.x0) / this.a; /* descale and de-offset */ + p.y = (p.y - this.y0) / this.a; + + p.x /= this.k0; + p.y /= this.k0; + if ( (rho = Math.sqrt(p.x*p.x + p.y*p.y)) ) { + var c = 2.0 * Math.atan2(rho, this.R2); + sinc = Math.sin(c); + cosc = Math.cos(c); + lat = Math.asin(cosc * this.sinc0 + p.y * sinc * this.cosc0 / rho); + lon = Math.atan2(p.x * sinc, rho * this.cosc0 * cosc - p.y * this.sinc0 * sinc); + } else { + lat = this.phic0; + lon = 0.; + } + + p.x = lon; + p.y = lat; + Proj4js.Proj['gauss'].inverse.apply(this,[p]); + p.x = Proj4js.common.adjust_lon(p.x + this.long0); /* adjust longitude to CM */ + return p; + } +}; + +/* ====================================================================== + projCode/poly.js + ====================================================================== */ + +/* Function to compute, phi4, the latitude for the inverse of the + Polyconic projection. +------------------------------------------------------------*/ +function phi4z (eccent,e0,e1,e2,e3,a,b,c,phi) { + var sinphi, sin2ph, tanphi, ml, mlp, con1, con2, con3, dphi, i; + + phi = a; + for (i = 1; i <= 15; i++) { + sinphi = Math.sin(phi); + tanphi = Math.tan(phi); + c = tanphi * Math.sqrt (1.0 - eccent * sinphi * sinphi); + sin2ph = Math.sin (2.0 * phi); + /* + ml = e0 * *phi - e1 * sin2ph + e2 * sin (4.0 * *phi); + mlp = e0 - 2.0 * e1 * cos (2.0 * *phi) + 4.0 * e2 * cos (4.0 * *phi); + */ + ml = e0 * phi - e1 * sin2ph + e2 * Math.sin (4.0 * phi) - e3 * Math.sin (6.0 * phi); + mlp = e0 - 2.0 * e1 * Math.cos (2.0 * phi) + 4.0 * e2 * Math.cos (4.0 * phi) - 6.0 * e3 * Math.cos (6.0 * phi); + con1 = 2.0 * ml + c * (ml * ml + b) - 2.0 * a * (c * ml + 1.0); + con2 = eccent * sin2ph * (ml * ml + b - 2.0 * a * ml) / (2.0 *c); + con3 = 2.0 * (a - ml) * (c * mlp - 2.0 / sin2ph) - 2.0 * mlp; + dphi = con1 / (con2 + con3); + phi += dphi; + if (Math.abs(dphi) <= .0000000001 ) return(phi); + } + Proj4js.reportError("phi4z: No convergence"); + return null; +} + + +/* Function to compute the constant e4 from the input of the eccentricity + of the spheroid, x. This constant is used in the Polar Stereographic + projection. +--------------------------------------------------------------------*/ +function e4fn(x) { + var con, com; + con = 1.0 + x; + com = 1.0 - x; + return (Math.sqrt((Math.pow(con,con))*(Math.pow(com,com)))); +} + + + + + +/******************************************************************************* +NAME POLYCONIC + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Polyconic projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +T. Mittan Mar, 1993 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + +Proj4js.Proj.poly = { + + /* Initialize the POLYCONIC projection + ----------------------------------*/ + init: function() { + var temp; /* temporary variable */ + if (this.lat0 == 0) this.lat0 = 90;//this.lat0 ca + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + this.temp = this.b / this.a; + this.es = 1.0 - Math.pow(this.temp,2);// devait etre dans tmerc.js mais n y est pas donc je commente sinon retour de valeurs nulles + 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);//si que des zeros le calcul ne se fait pas + //if (!this.ml0) {this.ml0=0;} + }, + + + /* Polyconic forward equations--mapping lat,long to x,y + ---------------------------------------------------*/ + forward: function(p) { + var sinphi, cosphi; /* sin and cos value */ + var al; /* temporary values */ + var c; /* temporary values */ + var con, ml; /* cone constant, small m */ + var ms; /* small m */ + var x,y; + + var lon=p.x; + var lat=p.y; + + con = Proj4js.common.adjust_lon(lon - this.long0); + if (Math.abs(lat) <= .0000001) { + x = this.x0 + this.a * con; + y = this.y0 - this.a * this.ml0; + } else { + sinphi = Math.sin(lat); + cosphi = Math.cos(lat); + + ml = Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, lat); + ms = Proj4js.common.msfnz(this.e,sinphi,cosphi); + con = sinphi; + x = this.x0 + this.a * ms * Math.sin(con)/sinphi; + y = this.y0 + this.a * (ml - this.ml0 + ms * (1.0 - Math.cos(con))/sinphi); + } + + p.x=x; + p.y=y; + return p; + }, + + + /* Inverse equations + -----------------*/ + inverse: function(p) { + var sin_phi, cos_phi; /* sin and cos value */ + var al; /* temporary values */ + var b; /* temporary values */ + var c; /* temporary values */ + var con, ml; /* cone constant, small m */ + var iflg; /* error flag */ + var lon,lat; + p.x -= this.x0; + p.y -= this.y0; + al = this.ml0 + p.y/this.a; + iflg = 0; + + if (Math.abs(al) <= .0000001) { + lon = p.x/this.a + this.long0; + lat = 0.0; + } else { + b = al * al + (p.x/this.a) * (p.x/this.a); + iflg = phi4z(this.es,this.e0,this.e1,this.e2,this.e3,this.al,b,c,lat); + if (iflg != 1) return(iflg); + lon = Proj4js.common.adjust_lon((Proj4js.common.asinz(p.x * c / this.a) / Math.sin(lat)) + this.long0); + } + + p.x=lon; + p.y=lat; + return p; + } +}; + + + +/* ====================================================================== + projCode/equi.js + ====================================================================== */ + +/******************************************************************************* +NAME EQUIRECTANGULAR + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Equirectangular projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +T. Mittan Mar, 1993 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ +Proj4js.Proj.equi = { + + init: function() { + if(!this.x0) this.x0=0; + if(!this.y0) this.y0=0; + if(!this.lat0) this.lat0=0; + if(!this.long0) this.long0=0; + ///this.t2; + }, + + + +/* Equirectangular forward equations--mapping lat,long to x,y + ---------------------------------------------------------*/ + forward: function(p) { + + var lon=p.x; + var lat=p.y; + + var dlon = Proj4js.common.adjust_lon(lon - this.long0); + var x = this.x0 +this. a * dlon *Math.cos(this.lat0); + var y = this.y0 + this.a * lat; + + this.t1=x; + this.t2=Math.cos(this.lat0); + p.x=x; + p.y=y; + return p; + }, //equiFwd() + + + +/* Equirectangular inverse equations--mapping x,y to lat/long + ---------------------------------------------------------*/ + inverse: function(p) { + + p.x -= this.x0; + p.y -= this.y0; + var lat = p.y /this. a; + + if ( Math.abs(lat) > Proj4js.common.HALF_PI) { + Proj4js.reportError("equi:Inv:DataError"); + } + var lon = Proj4js.common.adjust_lon(this.long0 + p.x / (this.a * Math.cos(this.lat0))); + p.x=lon; + p.y=lat; + }//equiInv() +}; + + +/* ====================================================================== + projCode/merc.js + ====================================================================== */ + +/******************************************************************************* +NAME MERCATOR + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Mercator projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +D. Steinwand, EROS Nov, 1991 +T. Mittan Mar, 1993 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + +//static double r_major = a; /* major axis */ +//static double r_minor = b; /* minor axis */ +//static double lon_center = long0; /* Center longitude (projection center) */ +//static double lat_origin = lat0; /* center latitude */ +//static double e,es; /* eccentricity constants */ +//static double m1; /* small value m */ +//static double false_northing = y0; /* y offset in meters */ +//static double false_easting = x0; /* x offset in meters */ +//scale_fact = k0 + +Proj4js.Proj.merc = { + init : function() { + //?this.temp = this.r_minor / this.r_major; + //this.temp = this.b / this.a; + //this.es = 1.0 - Math.sqrt(this.temp); + //this.e = Math.sqrt( this.es ); + //?this.m1 = Math.cos(this.lat_origin) / (Math.sqrt( 1.0 - this.es * Math.sin(this.lat_origin) * Math.sin(this.lat_origin))); + //this.m1 = Math.cos(0.0) / (Math.sqrt( 1.0 - this.es * Math.sin(0.0) * Math.sin(0.0))); + if (this.lat_ts) { + if (this.sphere) { + this.k0 = Math.cos(this.lat_ts); + } else { + this.k0 = Proj4js.common.msfnz(this.es, Math.sin(this.lat_ts), Math.cos(this.lat_ts)); + } + } + }, + +/* Mercator forward equations--mapping lat,long to x,y + --------------------------------------------------*/ + + forward : function(p) { + //alert("ll2m coords : "+coords); + var lon = p.x; + var lat = p.y; + // convert to radians + if ( lat*Proj4js.common.R2D > 90.0 && + lat*Proj4js.common.R2D < -90.0 && + lon*Proj4js.common.R2D > 180.0 && + lon*Proj4js.common.R2D < -180.0) { + Proj4js.reportError("merc:forward: llInputOutOfRange: "+ lon +" : " + lat); + return null; + } + + var x,y; + if(Math.abs( Math.abs(lat) - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN) { + Proj4js.reportError("merc:forward: ll2mAtPoles"); + return null; + } else { + if (this.sphere) { + x = this.x0 + this.a * this.k0 * Proj4js.common.adjust_lon(lon - this.long0); + y = this.y0 + this.a * this.k0 * Math.log(Math.tan(Proj4js.common.FORTPI + 0.5*lat)); + } else { + var sinphi = Math.sin(lat); + var ts = Proj4js.common.tsfnz(this.e,lat,sinphi); + x = this.x0 + this.a * this.k0 * Proj4js.common.adjust_lon(lon - this.long0); + y = this.y0 - this.a * this.k0 * Math.log(ts); + } + p.x = x; + p.y = y; + return p; + } + }, + + + /* Mercator inverse equations--mapping x,y to lat/long + --------------------------------------------------*/ + inverse : function(p) { + + var x = p.x - this.x0; + var y = p.y - this.y0; + var lon,lat; + + if (this.sphere) { + lat = Proj4js.common.HALF_PI - 2.0 * Math.atan(Math.exp(-y / this.a * this.k0)); + } else { + var ts = Math.exp(-y / (this.a * this.k0)); + lat = Proj4js.common.phi2z(this.e,ts); + if(lat == -9999) { + Proj4js.reportError("merc:inverse: lat = -9999"); + return null; + } + } + lon = Proj4js.common.adjust_lon(this.long0+ x / (this.a * this.k0)); + + p.x = lon; + p.y = lat; + return p; + } +}; + + +/* ====================================================================== + projCode/utm.js + ====================================================================== */ + +/******************************************************************************* +NAME TRANSVERSE MERCATOR + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Transverse Mercator projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + + +/** + Initialize Transverse Mercator projection +*/ + +Proj4js.Proj.utm = { + dependsOn : 'tmerc', + + init : function() { + if (!this.zone) { + Proj4js.reportError("utm:init: zone must be specified for UTM"); + return; + } + this.lat0 = 0.0; + this.long0 = ((6 * Math.abs(this.zone)) - 183) * Proj4js.common.D2R; + this.x0 = 500000.0; + this.y0 = this.utmSouth ? 10000000.0 : 0.0; + this.k0 = 0.9996; + + Proj4js.Proj['tmerc'].init.apply(this); + this.forward = Proj4js.Proj['tmerc'].forward; + this.inverse = Proj4js.Proj['tmerc'].inverse; + } +}; +/* ====================================================================== + projCode/eqdc.js + ====================================================================== */ + +/******************************************************************************* +NAME EQUIDISTANT CONIC + +PURPOSE: Transforms input longitude and latitude to Easting and Northing + for the Equidistant Conic projection. The longitude and + latitude must be in radians. The Easting and Northing values + will be returned in meters. + +PROGRAMMER DATE +---------- ---- +T. Mittan Mar, 1993 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + +/* Variables common to all subroutines in this code file + -----------------------------------------------------*/ + +Proj4js.Proj.eqdc = { + +/* Initialize the Equidistant Conic projection + ------------------------------------------*/ + init: function() { + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + + if(!this.mode) this.mode=0;//chosen default mode + this.temp = this.b / this.a; + this.es = 1.0 - 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); + + /* format B + ---------*/ + if (this.mode != 0) { + if (Math.abs(this.lat1 + this.lat2) < Proj4js.common.EPSLN) { + Proj4js.reportError("eqdc:Init:EqualLatitudes"); + //return(81); + } + this.sinphi=Math.sin(this.lat2); + this.cosphi=Math.cos(this.lat2); + + this.ms2 = Proj4js.common.msfnz(this.e,this.sinphi,this.cosphi); + this.ml2 = Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, this.lat2); + if (Math.abs(this.lat1 - this.lat2) >= Proj4js.common.EPSLN) { + this.ns = (this.ms1 - this.ms2) / (this.ml2 - this.ml1); + } else { + this.ns = this.sinphi; + } + } else { + this.ns = this.sinphi; + } + this.g = this.ml1 + this.ms1/this.ns; + this.ml0 = Proj4js.common.mlfn(this.e0, this.e1,this. e2, this.e3, this.lat0); + this.rh = this.a * (this.g - this.ml0); + }, + + +/* Equidistant Conic forward equations--mapping lat,long to x,y + -----------------------------------------------------------*/ + forward: function(p) { + var lon=p.x; + var lat=p.y; + + /* Forward equations + -----------------*/ + var ml = Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, lat); + var rh1 = this.a * (this.g - ml); + var theta = this.ns * Proj4js.common.adjust_lon(lon - this.long0); + + var x = this.x0 + rh1 * Math.sin(theta); + var y = this.y0 + this.rh - rh1 * Math.cos(theta); + p.x=x; + p.y=y; + return p; + }, + +/* Inverse equations + -----------------*/ + inverse: function(p) { + p.x -= this.x0; + p.y = this.rh - p.y + this.y0; + var con, rh1; + if (this.ns >= 0) { + rh1 = Math.sqrt(p.x *p.x + p.y * p.y); + con = 1.0; + } else { + rh1 = -Math.sqrt(p.x *p. x +p. y * p.y); + con = -1.0; + } + var theta = 0.0; + if (rh1 != 0.0) theta = Math.atan2(con *p.x, con *p.y); + var ml = this.g - rh1 /this.a; + var lat = this.phi3z(ml,this.e0,this.e1,this.e2,this.e3); + var lon = Proj4js.common.adjust_lon(this.long0 + theta / this.ns); + + p.x=lon; + p.y=lat; + return p; + }, + +/* Function to compute latitude, phi3, for the inverse of the Equidistant + Conic projection. +-----------------------------------------------------------------*/ + phi3z: function(ml,e0,e1,e2,e3) { + var phi; + var dphi; + + phi = ml; + for (var i = 0; i < 15; i++) { + dphi = (ml + e1 * Math.sin(2.0 * phi) - e2 * Math.sin(4.0 * phi) + e3 * Math.sin(6.0 * phi))/ e0 - phi; + phi += dphi; + if (Math.abs(dphi) <= .0000000001) { + return phi; + } + } + Proj4js.reportError("PHI3Z-CONV:Latitude failed to converge after 15 iterations"); + return null; + } + + +}; +/* ====================================================================== + projCode/tmerc.js + ====================================================================== */ + +/******************************************************************************* +NAME TRANSVERSE MERCATOR + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Transverse Mercator projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + + +/** + Initialize Transverse Mercator projection +*/ + +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); + }, + + /** + Transverse Mercator Forward - long/lat to x/y + long/lat in radians + */ + forward : function(p) { + var lon = p.x; + var lat = p.y; + + var delta_lon = Proj4js.common.adjust_lon(lon - this.long0); // Delta longitude + var con; // cone constant + var x, y; + var sin_phi=Math.sin(lat); + var cos_phi=Math.cos(lat); + + if (this.sphere) { /* spherical form */ + var b = cos_phi * Math.sin(delta_lon); + if ((Math.abs(Math.abs(b) - 1.0)) < .0000000001) { + Proj4js.reportError("tmerc:forward: Point projects into infinity"); + return(93); + } else { + x = .5 * this.a * this.k0 * Math.log((1.0 + b)/(1.0 - b)); + con = Math.acos(cos_phi * Math.cos(delta_lon)/Math.sqrt(1.0 - b*b)); + if (lat < 0) con = - con; + y = this.a * this.k0 * (con - this.lat0); + } + } else { + var al = cos_phi * delta_lon; + var als = Math.pow(al,2); + var c = this.ep2 * Math.pow(cos_phi,2); + var tq = Math.tan(lat); + var t = Math.pow(tq,2); + con = 1.0 - this.es * Math.pow(sin_phi,2); + var n = this.a / Math.sqrt(con); + var ml = this.a * Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, lat); + + x = this.k0 * n * al * (1.0 + als / 6.0 * (1.0 - t + c + als / 20.0 * (5.0 - 18.0 * t + Math.pow(t,2) + 72.0 * c - 58.0 * this.ep2))) + this.x0; + y = this.k0 * (ml - this.ml0 + n * tq * (als * (0.5 + als / 24.0 * (5.0 - t + 9.0 * c + 4.0 * Math.pow(c,2) + als / 30.0 * (61.0 - 58.0 * t + Math.pow(t,2) + 600.0 * c - 330.0 * this.ep2))))) + this.y0; + + } + p.x = x; p.y = y; + return p; + }, // tmercFwd() + + /** + Transverse Mercator Inverse - x/y to long/lat + */ + inverse : function(p) { + var con, phi; /* temporary angles */ + var delta_phi; /* difference between longitudes */ + var i; + var max_iter = 6; /* maximun number of iterations */ + var lat, lon; + + if (this.sphere) { /* spherical form */ + var f = Math.exp(p.x/(this.a * this.k0)); + var g = .5 * (f - 1/f); + var temp = this.lat0 + p.y/(this.a * this.k0); + var h = Math.cos(temp); + con = Math.sqrt((1.0 - h * h)/(1.0 + g * g)); + lat = Proj4js.common.asinz(con); + if (temp < 0) + lat = -lat; + if ((g == 0) && (h == 0)) { + lon = this.long0; + } else { + lon = Proj4js.common.adjust_lon(Math.atan2(g,h) + this.long0); + } + } else { // ellipsoidal form + var x = p.x - this.x0; + var y = p.y - this.y0; + + con = (this.ml0 + y / this.k0) / this.a; + phi = con; + for (i=0;true;i++) { + delta_phi=((con + this.e1 * Math.sin(2.0*phi) - this.e2 * Math.sin(4.0*phi) + this.e3 * Math.sin(6.0*phi)) / this.e0) - phi; + phi += delta_phi; + if (Math.abs(delta_phi) <= Proj4js.common.EPSLN) break; + if (i >= max_iter) { + Proj4js.reportError("tmerc:inverse: Latitude failed to converge"); + return(95); + } + } // for() + if (Math.abs(phi) < Proj4js.common.HALF_PI) { + // sincos(phi, &sin_phi, &cos_phi); + var sin_phi=Math.sin(phi); + var cos_phi=Math.cos(phi); + var tan_phi = Math.tan(phi); + var c = this.ep2 * Math.pow(cos_phi,2); + var cs = Math.pow(c,2); + var t = Math.pow(tan_phi,2); + var ts = Math.pow(t,2); + con = 1.0 - this.es * Math.pow(sin_phi,2); + var n = this.a / Math.sqrt(con); + var r = n * (1.0 - this.es) / con; + var d = x / (n * this.k0); + var ds = Math.pow(d,2); + lat = phi - (n * tan_phi * ds / r) * (0.5 - ds / 24.0 * (5.0 + 3.0 * t + 10.0 * c - 4.0 * cs - 9.0 * this.ep2 - ds / 30.0 * (61.0 + 90.0 * t + 298.0 * c + 45.0 * ts - 252.0 * this.ep2 - 3.0 * cs))); + lon = Proj4js.common.adjust_lon(this.long0 + (d * (1.0 - ds / 6.0 * (1.0 + 2.0 * t + c - ds / 20.0 * (5.0 - 2.0 * c + 28.0 * t - 3.0 * cs + 8.0 * this.ep2 + 24.0 * ts))) / cos_phi)); + } else { + lat = Proj4js.common.HALF_PI * Proj4js.common.sign(y); + lon = this.long0; + } + } + p.x = lon; + p.y = lat; + return p; + } // tmercInv() +}; +/* ====================================================================== + defs/GOOGLE.js + ====================================================================== */ + +Proj4js.defs["GOOGLE"]="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs"; +Proj4js.defs["EPSG:900913"]=Proj4js.defs["GOOGLE"]; +/* ====================================================================== + projCode/gstmerc.js + ====================================================================== */ + +Proj4js.Proj.gstmerc = { + init : function() { + + // array of: a, b, lon0, lat0, k0, x0, y0 + var temp= this.b / this.a; + this.e= Math.sqrt(1.0 - temp*temp); + this.lc= this.long0; + this.rs= Math.sqrt(1.0+this.e*this.e*Math.pow(Math.cos(this.lat0),4.0)/(1.0-this.e*this.e)); + var sinz= Math.sin(this.lat0); + var pc= Math.asin(sinz/this.rs); + var sinzpc= Math.sin(pc); + this.cp= Proj4js.common.latiso(0.0,pc,sinzpc)-this.rs*Proj4js.common.latiso(this.e,this.lat0,sinz); + this.n2= this.k0*this.a*Math.sqrt(1.0-this.e*this.e)/(1.0-this.e*this.e*sinz*sinz); + this.xs= this.x0; + this.ys= this.y0-this.n2*pc; + + if (!this.title) this.title = "Gauss Schreiber transverse mercator"; + }, + + + // forward equations--mapping lat,long to x,y + // ----------------------------------------------------------------- + forward : function(p) { + + var lon= p.x; + var lat= p.y; + + var L= this.rs*(lon-this.lc); + var Ls= this.cp+(this.rs*Proj4js.common.latiso(this.e,lat,Math.sin(lat))); + var lat1= Math.asin(Math.sin(L)/Proj4js.common.cosh(Ls)); + var Ls1= Proj4js.common.latiso(0.0,lat1,Math.sin(lat1)); + p.x= this.xs+(this.n2*Ls1); + p.y= this.ys+(this.n2*Math.atan(Proj4js.common.sinh(Ls)/Math.cos(L))); + return p; + }, + + // inverse equations--mapping x,y to lat/long + // ----------------------------------------------------------------- + inverse : function(p) { + + var x= p.x; + var y= p.y; + + var L= Math.atan(Proj4js.common.sinh((x-this.xs)/this.n2)/Math.cos((y-this.ys)/this.n2)); + var lat1= Math.asin(Math.sin((y-this.ys)/this.n2)/Proj4js.common.cosh((x-this.xs)/this.n2)); + var LC= Proj4js.common.latiso(0.0,lat1,Math.sin(lat1)); + p.x= this.lc+L/this.rs; + p.y= Proj4js.common.invlatiso(this.e,(LC-this.cp)/this.rs); + return p; + } + +}; +/* ====================================================================== + projCode/ortho.js + ====================================================================== */ + +/******************************************************************************* +NAME ORTHOGRAPHIC + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Orthographic projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +T. Mittan Mar, 1993 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + +Proj4js.Proj.ortho = { + + /* Initialize the Orthographic projection + -------------------------------------*/ + init: function(def) { + //double temp; /* temporary variable */ + + /* Place parameters in static storage for common use + -------------------------------------------------*/; + this.sin_p14=Math.sin(this.lat0); + this.cos_p14=Math.cos(this.lat0); + }, + + + /* Orthographic forward equations--mapping lat,long to x,y + ---------------------------------------------------*/ + forward: function(p) { + var sinphi, cosphi; /* sin and cos value */ + var dlon; /* delta longitude value */ + var coslon; /* cos of longitude */ + var ksp; /* scale factor */ + var g; + var lon=p.x; + var lat=p.y; + /* Forward equations + -----------------*/ + dlon = Proj4js.common.adjust_lon(lon - this.long0); + + sinphi=Math.sin(lat); + cosphi=Math.cos(lat); + + coslon = Math.cos(dlon); + g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon; + ksp = 1.0; + if ((g > 0) || (Math.abs(g) <= Proj4js.common.EPSLN)) { + var x = this.a * ksp * cosphi * Math.sin(dlon); + var y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon); + } else { + Proj4js.reportError("orthoFwdPointError"); + } + p.x=x; + p.y=y; + return p; + }, + + + inverse: function(p) { + var rh; /* height above ellipsoid */ + var z; /* angle */ + var sinz,cosz; /* sin of z and cos of z */ + var temp; + var con; + var lon , lat; + /* Inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + rh = Math.sqrt(p.x * p.x + p.y * p.y); + if (rh > this.a + .0000001) { + Proj4js.reportError("orthoInvDataError"); + } + z = Proj4js.common.asinz(rh / this.a); + + sinz=Math.sin(z); + cosz=Math.cos(z); + + lon = this.long0; + if (Math.abs(rh) <= Proj4js.common.EPSLN) { + lat = this.lat0; + } + lat = Proj4js.common.asinz(cosz * this.sin_p14 + (p.y * sinz * this.cos_p14)/rh); + con = Math.abs(this.lat0) - Proj4js.common.HALF_PI; + if (Math.abs(con) <= Proj4js.common.EPSLN) { + if (this.lat0 >= 0) { + lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2(p.x, -p.y)); + } else { + lon = Proj4js.common.adjust_lon(this.long0 -Math.atan2(-p.x, p.y)); + } + } + con = cosz - this.sin_p14 * Math.sin(lat); + p.x=lon; + p.y=lat; + return p; + } +}; + + +/* ====================================================================== + projCode/krovak.js + ====================================================================== */ + +/** + NOTES: According to EPSG the full Krovak projection method should have + the following parameters. Within PROJ.4 the azimuth, and pseudo + standard parallel are hardcoded in the algorithm and can't be + altered from outside. The others all have defaults to match the + common usage with Krovak projection. + + lat_0 = latitude of centre of the projection + + lon_0 = longitude of centre of the projection + + ** = azimuth (true) of the centre line passing through the centre of the projection + + ** = latitude of pseudo standard parallel + + k = scale factor on the pseudo standard parallel + + x_0 = False Easting of the centre of the projection at the apex of the cone + + y_0 = False Northing of the centre of the projection at the apex of the cone + + **/ + +Proj4js.Proj.krovak = { + + init: function() { + /* we want Bessel as fixed ellipsoid */ + this.a = 6377397.155; + this.es = 0.006674372230614; + this.e = Math.sqrt(this.es); + /* if latitude of projection center is not set, use 49d30'N */ + if (!this.lat0) { + this.lat0 = 0.863937979737193; + } + if (!this.long0) { + this.long0 = 0.7417649320975901 - 0.308341501185665; + } + /* if scale not set default to 0.9999 */ + if (!this.k0) { + this.k0 = 0.9999; + } + this.s45 = 0.785398163397448; /* 45° */ + this.s90 = 2 * this.s45; + this.fi0 = this.lat0; /* Latitude of projection centre 49° 30' */ + /* Ellipsoid Bessel 1841 a = 6377397.155m 1/f = 299.1528128, + e2=0.006674372230614; + */ + this.e2 = this.es; /* 0.006674372230614; */ + 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; /* DU(2, 59, 42, 42.69689) */ + this.u0 = Math.asin(Math.sin(this.fi0) / this.alfa); + this.g = Math.pow( (1. + this.e * Math.sin(this.fi0)) / (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; /* Latitude of pseudo standard parallel 78° 30'00" N */ + this.n = Math.sin(this.s0); + this.ro0 = this.k1 * this.n0 / Math.tan(this.s0); + this.ad = this.s90 - this.uq; + }, + + /* ellipsoid */ + /* calculate xy from lat/lon */ + /* Constants, identical to inverse transform function */ + forward: function(p) { + var gfi, u, deltav, s, d, eps, ro; + var lon = p.x; + var lat = p.y; + var delta_lon = Proj4js.common.adjust_lon(lon - this.long0); // Delta longitude + /* Transformation */ + gfi = Math.pow ( ((1. + this.e * Math.sin(lat)) / (1. - this.e * Math.sin(lat))) , (this.alfa * this.e / 2.)); + u= 2. * (Math.atan(this.k * Math.pow( Math.tan(lat / 2. + this.s45), this.alfa) / gfi)-this.s45); + deltav = - delta_lon * this.alfa; + s = Math.asin(Math.cos(this.ad) * Math.sin(u) + Math.sin(this.ad) * Math.cos(u) * Math.cos(deltav)); + d = Math.asin(Math.cos(u) * Math.sin(deltav) / Math.cos(s)); + eps = this.n * d; + ro = this.ro0 * Math.pow(Math.tan(this.s0 / 2. + this.s45) , this.n) / Math.pow(Math.tan(s / 2. + this.s45) , this.n); + /* x and y are reverted! */ + //p.y = ro * Math.cos(eps) / a; + //p.x = ro * Math.sin(eps) / a; + p.y = ro * Math.cos(eps) / 1.0; + p.x = ro * Math.sin(eps) / 1.0; + + if(this.czech) { + p.y *= -1.0; + p.x *= -1.0; + } + return (p); + }, + + /* calculate lat/lon from xy */ + inverse: function(p) { + /* Constants, identisch wie in der Umkehrfunktion */ + var u, deltav, s, d, eps, ro, fi1; + var ok; + + /* Transformation */ + /* revert y, x*/ + var tmp = p.x; + p.x=p.y; + p.y=tmp; + if(this.czech) { + p.y *= -1.0; + p.x *= -1.0; + } + ro = Math.sqrt(p.x * p.x + p.y * p.y); + eps = Math.atan2(p.y, p.x); + d = eps / Math.sin(this.s0); + s = 2. * (Math.atan( Math.pow(this.ro0 / ro, 1. / this.n) * Math.tan(this.s0 / 2. + this.s45)) - this.s45); + u = Math.asin(Math.cos(this.ad) * Math.sin(s) - Math.sin(this.ad) * Math.cos(s) * Math.cos(d)); + deltav = Math.asin(Math.cos(s) * Math.sin(d) / Math.cos(u)); + p.x = this.long0 - deltav / this.alfa; + /* ITERATION FOR lat */ + fi1 = u; + ok = 0; + var iter = 0; + do { + p.y = 2. * ( Math.atan( Math.pow( this.k, -1. / this.alfa) * + Math.pow( Math.tan(u / 2. + this.s45) , 1. / this.alfa) * + Math.pow( (1. + this.e * Math.sin(fi1)) / (1. - this.e * Math.sin(fi1)) , this.e / 2.) + ) - this.s45); + if (Math.abs(fi1 - p.y) < 0.0000000001) ok=1; + fi1 = p.y; + iter += 1; + } while (ok==0 && iter < 15); + if (iter >= 15) { + Proj4js.reportError("PHI3Z-CONV:Latitude failed to converge after 15 iterations"); + //console.log('iter:', iter); + return null; + } + + return (p); + } +}; +/* ====================================================================== + projCode/somerc.js + ====================================================================== */ + +/******************************************************************************* +NAME SWISS OBLIQUE MERCATOR + +PURPOSE: Swiss projection. +WARNING: X and Y are inverted (weird) in the swiss coordinate system. Not + here, since we want X to be horizontal and Y vertical. + +ALGORITHM REFERENCES +1. "Formules et constantes pour le Calcul pour la + projection cylindrique conforme à axe oblique et pour la transformation entre + des systèmes de référence". + http://www.swisstopo.admin.ch/internet/swisstopo/fr/home/topics/survey/sys/refsys/switzerland.parsysrelated1.31216.downloadList.77004.DownloadFile.tmp/swissprojectionfr.pdf + +*******************************************************************************/ + +Proj4js.Proj.somerc = { + + init: function() { + var phy0 = this.lat0; + this.lambda0 = this.long0; + var sinPhy0 = Math.sin(phy0); + var semiMajorAxis = this.a; + var invF = this.rf; + var flattening = 1 / invF; + var e2 = 2 * flattening - Math.pow(flattening, 2); + var e = this.e = Math.sqrt(e2); + this.R = this.k0 * semiMajorAxis * Math.sqrt(1 - e2) / (1 - e2 * Math.pow(sinPhy0, 2.0)); + this.alpha = Math.sqrt(1 + e2 / (1 - e2) * Math.pow(Math.cos(phy0), 4.0)); + this.b0 = Math.asin(sinPhy0 / this.alpha); + this.K = Math.log(Math.tan(Math.PI / 4.0 + this.b0 / 2.0)) + - this.alpha + * Math.log(Math.tan(Math.PI / 4.0 + phy0 / 2.0)) + + this.alpha + * e / 2 + * Math.log((1 + e * sinPhy0) + / (1 - e * sinPhy0)); + }, + + + forward: function(p) { + var Sa1 = Math.log(Math.tan(Math.PI / 4.0 - p.y / 2.0)); + var Sa2 = this.e / 2.0 + * Math.log((1 + this.e * Math.sin(p.y)) + / (1 - this.e * Math.sin(p.y))); + var S = -this.alpha * (Sa1 + Sa2) + this.K; + + // spheric latitude + var b = 2.0 * (Math.atan(Math.exp(S)) - Math.PI / 4.0); + + // spheric longitude + var I = this.alpha * (p.x - this.lambda0); + + // psoeudo equatorial rotation + var rotI = Math.atan(Math.sin(I) + / (Math.sin(this.b0) * Math.tan(b) + + Math.cos(this.b0) * Math.cos(I))); + + var rotB = Math.asin(Math.cos(this.b0) * Math.sin(b) - + Math.sin(this.b0) * Math.cos(b) * Math.cos(I)); + + p.y = this.R / 2.0 + * Math.log((1 + Math.sin(rotB)) / (1 - Math.sin(rotB))) + + this.y0; + p.x = this.R * rotI + this.x0; + return p; + }, + + inverse: function(p) { + var Y = p.x - this.x0; + var X = p.y - this.y0; + + var rotI = Y / this.R; + var rotB = 2 * (Math.atan(Math.exp(X / this.R)) - Math.PI / 4.0); + + var b = Math.asin(Math.cos(this.b0) * Math.sin(rotB) + + Math.sin(this.b0) * Math.cos(rotB) * Math.cos(rotI)); + var I = Math.atan(Math.sin(rotI) + / (Math.cos(this.b0) * Math.cos(rotI) - Math.sin(this.b0) + * Math.tan(rotB))); + + var lambda = this.lambda0 + I / this.alpha; + + var S = 0.0; + var phy = b; + var prevPhy = -1000.0; + var iteration = 0; + while (Math.abs(phy - prevPhy) > 0.0000001) + { + if (++iteration > 20) + { + Proj4js.reportError("omercFwdInfinity"); + return; + } + //S = Math.log(Math.tan(Math.PI / 4.0 + phy / 2.0)); + S = 1.0 + / this.alpha + * (Math.log(Math.tan(Math.PI / 4.0 + b / 2.0)) - this.K) + + this.e + * Math.log(Math.tan(Math.PI / 4.0 + + Math.asin(this.e * Math.sin(phy)) + / 2.0)); + prevPhy = phy; + phy = 2.0 * Math.atan(Math.exp(S)) - Math.PI / 2.0; + } + + p.x = lambda; + p.y = phy; + return p; + } +}; +/* ====================================================================== + projCode/stere.js + ====================================================================== */ + + +// Initialize the Stereographic projection + +Proj4js.Proj.stere = { + ssfn_: function(phit, sinphi, eccen) { + sinphi *= eccen; + return (Math.tan (.5 * (Proj4js.common.HALF_PI + phit)) * Math.pow((1. - sinphi) / (1. + sinphi), .5 * eccen)); + }, + TOL: 1.e-8, + NITER: 8, + CONV: 1.e-10, + S_POLE: 0, + N_POLE: 1, + OBLIQ: 2, + EQUIT: 3, + + init: function() { + this.phits = this.lat_ts ? this.lat_ts : Proj4js.common.HALF_PI; + var t = Math.abs(this.lat0); + if ((Math.abs(t) - Proj4js.common.HALF_PI) < Proj4js.common.EPSLN) { + this.mode = this.lat0 < 0. ? this.S_POLE : this.N_POLE; + } else { + this.mode = t > Proj4js.common.EPSLN ? this.OBLIQ : this.EQUIT; + } + this.phits = Math.abs(this.phits); + if (this.es) { + var X; + + switch (this.mode) { + case this.N_POLE: + case this.S_POLE: + if (Math.abs(this.phits - Proj4js.common.HALF_PI) < 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)); + } else { + t = Math.sin(this.phits); + this.akm1 = Math.cos(this.phits) / Proj4js.common.tsfnz(this.e, this.phits, t); + t *= this.e; + this.akm1 /= Math.sqrt(1. - t * t); + } + break; + case this.EQUIT: + this.akm1 = 2. * this.k0; + break; + case this.OBLIQ: + t = Math.sin(this.lat0); + X = 2. * Math.atan(this.ssfn_(this.lat0, t, this.e)) - Proj4js.common.HALF_PI; + t *= this.e; + this.akm1 = 2. * this.k0 * Math.cos(this.lat0) / Math.sqrt(1. - t * t); + this.sinX1 = Math.sin(X); + this.cosX1 = Math.cos(X); + break; + } + } else { + switch (this.mode) { + case this.OBLIQ: + this.sinph0 = 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 - .5 * this.phits) : + 2. * this.k0 ; + break; + } + } + }, + +// Stereographic forward equations--mapping lat,long to x,y + forward: function(p) { + var lon = p.x; + lon = Proj4js.common.adjust_lon(lon - this.long0); + var lat = p.y; + var x, y; + + if (this.sphere) { + var sinphi, cosphi, coslam, sinlam; + + sinphi = Math.sin(lat); + cosphi = Math.cos(lat); + coslam = Math.cos(lon); + sinlam = Math.sin(lon); + switch (this.mode) { + case this.EQUIT: + y = 1. + cosphi * coslam; + if (y <= Proj4js.common.EPSLN) { + Proj4js.reportError("stere:forward:Equit"); + } + y = this.akm1 / y; + x = y * cosphi * sinlam; + y *= sinphi; + break; + case this.OBLIQ: + y = 1. + this.sinph0 * sinphi + this.cosph0 * cosphi * coslam; + if (y <= Proj4js.common.EPSLN) { + Proj4js.reportError("stere:forward:Obliq"); + } + y = this.akm1 / y; + x = y * cosphi * sinlam; + y *= this.cosph0 * sinphi - this.sinph0 * cosphi * coslam; + break; + case this.N_POLE: + coslam = -coslam; + lat = -lat; + //Note no break here so it conitnues through S_POLE + case this.S_POLE: + if (Math.abs(lat - Proj4js.common.HALF_PI) < this.TOL) { + Proj4js.reportError("stere:forward:S_POLE"); + } + y = this.akm1 * Math.tan(Proj4js.common.FORTPI + .5 * lat); + x = sinlam * y; + y *= coslam; + break; + } + } else { + coslam = Math.cos(lon); + sinlam = Math.sin(lon); + sinphi = Math.sin(lat); + var sinX, cosX; + if (this.mode == this.OBLIQ || this.mode == this.EQUIT) { + var Xt = 2. * Math.atan(this.ssfn_(lat, sinphi, this.e)); + sinX = Math.sin(Xt - Proj4js.common.HALF_PI); + cosX = Math.cos(Xt); + } + switch (this.mode) { + case this.OBLIQ: + var A = this.akm1 / (this.cosX1 * (1. + this.sinX1 * sinX + this.cosX1 * cosX * coslam)); + y = A * (this.cosX1 * sinX - this.sinX1 * cosX * coslam); + x = A * cosX; + break; + case this.EQUIT: + var A = 2. * this.akm1 / (1. + cosX * coslam); + y = A * sinX; + x = A * cosX; + break; + case this.S_POLE: + lat = -lat; + coslam = - coslam; + sinphi = -sinphi; + case this.N_POLE: + x = this.akm1 * Proj4js.common.tsfnz(this.e, lat, sinphi); + y = - x * coslam; + break; + } + x = x * sinlam; + } + p.x = x*this.a + this.x0; + p.y = y*this.a + this.y0; + return p; + }, + + +//* Stereographic inverse equations--mapping x,y to lat/long + inverse: function(p) { + var x = (p.x - this.x0)/this.a; /* descale and de-offset */ + var y = (p.y - this.y0)/this.a; + var lon, lat; + + var cosphi, sinphi, tp=0.0, phi_l=0.0, rho, halfe=0.0, pi2=0.0; + var i; + + if (this.sphere) { + var c, rh, sinc, cosc; + + rh = Math.sqrt(x*x + y*y); + c = 2. * Math.atan(rh / this.akm1); + sinc = Math.sin(c); + cosc = Math.cos(c); + lon = 0.; + switch (this.mode) { + case this.EQUIT: + if (Math.abs(rh) <= Proj4js.common.EPSLN) { + lat = 0.; + } else { + lat = Math.asin(y * sinc / rh); + } + if (cosc != 0. || x != 0.) lon = Math.atan2(x * sinc, cosc * rh); + break; + case this.OBLIQ: + if (Math.abs(rh) <= Proj4js.common.EPSLN) { + lat = this.phi0; + } else { + lat = Math.asin(cosc * this.sinph0 + y * sinc * this.cosph0 / rh); + } + c = cosc - this.sinph0 * Math.sin(lat); + if (c != 0. || x != 0.) { + lon = Math.atan2(x * sinc * this.cosph0, c * rh); + } + break; + case this.N_POLE: + y = -y; + case this.S_POLE: + if (Math.abs(rh) <= Proj4js.common.EPSLN) { + lat = this.phi0; + } else { + lat = Math.asin(this.mode == this.S_POLE ? -cosc : cosc); + } + lon = (x == 0. && y == 0.) ? 0. : Math.atan2(x, y); + break; + } + p.x = Proj4js.common.adjust_lon(lon + this.long0); + p.y = lat; + } else { + rho = Math.sqrt(x*x + y*y); + switch (this.mode) { + case this.OBLIQ: + case this.EQUIT: + tp = 2. * Math.atan2(rho * this.cosX1 , this.akm1); + cosphi = Math.cos(tp); + sinphi = Math.sin(tp); + if( rho == 0.0 ) { + phi_l = Math.asin(cosphi * this.sinX1); + } else { + phi_l = Math.asin(cosphi * this.sinX1 + (y * sinphi * this.cosX1 / rho)); + } + + tp = Math.tan(.5 * (Proj4js.common.HALF_PI + phi_l)); + x *= sinphi; + y = rho * this.cosX1 * cosphi - y * this.sinX1* sinphi; + pi2 = Proj4js.common.HALF_PI; + halfe = .5 * this.e; + break; + case this.N_POLE: + y = -y; + case this.S_POLE: + tp = - rho / this.akm1; + phi_l = Proj4js.common.HALF_PI - 2. * Math.atan(tp); + pi2 = -Proj4js.common.HALF_PI; + halfe = -.5 * this.e; + break; + } + for (i = this.NITER; i--; phi_l = lat) { //check this + sinphi = this.e * Math.sin(phi_l); + lat = 2. * Math.atan(tp * Math.pow((1.+sinphi)/(1.-sinphi), halfe)) - pi2; + if (Math.abs(phi_l - lat) < this.CONV) { + if (this.mode == this.S_POLE) lat = -lat; + lon = (x == 0. && y == 0.) ? 0. : Math.atan2(x, y); + p.x = Proj4js.common.adjust_lon(lon + this.long0); + p.y = lat; + return p; + } + } + } + } +}; +/* ====================================================================== + projCode/nzmg.js + ====================================================================== */ + +/******************************************************************************* +NAME NEW ZEALAND MAP GRID + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the New Zealand Map Grid projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + + +ALGORITHM REFERENCES + +1. Department of Land and Survey Technical Circular 1973/32 + http://www.linz.govt.nz/docs/miscellaneous/nz-map-definition.pdf + +2. OSG Technical Report 4.1 + http://www.linz.govt.nz/docs/miscellaneous/nzmg.pdf + + +IMPLEMENTATION NOTES + +The two references use different symbols for the calculated values. This +implementation uses the variable names similar to the symbols in reference [1]. + +The alogrithm uses different units for delta latitude and delta longitude. +The delta latitude is assumed to be in units of seconds of arc x 10^-5. +The delta longitude is the usual radians. Look out for these conversions. + +The algorithm is described using complex arithmetic. There were three +options: + * find and use a Javascript library for complex arithmetic + * write my own complex library + * expand the complex arithmetic by hand to simple arithmetic + +This implementation has expanded the complex multiplication operations +into parallel simple arithmetic operations for the real and imaginary parts. +The imaginary part is way over to the right of the display; this probably +violates every coding standard in the world, but, to me, it makes it much +more obvious what is going on. + +The following complex operations are used: + - addition + - multiplication + - division + - complex number raised to integer power + - summation + +A summary of complex arithmetic operations: + (from http://en.wikipedia.org/wiki/Complex_arithmetic) + addition: (a + bi) + (c + di) = (a + c) + (b + d)i + subtraction: (a + bi) - (c + di) = (a - c) + (b - d)i + multiplication: (a + bi) x (c + di) = (ac - bd) + (bc + ad)i + division: (a + bi) / (c + di) = [(ac + bd)/(cc + dd)] + [(bc - ad)/(cc + dd)]i + +The algorithm needs to calculate summations of simple and complex numbers. This is +implemented using a for-loop, pre-loading the summed value to zero. + +The algorithm needs to calculate theta^2, theta^3, etc while doing a summation. +There are three possible implementations: + - use Math.pow in the summation loop - except for complex numbers + - precalculate the values before running the loop + - calculate theta^n = theta^(n-1) * theta during the loop +This implementation uses the third option for both real and complex arithmetic. + +For example + psi_n = 1; + sum = 0; + for (n = 1; n <=6; n++) { + psi_n1 = psi_n * psi; // calculate psi^(n+1) + psi_n = psi_n1; + sum = sum + A[n] * psi_n; + } + + +TEST VECTORS + +NZMG E, N: 2487100.638 6751049.719 metres +NZGD49 long, lat: 172.739194 -34.444066 degrees + +NZMG E, N: 2486533.395 6077263.661 metres +NZGD49 long, lat: 172.723106 -40.512409 degrees + +NZMG E, N: 2216746.425 5388508.765 metres +NZGD49 long, lat: 169.172062 -46.651295 degrees + +Note that these test vectors convert from NZMG metres to lat/long referenced +to NZGD49, not the more usual WGS84. The difference is about 70m N/S and about +10m E/W. + +These test vectors are provided in reference [1]. Many more test +vectors are available in + http://www.linz.govt.nz/docs/topography/topographicdata/placenamesdatabase/nznamesmar08.zip +which is a catalog of names on the 260-series maps. + + +EPSG CODES + +NZMG EPSG:27200 +NZGD49 EPSG:4272 + +http://spatialreference.org/ defines these as + Proj4js.defs["EPSG:4272"] = "+proj=longlat +ellps=intl +datum=nzgd49 +no_defs "; + Proj4js.defs["EPSG:27200"] = "+proj=nzmg +lat_0=-41 +lon_0=173 +x_0=2510000 +y_0=6023150 +ellps=intl +datum=nzgd49 +units=m +no_defs "; + + +LICENSE + Copyright: Stephen Irons 2008 + Released under terms of the LGPL as per: http://www.gnu.org/copyleft/lesser.html + +*******************************************************************************/ + + +/** + Initialize New Zealand Map Grip projection +*/ + +Proj4js.Proj.nzmg = { + + /** + * iterations: Number of iterations to refine inverse transform. + * 0 -> km accuracy + * 1 -> m accuracy -- suitable for most mapping applications + * 2 -> mm accuracy + */ + iterations: 1, + + init : function() { + this.A = new Array(); + this.A[1] = +0.6399175073; + this.A[2] = -0.1358797613; + this.A[3] = +0.063294409; + this.A[4] = -0.02526853; + this.A[5] = +0.0117879; + this.A[6] = -0.0055161; + this.A[7] = +0.0026906; + this.A[8] = -0.001333; + this.A[9] = +0.00067; + this.A[10] = -0.00034; + + this.B_re = new Array(); this.B_im = new Array(); + this.B_re[1] = +0.7557853228; this.B_im[1] = 0.0; + this.B_re[2] = +0.249204646; this.B_im[2] = +0.003371507; + this.B_re[3] = -0.001541739; this.B_im[3] = +0.041058560; + this.B_re[4] = -0.10162907; this.B_im[4] = +0.01727609; + this.B_re[5] = -0.26623489; this.B_im[5] = -0.36249218; + this.B_re[6] = -0.6870983; this.B_im[6] = -1.1651967; + + this.C_re = new Array(); this.C_im = new Array(); + this.C_re[1] = +1.3231270439; this.C_im[1] = 0.0; + this.C_re[2] = -0.577245789; this.C_im[2] = -0.007809598; + this.C_re[3] = +0.508307513; this.C_im[3] = -0.112208952; + this.C_re[4] = -0.15094762; this.C_im[4] = +0.18200602; + this.C_re[5] = +1.01418179; this.C_im[5] = +1.64497696; + this.C_re[6] = +1.9660549; this.C_im[6] = +2.5127645; + + this.D = new Array(); + this.D[1] = +1.5627014243; + this.D[2] = +0.5185406398; + this.D[3] = -0.03333098; + this.D[4] = -0.1052906; + this.D[5] = -0.0368594; + this.D[6] = +0.007317; + this.D[7] = +0.01220; + this.D[8] = +0.00394; + this.D[9] = -0.0013; + }, + + /** + New Zealand Map Grid Forward - long/lat to x/y + long/lat in radians + */ + forward : function(p) { + var lon = p.x; + var lat = p.y; + + var delta_lat = lat - this.lat0; + var delta_lon = lon - this.long0; + + // 1. Calculate d_phi and d_psi ... // and d_lambda + // For this algorithm, delta_latitude is in seconds of arc x 10-5, so we need to scale to those units. Longitude is radians. + var d_phi = delta_lat / Proj4js.common.SEC_TO_RAD * 1E-5; var d_lambda = delta_lon; + var d_phi_n = 1; // d_phi^0 + + var d_psi = 0; + for (var n = 1; n <= 10; n++) { + d_phi_n = d_phi_n * d_phi; + d_psi = d_psi + this.A[n] * d_phi_n; + } + + // 2. Calculate theta + var th_re = d_psi; var th_im = d_lambda; + + // 3. Calculate z + var th_n_re = 1; var th_n_im = 0; // theta^0 + var th_n_re1; var th_n_im1; + + var z_re = 0; var z_im = 0; + for (var n = 1; n <= 6; n++) { + th_n_re1 = th_n_re*th_re - th_n_im*th_im; th_n_im1 = th_n_im*th_re + th_n_re*th_im; + th_n_re = th_n_re1; th_n_im = th_n_im1; + z_re = z_re + this.B_re[n]*th_n_re - this.B_im[n]*th_n_im; z_im = z_im + this.B_im[n]*th_n_re + this.B_re[n]*th_n_im; + } + + // 4. Calculate easting and northing + p.x = (z_im * this.a) + this.x0; + p.y = (z_re * this.a) + this.y0; + + return p; + }, + + + /** + New Zealand Map Grid Inverse - x/y to long/lat + */ + inverse : function(p) { + + var x = p.x; + var y = p.y; + + var delta_x = x - this.x0; + var delta_y = y - this.y0; + + // 1. Calculate z + var z_re = delta_y / this.a; var z_im = delta_x / this.a; + + // 2a. Calculate theta - first approximation gives km accuracy + var z_n_re = 1; var z_n_im = 0; // z^0 + var z_n_re1; var z_n_im1; + + var th_re = 0; var th_im = 0; + for (var n = 1; n <= 6; n++) { + z_n_re1 = z_n_re*z_re - z_n_im*z_im; z_n_im1 = z_n_im*z_re + z_n_re*z_im; + z_n_re = z_n_re1; z_n_im = z_n_im1; + th_re = th_re + this.C_re[n]*z_n_re - this.C_im[n]*z_n_im; th_im = th_im + this.C_im[n]*z_n_re + this.C_re[n]*z_n_im; + } + + // 2b. Iterate to refine the accuracy of the calculation + // 0 iterations gives km accuracy + // 1 iteration gives m accuracy -- good enough for most mapping applications + // 2 iterations bives mm accuracy + for (var i = 0; i < this.iterations; i++) { + var th_n_re = th_re; var th_n_im = th_im; + var th_n_re1; var th_n_im1; + + var num_re = z_re; var num_im = z_im; + for (var n = 2; n <= 6; n++) { + th_n_re1 = th_n_re*th_re - th_n_im*th_im; th_n_im1 = th_n_im*th_re + th_n_re*th_im; + th_n_re = th_n_re1; th_n_im = th_n_im1; + num_re = num_re + (n-1)*(this.B_re[n]*th_n_re - this.B_im[n]*th_n_im); num_im = num_im + (n-1)*(this.B_im[n]*th_n_re + this.B_re[n]*th_n_im); + } + + th_n_re = 1; th_n_im = 0; + var den_re = this.B_re[1]; var den_im = this.B_im[1]; + for (var n = 2; n <= 6; n++) { + th_n_re1 = th_n_re*th_re - th_n_im*th_im; th_n_im1 = th_n_im*th_re + th_n_re*th_im; + th_n_re = th_n_re1; th_n_im = th_n_im1; + den_re = den_re + n * (this.B_re[n]*th_n_re - this.B_im[n]*th_n_im); den_im = den_im + n * (this.B_im[n]*th_n_re + this.B_re[n]*th_n_im); + } + + // Complex division + var den2 = den_re*den_re + den_im*den_im; + th_re = (num_re*den_re + num_im*den_im) / den2; th_im = (num_im*den_re - num_re*den_im) / den2; + } + + // 3. Calculate d_phi ... // and d_lambda + var d_psi = th_re; var d_lambda = th_im; + var d_psi_n = 1; // d_psi^0 + + var d_phi = 0; + for (var n = 1; n <= 9; n++) { + d_psi_n = d_psi_n * d_psi; + d_phi = d_phi + this.D[n] * d_psi_n; + } + + // 4. Calculate latitude and longitude + // d_phi is calcuated in second of arc * 10^-5, so we need to scale back to radians. d_lambda is in radians. + var lat = this.lat0 + (d_phi * Proj4js.common.SEC_TO_RAD * 1E5); + var lon = this.long0 + d_lambda; + + p.x = lon; + p.y = lat; + + return p; + } +}; +/* ====================================================================== + projCode/mill.js + ====================================================================== */ + +/******************************************************************************* +NAME MILLER CYLINDRICAL + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Miller Cylindrical projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +T. Mittan March, 1993 + +This function was adapted from the Lambert Azimuthal Equal Area projection +code (FORTRAN) in the General Cartographic Transformation Package software +which is available from the U.S. Geological Survey National Mapping Division. + +ALGORITHM REFERENCES + +1. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder, + The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355. + +2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +3. "Software Documentation for GCTP General Cartographic Transformation + Package", U.S. Geological Survey National Mapping Division, May 1982. +*******************************************************************************/ + +Proj4js.Proj.mill = { + +/* Initialize the Miller Cylindrical projection + -------------------------------------------*/ + init: function() { + //no-op + }, + + + /* Miller Cylindrical forward equations--mapping lat,long to x,y + ------------------------------------------------------------*/ + forward: function(p) { + var lon=p.x; + var lat=p.y; + /* Forward equations + -----------------*/ + var dlon = Proj4js.common.adjust_lon(lon -this.long0); + var x = this.x0 + this.a * dlon; + var y = this.y0 + this.a * Math.log(Math.tan((Proj4js.common.PI / 4.0) + (lat / 2.5))) * 1.25; + + p.x=x; + p.y=y; + return p; + },//millFwd() + + /* Miller Cylindrical inverse equations--mapping x,y to lat/long + ------------------------------------------------------------*/ + inverse: function(p) { + p.x -= this.x0; + p.y -= this.y0; + + var lon = Proj4js.common.adjust_lon(this.long0 + p.x /this.a); + var lat = 2.5 * (Math.atan(Math.exp(0.8*p.y/this.a)) - Proj4js.common.PI / 4.0); + + p.x=lon; + p.y=lat; + return p; + }//millInv() +}; +/* ====================================================================== + projCode/gnom.js + ====================================================================== */ + +/***************************************************************************** +NAME GNOMONIC + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Gnomonic Projection. + Implementation based on the existing sterea and ortho + implementations. + +PROGRAMMER DATE +---------- ---- +Richard Marsden November 2009 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Flattening the Earth - Two Thousand Years of Map + Projections", University of Chicago Press 1993 + +2. Wolfram Mathworld "Gnomonic Projection" + http://mathworld.wolfram.com/GnomonicProjection.html + Accessed: 12th November 2009 +******************************************************************************/ + +Proj4js.Proj.gnom = { + + /* Initialize the Gnomonic projection + -------------------------------------*/ + init: function(def) { + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + this.sin_p14=Math.sin(this.lat0); + this.cos_p14=Math.cos(this.lat0); + // Approximation for projecting points to the horizon (infinity) + this.infinity_dist = 1000 * this.a; + this.rc = 1; + }, + + + /* Gnomonic forward equations--mapping lat,long to x,y + ---------------------------------------------------*/ + forward: function(p) { + var sinphi, cosphi; /* sin and cos value */ + var dlon; /* delta longitude value */ + var coslon; /* cos of longitude */ + var ksp; /* scale factor */ + var g; + var x, y; + var lon=p.x; + var lat=p.y; + /* Forward equations + -----------------*/ + dlon = Proj4js.common.adjust_lon(lon - this.long0); + + sinphi=Math.sin(lat); + cosphi=Math.cos(lat); + + coslon = Math.cos(dlon); + g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon; + ksp = 1.0; + if ((g > 0) || (Math.abs(g) <= Proj4js.common.EPSLN)) { + x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon) / g; + y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon) / g; + } else { + Proj4js.reportError("orthoFwdPointError"); + + // Point is in the opposing hemisphere and is unprojectable + // We still need to return a reasonable point, so we project + // to infinity, on a bearing + // equivalent to the northern hemisphere equivalent + // This is a reasonable approximation for short shapes and lines that + // straddle the horizon. + + x = this.x0 + this.infinity_dist * cosphi * Math.sin(dlon); + y = this.y0 + this.infinity_dist * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon); + + } + p.x=x; + p.y=y; + return p; + }, + + + inverse: function(p) { + var rh; /* Rho */ + var z; /* angle */ + var sinc, cosc; + var c; + var lon , lat; + + /* Inverse equations + -----------------*/ + p.x = (p.x - this.x0) / this.a; + p.y = (p.y - this.y0) / this.a; + + p.x /= this.k0; + p.y /= this.k0; + + if ( (rh = Math.sqrt(p.x * p.x + p.y * p.y)) ) { + c = Math.atan2(rh, this.rc); + sinc = Math.sin(c); + cosc = Math.cos(c); + + lat = Proj4js.common.asinz(cosc*this.sin_p14 + (p.y*sinc*this.cos_p14) / rh); + lon = Math.atan2(p.x*sinc, rh*this.cos_p14*cosc - p.y*this.sin_p14*sinc); + lon = Proj4js.common.adjust_lon(this.long0+lon); + } else { + lat = this.phic0; + lon = 0.0; + } + + p.x=lon; + p.y=lat; + return p; + } +}; + + +/* ====================================================================== + projCode/sinu.js + ====================================================================== */ + +/******************************************************************************* +NAME SINUSOIDAL + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Sinusoidal projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +D. Steinwand, EROS May, 1991 + +This function was adapted from the Sinusoidal projection code (FORTRAN) in the +General Cartographic Transformation Package software which is available from +the U.S. Geological Survey National Mapping Division. + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. "Software Documentation for GCTP General Cartographic Transformation + Package", U.S. Geological Survey National Mapping Division, May 1982. +*******************************************************************************/ + +Proj4js.Proj.sinu = { + + /* Initialize the Sinusoidal projection + ------------------------------------*/ + init: function() { + /* Place parameters in static storage for common use + -------------------------------------------------*/ + + + if (!this.sphere) { + this.en = Proj4js.common.pj_enfn(this.es); + } else { + this.n = 1.; + this.m = 0.; + this.es = 0; + this.C_y = Math.sqrt((this.m + 1.) / this.n); + this.C_x = this.C_y/(this.m + 1.); + } + + }, + + /* Sinusoidal forward equations--mapping lat,long to x,y + -----------------------------------------------------*/ + forward: function(p) { + var x,y,delta_lon; + var lon=p.x; + var lat=p.y; + /* Forward equations + -----------------*/ + lon = Proj4js.common.adjust_lon(lon - this.long0); + + if (this.sphere) { + if (!this.m) { + lat = this.n != 1. ? Math.asin(this.n * Math.sin(lat)): lat; + } else { + var k = this.n * Math.sin(lat); + for (var i = Proj4js.common.MAX_ITER; i ; --i) { + var V = (this.m * lat + Math.sin(lat) - k) / (this.m + Math.cos(lat)); + lat -= V; + if (Math.abs(V) < Proj4js.common.EPSLN) break; + } + } + x = this.a * this.C_x * lon * (this.m + Math.cos(lat)); + y = this.a * this.C_y * lat; + + } else { + + var s = Math.sin(lat); + var c = Math.cos(lat); + y = this.a * Proj4js.common.pj_mlfn(lat, s, c, this.en); + x = this.a * lon * c / Math.sqrt(1. - this.es * s * s); + } + + p.x=x; + p.y=y; + return p; + }, + + inverse: function(p) { + var lat,temp,lon; + + /* Inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + lat = p.y / this.a; + + if (this.sphere) { + + p.y /= this.C_y; + lat = this.m ? Math.asin((this.m * p.y + Math.sin(p.y)) / this.n) : + ( this.n != 1. ? Math.asin(Math.sin(p.y) / this.n) : p.y ); + lon = p.x / (this.C_x * (this.m + Math.cos(p.y))); + + } else { + lat = Proj4js.common.pj_inv_mlfn(p.y/this.a, this.es, this.en) + var s = Math.abs(lat); + if (s < Proj4js.common.HALF_PI) { + s = Math.sin(lat); + temp = this.long0 + p.x * Math.sqrt(1. - this.es * s * s) /(this.a * Math.cos(lat)); + //temp = this.long0 + p.x / (this.a * Math.cos(lat)); + lon = Proj4js.common.adjust_lon(temp); + } else if ((s - Proj4js.common.EPSLN) < Proj4js.common.HALF_PI) { + lon = this.long0; + } + + } + + p.x=lon; + p.y=lat; + return p; + } +}; + + +/* ====================================================================== + projCode/vandg.js + ====================================================================== */ + +/******************************************************************************* +NAME VAN DER GRINTEN + +PURPOSE: Transforms input Easting and Northing to longitude and + latitude for the Van der Grinten projection. The + Easting and Northing must be in meters. The longitude + and latitude values will be returned in radians. + +PROGRAMMER DATE +---------- ---- +T. Mittan March, 1993 + +This function was adapted from the Van Der Grinten projection code +(FORTRAN) in the General Cartographic Transformation Package software +which is available from the U.S. Geological Survey National Mapping Division. + +ALGORITHM REFERENCES + +1. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder, + The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355. + +2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +3. "Software Documentation for GCTP General Cartographic Transformation + Package", U.S. Geological Survey National Mapping Division, May 1982. +*******************************************************************************/ + +Proj4js.Proj.vandg = { + +/* Initialize the Van Der Grinten projection + ----------------------------------------*/ + init: function() { + this.R = 6370997.0; //Radius of earth + }, + + forward: function(p) { + + var lon=p.x; + var lat=p.y; + + /* Forward equations + -----------------*/ + var dlon = Proj4js.common.adjust_lon(lon - this.long0); + var x,y; + + if (Math.abs(lat) <= Proj4js.common.EPSLN) { + x = this.x0 + this.R * dlon; + y = this.y0; + } + var theta = Proj4js.common.asinz(2.0 * Math.abs(lat / Proj4js.common.PI)); + if ((Math.abs(dlon) <= Proj4js.common.EPSLN) || (Math.abs(Math.abs(lat) - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN)) { + x = this.x0; + if (lat >= 0) { + y = this.y0 + Proj4js.common.PI * this.R * Math.tan(.5 * theta); + } else { + y = this.y0 + Proj4js.common.PI * this.R * - Math.tan(.5 * theta); + } + // return(OK); + } + var al = .5 * Math.abs((Proj4js.common.PI / dlon) - (dlon / Proj4js.common.PI)); + var asq = al * al; + var sinth = Math.sin(theta); + var costh = Math.cos(theta); + + var g = costh / (sinth + costh - 1.0); + var gsq = g * g; + var m = g * (2.0 / sinth - 1.0); + var msq = m * m; + var con = Proj4js.common.PI * this.R * (al * (g - msq) + Math.sqrt(asq * (g - msq) * (g - msq) - (msq + asq) * (gsq - msq))) / (msq + asq); + if (dlon < 0) { + con = -con; + } + x = this.x0 + con; + con = Math.abs(con / (Proj4js.common.PI * this.R)); + if (lat >= 0) { + y = this.y0 + Proj4js.common.PI * this.R * Math.sqrt(1.0 - con * con - 2.0 * al * con); + } else { + y = this.y0 - Proj4js.common.PI * this.R * Math.sqrt(1.0 - con * con - 2.0 * al * con); + } + p.x = x; + p.y = y; + return p; + }, + +/* Van Der Grinten inverse equations--mapping x,y to lat/long + ---------------------------------------------------------*/ + inverse: function(p) { + var lon, lat; + var xx,yy,xys,c1,c2,c3; + var al,asq; + var a1; + var m1; + var con; + var th1; + var d; + + /* inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + con = Proj4js.common.PI * this.R; + xx = p.x / con; + yy =p.y / con; + xys = xx * xx + yy * yy; + c1 = -Math.abs(yy) * (1.0 + xys); + c2 = c1 - 2.0 * yy * yy + xx * xx; + c3 = -2.0 * c1 + 1.0 + 2.0 * yy * yy + xys * xys; + d = yy * yy / c3 + (2.0 * c2 * c2 * c2 / c3 / c3 / c3 - 9.0 * c1 * c2 / c3 /c3) / 27.0; + a1 = (c1 - c2 * c2 / 3.0 / c3) / c3; + m1 = 2.0 * Math.sqrt( -a1 / 3.0); + con = ((3.0 * d) / a1) / m1; + if (Math.abs(con) > 1.0) { + if (con >= 0.0) { + con = 1.0; + } else { + con = -1.0; + } + } + th1 = Math.acos(con) / 3.0; + if (p.y >= 0) { + lat = (-m1 *Math.cos(th1 + Proj4js.common.PI / 3.0) - c2 / 3.0 / c3) * Proj4js.common.PI; + } else { + lat = -(-m1 * Math.cos(th1 + Proj4js.common.PI / 3.0) - c2 / 3.0 / c3) * Proj4js.common.PI; + } + + if (Math.abs(xx) < Proj4js.common.EPSLN) { + lon = this.long0; + } + lon = Proj4js.common.adjust_lon(this.long0 + Proj4js.common.PI * (xys - 1.0 + Math.sqrt(1.0 + 2.0 * (xx * xx - yy * yy) + xys * xys)) / 2.0 / xx); + + p.x=lon; + p.y=lat; + return p; + } +}; +/* ====================================================================== + projCode/cea.js + ====================================================================== */ + +/******************************************************************************* +NAME LAMBERT CYLINDRICAL EQUAL AREA + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Lambert Cylindrical Equal Area projection. + This class of projection includes the Behrmann and + Gall-Peters Projections. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +R. Marsden August 2009 +Winwaed Software Tech LLC, http://www.winwaed.com + +This function was adapted from the Miller Cylindrical Projection in the Proj4JS +library. + +Note: This implementation assumes a Spherical Earth. The (commented) code +has been included for the ellipsoidal forward transform, but derivation of +the ellispoidal inverse transform is beyond me. Note that most of the +Proj4JS implementations do NOT currently support ellipsoidal figures. +Therefore this is not seen as a problem - especially this lack of support +is explicitly stated here. + +ALGORITHM REFERENCES + +1. "Cartographic Projection Procedures for the UNIX Environment - + A User's Manual" by Gerald I. Evenden, USGS Open File Report 90-284 + and Release 4 Interim Reports (2003) + +2. Snyder, John P., "Flattening the Earth - Two Thousand Years of Map + Projections", Univ. Chicago Press, 1993 +*******************************************************************************/ + +Proj4js.Proj.cea = { + +/* Initialize the Cylindrical Equal Area projection + -------------------------------------------*/ + init: function() { + //no-op + }, + + + /* Cylindrical Equal Area forward equations--mapping lat,long to x,y + ------------------------------------------------------------*/ + forward: function(p) { + var lon=p.x; + var lat=p.y; + /* Forward equations + -----------------*/ + var dlon = Proj4js.common.adjust_lon(lon -this.long0); + var x = this.x0 + this.a * dlon * Math.cos(this.lat_ts); + var y = this.y0 + this.a * Math.sin(lat) / Math.cos(this.lat_ts); + /* Elliptical Forward Transform + Not implemented due to a lack of a matchign inverse function + { + var Sin_Lat = Math.sin(lat); + var Rn = this.a * (Math.sqrt(1.0e0 - this.es * Sin_Lat * Sin_Lat )); + x = this.x0 + this.a * dlon * Math.cos(this.lat_ts); + y = this.y0 + Rn * Math.sin(lat) / Math.cos(this.lat_ts); + } + */ + + + p.x=x; + p.y=y; + return p; + },//ceaFwd() + + /* Cylindrical Equal Area inverse equations--mapping x,y to lat/long + ------------------------------------------------------------*/ + inverse: function(p) { + p.x -= this.x0; + p.y -= this.y0; + + var lon = Proj4js.common.adjust_lon( this.long0 + (p.x / this.a) / Math.cos(this.lat_ts) ); + + var lat = Math.asin( (p.y/this.a) * Math.cos(this.lat_ts) ); + + p.x=lon; + p.y=lat; + return p; + }//ceaInv() +}; +/* ====================================================================== + projCode/eqc.js + ====================================================================== */ + +/* similar to equi.js FIXME proj4 uses eqc */ +Proj4js.Proj.eqc = { + init : function() { + + if(!this.x0) this.x0=0; + if(!this.y0) this.y0=0; + if(!this.lat0) this.lat0=0; + if(!this.long0) this.long0=0; + if(!this.lat_ts) this.lat_ts=0; + if (!this.title) this.title = "Equidistant Cylindrical (Plate Carre)"; + + this.rc= Math.cos(this.lat_ts); + }, + + + // forward equations--mapping lat,long to x,y + // ----------------------------------------------------------------- + forward : function(p) { + + var lon= p.x; + var lat= p.y; + + var dlon = Proj4js.common.adjust_lon(lon - this.long0); + var dlat = Proj4js.common.adjust_lat(lat - this.lat0 ); + p.x= this.x0 + (this.a*dlon*this.rc); + p.y= this.y0 + (this.a*dlat ); + return p; + }, + + // inverse equations--mapping x,y to lat/long + // ----------------------------------------------------------------- + inverse : function(p) { + + var x= p.x; + var y= p.y; + + p.x= Proj4js.common.adjust_lon(this.long0 + ((x - this.x0)/(this.a*this.rc))); + p.y= Proj4js.common.adjust_lat(this.lat0 + ((y - this.y0)/(this.a ))); + return p; + } + +}; +/* ====================================================================== + projCode/cass.js + ====================================================================== */ + +/******************************************************************************* +NAME CASSINI + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Cassini projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + Ported from PROJ.4. + + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government +*******************************************************************************/ + + +//Proj4js.defs["EPSG:28191"] = "+proj=cass +lat_0=31.73409694444445 +lon_0=35.21208055555556 +x_0=170251.555 +y_0=126867.909 +a=6378300.789 +b=6356566.435 +towgs84=-275.722,94.7824,340.894,-8.001,-4.42,-11.821,1 +units=m +no_defs"; + +// Initialize the Cassini projection +// ----------------------------------------------------------------- + +Proj4js.Proj.cass = { + init : function() { + if (!this.sphere) { + this.en = Proj4js.common.pj_enfn(this.es) + this.m0 = Proj4js.common.pj_mlfn(this.lat0, Math.sin(this.lat0), Math.cos(this.lat0), this.en); + } + }, + + C1: .16666666666666666666, + C2: .00833333333333333333, + C3: .04166666666666666666, + C4: .33333333333333333333, + C5: .06666666666666666666, + + +/* Cassini forward equations--mapping lat,long to x,y + -----------------------------------------------------------------------*/ + forward: function(p) { + + /* Forward equations + -----------------*/ + var x,y; + var lam=p.x; + var phi=p.y; + lam = Proj4js.common.adjust_lon(lam - this.long0); + + if (this.sphere) { + x = Math.asin(Math.cos(phi) * Math.sin(lam)); + y = Math.atan2(Math.tan(phi) , Math.cos(lam)) - this.phi0; + } else { + //ellipsoid + this.n = Math.sin(phi); + this.c = Math.cos(phi); + y = Proj4js.common.pj_mlfn(phi, this.n, this.c, this.en); + this.n = 1./Math.sqrt(1. - this.es * this.n * this.n); + this.tn = Math.tan(phi); + this.t = this.tn * this.tn; + this.a1 = lam * this.c; + this.c *= this.es * this.c / (1 - this.es); + this.a2 = this.a1 * this.a1; + x = this.n * this.a1 * (1. - this.a2 * this.t * (this.C1 - (8. - this.t + 8. * this.c) * this.a2 * this.C2)); + y -= this.m0 - this.n * this.tn * this.a2 * (.5 + (5. - this.t + 6. * this.c) * this.a2 * this.C3); + } + + p.x = this.a*x + this.x0; + p.y = this.a*y + this.y0; + return p; + },//cassFwd() + +/* Inverse equations + -----------------*/ + inverse: function(p) { + p.x -= this.x0; + p.y -= this.y0; + var x = p.x/this.a; + var y = p.y/this.a; + var phi, lam; + + if (this.sphere) { + this.dd = y + this.lat0; + phi = Math.asin(Math.sin(this.dd) * Math.cos(x)); + lam = Math.atan2(Math.tan(x), Math.cos(this.dd)); + } else { + /* ellipsoid */ + var ph1 = Proj4js.common.pj_inv_mlfn(this.m0 + y, this.es, this.en); + this.tn = Math.tan(ph1); + this.t = this.tn * this.tn; + this.n = Math.sin(ph1); + this.r = 1. / (1. - this.es * this.n * this.n); + this.n = Math.sqrt(this.r); + this.r *= (1. - this.es) * this.n; + this.dd = x / this.n; + this.d2 = this.dd * this.dd; + phi = ph1 - (this.n * this.tn / this.r) * this.d2 * (.5 - (1. + 3. * this.t) * this.d2 * this.C3); + lam = this.dd * (1. + this.t * this.d2 * (-this.C4 + (1. + 3. * this.t) * this.d2 * this.C5)) / Math.cos(ph1); + } + p.x = Proj4js.common.adjust_lon(this.long0+lam); + p.y = phi; + return p; + }//cassInv() + +} +/* ====================================================================== + projCode/gauss.js + ====================================================================== */ + + +Proj4js.Proj.gauss = { + + init : function() { + var sphi = Math.sin(this.lat0); + var cphi = Math.cos(this.lat0); + cphi *= cphi; + this.rc = Math.sqrt(1.0 - this.es) / (1.0 - this.es * sphi * sphi); + this.C = Math.sqrt(1.0 + this.es * cphi * cphi / (1.0 - this.es)); + this.phic0 = Math.asin(sphi / this.C); + this.ratexp = 0.5 * this.C * this.e; + this.K = Math.tan(0.5 * this.phic0 + Proj4js.common.FORTPI) / (Math.pow(Math.tan(0.5*this.lat0 + Proj4js.common.FORTPI), this.C) * Proj4js.common.srat(this.e*sphi, this.ratexp)); + }, + + forward : function(p) { + var lon = p.x; + var lat = p.y; + + p.y = 2.0 * Math.atan( this.K * Math.pow(Math.tan(0.5 * lat + Proj4js.common.FORTPI), this.C) * Proj4js.common.srat(this.e * Math.sin(lat), this.ratexp) ) - Proj4js.common.HALF_PI; + p.x = this.C * lon; + return p; + }, + + inverse : function(p) { + var DEL_TOL = 1e-14; + var lon = p.x / this.C; + var lat = p.y; + var num = Math.pow(Math.tan(0.5 * lat + Proj4js.common.FORTPI)/this.K, 1./this.C); + for (var i = Proj4js.common.MAX_ITER; i>0; --i) { + lat = 2.0 * Math.atan(num * Proj4js.common.srat(this.e * Math.sin(p.y), -0.5 * this.e)) - Proj4js.common.HALF_PI; + if (Math.abs(lat - p.y) < DEL_TOL) break; + p.y = lat; + } + /* convergence failed */ + if (!i) { + Proj4js.reportError("gauss:inverse:convergence failed"); + return null; + } + p.x = lon; + p.y = lat; + return p; + } +}; + +/* ====================================================================== + projCode/omerc.js + ====================================================================== */ + +/******************************************************************************* +NAME OBLIQUE MERCATOR (HOTINE) + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Oblique Mercator projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +T. Mittan Mar, 1993 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + +Proj4js.Proj.omerc = { + + /* Initialize the Oblique Mercator projection + ------------------------------------------*/ + init: function() { + if (!this.mode) this.mode=0; + if (!this.lon1) {this.lon1=0;this.mode=1;} + if (!this.lon2) this.lon2=0; + if (!this.lat2) this.lat2=0; + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + var temp = this.b/ this.a; + var es = 1.0 - Math.pow(temp,2); + var e = Math.sqrt(es); + + this.sin_p20=Math.sin(this.lat0); + this.cos_p20=Math.cos(this.lat0); + + this.con = 1.0 - this.es * this.sin_p20 * this.sin_p20; + this.com = Math.sqrt(1.0 - es); + this.bl = Math.sqrt(1.0 + this.es * Math.pow(this.cos_p20,4.0)/(1.0 - es)); + this.al = this.a * this.bl * this.k0 * this.com / this.con; + if (Math.abs(this.lat0) < Proj4js.common.EPSLN) { + this.ts = 1.0; + this.d = 1.0; + this.el = 1.0; + } else { + this.ts = Proj4js.common.tsfnz(this.e,this.lat0,this.sin_p20); + this.con = Math.sqrt(this.con); + this.d = this.bl * this.com / (this.cos_p20 * this.con); + if ((this.d * this.d - 1.0) > 0.0) { + if (this.lat0 >= 0.0) { + this.f = this.d + Math.sqrt(this.d * this.d - 1.0); + } else { + this.f = this.d - Math.sqrt(this.d * this.d - 1.0); + } + } else { + this.f = this.d; + } + this.el = this.f * Math.pow(this.ts,this.bl); + } + + //this.longc=52.60353916666667; + + if (this.mode != 0) { + this.g = .5 * (this.f - 1.0/this.f); + this.gama = Proj4js.common.asinz(Math.sin(this.alpha) / this.d); + this.longc= this.longc - Proj4js.common.asinz(this.g * Math.tan(this.gama))/this.bl; + + /* Report parameters common to format B + -------------------------------------*/ + //genrpt(azimuth * R2D,"Azimuth of Central Line: "); + //cenlon(lon_origin); + // cenlat(lat_origin); + + this.con = Math.abs(this.lat0); + if ((this.con > 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); + + if (this.lat0>= 0) { + this.u = (this.al / this.bl) * Math.atan(Math.sqrt(this.d*this.d - 1.0)/this.cosaz); + } else { + this.u = -(this.al / this.bl) *Math.atan(Math.sqrt(this.d*this.d - 1.0)/this.cosaz); + } + } else { + Proj4js.reportError("omerc:Init:DataError"); + } + } else { + this.sinphi =Math. sin(this.at1); + this.ts1 = Proj4js.common.tsfnz(this.e,this.lat1,this.sinphi); + 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 = .5 * (this.f - 1.0/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; + if (this.dlon < -Proj4js.common.PI) this.lon2 = this.lon2 - 2.0 * Proj4js.common.PI; + if (this.dlon > Proj4js.common.PI) this.lon2 = this.lon2 + 2.0 * Proj4js.common.PI; + this.dlon = this.lon1 - this.lon2; + this.longc = .5 * (this.lon1 + this.lon2) -Math.atan(this.j * Math.tan(.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)); + + /* Report parameters common to format A + -------------------------------------*/ + + if (Math.abs(this.lat1 - this.lat2) <= Proj4js.common.EPSLN) { + Proj4js.reportError("omercInitDataError"); + //return(202); + } else { + this.con = Math.abs(this.lat1); + } + if ((this.con <= Proj4js.common.EPSLN) || (Math.abs(this.con - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN)) { + Proj4js.reportError("omercInitDataError"); + //return(202); + } else { + if (Math.abs(Math.abs(this.lat0) - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN) { + Proj4js.reportError("omercInitDataError"); + //return(202); + } + } + + this.singam=Math.sin(this.gam); + this.cosgam=Math.cos(this.gam); + + this.sinaz=Math.sin(this.alpha); + this.cosaz=Math.cos(this.alpha); + + + if (this.lat0 >= 0) { + this.u = (this.al/this.bl) * Math.atan(Math.sqrt(this.d * this.d - 1.0)/this.cosaz); + } else { + this.u = -(this.al/this.bl) * Math.atan(Math.sqrt(this.d * this.d - 1.0)/this.cosaz); + } + } + }, + + + /* Oblique Mercator forward equations--mapping lat,long to x,y + ----------------------------------------------------------*/ + forward: function(p) { + var theta; /* angle */ + var sin_phi, cos_phi;/* sin and cos value */ + var b; /* temporary values */ + var c, t, tq; /* temporary values */ + var con, n, ml; /* cone constant, small m */ + var q,us,vl; + var ul,vs; + var s; + var dlon; + var ts1; + + var lon=p.x; + var lat=p.y; + /* Forward equations + -----------------*/ + sin_phi = Math.sin(lat); + dlon = Proj4js.common.adjust_lon(lon - this.longc); + vl = Math.sin(this.bl * dlon); + if (Math.abs(Math.abs(lat) - Proj4js.common.HALF_PI) > Proj4js.common.EPSLN) { + ts1 = Proj4js.common.tsfnz(this.e,lat,sin_phi); + q = this.el / (Math.pow(ts1,this.bl)); + s = .5 * (q - 1.0 / q); + t = .5 * (q + 1.0/ q); + ul = (s * this.singam - vl * this.cosgam) / t; + con = Math.cos(this.bl * dlon); + if (Math.abs(con) < .0000001) { + us = this.al * this.bl * dlon; + } else { + us = this.al * Math.atan((s * this.cosgam + vl * this.singam) / con)/this.bl; + if (con < 0) us = us + Proj4js.common.PI * this.al / this.bl; + } + } else { + if (lat >= 0) { + ul = this.singam; + } else { + ul = -this.singam; + } + us = this.al * lat / this.bl; + } + if (Math.abs(Math.abs(ul) - 1.0) <= Proj4js.common.EPSLN) { + //alert("Point projects into infinity","omer-for"); + Proj4js.reportError("omercFwdInfinity"); + //return(205); + } + vs = .5 * this.al * Math.log((1.0 - ul)/(1.0 + ul)) / this.bl; + us = us - this.u; + var x = this.x0 + vs * this.cosaz + us * this.sinaz; + var y = this.y0 + us * this.cosaz - vs * this.sinaz; + + p.x=x; + p.y=y; + return p; + }, + + inverse: function(p) { + var delta_lon; /* Delta longitude (Given longitude - center */ + var theta; /* angle */ + var delta_theta; /* adjusted longitude */ + var sin_phi, cos_phi;/* sin and cos value */ + var b; /* temporary values */ + var c, t, tq; /* temporary values */ + var con, n, ml; /* cone constant, small m */ + var vs,us,q,s,ts1; + var vl,ul,bs; + var lon, lat; + var flag; + + /* Inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + flag = 0; + vs = p.x * this.cosaz - p.y * this.sinaz; + us = p.y * this.cosaz + p.x * this.sinaz; + us = us + this.u; + q = Math.exp(-this.bl * vs / this.al); + s = .5 * (q - 1.0/q); + t = .5 * (q + 1.0/q); + vl = Math.sin(this.bl * us / this.al); + ul = (vl * this.cosgam + s * this.singam)/t; + if (Math.abs(Math.abs(ul) - 1.0) <= Proj4js.common.EPSLN) + { + lon = this.longc; + if (ul >= 0.0) { + lat = Proj4js.common.HALF_PI; + } else { + lat = -Proj4js.common.HALF_PI; + } + } else { + con = 1.0 / this.bl; + ts1 =Math.pow((this.el / Math.sqrt((1.0 + ul) / (1.0 - ul))),con); + lat = Proj4js.common.phi2z(this.e,ts1); + //if (flag != 0) + //return(flag); + //~ con = Math.cos(this.bl * us /al); + theta = this.longc - Math.atan2((s * this.cosgam - vl * this.singam) , con)/this.bl; + lon = Proj4js.common.adjust_lon(theta); + } + p.x=lon; + p.y=lat; + return p; + } +}; +/* ====================================================================== + projCode/lcc.js + ====================================================================== */ + +/******************************************************************************* +NAME LAMBERT CONFORMAL CONIC + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Lambert Conformal Conic projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government +*******************************************************************************/ + + +//<2104> +proj=lcc +lat_1=10.16666666666667 +lat_0=10.16666666666667 +lon_0=-71.60561777777777 +k_0=1 +x0=-17044 +x0=-23139.97 +ellps=intl +units=m +no_defs no_defs + +// Initialize the Lambert Conformal conic projection +// ----------------------------------------------------------------- + +//Proj4js.Proj.lcc = Class.create(); +Proj4js.Proj.lcc = { + init : function() { + + // array of: r_maj,r_min,lat1,lat2,c_lon,c_lat,false_east,false_north + //double c_lat; /* center latitude */ + //double c_lon; /* center longitude */ + //double lat1; /* first standard parallel */ + //double lat2; /* second standard parallel */ + //double r_maj; /* major axis */ + //double r_min; /* minor axis */ + //double false_east; /* x offset in meters */ + //double false_north; /* y offset in meters */ + + if (!this.lat2){this.lat2=this.lat0;}//if lat2 is not defined + if (!this.k0) this.k0 = 1.0; + + // Standard Parallels cannot be equal and on opposite sides of the equator + if (Math.abs(this.lat1+this.lat2) < Proj4js.common.EPSLN) { + Proj4js.reportError("lcc:init: Equal Latitudes"); + return; + } + + var temp = this.b / this.a; + this.e = Math.sqrt(1.0 - temp*temp); + + var sin1 = Math.sin(this.lat1); + var cos1 = Math.cos(this.lat1); + var ms1 = Proj4js.common.msfnz(this.e, sin1, cos1); + var ts1 = Proj4js.common.tsfnz(this.e, this.lat1, sin1); + + var sin2 = Math.sin(this.lat2); + var cos2 = Math.cos(this.lat2); + var ms2 = Proj4js.common.msfnz(this.e, sin2, cos2); + var ts2 = Proj4js.common.tsfnz(this.e, this.lat2, sin2); + + var ts0 = Proj4js.common.tsfnz(this.e, this.lat0, Math.sin(this.lat0)); + + if (Math.abs(this.lat1 - this.lat2) > Proj4js.common.EPSLN) { + this.ns = Math.log(ms1/ms2)/Math.log(ts1/ts2); + } else { + this.ns = sin1; + } + this.f0 = ms1 / (this.ns * Math.pow(ts1, this.ns)); + this.rh = this.a * this.f0 * Math.pow(ts0, this.ns); + if (!this.title) this.title = "Lambert Conformal Conic"; + }, + + + // Lambert Conformal conic forward equations--mapping lat,long to x,y + // ----------------------------------------------------------------- + forward : function(p) { + + var lon = p.x; + var lat = p.y; + + // convert to radians + if ( lat <= 90.0 && lat >= -90.0 && lon <= 180.0 && lon >= -180.0) { + //lon = lon * Proj4js.common.D2R; + //lat = lat * Proj4js.common.D2R; + } else { + Proj4js.reportError("lcc:forward: llInputOutOfRange: "+ lon +" : " + lat); + return null; + } + + var con = Math.abs( Math.abs(lat) - Proj4js.common.HALF_PI); + var ts, rh1; + if (con > Proj4js.common.EPSLN) { + ts = Proj4js.common.tsfnz(this.e, lat, Math.sin(lat) ); + rh1 = this.a * this.f0 * Math.pow(ts, this.ns); + } else { + con = lat * this.ns; + if (con <= 0) { + Proj4js.reportError("lcc:forward: No Projection"); + return null; + } + rh1 = 0; + } + var theta = this.ns * Proj4js.common.adjust_lon(lon - this.long0); + p.x = this.k0 * (rh1 * Math.sin(theta)) + this.x0; + p.y = this.k0 * (this.rh - rh1 * Math.cos(theta)) + this.y0; + + return p; + }, + + // Lambert Conformal Conic inverse equations--mapping x,y to lat/long + // ----------------------------------------------------------------- + inverse : function(p) { + + var rh1, con, ts; + var lat, lon; + var x = (p.x - this.x0)/this.k0; + var y = (this.rh - (p.y - this.y0)/this.k0); + if (this.ns > 0) { + rh1 = Math.sqrt (x * x + y * y); + con = 1.0; + } else { + rh1 = -Math.sqrt (x * x + y * y); + con = -1.0; + } + var theta = 0.0; + if (rh1 != 0) { + theta = Math.atan2((con * x),(con * y)); + } + if ((rh1 != 0) || (this.ns > 0.0)) { + con = 1.0/this.ns; + ts = Math.pow((rh1/(this.a * this.f0)), con); + lat = Proj4js.common.phi2z(this.e, ts); + if (lat == -9999) return null; + } else { + lat = -Proj4js.common.HALF_PI; + } + lon = Proj4js.common.adjust_lon(theta/this.ns + this.long0); + + p.x = lon; + p.y = lat; + return p; + } +}; + + + + +/* ====================================================================== + projCode/laea.js + ====================================================================== */ + +/******************************************************************************* +NAME LAMBERT AZIMUTHAL EQUAL-AREA + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Lambert Azimuthal Equal-Area projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +D. Steinwand, EROS March, 1991 + +This function was adapted from the Lambert Azimuthal Equal Area projection +code (FORTRAN) in the General Cartographic Transformation Package software +which is available from the U.S. Geological Survey National Mapping Division. + +ALGORITHM REFERENCES + +1. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder, + The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355. + +2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +3. "Software Documentation for GCTP General Cartographic Transformation + Package", U.S. Geological Survey National Mapping Division, May 1982. +*******************************************************************************/ + +Proj4js.Proj.laea = { + S_POLE: 1, + N_POLE: 2, + EQUIT: 3, + OBLIQ: 4, + + +/* Initialize the Lambert Azimuthal Equal Area projection + ------------------------------------------------------*/ + init: function() { + var t = Math.abs(this.lat0); + if (Math.abs(t - Proj4js.common.HALF_PI) < Proj4js.common.EPSLN) { + this.mode = this.lat0 < 0. ? this.S_POLE : this.N_POLE; + } else if (Math.abs(t) < Proj4js.common.EPSLN) { + this.mode = this.EQUIT; + } else { + this.mode = this.OBLIQ; + } + if (this.es > 0) { + var sinphi; + + this.qp = Proj4js.common.qsfnz(this.e, 1.0); + this.mmf = .5 / (1. - this.es); + this.apa = this.authset(this.es); + switch (this.mode) { + case this.N_POLE: + case this.S_POLE: + this.dd = 1.; + break; + case this.EQUIT: + this.rq = Math.sqrt(.5 * this.qp); + this.dd = 1. / this.rq; + this.xmf = 1.; + this.ymf = .5 * this.qp; + break; + case this.OBLIQ: + this.rq = Math.sqrt(.5 * this.qp); + sinphi = Math.sin(this.lat0); + this.sinb1 = Proj4js.common.qsfnz(this.e, sinphi) / this.qp; + this.cosb1 = Math.sqrt(1. - this.sinb1 * this.sinb1); + this.dd = Math.cos(this.lat0) / (Math.sqrt(1. - this.es * sinphi * sinphi) * this.rq * this.cosb1); + this.ymf = (this.xmf = this.rq) / this.dd; + this.xmf *= this.dd; + break; + } + } else { + if (this.mode == this.OBLIQ) { + this.sinph0 = Math.sin(this.lat0); + this.cosph0 = Math.cos(this.lat0); + } + } + }, + +/* Lambert Azimuthal Equal Area forward equations--mapping lat,long to x,y + -----------------------------------------------------------------------*/ + forward: function(p) { + + /* Forward equations + -----------------*/ + var x,y; + var lam=p.x; + var phi=p.y; + lam = Proj4js.common.adjust_lon(lam - this.long0); + + if (this.sphere) { + var coslam, cosphi, sinphi; + + sinphi = Math.sin(phi); + cosphi = Math.cos(phi); + coslam = Math.cos(lam); + switch (this.mode) { + case this.OBLIQ: + case this.EQUIT: + y = (this.mode == this.EQUIT) ? 1. + cosphi * coslam : 1. + this.sinph0 * sinphi + this.cosph0 * cosphi * coslam; + if (y <= Proj4js.common.EPSLN) { + Proj4js.reportError("laea:fwd:y less than eps"); + return null; + } + y = Math.sqrt(2. / y); + x = y * cosphi * Math.sin(lam); + y *= (this.mode == this.EQUIT) ? sinphi : this.cosph0 * sinphi - this.sinph0 * cosphi * coslam; + break; + case this.N_POLE: + coslam = -coslam; + case this.S_POLE: + if (Math.abs(phi + this.phi0) < Proj4js.common.EPSLN) { + Proj4js.reportError("laea:fwd:phi < eps"); + return null; + } + y = Proj4js.common.FORTPI - phi * .5; + y = 2. * ((this.mode == this.S_POLE) ? Math.cos(y) : Math.sin(y)); + x = y * Math.sin(lam); + y *= coslam; + break; + } + } else { + var coslam, sinlam, sinphi, q, sinb=0.0, cosb=0.0, b=0.0; + + coslam = Math.cos(lam); + sinlam = Math.sin(lam); + sinphi = Math.sin(phi); + q = Proj4js.common.qsfnz(this.e, sinphi); + if (this.mode == this.OBLIQ || this.mode == this.EQUIT) { + sinb = q / this.qp; + cosb = Math.sqrt(1. - sinb * sinb); + } + switch (this.mode) { + case this.OBLIQ: + b = 1. + this.sinb1 * sinb + this.cosb1 * cosb * coslam; + break; + case this.EQUIT: + b = 1. + cosb * coslam; + break; + case this.N_POLE: + b = Proj4js.common.HALF_PI + phi; + q = this.qp - q; + break; + case this.S_POLE: + b = phi - Proj4js.common.HALF_PI; + q = this.qp + q; + break; + } + if (Math.abs(b) < Proj4js.common.EPSLN) { + Proj4js.reportError("laea:fwd:b < eps"); + return null; + } + switch (this.mode) { + case this.OBLIQ: + case this.EQUIT: + b = Math.sqrt(2. / b); + if (this.mode == this.OBLIQ) { + y = this.ymf * b * (this.cosb1 * sinb - this.sinb1 * cosb * coslam); + } else { + y = (b = Math.sqrt(2. / (1. + cosb * coslam))) * sinb * this.ymf; + } + x = this.xmf * b * cosb * sinlam; + break; + case this.N_POLE: + case this.S_POLE: + if (q >= 0.) { + x = (b = Math.sqrt(q)) * sinlam; + y = coslam * ((this.mode == this.S_POLE) ? b : -b); + } else { + x = y = 0.; + } + break; + } + } + + //v 1.0 + /* + var sin_lat=Math.sin(lat); + var cos_lat=Math.cos(lat); + + var sin_delta_lon=Math.sin(delta_lon); + var cos_delta_lon=Math.cos(delta_lon); + + var g =this.sin_lat_o * sin_lat +this.cos_lat_o * cos_lat * cos_delta_lon; + if (g == -1.0) { + Proj4js.reportError("laea:fwd:Point projects to a circle of radius "+ 2.0 * R); + return null; + } + var ksp = this.a * Math.sqrt(2.0 / (1.0 + g)); + var x = ksp * cos_lat * sin_delta_lon + this.x0; + var y = ksp * (this.cos_lat_o * sin_lat - this.sin_lat_o * cos_lat * cos_delta_lon) + this.y0; + */ + p.x = this.a*x + this.x0; + p.y = this.a*y + this.y0; + return p; + },//lamazFwd() + +/* Inverse equations + -----------------*/ + inverse: function(p) { + p.x -= this.x0; + p.y -= this.y0; + var x = p.x/this.a; + var y = p.y/this.a; + var lam, phi; + + if (this.sphere) { + var cosz=0.0, rh, sinz=0.0; + + rh = Math.sqrt(x*x + y*y); + phi = rh * .5; + if (phi > 1.) { + Proj4js.reportError("laea:Inv:DataError"); + return null; + } + phi = 2. * Math.asin(phi); + if (this.mode == this.OBLIQ || this.mode == this.EQUIT) { + sinz = Math.sin(phi); + cosz = Math.cos(phi); + } + switch (this.mode) { + case this.EQUIT: + phi = (Math.abs(rh) <= Proj4js.common.EPSLN) ? 0. : Math.asin(y * sinz / rh); + x *= sinz; + y = cosz * rh; + break; + case this.OBLIQ: + phi = (Math.abs(rh) <= Proj4js.common.EPSLN) ? this.phi0 : Math.asin(cosz * this.sinph0 + y * sinz * this.cosph0 / rh); + x *= sinz * this.cosph0; + y = (cosz - Math.sin(phi) * this.sinph0) * rh; + break; + case this.N_POLE: + y = -y; + phi = Proj4js.common.HALF_PI - phi; + break; + case this.S_POLE: + phi -= Proj4js.common.HALF_PI; + break; + } + lam = (y == 0. && (this.mode == this.EQUIT || this.mode == this.OBLIQ)) ? 0. : Math.atan2(x, y); + } else { + var cCe, sCe, q, rho, ab=0.0; + + switch (this.mode) { + case this.EQUIT: + case this.OBLIQ: + x /= this.dd; + y *= this.dd; + rho = Math.sqrt(x*x + y*y); + if (rho < Proj4js.common.EPSLN) { + p.x = 0.; + p.y = this.phi0; + return p; + } + sCe = 2. * Math.asin(.5 * rho / this.rq); + cCe = Math.cos(sCe); + x *= (sCe = Math.sin(sCe)); + if (this.mode == this.OBLIQ) { + ab = cCe * this.sinb1 + y * sCe * this.cosb1 / rho + q = this.qp * ab; + y = rho * this.cosb1 * cCe - y * this.sinb1 * sCe; + } else { + ab = y * sCe / rho; + q = this.qp * ab; + y = rho * cCe; + } + break; + case this.N_POLE: + y = -y; + case this.S_POLE: + q = (x * x + y * y); + if (!q ) { + p.x = 0.; + p.y = this.phi0; + return p; + } + /* + q = this.qp - q; + */ + ab = 1. - q / this.qp; + if (this.mode == this.S_POLE) { + ab = - ab; + } + break; + } + lam = Math.atan2(x, y); + phi = this.authlat(Math.asin(ab), this.apa); + } + + /* + var Rh = Math.Math.sqrt(p.x *p.x +p.y * p.y); + var temp = Rh / (2.0 * this.a); + + if (temp > 1) { + Proj4js.reportError("laea:Inv:DataError"); + return null; + } + + var z = 2.0 * Proj4js.common.asinz(temp); + var sin_z=Math.sin(z); + var cos_z=Math.cos(z); + + var lon =this.long0; + if (Math.abs(Rh) > Proj4js.common.EPSLN) { + var lat = Proj4js.common.asinz(this.sin_lat_o * cos_z +this. cos_lat_o * sin_z *p.y / Rh); + var temp =Math.abs(this.lat0) - Proj4js.common.HALF_PI; + if (Math.abs(temp) > Proj4js.common.EPSLN) { + temp = cos_z -this.sin_lat_o * Math.sin(lat); + if(temp!=0.0) lon=Proj4js.common.adjust_lon(this.long0+Math.atan2(p.x*sin_z*this.cos_lat_o,temp*Rh)); + } else if (this.lat0 < 0.0) { + lon = Proj4js.common.adjust_lon(this.long0 - Math.atan2(-p.x,p.y)); + } else { + lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2(p.x, -p.y)); + } + } else { + lat = this.lat0; + } + */ + //return(OK); + p.x = Proj4js.common.adjust_lon(this.long0+lam); + p.y = phi; + return p; + },//lamazInv() + +/* determine latitude from authalic latitude */ + P00: .33333333333333333333, + P01: .17222222222222222222, + P02: .10257936507936507936, + P10: .06388888888888888888, + P11: .06640211640211640211, + P20: .01641501294219154443, + + authset: function(es) { + var t; + var APA = new Array(); + APA[0] = es * this.P00; + t = es * es; + APA[0] += t * this.P01; + APA[1] = t * this.P10; + t *= es; + APA[0] += t * this.P02; + APA[1] += t * this.P11; + APA[2] = t * this.P20; + return APA; + }, + + authlat: function(beta, APA) { + var t = beta+beta; + return(beta + APA[0] * Math.sin(t) + APA[1] * Math.sin(t+t) + APA[2] * Math.sin(t+t+t)); + } + +}; + + + +/* ====================================================================== + projCode/aeqd.js + ====================================================================== */ + +Proj4js.Proj.aeqd = { + + init : function() { + this.sin_p12=Math.sin(this.lat0); + this.cos_p12=Math.cos(this.lat0); + }, + + forward: function(p) { + var lon=p.x; + var lat=p.y; + var ksp; + + var sinphi=Math.sin(p.y); + var cosphi=Math.cos(p.y); + var dlon = Proj4js.common.adjust_lon(lon - this.long0); + var coslon = Math.cos(dlon); + var g = this.sin_p12 * sinphi + this.cos_p12 * cosphi * coslon; + if (Math.abs(Math.abs(g) - 1.0) < Proj4js.common.EPSLN) { + ksp = 1.0; + if (g < 0.0) { + Proj4js.reportError("aeqd:Fwd:PointError"); + return; + } + } else { + var z = Math.acos(g); + ksp = z/Math.sin(z); + } + p.x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon); + p.y = this.y0 + this.a * ksp * (this.cos_p12 * sinphi - this.sin_p12 * cosphi * coslon); + return p; + }, + + inverse: function(p){ + p.x -= this.x0; + p.y -= this.y0; + + var rh = Math.sqrt(p.x * p.x + p.y *p.y); + if (rh > (2.0 * Proj4js.common.HALF_PI * this.a)) { + Proj4js.reportError("aeqdInvDataError"); + return; + } + var z = rh / this.a; + + var sinz=Math.sin(z); + var cosz=Math.cos(z); + + var lon = this.long0; + var lat; + if (Math.abs(rh) <= Proj4js.common.EPSLN) { + lat = this.lat0; + } else { + lat = Proj4js.common.asinz(cosz * this.sin_p12 + (p.y * sinz * this.cos_p12) / rh); + var con = Math.abs(this.lat0) - Proj4js.common.HALF_PI; + if (Math.abs(con) <= Proj4js.common.EPSLN) { + if (this.lat0 >= 0.0) { + lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2(p.x , -p.y)); + } else { + lon = Proj4js.common.adjust_lon(this.long0 - Math.atan2(-p.x , p.y)); + } + } else { + con = cosz - this.sin_p12 * Math.sin(lat); + if ((Math.abs(con) < Proj4js.common.EPSLN) && (Math.abs(p.x) < Proj4js.common.EPSLN)) { + //no-op, just keep the lon value as is + } else { + var temp = Math.atan2((p.x * sinz * this.cos_p12), (con * rh)); + lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2((p.x * sinz * this.cos_p12), (con * rh))); + } + } + } + + p.x = lon; + p.y = lat; + return p; + } +}; +/* ====================================================================== + projCode/moll.js + ====================================================================== */ + +/******************************************************************************* +NAME MOLLWEIDE + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the MOllweide projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +D. Steinwand, EROS May, 1991; Updated Sept, 1992; Updated Feb, 1993 +S. Nelson, EDC Jun, 2993; Made corrections in precision and + number of iterations. + +ALGORITHM REFERENCES + +1. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. + +2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. +*******************************************************************************/ + +Proj4js.Proj.moll = { + + /* Initialize the Mollweide projection + ------------------------------------*/ + init: function(){ + //no-op + }, + + /* Mollweide forward equations--mapping lat,long to x,y + ----------------------------------------------------*/ + forward: function(p) { + + /* Forward equations + -----------------*/ + var lon=p.x; + var lat=p.y; + + var delta_lon = Proj4js.common.adjust_lon(lon - this.long0); + var theta = lat; + var con = Proj4js.common.PI * Math.sin(lat); + + /* Iterate using the Newton-Raphson method to find theta + -----------------------------------------------------*/ + for (var i=0;true;i++) { + var delta_theta = -(theta + Math.sin(theta) - con)/ (1.0 + Math.cos(theta)); + theta += delta_theta; + if (Math.abs(delta_theta) < Proj4js.common.EPSLN) break; + if (i >= 50) { + Proj4js.reportError("moll:Fwd:IterationError"); + //return(241); + } + } + theta /= 2.0; + + /* If the latitude is 90 deg, force the x coordinate to be "0 + false easting" + this is done here because of precision problems with "cos(theta)" + --------------------------------------------------------------------------*/ + if (Proj4js.common.PI/2 - Math.abs(lat) < Proj4js.common.EPSLN) delta_lon =0; + var x = 0.900316316158 * this.a * delta_lon * Math.cos(theta) + this.x0; + var y = 1.4142135623731 * this.a * Math.sin(theta) + this.y0; + + p.x=x; + p.y=y; + return p; + }, + + inverse: function(p){ + var theta; + var arg; + + /* Inverse equations + -----------------*/ + p.x-= this.x0; + //~ p.y -= this.y0; + var arg = p.y / (1.4142135623731 * this.a); + + /* Because of division by zero problems, 'arg' can not be 1.0. Therefore + a number very close to one is used instead. + -------------------------------------------------------------------*/ + if(Math.abs(arg) > 0.999999999999) arg=0.999999999999; + var theta =Math.asin(arg); + var lon = Proj4js.common.adjust_lon(this.long0 + (p.x / (0.900316316158 * this.a * Math.cos(theta)))); + if(lon < (-Proj4js.common.PI)) lon= -Proj4js.common.PI; + if(lon > Proj4js.common.PI) lon= Proj4js.common.PI; + arg = (2.0 * theta + Math.sin(2.0 * theta)) / Proj4js.common.PI; + if(Math.abs(arg) > 1.0)arg=1.0; + var lat = Math.asin(arg); + //return(OK); + + p.x=lon; + p.y=lat; + return p; + } +}; + diff --git a/ajax/libs/proj4js/1.1.0/proj4js-compressed.js b/ajax/libs/proj4js/1.1.0/proj4js-compressed.js new file mode 100755 index 000000000..d1f9c3f0a --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/proj4js-compressed.js @@ -0,0 +1,266 @@ +/* + proj4js.js -- Javascript reprojection library. + + Authors: Mike Adair madairATdmsolutions.ca + Richard Greenwood richATgreenwoodmap.com + Didier Richard didier.richardATign.fr + Stephen Irons stephen.ironsATclear.net.nz + Olivier Terral oterralATgmail.com + + License: + Copyright (c) 2012, Mike Adair, Richard Greenwood, Didier Richard, + Stephen Irons and Olivier Terral + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Note: This program is an almost direct port of the C library PROJ.4. +*/ +var Proj4js={defaultDatum:'WGS84',transform:function(source,dest,point){if(!source.readyToUse){this.reportError("Proj4js initialization for:"+source.srsCode+" not yet complete");return point;} +if(!dest.readyToUse){this.reportError("Proj4js initialization for:"+dest.srsCode+" not yet complete");return point;} +if(source.datum&&dest.datum&&(((source.datum.datum_type==Proj4js.common.PJD_3PARAM||source.datum.datum_type==Proj4js.common.PJD_7PARAM)&&dest.datumCode!="WGS84")||((dest.datum.datum_type==Proj4js.common.PJD_3PARAM||dest.datum.datum_type==Proj4js.common.PJD_7PARAM)&&source.datumCode!="WGS84"))){var wgs84=Proj4js.WGS84;this.transform(source,wgs84,point);source=wgs84;} +if(source.axis!="enu"){this.adjust_axis(source,false,point);} +if(source.projName=="longlat"){point.x*=Proj4js.common.D2R;point.y*=Proj4js.common.D2R;}else{if(source.to_meter){point.x*=source.to_meter;point.y*=source.to_meter;} +source.inverse(point);} +if(source.from_greenwich){point.x+=source.from_greenwich;} +point=this.datum_transform(source.datum,dest.datum,point);if(dest.from_greenwich){point.x-=dest.from_greenwich;} +if(dest.projName=="longlat"){point.x*=Proj4js.common.R2D;point.y*=Proj4js.common.R2D;}else{dest.forward(point);if(dest.to_meter){point.x/=dest.to_meter;point.y/=dest.to_meter;}} +if(dest.axis!="enu"){this.adjust_axis(dest,true,point);} +return point;},datum_transform:function(source,dest,point){if(source.compare_datums(dest)){return point;} +if(source.datum_type==Proj4js.common.PJD_NODATUM||dest.datum_type==Proj4js.common.PJD_NODATUM){return point;} +if(source.es!=dest.es||source.a!=dest.a||source.datum_type==Proj4js.common.PJD_3PARAM||source.datum_type==Proj4js.common.PJD_7PARAM||dest.datum_type==Proj4js.common.PJD_3PARAM||dest.datum_type==Proj4js.common.PJD_7PARAM) +{source.geodetic_to_geocentric(point);if(source.datum_type==Proj4js.common.PJD_3PARAM||source.datum_type==Proj4js.common.PJD_7PARAM){source.geocentric_to_wgs84(point);} +if(dest.datum_type==Proj4js.common.PJD_3PARAM||dest.datum_type==Proj4js.common.PJD_7PARAM){dest.geocentric_from_wgs84(point);} +dest.geocentric_to_geodetic(point);} +return point;},adjust_axis:function(crs,denorm,point){var xin=point.x,yin=point.y,zin=point.z||0.0;var v,t;for(var i=0;i<3;i++){if(denorm&&i==2&&point.z===undefined){continue;} +if(i==0){v=xin;t='x';} +else if(i==1){v=yin;t='y';} +else{v=zin;t='z';} +switch(crs.axis[i]){case'e':point[t]=v;break;case'w':point[t]=-v;break;case'n':point[t]=v;break;case's':point[t]=-v;break;case'u':if(point[t]!==undefined){point.z=v;} +break;case'd':if(point[t]!==undefined){point.z=-v;} +break;default:alert("ERROR: unknow axis ("+crs.axis[i]+") - check definition of "+crs.projName);return null;}} +return point;},reportError:function(msg){},extend:function(destination,source){destination=destination||{};if(source){for(var property in source){var value=source[property];if(value!==undefined){destination[property]=value;}}} +return destination;},Class:function(){var Class=function(){this.initialize.apply(this,arguments);};var extended={};var parent;for(var i=0;i-1)&&(index+scriptNameLen==src.length)){this.libPath=src.slice(0,-scriptNameLen);break;}}} +return this.libPath||"";},loadScript:function(url,onload,onfail,loadCheck){var script=document.createElement('script');script.defer=false;script.type="text/javascript";script.id=url;script.src=url;script.onload=onload;script.onerror=onfail;script.loadCheck=loadCheck;if(/MSIE/.test(navigator.userAgent)){script.onreadystatechange=this.checkReadyState;} +document.getElementsByTagName('head')[0].appendChild(script);},checkReadyState:function(){if(this.readyState=='loaded'){if(!this.loadCheck()){this.onerror();}else{this.onload();}}}};Proj4js.Proj=Proj4js.Class({readyToUse:false,title:null,projName:null,units:null,datum:null,x0:0,y0:0,localCS:false,queue:null,initialize:function(srsCode,callback){this.srsCodeInput=srsCode;this.queue=[];if(callback){this.queue.push(callback);} +if((srsCode.indexOf('GEOGCS')>=0)||(srsCode.indexOf('GEOCCS')>=0)||(srsCode.indexOf('PROJCS')>=0)||(srsCode.indexOf('LOCAL_CS')>=0)){this.parseWKT(srsCode);this.deriveConstants();this.loadProjCode(this.projName);return;} +if(srsCode.indexOf('urn:')==0){var urn=srsCode.split(':');if((urn[1]=='ogc'||urn[1]=='x-ogc')&&(urn[2]=='def')&&(urn[3]=='crs')){srsCode=urn[4]+':'+urn[urn.length-1];}}else if(srsCode.indexOf('http://')==0){var url=srsCode.split('#');if(url[0].match(/epsg.org/)){srsCode='EPSG:'+url[1];}else if(url[0].match(/RIG.xml/)){srsCode='IGNF:'+url[1];}} +this.srsCode=srsCode.toUpperCase();if(this.srsCode.indexOf("EPSG")==0){this.srsCode=this.srsCode;this.srsAuth='epsg';this.srsProjNumber=this.srsCode.substring(5);}else if(this.srsCode.indexOf("IGNF")==0){this.srsCode=this.srsCode;this.srsAuth='IGNF';this.srsProjNumber=this.srsCode.substring(5);}else if(this.srsCode.indexOf("CRS")==0){this.srsCode=this.srsCode;this.srsAuth='CRS';this.srsProjNumber=this.srsCode.substring(4);}else{this.srsAuth='';this.srsProjNumber=this.srsCode;} +this.loadProjDefinition();},loadProjDefinition:function(){if(Proj4js.defs[this.srsCode]){this.defsLoaded();return;} +var url=Proj4js.getScriptLocation()+'defs/'+this.srsAuth.toUpperCase()+this.srsProjNumber+'.js';Proj4js.loadScript(url,Proj4js.bind(this.defsLoaded,this),Proj4js.bind(this.loadFromService,this),Proj4js.bind(this.checkDefsLoaded,this));},loadFromService:function(){var url=Proj4js.defsLookupService+'/'+this.srsAuth+'/'+this.srsProjNumber+'/proj4js/';Proj4js.loadScript(url,Proj4js.bind(this.defsLoaded,this),Proj4js.bind(this.defsFailed,this),Proj4js.bind(this.checkDefsLoaded,this));},defsLoaded:function(){this.parseDefs();this.loadProjCode(this.projName);},checkDefsLoaded:function(){if(Proj4js.defs[this.srsCode]){return true;}else{return false;}},defsFailed:function(){Proj4js.reportError('failed to load projection definition for: '+this.srsCode);Proj4js.defs[this.srsCode]=Proj4js.defs['WGS84'];this.defsLoaded();},loadProjCode:function(projName){if(Proj4js.Proj[projName]){this.initTransforms();return;} +var url=Proj4js.getScriptLocation()+'projCode/'+projName+'.js';Proj4js.loadScript(url,Proj4js.bind(this.loadProjCodeSuccess,this,projName),Proj4js.bind(this.loadProjCodeFailure,this,projName),Proj4js.bind(this.checkCodeLoaded,this,projName));},loadProjCodeSuccess:function(projName){if(Proj4js.Proj[projName].dependsOn){this.loadProjCode(Proj4js.Proj[projName].dependsOn);}else{this.initTransforms();}},loadProjCodeFailure:function(projName){Proj4js.reportError("failed to find projection file for: "+projName);},checkCodeLoaded:function(projName){if(Proj4js.Proj[projName]){return true;}else{return false;}},initTransforms:function(){Proj4js.extend(this,Proj4js.Proj[this.projName]);this.init();this.readyToUse=true;if(this.queue){var item;while((item=this.queue.shift())){item.call(this,this);}}},wktRE:/^(\w+)\[(.*)\]$/,parseWKT:function(wkt){var wktMatch=wkt.match(this.wktRE);if(!wktMatch)return;var wktObject=wktMatch[1];var wktContent=wktMatch[2];var wktTemp=wktContent.split(",");var wktName;if(wktObject.toUpperCase()=="TOWGS84"){wktName=wktObject;}else{wktName=wktTemp.shift();} +wktName=wktName.replace(/^\"/,"");wktName=wktName.replace(/\"$/,"");var wktArray=new Array();var bkCount=0;var obj="";for(var i=0;i1.0e-7){con=eccent*sinphi;return((1.0-eccent*eccent)*(sinphi/(1.0-con*con)-(.5/eccent)*Math.log((1.0-con)/(1.0+con))));}else{return(2.0*sinphi);}},asinz:function(x){if(Math.abs(x)>1.0){x=(x>1.0)?1.0:-1.0;} +return Math.asin(x);},e0fn:function(x){return(1.0-0.25*x*(1.0+x/16.0*(3.0+1.25*x)));},e1fn:function(x){return(0.375*x*(1.0+0.25*x*(1.0+0.46875*x)));},e2fn:function(x){return(0.05859375*x*x*(1.0+0.75*x));},e3fn:function(x){return(x*x*x*(35.0/3072.0));},mlfn:function(e0,e1,e2,e3,phi){return(e0*phi-e1*Math.sin(2.0*phi)+e2*Math.sin(4.0*phi)-e3*Math.sin(6.0*phi));},srat:function(esinp,exp){return(Math.pow((1.0-esinp)/(1.0+esinp),exp));},sign:function(x){if(x<0.0)return(-1);else return(1);},adjust_lon:function(x){x=(Math.abs(x)this.HALF_PI)return+Number.NaN;if(phi==this.HALF_PI)return Number.POSITIVE_INFINITY;if(phi==-1.0*this.HALF_PI)return-1.0*Number.POSITIVE_INFINITY;var con=eccent*sinphi;return Math.log(Math.tan((this.HALF_PI+phi)/2.0))+eccent*Math.log((1.0-con)/(1.0+con))/2.0;},fL:function(x,L){return 2.0*Math.atan(x*Math.exp(L))-this.HALF_PI;},invlatiso:function(eccent,ts){var phi=this.fL(1.0,ts);var Iphi=0.0;var con=0.0;do{Iphi=phi;con=eccent*Math.sin(Iphi);phi=this.fL(Math.exp(eccent*Math.log((1.0+con)/(1.0-con))/2.0),ts)}while(Math.abs(phi-Iphi)>1.0e-12);return phi;},sinh:function(x) +{var r=Math.exp(x);r=(r-1.0/r)/2.0;return r;},cosh:function(x) +{var r=Math.exp(x);r=(r+1.0/r)/2.0;return r;},tanh:function(x) +{var r=Math.exp(x);r=(r-1.0/r)/(r+1.0/r);return r;},asinh:function(x) +{var s=(x>=0?1.0:-1.0);return s*(Math.log(Math.abs(x)+Math.sqrt(x*x+1.0)));},acosh:function(x) +{return 2.0*Math.log(Math.sqrt((x+1.0)/2.0)+Math.sqrt((x-1.0)/2.0));},atanh:function(x) +{return Math.log((x-1.0)/(x+1.0))/2.0;},gN:function(a,e,sinphi) +{var temp=e*sinphi;return a/Math.sqrt(1.0-temp*temp);},pj_enfn:function(es){var en=new Array();en[0]=this.C00-es*(this.C02+es*(this.C04+es*(this.C06+es*this.C08)));en[1]=es*(this.C22-es*(this.C04+es*(this.C06+es*this.C08)));var t=es*es;en[2]=t*(this.C44-es*(this.C46+es*this.C48));t*=es;en[3]=t*(this.C66-es*this.C68);en[4]=t*es*this.C88;return en;},pj_mlfn:function(phi,sphi,cphi,en){cphi*=sphi;sphi*=sphi;return(en[0]*phi-cphi*(en[1]+sphi*(en[2]+sphi*(en[3]+sphi*en[4]))));},pj_inv_mlfn:function(arg,es,en){var k=1./(1.-es);var phi=arg;for(var i=Proj4js.common.MAX_ITER;i;--i){var s=Math.sin(phi);var t=1.-es*s*s;t=(this.pj_mlfn(phi,s,Math.cos(phi),en)-arg)*(t*Math.sqrt(t))*k;phi-=t;if(Math.abs(t)3){if(proj.datum_params[3]!=0||proj.datum_params[4]!=0||proj.datum_params[5]!=0||proj.datum_params[6]!=0){this.datum_type=Proj4js.common.PJD_7PARAM;proj.datum_params[3]*=Proj4js.common.SEC_TO_RAD;proj.datum_params[4]*=Proj4js.common.SEC_TO_RAD;proj.datum_params[5]*=Proj4js.common.SEC_TO_RAD;proj.datum_params[6]=(proj.datum_params[6]/1000000.0)+1.0;}}} +if(proj){this.a=proj.a;this.b=proj.b;this.es=proj.es;this.ep2=proj.ep2;this.datum_params=proj.datum_params;}},compare_datums:function(dest){if(this.datum_type!=dest.datum_type){return false;}else if(this.a!=dest.a||Math.abs(this.es-dest.es)>0.000000000050){return false;}else if(this.datum_type==Proj4js.common.PJD_3PARAM){return(this.datum_params[0]==dest.datum_params[0]&&this.datum_params[1]==dest.datum_params[1]&&this.datum_params[2]==dest.datum_params[2]);}else if(this.datum_type==Proj4js.common.PJD_7PARAM){return(this.datum_params[0]==dest.datum_params[0]&&this.datum_params[1]==dest.datum_params[1]&&this.datum_params[2]==dest.datum_params[2]&&this.datum_params[3]==dest.datum_params[3]&&this.datum_params[4]==dest.datum_params[4]&&this.datum_params[5]==dest.datum_params[5]&&this.datum_params[6]==dest.datum_params[6]);}else if(this.datum_type==Proj4js.common.PJD_GRIDSHIFT||dest.datum_type==Proj4js.common.PJD_GRIDSHIFT){alert("ERROR: Grid shift transformations are not implemented.");return false}else{return true;}},geodetic_to_geocentric:function(p){var Longitude=p.x;var Latitude=p.y;var Height=p.z?p.z:0;var X;var Y;var Z;var Error_Code=0;var Rn;var Sin_Lat;var Sin2_Lat;var Cos_Lat;if(Latitude<-Proj4js.common.HALF_PI&&Latitude>-1.001*Proj4js.common.HALF_PI){Latitude=-Proj4js.common.HALF_PI;}else if(Latitude>Proj4js.common.HALF_PI&&Latitude<1.001*Proj4js.common.HALF_PI){Latitude=Proj4js.common.HALF_PI;}else if((Latitude<-Proj4js.common.HALF_PI)||(Latitude>Proj4js.common.HALF_PI)){Proj4js.reportError('geocent:lat out of range:'+Latitude);return null;} +if(Longitude>Proj4js.common.PI)Longitude-=(2*Proj4js.common.PI);Sin_Lat=Math.sin(Latitude);Cos_Lat=Math.cos(Latitude);Sin2_Lat=Sin_Lat*Sin_Lat;Rn=this.a/(Math.sqrt(1.0e0-this.es*Sin2_Lat));X=(Rn+Height)*Cos_Lat*Math.cos(Longitude);Y=(Rn+Height)*Cos_Lat*Math.sin(Longitude);Z=((Rn*(1-this.es))+Height)*Sin_Lat;p.x=X;p.y=Y;p.z=Z;return Error_Code;},geocentric_to_geodetic:function(p){var genau=1.E-12;var genau2=(genau*genau);var maxiter=30;var P;var RR;var CT;var ST;var RX;var RK;var RN;var CPHI0;var SPHI0;var CPHI;var SPHI;var SDPHI;var At_Pole;var iter;var X=p.x;var Y=p.y;var Z=p.z?p.z:0.0;var Longitude;var Latitude;var Height;At_Pole=false;P=Math.sqrt(X*X+Y*Y);RR=Math.sqrt(X*X+Y*Y+Z*Z);if(P/this.agenau2&&iter0) +{Longitude=Proj4js.common.HALF_PI;} +else if(Y<0) +{Longitude=-Proj4js.common.HALF_PI;} +else +{At_Pole=true;Longitude=0.0;if(Z>0.0) +{Latitude=Proj4js.common.HALF_PI;} +else if(Z<0.0) +{Latitude=-Proj4js.common.HALF_PI;} +else +{Latitude=Proj4js.common.HALF_PI;Height=-this.b;return;}}} +W2=X*X+Y*Y;W=Math.sqrt(W2);T0=Z*Proj4js.common.AD_C;S0=Math.sqrt(T0*T0+W2);Sin_B0=T0/S0;Cos_B0=W/S0;Sin3_B0=Sin_B0*Sin_B0*Sin_B0;T1=Z+this.b*this.ep2*Sin3_B0;Sum=W-this.a*this.es*Cos_B0*Cos_B0*Cos_B0;S1=Math.sqrt(T1*T1+Sum*Sum);Sin_p1=T1/S1;Cos_p1=Sum/S1;Rn=this.a/Math.sqrt(1.0-this.es*Sin_p1*Sin_p1);if(Cos_p1>=Proj4js.common.COS_67P5) +{Height=W/Cos_p1-Rn;} +else if(Cos_p1<=-Proj4js.common.COS_67P5) +{Height=W/-Cos_p1-Rn;} +else +{Height=Z/Sin_p1+Rn*(this.es-1.0);} +if(At_Pole==false) +{Latitude=Math.atan(Sin_p1/Cos_p1);} +p.x=Longitude;p.y=Latitude;p.z=Height;return p;},geocentric_to_wgs84:function(p){if(this.datum_type==Proj4js.common.PJD_3PARAM) +{p.x+=this.datum_params[0];p.y+=this.datum_params[1];p.z+=this.datum_params[2];} +else if(this.datum_type==Proj4js.common.PJD_7PARAM) +{var Dx_BF=this.datum_params[0];var Dy_BF=this.datum_params[1];var Dz_BF=this.datum_params[2];var Rx_BF=this.datum_params[3];var Ry_BF=this.datum_params[4];var Rz_BF=this.datum_params[5];var M_BF=this.datum_params[6];var x_out=M_BF*(p.x-Rz_BF*p.y+Ry_BF*p.z)+Dx_BF;var y_out=M_BF*(Rz_BF*p.x+p.y-Rx_BF*p.z)+Dy_BF;var z_out=M_BF*(-Ry_BF*p.x+Rx_BF*p.y+p.z)+Dz_BF;p.x=x_out;p.y=y_out;p.z=z_out;}},geocentric_from_wgs84:function(p){if(this.datum_type==Proj4js.common.PJD_3PARAM) +{p.x-=this.datum_params[0];p.y-=this.datum_params[1];p.z-=this.datum_params[2];} +else if(this.datum_type==Proj4js.common.PJD_7PARAM) +{var Dx_BF=this.datum_params[0];var Dy_BF=this.datum_params[1];var Dz_BF=this.datum_params[2];var Rx_BF=this.datum_params[3];var Ry_BF=this.datum_params[4];var Rz_BF=this.datum_params[5];var M_BF=this.datum_params[6];var x_tmp=(p.x-Dx_BF)/M_BF;var y_tmp=(p.y-Dy_BF)/M_BF;var z_tmp=(p.z-Dz_BF)/M_BF;p.x=x_tmp+Rz_BF*y_tmp-Ry_BF*z_tmp;p.y=-Rz_BF*x_tmp+y_tmp+Rx_BF*z_tmp;p.z=Ry_BF*x_tmp-Rx_BF*y_tmp+z_tmp;}}});Proj4js.Point=Proj4js.Class({initialize:function(x,y,z){if(typeof x=='object'){this.x=x[0];this.y=x[1];this.z=x[2]||0.0;}else if(typeof x=='string'&&typeof y=='undefined'){var coords=x.split(',');this.x=parseFloat(coords[0]);this.y=parseFloat(coords[1]);this.z=parseFloat(coords[2])||0.0;}else{this.x=x;this.y=y;this.z=z||0.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);}});Proj4js.PrimeMeridian={"greenwich":0.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};Proj4js.Ellipsoid={"MERIT":{a:6378137.0,rf:298.257,ellipseName:"MERIT 1983"},"SGS85":{a:6378136.0,rf:298.257,ellipseName:"Soviet Geodetic System 85"},"GRS80":{a:6378137.0,rf:298.257222101,ellipseName:"GRS 1980(IUGG, 1980)"},"IAU76":{a:6378140.0,rf:298.257,ellipseName:"IAU 1976"},"airy":{a:6377563.396,b:6356256.910,ellipseName:"Airy 1830"},"APL4.":{a:6378137,rf:298.25,ellipseName:"Appl. Physics. 1965"},"NWL9D":{a:6378145.0,rf:298.25,ellipseName:"Naval Weapons Lab., 1965"},"mod_airy":{a:6377340.189,b:6356034.446,ellipseName:"Modified Airy"},"andrae":{a:6377104.43,rf:300.0,ellipseName:"Andrae 1876 (Den., Iclnd.)"},"aust_SA":{a:6378160.0,rf:298.25,ellipseName:"Australian Natl & S. Amer. 1969"},"GRS67":{a:6378160.0,rf:298.2471674270,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,ellipseName:"Comm. des Poids et Mesures 1799"},"delmbr":{a:6376428.0,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)"},"fschr60":{a:6378166.0,rf:298.3,ellipseName:"Fischer (Mercury Datum) 1960"},"fschr60m":{a:6378155.0,rf:298.3,ellipseName:"Fischer 1960"},"fschr68":{a:6378150.0,rf:298.3,ellipseName:"Fischer 1968"},"helmert":{a:6378200.0,rf:298.3,ellipseName:"Helmert 1906"},"hough":{a:6378270.0,rf:297.0,ellipseName:"Hough"},"intl":{a:6378388.0,rf:297.0,ellipseName:"International 1909 (Hayford)"},"kaula":{a:6378163.0,rf:298.24,ellipseName:"Kaula 1961"},"lerch":{a:6378139.0,rf:298.257,ellipseName:"Lerch 1979"},"mprts":{a:6397300.0,rf:191.0,ellipseName:"Maupertius 1738"},"new_intl":{a:6378157.5,b:6356772.2,ellipseName:"New International 1967"},"plessis":{a:6376523.0,rf:6355863.0,ellipseName:"Plessis 1817 (France)"},"krass":{a:6378245.0,rf:298.3,ellipseName:"Krassovsky, 1942"},"SEasia":{a:6378155.0,b:6356773.3205,ellipseName:"Southeast Asia"},"walbeck":{a:6376896.0,b:6355834.8467,ellipseName:"Walbeck"},"WGS60":{a:6378165.0,rf:298.3,ellipseName:"WGS 60"},"WGS66":{a:6378145.0,rf:298.25,ellipseName:"WGS 66"},"WGS72":{a:6378135.0,rf:298.26,ellipseName:"WGS 72"},"WGS84":{a:6378137.0,rf:298.257223563,ellipseName:"WGS 84"},"sphere":{a:6370997.0,b:6370997.0,ellipseName:"Normal Sphere (r=6370997)"}};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",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"}};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"};Proj4js.Proj.aea={init:function(){if(Math.abs(this.lat1+this.lat2)Proj4js.common.EPSLN){this.ns0=(this.ms1*this.ms1-this.ms2*this.ms2)/(this.qs2-this.qs1);}else{this.ns0=this.con;} +this.c=this.ms1*this.ms1+this.ns0*this.qs1;this.rh=this.a*Math.sqrt(this.c-this.ns0*this.qs0)/this.ns0;},forward:function(p){var lon=p.x;var lat=p.y;this.sin_phi=Math.sin(lat);this.cos_phi=Math.cos(lat);var qs=Proj4js.common.qsfnz(this.e3,this.sin_phi,this.cos_phi);var rh1=this.a*Math.sqrt(this.c-this.ns0*qs)/this.ns0;var theta=this.ns0*Proj4js.common.adjust_lon(lon-this.long0);var x=rh1*Math.sin(theta)+this.x0;var y=this.rh-rh1*Math.cos(theta)+this.y0;p.x=x;p.y=y;return p;},inverse:function(p){var rh1,qs,con,theta,lon,lat;p.x-=this.x0;p.y=this.rh-p.y+this.y0;if(this.ns0>=0){rh1=Math.sqrt(p.x*p.x+p.y*p.y);con=1.0;}else{rh1=-Math.sqrt(p.x*p.x+p.y*p.y);con=-1.0;} +theta=0.0;if(rh1!=0.0){theta=Math.atan2(con*p.x,con*p.y);} +con=rh1*this.ns0/this.a;qs=(this.c-con*con)/this.ns0;if(this.e3>=1e-10){con=1-.5*(1.0-this.es)*Math.log((1.0-this.e3)/(1.0+this.e3))/this.e3;if(Math.abs(Math.abs(con)-Math.abs(qs))>.0000000001){lat=this.phi1z(this.e3,qs);}else{if(qs>=0){lat=.5*Proj4js.common.PI;}else{lat=-.5*Proj4js.common.PI;}}}else{lat=this.phi1z(this.e3,qs);} +lon=Proj4js.common.adjust_lon(theta/this.ns0+this.long0);p.x=lon;p.y=lat;return p;},phi1z:function(eccent,qs){var sinphi,cosphi,con,com,dphi;var phi=Proj4js.common.asinz(.5*qs);if(eccentProj4js.common.HALF_PI){Proj4js.reportError("equi:Inv:DataError");} +var lon=Proj4js.common.adjust_lon(this.long0+p.x/(this.a*Math.cos(this.lat0)));p.x=lon;p.y=lat;}};Proj4js.Proj.merc={init:function(){if(this.lat_ts){if(this.sphere){this.k0=Math.cos(this.lat_ts);}else{this.k0=Proj4js.common.msfnz(this.es,Math.sin(this.lat_ts),Math.cos(this.lat_ts));}}},forward:function(p){var lon=p.x;var lat=p.y;if(lat*Proj4js.common.R2D>90.0&&lat*Proj4js.common.R2D<-90.0&&lon*Proj4js.common.R2D>180.0&&lon*Proj4js.common.R2D<-180.0){Proj4js.reportError("merc:forward: llInputOutOfRange: "+lon+" : "+lat);return null;} +var x,y;if(Math.abs(Math.abs(lat)-Proj4js.common.HALF_PI)<=Proj4js.common.EPSLN){Proj4js.reportError("merc:forward: ll2mAtPoles");return null;}else{if(this.sphere){x=this.x0+this.a*this.k0*Proj4js.common.adjust_lon(lon-this.long0);y=this.y0+this.a*this.k0*Math.log(Math.tan(Proj4js.common.FORTPI+0.5*lat));}else{var sinphi=Math.sin(lat);var ts=Proj4js.common.tsfnz(this.e,lat,sinphi);x=this.x0+this.a*this.k0*Proj4js.common.adjust_lon(lon-this.long0);y=this.y0-this.a*this.k0*Math.log(ts);} +p.x=x;p.y=y;return p;}},inverse:function(p){var x=p.x-this.x0;var y=p.y-this.y0;var lon,lat;if(this.sphere){lat=Proj4js.common.HALF_PI-2.0*Math.atan(Math.exp(-y/this.a*this.k0));}else{var ts=Math.exp(-y/(this.a*this.k0));lat=Proj4js.common.phi2z(this.e,ts);if(lat==-9999){Proj4js.reportError("merc:inverse: lat = -9999");return null;}} +lon=Proj4js.common.adjust_lon(this.long0+x/(this.a*this.k0));p.x=lon;p.y=lat;return p;}};Proj4js.Proj.utm={dependsOn:'tmerc',init:function(){if(!this.zone){Proj4js.reportError("utm:init: zone must be specified for UTM");return;} +this.lat0=0.0;this.long0=((6*Math.abs(this.zone))-183)*Proj4js.common.D2R;this.x0=500000.0;this.y0=this.utmSouth?10000000.0:0.0;this.k0=0.9996;Proj4js.Proj['tmerc'].init.apply(this);this.forward=Proj4js.Proj['tmerc'].forward;this.inverse=Proj4js.Proj['tmerc'].inverse;}};Proj4js.Proj.eqdc={init:function(){if(!this.mode)this.mode=0;this.temp=this.b/this.a;this.es=1.0-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);if(this.mode!=0){if(Math.abs(this.lat1+this.lat2)=Proj4js.common.EPSLN){this.ns=(this.ms1-this.ms2)/(this.ml2-this.ml1);}else{this.ns=this.sinphi;}}else{this.ns=this.sinphi;} +this.g=this.ml1+this.ms1/this.ns;this.ml0=Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,this.lat0);this.rh=this.a*(this.g-this.ml0);},forward:function(p){var lon=p.x;var lat=p.y;var ml=Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,lat);var rh1=this.a*(this.g-ml);var theta=this.ns*Proj4js.common.adjust_lon(lon-this.long0);var x=this.x0+rh1*Math.sin(theta);var y=this.y0+this.rh-rh1*Math.cos(theta);p.x=x;p.y=y;return p;},inverse:function(p){p.x-=this.x0;p.y=this.rh-p.y+this.y0;var con,rh1;if(this.ns>=0){rh1=Math.sqrt(p.x*p.x+p.y*p.y);con=1.0;}else{rh1=-Math.sqrt(p.x*p.x+p.y*p.y);con=-1.0;} +var theta=0.0;if(rh1!=0.0)theta=Math.atan2(con*p.x,con*p.y);var ml=this.g-rh1/this.a;var lat=this.phi3z(ml,this.e0,this.e1,this.e2,this.e3);var lon=Proj4js.common.adjust_lon(this.long0+theta/this.ns);p.x=lon;p.y=lat;return p;},phi3z:function(ml,e0,e1,e2,e3){var phi;var dphi;phi=ml;for(var i=0;i<15;i++){dphi=(ml+e1*Math.sin(2.0*phi)-e2*Math.sin(4.0*phi)+e3*Math.sin(6.0*phi))/e0-phi;phi+=dphi;if(Math.abs(dphi)<=.0000000001){return phi;}} +Proj4js.reportError("PHI3Z-CONV:Latitude failed to converge after 15 iterations");return null;}};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(p){var lon=p.x;var lat=p.y;var delta_lon=Proj4js.common.adjust_lon(lon-this.long0);var con;var x,y;var sin_phi=Math.sin(lat);var cos_phi=Math.cos(lat);if(this.sphere){var b=cos_phi*Math.sin(delta_lon);if((Math.abs(Math.abs(b)-1.0))<.0000000001){Proj4js.reportError("tmerc:forward: Point projects into infinity");return(93);}else{x=.5*this.a*this.k0*Math.log((1.0+b)/(1.0-b));con=Math.acos(cos_phi*Math.cos(delta_lon)/Math.sqrt(1.0-b*b));if(lat<0)con=-con;y=this.a*this.k0*(con-this.lat0);}}else{var al=cos_phi*delta_lon;var als=Math.pow(al,2);var c=this.ep2*Math.pow(cos_phi,2);var tq=Math.tan(lat);var t=Math.pow(tq,2);con=1.0-this.es*Math.pow(sin_phi,2);var n=this.a/Math.sqrt(con);var ml=this.a*Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,lat);x=this.k0*n*al*(1.0+als/6.0*(1.0-t+c+als/20.0*(5.0-18.0*t+Math.pow(t,2)+72.0*c-58.0*this.ep2)))+this.x0;y=this.k0*(ml-this.ml0+n*tq*(als*(0.5+als/24.0*(5.0-t+9.0*c+4.0*Math.pow(c,2)+als/30.0*(61.0-58.0*t+Math.pow(t,2)+600.0*c-330.0*this.ep2)))))+this.y0;} +p.x=x;p.y=y;return p;},inverse:function(p){var con,phi;var delta_phi;var i;var max_iter=6;var lat,lon;if(this.sphere){var f=Math.exp(p.x/(this.a*this.k0));var g=.5*(f-1/f);var temp=this.lat0+p.y/(this.a*this.k0);var h=Math.cos(temp);con=Math.sqrt((1.0-h*h)/(1.0+g*g));lat=Proj4js.common.asinz(con);if(temp<0) +lat=-lat;if((g==0)&&(h==0)){lon=this.long0;}else{lon=Proj4js.common.adjust_lon(Math.atan2(g,h)+this.long0);}}else{var x=p.x-this.x0;var y=p.y-this.y0;con=(this.ml0+y/this.k0)/this.a;phi=con;for(i=0;true;i++){delta_phi=((con+this.e1*Math.sin(2.0*phi)-this.e2*Math.sin(4.0*phi)+this.e3*Math.sin(6.0*phi))/this.e0)-phi;phi+=delta_phi;if(Math.abs(delta_phi)<=Proj4js.common.EPSLN)break;if(i>=max_iter){Proj4js.reportError("tmerc:inverse: Latitude failed to converge");return(95);}} +if(Math.abs(phi)0)||(Math.abs(g)<=Proj4js.common.EPSLN)){var x=this.a*ksp*cosphi*Math.sin(dlon);var y=this.y0+this.a*ksp*(this.cos_p14*sinphi-this.sin_p14*cosphi*coslon);}else{Proj4js.reportError("orthoFwdPointError");} +p.x=x;p.y=y;return p;},inverse:function(p){var rh;var z;var sinz,cosz;var temp;var con;var lon,lat;p.x-=this.x0;p.y-=this.y0;rh=Math.sqrt(p.x*p.x+p.y*p.y);if(rh>this.a+.0000001){Proj4js.reportError("orthoInvDataError");} +z=Proj4js.common.asinz(rh/this.a);sinz=Math.sin(z);cosz=Math.cos(z);lon=this.long0;if(Math.abs(rh)<=Proj4js.common.EPSLN){lat=this.lat0;} +lat=Proj4js.common.asinz(cosz*this.sin_p14+(p.y*sinz*this.cos_p14)/rh);con=Math.abs(this.lat0)-Proj4js.common.HALF_PI;if(Math.abs(con)<=Proj4js.common.EPSLN){if(this.lat0>=0){lon=Proj4js.common.adjust_lon(this.long0+Math.atan2(p.x,-p.y));}else{lon=Proj4js.common.adjust_lon(this.long0-Math.atan2(-p.x,p.y));}} +con=cosz-this.sin_p14*Math.sin(lat);p.x=lon;p.y=lat;return p;}};Proj4js.Proj.krovak={init:function(){this.a=6377397.155;this.es=0.006674372230614;this.e=Math.sqrt(this.es);if(!this.lat0){this.lat0=0.863937979737193;} +if(!this.long0){this.long0=0.7417649320975901-0.308341501185665;} +if(!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))/(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(p){var gfi,u,deltav,s,d,eps,ro;var lon=p.x;var lat=p.y;var delta_lon=Proj4js.common.adjust_lon(lon-this.long0);gfi=Math.pow(((1.+this.e*Math.sin(lat))/(1.-this.e*Math.sin(lat))),(this.alfa*this.e/2.));u=2.*(Math.atan(this.k*Math.pow(Math.tan(lat/2.+this.s45),this.alfa)/gfi)-this.s45);deltav=-delta_lon*this.alfa;s=Math.asin(Math.cos(this.ad)*Math.sin(u)+Math.sin(this.ad)*Math.cos(u)*Math.cos(deltav));d=Math.asin(Math.cos(u)*Math.sin(deltav)/Math.cos(s));eps=this.n*d;ro=this.ro0*Math.pow(Math.tan(this.s0/2.+this.s45),this.n)/Math.pow(Math.tan(s/2.+this.s45),this.n);p.y=ro*Math.cos(eps)/1.0;p.x=ro*Math.sin(eps)/1.0;if(this.czech){p.y*=-1.0;p.x*=-1.0;} +return(p);},inverse:function(p){var u,deltav,s,d,eps,ro,fi1;var ok;var tmp=p.x;p.x=p.y;p.y=tmp;if(this.czech){p.y*=-1.0;p.x*=-1.0;} +ro=Math.sqrt(p.x*p.x+p.y*p.y);eps=Math.atan2(p.y,p.x);d=eps/Math.sin(this.s0);s=2.*(Math.atan(Math.pow(this.ro0/ro,1./this.n)*Math.tan(this.s0/2.+this.s45))-this.s45);u=Math.asin(Math.cos(this.ad)*Math.sin(s)-Math.sin(this.ad)*Math.cos(s)*Math.cos(d));deltav=Math.asin(Math.cos(s)*Math.sin(d)/Math.cos(u));p.x=this.long0-deltav/this.alfa;fi1=u;ok=0;var iter=0;do{p.y=2.*(Math.atan(Math.pow(this.k,-1./this.alfa)*Math.pow(Math.tan(u/2.+this.s45),1./this.alfa)*Math.pow((1.+this.e*Math.sin(fi1))/(1.-this.e*Math.sin(fi1)),this.e/2.))-this.s45);if(Math.abs(fi1-p.y)<0.0000000001)ok=1;fi1=p.y;iter+=1;}while(ok==0&&iter<15);if(iter>=15){Proj4js.reportError("PHI3Z-CONV:Latitude failed to converge after 15 iterations");return null;} +return(p);}};Proj4js.Proj.somerc={init:function(){var phy0=this.lat0;this.lambda0=this.long0;var sinPhy0=Math.sin(phy0);var semiMajorAxis=this.a;var invF=this.rf;var flattening=1/invF;var e2=2*flattening-Math.pow(flattening,2);var e=this.e=Math.sqrt(e2);this.R=this.k0*semiMajorAxis*Math.sqrt(1-e2)/(1-e2*Math.pow(sinPhy0,2.0));this.alpha=Math.sqrt(1+e2/(1-e2)*Math.pow(Math.cos(phy0),4.0));this.b0=Math.asin(sinPhy0/this.alpha);this.K=Math.log(Math.tan(Math.PI/4.0+this.b0/2.0)) +-this.alpha*Math.log(Math.tan(Math.PI/4.0+phy0/2.0)) ++this.alpha*e/2*Math.log((1+e*sinPhy0)/(1-e*sinPhy0));},forward:function(p){var Sa1=Math.log(Math.tan(Math.PI/4.0-p.y/2.0));var Sa2=this.e/2.0*Math.log((1+this.e*Math.sin(p.y))/(1-this.e*Math.sin(p.y)));var S=-this.alpha*(Sa1+Sa2)+this.K;var b=2.0*(Math.atan(Math.exp(S))-Math.PI/4.0);var I=this.alpha*(p.x-this.lambda0);var rotI=Math.atan(Math.sin(I)/(Math.sin(this.b0)*Math.tan(b)+ +Math.cos(this.b0)*Math.cos(I)));var rotB=Math.asin(Math.cos(this.b0)*Math.sin(b)- +Math.sin(this.b0)*Math.cos(b)*Math.cos(I));p.y=this.R/2.0*Math.log((1+Math.sin(rotB))/(1-Math.sin(rotB))) ++this.y0;p.x=this.R*rotI+this.x0;return p;},inverse:function(p){var Y=p.x-this.x0;var X=p.y-this.y0;var rotI=Y/this.R;var rotB=2*(Math.atan(Math.exp(X/this.R))-Math.PI/4.0);var b=Math.asin(Math.cos(this.b0)*Math.sin(rotB) ++Math.sin(this.b0)*Math.cos(rotB)*Math.cos(rotI));var I=Math.atan(Math.sin(rotI)/(Math.cos(this.b0)*Math.cos(rotI)-Math.sin(this.b0)*Math.tan(rotB)));var lambda=this.lambda0+I/this.alpha;var S=0.0;var phy=b;var prevPhy=-1000.0;var iteration=0;while(Math.abs(phy-prevPhy)>0.0000001) +{if(++iteration>20) +{Proj4js.reportError("omercFwdInfinity");return;} +S=1.0/this.alpha*(Math.log(Math.tan(Math.PI/4.0+b/2.0))-this.K) ++this.e*Math.log(Math.tan(Math.PI/4.0 ++Math.asin(this.e*Math.sin(phy))/2.0));prevPhy=phy;phy=2.0*Math.atan(Math.exp(S))-Math.PI/2.0;} +p.x=lambda;p.y=phy;return p;}};Proj4js.Proj.stere={ssfn_:function(phit,sinphi,eccen){sinphi*=eccen;return(Math.tan(.5*(Proj4js.common.HALF_PI+phit))*Math.pow((1.-sinphi)/(1.+sinphi),.5*eccen));},TOL:1.e-8,NITER:8,CONV:1.e-10,S_POLE:0,N_POLE:1,OBLIQ:2,EQUIT:3,init:function(){this.phits=this.lat_ts?this.lat_ts:Proj4js.common.HALF_PI;var t=Math.abs(this.lat0);if((Math.abs(t)-Proj4js.common.HALF_PI)Proj4js.common.EPSLN?this.OBLIQ:this.EQUIT;} +this.phits=Math.abs(this.phits);if(this.es){var X;switch(this.mode){case this.N_POLE:case this.S_POLE:if(Math.abs(this.phits-Proj4js.common.HALF_PI)=Proj4js.common.EPSLN?Math.cos(this.phits)/Math.tan(Proj4js.common.FORTPI-.5*this.phits):2.*this.k0;break;}}},forward:function(p){var lon=p.x;lon=Proj4js.common.adjust_lon(lon-this.long0);var lat=p.y;var x,y;if(this.sphere){var sinphi,cosphi,coslam,sinlam;sinphi=Math.sin(lat);cosphi=Math.cos(lat);coslam=Math.cos(lon);sinlam=Math.sin(lon);switch(this.mode){case this.EQUIT:y=1.+cosphi*coslam;if(y<=Proj4js.common.EPSLN){Proj4js.reportError("stere:forward:Equit");} +y=this.akm1/y;x=y*cosphi*sinlam;y*=sinphi;break;case this.OBLIQ:y=1.+this.sinph0*sinphi+this.cosph0*cosphi*coslam;if(y<=Proj4js.common.EPSLN){Proj4js.reportError("stere:forward:Obliq");} +y=this.akm1/y;x=y*cosphi*sinlam;y*=this.cosph0*sinphi-this.sinph0*cosphi*coslam;break;case this.N_POLE:coslam=-coslam;lat=-lat;case this.S_POLE:if(Math.abs(lat-Proj4js.common.HALF_PI)0)||(Math.abs(g)<=Proj4js.common.EPSLN)){x=this.x0+this.a*ksp*cosphi*Math.sin(dlon)/g;y=this.y0+this.a*ksp*(this.cos_p14*sinphi-this.sin_p14*cosphi*coslon)/g;}else{Proj4js.reportError("orthoFwdPointError");x=this.x0+this.infinity_dist*cosphi*Math.sin(dlon);y=this.y0+this.infinity_dist*(this.cos_p14*sinphi-this.sin_p14*cosphi*coslon);} +p.x=x;p.y=y;return p;},inverse:function(p){var rh;var z;var sinc,cosc;var c;var lon,lat;p.x=(p.x-this.x0)/this.a;p.y=(p.y-this.y0)/this.a;p.x/=this.k0;p.y/=this.k0;if((rh=Math.sqrt(p.x*p.x+p.y*p.y))){c=Math.atan2(rh,this.rc);sinc=Math.sin(c);cosc=Math.cos(c);lat=Proj4js.common.asinz(cosc*this.sin_p14+(p.y*sinc*this.cos_p14)/rh);lon=Math.atan2(p.x*sinc,rh*this.cos_p14*cosc-p.y*this.sin_p14*sinc);lon=Proj4js.common.adjust_lon(this.long0+lon);}else{lat=this.phic0;lon=0.0;} +p.x=lon;p.y=lat;return p;}};Proj4js.Proj.sinu={init:function(){if(!this.sphere){this.en=Proj4js.common.pj_enfn(this.es);}else{this.n=1.;this.m=0.;this.es=0;this.C_y=Math.sqrt((this.m+1.)/this.n);this.C_x=this.C_y/(this.m+1.);}},forward:function(p){var x,y,delta_lon;var lon=p.x;var lat=p.y;lon=Proj4js.common.adjust_lon(lon-this.long0);if(this.sphere){if(!this.m){lat=this.n!=1.?Math.asin(this.n*Math.sin(lat)):lat;}else{var k=this.n*Math.sin(lat);for(var i=Proj4js.common.MAX_ITER;i;--i){var V=(this.m*lat+Math.sin(lat)-k)/(this.m+Math.cos(lat));lat-=V;if(Math.abs(V)=0){y=this.y0+Proj4js.common.PI*this.R*Math.tan(.5*theta);}else{y=this.y0+Proj4js.common.PI*this.R*-Math.tan(.5*theta);}} +var al=.5*Math.abs((Proj4js.common.PI/dlon)-(dlon/Proj4js.common.PI));var asq=al*al;var sinth=Math.sin(theta);var costh=Math.cos(theta);var g=costh/(sinth+costh-1.0);var gsq=g*g;var m=g*(2.0/sinth-1.0);var msq=m*m;var con=Proj4js.common.PI*this.R*(al*(g-msq)+Math.sqrt(asq*(g-msq)*(g-msq)-(msq+asq)*(gsq-msq)))/(msq+asq);if(dlon<0){con=-con;} +x=this.x0+con;con=Math.abs(con/(Proj4js.common.PI*this.R));if(lat>=0){y=this.y0+Proj4js.common.PI*this.R*Math.sqrt(1.0-con*con-2.0*al*con);}else{y=this.y0-Proj4js.common.PI*this.R*Math.sqrt(1.0-con*con-2.0*al*con);} +p.x=x;p.y=y;return p;},inverse:function(p){var lon,lat;var xx,yy,xys,c1,c2,c3;var al,asq;var a1;var m1;var con;var th1;var d;p.x-=this.x0;p.y-=this.y0;con=Proj4js.common.PI*this.R;xx=p.x/con;yy=p.y/con;xys=xx*xx+yy*yy;c1=-Math.abs(yy)*(1.0+xys);c2=c1-2.0*yy*yy+xx*xx;c3=-2.0*c1+1.0+2.0*yy*yy+xys*xys;d=yy*yy/c3+(2.0*c2*c2*c2/c3/c3/c3-9.0*c1*c2/c3/c3)/27.0;a1=(c1-c2*c2/3.0/c3)/c3;m1=2.0*Math.sqrt(-a1/3.0);con=((3.0*d)/a1)/m1;if(Math.abs(con)>1.0){if(con>=0.0){con=1.0;}else{con=-1.0;}} +th1=Math.acos(con)/3.0;if(p.y>=0){lat=(-m1*Math.cos(th1+Proj4js.common.PI/3.0)-c2/3.0/c3)*Proj4js.common.PI;}else{lat=-(-m1*Math.cos(th1+Proj4js.common.PI/3.0)-c2/3.0/c3)*Proj4js.common.PI;} +if(Math.abs(xx)0;--i){lat=2.0*Math.atan(num*Proj4js.common.srat(this.e*Math.sin(p.y),-0.5*this.e))-Proj4js.common.HALF_PI;if(Math.abs(lat-p.y)0.0){if(this.lat0>=0.0){this.f=this.d+Math.sqrt(this.d*this.d-1.0);}else{this.f=this.d-Math.sqrt(this.d*this.d-1.0);}}else{this.f=this.d;} +this.el=this.f*Math.pow(this.ts,this.bl);} +if(this.mode!=0){this.g=.5*(this.f-1.0/this.f);this.gama=Proj4js.common.asinz(Math.sin(this.alpha)/this.d);this.longc=this.longc-Proj4js.common.asinz(this.g*Math.tan(this.gama))/this.bl;this.con=Math.abs(this.lat0);if((this.con>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);if(this.lat0>=0){this.u=(this.al/this.bl)*Math.atan(Math.sqrt(this.d*this.d-1.0)/this.cosaz);}else{this.u=-(this.al/this.bl)*Math.atan(Math.sqrt(this.d*this.d-1.0)/this.cosaz);}}else{Proj4js.reportError("omerc:Init:DataError");}}else{this.sinphi=Math.sin(this.at1);this.ts1=Proj4js.common.tsfnz(this.e,this.lat1,this.sinphi);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=.5*(this.f-1.0/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;if(this.dlon<-Proj4js.common.PI)this.lon2=this.lon2-2.0*Proj4js.common.PI;if(this.dlon>Proj4js.common.PI)this.lon2=this.lon2+2.0*Proj4js.common.PI;this.dlon=this.lon1-this.lon2;this.longc=.5*(this.lon1+this.lon2)-Math.atan(this.j*Math.tan(.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));if(Math.abs(this.lat1-this.lat2)<=Proj4js.common.EPSLN){Proj4js.reportError("omercInitDataError");}else{this.con=Math.abs(this.lat1);} +if((this.con<=Proj4js.common.EPSLN)||(Math.abs(this.con-Proj4js.common.HALF_PI)<=Proj4js.common.EPSLN)){Proj4js.reportError("omercInitDataError");}else{if(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);if(this.lat0>=0){this.u=(this.al/this.bl)*Math.atan(Math.sqrt(this.d*this.d-1.0)/this.cosaz);}else{this.u=-(this.al/this.bl)*Math.atan(Math.sqrt(this.d*this.d-1.0)/this.cosaz);}}},forward:function(p){var theta;var sin_phi,cos_phi;var b;var c,t,tq;var con,n,ml;var q,us,vl;var ul,vs;var s;var dlon;var ts1;var lon=p.x;var lat=p.y;sin_phi=Math.sin(lat);dlon=Proj4js.common.adjust_lon(lon-this.longc);vl=Math.sin(this.bl*dlon);if(Math.abs(Math.abs(lat)-Proj4js.common.HALF_PI)>Proj4js.common.EPSLN){ts1=Proj4js.common.tsfnz(this.e,lat,sin_phi);q=this.el/(Math.pow(ts1,this.bl));s=.5*(q-1.0/q);t=.5*(q+1.0/q);ul=(s*this.singam-vl*this.cosgam)/t;con=Math.cos(this.bl*dlon);if(Math.abs(con)<.0000001){us=this.al*this.bl*dlon;}else{us=this.al*Math.atan((s*this.cosgam+vl*this.singam)/con)/this.bl;if(con<0)us=us+Proj4js.common.PI*this.al/this.bl;}}else{if(lat>=0){ul=this.singam;}else{ul=-this.singam;} +us=this.al*lat/this.bl;} +if(Math.abs(Math.abs(ul)-1.0)<=Proj4js.common.EPSLN){Proj4js.reportError("omercFwdInfinity");} +vs=.5*this.al*Math.log((1.0-ul)/(1.0+ul))/this.bl;us=us-this.u;var x=this.x0+vs*this.cosaz+us*this.sinaz;var y=this.y0+us*this.cosaz-vs*this.sinaz;p.x=x;p.y=y;return p;},inverse:function(p){var delta_lon;var theta;var delta_theta;var sin_phi,cos_phi;var b;var c,t,tq;var con,n,ml;var vs,us,q,s,ts1;var vl,ul,bs;var lon,lat;var flag;p.x-=this.x0;p.y-=this.y0;flag=0;vs=p.x*this.cosaz-p.y*this.sinaz;us=p.y*this.cosaz+p.x*this.sinaz;us=us+this.u;q=Math.exp(-this.bl*vs/this.al);s=.5*(q-1.0/q);t=.5*(q+1.0/q);vl=Math.sin(this.bl*us/this.al);ul=(vl*this.cosgam+s*this.singam)/t;if(Math.abs(Math.abs(ul)-1.0)<=Proj4js.common.EPSLN) +{lon=this.longc;if(ul>=0.0){lat=Proj4js.common.HALF_PI;}else{lat=-Proj4js.common.HALF_PI;}}else{con=1.0/this.bl;ts1=Math.pow((this.el/Math.sqrt((1.0+ul)/(1.0-ul))),con);lat=Proj4js.common.phi2z(this.e,ts1);theta=this.longc-Math.atan2((s*this.cosgam-vl*this.singam),con)/this.bl;lon=Proj4js.common.adjust_lon(theta);} +p.x=lon;p.y=lat;return p;}};Proj4js.Proj.lcc={init:function(){if(!this.lat2){this.lat2=this.lat0;} +if(!this.k0)this.k0=1.0;if(Math.abs(this.lat1+this.lat2)Proj4js.common.EPSLN){this.ns=Math.log(ms1/ms2)/Math.log(ts1/ts2);}else{this.ns=sin1;} +this.f0=ms1/(this.ns*Math.pow(ts1,this.ns));this.rh=this.a*this.f0*Math.pow(ts0,this.ns);if(!this.title)this.title="Lambert Conformal Conic";},forward:function(p){var lon=p.x;var lat=p.y;if(lat<=90.0&&lat>=-90.0&&lon<=180.0&&lon>=-180.0){}else{Proj4js.reportError("lcc:forward: llInputOutOfRange: "+lon+" : "+lat);return null;} +var con=Math.abs(Math.abs(lat)-Proj4js.common.HALF_PI);var ts,rh1;if(con>Proj4js.common.EPSLN){ts=Proj4js.common.tsfnz(this.e,lat,Math.sin(lat));rh1=this.a*this.f0*Math.pow(ts,this.ns);}else{con=lat*this.ns;if(con<=0){Proj4js.reportError("lcc:forward: No Projection");return null;} +rh1=0;} +var theta=this.ns*Proj4js.common.adjust_lon(lon-this.long0);p.x=this.k0*(rh1*Math.sin(theta))+this.x0;p.y=this.k0*(this.rh-rh1*Math.cos(theta))+this.y0;return p;},inverse:function(p){var rh1,con,ts;var lat,lon;var x=(p.x-this.x0)/this.k0;var y=(this.rh-(p.y-this.y0)/this.k0);if(this.ns>0){rh1=Math.sqrt(x*x+y*y);con=1.0;}else{rh1=-Math.sqrt(x*x+y*y);con=-1.0;} +var theta=0.0;if(rh1!=0){theta=Math.atan2((con*x),(con*y));} +if((rh1!=0)||(this.ns>0.0)){con=1.0/this.ns;ts=Math.pow((rh1/(this.a*this.f0)),con);lat=Proj4js.common.phi2z(this.e,ts);if(lat==-9999)return null;}else{lat=-Proj4js.common.HALF_PI;} +lon=Proj4js.common.adjust_lon(theta/this.ns+this.long0);p.x=lon;p.y=lat;return p;}};Proj4js.Proj.laea={S_POLE:1,N_POLE:2,EQUIT:3,OBLIQ:4,init:function(){var t=Math.abs(this.lat0);if(Math.abs(t-Proj4js.common.HALF_PI)0){var sinphi;this.qp=Proj4js.common.qsfnz(this.e,1.0);this.mmf=.5/(1.-this.es);this.apa=this.authset(this.es);switch(this.mode){case this.N_POLE:case this.S_POLE:this.dd=1.;break;case this.EQUIT:this.rq=Math.sqrt(.5*this.qp);this.dd=1./this.rq;this.xmf=1.;this.ymf=.5*this.qp;break;case this.OBLIQ:this.rq=Math.sqrt(.5*this.qp);sinphi=Math.sin(this.lat0);this.sinb1=Proj4js.common.qsfnz(this.e,sinphi)/this.qp;this.cosb1=Math.sqrt(1.-this.sinb1*this.sinb1);this.dd=Math.cos(this.lat0)/(Math.sqrt(1.-this.es*sinphi*sinphi)*this.rq*this.cosb1);this.ymf=(this.xmf=this.rq)/this.dd;this.xmf*=this.dd;break;}}else{if(this.mode==this.OBLIQ){this.sinph0=Math.sin(this.lat0);this.cosph0=Math.cos(this.lat0);}}},forward:function(p){var x,y;var lam=p.x;var phi=p.y;lam=Proj4js.common.adjust_lon(lam-this.long0);if(this.sphere){var coslam,cosphi,sinphi;sinphi=Math.sin(phi);cosphi=Math.cos(phi);coslam=Math.cos(lam);switch(this.mode){case this.OBLIQ:case this.EQUIT:y=(this.mode==this.EQUIT)?1.+cosphi*coslam:1.+this.sinph0*sinphi+this.cosph0*cosphi*coslam;if(y<=Proj4js.common.EPSLN){Proj4js.reportError("laea:fwd:y less than eps");return null;} +y=Math.sqrt(2./y);x=y*cosphi*Math.sin(lam);y*=(this.mode==this.EQUIT)?sinphi:this.cosph0*sinphi-this.sinph0*cosphi*coslam;break;case this.N_POLE:coslam=-coslam;case this.S_POLE:if(Math.abs(phi+this.phi0)=0.){x=(b=Math.sqrt(q))*sinlam;y=coslam*((this.mode==this.S_POLE)?b:-b);}else{x=y=0.;} +break;}} +p.x=this.a*x+this.x0;p.y=this.a*y+this.y0;return p;},inverse:function(p){p.x-=this.x0;p.y-=this.y0;var x=p.x/this.a;var y=p.y/this.a;var lam,phi;if(this.sphere){var cosz=0.0,rh,sinz=0.0;rh=Math.sqrt(x*x+y*y);phi=rh*.5;if(phi>1.){Proj4js.reportError("laea:Inv:DataError");return null;} +phi=2.*Math.asin(phi);if(this.mode==this.OBLIQ||this.mode==this.EQUIT){sinz=Math.sin(phi);cosz=Math.cos(phi);} +switch(this.mode){case this.EQUIT:phi=(Math.abs(rh)<=Proj4js.common.EPSLN)?0.:Math.asin(y*sinz/rh);x*=sinz;y=cosz*rh;break;case this.OBLIQ:phi=(Math.abs(rh)<=Proj4js.common.EPSLN)?this.phi0:Math.asin(cosz*this.sinph0+y*sinz*this.cosph0/rh);x*=sinz*this.cosph0;y=(cosz-Math.sin(phi)*this.sinph0)*rh;break;case this.N_POLE:y=-y;phi=Proj4js.common.HALF_PI-phi;break;case this.S_POLE:phi-=Proj4js.common.HALF_PI;break;} +lam=(y==0.&&(this.mode==this.EQUIT||this.mode==this.OBLIQ))?0.:Math.atan2(x,y);}else{var cCe,sCe,q,rho,ab=0.0;switch(this.mode){case this.EQUIT:case this.OBLIQ:x/=this.dd;y*=this.dd;rho=Math.sqrt(x*x+y*y);if(rho(2.0*Proj4js.common.HALF_PI*this.a)){Proj4js.reportError("aeqdInvDataError");return;} +var z=rh/this.a;var sinz=Math.sin(z);var cosz=Math.cos(z);var lon=this.long0;var lat;if(Math.abs(rh)<=Proj4js.common.EPSLN){lat=this.lat0;}else{lat=Proj4js.common.asinz(cosz*this.sin_p12+(p.y*sinz*this.cos_p12)/rh);var con=Math.abs(this.lat0)-Proj4js.common.HALF_PI;if(Math.abs(con)<=Proj4js.common.EPSLN){if(this.lat0>=0.0){lon=Proj4js.common.adjust_lon(this.long0+Math.atan2(p.x,-p.y));}else{lon=Proj4js.common.adjust_lon(this.long0-Math.atan2(-p.x,p.y));}}else{con=cosz-this.sin_p12*Math.sin(lat);if((Math.abs(con)=50){Proj4js.reportError("moll:Fwd:IterationError");}} +theta/=2.0;if(Proj4js.common.PI/2-Math.abs(lat)0.999999999999)arg=0.999999999999;var theta=Math.asin(arg);var lon=Proj4js.common.adjust_lon(this.long0+(p.x/(0.900316316158*this.a*Math.cos(theta))));if(lon<(-Proj4js.common.PI))lon=-Proj4js.common.PI;if(lon>Proj4js.common.PI)lon=Proj4js.common.PI;arg=(2.0*theta+Math.sin(2.0*theta))/Proj4js.common.PI;if(Math.abs(arg)>1.0)arg=1.0;var lat=Math.asin(arg);p.x=lon;p.y=lat;return p;}}; \ No newline at end of file diff --git a/ajax/libs/proj4js/1.1.0/proj4js.js b/ajax/libs/proj4js/1.1.0/proj4js.js new file mode 100755 index 000000000..2f7f94bcb --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/proj4js.js @@ -0,0 +1,1816 @@ +/* +Author: Mike Adair madairATdmsolutions.ca + Richard Greenwood rich@greenwoodmap.com +License: LGPL as per: http://www.gnu.org/copyleft/lesser.html + +$Id: Proj.js 2956 2007-07-09 12:17:52Z steven $ +*/ + +/** + * Namespace: Proj4js + * + * Proj4js is a JavaScript library to transform point coordinates from one + * coordinate system to another, including datum transformations. + * + * This library is a port of both the Proj.4 and GCTCP C libraries to JavaScript. + * Enabling these transformations in the browser allows geographic data stored + * in different projections to be combined in browser-based web mapping + * applications. + * + * Proj4js must have access to coordinate system initialization strings (which + * are the same as for PROJ.4 command line). Thes can be included in your + * application using a + + def is a CS definition in PROJ.4 WKT format, for example: + +proj="tmerc" //longlat, etc. + +a=majorRadius + +b=minorRadius + +lat0=somenumber + +long=somenumber +*/ +Proj4js.defs = { + // These are so widely used, we'll go ahead and throw them in + // without requiring a separate .js file + 'WGS84': "+title=long/lat:WGS84 +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees", + 'EPSG:4326': "+title=long/lat:WGS84 +proj=longlat +a=6378137.0 +b=6356752.31424518 +ellps=WGS84 +datum=WGS84 +units=degrees", + 'EPSG:4269': "+title=long/lat:NAD83 +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees", + 'EPSG:3875': "+title= Google Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs" +}; +Proj4js.defs['EPSG:3785'] = Proj4js.defs['EPSG:3875']; //maintain backward compat, official code is 3875 +Proj4js.defs['GOOGLE'] = Proj4js.defs['EPSG:3875']; +Proj4js.defs['EPSG:900913'] = Proj4js.defs['EPSG:3875']; +Proj4js.defs['EPSG:102113'] = Proj4js.defs['EPSG:3875']; + +Proj4js.common = { + PI : 3.141592653589793238, //Math.PI, + HALF_PI : 1.570796326794896619, //Math.PI*0.5, + TWO_PI : 6.283185307179586477, //Math.PI*2, + FORTPI : 0.78539816339744833, + R2D : 57.29577951308232088, + D2R : 0.01745329251994329577, + SEC_TO_RAD : 4.84813681109535993589914102357e-6, /* SEC_TO_RAD = Pi/180/3600 */ + EPSLN : 1.0e-10, + MAX_ITER : 20, + // following constants from geocent.c + COS_67P5 : 0.38268343236508977, /* cosine of 67.5 degrees */ + AD_C : 1.0026000, /* Toms region 1 constant */ + + /* datum_type values */ + PJD_UNKNOWN : 0, + PJD_3PARAM : 1, + PJD_7PARAM : 2, + PJD_GRIDSHIFT: 3, + PJD_WGS84 : 4, // WGS84 or equivalent + PJD_NODATUM : 5, // WGS84 or equivalent + SRS_WGS84_SEMIMAJOR : 6378137.0, // only used in grid shift transforms + + // ellipoid pj_set_ell.c + SIXTH : .1666666666666666667, /* 1/6 */ + RA4 : .04722222222222222222, /* 17/360 */ + RA6 : .02215608465608465608, /* 67/3024 */ + RV4 : .06944444444444444444, /* 5/72 */ + RV6 : .04243827160493827160, /* 55/1296 */ + +// Function to compute the constant small m which is the radius of +// a parallel of latitude, phi, divided by the semimajor axis. +// ----------------------------------------------------------------- + msfnz : function(eccent, sinphi, cosphi) { + var con = eccent * sinphi; + return cosphi/(Math.sqrt(1.0 - con * con)); + }, + +// Function to compute the constant small t for use in the forward +// computations in the Lambert Conformal Conic and the Polar +// Stereographic projections. +// ----------------------------------------------------------------- + tsfnz : function(eccent, phi, sinphi) { + var con = eccent * sinphi; + var com = .5 * eccent; + con = Math.pow(((1.0 - con) / (1.0 + con)), com); + return (Math.tan(.5 * (this.HALF_PI - phi))/con); + }, + +// Function to compute the latitude angle, phi2, for the inverse of the +// Lambert Conformal Conic and Polar Stereographic projections. +// ---------------------------------------------------------------- + phi2z : function(eccent, ts) { + var eccnth = .5 * eccent; + var con, dphi; + var phi = this.HALF_PI - 2 * Math.atan(ts); + for (var i = 0; i <= 15; i++) { + con = eccent * Math.sin(phi); + dphi = this.HALF_PI - 2 * Math.atan(ts *(Math.pow(((1.0 - con)/(1.0 + con)),eccnth))) - phi; + phi += dphi; + if (Math.abs(dphi) <= .0000000001) return phi; + } + alert("phi2z has NoConvergence"); + return (-9999); + }, + +/* Function to compute constant small q which is the radius of a + parallel of latitude, phi, divided by the semimajor axis. +------------------------------------------------------------*/ + qsfnz : function(eccent,sinphi) { + var con; + if (eccent > 1.0e-7) { + con = eccent * sinphi; + return (( 1.0- eccent * eccent) * (sinphi /(1.0 - con * con) - (.5/eccent)*Math.log((1.0 - con)/(1.0 + con)))); + } else { + return(2.0 * sinphi); + } + }, + +/* Function to eliminate roundoff errors in asin +----------------------------------------------*/ + asinz : function(x) { + if (Math.abs(x)>1.0) { + x=(x>1.0)?1.0:-1.0; + } + return Math.asin(x); + }, + +// following functions from gctpc cproj.c for transverse mercator projections + e0fn : function(x) {return(1.0-0.25*x*(1.0+x/16.0*(3.0+1.25*x)));}, + e1fn : function(x) {return(0.375*x*(1.0+0.25*x*(1.0+0.46875*x)));}, + e2fn : function(x) {return(0.05859375*x*x*(1.0+0.75*x));}, + e3fn : function(x) {return(x*x*x*(35.0/3072.0));}, + mlfn : function(e0,e1,e2,e3,phi) {return(e0*phi-e1*Math.sin(2.0*phi)+e2*Math.sin(4.0*phi)-e3*Math.sin(6.0*phi));}, + + srat : function(esinp, exp) { + return(Math.pow((1.0-esinp)/(1.0+esinp), exp)); + }, + +// Function to return the sign of an argument + sign : function(x) { if (x < 0.0) return(-1); else return(1);}, + +// Function to adjust longitude to -180 to 180; input in radians + adjust_lon : function(x) { + x = (Math.abs(x) < this.PI) ? x: (x - (this.sign(x)*this.TWO_PI) ); + return x; + }, + +// IGNF - DGR : algorithms used by IGN France + +// Function to adjust latitude to -90 to 90; input in radians + adjust_lat : function(x) { + x= (Math.abs(x) < this.HALF_PI) ? x: (x - (this.sign(x)*this.PI) ); + return x; + }, + +// Latitude Isometrique - close to tsfnz ... + latiso : function(eccent, phi, sinphi) { + if (Math.abs(phi) > this.HALF_PI) return +Number.NaN; + if (phi==this.HALF_PI) return Number.POSITIVE_INFINITY; + if (phi==-1.0*this.HALF_PI) return -1.0*Number.POSITIVE_INFINITY; + + var con= eccent*sinphi; + return Math.log(Math.tan((this.HALF_PI+phi)/2.0))+eccent*Math.log((1.0-con)/(1.0+con))/2.0; + }, + + fL : function(x,L) { + return 2.0*Math.atan(x*Math.exp(L)) - this.HALF_PI; + }, + +// Inverse Latitude Isometrique - close to ph2z + invlatiso : function(eccent, ts) { + var phi= this.fL(1.0,ts); + var Iphi= 0.0; + var con= 0.0; + do { + Iphi= phi; + con= eccent*Math.sin(Iphi); + phi= this.fL(Math.exp(eccent*Math.log((1.0+con)/(1.0-con))/2.0),ts) + } while (Math.abs(phi-Iphi)>1.0e-12); + return phi; + }, + +// Needed for Gauss Schreiber +// Original: Denis Makarov (info@binarythings.com) +// Web Site: http://www.binarythings.com + sinh : function(x) + { + var r= Math.exp(x); + r= (r-1.0/r)/2.0; + return r; + }, + + cosh : function(x) + { + var r= Math.exp(x); + r= (r+1.0/r)/2.0; + return r; + }, + + tanh : function(x) + { + var r= Math.exp(x); + r= (r-1.0/r)/(r+1.0/r); + return r; + }, + + asinh : function(x) + { + var s= (x>= 0? 1.0:-1.0); + return s*(Math.log( Math.abs(x) + Math.sqrt(x*x+1.0) )); + }, + + acosh : function(x) + { + return 2.0*Math.log(Math.sqrt((x+1.0)/2.0) + Math.sqrt((x-1.0)/2.0)); + }, + + atanh : function(x) + { + return Math.log((x-1.0)/(x+1.0))/2.0; + }, + +// Grande Normale + gN : function(a,e,sinphi) + { + var temp= e*sinphi; + return a/Math.sqrt(1.0 - temp*temp); + }, + + //code from the PROJ.4 pj_mlfn.c file; this may be useful for other projections + pj_enfn: function(es) { + var en = new Array(); + en[0] = this.C00 - es * (this.C02 + es * (this.C04 + es * (this.C06 + es * this.C08))); + en[1] = es * (this.C22 - es * (this.C04 + es * (this.C06 + es * this.C08))); + var t = es * es; + en[2] = t * (this.C44 - es * (this.C46 + es * this.C48)); + t *= es; + en[3] = t * (this.C66 - es * this.C68); + en[4] = t * es * this.C88; + return en; + }, + + pj_mlfn: function(phi, sphi, cphi, en) { + cphi *= sphi; + sphi *= sphi; + return(en[0] * phi - cphi * (en[1] + sphi*(en[2]+ sphi*(en[3] + sphi*en[4])))); + }, + + pj_inv_mlfn: function(arg, es, en) { + var k = 1./(1.-es); + var phi = arg; + for (var i = Proj4js.common.MAX_ITER; i ; --i) { /* rarely goes over 2 iterations */ + var s = Math.sin(phi); + var t = 1. - es * s * s; + //t = this.pj_mlfn(phi, s, Math.cos(phi), en) - arg; + //phi -= t * (t * Math.sqrt(t)) * k; + t = (this.pj_mlfn(phi, s, Math.cos(phi), en) - arg) * (t * Math.sqrt(t)) * k; + phi -= t; + if (Math.abs(t) < Proj4js.common.EPSLN) + return phi; + } + Proj4js.reportError("cass:pj_inv_mlfn: Convergence error"); + return phi; + }, + +/* meridinal distance for ellipsoid and inverse +** 8th degree - accurate to < 1e-5 meters when used in conjuction +** with typical major axis values. +** Inverse determines phi to EPS (1e-11) radians, about 1e-6 seconds. +*/ + C00: 1.0, + C02: .25, + C04: .046875, + C06: .01953125, + C08: .01068115234375, + C22: .75, + C44: .46875, + C46: .01302083333333333333, + C48: .00712076822916666666, + C66: .36458333333333333333, + C68: .00569661458333333333, + C88: .3076171875 + +}; + +/** datum object +*/ +Proj4js.datum = Proj4js.Class({ + + initialize : function(proj) { + this.datum_type = Proj4js.common.PJD_WGS84; //default setting + if (proj.datumCode && proj.datumCode == 'none') { + this.datum_type = Proj4js.common.PJD_NODATUM; + } + if (proj && proj.datum_params) { + for (var i=0; i 3) { + if (proj.datum_params[3] != 0 || proj.datum_params[4] != 0 || + proj.datum_params[5] != 0 || proj.datum_params[6] != 0 ) { + this.datum_type = Proj4js.common.PJD_7PARAM; + proj.datum_params[3] *= Proj4js.common.SEC_TO_RAD; + proj.datum_params[4] *= Proj4js.common.SEC_TO_RAD; + proj.datum_params[5] *= Proj4js.common.SEC_TO_RAD; + proj.datum_params[6] = (proj.datum_params[6]/1000000.0) + 1.0; + } + } + } + if (proj) { + this.a = proj.a; //datum object also uses these values + this.b = proj.b; + this.es = proj.es; + this.ep2 = proj.ep2; + this.datum_params = proj.datum_params; + } + }, + + /****************************************************************/ + // cs_compare_datums() + // Returns TRUE if the two datums match, otherwise FALSE. + compare_datums : function( dest ) { + if( this.datum_type != dest.datum_type ) { + return false; // false, datums are not equal + } else if( this.a != dest.a || Math.abs(this.es-dest.es) > 0.000000000050 ) { + // the tolerence for es is to ensure that GRS80 and WGS84 + // are considered identical + return false; + } else if( this.datum_type == Proj4js.common.PJD_3PARAM ) { + return (this.datum_params[0] == dest.datum_params[0] + && this.datum_params[1] == dest.datum_params[1] + && this.datum_params[2] == dest.datum_params[2]); + } else if( this.datum_type == Proj4js.common.PJD_7PARAM ) { + return (this.datum_params[0] == dest.datum_params[0] + && this.datum_params[1] == dest.datum_params[1] + && this.datum_params[2] == dest.datum_params[2] + && this.datum_params[3] == dest.datum_params[3] + && this.datum_params[4] == dest.datum_params[4] + && this.datum_params[5] == dest.datum_params[5] + && this.datum_params[6] == dest.datum_params[6]); + } else if ( this.datum_type == Proj4js.common.PJD_GRIDSHIFT || + dest.datum_type == Proj4js.common.PJD_GRIDSHIFT ) { + alert("ERROR: Grid shift transformations are not implemented."); + return false + } else { + return true; // datums are equal + } + }, // cs_compare_datums() + + /* + * The function Convert_Geodetic_To_Geocentric converts geodetic coordinates + * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z), + * according to the current ellipsoid parameters. + * + * Latitude : Geodetic latitude in radians (input) + * Longitude : Geodetic longitude in radians (input) + * Height : Geodetic height, in meters (input) + * X : Calculated Geocentric X coordinate, in meters (output) + * Y : Calculated Geocentric Y coordinate, in meters (output) + * Z : Calculated Geocentric Z coordinate, in meters (output) + * + */ + geodetic_to_geocentric : function(p) { + var Longitude = p.x; + var Latitude = p.y; + var Height = p.z ? p.z : 0; //Z value not always supplied + var X; // output + var Y; + var Z; + + var Error_Code=0; // GEOCENT_NO_ERROR; + var Rn; /* Earth radius at location */ + var Sin_Lat; /* Math.sin(Latitude) */ + var Sin2_Lat; /* Square of Math.sin(Latitude) */ + var Cos_Lat; /* Math.cos(Latitude) */ + + /* + ** Don't blow up if Latitude is just a little out of the value + ** range as it may just be a rounding issue. Also removed longitude + ** test, it should be wrapped by Math.cos() and Math.sin(). NFW for PROJ.4, Sep/2001. + */ + if( Latitude < -Proj4js.common.HALF_PI && Latitude > -1.001 * Proj4js.common.HALF_PI ) { + Latitude = -Proj4js.common.HALF_PI; + } else if( Latitude > Proj4js.common.HALF_PI && Latitude < 1.001 * Proj4js.common.HALF_PI ) { + Latitude = Proj4js.common.HALF_PI; + } else if ((Latitude < -Proj4js.common.HALF_PI) || (Latitude > Proj4js.common.HALF_PI)) { + /* Latitude out of range */ + Proj4js.reportError('geocent:lat out of range:'+Latitude); + return null; + } + + if (Longitude > Proj4js.common.PI) Longitude -= (2*Proj4js.common.PI); + Sin_Lat = Math.sin(Latitude); + Cos_Lat = Math.cos(Latitude); + Sin2_Lat = Sin_Lat * Sin_Lat; + Rn = this.a / (Math.sqrt(1.0e0 - this.es * Sin2_Lat)); + X = (Rn + Height) * Cos_Lat * Math.cos(Longitude); + Y = (Rn + Height) * Cos_Lat * Math.sin(Longitude); + Z = ((Rn * (1 - this.es)) + Height) * Sin_Lat; + + p.x = X; + p.y = Y; + p.z = Z; + return Error_Code; + }, // cs_geodetic_to_geocentric() + + + geocentric_to_geodetic : function (p) { +/* local defintions and variables */ +/* end-criterium of loop, accuracy of sin(Latitude) */ +var genau = 1.E-12; +var genau2 = (genau*genau); +var maxiter = 30; + + var P; /* distance between semi-minor axis and location */ + var RR; /* distance between center and location */ + var CT; /* sin of geocentric latitude */ + var ST; /* cos of geocentric latitude */ + var RX; + var RK; + var RN; /* Earth radius at location */ + var CPHI0; /* cos of start or old geodetic latitude in iterations */ + var SPHI0; /* sin of start or old geodetic latitude in iterations */ + var CPHI; /* cos of searched geodetic latitude */ + var SPHI; /* sin of searched geodetic latitude */ + var SDPHI; /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */ + var At_Pole; /* indicates location is in polar region */ + var iter; /* # of continous iteration, max. 30 is always enough (s.a.) */ + + var X = p.x; + var Y = p.y; + var Z = p.z ? p.z : 0.0; //Z value not always supplied + var Longitude; + var Latitude; + var Height; + + At_Pole = false; + P = Math.sqrt(X*X+Y*Y); + RR = Math.sqrt(X*X+Y*Y+Z*Z); + +/* special cases for latitude and longitude */ + if (P/this.a < genau) { + +/* special case, if P=0. (X=0., Y=0.) */ + At_Pole = true; + Longitude = 0.0; + +/* if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis + * of ellipsoid (=center of mass), Latitude becomes PI/2 */ + if (RR/this.a < genau) { + Latitude = Proj4js.common.HALF_PI; + Height = -this.b; + return; + } + } else { +/* ellipsoidal (geodetic) longitude + * interval: -PI < Longitude <= +PI */ + Longitude=Math.atan2(Y,X); + } + +/* -------------------------------------------------------------- + * Following iterative algorithm was developped by + * "Institut f�r Erdmessung", University of Hannover, July 1988. + * Internet: www.ife.uni-hannover.de + * Iterative computation of CPHI,SPHI and Height. + * Iteration of CPHI and SPHI to 10**-12 radian resp. + * 2*10**-7 arcsec. + * -------------------------------------------------------------- + */ + CT = Z/RR; + ST = P/RR; + RX = 1.0/Math.sqrt(1.0-this.es*(2.0-this.es)*ST*ST); + CPHI0 = ST*(1.0-this.es)*RX; + SPHI0 = CT*RX; + iter = 0; + +/* loop to find sin(Latitude) resp. Latitude + * until |sin(Latitude(iter)-Latitude(iter-1))| < genau */ + do + { + iter++; + RN = this.a/Math.sqrt(1.0-this.es*SPHI0*SPHI0); + +/* ellipsoidal (geodetic) height */ + Height = P*CPHI0+Z*SPHI0-RN*(1.0-this.es*SPHI0*SPHI0); + + RK = this.es*RN/(RN+Height); + RX = 1.0/Math.sqrt(1.0-RK*(2.0-RK)*ST*ST); + CPHI = ST*(1.0-RK)*RX; + SPHI = CT*RX; + SDPHI = SPHI*CPHI0-CPHI*SPHI0; + CPHI0 = CPHI; + SPHI0 = SPHI; + } + while (SDPHI*SDPHI > genau2 && iter < maxiter); + +/* ellipsoidal (geodetic) latitude */ + Latitude=Math.atan(SPHI/Math.abs(CPHI)); + + p.x = Longitude; + p.y = Latitude; + p.z = Height; + return p; + }, // cs_geocentric_to_geodetic() + + /** Convert_Geocentric_To_Geodetic + * The method used here is derived from 'An Improved Algorithm for + * Geocentric to Geodetic Coordinate Conversion', by Ralph Toms, Feb 1996 + */ + geocentric_to_geodetic_noniter : function (p) { + var X = p.x; + var Y = p.y; + var Z = p.z ? p.z : 0; //Z value not always supplied + var Longitude; + var Latitude; + var Height; + + var W; /* distance from Z axis */ + var W2; /* square of distance from Z axis */ + var T0; /* initial estimate of vertical component */ + var T1; /* corrected estimate of vertical component */ + var S0; /* initial estimate of horizontal component */ + var S1; /* corrected estimate of horizontal component */ + var Sin_B0; /* Math.sin(B0), B0 is estimate of Bowring aux variable */ + var Sin3_B0; /* cube of Math.sin(B0) */ + var Cos_B0; /* Math.cos(B0) */ + var Sin_p1; /* Math.sin(phi1), phi1 is estimated latitude */ + var Cos_p1; /* Math.cos(phi1) */ + var Rn; /* Earth radius at location */ + var Sum; /* numerator of Math.cos(phi1) */ + var At_Pole; /* indicates location is in polar region */ + + X = parseFloat(X); // cast from string to float + Y = parseFloat(Y); + Z = parseFloat(Z); + + At_Pole = false; + if (X != 0.0) + { + Longitude = Math.atan2(Y,X); + } + else + { + if (Y > 0) + { + Longitude = Proj4js.common.HALF_PI; + } + else if (Y < 0) + { + Longitude = -Proj4js.common.HALF_PI; + } + else + { + At_Pole = true; + Longitude = 0.0; + if (Z > 0.0) + { /* north pole */ + Latitude = Proj4js.common.HALF_PI; + } + else if (Z < 0.0) + { /* south pole */ + Latitude = -Proj4js.common.HALF_PI; + } + else + { /* center of earth */ + Latitude = Proj4js.common.HALF_PI; + Height = -this.b; + return; + } + } + } + W2 = X*X + Y*Y; + W = Math.sqrt(W2); + T0 = Z * Proj4js.common.AD_C; + S0 = Math.sqrt(T0 * T0 + W2); + Sin_B0 = T0 / S0; + Cos_B0 = W / S0; + Sin3_B0 = Sin_B0 * Sin_B0 * Sin_B0; + T1 = Z + this.b * this.ep2 * Sin3_B0; + Sum = W - this.a * this.es * Cos_B0 * Cos_B0 * Cos_B0; + S1 = Math.sqrt(T1*T1 + Sum * Sum); + Sin_p1 = T1 / S1; + Cos_p1 = Sum / S1; + Rn = this.a / Math.sqrt(1.0 - this.es * Sin_p1 * Sin_p1); + if (Cos_p1 >= Proj4js.common.COS_67P5) + { + Height = W / Cos_p1 - Rn; + } + else if (Cos_p1 <= -Proj4js.common.COS_67P5) + { + Height = W / -Cos_p1 - Rn; + } + else + { + Height = Z / Sin_p1 + Rn * (this.es - 1.0); + } + if (At_Pole == false) + { + Latitude = Math.atan(Sin_p1 / Cos_p1); + } + + p.x = Longitude; + p.y = Latitude; + p.z = Height; + return p; + }, // geocentric_to_geodetic_noniter() + + /****************************************************************/ + // pj_geocentic_to_wgs84( p ) + // p = point to transform in geocentric coordinates (x,y,z) + geocentric_to_wgs84 : function ( p ) { + + if( this.datum_type == Proj4js.common.PJD_3PARAM ) + { + // if( x[io] == HUGE_VAL ) + // continue; + p.x += this.datum_params[0]; + p.y += this.datum_params[1]; + p.z += this.datum_params[2]; + + } + else if (this.datum_type == Proj4js.common.PJD_7PARAM) + { + var Dx_BF =this.datum_params[0]; + var Dy_BF =this.datum_params[1]; + var Dz_BF =this.datum_params[2]; + var Rx_BF =this.datum_params[3]; + var Ry_BF =this.datum_params[4]; + var Rz_BF =this.datum_params[5]; + var M_BF =this.datum_params[6]; + // if( x[io] == HUGE_VAL ) + // continue; + var x_out = M_BF*( p.x - Rz_BF*p.y + Ry_BF*p.z) + Dx_BF; + var y_out = M_BF*( Rz_BF*p.x + p.y - Rx_BF*p.z) + Dy_BF; + var z_out = M_BF*(-Ry_BF*p.x + Rx_BF*p.y + p.z) + Dz_BF; + p.x = x_out; + p.y = y_out; + p.z = z_out; + } + }, // cs_geocentric_to_wgs84 + + /****************************************************************/ + // pj_geocentic_from_wgs84() + // coordinate system definition, + // point to transform in geocentric coordinates (x,y,z) + geocentric_from_wgs84 : function( p ) { + + if( this.datum_type == Proj4js.common.PJD_3PARAM ) + { + //if( x[io] == HUGE_VAL ) + // continue; + p.x -= this.datum_params[0]; + p.y -= this.datum_params[1]; + p.z -= this.datum_params[2]; + + } + else if (this.datum_type == Proj4js.common.PJD_7PARAM) + { + var Dx_BF =this.datum_params[0]; + var Dy_BF =this.datum_params[1]; + var Dz_BF =this.datum_params[2]; + var Rx_BF =this.datum_params[3]; + var Ry_BF =this.datum_params[4]; + var Rz_BF =this.datum_params[5]; + var M_BF =this.datum_params[6]; + var x_tmp = (p.x - Dx_BF) / M_BF; + var y_tmp = (p.y - Dy_BF) / M_BF; + var z_tmp = (p.z - Dz_BF) / M_BF; + //if( x[io] == HUGE_VAL ) + // continue; + + p.x = x_tmp + Rz_BF*y_tmp - Ry_BF*z_tmp; + p.y = -Rz_BF*x_tmp + y_tmp + Rx_BF*z_tmp; + p.z = Ry_BF*x_tmp - Rx_BF*y_tmp + z_tmp; + } //cs_geocentric_from_wgs84() + } +}); + +/** point object, nothing fancy, just allows values to be + passed back and forth by reference rather than by value. + Other point classes may be used as long as they have + x and y properties, which will get modified in the transform method. +*/ +Proj4js.Point = Proj4js.Class({ + + /** + * Constructor: Proj4js.Point + * + * Parameters: + * - x {float} or {Array} either the first coordinates component or + * the full coordinates + * - y {float} the second component + * - z {float} the third component, optional. + */ + initialize : function(x,y,z) { + if (typeof x == 'object') { + this.x = x[0]; + this.y = x[1]; + this.z = x[2] || 0.0; + } else if (typeof x == 'string' && typeof y == 'undefined') { + var coords = x.split(','); + this.x = parseFloat(coords[0]); + this.y = parseFloat(coords[1]); + this.z = parseFloat(coords[2]) || 0.0; + } else { + this.x = x; + this.y = y; + this.z = z || 0.0; + } + }, + + /** + * APIMethod: clone + * Build a copy of a Proj4js.Point object. + * + * Return: + * {Proj4js}.Point the cloned point. + */ + clone : function() { + return new Proj4js.Point(this.x, this.y, this.z); + }, + + /** + * APIMethod: toString + * Return a readable string version of the point + * + * Return: + * {String} String representation of Proj4js.Point object. + * (ex. "x=5,y=42") + */ + toString : function() { + return ("x=" + this.x + ",y=" + this.y); + }, + + /** + * APIMethod: toShortString + * Return a short string version of the point. + * + * Return: + * {String} Shortened String representation of Proj4js.Point object. + * (ex. "5, 42") + */ + toShortString : function() { + return (this.x + ", " + this.y); + } +}); + +Proj4js.PrimeMeridian = { + "greenwich": 0.0, //"0dE", + "lisbon": -9.131906111111, //"9d07'54.862\"W", + "paris": 2.337229166667, //"2d20'14.025\"E", + "bogota": -74.080916666667, //"74d04'51.3\"W", + "madrid": -3.687938888889, //"3d41'16.58\"W", + "rome": 12.452333333333, //"12d27'8.4\"E", + "bern": 7.439583333333, //"7d26'22.5\"E", + "jakarta": 106.807719444444, //"106d48'27.79\"E", + "ferro": -17.666666666667, //"17d40'W", + "brussels": 4.367975, //"4d22'4.71\"E", + "stockholm": 18.058277777778, //"18d3'29.8\"E", + "athens": 23.7163375, //"23d42'58.815\"E", + "oslo": 10.722916666667 //"10d43'22.5\"E" +}; + +Proj4js.Ellipsoid = { + "MERIT": {a:6378137.0, rf:298.257, ellipseName:"MERIT 1983"}, + "SGS85": {a:6378136.0, rf:298.257, ellipseName:"Soviet Geodetic System 85"}, + "GRS80": {a:6378137.0, rf:298.257222101, ellipseName:"GRS 1980(IUGG, 1980)"}, + "IAU76": {a:6378140.0, rf:298.257, ellipseName:"IAU 1976"}, + "airy": {a:6377563.396, b:6356256.910, ellipseName:"Airy 1830"}, + "APL4.": {a:6378137, rf:298.25, ellipseName:"Appl. Physics. 1965"}, + "NWL9D": {a:6378145.0, rf:298.25, ellipseName:"Naval Weapons Lab., 1965"}, + "mod_airy": {a:6377340.189, b:6356034.446, ellipseName:"Modified Airy"}, + "andrae": {a:6377104.43, rf:300.0, ellipseName:"Andrae 1876 (Den., Iclnd.)"}, + "aust_SA": {a:6378160.0, rf:298.25, ellipseName:"Australian Natl & S. Amer. 1969"}, + "GRS67": {a:6378160.0, rf:298.2471674270, 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, ellipseName:"Comm. des Poids et Mesures 1799"}, + "delmbr": {a:6376428.0, 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)"}, + "fschr60": {a:6378166.0, rf:298.3, ellipseName:"Fischer (Mercury Datum) 1960"}, + "fschr60m": {a:6378155.0, rf:298.3, ellipseName:"Fischer 1960"}, + "fschr68": {a:6378150.0, rf:298.3, ellipseName:"Fischer 1968"}, + "helmert": {a:6378200.0, rf:298.3, ellipseName:"Helmert 1906"}, + "hough": {a:6378270.0, rf:297.0, ellipseName:"Hough"}, + "intl": {a:6378388.0, rf:297.0, ellipseName:"International 1909 (Hayford)"}, + "kaula": {a:6378163.0, rf:298.24, ellipseName:"Kaula 1961"}, + "lerch": {a:6378139.0, rf:298.257, ellipseName:"Lerch 1979"}, + "mprts": {a:6397300.0, rf:191.0, ellipseName:"Maupertius 1738"}, + "new_intl": {a:6378157.5, b:6356772.2, ellipseName:"New International 1967"}, + "plessis": {a:6376523.0, rf:6355863.0, ellipseName:"Plessis 1817 (France)"}, + "krass": {a:6378245.0, rf:298.3, ellipseName:"Krassovsky, 1942"}, + "SEasia": {a:6378155.0, b:6356773.3205, ellipseName:"Southeast Asia"}, + "walbeck": {a:6376896.0, b:6355834.8467, ellipseName:"Walbeck"}, + "WGS60": {a:6378165.0, rf:298.3, ellipseName:"WGS 60"}, + "WGS66": {a:6378145.0, rf:298.25, ellipseName:"WGS 66"}, + "WGS72": {a:6378135.0, rf:298.26, ellipseName:"WGS 72"}, + "WGS84": {a:6378137.0, rf:298.257223563, ellipseName:"WGS 84"}, + "sphere": {a:6370997.0, b:6370997.0, ellipseName:"Normal Sphere (r=6370997)"} +}; + +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", 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"} +}; + +Proj4js.WGS84 = new Proj4js.Proj('WGS84'); +Proj4js.Datum['OSB36'] = Proj4js.Datum['OSGB36']; //as returned from spatialreference.org + +//lookup table to go from the projection name in WKT to the Proj4js projection name +//build this out as required +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" +}; + + diff --git a/ajax/libs/proj4js/1.1.0/projCode/aea.js b/ajax/libs/proj4js/1.1.0/projCode/aea.js new file mode 100755 index 000000000..947e780af --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/aea.js @@ -0,0 +1,149 @@ +/******************************************************************************* +NAME ALBERS CONICAL EQUAL AREA + +PURPOSE: Transforms input longitude and latitude to Easting and Northing + for the Albers Conical Equal Area projection. The longitude + and latitude must be in radians. The Easting and Northing + values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +T. Mittan, Feb, 1992 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + + +Proj4js.Proj.aea = { + init : function() { + + if (Math.abs(this.lat1 + this.lat2) < Proj4js.common.EPSLN) { + Proj4js.reportError("aeaInitEqualLatitudes"); + return; + } + this.temp = this.b / this.a; + this.es = 1.0 - Math.pow(this.temp,2); + this.e3 = Math.sqrt(this.es); + + this.sin_po=Math.sin(this.lat1); + this.cos_po=Math.cos(this.lat1); + this.t1=this.sin_po; + this.con = this.sin_po; + this.ms1 = Proj4js.common.msfnz(this.e3,this.sin_po,this.cos_po); + this.qs1 = Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po); + + this.sin_po=Math.sin(this.lat2); + this.cos_po=Math.cos(this.lat2); + this.t2=this.sin_po; + this.ms2 = Proj4js.common.msfnz(this.e3,this.sin_po,this.cos_po); + this.qs2 = Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po); + + this.sin_po=Math.sin(this.lat0); + this.cos_po=Math.cos(this.lat0); + this.t3=this.sin_po; + this.qs0 = Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po); + + if (Math.abs(this.lat1 - this.lat2) > Proj4js.common.EPSLN) { + this.ns0 = (this.ms1 * this.ms1 - this.ms2 *this.ms2)/ (this.qs2 - this.qs1); + } else { + this.ns0 = this.con; + } + this.c = this.ms1 * this.ms1 + this.ns0 * this.qs1; + this.rh = this.a * Math.sqrt(this.c - this.ns0 * this.qs0)/this.ns0; + }, + +/* Albers Conical Equal Area forward equations--mapping lat,long to x,y + -------------------------------------------------------------------*/ + forward: function(p){ + + var lon=p.x; + var lat=p.y; + + this.sin_phi=Math.sin(lat); + this.cos_phi=Math.cos(lat); + + var qs = Proj4js.common.qsfnz(this.e3,this.sin_phi,this.cos_phi); + var rh1 =this.a * Math.sqrt(this.c - this.ns0 * qs)/this.ns0; + var theta = this.ns0 * Proj4js.common.adjust_lon(lon - this.long0); + var x = rh1 * Math.sin(theta) + this.x0; + var y = this.rh - rh1 * Math.cos(theta) + this.y0; + + p.x = x; + p.y = y; + return p; + }, + + + inverse: function(p) { + var rh1,qs,con,theta,lon,lat; + + p.x -= this.x0; + p.y = this.rh - p.y + this.y0; + if (this.ns0 >= 0) { + rh1 = Math.sqrt(p.x *p.x + p.y * p.y); + con = 1.0; + } else { + rh1 = -Math.sqrt(p.x * p.x + p.y *p.y); + con = -1.0; + } + theta = 0.0; + if (rh1 != 0.0) { + theta = Math.atan2(con * p.x, con * p.y); + } + con = rh1 * this.ns0 / this.a; + qs = (this.c - con * con) / this.ns0; + if (this.e3 >= 1e-10) { + con = 1 - .5 * (1.0 -this.es) * Math.log((1.0 - this.e3) / (1.0 + this.e3))/this.e3; + if (Math.abs(Math.abs(con) - Math.abs(qs)) > .0000000001 ) { + lat = this.phi1z(this.e3,qs); + } else { + if (qs >= 0) { + lat = .5 * Proj4js.common.PI; + } else { + lat = -.5 * Proj4js.common.PI; + } + } + } else { + lat = this.phi1z(this.e3,qs); + } + + lon = Proj4js.common.adjust_lon(theta/this.ns0 + this.long0); + p.x = lon; + p.y = lat; + return p; + }, + +/* Function to compute phi1, the latitude for the inverse of the + Albers Conical Equal-Area projection. +-------------------------------------------*/ + phi1z: function (eccent,qs) { + var sinphi, cosphi, con, com, dphi; + var phi = Proj4js.common.asinz(.5 * qs); + if (eccent < Proj4js.common.EPSLN) return phi; + + var eccnts = eccent * eccent; + for (var i = 1; i <= 25; i++) { + sinphi = Math.sin(phi); + cosphi = Math.cos(phi); + con = eccent * sinphi; + com = 1.0 - con * con; + dphi = .5 * com * com / cosphi * (qs / (1.0 - eccnts) - sinphi / com + .5 / eccent * Math.log((1.0 - con) / (1.0 + con))); + phi = phi + dphi; + if (Math.abs(dphi) <= 1e-7) return phi; + } + Proj4js.reportError("aea:phi1z:Convergence error"); + return null; + } + +}; + + + diff --git a/ajax/libs/proj4js/1.1.0/projCode/aeqd.js b/ajax/libs/proj4js/1.1.0/projCode/aeqd.js new file mode 100755 index 000000000..6e0455cb5 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/aeqd.js @@ -0,0 +1,75 @@ +Proj4js.Proj.aeqd = { + + init : function() { + this.sin_p12=Math.sin(this.lat0); + this.cos_p12=Math.cos(this.lat0); + }, + + forward: function(p) { + var lon=p.x; + var lat=p.y; + var ksp; + + var sinphi=Math.sin(p.y); + var cosphi=Math.cos(p.y); + var dlon = Proj4js.common.adjust_lon(lon - this.long0); + var coslon = Math.cos(dlon); + var g = this.sin_p12 * sinphi + this.cos_p12 * cosphi * coslon; + if (Math.abs(Math.abs(g) - 1.0) < Proj4js.common.EPSLN) { + ksp = 1.0; + if (g < 0.0) { + Proj4js.reportError("aeqd:Fwd:PointError"); + return; + } + } else { + var z = Math.acos(g); + ksp = z/Math.sin(z); + } + p.x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon); + p.y = this.y0 + this.a * ksp * (this.cos_p12 * sinphi - this.sin_p12 * cosphi * coslon); + return p; + }, + + inverse: function(p){ + p.x -= this.x0; + p.y -= this.y0; + + var rh = Math.sqrt(p.x * p.x + p.y *p.y); + if (rh > (2.0 * Proj4js.common.HALF_PI * this.a)) { + Proj4js.reportError("aeqdInvDataError"); + return; + } + var z = rh / this.a; + + var sinz=Math.sin(z); + var cosz=Math.cos(z); + + var lon = this.long0; + var lat; + if (Math.abs(rh) <= Proj4js.common.EPSLN) { + lat = this.lat0; + } else { + lat = Proj4js.common.asinz(cosz * this.sin_p12 + (p.y * sinz * this.cos_p12) / rh); + var con = Math.abs(this.lat0) - Proj4js.common.HALF_PI; + if (Math.abs(con) <= Proj4js.common.EPSLN) { + if (this.lat0 >= 0.0) { + lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2(p.x , -p.y)); + } else { + lon = Proj4js.common.adjust_lon(this.long0 - Math.atan2(-p.x , p.y)); + } + } else { + con = cosz - this.sin_p12 * Math.sin(lat); + if ((Math.abs(con) < Proj4js.common.EPSLN) && (Math.abs(p.x) < Proj4js.common.EPSLN)) { + //no-op, just keep the lon value as is + } else { + var temp = Math.atan2((p.x * sinz * this.cos_p12), (con * rh)); + lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2((p.x * sinz * this.cos_p12), (con * rh))); + } + } + } + + p.x = lon; + p.y = lat; + return p; + } +}; diff --git a/ajax/libs/proj4js/1.1.0/projCode/cass.js b/ajax/libs/proj4js/1.1.0/projCode/cass.js new file mode 100755 index 000000000..ef629457d --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/cass.js @@ -0,0 +1,108 @@ +/******************************************************************************* +NAME CASSINI + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Cassini projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + Ported from PROJ.4. + + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government +*******************************************************************************/ + + +//Proj4js.defs["EPSG:28191"] = "+proj=cass +lat_0=31.73409694444445 +lon_0=35.21208055555556 +x_0=170251.555 +y_0=126867.909 +a=6378300.789 +b=6356566.435 +towgs84=-275.722,94.7824,340.894,-8.001,-4.42,-11.821,1 +units=m +no_defs"; + +// Initialize the Cassini projection +// ----------------------------------------------------------------- + +Proj4js.Proj.cass = { + init : function() { + if (!this.sphere) { + this.en = Proj4js.common.pj_enfn(this.es) + this.m0 = Proj4js.common.pj_mlfn(this.lat0, Math.sin(this.lat0), Math.cos(this.lat0), this.en); + } + }, + + C1: .16666666666666666666, + C2: .00833333333333333333, + C3: .04166666666666666666, + C4: .33333333333333333333, + C5: .06666666666666666666, + + +/* Cassini forward equations--mapping lat,long to x,y + -----------------------------------------------------------------------*/ + forward: function(p) { + + /* Forward equations + -----------------*/ + var x,y; + var lam=p.x; + var phi=p.y; + lam = Proj4js.common.adjust_lon(lam - this.long0); + + if (this.sphere) { + x = Math.asin(Math.cos(phi) * Math.sin(lam)); + y = Math.atan2(Math.tan(phi) , Math.cos(lam)) - this.phi0; + } else { + //ellipsoid + this.n = Math.sin(phi); + this.c = Math.cos(phi); + y = Proj4js.common.pj_mlfn(phi, this.n, this.c, this.en); + this.n = 1./Math.sqrt(1. - this.es * this.n * this.n); + this.tn = Math.tan(phi); + this.t = this.tn * this.tn; + this.a1 = lam * this.c; + this.c *= this.es * this.c / (1 - this.es); + this.a2 = this.a1 * this.a1; + x = this.n * this.a1 * (1. - this.a2 * this.t * (this.C1 - (8. - this.t + 8. * this.c) * this.a2 * this.C2)); + y -= this.m0 - this.n * this.tn * this.a2 * (.5 + (5. - this.t + 6. * this.c) * this.a2 * this.C3); + } + + p.x = this.a*x + this.x0; + p.y = this.a*y + this.y0; + return p; + },//cassFwd() + +/* Inverse equations + -----------------*/ + inverse: function(p) { + p.x -= this.x0; + p.y -= this.y0; + var x = p.x/this.a; + var y = p.y/this.a; + var phi, lam; + + if (this.sphere) { + this.dd = y + this.lat0; + phi = Math.asin(Math.sin(this.dd) * Math.cos(x)); + lam = Math.atan2(Math.tan(x), Math.cos(this.dd)); + } else { + /* ellipsoid */ + var ph1 = Proj4js.common.pj_inv_mlfn(this.m0 + y, this.es, this.en); + this.tn = Math.tan(ph1); + this.t = this.tn * this.tn; + this.n = Math.sin(ph1); + this.r = 1. / (1. - this.es * this.n * this.n); + this.n = Math.sqrt(this.r); + this.r *= (1. - this.es) * this.n; + this.dd = x / this.n; + this.d2 = this.dd * this.dd; + phi = ph1 - (this.n * this.tn / this.r) * this.d2 * (.5 - (1. + 3. * this.t) * this.d2 * this.C3); + lam = this.dd * (1. + this.t * this.d2 * (-this.C4 + (1. + 3. * this.t) * this.d2 * this.C5)) / Math.cos(ph1); + } + p.x = Proj4js.common.adjust_lon(this.long0+lam); + p.y = phi; + return p; + }//cassInv() + +} diff --git a/ajax/libs/proj4js/1.1.0/projCode/cea.js b/ajax/libs/proj4js/1.1.0/projCode/cea.js new file mode 100755 index 000000000..6e2a8bc46 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/cea.js @@ -0,0 +1,85 @@ +/******************************************************************************* +NAME LAMBERT CYLINDRICAL EQUAL AREA + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Lambert Cylindrical Equal Area projection. + This class of projection includes the Behrmann and + Gall-Peters Projections. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +R. Marsden August 2009 +Winwaed Software Tech LLC, http://www.winwaed.com + +This function was adapted from the Miller Cylindrical Projection in the Proj4JS +library. + +Note: This implementation assumes a Spherical Earth. The (commented) code +has been included for the ellipsoidal forward transform, but derivation of +the ellispoidal inverse transform is beyond me. Note that most of the +Proj4JS implementations do NOT currently support ellipsoidal figures. +Therefore this is not seen as a problem - especially this lack of support +is explicitly stated here. + +ALGORITHM REFERENCES + +1. "Cartographic Projection Procedures for the UNIX Environment - + A User's Manual" by Gerald I. Evenden, USGS Open File Report 90-284 + and Release 4 Interim Reports (2003) + +2. Snyder, John P., "Flattening the Earth - Two Thousand Years of Map + Projections", Univ. Chicago Press, 1993 +*******************************************************************************/ + +Proj4js.Proj.cea = { + +/* Initialize the Cylindrical Equal Area projection + -------------------------------------------*/ + init: function() { + //no-op + }, + + + /* Cylindrical Equal Area forward equations--mapping lat,long to x,y + ------------------------------------------------------------*/ + forward: function(p) { + var lon=p.x; + var lat=p.y; + /* Forward equations + -----------------*/ + var dlon = Proj4js.common.adjust_lon(lon -this.long0); + var x = this.x0 + this.a * dlon * Math.cos(this.lat_ts); + var y = this.y0 + this.a * Math.sin(lat) / Math.cos(this.lat_ts); + /* Elliptical Forward Transform + Not implemented due to a lack of a matchign inverse function + { + var Sin_Lat = Math.sin(lat); + var Rn = this.a * (Math.sqrt(1.0e0 - this.es * Sin_Lat * Sin_Lat )); + x = this.x0 + this.a * dlon * Math.cos(this.lat_ts); + y = this.y0 + Rn * Math.sin(lat) / Math.cos(this.lat_ts); + } + */ + + + p.x=x; + p.y=y; + return p; + },//ceaFwd() + + /* Cylindrical Equal Area inverse equations--mapping x,y to lat/long + ------------------------------------------------------------*/ + inverse: function(p) { + p.x -= this.x0; + p.y -= this.y0; + + var lon = Proj4js.common.adjust_lon( this.long0 + (p.x / this.a) / Math.cos(this.lat_ts) ); + + var lat = Math.asin( (p.y/this.a) * Math.cos(this.lat_ts) ); + + p.x=lon; + p.y=lat; + return p; + }//ceaInv() +}; diff --git a/ajax/libs/proj4js/1.1.0/projCode/eqc.js b/ajax/libs/proj4js/1.1.0/projCode/eqc.js new file mode 100755 index 000000000..672c0e801 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/eqc.js @@ -0,0 +1,42 @@ +/* similar to equi.js FIXME proj4 uses eqc */ +Proj4js.Proj.eqc = { + init : function() { + + if(!this.x0) this.x0=0; + if(!this.y0) this.y0=0; + if(!this.lat0) this.lat0=0; + if(!this.long0) this.long0=0; + if(!this.lat_ts) this.lat_ts=0; + if (!this.title) this.title = "Equidistant Cylindrical (Plate Carre)"; + + this.rc= Math.cos(this.lat_ts); + }, + + + // forward equations--mapping lat,long to x,y + // ----------------------------------------------------------------- + forward : function(p) { + + var lon= p.x; + var lat= p.y; + + var dlon = Proj4js.common.adjust_lon(lon - this.long0); + var dlat = Proj4js.common.adjust_lat(lat - this.lat0 ); + p.x= this.x0 + (this.a*dlon*this.rc); + p.y= this.y0 + (this.a*dlat ); + return p; + }, + + // inverse equations--mapping x,y to lat/long + // ----------------------------------------------------------------- + inverse : function(p) { + + var x= p.x; + var y= p.y; + + p.x= Proj4js.common.adjust_lon(this.long0 + ((x - this.x0)/(this.a*this.rc))); + p.y= Proj4js.common.adjust_lat(this.lat0 + ((y - this.y0)/(this.a ))); + return p; + } + +}; diff --git a/ajax/libs/proj4js/1.1.0/projCode/eqdc.js b/ajax/libs/proj4js/1.1.0/projCode/eqdc.js new file mode 100755 index 000000000..ab8b4f8e1 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/eqdc.js @@ -0,0 +1,140 @@ +/******************************************************************************* +NAME EQUIDISTANT CONIC + +PURPOSE: Transforms input longitude and latitude to Easting and Northing + for the Equidistant Conic projection. The longitude and + latitude must be in radians. The Easting and Northing values + will be returned in meters. + +PROGRAMMER DATE +---------- ---- +T. Mittan Mar, 1993 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + +/* Variables common to all subroutines in this code file + -----------------------------------------------------*/ + +Proj4js.Proj.eqdc = { + +/* Initialize the Equidistant Conic projection + ------------------------------------------*/ + init: function() { + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + + if(!this.mode) this.mode=0;//chosen default mode + this.temp = this.b / this.a; + this.es = 1.0 - 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); + + /* format B + ---------*/ + if (this.mode != 0) { + if (Math.abs(this.lat1 + this.lat2) < Proj4js.common.EPSLN) { + Proj4js.reportError("eqdc:Init:EqualLatitudes"); + //return(81); + } + this.sinphi=Math.sin(this.lat2); + this.cosphi=Math.cos(this.lat2); + + this.ms2 = Proj4js.common.msfnz(this.e,this.sinphi,this.cosphi); + this.ml2 = Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, this.lat2); + if (Math.abs(this.lat1 - this.lat2) >= Proj4js.common.EPSLN) { + this.ns = (this.ms1 - this.ms2) / (this.ml2 - this.ml1); + } else { + this.ns = this.sinphi; + } + } else { + this.ns = this.sinphi; + } + this.g = this.ml1 + this.ms1/this.ns; + this.ml0 = Proj4js.common.mlfn(this.e0, this.e1,this. e2, this.e3, this.lat0); + this.rh = this.a * (this.g - this.ml0); + }, + + +/* Equidistant Conic forward equations--mapping lat,long to x,y + -----------------------------------------------------------*/ + forward: function(p) { + var lon=p.x; + var lat=p.y; + + /* Forward equations + -----------------*/ + var ml = Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, lat); + var rh1 = this.a * (this.g - ml); + var theta = this.ns * Proj4js.common.adjust_lon(lon - this.long0); + + var x = this.x0 + rh1 * Math.sin(theta); + var y = this.y0 + this.rh - rh1 * Math.cos(theta); + p.x=x; + p.y=y; + return p; + }, + +/* Inverse equations + -----------------*/ + inverse: function(p) { + p.x -= this.x0; + p.y = this.rh - p.y + this.y0; + var con, rh1; + if (this.ns >= 0) { + rh1 = Math.sqrt(p.x *p.x + p.y * p.y); + con = 1.0; + } else { + rh1 = -Math.sqrt(p.x *p. x +p. y * p.y); + con = -1.0; + } + var theta = 0.0; + if (rh1 != 0.0) theta = Math.atan2(con *p.x, con *p.y); + var ml = this.g - rh1 /this.a; + var lat = this.phi3z(ml,this.e0,this.e1,this.e2,this.e3); + var lon = Proj4js.common.adjust_lon(this.long0 + theta / this.ns); + + p.x=lon; + p.y=lat; + return p; + }, + +/* Function to compute latitude, phi3, for the inverse of the Equidistant + Conic projection. +-----------------------------------------------------------------*/ + phi3z: function(ml,e0,e1,e2,e3) { + var phi; + var dphi; + + phi = ml; + for (var i = 0; i < 15; i++) { + dphi = (ml + e1 * Math.sin(2.0 * phi) - e2 * Math.sin(4.0 * phi) + e3 * Math.sin(6.0 * phi))/ e0 - phi; + phi += dphi; + if (Math.abs(dphi) <= .0000000001) { + return phi; + } + } + Proj4js.reportError("PHI3Z-CONV:Latitude failed to converge after 15 iterations"); + return null; + } + + +}; \ No newline at end of file diff --git a/ajax/libs/proj4js/1.1.0/projCode/equi.js b/ajax/libs/proj4js/1.1.0/projCode/equi.js new file mode 100755 index 000000000..88af96f7f --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/equi.js @@ -0,0 +1,72 @@ +/******************************************************************************* +NAME EQUIRECTANGULAR + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Equirectangular projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +T. Mittan Mar, 1993 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ +Proj4js.Proj.equi = { + + init: function() { + if(!this.x0) this.x0=0; + if(!this.y0) this.y0=0; + if(!this.lat0) this.lat0=0; + if(!this.long0) this.long0=0; + ///this.t2; + }, + + + +/* Equirectangular forward equations--mapping lat,long to x,y + ---------------------------------------------------------*/ + forward: function(p) { + + var lon=p.x; + var lat=p.y; + + var dlon = Proj4js.common.adjust_lon(lon - this.long0); + var x = this.x0 +this. a * dlon *Math.cos(this.lat0); + var y = this.y0 + this.a * lat; + + this.t1=x; + this.t2=Math.cos(this.lat0); + p.x=x; + p.y=y; + return p; + }, //equiFwd() + + + +/* Equirectangular inverse equations--mapping x,y to lat/long + ---------------------------------------------------------*/ + inverse: function(p) { + + p.x -= this.x0; + p.y -= this.y0; + var lat = p.y /this. a; + + if ( Math.abs(lat) > Proj4js.common.HALF_PI) { + Proj4js.reportError("equi:Inv:DataError"); + } + var lon = Proj4js.common.adjust_lon(this.long0 + p.x / (this.a * Math.cos(this.lat0))); + p.x=lon; + p.y=lat; + }//equiInv() +}; + + diff --git a/ajax/libs/proj4js/1.1.0/projCode/gauss.js b/ajax/libs/proj4js/1.1.0/projCode/gauss.js new file mode 100755 index 000000000..11adff28f --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/gauss.js @@ -0,0 +1,44 @@ + +Proj4js.Proj.gauss = { + + init : function() { + var sphi = Math.sin(this.lat0); + var cphi = Math.cos(this.lat0); + cphi *= cphi; + this.rc = Math.sqrt(1.0 - this.es) / (1.0 - this.es * sphi * sphi); + this.C = Math.sqrt(1.0 + this.es * cphi * cphi / (1.0 - this.es)); + this.phic0 = Math.asin(sphi / this.C); + this.ratexp = 0.5 * this.C * this.e; + this.K = Math.tan(0.5 * this.phic0 + Proj4js.common.FORTPI) / (Math.pow(Math.tan(0.5*this.lat0 + Proj4js.common.FORTPI), this.C) * Proj4js.common.srat(this.e*sphi, this.ratexp)); + }, + + forward : function(p) { + var lon = p.x; + var lat = p.y; + + p.y = 2.0 * Math.atan( this.K * Math.pow(Math.tan(0.5 * lat + Proj4js.common.FORTPI), this.C) * Proj4js.common.srat(this.e * Math.sin(lat), this.ratexp) ) - Proj4js.common.HALF_PI; + p.x = this.C * lon; + return p; + }, + + inverse : function(p) { + var DEL_TOL = 1e-14; + var lon = p.x / this.C; + var lat = p.y; + var num = Math.pow(Math.tan(0.5 * lat + Proj4js.common.FORTPI)/this.K, 1./this.C); + for (var i = Proj4js.common.MAX_ITER; i>0; --i) { + lat = 2.0 * Math.atan(num * Proj4js.common.srat(this.e * Math.sin(p.y), -0.5 * this.e)) - Proj4js.common.HALF_PI; + if (Math.abs(lat - p.y) < DEL_TOL) break; + p.y = lat; + } + /* convergence failed */ + if (!i) { + Proj4js.reportError("gauss:inverse:convergence failed"); + return null; + } + p.x = lon; + p.y = lat; + return p; + } +}; + diff --git a/ajax/libs/proj4js/1.1.0/projCode/gnom.js b/ajax/libs/proj4js/1.1.0/projCode/gnom.js new file mode 100755 index 000000000..4ba4c9bdb --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/gnom.js @@ -0,0 +1,117 @@ +/***************************************************************************** +NAME GNOMONIC + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Gnomonic Projection. + Implementation based on the existing sterea and ortho + implementations. + +PROGRAMMER DATE +---------- ---- +Richard Marsden November 2009 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Flattening the Earth - Two Thousand Years of Map + Projections", University of Chicago Press 1993 + +2. Wolfram Mathworld "Gnomonic Projection" + http://mathworld.wolfram.com/GnomonicProjection.html + Accessed: 12th November 2009 +******************************************************************************/ + +Proj4js.Proj.gnom = { + + /* Initialize the Gnomonic projection + -------------------------------------*/ + init: function(def) { + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + this.sin_p14=Math.sin(this.lat0); + this.cos_p14=Math.cos(this.lat0); + // Approximation for projecting points to the horizon (infinity) + this.infinity_dist = 1000 * this.a; + this.rc = 1; + }, + + + /* Gnomonic forward equations--mapping lat,long to x,y + ---------------------------------------------------*/ + forward: function(p) { + var sinphi, cosphi; /* sin and cos value */ + var dlon; /* delta longitude value */ + var coslon; /* cos of longitude */ + var ksp; /* scale factor */ + var g; + var x, y; + var lon=p.x; + var lat=p.y; + /* Forward equations + -----------------*/ + dlon = Proj4js.common.adjust_lon(lon - this.long0); + + sinphi=Math.sin(lat); + cosphi=Math.cos(lat); + + coslon = Math.cos(dlon); + g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon; + ksp = 1.0; + if ((g > 0) || (Math.abs(g) <= Proj4js.common.EPSLN)) { + x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon) / g; + y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon) / g; + } else { + Proj4js.reportError("orthoFwdPointError"); + + // Point is in the opposing hemisphere and is unprojectable + // We still need to return a reasonable point, so we project + // to infinity, on a bearing + // equivalent to the northern hemisphere equivalent + // This is a reasonable approximation for short shapes and lines that + // straddle the horizon. + + x = this.x0 + this.infinity_dist * cosphi * Math.sin(dlon); + y = this.y0 + this.infinity_dist * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon); + + } + p.x=x; + p.y=y; + return p; + }, + + + inverse: function(p) { + var rh; /* Rho */ + var z; /* angle */ + var sinc, cosc; + var c; + var lon , lat; + + /* Inverse equations + -----------------*/ + p.x = (p.x - this.x0) / this.a; + p.y = (p.y - this.y0) / this.a; + + p.x /= this.k0; + p.y /= this.k0; + + if ( (rh = Math.sqrt(p.x * p.x + p.y * p.y)) ) { + c = Math.atan2(rh, this.rc); + sinc = Math.sin(c); + cosc = Math.cos(c); + + lat = Proj4js.common.asinz(cosc*this.sin_p14 + (p.y*sinc*this.cos_p14) / rh); + lon = Math.atan2(p.x*sinc, rh*this.cos_p14*cosc - p.y*this.sin_p14*sinc); + lon = Proj4js.common.adjust_lon(this.long0+lon); + } else { + lat = this.phic0; + lon = 0.0; + } + + p.x=lon; + p.y=lat; + return p; + } +}; + + diff --git a/ajax/libs/proj4js/1.1.0/projCode/gstmerc.js b/ajax/libs/proj4js/1.1.0/projCode/gstmerc.js new file mode 100755 index 000000000..d7f38ffa1 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/gstmerc.js @@ -0,0 +1,52 @@ +Proj4js.Proj.gstmerc = { + init : function() { + + // array of: a, b, lon0, lat0, k0, x0, y0 + var temp= this.b / this.a; + this.e= Math.sqrt(1.0 - temp*temp); + this.lc= this.long0; + this.rs= Math.sqrt(1.0+this.e*this.e*Math.pow(Math.cos(this.lat0),4.0)/(1.0-this.e*this.e)); + var sinz= Math.sin(this.lat0); + var pc= Math.asin(sinz/this.rs); + var sinzpc= Math.sin(pc); + this.cp= Proj4js.common.latiso(0.0,pc,sinzpc)-this.rs*Proj4js.common.latiso(this.e,this.lat0,sinz); + this.n2= this.k0*this.a*Math.sqrt(1.0-this.e*this.e)/(1.0-this.e*this.e*sinz*sinz); + this.xs= this.x0; + this.ys= this.y0-this.n2*pc; + + if (!this.title) this.title = "Gauss Schreiber transverse mercator"; + }, + + + // forward equations--mapping lat,long to x,y + // ----------------------------------------------------------------- + forward : function(p) { + + var lon= p.x; + var lat= p.y; + + var L= this.rs*(lon-this.lc); + var Ls= this.cp+(this.rs*Proj4js.common.latiso(this.e,lat,Math.sin(lat))); + var lat1= Math.asin(Math.sin(L)/Proj4js.common.cosh(Ls)); + var Ls1= Proj4js.common.latiso(0.0,lat1,Math.sin(lat1)); + p.x= this.xs+(this.n2*Ls1); + p.y= this.ys+(this.n2*Math.atan(Proj4js.common.sinh(Ls)/Math.cos(L))); + return p; + }, + + // inverse equations--mapping x,y to lat/long + // ----------------------------------------------------------------- + inverse : function(p) { + + var x= p.x; + var y= p.y; + + var L= Math.atan(Proj4js.common.sinh((x-this.xs)/this.n2)/Math.cos((y-this.ys)/this.n2)); + var lat1= Math.asin(Math.sin((y-this.ys)/this.n2)/Proj4js.common.cosh((x-this.xs)/this.n2)); + var LC= Proj4js.common.latiso(0.0,lat1,Math.sin(lat1)); + p.x= this.lc+L/this.rs; + p.y= Proj4js.common.invlatiso(this.e,(LC-this.cp)/this.rs); + return p; + } + +}; diff --git a/ajax/libs/proj4js/1.1.0/projCode/krovak.js b/ajax/libs/proj4js/1.1.0/projCode/krovak.js new file mode 100755 index 000000000..4496b0285 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/krovak.js @@ -0,0 +1,135 @@ +/** + NOTES: According to EPSG the full Krovak projection method should have + the following parameters. Within PROJ.4 the azimuth, and pseudo + standard parallel are hardcoded in the algorithm and can't be + altered from outside. The others all have defaults to match the + common usage with Krovak projection. + + lat_0 = latitude of centre of the projection + + lon_0 = longitude of centre of the projection + + ** = azimuth (true) of the centre line passing through the centre of the projection + + ** = latitude of pseudo standard parallel + + k = scale factor on the pseudo standard parallel + + x_0 = False Easting of the centre of the projection at the apex of the cone + + y_0 = False Northing of the centre of the projection at the apex of the cone + + **/ + +Proj4js.Proj.krovak = { + + init: function() { + /* we want Bessel as fixed ellipsoid */ + this.a = 6377397.155; + this.es = 0.006674372230614; + this.e = Math.sqrt(this.es); + /* if latitude of projection center is not set, use 49d30'N */ + if (!this.lat0) { + this.lat0 = 0.863937979737193; + } + if (!this.long0) { + this.long0 = 0.7417649320975901 - 0.308341501185665; + } + /* if scale not set default to 0.9999 */ + if (!this.k0) { + this.k0 = 0.9999; + } + this.s45 = 0.785398163397448; /* 45° */ + this.s90 = 2 * this.s45; + this.fi0 = this.lat0; /* Latitude of projection centre 49° 30' */ + /* Ellipsoid Bessel 1841 a = 6377397.155m 1/f = 299.1528128, + e2=0.006674372230614; + */ + this.e2 = this.es; /* 0.006674372230614; */ + 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; /* DU(2, 59, 42, 42.69689) */ + this.u0 = Math.asin(Math.sin(this.fi0) / this.alfa); + this.g = Math.pow( (1. + this.e * Math.sin(this.fi0)) / (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; /* Latitude of pseudo standard parallel 78° 30'00" N */ + this.n = Math.sin(this.s0); + this.ro0 = this.k1 * this.n0 / Math.tan(this.s0); + this.ad = this.s90 - this.uq; + }, + + /* ellipsoid */ + /* calculate xy from lat/lon */ + /* Constants, identical to inverse transform function */ + forward: function(p) { + var gfi, u, deltav, s, d, eps, ro; + var lon = p.x; + var lat = p.y; + var delta_lon = Proj4js.common.adjust_lon(lon - this.long0); // Delta longitude + /* Transformation */ + gfi = Math.pow ( ((1. + this.e * Math.sin(lat)) / (1. - this.e * Math.sin(lat))) , (this.alfa * this.e / 2.)); + u= 2. * (Math.atan(this.k * Math.pow( Math.tan(lat / 2. + this.s45), this.alfa) / gfi)-this.s45); + deltav = - delta_lon * this.alfa; + s = Math.asin(Math.cos(this.ad) * Math.sin(u) + Math.sin(this.ad) * Math.cos(u) * Math.cos(deltav)); + d = Math.asin(Math.cos(u) * Math.sin(deltav) / Math.cos(s)); + eps = this.n * d; + ro = this.ro0 * Math.pow(Math.tan(this.s0 / 2. + this.s45) , this.n) / Math.pow(Math.tan(s / 2. + this.s45) , this.n); + /* x and y are reverted! */ + //p.y = ro * Math.cos(eps) / a; + //p.x = ro * Math.sin(eps) / a; + p.y = ro * Math.cos(eps) / 1.0; + p.x = ro * Math.sin(eps) / 1.0; + + if(this.czech) { + p.y *= -1.0; + p.x *= -1.0; + } + return (p); + }, + + /* calculate lat/lon from xy */ + inverse: function(p) { + /* Constants, identisch wie in der Umkehrfunktion */ + var u, deltav, s, d, eps, ro, fi1; + var ok; + + /* Transformation */ + /* revert y, x*/ + var tmp = p.x; + p.x=p.y; + p.y=tmp; + if(this.czech) { + p.y *= -1.0; + p.x *= -1.0; + } + ro = Math.sqrt(p.x * p.x + p.y * p.y); + eps = Math.atan2(p.y, p.x); + d = eps / Math.sin(this.s0); + s = 2. * (Math.atan( Math.pow(this.ro0 / ro, 1. / this.n) * Math.tan(this.s0 / 2. + this.s45)) - this.s45); + u = Math.asin(Math.cos(this.ad) * Math.sin(s) - Math.sin(this.ad) * Math.cos(s) * Math.cos(d)); + deltav = Math.asin(Math.cos(s) * Math.sin(d) / Math.cos(u)); + p.x = this.long0 - deltav / this.alfa; + /* ITERATION FOR lat */ + fi1 = u; + ok = 0; + var iter = 0; + do { + p.y = 2. * ( Math.atan( Math.pow( this.k, -1. / this.alfa) * + Math.pow( Math.tan(u / 2. + this.s45) , 1. / this.alfa) * + Math.pow( (1. + this.e * Math.sin(fi1)) / (1. - this.e * Math.sin(fi1)) , this.e / 2.) + ) - this.s45); + if (Math.abs(fi1 - p.y) < 0.0000000001) ok=1; + fi1 = p.y; + iter += 1; + } while (ok==0 && iter < 15); + if (iter >= 15) { + Proj4js.reportError("PHI3Z-CONV:Latitude failed to converge after 15 iterations"); + //console.log('iter:', iter); + return null; + } + + return (p); + } +}; diff --git a/ajax/libs/proj4js/1.1.0/projCode/laea.js b/ajax/libs/proj4js/1.1.0/projCode/laea.js new file mode 100755 index 000000000..c786ba074 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/laea.js @@ -0,0 +1,358 @@ +/******************************************************************************* +NAME LAMBERT AZIMUTHAL EQUAL-AREA + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Lambert Azimuthal Equal-Area projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +D. Steinwand, EROS March, 1991 + +This function was adapted from the Lambert Azimuthal Equal Area projection +code (FORTRAN) in the General Cartographic Transformation Package software +which is available from the U.S. Geological Survey National Mapping Division. + +ALGORITHM REFERENCES + +1. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder, + The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355. + +2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +3. "Software Documentation for GCTP General Cartographic Transformation + Package", U.S. Geological Survey National Mapping Division, May 1982. +*******************************************************************************/ + +Proj4js.Proj.laea = { + S_POLE: 1, + N_POLE: 2, + EQUIT: 3, + OBLIQ: 4, + + +/* Initialize the Lambert Azimuthal Equal Area projection + ------------------------------------------------------*/ + init: function() { + var t = Math.abs(this.lat0); + if (Math.abs(t - Proj4js.common.HALF_PI) < Proj4js.common.EPSLN) { + this.mode = this.lat0 < 0. ? this.S_POLE : this.N_POLE; + } else if (Math.abs(t) < Proj4js.common.EPSLN) { + this.mode = this.EQUIT; + } else { + this.mode = this.OBLIQ; + } + if (this.es > 0) { + var sinphi; + + this.qp = Proj4js.common.qsfnz(this.e, 1.0); + this.mmf = .5 / (1. - this.es); + this.apa = this.authset(this.es); + switch (this.mode) { + case this.N_POLE: + case this.S_POLE: + this.dd = 1.; + break; + case this.EQUIT: + this.rq = Math.sqrt(.5 * this.qp); + this.dd = 1. / this.rq; + this.xmf = 1.; + this.ymf = .5 * this.qp; + break; + case this.OBLIQ: + this.rq = Math.sqrt(.5 * this.qp); + sinphi = Math.sin(this.lat0); + this.sinb1 = Proj4js.common.qsfnz(this.e, sinphi) / this.qp; + this.cosb1 = Math.sqrt(1. - this.sinb1 * this.sinb1); + this.dd = Math.cos(this.lat0) / (Math.sqrt(1. - this.es * sinphi * sinphi) * this.rq * this.cosb1); + this.ymf = (this.xmf = this.rq) / this.dd; + this.xmf *= this.dd; + break; + } + } else { + if (this.mode == this.OBLIQ) { + this.sinph0 = Math.sin(this.lat0); + this.cosph0 = Math.cos(this.lat0); + } + } + }, + +/* Lambert Azimuthal Equal Area forward equations--mapping lat,long to x,y + -----------------------------------------------------------------------*/ + forward: function(p) { + + /* Forward equations + -----------------*/ + var x,y; + var lam=p.x; + var phi=p.y; + lam = Proj4js.common.adjust_lon(lam - this.long0); + + if (this.sphere) { + var coslam, cosphi, sinphi; + + sinphi = Math.sin(phi); + cosphi = Math.cos(phi); + coslam = Math.cos(lam); + switch (this.mode) { + case this.OBLIQ: + case this.EQUIT: + y = (this.mode == this.EQUIT) ? 1. + cosphi * coslam : 1. + this.sinph0 * sinphi + this.cosph0 * cosphi * coslam; + if (y <= Proj4js.common.EPSLN) { + Proj4js.reportError("laea:fwd:y less than eps"); + return null; + } + y = Math.sqrt(2. / y); + x = y * cosphi * Math.sin(lam); + y *= (this.mode == this.EQUIT) ? sinphi : this.cosph0 * sinphi - this.sinph0 * cosphi * coslam; + break; + case this.N_POLE: + coslam = -coslam; + case this.S_POLE: + if (Math.abs(phi + this.phi0) < Proj4js.common.EPSLN) { + Proj4js.reportError("laea:fwd:phi < eps"); + return null; + } + y = Proj4js.common.FORTPI - phi * .5; + y = 2. * ((this.mode == this.S_POLE) ? Math.cos(y) : Math.sin(y)); + x = y * Math.sin(lam); + y *= coslam; + break; + } + } else { + var coslam, sinlam, sinphi, q, sinb=0.0, cosb=0.0, b=0.0; + + coslam = Math.cos(lam); + sinlam = Math.sin(lam); + sinphi = Math.sin(phi); + q = Proj4js.common.qsfnz(this.e, sinphi); + if (this.mode == this.OBLIQ || this.mode == this.EQUIT) { + sinb = q / this.qp; + cosb = Math.sqrt(1. - sinb * sinb); + } + switch (this.mode) { + case this.OBLIQ: + b = 1. + this.sinb1 * sinb + this.cosb1 * cosb * coslam; + break; + case this.EQUIT: + b = 1. + cosb * coslam; + break; + case this.N_POLE: + b = Proj4js.common.HALF_PI + phi; + q = this.qp - q; + break; + case this.S_POLE: + b = phi - Proj4js.common.HALF_PI; + q = this.qp + q; + break; + } + if (Math.abs(b) < Proj4js.common.EPSLN) { + Proj4js.reportError("laea:fwd:b < eps"); + return null; + } + switch (this.mode) { + case this.OBLIQ: + case this.EQUIT: + b = Math.sqrt(2. / b); + if (this.mode == this.OBLIQ) { + y = this.ymf * b * (this.cosb1 * sinb - this.sinb1 * cosb * coslam); + } else { + y = (b = Math.sqrt(2. / (1. + cosb * coslam))) * sinb * this.ymf; + } + x = this.xmf * b * cosb * sinlam; + break; + case this.N_POLE: + case this.S_POLE: + if (q >= 0.) { + x = (b = Math.sqrt(q)) * sinlam; + y = coslam * ((this.mode == this.S_POLE) ? b : -b); + } else { + x = y = 0.; + } + break; + } + } + + //v 1.0 + /* + var sin_lat=Math.sin(lat); + var cos_lat=Math.cos(lat); + + var sin_delta_lon=Math.sin(delta_lon); + var cos_delta_lon=Math.cos(delta_lon); + + var g =this.sin_lat_o * sin_lat +this.cos_lat_o * cos_lat * cos_delta_lon; + if (g == -1.0) { + Proj4js.reportError("laea:fwd:Point projects to a circle of radius "+ 2.0 * R); + return null; + } + var ksp = this.a * Math.sqrt(2.0 / (1.0 + g)); + var x = ksp * cos_lat * sin_delta_lon + this.x0; + var y = ksp * (this.cos_lat_o * sin_lat - this.sin_lat_o * cos_lat * cos_delta_lon) + this.y0; + */ + p.x = this.a*x + this.x0; + p.y = this.a*y + this.y0; + return p; + },//lamazFwd() + +/* Inverse equations + -----------------*/ + inverse: function(p) { + p.x -= this.x0; + p.y -= this.y0; + var x = p.x/this.a; + var y = p.y/this.a; + var lam, phi; + + if (this.sphere) { + var cosz=0.0, rh, sinz=0.0; + + rh = Math.sqrt(x*x + y*y); + phi = rh * .5; + if (phi > 1.) { + Proj4js.reportError("laea:Inv:DataError"); + return null; + } + phi = 2. * Math.asin(phi); + if (this.mode == this.OBLIQ || this.mode == this.EQUIT) { + sinz = Math.sin(phi); + cosz = Math.cos(phi); + } + switch (this.mode) { + case this.EQUIT: + phi = (Math.abs(rh) <= Proj4js.common.EPSLN) ? 0. : Math.asin(y * sinz / rh); + x *= sinz; + y = cosz * rh; + break; + case this.OBLIQ: + phi = (Math.abs(rh) <= Proj4js.common.EPSLN) ? this.phi0 : Math.asin(cosz * this.sinph0 + y * sinz * this.cosph0 / rh); + x *= sinz * this.cosph0; + y = (cosz - Math.sin(phi) * this.sinph0) * rh; + break; + case this.N_POLE: + y = -y; + phi = Proj4js.common.HALF_PI - phi; + break; + case this.S_POLE: + phi -= Proj4js.common.HALF_PI; + break; + } + lam = (y == 0. && (this.mode == this.EQUIT || this.mode == this.OBLIQ)) ? 0. : Math.atan2(x, y); + } else { + var cCe, sCe, q, rho, ab=0.0; + + switch (this.mode) { + case this.EQUIT: + case this.OBLIQ: + x /= this.dd; + y *= this.dd; + rho = Math.sqrt(x*x + y*y); + if (rho < Proj4js.common.EPSLN) { + p.x = 0.; + p.y = this.phi0; + return p; + } + sCe = 2. * Math.asin(.5 * rho / this.rq); + cCe = Math.cos(sCe); + x *= (sCe = Math.sin(sCe)); + if (this.mode == this.OBLIQ) { + ab = cCe * this.sinb1 + y * sCe * this.cosb1 / rho + q = this.qp * ab; + y = rho * this.cosb1 * cCe - y * this.sinb1 * sCe; + } else { + ab = y * sCe / rho; + q = this.qp * ab; + y = rho * cCe; + } + break; + case this.N_POLE: + y = -y; + case this.S_POLE: + q = (x * x + y * y); + if (!q ) { + p.x = 0.; + p.y = this.phi0; + return p; + } + /* + q = this.qp - q; + */ + ab = 1. - q / this.qp; + if (this.mode == this.S_POLE) { + ab = - ab; + } + break; + } + lam = Math.atan2(x, y); + phi = this.authlat(Math.asin(ab), this.apa); + } + + /* + var Rh = Math.Math.sqrt(p.x *p.x +p.y * p.y); + var temp = Rh / (2.0 * this.a); + + if (temp > 1) { + Proj4js.reportError("laea:Inv:DataError"); + return null; + } + + var z = 2.0 * Proj4js.common.asinz(temp); + var sin_z=Math.sin(z); + var cos_z=Math.cos(z); + + var lon =this.long0; + if (Math.abs(Rh) > Proj4js.common.EPSLN) { + var lat = Proj4js.common.asinz(this.sin_lat_o * cos_z +this. cos_lat_o * sin_z *p.y / Rh); + var temp =Math.abs(this.lat0) - Proj4js.common.HALF_PI; + if (Math.abs(temp) > Proj4js.common.EPSLN) { + temp = cos_z -this.sin_lat_o * Math.sin(lat); + if(temp!=0.0) lon=Proj4js.common.adjust_lon(this.long0+Math.atan2(p.x*sin_z*this.cos_lat_o,temp*Rh)); + } else if (this.lat0 < 0.0) { + lon = Proj4js.common.adjust_lon(this.long0 - Math.atan2(-p.x,p.y)); + } else { + lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2(p.x, -p.y)); + } + } else { + lat = this.lat0; + } + */ + //return(OK); + p.x = Proj4js.common.adjust_lon(this.long0+lam); + p.y = phi; + return p; + },//lamazInv() + +/* determine latitude from authalic latitude */ + P00: .33333333333333333333, + P01: .17222222222222222222, + P02: .10257936507936507936, + P10: .06388888888888888888, + P11: .06640211640211640211, + P20: .01641501294219154443, + + authset: function(es) { + var t; + var APA = new Array(); + APA[0] = es * this.P00; + t = es * es; + APA[0] += t * this.P01; + APA[1] = t * this.P10; + t *= es; + APA[0] += t * this.P02; + APA[1] += t * this.P11; + APA[2] = t * this.P20; + return APA; + }, + + authlat: function(beta, APA) { + var t = beta+beta; + return(beta + APA[0] * Math.sin(t) + APA[1] * Math.sin(t+t) + APA[2] * Math.sin(t+t+t)); + } + +}; + + + diff --git a/ajax/libs/proj4js/1.1.0/projCode/lcc.js b/ajax/libs/proj4js/1.1.0/projCode/lcc.js new file mode 100755 index 000000000..6e1523aad --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/lcc.js @@ -0,0 +1,148 @@ +/******************************************************************************* +NAME LAMBERT CONFORMAL CONIC + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Lambert Conformal Conic projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government +*******************************************************************************/ + + +//<2104> +proj=lcc +lat_1=10.16666666666667 +lat_0=10.16666666666667 +lon_0=-71.60561777777777 +k_0=1 +x0=-17044 +x0=-23139.97 +ellps=intl +units=m +no_defs no_defs + +// Initialize the Lambert Conformal conic projection +// ----------------------------------------------------------------- + +//Proj4js.Proj.lcc = Class.create(); +Proj4js.Proj.lcc = { + init : function() { + + // array of: r_maj,r_min,lat1,lat2,c_lon,c_lat,false_east,false_north + //double c_lat; /* center latitude */ + //double c_lon; /* center longitude */ + //double lat1; /* first standard parallel */ + //double lat2; /* second standard parallel */ + //double r_maj; /* major axis */ + //double r_min; /* minor axis */ + //double false_east; /* x offset in meters */ + //double false_north; /* y offset in meters */ + + if (!this.lat2){this.lat2=this.lat0;}//if lat2 is not defined + if (!this.k0) this.k0 = 1.0; + + // Standard Parallels cannot be equal and on opposite sides of the equator + if (Math.abs(this.lat1+this.lat2) < Proj4js.common.EPSLN) { + Proj4js.reportError("lcc:init: Equal Latitudes"); + return; + } + + var temp = this.b / this.a; + this.e = Math.sqrt(1.0 - temp*temp); + + var sin1 = Math.sin(this.lat1); + var cos1 = Math.cos(this.lat1); + var ms1 = Proj4js.common.msfnz(this.e, sin1, cos1); + var ts1 = Proj4js.common.tsfnz(this.e, this.lat1, sin1); + + var sin2 = Math.sin(this.lat2); + var cos2 = Math.cos(this.lat2); + var ms2 = Proj4js.common.msfnz(this.e, sin2, cos2); + var ts2 = Proj4js.common.tsfnz(this.e, this.lat2, sin2); + + var ts0 = Proj4js.common.tsfnz(this.e, this.lat0, Math.sin(this.lat0)); + + if (Math.abs(this.lat1 - this.lat2) > Proj4js.common.EPSLN) { + this.ns = Math.log(ms1/ms2)/Math.log(ts1/ts2); + } else { + this.ns = sin1; + } + this.f0 = ms1 / (this.ns * Math.pow(ts1, this.ns)); + this.rh = this.a * this.f0 * Math.pow(ts0, this.ns); + if (!this.title) this.title = "Lambert Conformal Conic"; + }, + + + // Lambert Conformal conic forward equations--mapping lat,long to x,y + // ----------------------------------------------------------------- + forward : function(p) { + + var lon = p.x; + var lat = p.y; + + // convert to radians + if ( lat <= 90.0 && lat >= -90.0 && lon <= 180.0 && lon >= -180.0) { + //lon = lon * Proj4js.common.D2R; + //lat = lat * Proj4js.common.D2R; + } else { + Proj4js.reportError("lcc:forward: llInputOutOfRange: "+ lon +" : " + lat); + return null; + } + + var con = Math.abs( Math.abs(lat) - Proj4js.common.HALF_PI); + var ts, rh1; + if (con > Proj4js.common.EPSLN) { + ts = Proj4js.common.tsfnz(this.e, lat, Math.sin(lat) ); + rh1 = this.a * this.f0 * Math.pow(ts, this.ns); + } else { + con = lat * this.ns; + if (con <= 0) { + Proj4js.reportError("lcc:forward: No Projection"); + return null; + } + rh1 = 0; + } + var theta = this.ns * Proj4js.common.adjust_lon(lon - this.long0); + p.x = this.k0 * (rh1 * Math.sin(theta)) + this.x0; + p.y = this.k0 * (this.rh - rh1 * Math.cos(theta)) + this.y0; + + return p; + }, + + // Lambert Conformal Conic inverse equations--mapping x,y to lat/long + // ----------------------------------------------------------------- + inverse : function(p) { + + var rh1, con, ts; + var lat, lon; + var x = (p.x - this.x0)/this.k0; + var y = (this.rh - (p.y - this.y0)/this.k0); + if (this.ns > 0) { + rh1 = Math.sqrt (x * x + y * y); + con = 1.0; + } else { + rh1 = -Math.sqrt (x * x + y * y); + con = -1.0; + } + var theta = 0.0; + if (rh1 != 0) { + theta = Math.atan2((con * x),(con * y)); + } + if ((rh1 != 0) || (this.ns > 0.0)) { + con = 1.0/this.ns; + ts = Math.pow((rh1/(this.a * this.f0)), con); + lat = Proj4js.common.phi2z(this.e, ts); + if (lat == -9999) return null; + } else { + lat = -Proj4js.common.HALF_PI; + } + lon = Proj4js.common.adjust_lon(theta/this.ns + this.long0); + + p.x = lon; + p.y = lat; + return p; + } +}; + + + + diff --git a/ajax/libs/proj4js/1.1.0/projCode/merc.js b/ajax/libs/proj4js/1.1.0/projCode/merc.js new file mode 100755 index 000000000..ebf55a77d --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/merc.js @@ -0,0 +1,115 @@ +/******************************************************************************* +NAME MERCATOR + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Mercator projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +D. Steinwand, EROS Nov, 1991 +T. Mittan Mar, 1993 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + +//static double r_major = a; /* major axis */ +//static double r_minor = b; /* minor axis */ +//static double lon_center = long0; /* Center longitude (projection center) */ +//static double lat_origin = lat0; /* center latitude */ +//static double e,es; /* eccentricity constants */ +//static double m1; /* small value m */ +//static double false_northing = y0; /* y offset in meters */ +//static double false_easting = x0; /* x offset in meters */ +//scale_fact = k0 + +Proj4js.Proj.merc = { + init : function() { + //?this.temp = this.r_minor / this.r_major; + //this.temp = this.b / this.a; + //this.es = 1.0 - Math.sqrt(this.temp); + //this.e = Math.sqrt( this.es ); + //?this.m1 = Math.cos(this.lat_origin) / (Math.sqrt( 1.0 - this.es * Math.sin(this.lat_origin) * Math.sin(this.lat_origin))); + //this.m1 = Math.cos(0.0) / (Math.sqrt( 1.0 - this.es * Math.sin(0.0) * Math.sin(0.0))); + if (this.lat_ts) { + if (this.sphere) { + this.k0 = Math.cos(this.lat_ts); + } else { + this.k0 = Proj4js.common.msfnz(this.es, Math.sin(this.lat_ts), Math.cos(this.lat_ts)); + } + } + }, + +/* Mercator forward equations--mapping lat,long to x,y + --------------------------------------------------*/ + + forward : function(p) { + //alert("ll2m coords : "+coords); + var lon = p.x; + var lat = p.y; + // convert to radians + if ( lat*Proj4js.common.R2D > 90.0 && + lat*Proj4js.common.R2D < -90.0 && + lon*Proj4js.common.R2D > 180.0 && + lon*Proj4js.common.R2D < -180.0) { + Proj4js.reportError("merc:forward: llInputOutOfRange: "+ lon +" : " + lat); + return null; + } + + var x,y; + if(Math.abs( Math.abs(lat) - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN) { + Proj4js.reportError("merc:forward: ll2mAtPoles"); + return null; + } else { + if (this.sphere) { + x = this.x0 + this.a * this.k0 * Proj4js.common.adjust_lon(lon - this.long0); + y = this.y0 + this.a * this.k0 * Math.log(Math.tan(Proj4js.common.FORTPI + 0.5*lat)); + } else { + var sinphi = Math.sin(lat); + var ts = Proj4js.common.tsfnz(this.e,lat,sinphi); + x = this.x0 + this.a * this.k0 * Proj4js.common.adjust_lon(lon - this.long0); + y = this.y0 - this.a * this.k0 * Math.log(ts); + } + p.x = x; + p.y = y; + return p; + } + }, + + + /* Mercator inverse equations--mapping x,y to lat/long + --------------------------------------------------*/ + inverse : function(p) { + + var x = p.x - this.x0; + var y = p.y - this.y0; + var lon,lat; + + if (this.sphere) { + lat = Proj4js.common.HALF_PI - 2.0 * Math.atan(Math.exp(-y / this.a * this.k0)); + } else { + var ts = Math.exp(-y / (this.a * this.k0)); + lat = Proj4js.common.phi2z(this.e,ts); + if(lat == -9999) { + Proj4js.reportError("merc:inverse: lat = -9999"); + return null; + } + } + lon = Proj4js.common.adjust_lon(this.long0+ x / (this.a * this.k0)); + + p.x = lon; + p.y = lat; + return p; + } +}; + + diff --git a/ajax/libs/proj4js/1.1.0/projCode/mill.js b/ajax/libs/proj4js/1.1.0/projCode/mill.js new file mode 100755 index 000000000..23d94ac1a --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/mill.js @@ -0,0 +1,68 @@ +/******************************************************************************* +NAME MILLER CYLINDRICAL + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Miller Cylindrical projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +T. Mittan March, 1993 + +This function was adapted from the Lambert Azimuthal Equal Area projection +code (FORTRAN) in the General Cartographic Transformation Package software +which is available from the U.S. Geological Survey National Mapping Division. + +ALGORITHM REFERENCES + +1. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder, + The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355. + +2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +3. "Software Documentation for GCTP General Cartographic Transformation + Package", U.S. Geological Survey National Mapping Division, May 1982. +*******************************************************************************/ + +Proj4js.Proj.mill = { + +/* Initialize the Miller Cylindrical projection + -------------------------------------------*/ + init: function() { + //no-op + }, + + + /* Miller Cylindrical forward equations--mapping lat,long to x,y + ------------------------------------------------------------*/ + forward: function(p) { + var lon=p.x; + var lat=p.y; + /* Forward equations + -----------------*/ + var dlon = Proj4js.common.adjust_lon(lon -this.long0); + var x = this.x0 + this.a * dlon; + var y = this.y0 + this.a * Math.log(Math.tan((Proj4js.common.PI / 4.0) + (lat / 2.5))) * 1.25; + + p.x=x; + p.y=y; + return p; + },//millFwd() + + /* Miller Cylindrical inverse equations--mapping x,y to lat/long + ------------------------------------------------------------*/ + inverse: function(p) { + p.x -= this.x0; + p.y -= this.y0; + + var lon = Proj4js.common.adjust_lon(this.long0 + p.x /this.a); + var lat = 2.5 * (Math.atan(Math.exp(0.8*p.y/this.a)) - Proj4js.common.PI / 4.0); + + p.x=lon; + p.y=lat; + return p; + }//millInv() +}; diff --git a/ajax/libs/proj4js/1.1.0/projCode/moll.js b/ajax/libs/proj4js/1.1.0/projCode/moll.js new file mode 100755 index 000000000..78b4476f6 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/moll.js @@ -0,0 +1,100 @@ +/******************************************************************************* +NAME MOLLWEIDE + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the MOllweide projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +D. Steinwand, EROS May, 1991; Updated Sept, 1992; Updated Feb, 1993 +S. Nelson, EDC Jun, 2993; Made corrections in precision and + number of iterations. + +ALGORITHM REFERENCES + +1. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. + +2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. +*******************************************************************************/ + +Proj4js.Proj.moll = { + + /* Initialize the Mollweide projection + ------------------------------------*/ + init: function(){ + //no-op + }, + + /* Mollweide forward equations--mapping lat,long to x,y + ----------------------------------------------------*/ + forward: function(p) { + + /* Forward equations + -----------------*/ + var lon=p.x; + var lat=p.y; + + var delta_lon = Proj4js.common.adjust_lon(lon - this.long0); + var theta = lat; + var con = Proj4js.common.PI * Math.sin(lat); + + /* Iterate using the Newton-Raphson method to find theta + -----------------------------------------------------*/ + for (var i=0;true;i++) { + var delta_theta = -(theta + Math.sin(theta) - con)/ (1.0 + Math.cos(theta)); + theta += delta_theta; + if (Math.abs(delta_theta) < Proj4js.common.EPSLN) break; + if (i >= 50) { + Proj4js.reportError("moll:Fwd:IterationError"); + //return(241); + } + } + theta /= 2.0; + + /* If the latitude is 90 deg, force the x coordinate to be "0 + false easting" + this is done here because of precision problems with "cos(theta)" + --------------------------------------------------------------------------*/ + if (Proj4js.common.PI/2 - Math.abs(lat) < Proj4js.common.EPSLN) delta_lon =0; + var x = 0.900316316158 * this.a * delta_lon * Math.cos(theta) + this.x0; + var y = 1.4142135623731 * this.a * Math.sin(theta) + this.y0; + + p.x=x; + p.y=y; + return p; + }, + + inverse: function(p){ + var theta; + var arg; + + /* Inverse equations + -----------------*/ + p.x-= this.x0; + //~ p.y -= this.y0; + var arg = p.y / (1.4142135623731 * this.a); + + /* Because of division by zero problems, 'arg' can not be 1.0. Therefore + a number very close to one is used instead. + -------------------------------------------------------------------*/ + if(Math.abs(arg) > 0.999999999999) arg=0.999999999999; + var theta =Math.asin(arg); + var lon = Proj4js.common.adjust_lon(this.long0 + (p.x / (0.900316316158 * this.a * Math.cos(theta)))); + if(lon < (-Proj4js.common.PI)) lon= -Proj4js.common.PI; + if(lon > Proj4js.common.PI) lon= Proj4js.common.PI; + arg = (2.0 * theta + Math.sin(2.0 * theta)) / Proj4js.common.PI; + if(Math.abs(arg) > 1.0)arg=1.0; + var lat = Math.asin(arg); + //return(OK); + + p.x=lon; + p.y=lat; + return p; + } +}; + diff --git a/ajax/libs/proj4js/1.1.0/projCode/nzmg.js b/ajax/libs/proj4js/1.1.0/projCode/nzmg.js new file mode 100755 index 000000000..36560b8cf --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/nzmg.js @@ -0,0 +1,284 @@ +/******************************************************************************* +NAME NEW ZEALAND MAP GRID + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the New Zealand Map Grid projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + + +ALGORITHM REFERENCES + +1. Department of Land and Survey Technical Circular 1973/32 + http://www.linz.govt.nz/docs/miscellaneous/nz-map-definition.pdf + +2. OSG Technical Report 4.1 + http://www.linz.govt.nz/docs/miscellaneous/nzmg.pdf + + +IMPLEMENTATION NOTES + +The two references use different symbols for the calculated values. This +implementation uses the variable names similar to the symbols in reference [1]. + +The alogrithm uses different units for delta latitude and delta longitude. +The delta latitude is assumed to be in units of seconds of arc x 10^-5. +The delta longitude is the usual radians. Look out for these conversions. + +The algorithm is described using complex arithmetic. There were three +options: + * find and use a Javascript library for complex arithmetic + * write my own complex library + * expand the complex arithmetic by hand to simple arithmetic + +This implementation has expanded the complex multiplication operations +into parallel simple arithmetic operations for the real and imaginary parts. +The imaginary part is way over to the right of the display; this probably +violates every coding standard in the world, but, to me, it makes it much +more obvious what is going on. + +The following complex operations are used: + - addition + - multiplication + - division + - complex number raised to integer power + - summation + +A summary of complex arithmetic operations: + (from http://en.wikipedia.org/wiki/Complex_arithmetic) + addition: (a + bi) + (c + di) = (a + c) + (b + d)i + subtraction: (a + bi) - (c + di) = (a - c) + (b - d)i + multiplication: (a + bi) x (c + di) = (ac - bd) + (bc + ad)i + division: (a + bi) / (c + di) = [(ac + bd)/(cc + dd)] + [(bc - ad)/(cc + dd)]i + +The algorithm needs to calculate summations of simple and complex numbers. This is +implemented using a for-loop, pre-loading the summed value to zero. + +The algorithm needs to calculate theta^2, theta^3, etc while doing a summation. +There are three possible implementations: + - use Math.pow in the summation loop - except for complex numbers + - precalculate the values before running the loop + - calculate theta^n = theta^(n-1) * theta during the loop +This implementation uses the third option for both real and complex arithmetic. + +For example + psi_n = 1; + sum = 0; + for (n = 1; n <=6; n++) { + psi_n1 = psi_n * psi; // calculate psi^(n+1) + psi_n = psi_n1; + sum = sum + A[n] * psi_n; + } + + +TEST VECTORS + +NZMG E, N: 2487100.638 6751049.719 metres +NZGD49 long, lat: 172.739194 -34.444066 degrees + +NZMG E, N: 2486533.395 6077263.661 metres +NZGD49 long, lat: 172.723106 -40.512409 degrees + +NZMG E, N: 2216746.425 5388508.765 metres +NZGD49 long, lat: 169.172062 -46.651295 degrees + +Note that these test vectors convert from NZMG metres to lat/long referenced +to NZGD49, not the more usual WGS84. The difference is about 70m N/S and about +10m E/W. + +These test vectors are provided in reference [1]. Many more test +vectors are available in + http://www.linz.govt.nz/docs/topography/topographicdata/placenamesdatabase/nznamesmar08.zip +which is a catalog of names on the 260-series maps. + + +EPSG CODES + +NZMG EPSG:27200 +NZGD49 EPSG:4272 + +http://spatialreference.org/ defines these as + Proj4js.defs["EPSG:4272"] = "+proj=longlat +ellps=intl +datum=nzgd49 +no_defs "; + Proj4js.defs["EPSG:27200"] = "+proj=nzmg +lat_0=-41 +lon_0=173 +x_0=2510000 +y_0=6023150 +ellps=intl +datum=nzgd49 +units=m +no_defs "; + + +LICENSE + Copyright: Stephen Irons 2008 + Released under terms of the LGPL as per: http://www.gnu.org/copyleft/lesser.html + +*******************************************************************************/ + + +/** + Initialize New Zealand Map Grip projection +*/ + +Proj4js.Proj.nzmg = { + + /** + * iterations: Number of iterations to refine inverse transform. + * 0 -> km accuracy + * 1 -> m accuracy -- suitable for most mapping applications + * 2 -> mm accuracy + */ + iterations: 1, + + init : function() { + this.A = new Array(); + this.A[1] = +0.6399175073; + this.A[2] = -0.1358797613; + this.A[3] = +0.063294409; + this.A[4] = -0.02526853; + this.A[5] = +0.0117879; + this.A[6] = -0.0055161; + this.A[7] = +0.0026906; + this.A[8] = -0.001333; + this.A[9] = +0.00067; + this.A[10] = -0.00034; + + this.B_re = new Array(); this.B_im = new Array(); + this.B_re[1] = +0.7557853228; this.B_im[1] = 0.0; + this.B_re[2] = +0.249204646; this.B_im[2] = +0.003371507; + this.B_re[3] = -0.001541739; this.B_im[3] = +0.041058560; + this.B_re[4] = -0.10162907; this.B_im[4] = +0.01727609; + this.B_re[5] = -0.26623489; this.B_im[5] = -0.36249218; + this.B_re[6] = -0.6870983; this.B_im[6] = -1.1651967; + + this.C_re = new Array(); this.C_im = new Array(); + this.C_re[1] = +1.3231270439; this.C_im[1] = 0.0; + this.C_re[2] = -0.577245789; this.C_im[2] = -0.007809598; + this.C_re[3] = +0.508307513; this.C_im[3] = -0.112208952; + this.C_re[4] = -0.15094762; this.C_im[4] = +0.18200602; + this.C_re[5] = +1.01418179; this.C_im[5] = +1.64497696; + this.C_re[6] = +1.9660549; this.C_im[6] = +2.5127645; + + this.D = new Array(); + this.D[1] = +1.5627014243; + this.D[2] = +0.5185406398; + this.D[3] = -0.03333098; + this.D[4] = -0.1052906; + this.D[5] = -0.0368594; + this.D[6] = +0.007317; + this.D[7] = +0.01220; + this.D[8] = +0.00394; + this.D[9] = -0.0013; + }, + + /** + New Zealand Map Grid Forward - long/lat to x/y + long/lat in radians + */ + forward : function(p) { + var lon = p.x; + var lat = p.y; + + var delta_lat = lat - this.lat0; + var delta_lon = lon - this.long0; + + // 1. Calculate d_phi and d_psi ... // and d_lambda + // For this algorithm, delta_latitude is in seconds of arc x 10-5, so we need to scale to those units. Longitude is radians. + var d_phi = delta_lat / Proj4js.common.SEC_TO_RAD * 1E-5; var d_lambda = delta_lon; + var d_phi_n = 1; // d_phi^0 + + var d_psi = 0; + for (var n = 1; n <= 10; n++) { + d_phi_n = d_phi_n * d_phi; + d_psi = d_psi + this.A[n] * d_phi_n; + } + + // 2. Calculate theta + var th_re = d_psi; var th_im = d_lambda; + + // 3. Calculate z + var th_n_re = 1; var th_n_im = 0; // theta^0 + var th_n_re1; var th_n_im1; + + var z_re = 0; var z_im = 0; + for (var n = 1; n <= 6; n++) { + th_n_re1 = th_n_re*th_re - th_n_im*th_im; th_n_im1 = th_n_im*th_re + th_n_re*th_im; + th_n_re = th_n_re1; th_n_im = th_n_im1; + z_re = z_re + this.B_re[n]*th_n_re - this.B_im[n]*th_n_im; z_im = z_im + this.B_im[n]*th_n_re + this.B_re[n]*th_n_im; + } + + // 4. Calculate easting and northing + p.x = (z_im * this.a) + this.x0; + p.y = (z_re * this.a) + this.y0; + + return p; + }, + + + /** + New Zealand Map Grid Inverse - x/y to long/lat + */ + inverse : function(p) { + + var x = p.x; + var y = p.y; + + var delta_x = x - this.x0; + var delta_y = y - this.y0; + + // 1. Calculate z + var z_re = delta_y / this.a; var z_im = delta_x / this.a; + + // 2a. Calculate theta - first approximation gives km accuracy + var z_n_re = 1; var z_n_im = 0; // z^0 + var z_n_re1; var z_n_im1; + + var th_re = 0; var th_im = 0; + for (var n = 1; n <= 6; n++) { + z_n_re1 = z_n_re*z_re - z_n_im*z_im; z_n_im1 = z_n_im*z_re + z_n_re*z_im; + z_n_re = z_n_re1; z_n_im = z_n_im1; + th_re = th_re + this.C_re[n]*z_n_re - this.C_im[n]*z_n_im; th_im = th_im + this.C_im[n]*z_n_re + this.C_re[n]*z_n_im; + } + + // 2b. Iterate to refine the accuracy of the calculation + // 0 iterations gives km accuracy + // 1 iteration gives m accuracy -- good enough for most mapping applications + // 2 iterations bives mm accuracy + for (var i = 0; i < this.iterations; i++) { + var th_n_re = th_re; var th_n_im = th_im; + var th_n_re1; var th_n_im1; + + var num_re = z_re; var num_im = z_im; + for (var n = 2; n <= 6; n++) { + th_n_re1 = th_n_re*th_re - th_n_im*th_im; th_n_im1 = th_n_im*th_re + th_n_re*th_im; + th_n_re = th_n_re1; th_n_im = th_n_im1; + num_re = num_re + (n-1)*(this.B_re[n]*th_n_re - this.B_im[n]*th_n_im); num_im = num_im + (n-1)*(this.B_im[n]*th_n_re + this.B_re[n]*th_n_im); + } + + th_n_re = 1; th_n_im = 0; + var den_re = this.B_re[1]; var den_im = this.B_im[1]; + for (var n = 2; n <= 6; n++) { + th_n_re1 = th_n_re*th_re - th_n_im*th_im; th_n_im1 = th_n_im*th_re + th_n_re*th_im; + th_n_re = th_n_re1; th_n_im = th_n_im1; + den_re = den_re + n * (this.B_re[n]*th_n_re - this.B_im[n]*th_n_im); den_im = den_im + n * (this.B_im[n]*th_n_re + this.B_re[n]*th_n_im); + } + + // Complex division + var den2 = den_re*den_re + den_im*den_im; + th_re = (num_re*den_re + num_im*den_im) / den2; th_im = (num_im*den_re - num_re*den_im) / den2; + } + + // 3. Calculate d_phi ... // and d_lambda + var d_psi = th_re; var d_lambda = th_im; + var d_psi_n = 1; // d_psi^0 + + var d_phi = 0; + for (var n = 1; n <= 9; n++) { + d_psi_n = d_psi_n * d_psi; + d_phi = d_phi + this.D[n] * d_psi_n; + } + + // 4. Calculate latitude and longitude + // d_phi is calcuated in second of arc * 10^-5, so we need to scale back to radians. d_lambda is in radians. + var lat = this.lat0 + (d_phi * Proj4js.common.SEC_TO_RAD * 1E5); + var lon = this.long0 + d_lambda; + + p.x = lon; + p.y = lat; + + return p; + } +}; diff --git a/ajax/libs/proj4js/1.1.0/projCode/omerc.js b/ajax/libs/proj4js/1.1.0/projCode/omerc.js new file mode 100755 index 000000000..a56bbf5fd --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/omerc.js @@ -0,0 +1,256 @@ +/******************************************************************************* +NAME OBLIQUE MERCATOR (HOTINE) + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Oblique Mercator projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +T. Mittan Mar, 1993 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + +Proj4js.Proj.omerc = { + + /* Initialize the Oblique Mercator projection + ------------------------------------------*/ + init: function() { + if (!this.mode) this.mode=0; + if (!this.lon1) {this.lon1=0;this.mode=1;} + if (!this.lon2) this.lon2=0; + if (!this.lat2) this.lat2=0; + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + var temp = this.b/ this.a; + var es = 1.0 - Math.pow(temp,2); + var e = Math.sqrt(es); + + this.sin_p20=Math.sin(this.lat0); + this.cos_p20=Math.cos(this.lat0); + + this.con = 1.0 - this.es * this.sin_p20 * this.sin_p20; + this.com = Math.sqrt(1.0 - es); + this.bl = Math.sqrt(1.0 + this.es * Math.pow(this.cos_p20,4.0)/(1.0 - es)); + this.al = this.a * this.bl * this.k0 * this.com / this.con; + if (Math.abs(this.lat0) < Proj4js.common.EPSLN) { + this.ts = 1.0; + this.d = 1.0; + this.el = 1.0; + } else { + this.ts = Proj4js.common.tsfnz(this.e,this.lat0,this.sin_p20); + this.con = Math.sqrt(this.con); + this.d = this.bl * this.com / (this.cos_p20 * this.con); + if ((this.d * this.d - 1.0) > 0.0) { + if (this.lat0 >= 0.0) { + this.f = this.d + Math.sqrt(this.d * this.d - 1.0); + } else { + this.f = this.d - Math.sqrt(this.d * this.d - 1.0); + } + } else { + this.f = this.d; + } + this.el = this.f * Math.pow(this.ts,this.bl); + } + + //this.longc=52.60353916666667; + + if (this.mode != 0) { + this.g = .5 * (this.f - 1.0/this.f); + this.gama = Proj4js.common.asinz(Math.sin(this.alpha) / this.d); + this.longc= this.longc - Proj4js.common.asinz(this.g * Math.tan(this.gama))/this.bl; + + /* Report parameters common to format B + -------------------------------------*/ + //genrpt(azimuth * R2D,"Azimuth of Central Line: "); + //cenlon(lon_origin); + // cenlat(lat_origin); + + this.con = Math.abs(this.lat0); + if ((this.con > 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); + + if (this.lat0>= 0) { + this.u = (this.al / this.bl) * Math.atan(Math.sqrt(this.d*this.d - 1.0)/this.cosaz); + } else { + this.u = -(this.al / this.bl) *Math.atan(Math.sqrt(this.d*this.d - 1.0)/this.cosaz); + } + } else { + Proj4js.reportError("omerc:Init:DataError"); + } + } else { + this.sinphi =Math. sin(this.at1); + this.ts1 = Proj4js.common.tsfnz(this.e,this.lat1,this.sinphi); + 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 = .5 * (this.f - 1.0/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; + if (this.dlon < -Proj4js.common.PI) this.lon2 = this.lon2 - 2.0 * Proj4js.common.PI; + if (this.dlon > Proj4js.common.PI) this.lon2 = this.lon2 + 2.0 * Proj4js.common.PI; + this.dlon = this.lon1 - this.lon2; + this.longc = .5 * (this.lon1 + this.lon2) -Math.atan(this.j * Math.tan(.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)); + + /* Report parameters common to format A + -------------------------------------*/ + + if (Math.abs(this.lat1 - this.lat2) <= Proj4js.common.EPSLN) { + Proj4js.reportError("omercInitDataError"); + //return(202); + } else { + this.con = Math.abs(this.lat1); + } + if ((this.con <= Proj4js.common.EPSLN) || (Math.abs(this.con - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN)) { + Proj4js.reportError("omercInitDataError"); + //return(202); + } else { + if (Math.abs(Math.abs(this.lat0) - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN) { + Proj4js.reportError("omercInitDataError"); + //return(202); + } + } + + this.singam=Math.sin(this.gam); + this.cosgam=Math.cos(this.gam); + + this.sinaz=Math.sin(this.alpha); + this.cosaz=Math.cos(this.alpha); + + + if (this.lat0 >= 0) { + this.u = (this.al/this.bl) * Math.atan(Math.sqrt(this.d * this.d - 1.0)/this.cosaz); + } else { + this.u = -(this.al/this.bl) * Math.atan(Math.sqrt(this.d * this.d - 1.0)/this.cosaz); + } + } + }, + + + /* Oblique Mercator forward equations--mapping lat,long to x,y + ----------------------------------------------------------*/ + forward: function(p) { + var theta; /* angle */ + var sin_phi, cos_phi;/* sin and cos value */ + var b; /* temporary values */ + var c, t, tq; /* temporary values */ + var con, n, ml; /* cone constant, small m */ + var q,us,vl; + var ul,vs; + var s; + var dlon; + var ts1; + + var lon=p.x; + var lat=p.y; + /* Forward equations + -----------------*/ + sin_phi = Math.sin(lat); + dlon = Proj4js.common.adjust_lon(lon - this.longc); + vl = Math.sin(this.bl * dlon); + if (Math.abs(Math.abs(lat) - Proj4js.common.HALF_PI) > Proj4js.common.EPSLN) { + ts1 = Proj4js.common.tsfnz(this.e,lat,sin_phi); + q = this.el / (Math.pow(ts1,this.bl)); + s = .5 * (q - 1.0 / q); + t = .5 * (q + 1.0/ q); + ul = (s * this.singam - vl * this.cosgam) / t; + con = Math.cos(this.bl * dlon); + if (Math.abs(con) < .0000001) { + us = this.al * this.bl * dlon; + } else { + us = this.al * Math.atan((s * this.cosgam + vl * this.singam) / con)/this.bl; + if (con < 0) us = us + Proj4js.common.PI * this.al / this.bl; + } + } else { + if (lat >= 0) { + ul = this.singam; + } else { + ul = -this.singam; + } + us = this.al * lat / this.bl; + } + if (Math.abs(Math.abs(ul) - 1.0) <= Proj4js.common.EPSLN) { + //alert("Point projects into infinity","omer-for"); + Proj4js.reportError("omercFwdInfinity"); + //return(205); + } + vs = .5 * this.al * Math.log((1.0 - ul)/(1.0 + ul)) / this.bl; + us = us - this.u; + var x = this.x0 + vs * this.cosaz + us * this.sinaz; + var y = this.y0 + us * this.cosaz - vs * this.sinaz; + + p.x=x; + p.y=y; + return p; + }, + + inverse: function(p) { + var delta_lon; /* Delta longitude (Given longitude - center */ + var theta; /* angle */ + var delta_theta; /* adjusted longitude */ + var sin_phi, cos_phi;/* sin and cos value */ + var b; /* temporary values */ + var c, t, tq; /* temporary values */ + var con, n, ml; /* cone constant, small m */ + var vs,us,q,s,ts1; + var vl,ul,bs; + var lon, lat; + var flag; + + /* Inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + flag = 0; + vs = p.x * this.cosaz - p.y * this.sinaz; + us = p.y * this.cosaz + p.x * this.sinaz; + us = us + this.u; + q = Math.exp(-this.bl * vs / this.al); + s = .5 * (q - 1.0/q); + t = .5 * (q + 1.0/q); + vl = Math.sin(this.bl * us / this.al); + ul = (vl * this.cosgam + s * this.singam)/t; + if (Math.abs(Math.abs(ul) - 1.0) <= Proj4js.common.EPSLN) + { + lon = this.longc; + if (ul >= 0.0) { + lat = Proj4js.common.HALF_PI; + } else { + lat = -Proj4js.common.HALF_PI; + } + } else { + con = 1.0 / this.bl; + ts1 =Math.pow((this.el / Math.sqrt((1.0 + ul) / (1.0 - ul))),con); + lat = Proj4js.common.phi2z(this.e,ts1); + //if (flag != 0) + //return(flag); + //~ con = Math.cos(this.bl * us /al); + theta = this.longc - Math.atan2((s * this.cosgam - vl * this.singam) , con)/this.bl; + lon = Proj4js.common.adjust_lon(theta); + } + p.x=lon; + p.y=lat; + return p; + } +}; diff --git a/ajax/libs/proj4js/1.1.0/projCode/ortho.js b/ajax/libs/proj4js/1.1.0/projCode/ortho.js new file mode 100755 index 000000000..800dfdc52 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/ortho.js @@ -0,0 +1,110 @@ +/******************************************************************************* +NAME ORTHOGRAPHIC + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Orthographic projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +T. Mittan Mar, 1993 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + +Proj4js.Proj.ortho = { + + /* Initialize the Orthographic projection + -------------------------------------*/ + init: function(def) { + //double temp; /* temporary variable */ + + /* Place parameters in static storage for common use + -------------------------------------------------*/; + this.sin_p14=Math.sin(this.lat0); + this.cos_p14=Math.cos(this.lat0); + }, + + + /* Orthographic forward equations--mapping lat,long to x,y + ---------------------------------------------------*/ + forward: function(p) { + var sinphi, cosphi; /* sin and cos value */ + var dlon; /* delta longitude value */ + var coslon; /* cos of longitude */ + var ksp; /* scale factor */ + var g; + var lon=p.x; + var lat=p.y; + /* Forward equations + -----------------*/ + dlon = Proj4js.common.adjust_lon(lon - this.long0); + + sinphi=Math.sin(lat); + cosphi=Math.cos(lat); + + coslon = Math.cos(dlon); + g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon; + ksp = 1.0; + if ((g > 0) || (Math.abs(g) <= Proj4js.common.EPSLN)) { + var x = this.a * ksp * cosphi * Math.sin(dlon); + var y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon); + } else { + Proj4js.reportError("orthoFwdPointError"); + } + p.x=x; + p.y=y; + return p; + }, + + + inverse: function(p) { + var rh; /* height above ellipsoid */ + var z; /* angle */ + var sinz,cosz; /* sin of z and cos of z */ + var temp; + var con; + var lon , lat; + /* Inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + rh = Math.sqrt(p.x * p.x + p.y * p.y); + if (rh > this.a + .0000001) { + Proj4js.reportError("orthoInvDataError"); + } + z = Proj4js.common.asinz(rh / this.a); + + sinz=Math.sin(z); + cosz=Math.cos(z); + + lon = this.long0; + if (Math.abs(rh) <= Proj4js.common.EPSLN) { + lat = this.lat0; + } + lat = Proj4js.common.asinz(cosz * this.sin_p14 + (p.y * sinz * this.cos_p14)/rh); + con = Math.abs(this.lat0) - Proj4js.common.HALF_PI; + if (Math.abs(con) <= Proj4js.common.EPSLN) { + if (this.lat0 >= 0) { + lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2(p.x, -p.y)); + } else { + lon = Proj4js.common.adjust_lon(this.long0 -Math.atan2(-p.x, p.y)); + } + } + con = cosz - this.sin_p14 * Math.sin(lat); + p.x=lon; + p.y=lat; + return p; + } +}; + + diff --git a/ajax/libs/proj4js/1.1.0/projCode/poly.js b/ajax/libs/proj4js/1.1.0/projCode/poly.js new file mode 100755 index 000000000..0176efdba --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/poly.js @@ -0,0 +1,157 @@ +/* Function to compute, phi4, the latitude for the inverse of the + Polyconic projection. +------------------------------------------------------------*/ +function phi4z (eccent,e0,e1,e2,e3,a,b,c,phi) { + var sinphi, sin2ph, tanphi, ml, mlp, con1, con2, con3, dphi, i; + + phi = a; + for (i = 1; i <= 15; i++) { + sinphi = Math.sin(phi); + tanphi = Math.tan(phi); + c = tanphi * Math.sqrt (1.0 - eccent * sinphi * sinphi); + sin2ph = Math.sin (2.0 * phi); + /* + ml = e0 * *phi - e1 * sin2ph + e2 * sin (4.0 * *phi); + mlp = e0 - 2.0 * e1 * cos (2.0 * *phi) + 4.0 * e2 * cos (4.0 * *phi); + */ + ml = e0 * phi - e1 * sin2ph + e2 * Math.sin (4.0 * phi) - e3 * Math.sin (6.0 * phi); + mlp = e0 - 2.0 * e1 * Math.cos (2.0 * phi) + 4.0 * e2 * Math.cos (4.0 * phi) - 6.0 * e3 * Math.cos (6.0 * phi); + con1 = 2.0 * ml + c * (ml * ml + b) - 2.0 * a * (c * ml + 1.0); + con2 = eccent * sin2ph * (ml * ml + b - 2.0 * a * ml) / (2.0 *c); + con3 = 2.0 * (a - ml) * (c * mlp - 2.0 / sin2ph) - 2.0 * mlp; + dphi = con1 / (con2 + con3); + phi += dphi; + if (Math.abs(dphi) <= .0000000001 ) return(phi); + } + Proj4js.reportError("phi4z: No convergence"); + return null; +} + + +/* Function to compute the constant e4 from the input of the eccentricity + of the spheroid, x. This constant is used in the Polar Stereographic + projection. +--------------------------------------------------------------------*/ +function e4fn(x) { + var con, com; + con = 1.0 + x; + com = 1.0 - x; + return (Math.sqrt((Math.pow(con,con))*(Math.pow(com,com)))); +} + + + + + +/******************************************************************************* +NAME POLYCONIC + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Polyconic projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +T. Mittan Mar, 1993 + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + +Proj4js.Proj.poly = { + + /* Initialize the POLYCONIC projection + ----------------------------------*/ + init: function() { + var temp; /* temporary variable */ + if (this.lat0 == 0) this.lat0 = 90;//this.lat0 ca + + /* Place parameters in static storage for common use + -------------------------------------------------*/ + this.temp = this.b / this.a; + this.es = 1.0 - Math.pow(this.temp,2);// devait etre dans tmerc.js mais n y est pas donc je commente sinon retour de valeurs nulles + 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);//si que des zeros le calcul ne se fait pas + //if (!this.ml0) {this.ml0=0;} + }, + + + /* Polyconic forward equations--mapping lat,long to x,y + ---------------------------------------------------*/ + forward: function(p) { + var sinphi, cosphi; /* sin and cos value */ + var al; /* temporary values */ + var c; /* temporary values */ + var con, ml; /* cone constant, small m */ + var ms; /* small m */ + var x,y; + + var lon=p.x; + var lat=p.y; + + con = Proj4js.common.adjust_lon(lon - this.long0); + if (Math.abs(lat) <= .0000001) { + x = this.x0 + this.a * con; + y = this.y0 - this.a * this.ml0; + } else { + sinphi = Math.sin(lat); + cosphi = Math.cos(lat); + + ml = Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, lat); + ms = Proj4js.common.msfnz(this.e,sinphi,cosphi); + con = sinphi; + x = this.x0 + this.a * ms * Math.sin(con)/sinphi; + y = this.y0 + this.a * (ml - this.ml0 + ms * (1.0 - Math.cos(con))/sinphi); + } + + p.x=x; + p.y=y; + return p; + }, + + + /* Inverse equations + -----------------*/ + inverse: function(p) { + var sin_phi, cos_phi; /* sin and cos value */ + var al; /* temporary values */ + var b; /* temporary values */ + var c; /* temporary values */ + var con, ml; /* cone constant, small m */ + var iflg; /* error flag */ + var lon,lat; + p.x -= this.x0; + p.y -= this.y0; + al = this.ml0 + p.y/this.a; + iflg = 0; + + if (Math.abs(al) <= .0000001) { + lon = p.x/this.a + this.long0; + lat = 0.0; + } else { + b = al * al + (p.x/this.a) * (p.x/this.a); + iflg = phi4z(this.es,this.e0,this.e1,this.e2,this.e3,this.al,b,c,lat); + if (iflg != 1) return(iflg); + lon = Proj4js.common.adjust_lon((Proj4js.common.asinz(p.x * c / this.a) / Math.sin(lat)) + this.long0); + } + + p.x=lon; + p.y=lat; + return p; + } +}; + + + diff --git a/ajax/libs/proj4js/1.1.0/projCode/sinu.js b/ajax/libs/proj4js/1.1.0/projCode/sinu.js new file mode 100755 index 000000000..0b5193340 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/sinu.js @@ -0,0 +1,121 @@ +/******************************************************************************* +NAME SINUSOIDAL + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Sinusoidal projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +PROGRAMMER DATE +---------- ---- +D. Steinwand, EROS May, 1991 + +This function was adapted from the Sinusoidal projection code (FORTRAN) in the +General Cartographic Transformation Package software which is available from +the U.S. Geological Survey National Mapping Division. + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. "Software Documentation for GCTP General Cartographic Transformation + Package", U.S. Geological Survey National Mapping Division, May 1982. +*******************************************************************************/ + +Proj4js.Proj.sinu = { + + /* Initialize the Sinusoidal projection + ------------------------------------*/ + init: function() { + /* Place parameters in static storage for common use + -------------------------------------------------*/ + + + if (!this.sphere) { + this.en = Proj4js.common.pj_enfn(this.es); + } else { + this.n = 1.; + this.m = 0.; + this.es = 0; + this.C_y = Math.sqrt((this.m + 1.) / this.n); + this.C_x = this.C_y/(this.m + 1.); + } + + }, + + /* Sinusoidal forward equations--mapping lat,long to x,y + -----------------------------------------------------*/ + forward: function(p) { + var x,y,delta_lon; + var lon=p.x; + var lat=p.y; + /* Forward equations + -----------------*/ + lon = Proj4js.common.adjust_lon(lon - this.long0); + + if (this.sphere) { + if (!this.m) { + lat = this.n != 1. ? Math.asin(this.n * Math.sin(lat)): lat; + } else { + var k = this.n * Math.sin(lat); + for (var i = Proj4js.common.MAX_ITER; i ; --i) { + var V = (this.m * lat + Math.sin(lat) - k) / (this.m + Math.cos(lat)); + lat -= V; + if (Math.abs(V) < Proj4js.common.EPSLN) break; + } + } + x = this.a * this.C_x * lon * (this.m + Math.cos(lat)); + y = this.a * this.C_y * lat; + + } else { + + var s = Math.sin(lat); + var c = Math.cos(lat); + y = this.a * Proj4js.common.pj_mlfn(lat, s, c, this.en); + x = this.a * lon * c / Math.sqrt(1. - this.es * s * s); + } + + p.x=x; + p.y=y; + return p; + }, + + inverse: function(p) { + var lat,temp,lon; + + /* Inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + lat = p.y / this.a; + + if (this.sphere) { + + p.y /= this.C_y; + lat = this.m ? Math.asin((this.m * p.y + Math.sin(p.y)) / this.n) : + ( this.n != 1. ? Math.asin(Math.sin(p.y) / this.n) : p.y ); + lon = p.x / (this.C_x * (this.m + Math.cos(p.y))); + + } else { + lat = Proj4js.common.pj_inv_mlfn(p.y/this.a, this.es, this.en) + var s = Math.abs(lat); + if (s < Proj4js.common.HALF_PI) { + s = Math.sin(lat); + temp = this.long0 + p.x * Math.sqrt(1. - this.es * s * s) /(this.a * Math.cos(lat)); + //temp = this.long0 + p.x / (this.a * Math.cos(lat)); + lon = Proj4js.common.adjust_lon(temp); + } else if ((s - Proj4js.common.EPSLN) < Proj4js.common.HALF_PI) { + lon = this.long0; + } + + } + + p.x=lon; + p.y=lat; + return p; + } +}; + + diff --git a/ajax/libs/proj4js/1.1.0/projCode/somerc.js b/ajax/libs/proj4js/1.1.0/projCode/somerc.js new file mode 100755 index 000000000..474ad2e01 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/somerc.js @@ -0,0 +1,110 @@ +/******************************************************************************* +NAME SWISS OBLIQUE MERCATOR + +PURPOSE: Swiss projection. +WARNING: X and Y are inverted (weird) in the swiss coordinate system. Not + here, since we want X to be horizontal and Y vertical. + +ALGORITHM REFERENCES +1. "Formules et constantes pour le Calcul pour la + projection cylindrique conforme à axe oblique et pour la transformation entre + des systèmes de référence". + http://www.swisstopo.admin.ch/internet/swisstopo/fr/home/topics/survey/sys/refsys/switzerland.parsysrelated1.31216.downloadList.77004.DownloadFile.tmp/swissprojectionfr.pdf + +*******************************************************************************/ + +Proj4js.Proj.somerc = { + + init: function() { + var phy0 = this.lat0; + this.lambda0 = this.long0; + var sinPhy0 = Math.sin(phy0); + var semiMajorAxis = this.a; + var invF = this.rf; + var flattening = 1 / invF; + var e2 = 2 * flattening - Math.pow(flattening, 2); + var e = this.e = Math.sqrt(e2); + this.R = this.k0 * semiMajorAxis * Math.sqrt(1 - e2) / (1 - e2 * Math.pow(sinPhy0, 2.0)); + this.alpha = Math.sqrt(1 + e2 / (1 - e2) * Math.pow(Math.cos(phy0), 4.0)); + this.b0 = Math.asin(sinPhy0 / this.alpha); + this.K = Math.log(Math.tan(Math.PI / 4.0 + this.b0 / 2.0)) + - this.alpha + * Math.log(Math.tan(Math.PI / 4.0 + phy0 / 2.0)) + + this.alpha + * e / 2 + * Math.log((1 + e * sinPhy0) + / (1 - e * sinPhy0)); + }, + + + forward: function(p) { + var Sa1 = Math.log(Math.tan(Math.PI / 4.0 - p.y / 2.0)); + var Sa2 = this.e / 2.0 + * Math.log((1 + this.e * Math.sin(p.y)) + / (1 - this.e * Math.sin(p.y))); + var S = -this.alpha * (Sa1 + Sa2) + this.K; + + // spheric latitude + var b = 2.0 * (Math.atan(Math.exp(S)) - Math.PI / 4.0); + + // spheric longitude + var I = this.alpha * (p.x - this.lambda0); + + // psoeudo equatorial rotation + var rotI = Math.atan(Math.sin(I) + / (Math.sin(this.b0) * Math.tan(b) + + Math.cos(this.b0) * Math.cos(I))); + + var rotB = Math.asin(Math.cos(this.b0) * Math.sin(b) - + Math.sin(this.b0) * Math.cos(b) * Math.cos(I)); + + p.y = this.R / 2.0 + * Math.log((1 + Math.sin(rotB)) / (1 - Math.sin(rotB))) + + this.y0; + p.x = this.R * rotI + this.x0; + return p; + }, + + inverse: function(p) { + var Y = p.x - this.x0; + var X = p.y - this.y0; + + var rotI = Y / this.R; + var rotB = 2 * (Math.atan(Math.exp(X / this.R)) - Math.PI / 4.0); + + var b = Math.asin(Math.cos(this.b0) * Math.sin(rotB) + + Math.sin(this.b0) * Math.cos(rotB) * Math.cos(rotI)); + var I = Math.atan(Math.sin(rotI) + / (Math.cos(this.b0) * Math.cos(rotI) - Math.sin(this.b0) + * Math.tan(rotB))); + + var lambda = this.lambda0 + I / this.alpha; + + var S = 0.0; + var phy = b; + var prevPhy = -1000.0; + var iteration = 0; + while (Math.abs(phy - prevPhy) > 0.0000001) + { + if (++iteration > 20) + { + Proj4js.reportError("omercFwdInfinity"); + return; + } + //S = Math.log(Math.tan(Math.PI / 4.0 + phy / 2.0)); + S = 1.0 + / this.alpha + * (Math.log(Math.tan(Math.PI / 4.0 + b / 2.0)) - this.K) + + this.e + * Math.log(Math.tan(Math.PI / 4.0 + + Math.asin(this.e * Math.sin(phy)) + / 2.0)); + prevPhy = phy; + phy = 2.0 * Math.atan(Math.exp(S)) - Math.PI / 2.0; + } + + p.x = lambda; + p.y = phy; + return p; + } +}; diff --git a/ajax/libs/proj4js/1.1.0/projCode/stere.js b/ajax/libs/proj4js/1.1.0/projCode/stere.js new file mode 100755 index 000000000..8575ffcd6 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/stere.js @@ -0,0 +1,247 @@ + +// Initialize the Stereographic projection + +Proj4js.Proj.stere = { + ssfn_: function(phit, sinphi, eccen) { + sinphi *= eccen; + return (Math.tan (.5 * (Proj4js.common.HALF_PI + phit)) * Math.pow((1. - sinphi) / (1. + sinphi), .5 * eccen)); + }, + TOL: 1.e-8, + NITER: 8, + CONV: 1.e-10, + S_POLE: 0, + N_POLE: 1, + OBLIQ: 2, + EQUIT: 3, + + init: function() { + this.phits = this.lat_ts ? this.lat_ts : Proj4js.common.HALF_PI; + var t = Math.abs(this.lat0); + if ((Math.abs(t) - Proj4js.common.HALF_PI) < Proj4js.common.EPSLN) { + this.mode = this.lat0 < 0. ? this.S_POLE : this.N_POLE; + } else { + this.mode = t > Proj4js.common.EPSLN ? this.OBLIQ : this.EQUIT; + } + this.phits = Math.abs(this.phits); + if (this.es) { + var X; + + switch (this.mode) { + case this.N_POLE: + case this.S_POLE: + if (Math.abs(this.phits - Proj4js.common.HALF_PI) < 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)); + } else { + t = Math.sin(this.phits); + this.akm1 = Math.cos(this.phits) / Proj4js.common.tsfnz(this.e, this.phits, t); + t *= this.e; + this.akm1 /= Math.sqrt(1. - t * t); + } + break; + case this.EQUIT: + this.akm1 = 2. * this.k0; + break; + case this.OBLIQ: + t = Math.sin(this.lat0); + X = 2. * Math.atan(this.ssfn_(this.lat0, t, this.e)) - Proj4js.common.HALF_PI; + t *= this.e; + this.akm1 = 2. * this.k0 * Math.cos(this.lat0) / Math.sqrt(1. - t * t); + this.sinX1 = Math.sin(X); + this.cosX1 = Math.cos(X); + break; + } + } else { + switch (this.mode) { + case this.OBLIQ: + this.sinph0 = 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 - .5 * this.phits) : + 2. * this.k0 ; + break; + } + } + }, + +// Stereographic forward equations--mapping lat,long to x,y + forward: function(p) { + var lon = p.x; + lon = Proj4js.common.adjust_lon(lon - this.long0); + var lat = p.y; + var x, y; + + if (this.sphere) { + var sinphi, cosphi, coslam, sinlam; + + sinphi = Math.sin(lat); + cosphi = Math.cos(lat); + coslam = Math.cos(lon); + sinlam = Math.sin(lon); + switch (this.mode) { + case this.EQUIT: + y = 1. + cosphi * coslam; + if (y <= Proj4js.common.EPSLN) { + Proj4js.reportError("stere:forward:Equit"); + } + y = this.akm1 / y; + x = y * cosphi * sinlam; + y *= sinphi; + break; + case this.OBLIQ: + y = 1. + this.sinph0 * sinphi + this.cosph0 * cosphi * coslam; + if (y <= Proj4js.common.EPSLN) { + Proj4js.reportError("stere:forward:Obliq"); + } + y = this.akm1 / y; + x = y * cosphi * sinlam; + y *= this.cosph0 * sinphi - this.sinph0 * cosphi * coslam; + break; + case this.N_POLE: + coslam = -coslam; + lat = -lat; + //Note no break here so it conitnues through S_POLE + case this.S_POLE: + if (Math.abs(lat - Proj4js.common.HALF_PI) < this.TOL) { + Proj4js.reportError("stere:forward:S_POLE"); + } + y = this.akm1 * Math.tan(Proj4js.common.FORTPI + .5 * lat); + x = sinlam * y; + y *= coslam; + break; + } + } else { + coslam = Math.cos(lon); + sinlam = Math.sin(lon); + sinphi = Math.sin(lat); + var sinX, cosX; + if (this.mode == this.OBLIQ || this.mode == this.EQUIT) { + var Xt = 2. * Math.atan(this.ssfn_(lat, sinphi, this.e)); + sinX = Math.sin(Xt - Proj4js.common.HALF_PI); + cosX = Math.cos(Xt); + } + switch (this.mode) { + case this.OBLIQ: + var A = this.akm1 / (this.cosX1 * (1. + this.sinX1 * sinX + this.cosX1 * cosX * coslam)); + y = A * (this.cosX1 * sinX - this.sinX1 * cosX * coslam); + x = A * cosX; + break; + case this.EQUIT: + var A = 2. * this.akm1 / (1. + cosX * coslam); + y = A * sinX; + x = A * cosX; + break; + case this.S_POLE: + lat = -lat; + coslam = - coslam; + sinphi = -sinphi; + case this.N_POLE: + x = this.akm1 * Proj4js.common.tsfnz(this.e, lat, sinphi); + y = - x * coslam; + break; + } + x = x * sinlam; + } + p.x = x*this.a + this.x0; + p.y = y*this.a + this.y0; + return p; + }, + + +//* Stereographic inverse equations--mapping x,y to lat/long + inverse: function(p) { + var x = (p.x - this.x0)/this.a; /* descale and de-offset */ + var y = (p.y - this.y0)/this.a; + var lon, lat; + + var cosphi, sinphi, tp=0.0, phi_l=0.0, rho, halfe=0.0, pi2=0.0; + var i; + + if (this.sphere) { + var c, rh, sinc, cosc; + + rh = Math.sqrt(x*x + y*y); + c = 2. * Math.atan(rh / this.akm1); + sinc = Math.sin(c); + cosc = Math.cos(c); + lon = 0.; + switch (this.mode) { + case this.EQUIT: + if (Math.abs(rh) <= Proj4js.common.EPSLN) { + lat = 0.; + } else { + lat = Math.asin(y * sinc / rh); + } + if (cosc != 0. || x != 0.) lon = Math.atan2(x * sinc, cosc * rh); + break; + case this.OBLIQ: + if (Math.abs(rh) <= Proj4js.common.EPSLN) { + lat = this.phi0; + } else { + lat = Math.asin(cosc * this.sinph0 + y * sinc * this.cosph0 / rh); + } + c = cosc - this.sinph0 * Math.sin(lat); + if (c != 0. || x != 0.) { + lon = Math.atan2(x * sinc * this.cosph0, c * rh); + } + break; + case this.N_POLE: + y = -y; + case this.S_POLE: + if (Math.abs(rh) <= Proj4js.common.EPSLN) { + lat = this.phi0; + } else { + lat = Math.asin(this.mode == this.S_POLE ? -cosc : cosc); + } + lon = (x == 0. && y == 0.) ? 0. : Math.atan2(x, y); + break; + } + p.x = Proj4js.common.adjust_lon(lon + this.long0); + p.y = lat; + } else { + rho = Math.sqrt(x*x + y*y); + switch (this.mode) { + case this.OBLIQ: + case this.EQUIT: + tp = 2. * Math.atan2(rho * this.cosX1 , this.akm1); + cosphi = Math.cos(tp); + sinphi = Math.sin(tp); + if( rho == 0.0 ) { + phi_l = Math.asin(cosphi * this.sinX1); + } else { + phi_l = Math.asin(cosphi * this.sinX1 + (y * sinphi * this.cosX1 / rho)); + } + + tp = Math.tan(.5 * (Proj4js.common.HALF_PI + phi_l)); + x *= sinphi; + y = rho * this.cosX1 * cosphi - y * this.sinX1* sinphi; + pi2 = Proj4js.common.HALF_PI; + halfe = .5 * this.e; + break; + case this.N_POLE: + y = -y; + case this.S_POLE: + tp = - rho / this.akm1; + phi_l = Proj4js.common.HALF_PI - 2. * Math.atan(tp); + pi2 = -Proj4js.common.HALF_PI; + halfe = -.5 * this.e; + break; + } + for (i = this.NITER; i--; phi_l = lat) { //check this + sinphi = this.e * Math.sin(phi_l); + lat = 2. * Math.atan(tp * Math.pow((1.+sinphi)/(1.-sinphi), halfe)) - pi2; + if (Math.abs(phi_l - lat) < this.CONV) { + if (this.mode == this.S_POLE) lat = -lat; + lon = (x == 0. && y == 0.) ? 0. : Math.atan2(x, y); + p.x = Proj4js.common.adjust_lon(lon + this.long0); + p.y = lat; + return p; + } + } + } + } +}; diff --git a/ajax/libs/proj4js/1.1.0/projCode/sterea.js b/ajax/libs/proj4js/1.1.0/projCode/sterea.js new file mode 100755 index 000000000..095295679 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/sterea.js @@ -0,0 +1,57 @@ + +Proj4js.Proj.sterea = { + dependsOn : 'gauss', + + init : function() { + Proj4js.Proj['gauss'].init.apply(this); + if (!this.rc) { + Proj4js.reportError("sterea:init:E_ERROR_0"); + return; + } + this.sinc0 = Math.sin(this.phic0); + this.cosc0 = Math.cos(this.phic0); + this.R2 = 2.0 * this.rc; + if (!this.title) this.title = "Oblique Stereographic Alternative"; + }, + + forward : function(p) { + var sinc, cosc, cosl, k; + p.x = Proj4js.common.adjust_lon(p.x-this.long0); /* adjust del longitude */ + Proj4js.Proj['gauss'].forward.apply(this, [p]); + sinc = Math.sin(p.y); + cosc = Math.cos(p.y); + cosl = Math.cos(p.x); + k = this.k0 * this.R2 / (1.0 + this.sinc0 * sinc + this.cosc0 * cosc * cosl); + p.x = k * cosc * Math.sin(p.x); + p.y = k * (this.cosc0 * sinc - this.sinc0 * cosc * cosl); + p.x = this.a * p.x + this.x0; + p.y = this.a * p.y + this.y0; + return p; + }, + + inverse : function(p) { + var sinc, cosc, lon, lat, rho; + p.x = (p.x - this.x0) / this.a; /* descale and de-offset */ + p.y = (p.y - this.y0) / this.a; + + p.x /= this.k0; + p.y /= this.k0; + if ( (rho = Math.sqrt(p.x*p.x + p.y*p.y)) ) { + var c = 2.0 * Math.atan2(rho, this.R2); + sinc = Math.sin(c); + cosc = Math.cos(c); + lat = Math.asin(cosc * this.sinc0 + p.y * sinc * this.cosc0 / rho); + lon = Math.atan2(p.x * sinc, rho * this.cosc0 * cosc - p.y * this.sinc0 * sinc); + } else { + lat = this.phic0; + lon = 0.; + } + + p.x = lon; + p.y = lat; + Proj4js.Proj['gauss'].inverse.apply(this,[p]); + p.x = Proj4js.common.adjust_lon(p.x + this.long0); /* adjust longitude to CM */ + return p; + } +}; + diff --git a/ajax/libs/proj4js/1.1.0/projCode/tmerc.js b/ajax/libs/proj4js/1.1.0/projCode/tmerc.js new file mode 100755 index 000000000..ed23841d6 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/tmerc.js @@ -0,0 +1,141 @@ +/******************************************************************************* +NAME TRANSVERSE MERCATOR + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Transverse Mercator projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + + +/** + Initialize Transverse Mercator projection +*/ + +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); + }, + + /** + Transverse Mercator Forward - long/lat to x/y + long/lat in radians + */ + forward : function(p) { + var lon = p.x; + var lat = p.y; + + var delta_lon = Proj4js.common.adjust_lon(lon - this.long0); // Delta longitude + var con; // cone constant + var x, y; + var sin_phi=Math.sin(lat); + var cos_phi=Math.cos(lat); + + if (this.sphere) { /* spherical form */ + var b = cos_phi * Math.sin(delta_lon); + if ((Math.abs(Math.abs(b) - 1.0)) < .0000000001) { + Proj4js.reportError("tmerc:forward: Point projects into infinity"); + return(93); + } else { + x = .5 * this.a * this.k0 * Math.log((1.0 + b)/(1.0 - b)); + con = Math.acos(cos_phi * Math.cos(delta_lon)/Math.sqrt(1.0 - b*b)); + if (lat < 0) con = - con; + y = this.a * this.k0 * (con - this.lat0); + } + } else { + var al = cos_phi * delta_lon; + var als = Math.pow(al,2); + var c = this.ep2 * Math.pow(cos_phi,2); + var tq = Math.tan(lat); + var t = Math.pow(tq,2); + con = 1.0 - this.es * Math.pow(sin_phi,2); + var n = this.a / Math.sqrt(con); + var ml = this.a * Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, lat); + + x = this.k0 * n * al * (1.0 + als / 6.0 * (1.0 - t + c + als / 20.0 * (5.0 - 18.0 * t + Math.pow(t,2) + 72.0 * c - 58.0 * this.ep2))) + this.x0; + y = this.k0 * (ml - this.ml0 + n * tq * (als * (0.5 + als / 24.0 * (5.0 - t + 9.0 * c + 4.0 * Math.pow(c,2) + als / 30.0 * (61.0 - 58.0 * t + Math.pow(t,2) + 600.0 * c - 330.0 * this.ep2))))) + this.y0; + + } + p.x = x; p.y = y; + return p; + }, // tmercFwd() + + /** + Transverse Mercator Inverse - x/y to long/lat + */ + inverse : function(p) { + var con, phi; /* temporary angles */ + var delta_phi; /* difference between longitudes */ + var i; + var max_iter = 6; /* maximun number of iterations */ + var lat, lon; + + if (this.sphere) { /* spherical form */ + var f = Math.exp(p.x/(this.a * this.k0)); + var g = .5 * (f - 1/f); + var temp = this.lat0 + p.y/(this.a * this.k0); + var h = Math.cos(temp); + con = Math.sqrt((1.0 - h * h)/(1.0 + g * g)); + lat = Proj4js.common.asinz(con); + if (temp < 0) + lat = -lat; + if ((g == 0) && (h == 0)) { + lon = this.long0; + } else { + lon = Proj4js.common.adjust_lon(Math.atan2(g,h) + this.long0); + } + } else { // ellipsoidal form + var x = p.x - this.x0; + var y = p.y - this.y0; + + con = (this.ml0 + y / this.k0) / this.a; + phi = con; + for (i=0;true;i++) { + delta_phi=((con + this.e1 * Math.sin(2.0*phi) - this.e2 * Math.sin(4.0*phi) + this.e3 * Math.sin(6.0*phi)) / this.e0) - phi; + phi += delta_phi; + if (Math.abs(delta_phi) <= Proj4js.common.EPSLN) break; + if (i >= max_iter) { + Proj4js.reportError("tmerc:inverse: Latitude failed to converge"); + return(95); + } + } // for() + if (Math.abs(phi) < Proj4js.common.HALF_PI) { + // sincos(phi, &sin_phi, &cos_phi); + var sin_phi=Math.sin(phi); + var cos_phi=Math.cos(phi); + var tan_phi = Math.tan(phi); + var c = this.ep2 * Math.pow(cos_phi,2); + var cs = Math.pow(c,2); + var t = Math.pow(tan_phi,2); + var ts = Math.pow(t,2); + con = 1.0 - this.es * Math.pow(sin_phi,2); + var n = this.a / Math.sqrt(con); + var r = n * (1.0 - this.es) / con; + var d = x / (n * this.k0); + var ds = Math.pow(d,2); + lat = phi - (n * tan_phi * ds / r) * (0.5 - ds / 24.0 * (5.0 + 3.0 * t + 10.0 * c - 4.0 * cs - 9.0 * this.ep2 - ds / 30.0 * (61.0 + 90.0 * t + 298.0 * c + 45.0 * ts - 252.0 * this.ep2 - 3.0 * cs))); + lon = Proj4js.common.adjust_lon(this.long0 + (d * (1.0 - ds / 6.0 * (1.0 + 2.0 * t + c - ds / 20.0 * (5.0 - 2.0 * c + 28.0 * t - 3.0 * cs + 8.0 * this.ep2 + 24.0 * ts))) / cos_phi)); + } else { + lat = Proj4js.common.HALF_PI * Proj4js.common.sign(y); + lon = this.long0; + } + } + p.x = lon; + p.y = lat; + return p; + } // tmercInv() +}; \ No newline at end of file diff --git a/ajax/libs/proj4js/1.1.0/projCode/utm.js b/ajax/libs/proj4js/1.1.0/projCode/utm.js new file mode 100755 index 000000000..f1c5b9ff9 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/utm.js @@ -0,0 +1,43 @@ +/******************************************************************************* +NAME TRANSVERSE MERCATOR + +PURPOSE: Transforms input longitude and latitude to Easting and + Northing for the Transverse Mercator projection. The + longitude and latitude must be in radians. The Easting + and Northing values will be returned in meters. + +ALGORITHM REFERENCES + +1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections", + U.S. Geological Survey Professional Paper 1453 , United State Government + Printing Office, Washington D.C., 1989. +*******************************************************************************/ + + +/** + Initialize Transverse Mercator projection +*/ + +Proj4js.Proj.utm = { + dependsOn : 'tmerc', + + init : function() { + if (!this.zone) { + Proj4js.reportError("utm:init: zone must be specified for UTM"); + return; + } + this.lat0 = 0.0; + this.long0 = ((6 * Math.abs(this.zone)) - 183) * Proj4js.common.D2R; + this.x0 = 500000.0; + this.y0 = this.utmSouth ? 10000000.0 : 0.0; + this.k0 = 0.9996; + + Proj4js.Proj['tmerc'].init.apply(this); + this.forward = Proj4js.Proj['tmerc'].forward; + this.inverse = Proj4js.Proj['tmerc'].inverse; + } +}; \ No newline at end of file diff --git a/ajax/libs/proj4js/1.1.0/projCode/vandg.js b/ajax/libs/proj4js/1.1.0/projCode/vandg.js new file mode 100755 index 000000000..6b6e0e635 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/projCode/vandg.js @@ -0,0 +1,137 @@ +/******************************************************************************* +NAME VAN DER GRINTEN + +PURPOSE: Transforms input Easting and Northing to longitude and + latitude for the Van der Grinten projection. The + Easting and Northing must be in meters. The longitude + and latitude values will be returned in radians. + +PROGRAMMER DATE +---------- ---- +T. Mittan March, 1993 + +This function was adapted from the Van Der Grinten projection code +(FORTRAN) in the General Cartographic Transformation Package software +which is available from the U.S. Geological Survey National Mapping Division. + +ALGORITHM REFERENCES + +1. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder, + The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355. + +2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological + Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United + State Government Printing Office, Washington D.C., 1987. + +3. "Software Documentation for GCTP General Cartographic Transformation + Package", U.S. Geological Survey National Mapping Division, May 1982. +*******************************************************************************/ + +Proj4js.Proj.vandg = { + +/* Initialize the Van Der Grinten projection + ----------------------------------------*/ + init: function() { + this.R = 6370997.0; //Radius of earth + }, + + forward: function(p) { + + var lon=p.x; + var lat=p.y; + + /* Forward equations + -----------------*/ + var dlon = Proj4js.common.adjust_lon(lon - this.long0); + var x,y; + + if (Math.abs(lat) <= Proj4js.common.EPSLN) { + x = this.x0 + this.R * dlon; + y = this.y0; + } + var theta = Proj4js.common.asinz(2.0 * Math.abs(lat / Proj4js.common.PI)); + if ((Math.abs(dlon) <= Proj4js.common.EPSLN) || (Math.abs(Math.abs(lat) - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN)) { + x = this.x0; + if (lat >= 0) { + y = this.y0 + Proj4js.common.PI * this.R * Math.tan(.5 * theta); + } else { + y = this.y0 + Proj4js.common.PI * this.R * - Math.tan(.5 * theta); + } + // return(OK); + } + var al = .5 * Math.abs((Proj4js.common.PI / dlon) - (dlon / Proj4js.common.PI)); + var asq = al * al; + var sinth = Math.sin(theta); + var costh = Math.cos(theta); + + var g = costh / (sinth + costh - 1.0); + var gsq = g * g; + var m = g * (2.0 / sinth - 1.0); + var msq = m * m; + var con = Proj4js.common.PI * this.R * (al * (g - msq) + Math.sqrt(asq * (g - msq) * (g - msq) - (msq + asq) * (gsq - msq))) / (msq + asq); + if (dlon < 0) { + con = -con; + } + x = this.x0 + con; + con = Math.abs(con / (Proj4js.common.PI * this.R)); + if (lat >= 0) { + y = this.y0 + Proj4js.common.PI * this.R * Math.sqrt(1.0 - con * con - 2.0 * al * con); + } else { + y = this.y0 - Proj4js.common.PI * this.R * Math.sqrt(1.0 - con * con - 2.0 * al * con); + } + p.x = x; + p.y = y; + return p; + }, + +/* Van Der Grinten inverse equations--mapping x,y to lat/long + ---------------------------------------------------------*/ + inverse: function(p) { + var lon, lat; + var xx,yy,xys,c1,c2,c3; + var al,asq; + var a1; + var m1; + var con; + var th1; + var d; + + /* inverse equations + -----------------*/ + p.x -= this.x0; + p.y -= this.y0; + con = Proj4js.common.PI * this.R; + xx = p.x / con; + yy =p.y / con; + xys = xx * xx + yy * yy; + c1 = -Math.abs(yy) * (1.0 + xys); + c2 = c1 - 2.0 * yy * yy + xx * xx; + c3 = -2.0 * c1 + 1.0 + 2.0 * yy * yy + xys * xys; + d = yy * yy / c3 + (2.0 * c2 * c2 * c2 / c3 / c3 / c3 - 9.0 * c1 * c2 / c3 /c3) / 27.0; + a1 = (c1 - c2 * c2 / 3.0 / c3) / c3; + m1 = 2.0 * Math.sqrt( -a1 / 3.0); + con = ((3.0 * d) / a1) / m1; + if (Math.abs(con) > 1.0) { + if (con >= 0.0) { + con = 1.0; + } else { + con = -1.0; + } + } + th1 = Math.acos(con) / 3.0; + if (p.y >= 0) { + lat = (-m1 *Math.cos(th1 + Proj4js.common.PI / 3.0) - c2 / 3.0 / c3) * Proj4js.common.PI; + } else { + lat = -(-m1 * Math.cos(th1 + Proj4js.common.PI / 3.0) - c2 / 3.0 / c3) * Proj4js.common.PI; + } + + if (Math.abs(xx) < Proj4js.common.EPSLN) { + lon = this.long0; + } + lon = Proj4js.common.adjust_lon(this.long0 + Proj4js.common.PI * (xys - 1.0 + Math.sqrt(1.0 + 2.0 * (xx * xx - yy * yy) + xys * xys)) / 2.0 / xx); + + p.x=lon; + p.y=lat; + return p; + } +}; diff --git a/ajax/libs/proj4js/1.1.0/util/MGRS.js b/ajax/libs/proj4js/1.1.0/util/MGRS.js new file mode 100755 index 000000000..c59fa3a85 --- /dev/null +++ b/ajax/libs/proj4js/1.1.0/util/MGRS.js @@ -0,0 +1,950 @@ +/* +Portions of this software are based on a port of components from the OpenMap +com.bbn.openmap.proj.coords Java package. An initial port was initially created +by Patrice G. Cappelaere and included in Community Mapbuilder +(http://svn.codehaus.org/mapbuilder/), which is licensed under the LGPL license +as per http://www.gnu.org/copyleft/lesser.html. OpenMap is licensed under the +following license agreement: + + + OpenMap Software License Agreement + ---------------------------------- + +This Agreement sets forth the terms and conditions under which +the software known as OpenMap(tm) will be licensed by BBN +Technologies ("BBN") to you ("Licensee"), and by which Derivative +Works (as hereafter defined) of OpenMap will be licensed by you to BBN. + +Definitions: + + "Derivative Work(s)" shall mean any revision, enhancement, + modification, translation, abridgement, condensation or + expansion created by Licensee or BBN that is based upon the + Software or a portion thereof that would be a copyright + infringement if prepared without the authorization of the + copyright owners of the Software or portion thereof. + + "OpenMap" shall mean a programmer's toolkit for building map + based applications as originally created by BBN, and any + Derivative Works thereof as created by either BBN or Licensee, + but shall include only those Derivative Works BBN has approved + for inclusion into, and BBN has integrated into OpenMap. + + "Standard Version" shall mean OpenMap, as originally created by + BBN. + + "Software" shall mean OpenMap and the Derivative Works created + by Licensee and the collection of files distributed by the + Licensee with OpenMap, and the collection of files created + through textual modifications. + + "Copyright Holder" is whoever is named in the copyright or + copyrights for the Derivative Works. + + "Licensee" is you, only if you agree to be bound by the terms + and conditions set forth in this Agreement. + + "Reasonable copying fee" is whatever you can justify on the + basis of media cost, duplication charges, time of people + involved. + + "Freely Available" means that no fee is charged for the item + itself, though there may be fees involved in handling the item. + It also means that recipients of the item may redistribute it + under the same conditions that they received it. + +1. BBN maintains all rights, title and interest in and to +OpenMap, including all applicable copyrights, trade secrets, +patents and other intellectual rights therein. Licensee hereby +grants to BBN all right, title and interest into the compilation +of OpenMap. Licensee shall own all rights, title and interest +into the Derivative Works created by Licensee (subject to the +compilation ownership by BBN). + +2. BBN hereby grants to Licensee a royalty free, worldwide right +and license to use, copy, distribute and make Derivative Works of +OpenMap, and sublicensing rights of any of the foregoing in +accordance with the terms and conditions of this Agreement, +provided that you duplicate all of the original copyright notices +and associated disclaimers. + +3. Licensee hereby grants to BBN a royalty free, worldwide right +and license to use, copy, distribute and make Derivative Works of +Derivative Works created by Licensee and sublicensing rights of +any of the foregoing. + +4. Licensee's right to create Derivative Works in the Software is +subject to Licensee agreement to insert a prominent notice in +each changed file stating how and when you changed that file, and +provided that you do at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or + placing the modifications on a major archive site and by + providing your modifications to the Copyright Holder. + + b) use the modified Package only within your corporation or + organization. + + c) rename any non-standard executables so the names do not + conflict with standard executables, which must also be + provided, and provide a separate manual page for each + non-standard executable that clearly documents how it + differs from OpenMap. + + d) make other distribution arrangements with the Copyright + Holder. + +5. Licensee may distribute the programs of this Software in +object code or executable form, provided that you do at least ONE +of the following: + + a) distribute an OpenMap version of the executables and + library files, together with instructions (in the manual + page or equivalent) on where to get OpenMap. + + b) accompany the distribution with the machine-readable + source code with your modifications. + + c) accompany any non-standard executables with their + corresponding OpenMap executables, giving the non-standard + executables non-standard names, and clearly documenting + the differences in manual pages (or equivalent), together + with instructions on where to get OpenMap. + + d) make other distribution arrangements with the Copyright + Holder. + +6. You may charge a reasonable copying fee for any distribution +of this Software. You may charge any fee you choose for support +of this Software. You may not charge a fee for this Software +itself. However, you may distribute this Software in aggregate +with other (possibly commercial) programs as part of a larger +(possibly commercial) software distribution provided that you do +not advertise this Software as a product of your own. + +7. The data and images supplied as input to or produced as output +from the Software do not automatically fall under the copyright +of this Software, but belong to whomever generated them, and may +be sold commercially, and may be aggregated with this Software. + +8. BBN makes no representation about the suitability of OpenMap +for any purposes. BBN shall have no duty or requirement to +include any Derivative Works into OpenMap. + +9. Each party hereto represents and warrants that they have the +full unrestricted right to grant all rights and licenses granted +to the other party herein. + +10. THIS PACKAGE IS PROVIDED "AS IS" WITHOUT WARRANTIES OF ANY +KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING (BUT NOT LIMITED TO) +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND +WITHOUT ANY WARRANTIES AS TO NONINFRINGEMENT. + +11. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES WHATSOEVER RESULTING +FROM LOSS OF USE OF DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS CONDUCT, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PACKAGE. + +12. Without limitation of the foregoing, You agree to commit no +act which, directly or indirectly, would violate any U.S. law, +regulation, or treaty, or any other international treaty or +agreement to which the United States adheres or with which the +United States complies, relating to the export or re-export of +any commodities, software, or technical data. +*/ + +if (window.Proj4js && !Proj4js.util) { Proj4js.util = {}; } + +/** + * Converts between lat/lon and MGRS coordinates. Note that this static class + * is restricted to the WGS84 ellipsoid and does not support MGRS notations + * for polar regions (i.e. above 84° North and below 80° South). + * + * If Proj4js is loaded, this will be referenced as Proj4js.util.MGRS. If used + * standalone, it will be referenced as window.MGRS. + * + * @static + */ +(window.Proj4js ? Proj4js.util : window)["MGRS"] = (function() { + + /** + * UTM zones are grouped, and assigned to one of a group of 6 + * sets. + * + * {int} @private + */ + var NUM_100K_SETS = 6; + + /** + * The column letters (for easting) of the lower left value, per + * set. + * + * {string} @private + */ + var SET_ORIGIN_COLUMN_LETTERS = 'AJSAJS'; + + /** + * The row letters (for northing) of the lower left value, per + * set. + * + * {string} @private + */ + var SET_ORIGIN_ROW_LETTERS = 'AFAFAF'; + + var A = 65; // A + var I = 73; // I + var O = 79; // O + var V = 86; // V + var Z = 90; // Z + + /** + * Conversion of lat/lon to MGRS. + * + * @param {object} ll Object literal with lat and lon properties on a + * WGS84 ellipsoid. + * @param {int} accuracy Accuracy in digits (5 for 1 m, 4 for 10 m, 3 for + * 100 m, 4 for 1000 m or 5 for 10000 m). Optional, default is 5. + * @return {string} the MGRS string for the given location and accuracy. + */ + function forward(ll, accuracy) { + accuracy = accuracy || 5; // default accuracy 1m + return encode(LLtoUTM({lat: ll.lat, lon: ll.lon}), accuracy); + } + + /** + * Conversion of MGRS to lat/lon. + * + * @param {string} mgrs MGRS string. + * @return {array} An array with left (longitude), bottom (latitude), right + * (longitude) and top (latitude) values in WGS84, representing the + * bounding box for the provided MGRS reference. + */ + function inverse(mgrs) { + var bbox = UTMtoLL(decode(mgrs.toUpperCase())); + return [bbox.left, bbox.bottom, bbox.right, bbox.top]; + } + + /** + * Conversion from degrees to radians. + * + * @private + * @param {number} deg the angle in degrees. + * @return {number} the angle in radians. + */ + function degToRad(deg) { + return (deg * (Math.PI / 180.0)); + } + + /** + * Conversion from radians to degrees. + * + * @private + * @param {number} rad the angle in radians. + * @return {number} the angle in degrees. + */ + function radToDeg(rad) { + return (180.0 * (rad / Math.PI)); + } + + /** + * Converts a set of Longitude and Latitude co-ordinates to UTM + * using the WGS84 ellipsoid. + * + * @private + * @param {object} ll Object literal with lat and lon properties + * representing the WGS84 coordinate to be converted. + * @return {object} Object literal containing the UTM value with easting, + * northing, zoneNumber and zoneLetter properties, and an optional + * accuracy property in digits. Returns null if the conversion failed. + */ + function LLtoUTM(ll) { + var Lat = ll.lat; + var Long = ll.lon; + var a = 6378137.0; //ellip.radius; + var eccSquared = 0.00669438; //ellip.eccsq; + var k0 = 0.9996; + var LongOrigin; + var eccPrimeSquared; + var N, T, C, A, M; + var LatRad = degToRad(Lat); + var LongRad = degToRad(Long); + var LongOriginRad; + var ZoneNumber; + // (int) + ZoneNumber = Math.floor((Long + 180) / 6) + 1; + + //Make sure the longitude 180.00 is in Zone 60 + if (Long == 180) { + ZoneNumber = 60; + } + + // Special zone for Norway + if (Lat >= 56.0 && Lat < 64.0 && Long >= 3.0 && Long < 12.0) { + ZoneNumber = 32; + } + + // Special zones for Svalbard + if (Lat >= 72.0 && Lat < 84.0) { + if (Long >= 0.0 && Long < 9.0) + ZoneNumber = 31; + else if (Long >= 9.0 && Long < 21.0) + ZoneNumber = 33; + else if (Long >= 21.0 && Long < 33.0) + ZoneNumber = 35; + else if (Long >= 33.0 && Long < 42.0) + ZoneNumber = 37; + } + + LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3; //+3 puts origin + // in middle of + // zone + LongOriginRad = degToRad(LongOrigin); + + eccPrimeSquared = (eccSquared) / (1 - eccSquared); + + N = a / Math.sqrt(1 - eccSquared * Math.sin(LatRad) * Math.sin(LatRad)); + T = Math.tan(LatRad) * Math.tan(LatRad); + C = eccPrimeSquared * Math.cos(LatRad) * Math.cos(LatRad); + A = Math.cos(LatRad) * (LongRad - LongOriginRad); + + M = a + * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 + * eccSquared * eccSquared * eccSquared / 256) + * LatRad + - (3 * eccSquared / 8 + 3 * eccSquared * eccSquared + / 32 + 45 * eccSquared * eccSquared + * eccSquared / 1024) + * Math.sin(2 * LatRad) + + (15 * eccSquared * eccSquared / 256 + 45 * eccSquared + * eccSquared * eccSquared / 1024) + * Math.sin(4 * LatRad) - (35 * eccSquared * eccSquared + * eccSquared / 3072) + * Math.sin(6 * LatRad)); + + var UTMEasting = (k0 + * N + * (A + (1 - T + C) * A * A * A / 6.0 + (5 - 18 * T + T * T + + 72 * C - 58 * eccPrimeSquared) + * A * A * A * A * A / 120.0) + 500000.0); + + var UTMNorthing = (k0 * (M + N + * Math.tan(LatRad) + * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A + / 24.0 + (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) + * A * A * A * A * A * A / 720.0))); + if (Lat < 0.0) { + UTMNorthing += 10000000.0; //10000000 meter offset for + // southern hemisphere + } + + return { + northing: Math.round(UTMNorthing), + easting: Math.round(UTMEasting), + zoneNumber: ZoneNumber, + zoneLetter: getLetterDesignator(Lat) + }; + } + + /** + * Converts UTM coords to lat/long, using the WGS84 ellipsoid. This is a convenience + * class where the Zone can be specified as a single string eg."60N" which + * is then broken down into the ZoneNumber and ZoneLetter. + * + * @private + * @param {object} utm An object literal with northing, easting, zoneNumber + * and zoneLetter properties. If an optional accuracy property is + * provided (in meters), a bounding box will be returned instead of + * latitude and longitude. + * @return {object} An object literal containing either lat and lon values + * (if no accuracy was provided), or top, right, bottom and left values + * for the bounding box calculated according to the provided accuracy. + * Returns null if the conversion failed. + */ + function UTMtoLL(utm) { + + var UTMNorthing = utm.northing; + var UTMEasting = utm.easting; + var zoneLetter = utm.zoneLetter; + var zoneNumber = utm.zoneNumber; + // check the ZoneNummber is valid + if (zoneNumber < 0 || zoneNumber > 60) { + return null; + } + + var k0 = 0.9996; + var a = 6378137.0; //ellip.radius; + var eccSquared = 0.00669438; //ellip.eccsq; + var eccPrimeSquared; + var e1 = (1 - Math.sqrt(1 - eccSquared)) / (1 + Math.sqrt(1 - eccSquared)); + var N1, T1, C1, R1, D, M; + var LongOrigin; + var mu, phi1Rad; + + // remove 500,000 meter offset for longitude + var x = UTMEasting - 500000.0; + var y = UTMNorthing; + + // We must know somehow if we are in the Northern or Southern + // hemisphere, this is the only time we use the letter So even + // if the Zone letter isn't exactly correct it should indicate + // the hemisphere correctly + if (zoneLetter == 'S') { + y -= 10000000.0;// remove 10,000,000 meter offset used + // for southern hemisphere + } + + // There are 60 zones with zone 1 being at West -180 to -174 + LongOrigin = (zoneNumber - 1) * 6 - 180 + 3; // +3 puts origin + // in middle of + // zone + + eccPrimeSquared = (eccSquared) / (1 - eccSquared); + + M = y / k0; + mu = M / (a * (1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256)); + + phi1Rad = + mu + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * mu) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) + * Math.sin(4 * mu) + (151 * e1 * e1 * e1 / 96) * Math.sin(6 * mu); + // double phi1 = ProjMath.radToDeg(phi1Rad); + + N1 = a / Math.sqrt(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad)); + T1 = Math.tan(phi1Rad) * Math.tan(phi1Rad); + C1 = eccPrimeSquared * Math.cos(phi1Rad) * Math.cos(phi1Rad); + R1 = a * (1 - eccSquared) / Math.pow(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad), 1.5); + D = x / (N1 * k0); + + var lat = + phi1Rad + - (N1 * Math.tan(phi1Rad) / R1) + * (D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * eccPrimeSquared) * D * D * D * D / 24 + (61 + 90 + * T1 + 298 * C1 + 45 * T1 * T1 - 252 * eccPrimeSquared - 3 * C1 * C1) + * D * D * D * D * D * D / 720); + lat = radToDeg(lat); + + var lon = + (D - (1 + 2 * T1 + C1) * D * D * D / 6 + (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * eccPrimeSquared + 24 * T1 * T1) + * D * D * D * D * D / 120) / Math.cos(phi1Rad); + lon = LongOrigin + radToDeg(lon); + + var result; + if (utm.accuracy) { + var topRight = UTMtoLL({ + northing: utm.northing + utm.accuracy, + easting: utm.easting + utm.accuracy, + zoneLetter: utm.zoneLetter, + zoneNumber: utm.zoneNumber + }); + result = { + top: topRight.lat, + right: topRight.lon, + bottom: lat, + left: lon + }; + } else { + result = { + lat: lat, + lon: lon + }; + } + return result; + } + + /** + * Calculates the MGRS letter designator for the given latitude. + * + * @private + * @param {number} lat The latitude in WGS84 to get the letter designator + * for. + * @return {char} The letter designator. + */ + function getLetterDesignator(lat) { + //This is here as an error flag to show that the Latitude is + //outside MGRS limits + var LetterDesignator = 'Z'; + + if ((84 >= lat) && (lat >= 72)) + LetterDesignator = 'X'; + else if ((72 > lat) && (lat >= 64)) + LetterDesignator = 'W'; + else if ((64 > lat) && (lat >= 56)) + LetterDesignator = 'V'; + else if ((56 > lat) && (lat >= 48)) + LetterDesignator = 'U'; + else if ((48 > lat) && (lat >= 40)) + LetterDesignator = 'T'; + else if ((40 > lat) && (lat >= 32)) + LetterDesignator = 'S'; + else if ((32 > lat) && (lat >= 24)) + LetterDesignator = 'R'; + else if ((24 > lat) && (lat >= 16)) + LetterDesignator = 'Q'; + else if ((16 > lat) && (lat >= 8)) + LetterDesignator = 'P'; + else if ((8 > lat) && (lat >= 0)) + LetterDesignator = 'N'; + else if ((0 > lat) && (lat >= -8)) + LetterDesignator = 'M'; + else if ((-8 > lat) && (lat >= -16)) + LetterDesignator = 'L'; + else if ((-16 > lat) && (lat >= -24)) + LetterDesignator = 'K'; + else if ((-24 > lat) && (lat >= -32)) + LetterDesignator = 'J'; + else if ((-32 > lat) && (lat >= -40)) + LetterDesignator = 'H'; + else if ((-40 > lat) && (lat >= -48)) + LetterDesignator = 'G'; + else if ((-48 > lat) && (lat >= -56)) + LetterDesignator = 'F'; + else if ((-56 > lat) && (lat >= -64)) + LetterDesignator = 'E'; + else if ((-64 > lat) && (lat >= -72)) + LetterDesignator = 'D'; + else if ((-72 > lat) && (lat >= -80)) + LetterDesignator = 'C'; + return LetterDesignator; + } + + /** + * Encodes a UTM location as MGRS string. + * + * @private + * @param {object} utm An object literal with easting, northing, + * zoneLetter, zoneNumber + * @param {number} accuracy Accuracy in digits (1-5). + * @return {string} MGRS string for the given UTM location. + */ + function encode(utm, accuracy) { + var seasting = "" + utm.easting, + snorthing = "" + utm.northing; + + return utm.zoneNumber + utm.zoneLetter + + get100kID(utm.easting, utm.northing, utm.zoneNumber) + + seasting.substr(seasting.length - 5, accuracy) + + snorthing.substr(snorthing.length - 5, accuracy); + } + + /** + * Get the two letter 100k designator for a given UTM easting, + * northing and zone number value. + * + * @private + * @param {number} easting + * @param {number} northing + * @param {number} zoneNumber + * @return the two letter 100k designator for the given UTM location. + */ + function get100kID(easting, northing, zoneNumber) { + var setParm = get100kSetForZone(zoneNumber); + var setColumn = Math.floor(easting / 100000); + var setRow = Math.floor(northing / 100000) % 20; + return getLetter100kID(setColumn, setRow, setParm); + } + + /** + * Given a UTM zone number, figure out the MGRS 100K set it is in. + * + * @private + * @param {number} i An UTM zone number. + * @return {number} the 100k set the UTM zone is in. + */ + function get100kSetForZone(i) { + var setParm = i % NUM_100K_SETS; + if (setParm == 0) + setParm = NUM_100K_SETS; + + return setParm; + } + + /** + * Get the two-letter MGRS 100k designator given information + * translated from the UTM northing, easting and zone number. + * + * @private + * @param {number} column the column index as it relates to the MGRS + * 100k set spreadsheet, created from the UTM easting. + * Values are 1-8. + * @param {number} row the row index as it relates to the MGRS 100k set + * spreadsheet, created from the UTM northing value. Values + * are from 0-19. + * @param {number} parm the set block, as it relates to the MGRS 100k set + * spreadsheet, created from the UTM zone. Values are from + * 1-60. + * @return two letter MGRS 100k code. + */ + function getLetter100kID(column, row, parm) { + // colOrigin and rowOrigin are the letters at the origin of the set + var index = parm-1; + var colOrigin = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(index); + var rowOrigin = SET_ORIGIN_ROW_LETTERS.charCodeAt(index); + + // colInt and rowInt are the letters to build to return + var colInt = colOrigin + column - 1; + var rowInt = rowOrigin + row; + var rollover = false; + + if ( colInt > Z ) { + colInt = colInt - Z + A - 1; + rollover = true; + } + + if (colInt == I || (colOrigin < I && colInt > I) + || ((colInt > I || colOrigin < I) && rollover)) { + colInt++; + } + + if (colInt == O || (colOrigin < O && colInt > O) + || ((colInt > O || colOrigin < O) && rollover)) { + colInt++; + + if (colInt == I) { + colInt++; + } + } + + if (colInt > Z) { + colInt = colInt - Z + A - 1; + } + + if (rowInt > V) { + rowInt = rowInt - V + A - 1; + rollover = true; + } else { + rollover = false; + } + + if( ((rowInt == I) || ((rowOrigin < I) && (rowInt > I))) + || (((rowInt > I)||(rowOrigin < I)) && rollover)) { + rowInt++; + } + + if( ((rowInt == O) || ((rowOrigin < O) && (rowInt > O))) + || (((rowInt > O)|| (rowOrigin < O)) && rollover)) { + rowInt++; + + if (rowInt == I) { + rowInt++; + } + } + + if (rowInt > V) { + rowInt = rowInt - V + A - 1; + } + + var twoLetter = String.fromCharCode(colInt) + String.fromCharCode(rowInt); + return twoLetter; + } + + /** + * Decode the UTM parameters from a MGRS string. + * + * @private + * @param {string} mgrsString an UPPERCASE coordinate string is expected. + * @return {object} An object literal with easting, northing, zoneLetter, + * zoneNumber and accuracy (in meters) properties. + */ + function decode(mgrsString) { + + if (mgrsString == null || mgrsString.length == 0) { + throw("MGRSPoint coverting from nothing"); + } + + var length = mgrsString.length; + + var hunK = null; + var sb = ""; + var testChar; + var i = 0; + + // get Zone number + while (!(/[A-Z]/).test(testChar = mgrsString.charAt(i))) { + if (i >= 2) { + throw("MGRSPoint bad conversion from: " + + mgrsString); + } + sb += testChar; + i++; + } + + var zoneNumber = parseInt(sb, 10); + + if (i == 0 || i + 3 > length) { + // A good MGRS string has to be 4-5 digits long, + // ##AAA/#AAA at least. + throw("MGRSPoint bad conversion from: " + + mgrsString); + } + + var zoneLetter = mgrsString.charAt(i++); + + // Should we check the zone letter here? Why not. + if (zoneLetter <= 'A' || zoneLetter == 'B' || zoneLetter == 'Y' + || zoneLetter >= 'Z' || zoneLetter == 'I' + || zoneLetter == 'O') { + throw("MGRSPoint zone letter " + + zoneLetter + " not handled: " + mgrsString); + } + + hunK = mgrsString.substring(i, i += 2); + + var set = get100kSetForZone(zoneNumber); + + var east100k = getEastingFromChar(hunK.charAt(0), set); + var north100k = getNorthingFromChar(hunK.charAt(1), set); + + // We have a bug where the northing may be 2000000 too low. + // How + // do we know when to roll over? + + while (north100k < getMinNorthing(zoneLetter)) { + north100k += 2000000; + } + + // calculate the char index for easting/northing separator + var remainder = length - i; + + if (remainder % 2 != 0) { + throw("MGRSPoint has to have an even number \nof digits after the zone letter and two 100km letters - front \nhalf for easting meters, second half for \nnorthing meters" + + mgrsString); + } + + var sep = remainder / 2; + + var sepEasting = 0.0; + var sepNorthing = 0.0; + + if (sep > 0) { + var accuracyBonus = 100000.0 / Math.pow(10, sep); + var sepEastingString = mgrsString.substring(i, i + sep); + sepEasting = parseFloat(sepEastingString) * accuracyBonus; + var sepNorthingString = mgrsString.substring(i + sep); + sepNorthing = parseFloat(sepNorthingString) * accuracyBonus; + } + + easting = sepEasting + east100k; + northing = sepNorthing + north100k; + + return { + easting: easting, + northing: northing, + zoneLetter: zoneLetter, + zoneNumber: zoneNumber, + accuracy: accuracyBonus + }; + } + + /** + * Given the first letter from a two-letter MGRS 100k zone, and given the + * MGRS table set for the zone number, figure out the easting value that + * should be added to the other, secondary easting value. + * + * @private + * @param {char} e The first letter from a two-letter MGRS 100´k zone. + * @param {number} set The MGRS table set for the zone number. + * @return {number} The easting value for the given letter and set. + */ + function getEastingFromChar(e, set) { + // colOrigin is the letter at the origin of the set for the + // column + var curCol = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(set - 1); + var eastingValue = 100000.0; + var rewindMarker = false; + + while (curCol != e.charCodeAt(0)) { + curCol++; + if (curCol == I) + curCol++; + if (curCol == O) + curCol++; + if (curCol > Z) { + if (rewindMarker) { + throw("Bad character: " + e); + } + curCol = A; + rewindMarker = true; + } + eastingValue += 100000.0; + } + + return eastingValue; + } + + /** + * Given the second letter from a two-letter MGRS 100k zone, and given the + * MGRS table set for the zone number, figure out the northing value that + * should be added to the other, secondary northing value. You have to + * remember that Northings are determined from the equator, and the vertical + * cycle of letters mean a 2000000 additional northing meters. This happens + * approx. every 18 degrees of latitude. This method does *NOT* count any + * additional northings. You have to figure out how many 2000000 meters need + * to be added for the zone letter of the MGRS coordinate. + * + * @private + * @param {char} n Second letter of the MGRS 100k zone + * @param {number} set The MGRS table set number, which is dependent on the + * UTM zone number. + * @return {number} The northing value for the given letter and set. + */ + function getNorthingFromChar(n, set) { + + if (n > 'V') { + throw("MGRSPoint given invalid Northing " + + n); + } + + // rowOrigin is the letter at the origin of the set for the + // column + var curRow = SET_ORIGIN_ROW_LETTERS.charCodeAt(set - 1); + var northingValue = 0.0; + var rewindMarker = false; + + while (curRow != n.charCodeAt(0)) { + curRow++; + if (curRow == I) + curRow++; + if (curRow == O) + curRow++; + // fixing a bug making whole application hang in this loop + // when 'n' is a wrong character + if (curRow > V) { + if (rewindMarker) { // making sure that this loop ends + throw("Bad character: " + n); + } + curRow = A; + rewindMarker = true; + } + northingValue += 100000.0; + } + + return northingValue; + } + + /** + * The function getMinNorthing returns the minimum northing value of a MGRS + * zone. + * + * Ported from Geotrans' c Lattitude_Band_Value structure table. + * + * @private + * @param {char} zoneLetter The MGRS zone to get the min northing for. + * @return {number} + */ + function getMinNorthing(zoneLetter) { + var northing; + switch (zoneLetter) { + case 'C': + northing = 1100000.0; + break; + case 'D': + northing = 2000000.0; + break; + case 'E': + northing = 2800000.0; + break; + case 'F': + northing = 3700000.0; + break; + case 'G': + northing = 4600000.0; + break; + case 'H': + northing = 5500000.0; + break; + case 'J': + northing = 6400000.0; + break; + case 'K': + northing = 7300000.0; + break; + case 'L': + northing = 8200000.0; + break; + case 'M': + northing = 9100000.0; + break; + case 'N': + northing = 0.0; + break; + case 'P': + northing = 800000.0; + break; + case 'Q': + northing = 1700000.0; + break; + case 'R': + northing = 2600000.0; + break; + case 'S': + northing = 3500000.0; + break; + case 'T': + northing = 4400000.0; + break; + case 'U': + northing = 5300000.0; + break; + case 'V': + northing = 6200000.0; + break; + case 'W': + northing = 7000000.0; + break; + case 'X': + northing = 7900000.0; + break; + default: + northing = -1.0; + } + if (northing >= 0.0) { + return northing; + } else { + throw("Invalid zone letter: " + + zoneLetter); + } + + } + + return { + forward: forward, + inverse: inverse + }; + +})(); + +if (window.Proj4js && Proj4js.Point) { + + /** + * Creates a Proj4js.Point instance from a MGRS reference. The point will + * reference the center of the MGRS reference, and coordinates will be in + * WGS84 longitude and latitude. + * + * Only available if Proj4js is loaded. + * + * @param mgrs {string} MGRS reference + */ + Proj4js.Point.fromMGRS = function(mgrs) { + var llbbox = Proj4js.util.MGRS.inverse(mgrs); + return new Proj4js.Point( + (llbbox[2] + llbbox[0]) / 2, + (llbbox[3] + llbbox[1]) / 2 + ); + }; + + /** + * Converts a Proj4js.Point instance to a MGRS reference. The point + * coordinates are expected to be in WGS84 longitude and latitude. + * + * Only available if Proj4js is loaded. + * + * @param accuracy {int} The accuracy for the MGRS reference in digits (5 + * for 1 m, 4 for 10 m, 3 for 100 m, 4 for 1000 m or 5 for 10000 m) + */ + Proj4js.Point.prototype.toMGRS = function(accuracy) { + return Proj4js.util.MGRS.forward({lon: this.x, lat: this.y}, accuracy); + }; + +} diff --git a/ajax/libs/proj4js/package.json b/ajax/libs/proj4js/package.json new file mode 100755 index 000000000..138c9b583 --- /dev/null +++ b/ajax/libs/proj4js/package.json @@ -0,0 +1,16 @@ +{ + "name": "proj4js", + "filename": "proj4js-compressed.js", + "version": "1.1.0", + "description": "Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations.", + "homepage": "http://trac.osgeo.org/proj4js/", + "keywords": [ + "projection" + ], + "repositories": [ + { + "type": "svn", + "url": "http://svn.osgeo.org/metacrs/proj4js/trunk/" + } + ] +}