UNPKG

s2-tools

Version:

A collection of geospatial tools primarily designed for WGS84, Web Mercator, and S2.

132 lines 4.42 kB
import { buildDatum } from './datum'; import { D2R, FT_TO_M, PRIME_MERIDIAN, US_FT_TO_M, deriveEccentricity, deriveSphere, } from './constants'; import { isWKTProjection, parseWKTProjection } from '../readers/wkt'; /** * Parse a proj4 string or object into a projection object * TODO: Support json objects that use the jsonScheme.ts file * @param code - a proj4 projection definition string or object * @param transformer - the transformer to build the projection state around * @returns - a projection object */ export function parseProj(code, transformer) { let params = {}; if (typeof code === 'object') params = code; else if (code[0] === '+') params = parseProj4Str(code); else if (isWKTProjection(code)) params = parseWKTProjection(code); else throw new Error(`Invalid projection string: ${code}`); // adjust params as needed deriveSphere(params); deriveEccentricity(params); params.lat1 = params.lat1 ?? params.lat0; // Lambert_Conformal_Conic_1SP, for example, needs this params.k0 = params.k ?? params.k0; buildDatum(params, transformer); // filter undefined values Object.keys(params).forEach((key) => { // @ts-expect-error - key is a string if (params[key] === undefined) delete params[key]; }); return params; } /** * Parse a proj4 string into a projection object * @param code - a proj4 projection definition string * @returns - a projection description object */ function parseProj4Str(code) { return code .split('+') .map((v) => v.trim()) .filter((a) => a.length > 0) .reduce((res, a) => { const [key, value] = a.split('='); parseProj4StrKeyValue(res, key, value); return res; }, {}); } /** * Modify a key/value pair in a proj4 string to match the CRS projection standard * @param res - a projection description object * @param key - a proj4 string key * @param value - a proj4 string value */ function parseProj4StrKeyValue(res, key, value) { // adjust key key = key.replace(/_([a-zA-Z0-9])/g, (_, letter) => letter.toUpperCase()); if (key === 'proj') res.name = value; else if ([ 'alpha', 'lat0', 'lat1', 'lat2', 'latTs', 'fromGreenwich', 'long0', 'long1', 'long2', 'longc', ].includes(key)) res[key] = parseFloat(value) * D2R; else if (['lon0', 'lon1', 'lon2', 'lonc'].includes(key)) { const modKey = key.replace('n', 'ng'); res[modKey] = parseFloat(value) * D2R; } else if (['ellps', 'datumCode'].includes(key)) res[key] = value; else if (key === 'datum') res.datumCode = value; else if (['noDefs', 'noOff', 'noRot', 'noUoff', 'rA', 'utmSouth', 'approx'].includes(key)) res[key] = true; else if (key === 'zone') res[key] = parseInt(value, 10); else if (key === 'units') { res.units = value; if (value === 'us-ft') res.toMeter = US_FT_TO_M; else if (value === 'ft') res.toMeter = FT_TO_M; } else if (key === 'nadgrids') { res.nadgrids = value; if (value === '@null') res.datumCode = 'none'; } else if (key === 'pm') { const pm = PRIME_MERIDIAN[value] ?? 0; res.fromGreenwich = pm * D2R; } else if (key === 'towgs84' || key === 'datumParams') { res.datumParams = value.split(',').map((a) => parseFloat(a)); } else if (key === 'axis') { const legalAxis = 'ewnsud'; if (value.length === 3 && legalAxis.indexOf(value.slice(0, 1)) !== -1 && legalAxis.indexOf(value.slice(1, 2)) !== -1 && legalAxis.indexOf(value.slice(2, 3)) !== -1) { res.axis = value; } } else if (key === 'r' || key === 'R') { res.a = res.b = parseFloat(value); } else if (key === 'gamma') { res.rectifiedGridAngle = parseFloat(value); } else if (key === 'sweep') { res.sweep = value === 'x' ? 'x' : 'y'; } else if (!isNaN(value)) // @ts-expect-error - key is a string in ProjectionParams res[key] = parseFloat(value); // @ts-expect-error - key is a string in ProjectionParams else res[key] = value; } //# sourceMappingURL=parseCode.js.map