UNPKG

get-epsg-code

Version:

Gets EPSG Code for Various Inputs (incl. OGC WKT, ESRI WKT, GML, Mapfile, PROJ String, Proj4js String, XML)

190 lines (166 loc) 6.4 kB
const b64ab = require("b64ab"); const findTagByPath = require("xml-utils/find-tag-by-path"); const findTagByName = require("xml-utils/find-tag-by-name"); const getAttribute = require("xml-utils/get-attribute"); const parseWKT = require("wkt-parser"); const utmUtils_getCodeFromEsriWKT = require("utm-utils/src/getCodeFromEsriWKT.js"); const utmUtils_getCodeFromProjString = require("utm-utils/src/getCodeFromProjString.js"); const hash = require("./hash.js"); const normalize_esriwkt = require("./normalize/esriwkt.js"); const normalize_proj4 = require("./normalize/proj4.js"); const getProjType = require("./get-proj-type.js"); const parseProj4JS = require("./parse/proj4js.js"); const { FORMATS } = require("./enums.js"); const data = require("./data/esriwkt-mapfile-proj4.json"); const getDefault = fn => fn.default || fn; const rows = []; function _load_rows(debug) { const decoded = b64ab.toArrayBuffer(data.data); const arr = new Int32Array(decoded); if (debug) console.log("arr:", arr); const num_fields = data.properties.columns.length; const num_rows = arr.length / num_fields; for (let r = 0; r < num_rows; r++) { const row = {}; for (let f = 0; f < num_fields; f++) { row[data.properties.columns[f]] = arr[r * num_fields + f]; } rows.push(row); } if (debug) console.log("[get-epsg-code] rows:", rows); return rows; } function lookup(input, dataType, debug = false) { if (!data.properties.columns.includes(dataType)) { throw new Error("[get-epsg-code] " + dataType + " not supported"); } if (rows.length === 0) { _load_rows(debug); } const hashed = hash(input); if (debug) console.log("[get-epsg-code] hashed:", hashed); const found = rows.filter(row => row[dataType] === hashed); if (debug) console.log("[get-epsg-code] found:", found); return found.map(row => row.epsg_code); } const { ESRI_WKT, GEOSERVER, MAPFILE, MAPNIK, OGC_GML, OGC_XML, OGC_WKT, POSTGIS, PROJJSON, PROJ_4, PROJ_4_JS, WKT_2 } = FORMATS; function getEPSGCodes(input, options) { //console.log("starting get-epsg-code with", input, options); var debug = options && options.debug ? options.debug : false; if (typeof input === "string") input = input.trim(); const dataType = getProjType(input, { debug }); if (debug) console.log("dataType:", dataType); if (dataType === OGC_WKT) { const parsed = getDefault(parseWKT)(input); if (debug) console.log("parsed:", parsed); if (parsed.AUTHORITY) { const authority = parsed.AUTHORITY; return { type: dataType, codes: [Number(authority.epsg || authority.EPSG)] }; } } else if (dataType === WKT_2) { const parsed = getDefault(parseWKT)(input); if (debug) console.log("parsed:", parsed); if (typeof parsed.ID === "object" && typeof parsed.ID.EPSG === "number") { return { type: dataType, codes: [parsed.ID.EPSG] }; } } else if (dataType == ESRI_WKT) { // try utm parsing const code = utmUtils_getCodeFromEsriWKT(input); if (code) return { type: dataType, codes: [code] }; input = normalize_esriwkt(input, { debug }); return { type: dataType, codes: lookup(input, ESRI_WKT, debug) }; } else if (dataType === OGC_GML) { const identifier = getDefault(findTagByName)(input, "gml:identifier", { debug }).inner; return { type: dataType, codes: [Number(identifier.replace("urn:ogc:def:crs:EPSG::", ""))] }; } else if (dataType === OGC_XML) { return { type: dataType, codes: [Number(getDefault(findTagByPath)(input, ["gml:srsID", "gml:name"], { debug }).inner)] }; } else if (dataType === PROJ_4) { input = normalize_proj4(input, { debug }); if (input.startsWith("+") && input.includes("+proj=utm")) { return { type: dataType, codes: [utmUtils_getCodeFromProjString(input)] }; } else { return { type: dataType, codes: lookup(input, PROJ_4, debug) }; } } else if (dataType === PROJ_4_JS) { const code = parseProj4JS(input); return { type: dataType, codes: code ? [code] : [] }; } else if (dataType === GEOSERVER) { return { type: dataType, codes: [Number(input.match(/^\d{1,6}/)[0])] }; } else if (dataType === MAPFILE) { if (input.includes("init=epsg:")) { return { type: dataType, codes: [Number.parseInt(/("init\=epsg:)(\d{1,10})(")/.exec(input)[2])] }; } else if (input.includes('"proj=utm"')) { const zone = /("zone\=)(\d{1,2})(")/.exec(input)[2]; const south = input.includes('"south"'); if (input.includes("ellps=GRS80") && south === false) { return { type: dataType, codes: [Number.parseInt("269" + zone)] }; } else { const hemisphere = south ? "7" : "6"; return { type: dataType, codes: [Number.parseInt("32" + hemisphere + zone)] }; } } else { return { type: dataType, codes: lookup(input, MAPFILE, debug) }; } } else if (dataType === MAPNIK) { const map = findTagByName(input, "Map"); const srs = getAttribute(map.outer, "srs"); // Proj.4 String return { type: dataType, codes: getEPSGCodes(srs).codes }; } else if (dataType === POSTGIS) { return { type: dataType, codes: [Number(input.substring(input.indexOf("values (") + 8, input.indexOf("EPSG") - 3).trim())] }; } else if (dataType === PROJJSON) { const data = JSON.parse(input); if (typeof data.id === "object") { if (data.id.authority === "EPSG" || !("authority" in data.id)) { if (typeof data.id.code === "number") { return { type: dataType, codes: [data.id.code] }; } } } } } function getEPSGCode(input, options) { const result = getEPSGCodes(input, options); if (result) return result.codes[0]; } if (typeof module !== "undefined" && typeof module.exports !== "undefined") { module.exports = getEPSGCode; module.exports.getEPSGCode = getEPSGCode; module.exports.getEPSGCodes = getEPSGCodes; module.exports._load_rows = _load_rows; } if (typeof window !== "undefined") { window["getEPSGCode"] = getEPSGCode; window["getEPSGCodes"] = getEPSGCodes; } else if (typeof self !== "undefined") { self["getEPSGCode"] = getEPSGCode; // jshint ignore:line self["getEPSGCodes"] = getEPSGCodes; // jshint ignore:line }