Skip to content

Commit

Permalink
fix previous commit: forgot to export parseWKT
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbol99 committed Jun 29, 2024
1 parent e56cce2 commit 4e37406
Show file tree
Hide file tree
Showing 7 changed files with 468 additions and 2 deletions.
154 changes: 154 additions & 0 deletions dist/main.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -8833,6 +8833,158 @@ class Distance {

Flatten.Distance = Distance;

// POINT (30 10)
// MULTIPOINT (10 40, 40 30, 20 20, 30 10)
// LINESTRING (30 10, 10 30, 40 40)
// MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))
// MULTILINESTRING ((8503.732 4424.547, 8963.747 3964.532), (8963.747 3964.532, 8707.468 3708.253), (8707.468 3708.253, 8247.454 4168.268), (8247.454 4168.268, 8503.732 4424.547))
// POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))
// MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), ((20 35, 10 30, 10 10, 30 5, 45 20, 20 35), (30 20, 20 15, 20 25, 30 20)))

function parseSinglePoint(pointStr) {
return new Point$1(pointStr.split(' ').map(Number))
}

function parseMultiPoint(multipointStr) {
return multipointStr.split(', ').map(parseSinglePoint)
}

function parseLineString(lineStr) {
const points = parseMultiPoint(lineStr);
let segments = [];
for (let i = 0; i < points.length-1; i++) {
segments.push(new Segment(points[i], points[i+1]));
}
return new Multiline(segments)
}

function parseMultiLineString(multilineStr) {
const lineStrings = multilineStr.replace(/\(\(/, '').replace(/\)\)$/, '').split('), (');
return lineStrings.map(parseLineString)
}

function parseSinglePolygon(polygonStr) {
const facesStr = polygonStr.replace(/\(\(/, '').replace(/\)\)$/, '').split('), (');
const polygon = new Polygon();
let orientation;
facesStr.forEach((facesStr, idx) => {
let points = facesStr.split(', ').map(coordStr => {
return new Point$1(coordStr.split(' ').map(Number))
});
const face = polygon.addFace(points);
if (idx === 0) {
orientation = face.orientation();
}
else {
if (face.orientation() === orientation) {
face.reverse();
}
}
});
return polygon
}

function parseMutliPolygon(multiPolygonString) {
const polygonStrings = multiPolygonString.split('?');
const polygons = polygonStrings.map(parseSinglePolygon);
const polygon = new Polygon();
const faces = polygons.reduce((acc, polygon) => [...acc, ...polygon?.faces], []);
faces.forEach(face => polygon.addFace([...face?.shapes]));
return polygon;
}

function parsePolygon(wkt) {
if (wkt.startsWith("POLYGON")) {
const polygonStr = wkt.replace(/^POLYGON /, '');
return parseSinglePolygon(polygonStr)
}
else {
const multiPolygonString = wkt.replace(/^MULTIPOLYGON \(/, '').replace(/\)$/, '').replace(/\)\), \(\(/,'))?((');
return parseMutliPolygon(multiPolygonString)
}
}

function parseArrayOfPoints(str) {
const arr = str.split('\n').map(x => x.match(/\(([^)]+)\)/)[1]);
return arr.map(parseSinglePoint)
}

function parseArrayOfLineStrings(str) {
const arr = str.split('\n').map(x => x.match(/\(([^)]+)\)/)[1]);
return arr.map(parseLineString).reduce((acc, x) => [...acc, ...x], [])
}

/**
* Convert WKT string to array of Flatten shapes.
* @param str
* @returns {Point | Point[] | Multiline | Multiline[] | Polygon | Shape[] | null}
*/
function parseWKT(str) {
if (str.startsWith("POINT")) {
const pointStr = str.replace(/^POINT \(/, '').replace(/\)$/, '');
return parseSinglePoint(pointStr)
}
else if (str.startsWith("MULTIPOINT")) {
const multiPointStr = str.replace(/^MULTIPOINT \(/, '').replace(/\)$/, '');
return parseMultiPoint(multiPointStr)
}
else if (str.startsWith("LINESTRING")) {
const lineStr = str.replace(/^LINESTRING \(/, '').replace(/\)$/, '');
return parseLineString(lineStr)
}
else if (str.startsWith("MULTILINESTRING")) {
const multilineStr = str.replace(/^MULTILINESTRING /, '');
return parseMultiLineString(multilineStr)
}
else if (str.startsWith("POLYGON") || str.startsWith("MULTIPOLYGON")) {
return parsePolygon(str)
}
else if (str.startsWith("GEOMETRYCOLLECTION")) {
const regex = /(POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION) \([^\)]+\)/g;
const wktArray = str.match(regex);
if (wktArray[0].startsWith('GEOMETRYCOLLECTION')) {
wktArray[0] = wktArray[0].replace('GEOMETRYCOLLECTION (','');
}
const flArray = wktArray.map(parseWKT).map(x => x instanceof Array ? x : [x]);
return flArray.reduce((acc, x) => [...acc, ...x], [])
}
else if (isArrayOfPoints(str)) {
return parseArrayOfPoints(str)
}
else if (isArrayOfLines(str)) {
return parseArrayOfLineStrings(str)
}
return []
}

function isArrayOfPoints(str) {
return str.split('\n')?.every(str => str.includes('POINT'))
}

function isArrayOfLines(str) {
return str.split('\n')?.every(str => str.includes('LINESTRING'))
}

/**
* Return true if given string starts with one of WKT tags and possibly contains WKT string,
* @param str
* @returns {boolean}
*/
function isWktString(str) {
return (
str.startsWith("POINT") || isArrayOfPoints(str) ||
str.startsWith("LINESTRING") || isArrayOfLines(str) ||
str.startsWith("MULTILINESTRING") ||
str.startsWith("POLYGON") ||
str.startsWith("MULTIPOINT") ||
str.startsWith("MULTIPOLYGON") ||
str.startsWith("GEOMETRYCOLLECTION")
)
}

Flatten.isWktString = isWktString;
Flatten.parseWKT = parseWKT;

/**
* Created by Alex Bol on 2/18/2017.
*/
Expand Down Expand Up @@ -8875,9 +9027,11 @@ exports.box = box;
exports.circle = circle;
exports.default = Flatten;
exports.inversion = inversion;
exports.isWktString = isWktString;
exports.line = line;
exports.matrix = matrix;
exports.multiline = multiline;
exports.parseWKT = parseWKT;
exports.point = point;
exports.polygon = polygon;
exports.ray = ray;
Expand Down
154 changes: 153 additions & 1 deletion dist/main.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8829,6 +8829,158 @@ class Distance {

Flatten.Distance = Distance;

// POINT (30 10)
// MULTIPOINT (10 40, 40 30, 20 20, 30 10)
// LINESTRING (30 10, 10 30, 40 40)
// MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))
// MULTILINESTRING ((8503.732 4424.547, 8963.747 3964.532), (8963.747 3964.532, 8707.468 3708.253), (8707.468 3708.253, 8247.454 4168.268), (8247.454 4168.268, 8503.732 4424.547))
// POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))
// MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), ((20 35, 10 30, 10 10, 30 5, 45 20, 20 35), (30 20, 20 15, 20 25, 30 20)))

function parseSinglePoint(pointStr) {
return new Point$1(pointStr.split(' ').map(Number))
}

function parseMultiPoint(multipointStr) {
return multipointStr.split(', ').map(parseSinglePoint)
}

function parseLineString(lineStr) {
const points = parseMultiPoint(lineStr);
let segments = [];
for (let i = 0; i < points.length-1; i++) {
segments.push(new Segment(points[i], points[i+1]));
}
return new Multiline(segments)
}

function parseMultiLineString(multilineStr) {
const lineStrings = multilineStr.replace(/\(\(/, '').replace(/\)\)$/, '').split('), (');
return lineStrings.map(parseLineString)
}

function parseSinglePolygon(polygonStr) {
const facesStr = polygonStr.replace(/\(\(/, '').replace(/\)\)$/, '').split('), (');
const polygon = new Polygon();
let orientation;
facesStr.forEach((facesStr, idx) => {
let points = facesStr.split(', ').map(coordStr => {
return new Point$1(coordStr.split(' ').map(Number))
});
const face = polygon.addFace(points);
if (idx === 0) {
orientation = face.orientation();
}
else {
if (face.orientation() === orientation) {
face.reverse();
}
}
});
return polygon
}

function parseMutliPolygon(multiPolygonString) {
const polygonStrings = multiPolygonString.split('?');
const polygons = polygonStrings.map(parseSinglePolygon);
const polygon = new Polygon();
const faces = polygons.reduce((acc, polygon) => [...acc, ...polygon?.faces], []);
faces.forEach(face => polygon.addFace([...face?.shapes]));
return polygon;
}

function parsePolygon(wkt) {
if (wkt.startsWith("POLYGON")) {
const polygonStr = wkt.replace(/^POLYGON /, '');
return parseSinglePolygon(polygonStr)
}
else {
const multiPolygonString = wkt.replace(/^MULTIPOLYGON \(/, '').replace(/\)$/, '').replace(/\)\), \(\(/,'))?((');
return parseMutliPolygon(multiPolygonString)
}
}

function parseArrayOfPoints(str) {
const arr = str.split('\n').map(x => x.match(/\(([^)]+)\)/)[1]);
return arr.map(parseSinglePoint)
}

function parseArrayOfLineStrings(str) {
const arr = str.split('\n').map(x => x.match(/\(([^)]+)\)/)[1]);
return arr.map(parseLineString).reduce((acc, x) => [...acc, ...x], [])
}

/**
* Convert WKT string to array of Flatten shapes.
* @param str
* @returns {Point | Point[] | Multiline | Multiline[] | Polygon | Shape[] | null}
*/
function parseWKT(str) {
if (str.startsWith("POINT")) {
const pointStr = str.replace(/^POINT \(/, '').replace(/\)$/, '');
return parseSinglePoint(pointStr)
}
else if (str.startsWith("MULTIPOINT")) {
const multiPointStr = str.replace(/^MULTIPOINT \(/, '').replace(/\)$/, '');
return parseMultiPoint(multiPointStr)
}
else if (str.startsWith("LINESTRING")) {
const lineStr = str.replace(/^LINESTRING \(/, '').replace(/\)$/, '');
return parseLineString(lineStr)
}
else if (str.startsWith("MULTILINESTRING")) {
const multilineStr = str.replace(/^MULTILINESTRING /, '');
return parseMultiLineString(multilineStr)
}
else if (str.startsWith("POLYGON") || str.startsWith("MULTIPOLYGON")) {
return parsePolygon(str)
}
else if (str.startsWith("GEOMETRYCOLLECTION")) {
const regex = /(POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION) \([^\)]+\)/g;
const wktArray = str.match(regex);
if (wktArray[0].startsWith('GEOMETRYCOLLECTION')) {
wktArray[0] = wktArray[0].replace('GEOMETRYCOLLECTION (','');
}
const flArray = wktArray.map(parseWKT).map(x => x instanceof Array ? x : [x]);
return flArray.reduce((acc, x) => [...acc, ...x], [])
}
else if (isArrayOfPoints(str)) {
return parseArrayOfPoints(str)
}
else if (isArrayOfLines(str)) {
return parseArrayOfLineStrings(str)
}
return []
}

function isArrayOfPoints(str) {
return str.split('\n')?.every(str => str.includes('POINT'))
}

function isArrayOfLines(str) {
return str.split('\n')?.every(str => str.includes('LINESTRING'))
}

/**
* Return true if given string starts with one of WKT tags and possibly contains WKT string,
* @param str
* @returns {boolean}
*/
function isWktString(str) {
return (
str.startsWith("POINT") || isArrayOfPoints(str) ||
str.startsWith("LINESTRING") || isArrayOfLines(str) ||
str.startsWith("MULTILINESTRING") ||
str.startsWith("POLYGON") ||
str.startsWith("MULTIPOINT") ||
str.startsWith("MULTIPOLYGON") ||
str.startsWith("GEOMETRYCOLLECTION")
)
}

Flatten.isWktString = isWktString;
Flatten.parseWKT = parseWKT;

/**
* Created by Alex Bol on 2/18/2017.
*/
Expand All @@ -8837,4 +8989,4 @@ Flatten.Distance = Distance;
Flatten.BooleanOperations = BooleanOperations;
Flatten.Relations = Relations;

export { Arc, BOUNDARY$1 as BOUNDARY, BooleanOperations, Box, CCW, CW, Circle$1 as Circle, Distance, Edge, Errors, Face, INSIDE$2 as INSIDE, Inversion, Line$1 as Line, Matrix, Multiline, ORIENTATION, OUTSIDE$1 as OUTSIDE, OVERLAP_OPPOSITE$1 as OVERLAP_OPPOSITE, OVERLAP_SAME$1 as OVERLAP_SAME, PlanarSet, Point$1 as Point, Polygon, Ray, Relations, Segment, smart_intersections as SmartIntersections, Utils$1 as Utils, Vector$1 as Vector, arc, box, circle, Flatten as default, inversion, line, matrix, multiline, point, polygon, ray, ray_shoot, segment, vector$1 as vector };
export { Arc, BOUNDARY$1 as BOUNDARY, BooleanOperations, Box, CCW, CW, Circle$1 as Circle, Distance, Edge, Errors, Face, INSIDE$2 as INSIDE, Inversion, Line$1 as Line, Matrix, Multiline, ORIENTATION, OUTSIDE$1 as OUTSIDE, OVERLAP_OPPOSITE$1 as OVERLAP_OPPOSITE, OVERLAP_SAME$1 as OVERLAP_SAME, PlanarSet, Point$1 as Point, Polygon, Ray, Relations, Segment, smart_intersections as SmartIntersections, Utils$1 as Utils, Vector$1 as Vector, arc, box, circle, Flatten as default, inversion, isWktString, line, matrix, multiline, parseWKT, point, polygon, ray, ray_shoot, segment, vector$1 as vector };
Loading

0 comments on commit 4e37406

Please sign in to comment.