UNPKG

terriajs

Version:

Geospatial data visualization platform.

105 lines (98 loc) 3.61 kB
import proj4 from "proj4"; import defined from "terriajs-cesium/Source/Core/defined"; import urijs from "urijs"; import loadText from "../../Core/loadText"; import Proj4Definitions from "./Proj4Definitions"; export default { TERRIA_CRS: "EPSG:4326", /** * Convert a CRS string into a code that Proj4 understands. * @param crsString A CRS URI * @return A code that is recognised by Proj4 as a valid CRS code. */ crsStringToCode: function (crsString: string): string | undefined { const crs = crsString.toLowerCase(); let code; if (crs.indexOf("epsg:") === 0) { code = crsString.toUpperCase(); } else if (crs.indexOf("urn:ogc:def:crs:epsg::") === 0) { code = "EPSG:" + crsString.substring("urn:ogc:def:crs:EPSG::".length); } else if (crs.indexOf("urn:ogc:def:crs:epsg") === 0) { // With version code = "EPSG:" + crsString.substring("urn:ogc:def:crs:EPSG::x.x".length); } else if (crs.indexOf("crs84") !== -1) { code = this.TERRIA_CRS; } return code; }, /** * A point will need reprojecting if it isn't using the same (or equivalent) CRS as TerriaJS. * TerriaJS is assumed to be using EPSG:4326. * * If the code is not defined, it's assumed that the point/s will not need reprojecting as we don't know what the * source is, so we can't reproject anyway. * * @param code A CRS code that Proj4 recognises. * @return whether points in the CRS provided will need reprojecting. */ willNeedReprojecting: function (code: string): boolean { if (!defined(code) || code === this.TERRIA_CRS || code === "EPSG:4283") { return false; } return true; }, /** * Reproject points from one CRS to another. * @param coordinates which are two floating point numbers in an array in order long, lat. * @param sourceCode The Proj4 code for the CRS the source coordinates are in. * @param destCode The Proj4 code for the CRS the generated coordinates should be in. * @return coordinates in destCode CRS projection, two floating points in order long, lat. */ reprojectPoint: function ( coordinates: [number, number], sourceCode: string, destCode: string ): [number, number] | undefined { const source = sourceCode in Proj4Definitions ? proj4.Proj(Proj4Definitions[sourceCode]) : undefined; const dest = destCode in Proj4Definitions ? proj4.Proj(Proj4Definitions[destCode]) : undefined; if (!source || !dest) { return; } const result = proj4.transform(source, dest, coordinates, false); if (result) { const { x, y } = result; return [x, y]; } return undefined; }, /** * Add the reprojection parameters to proj4 if the code is not already known by Proj4. * @param proj4ServiceBaseUrl URL relative to Terria for accessing the proj4 service * @param code The Proj4 CRS code to check for and potentially add * @return Eventually resolves to false if code wasn't there and wasn't able to be added */ checkProjection: async function ( proj4ServiceBaseUrl: string, code: string ): Promise<boolean> { if (Object.prototype.hasOwnProperty.call(Proj4Definitions, code)) { return true; } const url = new urijs(proj4ServiceBaseUrl).segment(code).toString(); return loadText(url) .then(function (proj4Text: string) { Proj4Definitions[code] = proj4Text; console.log("Added new string for", code, "=", proj4Text); return true; }) .catch(function () { return false; }); } };