UNPKG

s2-tools

Version:

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

160 lines 5.14 kB
import { cleanString } from '.'; /** * Parse a WKT string geometry to a VectorGeometry * @param wktStr - WKT string * @returns - VectorGeometry */ export function parseWKTGeometry(wktStr) { if (wktStr.startsWith('POINT')) return parseWKTPoint(wktStr, wktStr.startsWith('POINT Z')); else if (wktStr.startsWith('MULTIPOINT')) return parseWKTLine(wktStr, 'MultiPoint', wktStr.startsWith('MULTIPOINT Z')); else if (wktStr.startsWith('LINESTRING')) return parseWKTLine(wktStr, 'LineString', wktStr.startsWith('LINESTRING Z')); else if (wktStr.startsWith('MULTILINESTRING')) return parseWKTMultiLine(wktStr, 'MultiLineString', wktStr.startsWith('MULTILINESTRING Z')); else if (wktStr.startsWith('POLYGON')) return parseWKTMultiLine(wktStr, 'Polygon', wktStr.startsWith('POLYGON Z')); else if (wktStr.startsWith('MULTIPOLYGON')) return parseWKTMultiPolygon(wktStr, wktStr.startsWith('MULTIPOLYGON Z')); throw new Error('Unimplemented WKT geometry: ' + wktStr); } /** * Parse a WKT point string to a VectorPoint * @param wktStr - WKT string * @param is3D - true if the point is 3D * @returns - VectorPoint */ function parseWKTPoint(wktStr, is3D) { const geo = parseWKTArray(wktStr); return { type: 'Point', is3D, coordinates: geo[0], }; } /** * Parse a WKT array to a LineString or MultiPoint geometry * @param wktStr - WKT string * @param type - 'MultiPoint' or 'LineString' * @param is3D - true if the point is 3D * @returns - VectorGeometry (LineString or MultiPoint) */ function parseWKTLine(wktStr, type, is3D) { let geo = parseWKTArray(wktStr); geo = geo.length > 0 && Array.isArray(geo[0]) ? geo.map((e) => e[0]) : geo; return { type, is3D, coordinates: geo, }; } /** * Parse a WKT array to a MultiLineString or Polygon * @param wktStr - WKT string * @param type - 'MultiLineString' or 'Polygon' * @param is3D - true if the point is 3D * @returns - VectorGeometry */ function parseWKTMultiLine(wktStr, type, is3D) { let geo = parseWKTArray(wktStr); geo = geo.length > 0 && geo[0].length > 0 && Array.isArray(geo[0][0]) ? geo.map((e) => { return e.map((e2) => e2[0]); }) : geo; return { type, is3D, coordinates: geo, }; } /** * Parse a WKT array to a MultiPolygon * @param wktStr - WKT string * @param is3D - true if each point is 3D * @returns - VectorGeometry */ function parseWKTMultiPolygon(wktStr, is3D) { let geo = parseWKTArray(wktStr); geo = geo.length > 0 && geo[0].length > 0 && geo[0][0].length > 0 && Array.isArray(geo[0][0][0]) ? geo.map((e) => { return e.map((e2) => e2.map((e3) => e3[0])); }) : geo; return { type: 'MultiPolygon', is3D, coordinates: geo, }; } /** * Parse a WKT array * @param wktStr - WKT string * @returns - collection of points */ function parseWKTArray(wktStr) { const res = []; _parseWKTArray(wktStr, res); return res.length > 0 ? res[0] : res; } /** * Parse a WKT array. * always return the endBracketIndex if we hit it * @param wktStr - WKT string * @param res - collection to store the values * @returns - a sliced WKT string with the parsed values */ function _parseWKTArray(wktStr, res) { // first get the array name and build the residual while (wktStr.length > 0) { let commaIndex = wktStr.indexOf(','); let startBracketIndex = wktStr.indexOf('('); const endBracketIndex = wktStr.indexOf(')'); if (commaIndex === -1) commaIndex = Infinity; if (startBracketIndex === -1) startBracketIndex = Infinity; if (commaIndex < Math.min(startBracketIndex, endBracketIndex)) { // store the value const key = wktStr.slice(0, commaIndex); if (key.length > 0) res.push(buildPoint(key)); wktStr = wktStr.slice(commaIndex + 1); } else if (startBracketIndex < endBracketIndex) { // store the array const array = []; wktStr = _parseWKTArray(wktStr.slice(startBracketIndex + 1), array); res.push(array); } else { // store the LAST value if it exists, be sure to increment past the bracket for this recursive call if (endBracketIndex > 0) { res.push(buildPoint(wktStr.slice(0, endBracketIndex))); wktStr = wktStr.slice(endBracketIndex + 1); } else { wktStr = wktStr.slice(1); } return wktStr; } } // hit the end return wktStr; } /** * Build a point from a WKT string * @param str - WKT string * @returns - VectorPoint */ function buildPoint(str) { const [x, y, z] = cleanString(str).split(' '); return { x: Number(x), y: Number(y), z: z !== undefined ? Number(z) : undefined }; } //# sourceMappingURL=geometry.js.map