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) { if (wkt.type === 'GEOGCS') { if (wkt.DATUM && wkt.DATUM.SPHEROID) { wkt.to_meter = parseFloat(wkt.UNIT.convert, 10)*wkt.DATUM.SPHEROID.a; } } else { 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.datumCode.indexOf('belge')) { wkt.datumCode = "rnb72"; } 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.datumCode.indexOf('osgb_1936')) { wkt.datumCode = "osgb36"; } } 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'], ['latitude_of_origin', 'Central_Parallel'], ['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.projName === 'Albers_Conic_Equal_Area' || wkt.projName === "Lambert_Azimuthal_Equal_Area")) { wkt.long0 = wkt.longc; } if (!wkt.lat_ts && wkt.lat1 && (wkt.projName === 'Stereographic_South_Pole' || wkt.projName === 'Polar Stereographic (variant B)')) { wkt.lat0 = d2r(wkt.lat1 > 0 ? 90 : -90); wkt.lat_ts = wkt.lat1; } } 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"]').replace(/,\["VERTCS".+/,'')); 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); };