@turf/polygonize 6.5.0 → 7.0.0-alpha.0
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/README.md +7 -6
- package/dist/es/index.js +6 -6
- package/dist/es/lib/Edge.js +16 -18
- package/dist/es/lib/EdgeRing.js +49 -60
- package/dist/es/lib/Graph.js +73 -86
- package/dist/es/lib/Node.js +35 -38
- package/dist/es/lib/util.js +3 -5
- package/dist/js/index.d.ts +1 -1
- package/dist/js/index.js +10 -12
- package/dist/js/lib/Edge.d.ts +1 -1
- package/dist/js/lib/Edge.js +18 -19
- package/dist/js/lib/EdgeRing.d.ts +2 -2
- package/dist/js/lib/EdgeRing.js +53 -65
- package/dist/js/lib/Graph.d.ts +1 -1
- package/dist/js/lib/Graph.js +79 -93
- package/dist/js/lib/Node.js +36 -38
- package/dist/js/lib/util.d.ts +1 -1
- package/dist/js/lib/util.js +6 -10
- package/package.json +9 -8
package/README.md
CHANGED
|
@@ -13,17 +13,18 @@ noded, i.e., they must only meet at their endpoints.
|
|
|
13
13
|
|
|
14
14
|
The implementation correctly handles:
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
* Dangles: edges which have one or both ends which are not incident on another edge endpoint.
|
|
17
|
+
* Cut Edges (bridges): edges that are connected at both ends but which do not form part of a polygon.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
### Parameters
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
* `geoJson` **([FeatureCollection][3] | [Geometry][4] | [Feature][5]<([LineString][6] | [MultiLineString][7])>)** Lines in order to polygonize
|
|
22
22
|
|
|
23
|
+
<!---->
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
* Throws **[Error][8]** if geoJson is invalid.
|
|
25
26
|
|
|
26
|
-
Returns **[FeatureCollection][3]
|
|
27
|
+
Returns **[FeatureCollection][3]<[Polygon][9]>** Polygons created
|
|
27
28
|
|
|
28
29
|
[1]: https://tools.ietf.org/html/rfc7946#section-3.1.4
|
|
29
30
|
|
package/dist/es/index.js
CHANGED
|
@@ -20,27 +20,27 @@ import EdgeRing from "./lib/EdgeRing.js";
|
|
|
20
20
|
* @throws {Error} if geoJson is invalid.
|
|
21
21
|
*/
|
|
22
22
|
export default function polygonize(geoJson) {
|
|
23
|
-
|
|
23
|
+
const graph = Graph.fromGeoJson(geoJson);
|
|
24
24
|
// 1. Remove dangle node
|
|
25
25
|
graph.deleteDangles();
|
|
26
26
|
// 2. Remove cut-edges (bridge edges)
|
|
27
27
|
graph.deleteCutEdges();
|
|
28
28
|
// 3. Get all holes and shells
|
|
29
|
-
|
|
29
|
+
const holes = [], shells = [];
|
|
30
30
|
graph
|
|
31
31
|
.getEdgeRings()
|
|
32
|
-
.filter(
|
|
33
|
-
.forEach(
|
|
32
|
+
.filter((edgeRing) => edgeRing.isValid())
|
|
33
|
+
.forEach((edgeRing) => {
|
|
34
34
|
if (edgeRing.isHole())
|
|
35
35
|
holes.push(edgeRing);
|
|
36
36
|
else
|
|
37
37
|
shells.push(edgeRing);
|
|
38
38
|
});
|
|
39
39
|
// 4. Assign Holes to Shells
|
|
40
|
-
holes.forEach(
|
|
40
|
+
holes.forEach((hole) => {
|
|
41
41
|
if (EdgeRing.findEdgeRingContaining(hole, shells))
|
|
42
42
|
shells.push(hole);
|
|
43
43
|
});
|
|
44
44
|
// 5. EdgeRings to Polygons
|
|
45
|
-
return featureCollection(shells.map(
|
|
45
|
+
return featureCollection(shells.map((shell) => shell.toPolygon()));
|
|
46
46
|
}
|
package/dist/es/lib/Edge.js
CHANGED
|
@@ -3,12 +3,12 @@ import { orientationIndex } from "./util.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* This class is inspired by GEOS's geos::operation::polygonize::PolygonizeDirectedEdge
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
export default class Edge {
|
|
7
7
|
/**
|
|
8
8
|
* @param {Node} from - start node of the Edge
|
|
9
9
|
* @param {Node} to - end node of the edge
|
|
10
10
|
*/
|
|
11
|
-
|
|
11
|
+
constructor(from, to) {
|
|
12
12
|
this.from = from; //< start
|
|
13
13
|
this.to = to; //< End
|
|
14
14
|
this.next = undefined; //< The edge to be computed after
|
|
@@ -23,20 +23,20 @@ var Edge = /** @class */ (function () {
|
|
|
23
23
|
*
|
|
24
24
|
* @returns {Edge} - Symetric Edge.
|
|
25
25
|
*/
|
|
26
|
-
|
|
26
|
+
getSymetric() {
|
|
27
27
|
if (!this.symetric) {
|
|
28
28
|
this.symetric = new Edge(this.to, this.from);
|
|
29
29
|
this.symetric.symetric = this;
|
|
30
30
|
}
|
|
31
31
|
return this.symetric;
|
|
32
|
-
}
|
|
32
|
+
}
|
|
33
33
|
/**
|
|
34
34
|
* Removes edge from from and to nodes.
|
|
35
35
|
*/
|
|
36
|
-
|
|
36
|
+
deleteEdge() {
|
|
37
37
|
this.from.removeOuterEdge(this);
|
|
38
38
|
this.to.removeInnerEdge(this);
|
|
39
|
-
}
|
|
39
|
+
}
|
|
40
40
|
/**
|
|
41
41
|
* Compares Edge equallity.
|
|
42
42
|
*
|
|
@@ -45,20 +45,20 @@ var Edge = /** @class */ (function () {
|
|
|
45
45
|
* @param {Edge} edge - Another Edge
|
|
46
46
|
* @returns {boolean} - True if Edges are equal, False otherwise
|
|
47
47
|
*/
|
|
48
|
-
|
|
48
|
+
isEqual(edge) {
|
|
49
49
|
return this.from.id === edge.from.id && this.to.id === edge.to.id;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return
|
|
53
|
-
}
|
|
50
|
+
}
|
|
51
|
+
toString() {
|
|
52
|
+
return `Edge { ${this.from.id} -> ${this.to.id} }`;
|
|
53
|
+
}
|
|
54
54
|
/**
|
|
55
55
|
* Returns a LineString representation of the Edge
|
|
56
56
|
*
|
|
57
57
|
* @returns {Feature<LineString>} - LineString representation of the Edge
|
|
58
58
|
*/
|
|
59
|
-
|
|
59
|
+
toLineString() {
|
|
60
60
|
return lineString([this.from.coordinates, this.to.coordinates]);
|
|
61
|
-
}
|
|
61
|
+
}
|
|
62
62
|
/**
|
|
63
63
|
* Comparator of two edges.
|
|
64
64
|
*
|
|
@@ -69,9 +69,7 @@ var Edge = /** @class */ (function () {
|
|
|
69
69
|
* 0 if the Edges are colinear,
|
|
70
70
|
* 1 otherwise
|
|
71
71
|
*/
|
|
72
|
-
|
|
72
|
+
compareTo(edge) {
|
|
73
73
|
return orientationIndex(edge.from.coordinates, edge.to.coordinates, this.to.coordinates);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
}());
|
|
77
|
-
export default Edge;
|
|
74
|
+
}
|
|
75
|
+
}
|
package/dist/es/lib/EdgeRing.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { orientationIndex, envelopeIsEqual, envelopeContains, coordinatesEqual, } from "./util.js";
|
|
2
|
-
import { multiPoint, polygon, point
|
|
2
|
+
import { multiPoint, polygon, point } from "@turf/helpers";
|
|
3
3
|
import envelope from "@turf/envelope";
|
|
4
4
|
import booleanPointInPolygon from "@turf/boolean-point-in-polygon";
|
|
5
5
|
/**
|
|
@@ -9,8 +9,8 @@ import booleanPointInPolygon from "@turf/boolean-point-in-polygon";
|
|
|
9
9
|
*
|
|
10
10
|
* This class is inspired in GEOS's geos::operation::polygonize::EdgeRing
|
|
11
11
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
export default class EdgeRing {
|
|
13
|
+
constructor() {
|
|
14
14
|
this.edges = [];
|
|
15
15
|
this.polygon = undefined; //< Caches Polygon representation
|
|
16
16
|
this.envelope = undefined; //< Caches Envelope representation
|
|
@@ -21,10 +21,10 @@ var EdgeRing = /** @class */ (function () {
|
|
|
21
21
|
* @memberof EdgeRing
|
|
22
22
|
* @param {Edge} edge - Edge to be inserted
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
push(edge) {
|
|
25
25
|
this.edges.push(edge);
|
|
26
26
|
this.polygon = this.envelope = undefined;
|
|
27
|
-
}
|
|
27
|
+
}
|
|
28
28
|
/**
|
|
29
29
|
* Get Edge.
|
|
30
30
|
*
|
|
@@ -32,31 +32,27 @@ var EdgeRing = /** @class */ (function () {
|
|
|
32
32
|
* @param {number} i - Index
|
|
33
33
|
* @returns {Edge} - Edge in the i position
|
|
34
34
|
*/
|
|
35
|
-
|
|
35
|
+
get(i) {
|
|
36
36
|
return this.edges[i];
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
},
|
|
48
|
-
enumerable: true,
|
|
49
|
-
configurable: true
|
|
50
|
-
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Getter of length property.
|
|
40
|
+
*
|
|
41
|
+
* @memberof EdgeRing
|
|
42
|
+
* @returns {number} - Length of the edge ring.
|
|
43
|
+
*/
|
|
44
|
+
get length() {
|
|
45
|
+
return this.edges.length;
|
|
46
|
+
}
|
|
51
47
|
/**
|
|
52
48
|
* Similar to Array.prototype.forEach for the list of Edges in the EdgeRing.
|
|
53
49
|
*
|
|
54
50
|
* @memberof EdgeRing
|
|
55
51
|
* @param {Function} f - The same function to be passed to Array.prototype.forEach
|
|
56
52
|
*/
|
|
57
|
-
|
|
53
|
+
forEach(f) {
|
|
58
54
|
this.edges.forEach(f);
|
|
59
|
-
}
|
|
55
|
+
}
|
|
60
56
|
/**
|
|
61
57
|
* Similar to Array.prototype.map for the list of Edges in the EdgeRing.
|
|
62
58
|
*
|
|
@@ -64,9 +60,9 @@ var EdgeRing = /** @class */ (function () {
|
|
|
64
60
|
* @param {Function} f - The same function to be passed to Array.prototype.map
|
|
65
61
|
* @returns {Array} - The mapped values in the function
|
|
66
62
|
*/
|
|
67
|
-
|
|
63
|
+
map(f) {
|
|
68
64
|
return this.edges.map(f);
|
|
69
|
-
}
|
|
65
|
+
}
|
|
70
66
|
/**
|
|
71
67
|
* Similar to Array.prototype.some for the list of Edges in the EdgeRing.
|
|
72
68
|
*
|
|
@@ -74,9 +70,9 @@ var EdgeRing = /** @class */ (function () {
|
|
|
74
70
|
* @param {Function} f - The same function to be passed to Array.prototype.some
|
|
75
71
|
* @returns {boolean} - True if an Edge check the condition
|
|
76
72
|
*/
|
|
77
|
-
|
|
73
|
+
some(f) {
|
|
78
74
|
return this.edges.some(f);
|
|
79
|
-
}
|
|
75
|
+
}
|
|
80
76
|
/**
|
|
81
77
|
* Check if the ring is valid in geomtry terms.
|
|
82
78
|
*
|
|
@@ -87,10 +83,10 @@ var EdgeRing = /** @class */ (function () {
|
|
|
87
83
|
* @memberof EdgeRing
|
|
88
84
|
* @returns {boolean} - Validity of the EdgeRing
|
|
89
85
|
*/
|
|
90
|
-
|
|
86
|
+
isValid() {
|
|
91
87
|
// TODO: stub
|
|
92
88
|
return true;
|
|
93
|
-
}
|
|
89
|
+
}
|
|
94
90
|
/**
|
|
95
91
|
* Tests whether this ring is a hole.
|
|
96
92
|
*
|
|
@@ -100,12 +96,11 @@ var EdgeRing = /** @class */ (function () {
|
|
|
100
96
|
* @memberof EdgeRing
|
|
101
97
|
* @returns {boolean} - true: if it is a hole
|
|
102
98
|
*/
|
|
103
|
-
|
|
104
|
-
var _this = this;
|
|
99
|
+
isHole() {
|
|
105
100
|
// XXX: Assuming Ring is valid
|
|
106
101
|
// Find highest point
|
|
107
|
-
|
|
108
|
-
if (edge.from.coordinates[1] >
|
|
102
|
+
const hiIndex = this.edges.reduce((high, edge, i) => {
|
|
103
|
+
if (edge.from.coordinates[1] > this.edges[high].from.coordinates[1])
|
|
109
104
|
high = i;
|
|
110
105
|
return high;
|
|
111
106
|
}, 0), iPrev = (hiIndex === 0 ? this.length : hiIndex) - 1, iNext = (hiIndex + 1) % this.length, disc = orientationIndex(this.edges[iPrev].from.coordinates, this.edges[hiIndex].from.coordinates, this.edges[iNext].from.coordinates);
|
|
@@ -113,40 +108,40 @@ var EdgeRing = /** @class */ (function () {
|
|
|
113
108
|
return (this.edges[iPrev].from.coordinates[0] >
|
|
114
109
|
this.edges[iNext].from.coordinates[0]);
|
|
115
110
|
return disc > 0;
|
|
116
|
-
}
|
|
111
|
+
}
|
|
117
112
|
/**
|
|
118
113
|
* Creates a MultiPoint representing the EdgeRing (discarts edges directions).
|
|
119
114
|
*
|
|
120
115
|
* @memberof EdgeRing
|
|
121
116
|
* @returns {Feature<MultiPoint>} - Multipoint representation of the EdgeRing
|
|
122
117
|
*/
|
|
123
|
-
|
|
124
|
-
return multiPoint(this.edges.map(
|
|
125
|
-
}
|
|
118
|
+
toMultiPoint() {
|
|
119
|
+
return multiPoint(this.edges.map((edge) => edge.from.coordinates));
|
|
120
|
+
}
|
|
126
121
|
/**
|
|
127
122
|
* Creates a Polygon representing the EdgeRing.
|
|
128
123
|
*
|
|
129
124
|
* @memberof EdgeRing
|
|
130
125
|
* @returns {Feature<Polygon>} - Polygon representation of the Edge Ring
|
|
131
126
|
*/
|
|
132
|
-
|
|
127
|
+
toPolygon() {
|
|
133
128
|
if (this.polygon)
|
|
134
129
|
return this.polygon;
|
|
135
|
-
|
|
130
|
+
const coordinates = this.edges.map((edge) => edge.from.coordinates);
|
|
136
131
|
coordinates.push(this.edges[0].from.coordinates);
|
|
137
132
|
return (this.polygon = polygon([coordinates]));
|
|
138
|
-
}
|
|
133
|
+
}
|
|
139
134
|
/**
|
|
140
135
|
* Calculates the envelope of the EdgeRing.
|
|
141
136
|
*
|
|
142
137
|
* @memberof EdgeRing
|
|
143
138
|
* @returns {Feature<Polygon>} - envelope
|
|
144
139
|
*/
|
|
145
|
-
|
|
140
|
+
getEnvelope() {
|
|
146
141
|
if (this.envelope)
|
|
147
142
|
return this.envelope;
|
|
148
143
|
return (this.envelope = envelope(this.toPolygon()));
|
|
149
|
-
}
|
|
144
|
+
}
|
|
150
145
|
/**
|
|
151
146
|
* `geos::operation::polygonize::EdgeRing::findEdgeRingContaining`
|
|
152
147
|
*
|
|
@@ -155,27 +150,23 @@ var EdgeRing = /** @class */ (function () {
|
|
|
155
150
|
*
|
|
156
151
|
* @returns {EdgeRing} - EdgeRing which contains the testEdgeRing
|
|
157
152
|
*/
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
shellList.forEach(
|
|
162
|
-
|
|
153
|
+
static findEdgeRingContaining(testEdgeRing, shellList) {
|
|
154
|
+
const testEnvelope = testEdgeRing.getEnvelope();
|
|
155
|
+
let minEnvelope, minShell;
|
|
156
|
+
shellList.forEach((shell) => {
|
|
157
|
+
const tryEnvelope = shell.getEnvelope();
|
|
163
158
|
if (minShell)
|
|
164
159
|
minEnvelope = minShell.getEnvelope();
|
|
165
160
|
// the hole envelope cannot equal the shell envelope
|
|
166
161
|
if (envelopeIsEqual(tryEnvelope, testEnvelope))
|
|
167
162
|
return;
|
|
168
163
|
if (envelopeContains(tryEnvelope, testEnvelope)) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (!shell.some(
|
|
164
|
+
const testEdgeRingCoordinates = testEdgeRing.map((edge) => edge.from.coordinates);
|
|
165
|
+
let testPoint;
|
|
166
|
+
for (const pt of testEdgeRingCoordinates) {
|
|
167
|
+
if (!shell.some((edge) => coordinatesEqual(pt, edge.from.coordinates))) {
|
|
173
168
|
testPoint = pt;
|
|
174
169
|
}
|
|
175
|
-
};
|
|
176
|
-
for (var _i = 0, testEdgeRingCoordinates_1 = testEdgeRingCoordinates; _i < testEdgeRingCoordinates_1.length; _i++) {
|
|
177
|
-
var pt = testEdgeRingCoordinates_1[_i];
|
|
178
|
-
_loop_1(pt);
|
|
179
170
|
}
|
|
180
171
|
if (testPoint && shell.inside(point(testPoint))) {
|
|
181
172
|
if (!minShell || envelopeContains(minEnvelope, tryEnvelope))
|
|
@@ -184,16 +175,14 @@ var EdgeRing = /** @class */ (function () {
|
|
|
184
175
|
}
|
|
185
176
|
});
|
|
186
177
|
return minShell;
|
|
187
|
-
}
|
|
178
|
+
}
|
|
188
179
|
/**
|
|
189
180
|
* Checks if the point is inside the edgeRing
|
|
190
181
|
*
|
|
191
182
|
* @param {Feature<Point>} pt - Point to check if it is inside the edgeRing
|
|
192
183
|
* @returns {boolean} - True if it is inside, False otherwise
|
|
193
184
|
*/
|
|
194
|
-
|
|
185
|
+
inside(pt) {
|
|
195
186
|
return booleanPointInPolygon(pt, this.toPolygon());
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
}());
|
|
199
|
-
export default EdgeRing;
|
|
187
|
+
}
|
|
188
|
+
}
|