s2-tools
Version:
A collection of geospatial tools primarily designed for WGS84, Web Mercator, and S2.
160 lines • 5.14 kB
JavaScript
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