@team-geospan/structuresio 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/geojson.js +53 -44
- package/package.json +8 -3
package/lib/geojson.js
CHANGED
|
@@ -19,59 +19,68 @@
|
|
|
19
19
|
* Convert a StructuresJSON Structure or StructureCollection to GeoJSON
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import { isCollection } from "./helpers";
|
|
22
|
+
import { isCollection } from "./helpers.js";
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* This is written to be as clear and testable as possible.
|
|
29
|
-
* There are likely more efficient ways to loop through this loop,
|
|
30
|
-
* but this version works and is relatively easy to read.
|
|
31
|
-
*
|
|
25
|
+
* simplifyRing converts a single surface ring and coverts it to a list
|
|
26
|
+
* of points.
|
|
32
27
|
*/
|
|
33
|
-
export const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
28
|
+
export const simplifyRing = (ringEdges) => {
|
|
29
|
+
if (ringEdges.length === 0) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let edges = structuredClone(ringEdges);
|
|
34
|
+
const sortedList = [];
|
|
35
|
+
|
|
36
|
+
sortedList.push(edges.shift());
|
|
37
|
+
|
|
38
|
+
// ensure the iterations of the while loop do not exceed
|
|
39
|
+
// O(n^2), the input edge structure is likely degenerate.
|
|
40
|
+
let maxIter = edges.length * edges.length;
|
|
41
|
+
while (maxIter > 0 && edges.length > 0) {
|
|
42
|
+
for (let i = 0, len = edges.length; i < len; i++) {
|
|
43
|
+
const edge = edges[i];
|
|
44
|
+
const len = sortedList.length - 1;
|
|
45
|
+
if (sortedList[len][1] === edge[0]) {
|
|
46
|
+
sortedList.push(edge);
|
|
47
|
+
edges = edges.slice(0, i).concat(edges.slice(i + 1));
|
|
48
|
+
break;
|
|
49
|
+
} else if (sortedList[len][1] === edge[edge.length - 1]) {
|
|
50
|
+
sortedList.push(edge.reverse());
|
|
51
|
+
edges = edges.slice(0, i).concat(edges.slice(i + 1));
|
|
52
|
+
break;
|
|
59
53
|
}
|
|
60
|
-
// use slice(1) to prevent duplicate points.
|
|
61
|
-
nextPoints.slice(1).forEach((p) => edgePoints.push(p));
|
|
62
|
-
});
|
|
63
|
-
// ensure the polygon is closed.
|
|
64
|
-
if (edgePoints[0] !== edgePoints[edgePoints.length - 1]) {
|
|
65
|
-
edgePoints.push(edgePoints[0]);
|
|
66
54
|
}
|
|
67
|
-
|
|
68
|
-
|
|
55
|
+
maxIter--;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// flatten the list
|
|
59
|
+
const asPoints = sortedList.map((edge) => edge[0]);
|
|
60
|
+
// ensure the polygon is closed
|
|
61
|
+
asPoints.push(sortedList[0][0]);
|
|
62
|
+
return asPoints;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// surfaceRings returns a list of point ids based on the surfaces edges
|
|
66
|
+
const surfaceRings = (surfaceId, { surfaces, edges }) => {
|
|
67
|
+
return surfaces[surfaceId].edges.map((ring) => {
|
|
68
|
+
return ring.map((edgeId) => {
|
|
69
|
+
return edges[edgeId].points;
|
|
70
|
+
});
|
|
69
71
|
});
|
|
70
|
-
return coords;
|
|
71
72
|
};
|
|
72
73
|
|
|
73
74
|
const structureToPolygonFeature = ({ surfaces, points, edges }) => {
|
|
74
75
|
const features = Object.keys(surfaces).map((surfaceId) => {
|
|
76
|
+
const rings = surfaceRings(surfaceId, { surfaces, edges }).map((ring) =>
|
|
77
|
+
simplifyRing(ring),
|
|
78
|
+
);
|
|
79
|
+
// convert all the rings into coordinates
|
|
80
|
+
const coordinates = rings.map((ring) =>
|
|
81
|
+
ring.map((pointId) => points[pointId].coordinates),
|
|
82
|
+
);
|
|
83
|
+
|
|
75
84
|
return {
|
|
76
85
|
type: "Feature",
|
|
77
86
|
properties: {
|
|
@@ -81,7 +90,7 @@ const structureToPolygonFeature = ({ surfaces, points, edges }) => {
|
|
|
81
90
|
},
|
|
82
91
|
geometry: {
|
|
83
92
|
type: "Polygon",
|
|
84
|
-
coordinates
|
|
93
|
+
coordinates,
|
|
85
94
|
},
|
|
86
95
|
};
|
|
87
96
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@team-geospan/structuresio",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "Collection of utilities for working with StructuresJSON",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -26,16 +26,21 @@
|
|
|
26
26
|
},
|
|
27
27
|
"extends": [
|
|
28
28
|
"eslint:recommended",
|
|
29
|
-
"plugin:prettier/recommended"
|
|
29
|
+
"plugin:prettier/recommended",
|
|
30
|
+
"plugin:import/recommended"
|
|
30
31
|
],
|
|
31
32
|
"rules": {
|
|
32
|
-
"prettier/prettier": "error"
|
|
33
|
+
"prettier/prettier": "error",
|
|
34
|
+
"import/extensions": ["error", "always", {
|
|
35
|
+
"js": "always"
|
|
36
|
+
}]
|
|
33
37
|
}
|
|
34
38
|
},
|
|
35
39
|
"devDependencies": {
|
|
36
40
|
"@vitest/coverage-v8": "^3.1.1",
|
|
37
41
|
"eslint": "^8.57.0",
|
|
38
42
|
"eslint-config-prettier": "^10.0.1",
|
|
43
|
+
"eslint-plugin-import": "^2.31.0",
|
|
39
44
|
"eslint-plugin-prettier": "^5.2.3",
|
|
40
45
|
"vitest": "^3.1.1"
|
|
41
46
|
},
|