/*
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 <script> tag or Proj4js can load CS initialization
* strings from a local directory or a web service such as spatialreference.org.
*
* Similarly, Proj4js must have access to projection transform code. These can
* be included individually using a <script> tag in your page, built into a
* custom build of Proj4js or loaded dynamically at run-time. Using the
* -combined and -compressed versions of Proj4js includes all projection class
* code by default.
*
* Note that dynamic loading of defs and code happens ascynchrously, check the
* Proj.readyToUse flag before using the Proj object. If the defs and code
* required by your application are loaded through script tags, dynamic loading
* is not required and the Proj object will be readyToUse on return from the
* constructor.
*
* All coordinates are handled as points which have a .x and a .y property
* which will be modified in place.
*
* Override Proj4js.reportError for output of alerts and warnings.
*
* See http://trac.osgeo.org/proj4js/wiki/UserGuide for full details.
*/
/**
* Global namespace object for Proj4js library
*/
var Proj4js = {
/**
* Property: defaultDatum
* The datum to use when no others a specified
*/
defaultDatum: 'WGS84', //default datum
/**
* Method: transform(source, dest, point)
* Transform a point coordinate from one map projection to another. This is
* really the only public method you should need to use.
*
* Parameters:
* source - {Proj4js.Proj} source map projection for the transformation
* dest - {Proj4js.Proj} destination map projection for the transformation
* point - {Object} point to transform, may be geodetic (long, lat) or
* projected Cartesian (x,y), but should always have x,y properties.
*/
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;
}
// Workaround for datum shifts towgs84, if either source or destination projection is not wgs84
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;
}
// DGR, 2010/11/12
if (source.axis!="enu") {
this.adjust_axis(source,false,point);
}
// Transform source points to long/lat, if they aren't already.
if ( source.projName=="longlat") {
point.x *= Proj4js.common.D2R; // convert degrees to radians
point.y *= Proj4js.common.D2R;
} else {
if (source.to_meter) {
point.x *= source.to_meter;
point.y *= source.to_meter;
}
source.inverse(point); // Convert Cartesian to longlat
}
// Adjust for the prime meridian if necessary
if (source.from_greenwich) {
point.x += source.from_greenwich;
}
// Convert datums if needed, and if possible.
point = this.datum_transform( source.datum, dest.datum, point );
// Adjust for the prime meridian if necessary
if (dest.from_greenwich) {
point.x -= dest.from_greenwich;
}
if( dest.projName=="longlat" ) {
// convert radians to decimal degrees
point.x *= Proj4js.common.R2D;
point.y *= Proj4js.common.R2D;
} else { // else project
dest.forward(point);
if (dest.to_meter) {
point.x /= dest.to_meter;
point.y /= dest.to_meter;
}
}
// DGR, 2010/11/12
if (dest.axis!="enu") {
this.adjust_axis(dest,true,point);
}
return point;
}, // transform()
/** datum_transform()
source coordinate system definition,
destination coordinate system definition,
point to transform in geodetic coordinates (long, lat, height)
*/
datum_transform : function( source, dest, point ) {
// Short cut if the datums are identical.
if( source.compare_datums( dest ) ) {
return point; // in this case, zero is sucess,
// whereas cs_compare_datums returns 1 to indicate TRUE
// confusing, should fix this
}
// Explicitly skip datum transform by setting 'datum=none' as parameter for either source or dest
if( source.datum_type == Proj4js.common.PJD_NODATUM
|| dest.datum_type == Proj4js.common.PJD_NODATUM) {
return point;
}
// Do we need to go through geocentric coordinates?
if( source.es != dest.es || source.a != dest.a
|| source.datum_type == Proj4js.common.PJD_3PARAM
|| source.datum_type == Proj4js.common.PJD_7PARAM