proj4
Version:
Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations.
207 lines (198 loc) • 5.51 kB
JavaScript
var D2R = 0.01745329251994329577;
var extend = require('./extend');
function mapit(obj, key, v) {
obj[key] = v.map(function(aa) {
var o = {};
sExpr(aa, o);
return o;
}).reduce(function(a, b) {
return extend(a, b);
}, {});
}
function sExpr(v, obj) {
var key;
if (!Array.isArray(v)) {
obj[v] = true;
return;
}
else {
key = v.shift();
if (key === 'PARAMETER') {
key = v.shift();
}
if (v.length === 1) {
if (Array.isArray(v[0])) {
obj[key] = {};
sExpr(v[0], obj[key]);
}
else {
obj[key] = v[0];
}
}
else if (!v.length) {
obj[key] = true;
}
else if (key === 'TOWGS84') {
obj[key] = v;
}
else {
obj[key] = {};
if (['UNIT', 'PRIMEM', 'VERT_DATUM'].indexOf(key) > -1) {
obj[key] = {
name: v[0].toLowerCase(),
convert: v[1]
};
if (v.length === 3) {
obj[key].auth = v[2];
}
}
else if (key === 'SPHEROID') {
obj[key] = {
name: v[0],
a: v[1],
rf: v[2]
};
if (v.length === 4) {
obj[key].auth = v[3];
}
}
else if (['GEOGCS', 'GEOCCS', 'DATUM', 'VERT_CS', 'COMPD_CS', 'LOCAL_CS', 'FITTED_CS', 'LOCAL_DATUM'].indexOf(key) > -1) {
v[0] = ['name', v[0]];
mapit(obj, key, v);
}
else if (v.every(function(aa) {
return Array.isArray(aa);
})) {
mapit(obj, key, v);
}
else {
sExpr(v, obj[key]);
}
}
}
}
function rename(obj, params) {
var outName = params[0];
var inName = params[1];
if (!(outName in obj) && (inName in obj)) {
obj[outName] = obj[inName];
if (params.length === 3) {
obj[outName] = params[2](obj[outName]);
}
}
}
function d2r(input) {
return input * D2R;
}
function cleanWKT(wkt) {
if (wkt.type === 'GEOGCS') {
wkt.projName = 'longlat';
}
else if (wkt.type === 'LOCAL_CS') {
wkt.projName = 'identity';
wkt.local = true;
}
else {
if (typeof wkt.PROJECTION === "object") {
wkt.projName = Object.keys(wkt.PROJECTION)[0];
}
else {
wkt.projName = wkt.PROJECTION;
}
}
if (wkt.UNIT) {
wkt.units = wkt.UNIT.name.toLowerCase();
if (wkt.units === 'metre') {
wkt.units = 'meter';
}
if (wkt.UNIT.convert) {
wkt.to_meter = parseFloat(wkt.UNIT.convert, 10);
}
}
if (wkt.GEOGCS) {
//if(wkt.GEOGCS.PRIMEM&&wkt.GEOGCS.PRIMEM.convert){
// wkt.from_greenwich=wkt.GEOGCS.PRIMEM.convert*D2R;
//}
if (wkt.GEOGCS.DATUM) {
wkt.datumCode = wkt.GEOGCS.DATUM.name.toLowerCase();
}
else {
wkt.datumCode = wkt.GEOGCS.name.toLowerCase();
}
if (wkt.datumCode.slice(0, 2) === 'd_') {
wkt.datumCode = wkt.datumCode.slice(2);
}
if (wkt.datumCode === 'new_zealand_geodetic_datum_1949' || wkt.datumCode === 'new_zealand_1949') {
wkt.datumCode = 'nzgd49';
}
if (wkt.datumCode === "wgs_1984") {
if (wkt.PROJECTION === 'Mercator_Auxiliary_Sphere') {
wkt.sphere = true;
}
wkt.datumCode = 'wgs84';
}
if (wkt.datumCode.slice(-6) === '_ferro') {
wkt.datumCode = wkt.datumCode.slice(0, - 6);
}
if (wkt.datumCode.slice(-8) === '_jakarta') {
wkt.datumCode = wkt.datumCode.slice(0, - 8);
}
if (wkt.GEOGCS.DATUM && wkt.GEOGCS.DATUM.SPHEROID) {
wkt.ellps = wkt.GEOGCS.DATUM.SPHEROID.name.replace('_19', '').replace(/[Cc]larke\_18/, 'clrk');
if (wkt.ellps.toLowerCase().slice(0, 13) === "international") {
wkt.ellps = 'intl';
}
wkt.a = wkt.GEOGCS.DATUM.SPHEROID.a;
wkt.rf = parseFloat(wkt.GEOGCS.DATUM.SPHEROID.rf, 10);
}
}
if (wkt.b && !isFinite(wkt.b)) {
wkt.b = wkt.a;
}
function toMeter(input) {
var ratio = wkt.to_meter || 1;
return parseFloat(input, 10) * ratio;
}
var renamer = function(a) {
return rename(wkt, a);
};
var list = [
['standard_parallel_1', 'Standard_Parallel_1'],
['standard_parallel_2', 'Standard_Parallel_2'],
['false_easting', 'False_Easting'],
['false_northing', 'False_Northing'],
['central_meridian', 'Central_Meridian'],
['latitude_of_origin', 'Latitude_Of_Origin'],
['scale_factor', 'Scale_Factor'],
['k0', 'scale_factor'],
['latitude_of_center', 'Latitude_of_center'],
['lat0', 'latitude_of_center', d2r],
['longitude_of_center', 'Longitude_Of_Center'],
['longc', 'longitude_of_center', d2r],
['x0', 'false_easting', toMeter],
['y0', 'false_northing', toMeter],
['long0', 'central_meridian', d2r],
['lat0', 'latitude_of_origin', d2r],
['lat0', 'standard_parallel_1', d2r],
['lat1', 'standard_parallel_1', d2r],
['lat2', 'standard_parallel_2', d2r],
['alpha', 'azimuth', d2r],
['srsCode', 'name']
];
list.forEach(renamer);
if (!wkt.long0 && wkt.longc && (wkt.PROJECTION === 'Albers_Conic_Equal_Area' || wkt.PROJECTION === "Lambert_Azimuthal_Equal_Area")) {
wkt.long0 = wkt.longc;
}
}
module.exports = function(wkt, self) {
var lisp = JSON.parse(("," + wkt).replace(/\s*\,\s*([A-Z_0-9]+?)(\[)/g, ',["$1",').slice(1).replace(/\s*\,\s*([A-Z_0-9]+?)\]/g, ',"$1"]'));
var type = lisp.shift();
var name = lisp.shift();
lisp.unshift(['name', name]);
lisp.unshift(['type', type]);
lisp.unshift('output');
var obj = {};
sExpr(lisp, obj);
cleanWKT(obj.output);
return extend(self, obj.output);
};