├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE.txt ├── README.md ├── appveyor.yml ├── lib ├── constants.js ├── index.js ├── parse.js └── srs.js ├── package.json └── test ├── data ├── 27700_esri_wkt.prj ├── 27700_ogc_wkt.prj ├── 3395-non-spherical-merc.prj ├── 3857-ogr-1.10.0-wkt.prj ├── 4326.esri.prj ├── 4326.prj ├── 900913.esri.prj ├── admin-0-poly.prj ├── bogus_mercator2sp.prj ├── cali.prj ├── esri-mercator-1sp.prj ├── esri_webmerc.prj ├── esri_webmerc_auxshpere.prj ├── esri_webmerc_auxshpere2.prj ├── maryland.prj ├── mystery-api ├── osm_landusages.prj ├── prj2epsg-wkt-3857.prj ├── simplified-land-polygons-complete-3857.prj ├── sr-org-6-esriwkt.prj ├── sr-org-6-ogcwkt.prj ├── test.json ├── transverse_merc_kasey.prj ├── transverse_merc_kasey_custom_grids.prj ├── world_borders_merc.prj ├── world_extent_merc.geojson └── world_extent_wgs84.geojson ├── esri_variant.test.js ├── geojson.test.js ├── invalid.test.js ├── qgis-qpj.test.js ├── shapefile.27700.test.js ├── shapefile.3857.test.js ├── shapefile.4326.test.js ├── split_proj.js ├── util.js └── version.test.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | os: 4 | - linux 5 | - osx 6 | 7 | node_js: 8 | - "0.10" 9 | - "4" 10 | - "5" 11 | - "6" 12 | 13 | addons: 14 | apt: 15 | sources: 16 | - ubuntu-toolchain-r-test 17 | packages: 18 | - libstdc++6 # upgrade libstdc++ on linux to support C++11 19 | 20 | sudo: false 21 | 22 | install: 23 | - npm install --fallback-to-build=false 24 | 25 | script: 26 | - npm test -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # changelog 2 | 3 | ## 1.2.0 4 | 5 | - Upgraded to node-gdal@0.9.x 6 | - Test on OSX 7 | - Test with Node.js v4, v5, v6 8 | 9 | ## 1.1.0 10 | 11 | - Upgraded to node-gdal@0.8.0 12 | 13 | ## 1.0.1 14 | 15 | - Removed some unnecessary data from package 16 | 17 | ## 1.0.0 18 | 19 | - Re-implemented as a JS module on top of node-gdal. 20 | 21 | ## 0.4.9 22 | 23 | - Upgraded to gdal 2.0 24 | - Now building against libc++ on osx 25 | - Now providing binaries against Visual Studio 2015 (pass --toolset=v140) and use binaries from https://github.com/mapbox/node-cpp11 26 | 27 | 28 | ## 0.4.8 29 | 30 | - Upgraded to nan@1.8.4 31 | - Upgraded to node-pre-gyp@0.6.7 32 | 33 | 0.4.7 34 | 35 | - Added support (and pre-build binaries) for io.js 1.2.x and node v0.12.x 36 | - Upgraded to nan@1.7.0 37 | - Upgraded to node-pre-gyp@0.6.4 38 | 39 | 0.4.6 40 | 41 | - Removed getenv workaround for Visual Studio 2013 42 | 43 | ## 0.4.5 44 | 45 | - Upgraded bundled node-pre-gyp 46 | 47 | ## 0.4.4 48 | 49 | - Upgraded to GDAL 1.11.1 50 | - Stopped providing binaries for node v0.8.x 51 | - Now providing binaries against Visual Studio 2014 (pass --toolset=v140) and use binaries from https://github.com/mapbox/node-cpp11 52 | 53 | ## 0.4.3 54 | 55 | - No changes: just re-published to try to avoid npm shasum error upon download 56 | 57 | ## 0.4.2 58 | 59 | - Now supporting node v0.11.x 60 | 61 | ## 0.4.1 62 | 63 | - Now shipping binaries for OS X, Windows, and Ubuntu Linux 64 | 65 | ## 0.4.0 66 | 67 | - Now builds on FreeBSD 68 | - `srs.jsonCrs` added for detecting projection inside JSON object representing GeoJSON. Pass the result to `srs.parse` 69 | - `srs.parse` no longer supports being passed a filepath to a GeoJSON. 70 | 71 | ## 0.3.12 72 | 73 | - Fixed generation of valid `srs_settings.js` on windows (#39) 74 | - Fixed detection of some ESRI variant projections (#38) 75 | - Added preliminary appveyor.yml for continuous builds on windows 76 | 77 | ## 0.3.11 78 | 79 | - Removed binary stripping on OS X which may cause link problems on mavericks 80 | - Move to Mapbox organization 81 | 82 | ## 0.3.10 83 | 84 | - Improved support for topojson 85 | 86 | ## 0.3.9 87 | 88 | - `--runtime_link` option fixed to only apply when `--shared_gdal` is passed. 89 | 90 | ## 0.3.8 91 | 92 | - Build fixes for windows 93 | 94 | ## 0.3.7 95 | 96 | - Build fix for python3 (#33) 97 | 98 | ## 0.3.6 99 | 100 | - Build fixes to avoid possible undefined symbol errors are runtime on ubuntu linux 101 | - Additional travis.ci testing of 32bit builds 102 | 103 | ## 0.3.5 104 | 105 | - Minor test fixes to work with variable external gdal versions 106 | 107 | ## 0.3.4 108 | 109 | - Changed name of build option to configure against shared gdal lib. Now pass `npm install --shared_gdal` (to be consistent with older node-srs). 110 | 111 | ## 0.3.3 112 | 113 | - Now building against internal `osr` again by default. Pass `npm install --gdal=shared` to build against systemwide GDAL (#30) 114 | - Now forcing canonical wgs84/epsg:4326 represenation 115 | - Now translating `+init` syntax to `+proj` for known projections (epsg:4326 and epsg:3857) 116 | - Various fixes to detect more projections 117 | 118 | ## 0.3.2 119 | 120 | - Re-enabled optional linking with `gdal-config --dep-libs` by passing `npm install --runtime_link=static` 121 | 122 | ## 0.3.1 123 | 124 | - Removed build linking to gdal libs / gdal-config --dep-libs, now only linking to libgdal itself by default 125 | 126 | ## 0.3.0 127 | 128 | - Now using node-gyp for build 129 | - Now requiring Node >= 0.6.13 (for node-gyp support) 130 | - Node v0.10.x support 131 | - Now requiring external libgdal 132 | - Better detection of more spherical mercator variants 133 | - Better detection of +init=epsg based mercator srs and auto-transformation to +proj syntax 134 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011, Dane Springmeyer 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following 12 | disclaimer in the documentation and/or other materials provided 13 | with the distribution. 14 | * Neither the name of the author nor the names of other 15 | contributors may be used to endorse or promote products derived 16 | from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | This project also includes code and files from GDAL, see GDAL_LICENSE 32 | for more details. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Node-Srs 2 | 3 | Linux: [![Build Status](https://secure.travis-ci.org/mapbox/node-srs.svg)](http://travis-ci.org/mapbox/node-srs) 4 | 5 | Windows: [![Build status](https://ci.appveyor.com/api/projects/status/ff1n3h7h506i4vx0)](https://ci.appveyor.com/project/Mapbox/node-srs) 6 | 7 | This module tries to detect projections, also known as "spatial reference systems". It works similiarly to [gdalsrsinfo](http://www.gdal.org/gdalsrsinfo.html). 8 | 9 | `node-srs` supports parsing a variety of textual representations of projections, like the formats known as `OGC WKT`, `ESRI WKT`, `OGC CRS URN`, or `proj4`. It supports [shapefiles](http://en.wikipedia.org/wiki/Shapefile) and [GeoJSON](http://geojson.org/). Shapefiles optionally come with a separate .prj and inside the `.prj` the text is usually in the `ESRI WKT` format. GeoJSON optionally contains a `crs` property that declares projection as `OGC CRS URN`. 10 | 11 | Detecting projections is important for applications like TileMill, which - through Mapnik - needs the `proj4` representation of a projection to create coordinate transformations for re-projecting vector or raster data on the fly. 12 | 13 | `node-srs` includes a variety of hacks to determine if your projection looks like `web mercator` (epsg:3857) or `wgs84` (epsg:4326) and if so returns the canonical representations of these projections (according to @springmeyer). This ensures applications like TileMill can avoid unneeded projection. It is common for data out in the wild in web mercator projection to store slightly different projection strings based on the software that created the files. `node-srs` ensures a consistent final `proj4` representation is returned for all of the variety of representations of web mercator. This is critical because even mercator to mercator transformations are expensive if proj4 is asked to do this for large datasets. 14 | 15 | `node-srs` does not support looking for, or detecting, projection information in formats like GeoTIFF, PostGIS, or SQLite. Rather for those formats you would need to extract the projection information yourself and then pass it to `node-srs`. 16 | 17 | ## API 18 | 19 | ### `srs.parse(string)` 20 | 21 | Parse a string of projection specification data and return an object describing 22 | the detected projection. If the SRS cannot be parsed, throws a `TypeError` 23 | describing the issue. 24 | 25 | ## Example 26 | 27 | Detect a proj4 literal string as spherical mercator: 28 | 29 | ```js 30 | > var srs = require('srs'); 31 | > srs.parse('+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 +wktext +no_defs') 32 | { proj4: '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over', 33 | srid: 3857, 34 | auth: 'EPSG', 35 | pretty_wkt: 'PROJCS["WGS 84 / Pseudo-Mercator",\n GEOGCS["WGS 84",\n DATUM["WGS_1984",\n SPHEROID["WGS 84",6378137,298.257223563,\n AUTHORITY["EPSG","7030"]],\n AUTHORITY["EPSG","6326"]],\n PRIMEM["Greenwich",0,\n AUTHORITY["EPSG","8901"]],\n UNIT["degree",0.0174532925199433,\n AUTHORITY["EPSG","9122"]],\n AUTHORITY["EPSG","4326"]],\n UNIT["metre",1,\n AUTHORITY["EPSG","9001"]],\n PROJECTION["Mercator_1SP"],\n PARAMETER["central_meridian",0],\n PARAMETER["scale_factor",1],\n PARAMETER["false_easting",0],\n PARAMETER["false_northing",0],\n EXTENSION["PROJ4","+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 +wktext +no_defs"],\n AUTHORITY["EPSG","3857"],\n AXIS["X",EAST],\n AXIS["Y",NORTH]]', 36 | esri: false, 37 | name: 'Google Maps Global Mercator', 38 | valid: true, 39 | is_geographic: false, 40 | input: '+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 +wktext +no_defs' } 41 | ``` 42 | 43 | Detect a WKT string as WGS84: 44 | 45 | ```js 46 | > srs.parse('GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]') 47 | { input: 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]', 48 | proj4: '+proj=longlat +ellps=WGS84 +no_defs', 49 | srid: 4326, 50 | auth: 'EPSG', 51 | pretty_wkt: 'GEOGCS["GCS_WGS_1984",\n DATUM["D_WGS_1984",\n SPHEROID["WGS_1984",6378137,298.257223563]],\n PRIMEM["Greenwich",0],\n UNIT["Degree",0.017453292519943295],\n AUTHORITY["EPSG","4326"]]', 52 | esri: false, 53 | name: 'GCS_WGS_1984', 54 | valid: true, 55 | is_geographic: true } 56 | ``` 57 | 58 | ## Installation 59 | 60 | npm install 61 | 62 | ## Test 63 | 64 | npm test 65 | 66 | ## License 67 | 68 | BSD, see LICENSE.txt 69 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - nodejs_version: 0.10 4 | - nodejs_version: 0.12 5 | - nodejs_version: 4 6 | - nodejs_version: 5 7 | - nodejs_version: 6 8 | 9 | platform: 10 | - x64 11 | - x86 12 | 13 | install: 14 | - npm install 15 | - npm test 16 | 17 | build: OFF 18 | test: OFF 19 | deploy: OFF 20 | -------------------------------------------------------------------------------- /lib/constants.js: -------------------------------------------------------------------------------- 1 | /* 2 | This is a custom srs definition for 3 | spherical mercator that we make 4 | canonical because no single variant 5 | of the projection stored by various 6 | applications is optimal. 7 | 8 | This is basically a modification of gdal's 9 | understanding of epsg 3857 10 | 11 | Changes: 12 | 13 | * add +over and +wktext to proj4 string 14 | * remove any double spaces in proj4 string 15 | * epsg is 3857, the new official epsg for 900913 16 | * name is pulled from gdal/data/cubwerx_extra.wkt for 900913 17 | instead of using 'WGS 84 / Pseudo-Mercator' or 'Popular...' 18 | 19 | TODO: 20 | * +x_0=0.0 vs +x_0=0 (same with +y_0) 21 | * handle two scaling aliases +k and +k_0 22 | * meaning of +k=1. vs +k=1.0 ? 23 | 24 | */ 25 | var merc_pretty_wkt = 'PROJCS["WGS 84 / Pseudo-Mercator",\n GEOGCS["WGS 84",\n DATUM["WGS_1984",\n SPHEROID["WGS 84",6378137,298.257223563,\n AUTHORITY["EPSG","7030"]],\n AUTHORITY["EPSG","6326"]],\n PRIMEM["Greenwich",0,\n AUTHORITY["EPSG","8901"]],\n UNIT["degree",0.0174532925199433,\n AUTHORITY["EPSG","9122"]],\n AUTHORITY["EPSG","4326"]],\n UNIT["metre",1,\n AUTHORITY["EPSG","9001"]],\n PROJECTION["Mercator_1SP"],\n PARAMETER["central_meridian",0],\n PARAMETER["scale_factor",1],\n PARAMETER["false_easting",0],\n PARAMETER["false_northing",0],\n EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over"],\n AUTHORITY["EPSG","3857"],\n AXIS["X",EAST],\n AXIS["Y",NORTH]]'; 26 | 27 | var lon_lat_pretty_wkt = 'GEOGCS["WGS 84",\n DATUM["WGS_1984",\n SPHEROID["WGS 84",6378137,298.257223563,\n AUTHORITY["EPSG","7030"]],\n TOWGS84[0,0,0,0,0,0,0],\n AUTHORITY["EPSG","6326"]],\n PRIMEM["Greenwich",0,\n AUTHORITY["EPSG","8901"]],\n UNIT["degree",0.0174532925199433,\n AUTHORITY["EPSG","9108"]],\n AUTHORITY["EPSG","4326"]]'; 28 | 29 | module.exports.merc_names = [ 30 | 'Google_Maps_Global_Mercator', 31 | 'Google Maps Global Mercator', 32 | 'WGS 84 / Pseudo-Mercator', // 3857 33 | 'WGS_84_Pseudo_Mercator', // 3857 with new gdal/ogr name as per https://github.com/mapbox/node-srs/issues/27 34 | 'Popular Visualisation CRS / Mercator', // 3785 35 | 'WGS_1984_Web_Mercator', // ESRI 36 | 'WGS_1984_Web_Mercator_Auxiliary_Sphere', // ESRI 37 | 'Popular_Visualisation_CRS_Mercator_deprecated', // wtf 38 | 'Mercator_1SP', 39 | 'Mercator_2SP' 40 | ]; 41 | 42 | module.exports.merc_srids = [ 43 | 900913, // http://crschmidt.net/blog/archives/243/google-projection-900913/ 44 | 3857, // epsg official, second try 45 | 3785, // epsg deprecated, failed first try 46 | 102100, // esri official, second try 47 | 102113, // esri deprecated, failed first try 48 | 41001 //osgeo 49 | ]; 50 | 51 | // commonly confused as spherical mercator, but not, right? 52 | // here only for reference currently, nothing done programmatically 53 | module.exports.other_merc_srids = [ 54 | 3395, // "WGS 84 / World Mercator" or normal, no googlized mercator: lacked +a=6378137 +b=6378137 55 | 3587, // common typo but actually NAD83(NSRS2007) / Michigan Central 56 | // for these see also notes in shapefile.3857.test.js 57 | 9804, // older, esri style-named traditional merc: http://www.remotesensing.org/geotiff/proj_list/mercator_1sp.html 58 | 9805, // older, esri style-named traditional merc: http://www.remotesensing.org/geotiff/proj_list/mercator_2sp.html 59 | ]; 60 | 61 | module.exports.known_esri_variant_special_cases = [ 62 | ['DATUM["D_OSGB_1936"','DATUM["OSGB_1936"'] 63 | ]; 64 | 65 | module.exports.canonical = { 66 | spherical_mercator: { 67 | proj4: '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over', 68 | srid: 3857, // or 900913 69 | auth: 'EPSG', 70 | pretty_wkt: merc_pretty_wkt, 71 | esri: false, 72 | name: 'Google Maps Global Mercator', // so many variants here 73 | valid: true, 74 | is_geographic: false 75 | }, 76 | wgs84: { 77 | proj4: '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs', 78 | srid: 4326, 79 | auth: 'EPSG', 80 | pretty_wkt: lon_lat_pretty_wkt, 81 | esri: false, 82 | name: 'WGS 84', 83 | valid: true, 84 | is_geographic: true 85 | } 86 | }; 87 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./srs'); 2 | -------------------------------------------------------------------------------- /lib/parse.js: -------------------------------------------------------------------------------- 1 | var gdal = require('gdal'); 2 | 3 | module.exports = function(str){ 4 | var srs, auth, name, code; 5 | var result = { 6 | input: str, 7 | name: undefined, 8 | proj4: undefined, 9 | srid: undefined, 10 | auth: undefined, 11 | pretty_wkt: undefined, 12 | esri: undefined 13 | }; 14 | 15 | try { 16 | srs = gdal.SpatialReference.fromUserInput(str); 17 | result.esri = str.indexOf('ESRI::') == 0; 18 | } catch (err) { 19 | srs = gdal.SpatialReference.fromESRI(str.split(/[ \t\n]/)); 20 | result.esri = true; 21 | } 22 | 23 | result.valid = srs.validate() === null; 24 | 25 | try { 26 | result.proj4 = srs.toProj4(); 27 | } catch (err) {} 28 | try { 29 | srs.autoIdentifyEPSG(); 30 | } catch (err) {} 31 | 32 | if(!srs.isProjected()) { 33 | result.is_geographic = true; 34 | if(code = srs.getAuthorityCode('GEOGCS')) { 35 | result.srid = parseInt(code); 36 | } 37 | if(auth = srs.getAuthorityName('GEOGCS')) { 38 | result.auth = auth; 39 | } 40 | if(name = srs.getAttrValue('GEOGCS')) { 41 | result.name = name; 42 | } 43 | } else { 44 | result.is_geographic = false; 45 | if(code = srs.getAuthorityCode('PROJCS')) { 46 | result.srid = parseInt(code); 47 | } 48 | if(auth = srs.getAuthorityName('PROJCS')) { 49 | result.auth = auth; 50 | } 51 | if(name = srs.getAttrValue('PROJCS')) { 52 | result.name = name; 53 | } 54 | } 55 | 56 | try { 57 | result.pretty_wkt = srs.toPrettyWKT(); 58 | } catch(err) {} 59 | 60 | return result; 61 | } -------------------------------------------------------------------------------- /lib/srs.js: -------------------------------------------------------------------------------- 1 | var exists = require('fs').existsSync || require('path').existsSync; 2 | var path = require('path'); 3 | 4 | var constants = require('./constants'); 5 | var _parse = require('./parse'); 6 | var canonical = constants.canonical; 7 | 8 | var canonical_parts = split_proj(canonical.spherical_mercator.proj4); 9 | var canonical_stringify = JSON.stringify(canonical_parts); 10 | 11 | var srs = module.exports = exports; 12 | 13 | srs.version = require('../package').version; 14 | 15 | 16 | function split_proj(literal) { 17 | var parts = literal.split(' '); 18 | // remove blank parts due to double spaces (common in proj epsg table) 19 | var len = parts.length; 20 | for (i = 0; i < len; i++) { 21 | if (parts[i] === '') { 22 | parts.splice(i, 1); 23 | } 24 | } 25 | // break into key=value pairs, discarding +modifiers without values 26 | var pairs = {}; 27 | parts.sort(); 28 | var new_len = parts.length; 29 | for (i = 0; i < new_len; i++) { 30 | var p = parts[i]; 31 | if (p.indexOf('=') != -1) { 32 | var pair = p.split('='); 33 | if (pair[1] && pair[1] === '0') { 34 | // https://github.com/mapbox/tilemill/issues/1866 35 | pair[1] = '0.0'; 36 | } 37 | pairs[pair[0]] = pair[1]; 38 | } 39 | } 40 | return pairs; 41 | } 42 | 43 | function parse(arg) { 44 | if (arg instanceof Buffer) { 45 | arg = arg.toString(); 46 | } 47 | 48 | // early check for known +init=epsg: syntax, which we will 49 | // translate to +proj literal to avoid requiring proj4 to do that in mapnik 50 | var arg_lower = arg.toLowerCase(); 51 | if (arg_lower.indexOf('+init=') > -1) { 52 | var parts = arg_lower.split(':'); 53 | if (parts[1]) { 54 | var code = +parts[1]; 55 | if (constants.merc_srids.indexOf(code) > -1) { 56 | return force_merc({input:arg}); 57 | } 58 | if (code === 4326) { 59 | return force_wgs84({input:arg}); 60 | } 61 | } 62 | } 63 | 64 | for (var hack in constants.known_esri_variant_special_cases) { 65 | var obj = constants.known_esri_variant_special_cases[hack]; 66 | if (arg.indexOf(obj[0]) > -1) { 67 | arg = arg.replace(obj[0],obj[1]); 68 | } 69 | } 70 | 71 | var result; 72 | var esri_try = false; 73 | try { 74 | result = _parse(arg); 75 | } catch (err) { 76 | if (arg.indexOf('ESRI::') !== 0) { 77 | try { 78 | esri_try = true; 79 | result = _parse('ESRI::' + arg); 80 | } catch (esri_err) { 81 | throw err; // throw original error 82 | } 83 | } else { 84 | throw err; 85 | } 86 | } 87 | 88 | // if the first parse succeeded without throwing 89 | // but still failed to detect the proj4 string then 90 | // we need to try harder and assume an ESRI variant 91 | if (result.proj4 === undefined && 92 | esri_try === false && 93 | arg.indexOf('ESRI::') !== 0) { 94 | try { 95 | var esri_result = _parse('ESRI::' + arg); 96 | // success detecting proj4 as ESRI variant? 97 | if (esri_result.proj4) { 98 | result = esri_result; 99 | } 100 | } catch (err) { 101 | // pass 102 | } 103 | } 104 | 105 | // force wgs84 variants to canonical 106 | if (result.srid === 4326) { 107 | return force_wgs84(result); 108 | } 109 | // detect mercator variants and 110 | // replace with canonical.spherical_mercator 111 | if (result.name in oc(constants.merc_names)) { 112 | // this should be a fast track for many .prj files 113 | return force_merc(result); 114 | } else if (result.srid in oc(constants.merc_srids)) { 115 | return force_merc(result); 116 | } else if (result.proj4 !== undefined && result.proj4.indexOf('+proj=merc') != -1) { 117 | // catch case of gdal's translation to proj4 being used as input 118 | if (result.proj4 === '+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +ellps=WGS84 +units=m +no_defs') { 119 | return force_merc(result); 120 | } else if (result.proj4 === '+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +a=6378137 +b=6378137 +units=m +no_defs') { 121 | return force_merc(result); 122 | } 123 | // break into parts 124 | // TODO - sort and remove less critical pairs 125 | var parts = split_proj(result.proj4); 126 | if (JSON.stringify(parts) === canonical_stringify) { 127 | return force_merc(result); 128 | } 129 | } 130 | 131 | // detect OSGB variant and fix the srid 132 | // https://github.com/mapbox/node-srs/issues/25 133 | if (!result.srid && result.name == 'OSGB 1936 / British National Grid') { 134 | result.srid = 27700; 135 | result.auth = 27700; 136 | } 137 | 138 | return result; 139 | }; 140 | 141 | function jsonCrs(gj) { 142 | if (gj.crs && gj.crs.properties) { 143 | if (gj.crs.properties.urn) { 144 | return gj.crs.properties.urn; 145 | } else if (gj.crs.properties.name) { 146 | return gj.crs.properties.name; 147 | } 148 | } else { 149 | return canonical.wgs84.proj4; 150 | } 151 | } 152 | 153 | function oc(a) { 154 | var o = {}; 155 | for (var i = 0; i < a.length; i++) { 156 | o[a[i]] = ''; 157 | } 158 | return o; 159 | } 160 | 161 | function force_merc(result) { 162 | var new_srs = canonical.spherical_mercator; 163 | new_srs.input = result.input; 164 | return new_srs; 165 | } 166 | 167 | function force_wgs84(result) { 168 | var new_srs = canonical.wgs84; 169 | new_srs.input = result.input; 170 | return new_srs; 171 | } 172 | 173 | // make available objects from js 174 | srs.canonical = canonical; 175 | srs.split_proj = split_proj; 176 | srs.parse = parse; 177 | srs.jsonCrs = jsonCrs; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "srs", 3 | "version": "1.2.0", 4 | "main": "./lib/index.js", 5 | "description": "Spatial reference library for node", 6 | "keywords": [ 7 | "map", 8 | "projection", 9 | "spatialreference", 10 | "srid", 11 | "proj4", 12 | "mercator", 13 | "gdal", 14 | "ogr", 15 | "osr" 16 | ], 17 | "url": "http://github.com/mapbox/node-srs", 18 | "repository": { 19 | "type": "git", 20 | "url": "git://github.com/mapbox/node-srs.git" 21 | }, 22 | "dependencies": { 23 | "gdal": "~0.9.2" 24 | }, 25 | "author": "Dane Springmeyer ", 26 | "licenses": [ 27 | "BSD" 28 | ], 29 | "scripts": { 30 | "test": "mocha -R spec" 31 | }, 32 | "devDependencies": { 33 | "mocha": "1.x" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/data/27700_esri_wkt.prj: -------------------------------------------------------------------------------- 1 | PROJCS["OSGB 1936 / British National Grid",GEOGCS["OSGB 1936",DATUM["D_OSGB_1936",SPHEROID["Airy_1830",6377563.396,299.3249646]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",49],PARAMETER["central_meridian",-2],PARAMETER["scale_factor",0.9996012717],PARAMETER["false_easting",400000],PARAMETER["false_northing",-100000],UNIT["Meter",1]] -------------------------------------------------------------------------------- /test/data/27700_ogc_wkt.prj: -------------------------------------------------------------------------------- 1 | PROJCS["OSGB 1936 / British National Grid",GEOGCS["OSGB 1936",DATUM["OSGB_1936",SPHEROID["Airy 1830",6377563.396,299.3249646,AUTHORITY["EPSG","7001"]],AUTHORITY["EPSG","6277"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4277"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",49],PARAMETER["central_meridian",-2],PARAMETER["scale_factor",0.9996012717],PARAMETER["false_easting",400000],PARAMETER["false_northing",-100000],AUTHORITY["EPSG","27700"],AXIS["Easting",EAST],AXIS["Northing",NORTH]] -------------------------------------------------------------------------------- /test/data/3395-non-spherical-merc.prj: -------------------------------------------------------------------------------- 1 | +proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs -------------------------------------------------------------------------------- /test/data/3857-ogr-1.10.0-wkt.prj: -------------------------------------------------------------------------------- 1 | PROJCS["WGS_84_Pseudo_Mercator",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mercator"],PARAMETER["central_meridian",0],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1],PARAMETER["standard_parallel_1",0.0]] -------------------------------------------------------------------------------- /test/data/4326.esri.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] -------------------------------------------------------------------------------- /test/data/4326.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] -------------------------------------------------------------------------------- /test/data/900913.esri.prj: -------------------------------------------------------------------------------- 1 | PROJCS["Google_Maps_Global_Mercator",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mercator_2SP"],PARAMETER["standard_parallel_1",0],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",0],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1]] -------------------------------------------------------------------------------- /test/data/admin-0-poly.prj: -------------------------------------------------------------------------------- 1 | PROJCS["Mercator_2SP",GEOGCS["unnamed ellipse",DATUM["D_unknown",SPHEROID["Unknown",6378137,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mercator_2SP"],PARAMETER["standard_parallel_1",0],PARAMETER["central_meridian",0],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1]] -------------------------------------------------------------------------------- /test/data/bogus_mercator2sp.prj: -------------------------------------------------------------------------------- 1 | PROJCS["Mercator_2SP",GEOGCS["unnamed ellipse",DATUM["D_unknown",SPHEROID["Unknown",6378137,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mercator_2SP"],PARAMETER["standard_parallel_1",0],PARAMETER["central_meridian",0],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1]] -------------------------------------------------------------------------------- /test/data/cali.prj: -------------------------------------------------------------------------------- 1 | PROJCS["NAD_1983_StatePlane_California_III_FIPS_0403_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",37.06666666666667],PARAMETER["Standard_Parallel_2",38.43333333333333],PARAMETER["Latitude_Of_Origin",36.5],UNIT["Foot_US",0.3048006096012192]] -------------------------------------------------------------------------------- /test/data/esri-mercator-1sp.prj: -------------------------------------------------------------------------------- 1 | PROJCS["Mercator_1SP",GEOGCS["GCS_Geographic Coordinate System",DATUM["D_WGS_1984_MAJOR_AUXILIARY_SPHERE",SPHEROID["Sphere_Radius_6378137_m",6378137,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mercator"],PARAMETER["central_meridian",0],PARAMETER["standard_parallel_1",0],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1]] 2 | -------------------------------------------------------------------------------- /test/data/esri_webmerc.prj: -------------------------------------------------------------------------------- 1 | PROJCS["WGS_1984_Web_Mercator",GEOGCS["GCS_WGS_1984_Major_Auxiliary_Sphere",DATUM["D_WGS_1984_Major_Auxiliary_Sphere",SPHEROID["WGS_1984_Major_Auxiliary_Sphere",6378137.0,0.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",0.0],UNIT["Meter",1.0]] -------------------------------------------------------------------------------- /test/data/esri_webmerc_auxshpere.prj: -------------------------------------------------------------------------------- 1 | PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0]] -------------------------------------------------------------------------------- /test/data/esri_webmerc_auxshpere2.prj: -------------------------------------------------------------------------------- 1 | PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere", 2 | GEOGCS["GCS_WGS_1984", 3 | DATUM["D_WGS_1984", 4 | SPHEROID["WGS_1984",6378137.0,298.257223563]], 5 | PRIMEM["Greenwich",0.0], 6 | UNIT["Degree",0.0174532925199433]], 7 | PROJECTION["Mercator_Auxiliary_Sphere"], 8 | PARAMETER["False_Easting",0.0], 9 | PARAMETER["False_Northing",0.0], 10 | PARAMETER["Central_Meridian",0.0], 11 | PARAMETER["Standard_Parallel_1",0.0], 12 | PARAMETER["Auxiliary_Sphere_Type",0.0], 13 | UNIT["Meter",1.0], 14 | AUTHORITY["ESRI","102100"]] -------------------------------------------------------------------------------- /test/data/maryland.prj: -------------------------------------------------------------------------------- 1 | PROJCS["NAD_1983_StatePlane_Maryland_FIPS_1900",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",400000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-77.0],PARAMETER["Standard_Parallel_1",38.3],PARAMETER["Standard_Parallel_2",39.45],PARAMETER["Latitude_Of_Origin",37.66666666666666],UNIT["Meter",1.0]] -------------------------------------------------------------------------------- /test/data/mystery-api: -------------------------------------------------------------------------------- 1 | { 2 | "type":"Feature", 3 | "id":"OpenLayers.Feature.Vector_314", 4 | "properties":{}, 5 | "geometry":{ 6 | "type":"Point", 7 | "coordinates":[97.03125, 39.7265625] 8 | } 9 | } -------------------------------------------------------------------------------- /test/data/osm_landusages.prj: -------------------------------------------------------------------------------- 1 | PROJCS["Popular_Visualisation_CRS_Mercator_deprecated",GEOGCS["GCS_Popular Visualisation CRS",DATUM["D_Popular_Visualisation_Datum",SPHEROID["Popular_Visualisation_Sphere",6378137,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mercator"],PARAMETER["central_meridian",0],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1],PARAMETER["standard_parallel_1",0.0]] -------------------------------------------------------------------------------- /test/data/prj2epsg-wkt-3857.prj: -------------------------------------------------------------------------------- 1 | PROJCS["WGS 84 / Pseudo-Mercator", 2 | GEOGCS["WGS 84", 3 | DATUM["World Geodetic System 1984", 4 | SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], 5 | AUTHORITY["EPSG","6326"]], 6 | PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], 7 | UNIT["degree", 0.017453292519943295], 8 | AXIS["Geodetic longitude", EAST], 9 | AXIS["Geodetic latitude", NORTH], 10 | AUTHORITY["EPSG","4326"]], 11 | PROJECTION["Popular Visualisation Pseudo Mercator", AUTHORITY["EPSG","1024"]], 12 | PARAMETER["semi_minor", 6378137.0], 13 | PARAMETER["latitude_of_origin", 0.0], 14 | PARAMETER["central_meridian", 0.0], 15 | PARAMETER["scale_factor", 1.0], 16 | PARAMETER["false_easting", 0.0], 17 | PARAMETER["false_northing", 0.0], 18 | UNIT["m", 1.0], 19 | AXIS["Easting", EAST], 20 | AXIS["Northing", NORTH], 21 | AUTHORITY["EPSG","3857"]] 22 | -------------------------------------------------------------------------------- /test/data/simplified-land-polygons-complete-3857.prj: -------------------------------------------------------------------------------- 1 | PROJCS["WGS 84 / Pseudo-Mercator", 2 | GEOGCS["WGS 84", 3 | DATUM["WGS_1984", 4 | SPHEROID["WGS 84",6378137,298.257223563, 5 | AUTHORITY["EPSG","7030"]], 6 | AUTHORITY["EPSG","6326"]], 7 | PRIMEM["Greenwich",0, 8 | AUTHORITY["EPSG","8901"]], 9 | UNIT["degree",0.0174532925199433, 10 | AUTHORITY["EPSG","9122"]], 11 | AUTHORITY["EPSG","4326"]], 12 | PROJECTION["Mercator_1SP"], 13 | PARAMETER["central_meridian",0], 14 | PARAMETER["scale_factor",1], 15 | PARAMETER["false_easting",0], 16 | PARAMETER["false_northing",0], 17 | UNIT["metre",1, 18 | AUTHORITY["EPSG","9001"]], 19 | AXIS["X",EAST], 20 | AXIS["Y",NORTH], 21 | EXTENSION["PROJ4","+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 +wktext +no_defs"], 22 | AUTHORITY["EPSG","3857"]] 23 | -------------------------------------------------------------------------------- /test/data/sr-org-6-esriwkt.prj: -------------------------------------------------------------------------------- 1 | PROJCS["Mercator_2SP",GEOGCS["unnamed ellipse",DATUM["D_unknown",SPHEROID["Unknown",6378137,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mercator_2SP"],PARAMETER["standard_parallel_1",0],PARAMETER["central_meridian",0],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1],EXTENSION["PROJ4","+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 +wktext +no_defs"]] -------------------------------------------------------------------------------- /test/data/sr-org-6-ogcwkt.prj: -------------------------------------------------------------------------------- 1 | PROJCS["unnamed",GEOGCS["unnamed ellipse",DATUM["unknown",SPHEROID["unnamed",6378137,0]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Mercator_2SP"],PARAMETER["standard_parallel_1",0],PARAMETER["central_meridian",0],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1],EXTENSION["PROJ4","+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 +wktext +no_defs"]] -------------------------------------------------------------------------------- /test/data/test.json: -------------------------------------------------------------------------------- 1 | { 2 | "type":"Feature", 3 | "id":"OpenLayers.Feature.Vector_314", 4 | "properties":{}, 5 | "geometry":{ 6 | "type":"Point", 7 | "coordinates":[97.03125, 39.7265625] 8 | }, 9 | "crs":{ 10 | "type":"OGC", 11 | "properties":{ 12 | "urn":"urn:ogc:def:crs:OGC:1.3:CRS84" 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /test/data/transverse_merc_kasey.prj: -------------------------------------------------------------------------------- 1 | PROJCS["Transverse_Mercator",GEOGCS["GCS_Clarke 1866",DATUM["D_unknown",SPHEROID["clrk66",6378206.4,294.9786982]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",35.83333333333334],PARAMETER["central_meridian",-90.5],PARAMETER["scale_factor",0.9999333333333333],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Foot_US",0.30480060960121924]] -------------------------------------------------------------------------------- /test/data/transverse_merc_kasey_custom_grids.prj: -------------------------------------------------------------------------------- 1 | PROJCS["unnamed",GEOGCS["Clarke 1866",DATUM["unknown",SPHEROID["clrk66",6378206.4,294.9786982139006],EXTENSION["PROJ4_GRIDS","@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",35.83333333333334],PARAMETER["central_meridian",-90.5],PARAMETER["scale_factor",0.9999333333333333],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Foot_US",0.3048006096012192]] 2 | -------------------------------------------------------------------------------- /test/data/world_borders_merc.prj: -------------------------------------------------------------------------------- 1 | PROJCS["Mercator_2SP",GEOGCS["GCS_unnamed ellipse",DATUM["D_unknown",SPHEROID["Unknown",6378137,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mercator_2SP"],PARAMETER["standard_parallel_1",0],PARAMETER["central_meridian",0],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1]] -------------------------------------------------------------------------------- /test/data/world_extent_merc.geojson: -------------------------------------------------------------------------------- 1 | { 2 | "crs": { "type": "name", "properties": { "name": "epsg:900913" } }, 3 | "type": "FeatureCollection", 4 | "features": [ 5 | { "type": "Feature", 6 | "properties": { "FID": 0.000000 }, 7 | "geometry": 8 | { "type": "Polygon", 9 | "coordinates": [[ 10 | [-20037508.34,-20037508.34], 11 | [-20037508.34,20037508.34], 12 | [20037508.34,20037508.34], 13 | [20037508.34,-20037508.34], 14 | [-20037508.34,-20037508.34] 15 | ]] 16 | } 17 | } 18 | 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /test/data/world_extent_wgs84.geojson: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FeatureCollection", 3 | "features": [ 4 | 5 | { "type": "Feature", 6 | "properties": { "FID": 0.000000 }, 7 | "geometry": 8 | { "type": "Polygon", 9 | "coordinates": [ [ 10 | [ -180.0, -85.051129 ], 11 | [ -180.0, 85.051129 ], 12 | [ 180.0, 85.051129 ], 13 | [ 180.0, -85.051129 ], 14 | [ -180.0, -85.051129 ] 15 | ] ] 16 | } 17 | } 18 | 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /test/esri_variant.test.js: -------------------------------------------------------------------------------- 1 | var srs = require('../'); 2 | var fs = require('fs'); 3 | var assert = require('assert'); 4 | 5 | // http://spatialreference.org/ref/esri/102685/ 6 | // http://spatialreference.org/ref/sr-org/7058/ 7 | describe('maryland ESRI variant', function() { 8 | it('detects proj if parsed as ESRI::', function(done) { 9 | var ref = srs.parse(fs.readFileSync('./test/data/maryland.prj')); 10 | assert.ok(ref.proj4); 11 | assert.equal(ref.name,'NAD_1983_StatePlane_Maryland_FIPS_1900'); 12 | done(); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /test/geojson.test.js: -------------------------------------------------------------------------------- 1 | var srs = require('../'); 2 | var assert = require('assert'); 3 | var fs = require('fs'); 4 | var util = require('./util'); 5 | 6 | describe('GeoJSON', function() { 7 | it('should detect mercator', function() { 8 | var merc = srs.parse(srs.jsonCrs(JSON.parse(fs.readFileSync('./test/data/world_extent_merc.geojson')))); 9 | assert.equal(merc.proj4, srs.canonical.spherical_mercator.proj4); 10 | }); 11 | 12 | it('should detect wgs84', function() { 13 | var parsed = srs.parse(srs.jsonCrs(JSON.parse(fs.readFileSync('./test/data/world_extent_wgs84.geojson')))); 14 | util.assert_wgs84(parsed); 15 | }); 16 | 17 | it('should detect wgs84 2', function() { 18 | var parsed = srs.parse(srs.jsonCrs(JSON.parse(fs.readFileSync('./test/data/test.json')))); 19 | util.assert_wgs84(parsed); 20 | }); 21 | 22 | it('should detect with no ext', function() { 23 | var parsed = srs.parse(srs.jsonCrs(JSON.parse(fs.readFileSync('./test/data/mystery-api')))); 24 | util.assert_wgs84(parsed); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /test/invalid.test.js: -------------------------------------------------------------------------------- 1 | var srs = require('../'); 2 | var fs = require('fs'); 3 | var assert = require('assert'); 4 | 5 | // http://spatialreference.org/ref/esri/102685/ 6 | // http://spatialreference.org/ref/sr-org/7058/ 7 | describe('throws on invalid input', function() { 8 | it('detects proj if parsed as ESRI::', function() { 9 | assert.throws(function() { 10 | var ref = srs.parse('PROCS[]'); 11 | }); 12 | }); 13 | it('init=epsg:3857', function() { 14 | assert.throws(function() { 15 | srs.parse('init=epsg:3857'); 16 | }); 17 | }); 18 | it('+init=epsg', function() { 19 | assert.throws(function() { 20 | srs.parse('+init=epsg'); 21 | }); 22 | }); 23 | it('+init=epsg:500', function() { 24 | assert.throws(function() { 25 | assert.ok(srs.parse('+init=epsg:500')); 26 | }); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /test/qgis-qpj.test.js: -------------------------------------------------------------------------------- 1 | var srs = require('../'); 2 | var fs = require('fs'); 3 | var assert = require('assert'); 4 | 5 | describe('qgis qpj format', function() { 6 | it('detects custom grids inside qgis transverse mercator projection', function(done) { 7 | var qgis = srs.parse(fs.readFileSync('./test/data/transverse_merc_kasey_custom_grids.prj')); 8 | var normal = srs.parse(fs.readFileSync('./test/data/transverse_merc_kasey.prj')); 9 | assert.ok(normal.proj4); 10 | assert.ok(qgis.proj4); 11 | assert.ok(qgis.proj4.indexOf('nadgrids=@conus') > 0); 12 | assert.ok(qgis.proj4.indexOf('proj=tmerc') > 0); 13 | assert.ok(qgis.proj4.indexOf('ellps=clrk66') > 0); 14 | assert.ok(normal.proj4.indexOf('nadgrids=@conus') == -1); 15 | assert.ok(normal.name,'Transverse_Mercator'); 16 | assert.ok(normal.proj4.indexOf('proj=tmerc') > 0); 17 | assert.ok(normal.proj4.indexOf('ellps=clrk66') > 0); 18 | done(); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /test/shapefile.27700.test.js: -------------------------------------------------------------------------------- 1 | var srs = require('../'); 2 | var fs = require('fs'); 3 | var assert = require('assert'); 4 | 5 | 6 | describe('OSGB 1936', function() { 7 | 8 | it('should report that it was parsed as esri if ESRI:: was manually prepended', function() { 9 | var esri_srs = fs.readFileSync('./test/data/27700_esri_wkt.prj').toString(); 10 | var esri_result = srs.parse('ESRI::'+esri_srs); 11 | assert.equal(esri_result.esri,true); 12 | }); 13 | 14 | // https://github.com/mapbox/node-srs/issues/25 15 | it('should detect OGC format for OSGB 1936 / British National Grid', function() { 16 | var ogc_srs = fs.readFileSync('./test/data/27700_ogc_wkt.prj').toString(); 17 | var ogc = srs.parse(ogc_srs); 18 | assert.equal(ogc.srid,27700); 19 | assert.equal(ogc.name,'OSGB 1936 / British National Grid'); 20 | assert.equal(ogc.esri,false); 21 | assert.equal(ogc.proj4.indexOf('datum=OSGB36') > -1,true); 22 | assert.equal(ogc.proj4.indexOf('proj=tmerc') > -1,true); 23 | // not stable across gdal versions 24 | //assert.equal(ogc.proj4,'+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +datum=OSGB36 +units=m +no_defs'); 25 | }); 26 | 27 | // https://github.com/mapbox/node-srs/issues/25 28 | it('should detect correct proj4 for ESRI format for OSGB 1936 / British National Grid', function() { 29 | var esri_srs = fs.readFileSync('./test/data/27700_esri_wkt.prj').toString(); 30 | // parse by forcing ESRI:: prepend 31 | var esri_result = srs.parse('ESRI::'+esri_srs); 32 | assert.equal(esri_result.name,'OSGB 1936 / British National Grid'); 33 | // should be: 34 | // +proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +datum=OSGB36 +units=m +no_defs 35 | // not: 36 | // +proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +units=m +no_defs 37 | assert.equal(esri_result.proj4.indexOf('datum=OSGB36') > -1,true); 38 | assert.equal(esri_result.proj4.indexOf('proj=tmerc') > -1,true); 39 | // not stable across gdal versions 40 | //var expected = '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +datum=OSGB36 +units=m +no_defs'; 41 | //assert.equal(esri_result.proj4,expected); 42 | // and test parsing without forcing ESRI:: prepend 43 | var esri_result2 = srs.parse(esri_srs); 44 | //assert.equal(esri_result2.proj4,expected); 45 | assert.equal(esri_result2.proj4.indexOf('datum=OSGB36') > -1,true); 46 | assert.equal(esri_result2.proj4.indexOf('proj=tmerc') > -1,true); 47 | }); 48 | 49 | it('should detect correct srid for ESRI format for OSGB 1936 / British National Grid', function() { 50 | var esri_srs = fs.readFileSync('./test/data/27700_esri_wkt.prj').toString(); 51 | var esri_result = srs.parse(esri_srs); 52 | assert.equal(esri_result.srid,27700); 53 | }); 54 | }); -------------------------------------------------------------------------------- /test/shapefile.3857.test.js: -------------------------------------------------------------------------------- 1 | var srs = require('../'); 2 | var fs = require('fs'); 3 | var assert = require('assert'); 4 | 5 | var expected = srs.canonical.spherical_mercator; 6 | 7 | describe('Mercator', function() { 8 | it('should detect non-spherical mercator', function() { 9 | // non spherical merc's - should not match 10 | //# WGS 84 / PDC Mercator (deprecated) 11 | //<3349> +proj=merc +lon_0=-150 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs <> 12 | // typo NAD83(NSRS2007) / Michigan Central 13 | //check_result('+init=epsg:3587',srs.canonical.spherical_mercator, false); 14 | var not_3857 = { srid: undefined, auth: undefined, esri: false, is_geographic: false, valid: true }; 15 | var srid3349 = '+proj=merc +lon_0=-150 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs'; 16 | var parsed = srs.parse(srid3349); 17 | assert.ok(parsed.proj4); 18 | assert.equal(parsed.proj4.indexOf('+nadgrids=@null'), -1); 19 | assert.equal(parsed.srid, not_3857.srid); 20 | assert.equal(parsed.auth, not_3857.auth); 21 | assert.equal(parsed.esri, not_3857.esri); 22 | assert.equal(parsed.is_geographic, not_3857.is_geographic); 23 | assert.equal(parsed.valid, not_3857.valid); 24 | var epsg3395 = fs.readFileSync('./test/data/3395-non-spherical-merc.prj').toString(); 25 | parsed = srs.parse(epsg3395); 26 | assert.ok(parsed.proj4); 27 | assert.equal(parsed.proj4.indexOf('+nadgrids=@null'), -1); 28 | assert.equal(parsed.srid, not_3857.srid); 29 | assert.equal(parsed.auth, not_3857.auth); 30 | assert.equal(parsed.esri, not_3857.esri); 31 | assert.equal(parsed.is_geographic, not_3857.is_geographic); 32 | assert.equal(parsed.valid, not_3857.valid); 33 | 34 | }); 35 | 36 | /* 37 | 38 | EPSG:900913 aka. Spherical Mercator 39 | 40 | http://wiki.openstreetmap.org/wiki/EPSG:3857 41 | 42 | */ 43 | 44 | // https://github.com/mapbox/node-srs/issues/27 45 | it('should detect qgis/ogr wkt', function() { 46 | var val = fs.readFileSync('./test/data/3857-ogr-1.10.0-wkt.prj').toString(); 47 | var parsed = srs.parse(val); 48 | assert.ok(parsed.proj4); 49 | //assert.equal(parsed.proj4,''); 50 | assert.equal(parsed.srid, expected.srid); 51 | assert.equal(parsed.auth, expected.auth); 52 | assert.equal(parsed.esri, expected.esri); 53 | assert.equal(parsed.is_geographic, expected.is_geographic); 54 | assert.equal(parsed.valid, expected.valid); 55 | }); 56 | 57 | it('should detect qgis/ogr wkt', function() { 58 | var val = fs.readFileSync('./test/data/world_borders_merc.prj').toString(); 59 | var parsed = srs.parse(val); 60 | assert.ok(parsed.proj4); 61 | //assert.equal(parsed.proj4,''); 62 | assert.equal(parsed.srid, expected.srid); 63 | assert.equal(parsed.auth, expected.auth); 64 | assert.equal(parsed.esri, expected.esri); 65 | assert.equal(parsed.is_geographic, expected.is_geographic); 66 | assert.equal(parsed.valid, expected.valid); 67 | }); 68 | 69 | it('should detect sr-org produced by older ogr version', function() { 70 | var val = fs.readFileSync('./test/data/sr-org-6-esriwkt.prj').toString(); 71 | var parsed = srs.parse(val); 72 | assert.ok(parsed.proj4); 73 | //assert.equal(parsed.proj4,''); 74 | assert.equal(parsed.srid, expected.srid); 75 | assert.equal(parsed.auth, expected.auth); 76 | assert.equal(parsed.esri, expected.esri); 77 | assert.equal(parsed.is_geographic, expected.is_geographic); 78 | assert.equal(parsed.valid, expected.valid); 79 | }); 80 | 81 | it('should detect sr-ogr6', function() { 82 | var val = '+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 +wktext +no_defs'; 83 | var parsed = srs.parse(val); 84 | assert.ok(parsed.proj4); 85 | //assert.equal(parsed.proj4,''); 86 | assert.equal(parsed.srid, expected.srid); 87 | assert.equal(parsed.auth, expected.auth); 88 | assert.equal(parsed.esri, expected.esri); 89 | assert.equal(parsed.is_geographic, expected.is_geographic); 90 | assert.equal(parsed.valid, expected.valid); 91 | }); 92 | 93 | it('should detect http://prj2epsg.org/epsg/3857', function() { 94 | var val = fs.readFileSync('./test/data/prj2epsg-wkt-3857.prj').toString(); 95 | var parsed = srs.parse(val); 96 | assert.ok(parsed.proj4); 97 | //assert.equal(parsed.proj4,''); 98 | assert.equal(parsed.srid, expected.srid); 99 | assert.equal(parsed.auth, expected.auth); 100 | assert.equal(parsed.esri, expected.esri); 101 | assert.equal(parsed.is_geographic, expected.is_geographic); 102 | assert.equal(parsed.valid, expected.valid); 103 | }); 104 | 105 | it('should detect +over stripped', function() { 106 | var val = '+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +ellps=WGS84 +units=m +no_defs'; 107 | var parsed = srs.parse(val); 108 | assert.ok(parsed.proj4); 109 | //assert.equal(parsed.proj4,''); 110 | assert.equal(parsed.srid, expected.srid); 111 | assert.equal(parsed.auth, expected.auth); 112 | assert.equal(parsed.esri, expected.esri); 113 | assert.equal(parsed.is_geographic, expected.is_geographic); 114 | assert.equal(parsed.valid, expected.valid); 115 | }); 116 | 117 | it('should detect proj 3857', function() { 118 | var val = '+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 +wktext +no_defs'; 119 | var parsed = srs.parse(val); 120 | assert.ok(parsed.proj4); 121 | //assert.equal(parsed.proj4,''); 122 | assert.equal(parsed.srid, expected.srid); 123 | assert.equal(parsed.auth, expected.auth); 124 | assert.equal(parsed.esri, expected.esri); 125 | assert.equal(parsed.is_geographic, expected.is_geographic); 126 | assert.equal(parsed.valid, expected.valid); 127 | }); 128 | 129 | it('should detect 900913', function() { 130 | var val = '+init=epsg:900913'; 131 | var parsed = srs.parse(val); 132 | assert.ok(parsed.proj4); 133 | //assert.equal(parsed.proj4,''); 134 | assert.equal(parsed.srid, expected.srid); 135 | assert.equal(parsed.auth, expected.auth); 136 | assert.equal(parsed.esri, expected.esri); 137 | assert.equal(parsed.is_geographic, expected.is_geographic); 138 | assert.equal(parsed.valid, expected.valid); 139 | }); 140 | 141 | it('should detect esri 900913', function() { 142 | var val = fs.readFileSync('./test/data/900913.esri.prj').toString(); 143 | var parsed = srs.parse(val); 144 | assert.ok(parsed.proj4); 145 | //assert.equal(parsed.proj4,''); 146 | assert.equal(parsed.srid, expected.srid); 147 | assert.equal(parsed.auth, expected.auth); 148 | assert.equal(parsed.esri, expected.esri); 149 | assert.equal(parsed.is_geographic, expected.is_geographic); 150 | assert.equal(parsed.valid, expected.valid); 151 | }); 152 | 153 | it('should detect esri 900913 hint', function() { 154 | var val = 'ESRI::' + fs.readFileSync('./test/data/900913.esri.prj').toString(); 155 | var parsed = srs.parse(val); 156 | assert.ok(parsed.proj4); 157 | //assert.equal(parsed.proj4,''); 158 | assert.equal(parsed.srid, expected.srid); 159 | assert.equal(parsed.auth, expected.auth); 160 | assert.equal(parsed.esri, expected.esri); 161 | assert.equal(parsed.is_geographic, expected.is_geographic); 162 | assert.equal(parsed.valid, expected.valid); 163 | }); 164 | 165 | it('should detect esri webmerc', function() { 166 | var val = fs.readFileSync('./test/data/esri_webmerc.prj').toString(); 167 | var parsed = srs.parse(val); 168 | assert.ok(parsed.proj4); 169 | //assert.equal(parsed.proj4,''); 170 | assert.equal(parsed.srid, expected.srid); 171 | assert.equal(parsed.auth, expected.auth); 172 | assert.equal(parsed.esri, expected.esri); 173 | assert.equal(parsed.is_geographic, expected.is_geographic); 174 | assert.equal(parsed.valid, expected.valid); 175 | }); 176 | 177 | it('should detect esri webmerc hint', function() { 178 | var val = 'ESRI::' + fs.readFileSync('./test/data/esri_webmerc.prj').toString(); 179 | var parsed = srs.parse(val); 180 | assert.ok(parsed.proj4); 181 | //assert.equal(parsed.proj4,''); 182 | assert.equal(parsed.srid, expected.srid); 183 | assert.equal(parsed.auth, expected.auth); 184 | assert.equal(parsed.esri, expected.esri); 185 | assert.equal(parsed.is_geographic, expected.is_geographic); 186 | assert.equal(parsed.valid, expected.valid); 187 | }); 188 | 189 | it('should detect esri webmerc aux', function() { 190 | var val = fs.readFileSync('./test/data/esri_webmerc_auxshpere.prj').toString(); 191 | var parsed = srs.parse(val); 192 | assert.ok(parsed.proj4); 193 | //assert.equal(parsed.proj4,''); 194 | assert.equal(parsed.srid, expected.srid); 195 | assert.equal(parsed.auth, expected.auth); 196 | assert.equal(parsed.esri, expected.esri); 197 | assert.equal(parsed.is_geographic, expected.is_geographic); 198 | assert.equal(parsed.valid, expected.valid); 199 | }); 200 | 201 | it('should detect webmerc aux hint', function() { 202 | var val = 'ESRI::' + fs.readFileSync('./test/data/esri_webmerc_auxshpere.prj').toString(); 203 | var parsed = srs.parse(val); 204 | assert.ok(parsed.proj4); 205 | //assert.equal(parsed.proj4,''); 206 | assert.equal(parsed.srid, expected.srid); 207 | assert.equal(parsed.auth, expected.auth); 208 | assert.equal(parsed.esri, expected.esri); 209 | assert.equal(parsed.is_geographic, expected.is_geographic); 210 | assert.equal(parsed.valid, expected.valid); 211 | }); 212 | 213 | it('should detect esri webmerc aux2', function() { 214 | var val = fs.readFileSync('./test/data/esri_webmerc_auxshpere2.prj').toString(); 215 | var parsed = srs.parse(val); 216 | assert.ok(parsed.proj4); 217 | //assert.equal(parsed.proj4,''); 218 | assert.equal(parsed.srid, expected.srid); 219 | assert.equal(parsed.auth, expected.auth); 220 | assert.equal(parsed.esri, expected.esri); 221 | assert.equal(parsed.is_geographic, expected.is_geographic); 222 | assert.equal(parsed.valid, expected.valid); 223 | }); 224 | 225 | it('should detect esri webmerc aux2 hint', function() { 226 | var val = 'ESRI::' + fs.readFileSync('./test/data/esri_webmerc_auxshpere2.prj').toString(); 227 | var parsed = srs.parse(val); 228 | assert.ok(parsed.proj4); 229 | //assert.equal(parsed.proj4,''); 230 | assert.equal(parsed.srid, expected.srid); 231 | assert.equal(parsed.auth, expected.auth); 232 | assert.equal(parsed.esri, expected.esri); 233 | assert.equal(parsed.is_geographic, expected.is_geographic); 234 | assert.equal(parsed.valid, expected.valid); 235 | }); 236 | 237 | // https://github.com/mapbox/tilemill/issues/1759 238 | it('should detect osm_landusages', function() { 239 | var val = 'ESRI::' + fs.readFileSync('./test/data/osm_landusages.prj').toString(); 240 | var parsed = srs.parse(val); 241 | assert.ok(parsed.proj4); 242 | //assert.equal(parsed.proj4,''); 243 | assert.equal(parsed.srid, expected.srid); 244 | assert.equal(parsed.auth, expected.auth); 245 | assert.equal(parsed.esri, expected.esri); 246 | assert.equal(parsed.is_geographic, expected.is_geographic); 247 | assert.equal(parsed.valid, expected.valid); 248 | }); 249 | 250 | it('should detect bogus proj 1', function() { 251 | var val = '+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +ellps=WGS84 +units=m +no_defs +foo'; 252 | var parsed = srs.parse(val); 253 | assert.ok(parsed.proj4); 254 | //assert.equal(parsed.proj4,''); 255 | assert.equal(parsed.srid, expected.srid); 256 | assert.equal(parsed.auth, expected.auth); 257 | assert.equal(parsed.esri, expected.esri); 258 | assert.equal(parsed.is_geographic, expected.is_geographic); 259 | assert.equal(parsed.valid, expected.valid); 260 | }); 261 | 262 | it('should detect bogus proj 2', function() { 263 | var val = '+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +a=6378137 +b=6378137 +units=m'; 264 | var parsed = srs.parse(val); 265 | assert.ok(parsed.proj4); 266 | //assert.equal(parsed.proj4,''); 267 | assert.equal(parsed.srid, expected.srid); 268 | assert.equal(parsed.auth, expected.auth); 269 | assert.equal(parsed.esri, expected.esri); 270 | assert.equal(parsed.is_geographic, expected.is_geographic); 271 | assert.equal(parsed.valid, expected.valid); 272 | }); 273 | 274 | /* 275 | Mercator_1SP and Mercator_2SP 276 | lots of confusion with these: 277 | http://trac.osgeo.org/gdal/ticket/2744 278 | http://trac.osgeo.org/gdal/ticket/1797 279 | http://www.remotesensing.org/geotiff/proj_list/mercator_2sp.html 280 | 281 | These are not spherical merc, but for our purposes we are going to ignore complexity 282 | and assume when these keywords are used in the top level name, aka the `PROJCS` 283 | then this is meant to be spherical mercator and may originate from some app or 284 | lonely soul grabbing a wkt in deparation from 285 | http://spatialreference.org/ref/sr-org/7299/ogcwkt/ 286 | which at the time of writing was equal to: 287 | 288 | PROJCS["Mercator_1SP",GEOGCS["GCS_Geographic Coordinate System",DATUM["D_WGS_1984_MAJOR_AUXILIARY_SPHERE",SPHEROID["Sphere_Radius_6378137_m",6378137,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mercator"],PARAMETER["central_meridian",0],PARAMETER["standard_parallel_1",0],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1]] 289 | 290 | or http://spatialreference.org/ref/sr-org/google-projection/esriwkt/: 291 | 292 | PROJCS["Mercator_2SP",GEOGCS["unnamed ellipse",DATUM["D_unknown",SPHEROID["Unknown",6378137,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mercator_2SP"],PARAMETER["standard_parallel_1",0],PARAMETER["central_meridian",0],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["Meter",1]] 293 | */ 294 | 295 | it('should detect sr.org mercator1sp', function() { 296 | var val = 'ESRI::' + fs.readFileSync('./test/data/esri-mercator-1sp.prj').toString(); 297 | var parsed = srs.parse(val); 298 | assert.ok(parsed.proj4); 299 | assert.ok(parsed.proj4); 300 | //assert.equal(parsed.proj4,''); 301 | assert.equal(parsed.srid, expected.srid); 302 | assert.equal(parsed.auth, expected.auth); 303 | assert.equal(parsed.esri, expected.esri); 304 | assert.equal(parsed.is_geographic, expected.is_geographic); 305 | assert.equal(parsed.valid, expected.valid); 306 | }); 307 | 308 | it('should detect sr.org messed up mercator2sp', function() { 309 | var val = 'ESRI::' + fs.readFileSync('./test/data/bogus_mercator2sp.prj').toString(); 310 | var parsed = srs.parse(val); 311 | assert.ok(parsed.proj4); 312 | assert.ok(parsed.proj4); 313 | //assert.equal(parsed.proj4,''); 314 | assert.equal(parsed.srid, expected.srid); 315 | assert.equal(parsed.auth, expected.auth); 316 | assert.equal(parsed.esri, expected.esri); 317 | assert.equal(parsed.is_geographic, expected.is_geographic); 318 | assert.equal(parsed.valid, expected.valid); 319 | }); 320 | 321 | it('should detect openstreetmapdata.com as 3857', function() { 322 | var val = fs.readFileSync('./test/data/simplified-land-polygons-complete-3857.prj').toString(); 323 | var parsed = srs.parse(val); 324 | assert.ok(parsed.proj4); 325 | assert.ok(parsed.proj4); 326 | //assert.equal(parsed.proj4,''); 327 | assert.equal(parsed.srid, expected.srid); 328 | assert.equal(parsed.auth, expected.auth); 329 | assert.equal(parsed.esri, expected.esri); 330 | assert.equal(parsed.is_geographic, expected.is_geographic); 331 | assert.equal(parsed.valid, expected.valid); 332 | }); 333 | 334 | it('should detect +init=epsg:3857 as 3857', function() { 335 | var val = '+init=epsg:3857'; 336 | var parsed = srs.parse(val); 337 | assert.ok(parsed.proj4); 338 | //assert.equal(parsed.proj4,''); 339 | assert.equal(parsed.srid,expected.srid); 340 | assert.equal(parsed.auth,expected.auth); 341 | assert.equal(parsed.esri,expected.esri); 342 | assert.equal(parsed.is_geographic,expected.is_geographic); 343 | assert.equal(parsed.valid,expected.valid); 344 | }); 345 | 346 | it('should detect +init=esri:102100 as 3857', function() { 347 | var val = '+init=esri:102100'; 348 | var parsed = srs.parse(val); 349 | assert.ok(parsed.proj4); 350 | //assert.equal(parsed.proj4,''); 351 | assert.equal(parsed.srid,expected.srid); 352 | assert.equal(parsed.auth,expected.auth); 353 | assert.equal(parsed.esri,expected.esri); 354 | assert.equal(parsed.is_geographic,expected.is_geographic); 355 | assert.equal(parsed.valid,expected.valid); 356 | }); 357 | 358 | it('should detect +init=esri:102113 as 3857', function() { 359 | var val = '+init=esri:102113'; 360 | var parsed = srs.parse(val); 361 | assert.ok(parsed.proj4); 362 | //assert.equal(parsed.proj4,''); 363 | assert.equal(parsed.srid,expected.srid); 364 | assert.equal(parsed.auth,expected.auth); 365 | assert.equal(parsed.esri,expected.esri); 366 | assert.equal(parsed.is_geographic,expected.is_geographic); 367 | assert.equal(parsed.valid,expected.valid); 368 | }); 369 | 370 | it('should detect +init=epsg:3785 as 3857', function() { 371 | var val = '+init=epsg:3785'; 372 | var parsed = srs.parse(val); 373 | assert.ok(parsed.proj4); 374 | //assert.equal(parsed.proj4,''); 375 | assert.equal(parsed.srid,expected.srid); 376 | assert.equal(parsed.auth,expected.auth); 377 | assert.equal(parsed.esri,expected.esri); 378 | assert.equal(parsed.is_geographic,expected.is_geographic); 379 | assert.equal(parsed.valid,expected.valid); 380 | }); 381 | 382 | it('should detect +init=osgeo:41001 as 3857', function() { 383 | var val = '+init=osgeo:41001'; 384 | var parsed = srs.parse(val); 385 | assert.ok(parsed.proj4); 386 | //assert.equal(parsed.proj4,''); 387 | assert.equal(parsed.srid,expected.srid); 388 | assert.equal(parsed.auth,expected.auth); 389 | assert.equal(parsed.esri,expected.esri); 390 | assert.equal(parsed.is_geographic,expected.is_geographic); 391 | assert.equal(parsed.valid,expected.valid); 392 | }); 393 | 394 | }); 395 | 396 | -------------------------------------------------------------------------------- /test/shapefile.4326.test.js: -------------------------------------------------------------------------------- 1 | var srs = require('../'); 2 | var fs = require('fs'); 3 | var assert = require('assert'); 4 | var util = require('./util'); 5 | 6 | describe('WGS84', function() { 7 | it('should detect wgs84 proj4 init detection', function() { 8 | var parsed = srs.parse('+init=epsg:4326'); 9 | util.assert_wgs84(parsed); 10 | }); 11 | 12 | it('should detect wgs84 proj4 literal from gdal trunk detection', function() { 13 | // +datum=WGS84 14 | var parsed = srs.parse('+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs'); 15 | util.assert_wgs84(parsed); 16 | }); 17 | 18 | it('should detect wgs84 proj4 literal +datum will trigger addition to towgs detection', function() { 19 | // +datum will trigger addition to towgs 20 | var parsed = srs.parse('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'); 21 | util.assert_wgs84(parsed); 22 | }); 23 | 24 | it('should detect wgs84 wkt detection', function() { 25 | 26 | var val = 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]'; 27 | var parsed = srs.parse(val); 28 | util.assert_wgs84(parsed); 29 | }); 30 | 31 | it('should detect wgs84 epsg detection', function() { 32 | 33 | var parsed = srs.parse('EPSG:4326'); 34 | util.assert_wgs84(parsed); 35 | }); 36 | 37 | it('should detect wgs84 common name detection', function() { 38 | 39 | var parsed = srs.parse('WGS84'); 40 | util.assert_wgs84(parsed); 41 | }); 42 | 43 | it('should detect wgs84 proj4 literal no datum detection', function() { 44 | 45 | var parsed = srs.parse('+proj=longlat +ellps=WGS84 +no_defs'); 46 | util.assert_wgs84(parsed); 47 | }); 48 | 49 | it('should detect wgs84 wkt from prj file', function() { 50 | 51 | var data = fs.readFileSync('./test/data/4326.esri.prj'); 52 | var parsed = srs.parse(data); 53 | util.assert_wgs84(parsed); 54 | }); 55 | 56 | it('should detect wgs84 wkt from another prj file', function() { 57 | 58 | var data = fs.readFileSync('./test/data/4326.prj'); 59 | var parsed = srs.parse(data); 60 | util.assert_wgs84(parsed); 61 | }); 62 | 63 | }); -------------------------------------------------------------------------------- /test/split_proj.js: -------------------------------------------------------------------------------- 1 | var srs = require('../'); 2 | var assert = require('assert'); 3 | var util = require('./util'); 4 | 5 | describe('#split_proj', function() { 6 | it('splits on spaces', function() { 7 | assert.deepEqual(srs.split_proj('a=b'), {a:'b'}); 8 | assert.deepEqual(srs.split_proj('a=b c=d'), {a:'b',c:'d'}); 9 | assert.deepEqual(srs.split_proj('a=b c=0'), {a:'b',c:'0.0'}); 10 | assert.deepEqual(srs.split_proj('a=b c=2.0'), {a:'b',c:'2.0'}); 11 | assert.deepEqual(srs.split_proj('a=b +bar c=2.0'), {a:'b',c:'2.0'}); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /test/util.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var srs = require('../'); 3 | 4 | function assert_wgs84(parsed) { 5 | assert.ok(parsed.proj4); 6 | assert.equal(parsed.name, srs.canonical.wgs84.name); 7 | assert.equal(parsed.srid, srs.canonical.wgs84.srid); 8 | assert.equal(parsed.auth, srs.canonical.wgs84.auth); 9 | assert.equal(parsed.esri, srs.canonical.wgs84.esri); 10 | assert.equal(parsed.is_geographic, srs.canonical.wgs84.is_geographic); 11 | assert.equal(parsed.valid, srs.canonical.wgs84.valid); 12 | assert.equal(parsed.proj4, srs.canonical.wgs84.proj4); 13 | } 14 | 15 | exports.assert_wgs84 = assert_wgs84; 16 | -------------------------------------------------------------------------------- /test/version.test.js: -------------------------------------------------------------------------------- 1 | var srs = require('../'); 2 | var fs = require('fs'); 3 | var assert = require('assert'); 4 | 5 | describe('Version check', function() { 6 | it('test version updated for release', function() { 7 | if (parseInt(process.version.split('.')[1]) > 4) { 8 | var info = require('../package.json'); 9 | assert.equal(info.version, srs.version); 10 | } 11 | }); 12 | }); 13 | --------------------------------------------------------------------------------