@turf/polygonize 7.0.0-alpha.2 → 7.1.0-alpha.7

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.
@@ -1,289 +0,0 @@
1
- import Node from "./Node.js";
2
- import Edge from "./Edge.js";
3
- import EdgeRing from "./EdgeRing.js";
4
- import { flattenEach, coordReduce } from "@turf/meta";
5
- import { featureOf } from "@turf/invariant";
6
- /**
7
- * Validates the geoJson.
8
- *
9
- * @param {GeoJSON} geoJson - input geoJson.
10
- * @throws {Error} if geoJson is invalid.
11
- */
12
- function validateGeoJson(geoJson) {
13
- if (!geoJson)
14
- throw new Error("No geojson passed");
15
- if (geoJson.type !== "FeatureCollection" &&
16
- geoJson.type !== "GeometryCollection" &&
17
- geoJson.type !== "MultiLineString" &&
18
- geoJson.type !== "LineString" &&
19
- geoJson.type !== "Feature")
20
- throw new Error(`Invalid input type '${geoJson.type}'. Geojson must be FeatureCollection, GeometryCollection, LineString, MultiLineString or Feature`);
21
- }
22
- /**
23
- * Represents a planar graph of edges and nodes that can be used to compute a polygonization.
24
- *
25
- * Although, this class is inspired by GEOS's `geos::operation::polygonize::PolygonizeGraph`,
26
- * it isn't a rewrite. As regards algorithm, this class implements the same logic, but it
27
- * isn't a javascript transcription of the C++ source.
28
- *
29
- * This graph is directed (both directions are created)
30
- */
31
- export default class Graph {
32
- constructor() {
33
- this.edges = []; //< {Edge[]} dirEdges
34
- // The key is the `id` of the Node (ie: coordinates.join(','))
35
- this.nodes = {};
36
- }
37
- /**
38
- * Creates a graph from a GeoJSON.
39
- *
40
- * @param {FeatureCollection<LineString>} geoJson - it must comply with the restrictions detailed in the index
41
- * @returns {Graph} - The newly created graph
42
- * @throws {Error} if geoJson is invalid.
43
- */
44
- static fromGeoJson(geoJson) {
45
- validateGeoJson(geoJson);
46
- const graph = new Graph();
47
- flattenEach(geoJson, (feature) => {
48
- featureOf(feature, "LineString", "Graph::fromGeoJson");
49
- // When a LineString if formed by many segments, split them
50
- coordReduce(feature, (prev, cur) => {
51
- if (prev) {
52
- const start = graph.getNode(prev), end = graph.getNode(cur);
53
- graph.addEdge(start, end);
54
- }
55
- return cur;
56
- });
57
- });
58
- return graph;
59
- }
60
- /**
61
- * Creates or get a Node.
62
- *
63
- * @param {number[]} coordinates - Coordinates of the node
64
- * @returns {Node} - The created or stored node
65
- */
66
- getNode(coordinates) {
67
- const id = Node.buildId(coordinates);
68
- let node = this.nodes[id];
69
- if (!node)
70
- node = this.nodes[id] = new Node(coordinates);
71
- return node;
72
- }
73
- /**
74
- * Adds an Edge and its symetricall.
75
- *
76
- * Edges are added symetrically, i.e.: we also add its symetric
77
- *
78
- * @param {Node} from - Node which starts the Edge
79
- * @param {Node} to - Node which ends the Edge
80
- */
81
- addEdge(from, to) {
82
- const edge = new Edge(from, to), symetricEdge = edge.getSymetric();
83
- this.edges.push(edge);
84
- this.edges.push(symetricEdge);
85
- }
86
- /**
87
- * Removes Dangle Nodes (nodes with grade 1).
88
- */
89
- deleteDangles() {
90
- Object.keys(this.nodes)
91
- .map((id) => this.nodes[id])
92
- .forEach((node) => this._removeIfDangle(node));
93
- }
94
- /**
95
- * Check if node is dangle, if so, remove it.
96
- *
97
- * It calls itself recursively, removing a dangling node might cause another dangling node
98
- *
99
- * @param {Node} node - Node to check if it's a dangle
100
- */
101
- _removeIfDangle(node) {
102
- // As edges are directed and symetrical, we count only innerEdges
103
- if (node.innerEdges.length <= 1) {
104
- const outerNodes = node.getOuterEdges().map((e) => e.to);
105
- this.removeNode(node);
106
- outerNodes.forEach((n) => this._removeIfDangle(n));
107
- }
108
- }
109
- /**
110
- * Delete cut-edges (bridge edges).
111
- *
112
- * The graph will be traversed, all the edges will be labeled according the ring
113
- * in which they are. (The label is a number incremented by 1). Edges with the same
114
- * label are cut-edges.
115
- */
116
- deleteCutEdges() {
117
- this._computeNextCWEdges();
118
- this._findLabeledEdgeRings();
119
- // Cut-edges (bridges) are edges where both edges have the same label
120
- this.edges.forEach((edge) => {
121
- if (edge.label === edge.symetric.label) {
122
- this.removeEdge(edge.symetric);
123
- this.removeEdge(edge);
124
- }
125
- });
126
- }
127
- /**
128
- * Set the `next` property of each Edge.
129
- *
130
- * The graph will be transversed in a CW form, so, we set the next of the symetrical edge as the previous one.
131
- * OuterEdges are sorted CCW.
132
- *
133
- * @param {Node} [node] - If no node is passed, the function calls itself for every node in the Graph
134
- */
135
- _computeNextCWEdges(node) {
136
- if (typeof node === "undefined") {
137
- Object.keys(this.nodes).forEach((id) => this._computeNextCWEdges(this.nodes[id]));
138
- }
139
- else {
140
- node.getOuterEdges().forEach((edge, i) => {
141
- node.getOuterEdge((i === 0 ? node.getOuterEdges().length : i) - 1).symetric.next = edge;
142
- });
143
- }
144
- }
145
- /**
146
- * Computes the next edge pointers going CCW around the given node, for the given edgering label.
147
- *
148
- * This algorithm has the effect of converting maximal edgerings into minimal edgerings
149
- *
150
- * XXX: method literally transcribed from `geos::operation::polygonize::PolygonizeGraph::computeNextCCWEdges`,
151
- * could be written in a more javascript way.
152
- *
153
- * @param {Node} node - Node
154
- * @param {number} label - Ring's label
155
- */
156
- _computeNextCCWEdges(node, label) {
157
- const edges = node.getOuterEdges();
158
- let firstOutDE, prevInDE;
159
- for (let i = edges.length - 1; i >= 0; --i) {
160
- let de = edges[i], sym = de.symetric, outDE, inDE;
161
- if (de.label === label)
162
- outDE = de;
163
- if (sym.label === label)
164
- inDE = sym;
165
- if (!outDE || !inDE)
166
- // This edge is not in edgering
167
- continue;
168
- if (inDE)
169
- prevInDE = inDE;
170
- if (outDE) {
171
- if (prevInDE) {
172
- prevInDE.next = outDE;
173
- prevInDE = undefined;
174
- }
175
- if (!firstOutDE)
176
- firstOutDE = outDE;
177
- }
178
- }
179
- if (prevInDE)
180
- prevInDE.next = firstOutDE;
181
- }
182
- /**
183
- * Finds rings and labels edges according to which rings are.
184
- *
185
- * The label is a number which is increased for each ring.
186
- *
187
- * @returns {Edge[]} edges that start rings
188
- */
189
- _findLabeledEdgeRings() {
190
- const edgeRingStarts = [];
191
- let label = 0;
192
- this.edges.forEach((edge) => {
193
- if (edge.label >= 0)
194
- return;
195
- edgeRingStarts.push(edge);
196
- let e = edge;
197
- do {
198
- e.label = label;
199
- e = e.next;
200
- } while (!edge.isEqual(e));
201
- label++;
202
- });
203
- return edgeRingStarts;
204
- }
205
- /**
206
- * Computes the EdgeRings formed by the edges in this graph.
207
- *
208
- * @returns {EdgeRing[]} - A list of all the EdgeRings in the graph.
209
- */
210
- getEdgeRings() {
211
- this._computeNextCWEdges();
212
- // Clear labels
213
- this.edges.forEach((edge) => {
214
- edge.label = undefined;
215
- });
216
- this._findLabeledEdgeRings().forEach((edge) => {
217
- // convertMaximalToMinimalEdgeRings
218
- this._findIntersectionNodes(edge).forEach((node) => {
219
- this._computeNextCCWEdges(node, edge.label);
220
- });
221
- });
222
- const edgeRingList = [];
223
- // find all edgerings
224
- this.edges.forEach((edge) => {
225
- if (edge.ring)
226
- return;
227
- edgeRingList.push(this._findEdgeRing(edge));
228
- });
229
- return edgeRingList;
230
- }
231
- /**
232
- * Find all nodes in a Maxima EdgeRing which are self-intersection nodes.
233
- *
234
- * @param {Node} startEdge - Start Edge of the Ring
235
- * @returns {Node[]} - intersection nodes
236
- */
237
- _findIntersectionNodes(startEdge) {
238
- const intersectionNodes = [];
239
- let edge = startEdge;
240
- do {
241
- // getDegree
242
- let degree = 0;
243
- edge.from.getOuterEdges().forEach((e) => {
244
- if (e.label === startEdge.label)
245
- ++degree;
246
- });
247
- if (degree > 1)
248
- intersectionNodes.push(edge.from);
249
- edge = edge.next;
250
- } while (!startEdge.isEqual(edge));
251
- return intersectionNodes;
252
- }
253
- /**
254
- * Get the edge-ring which starts from the provided Edge.
255
- *
256
- * @param {Edge} startEdge - starting edge of the edge ring
257
- * @returns {EdgeRing} - EdgeRing which start Edge is the provided one.
258
- */
259
- _findEdgeRing(startEdge) {
260
- let edge = startEdge;
261
- const edgeRing = new EdgeRing();
262
- do {
263
- edgeRing.push(edge);
264
- edge.ring = edgeRing;
265
- edge = edge.next;
266
- } while (!startEdge.isEqual(edge));
267
- return edgeRing;
268
- }
269
- /**
270
- * Removes a node from the Graph.
271
- *
272
- * It also removes edges asociated to that node
273
- * @param {Node} node - Node to be removed
274
- */
275
- removeNode(node) {
276
- node.getOuterEdges().forEach((edge) => this.removeEdge(edge));
277
- node.innerEdges.forEach((edge) => this.removeEdge(edge));
278
- delete this.nodes[node.id];
279
- }
280
- /**
281
- * Remove edge from the graph and deletes the edge.
282
- *
283
- * @param {Edge} edge - Edge to be removed
284
- */
285
- removeEdge(edge) {
286
- this.edges = this.edges.filter((e) => !e.isEqual(edge));
287
- edge.deleteEdge();
288
- }
289
- }
@@ -1,90 +0,0 @@
1
- import { orientationIndex } from "./util.js";
2
- /**
3
- * Node
4
- */
5
- export default class Node {
6
- constructor(coordinates) {
7
- this.id = Node.buildId(coordinates);
8
- this.coordinates = coordinates; //< {Number[]}
9
- this.innerEdges = []; //< {Edge[]}
10
- // We wil store to (out) edges in an CCW order as geos::planargraph::DirectedEdgeStar does
11
- this.outerEdges = []; //< {Edge[]}
12
- this.outerEdgesSorted = false; //< {Boolean} flag that stores if the outer Edges had been sorted
13
- }
14
- static buildId(coordinates) {
15
- return coordinates.join(",");
16
- }
17
- removeInnerEdge(edge) {
18
- this.innerEdges = this.innerEdges.filter((e) => e.from.id !== edge.from.id);
19
- }
20
- removeOuterEdge(edge) {
21
- this.outerEdges = this.outerEdges.filter((e) => e.to.id !== edge.to.id);
22
- }
23
- /**
24
- * Outer edges are stored CCW order.
25
- *
26
- * @memberof Node
27
- * @param {Edge} edge - Edge to add as an outerEdge.
28
- */
29
- addOuterEdge(edge) {
30
- this.outerEdges.push(edge);
31
- this.outerEdgesSorted = false;
32
- }
33
- /**
34
- * Sorts outer edges in CCW way.
35
- *
36
- * @memberof Node
37
- * @private
38
- */
39
- sortOuterEdges() {
40
- if (!this.outerEdgesSorted) {
41
- //this.outerEdges.sort((a, b) => a.compareTo(b));
42
- // Using this comparator in order to be deterministic
43
- this.outerEdges.sort((a, b) => {
44
- const aNode = a.to, bNode = b.to;
45
- if (aNode.coordinates[0] - this.coordinates[0] >= 0 &&
46
- bNode.coordinates[0] - this.coordinates[0] < 0)
47
- return 1;
48
- if (aNode.coordinates[0] - this.coordinates[0] < 0 &&
49
- bNode.coordinates[0] - this.coordinates[0] >= 0)
50
- return -1;
51
- if (aNode.coordinates[0] - this.coordinates[0] === 0 &&
52
- bNode.coordinates[0] - this.coordinates[0] === 0) {
53
- if (aNode.coordinates[1] - this.coordinates[1] >= 0 ||
54
- bNode.coordinates[1] - this.coordinates[1] >= 0)
55
- return aNode.coordinates[1] - bNode.coordinates[1];
56
- return bNode.coordinates[1] - aNode.coordinates[1];
57
- }
58
- const det = orientationIndex(this.coordinates, aNode.coordinates, bNode.coordinates);
59
- if (det < 0)
60
- return 1;
61
- if (det > 0)
62
- return -1;
63
- const d1 = Math.pow(aNode.coordinates[0] - this.coordinates[0], 2) +
64
- Math.pow(aNode.coordinates[1] - this.coordinates[1], 2), d2 = Math.pow(bNode.coordinates[0] - this.coordinates[0], 2) +
65
- Math.pow(bNode.coordinates[1] - this.coordinates[1], 2);
66
- return d1 - d2;
67
- });
68
- this.outerEdgesSorted = true;
69
- }
70
- }
71
- /**
72
- * Retrieves outer edges.
73
- *
74
- * They are sorted if they aren't in the CCW order.
75
- *
76
- * @memberof Node
77
- * @returns {Edge[]} - List of outer edges sorted in a CCW order.
78
- */
79
- getOuterEdges() {
80
- this.sortOuterEdges();
81
- return this.outerEdges;
82
- }
83
- getOuterEdge(i) {
84
- this.sortOuterEdges();
85
- return this.outerEdges[i];
86
- }
87
- addInnerEdge(edge) {
88
- this.innerEdges.push(edge);
89
- }
90
- }
@@ -1,64 +0,0 @@
1
- import booleanPointInPolygon from "@turf/boolean-point-in-polygon";
2
- import { point } from "@turf/helpers";
3
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign#Polyfill
4
- function mathSign(x) {
5
- return ((x > 0) - (x < 0) || +x);
6
- }
7
- /**
8
- * Returns the direction of the point q relative to the vector p1 -> p2.
9
- *
10
- * Implementation of geos::algorithm::CGAlgorithm::orientationIndex()
11
- * (same as geos::algorithm::CGAlgorithm::computeOrientation())
12
- *
13
- * @param {number[]} p1 - the origin point of the vector
14
- * @param {number[]} p2 - the final point of the vector
15
- * @param {number[]} q - the point to compute the direction to
16
- *
17
- * @returns {number} - 1 if q is ccw (left) from p1->p2,
18
- * -1 if q is cw (right) from p1->p2,
19
- * 0 if q is colinear with p1->p2
20
- */
21
- export function orientationIndex(p1, p2, q) {
22
- const dx1 = p2[0] - p1[0], dy1 = p2[1] - p1[1], dx2 = q[0] - p2[0], dy2 = q[1] - p2[1];
23
- return mathSign(dx1 * dy2 - dx2 * dy1);
24
- }
25
- /**
26
- * Checks if two envelopes are equal.
27
- *
28
- * The function assumes that the arguments are envelopes, i.e.: Rectangular polygon
29
- *
30
- * @param {Feature<Polygon>} env1 - Envelope
31
- * @param {Feature<Polygon>} env2 - Envelope
32
- * @returns {boolean} - True if the envelopes are equal
33
- */
34
- export function envelopeIsEqual(env1, env2) {
35
- const envX1 = env1.geometry.coordinates[0].map((c) => c[0]), envY1 = env1.geometry.coordinates[0].map((c) => c[1]), envX2 = env2.geometry.coordinates[0].map((c) => c[0]), envY2 = env2.geometry.coordinates[0].map((c) => c[1]);
36
- return (Math.max.apply(null, envX1) === Math.max.apply(null, envX2) &&
37
- Math.max.apply(null, envY1) === Math.max.apply(null, envY2) &&
38
- Math.min.apply(null, envX1) === Math.min.apply(null, envX2) &&
39
- Math.min.apply(null, envY1) === Math.min.apply(null, envY2));
40
- }
41
- /**
42
- * Check if a envelope is contained in other one.
43
- *
44
- * The function assumes that the arguments are envelopes, i.e.: Convex polygon
45
- * XXX: Envelopes are rectangular, checking if a point is inside a rectangule is something easy,
46
- * this could be further improved.
47
- *
48
- * @param {Feature<Polygon>} self - Envelope
49
- * @param {Feature<Polygon>} env - Envelope
50
- * @returns {boolean} - True if env is contained in self
51
- */
52
- export function envelopeContains(self, env) {
53
- return env.geometry.coordinates[0].every((c) => booleanPointInPolygon(point(c), self));
54
- }
55
- /**
56
- * Checks if two coordinates are equal.
57
- *
58
- * @param {number[]} coord1 - First coordinate
59
- * @param {number[]} coord2 - Second coordinate
60
- * @returns {boolean} - True if coordinates are equal
61
- */
62
- export function coordinatesEqual(coord1, coord2) {
63
- return coord1[0] === coord2[0] && coord1[1] === coord2[1];
64
- }
@@ -1 +0,0 @@
1
- {"type":"module"}
package/dist/js/index.js DELETED
@@ -1,50 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- const helpers_1 = require("@turf/helpers");
5
- const Graph_1 = tslib_1.__importDefault(require("./lib/Graph"));
6
- const EdgeRing_1 = tslib_1.__importDefault(require("./lib/EdgeRing"));
7
- /**
8
- * Polygonizes {@link LineString|(Multi)LineString(s)} into {@link Polygons}.
9
- *
10
- * Implementation of GEOSPolygonize function (`geos::operation::polygonize::Polygonizer`).
11
- *
12
- * Polygonizes a set of lines that represents edges in a planar graph. Edges must be correctly
13
- * noded, i.e., they must only meet at their endpoints.
14
- *
15
- * The implementation correctly handles:
16
- *
17
- * - Dangles: edges which have one or both ends which are not incident on another edge endpoint.
18
- * - Cut Edges (bridges): edges that are connected at both ends but which do not form part of a polygon.
19
- *
20
- * @name polygonize
21
- * @param {FeatureCollection|Geometry|Feature<LineString|MultiLineString>} geoJson Lines in order to polygonize
22
- * @returns {FeatureCollection<Polygon>} Polygons created
23
- * @throws {Error} if geoJson is invalid.
24
- */
25
- function polygonize(geoJson) {
26
- const graph = Graph_1.default.fromGeoJson(geoJson);
27
- // 1. Remove dangle node
28
- graph.deleteDangles();
29
- // 2. Remove cut-edges (bridge edges)
30
- graph.deleteCutEdges();
31
- // 3. Get all holes and shells
32
- const holes = [], shells = [];
33
- graph
34
- .getEdgeRings()
35
- .filter((edgeRing) => edgeRing.isValid())
36
- .forEach((edgeRing) => {
37
- if (edgeRing.isHole())
38
- holes.push(edgeRing);
39
- else
40
- shells.push(edgeRing);
41
- });
42
- // 4. Assign Holes to Shells
43
- holes.forEach((hole) => {
44
- if (EdgeRing_1.default.findEdgeRingContaining(hole, shells))
45
- shells.push(hole);
46
- });
47
- // 5. EdgeRings to Polygons
48
- return helpers_1.featureCollection(shells.map((shell) => shell.toPolygon()));
49
- }
50
- exports.default = polygonize;
@@ -1,55 +0,0 @@
1
- import Node from "./Node";
2
- import EdgeRing from "./EdgeRing";
3
- /**
4
- * This class is inspired by GEOS's geos::operation::polygonize::PolygonizeDirectedEdge
5
- */
6
- export default class Edge {
7
- label?: number;
8
- symetric?: Edge;
9
- from: Node;
10
- to: Node;
11
- next?: Edge;
12
- ring?: EdgeRing;
13
- /**
14
- * Creates or get the symetric Edge.
15
- *
16
- * @returns {Edge} - Symetric Edge.
17
- */
18
- getSymetric(): Edge;
19
- /**
20
- * @param {Node} from - start node of the Edge
21
- * @param {Node} to - end node of the edge
22
- */
23
- constructor(from: Node, to: Node);
24
- /**
25
- * Removes edge from from and to nodes.
26
- */
27
- deleteEdge(): void;
28
- /**
29
- * Compares Edge equallity.
30
- *
31
- * An edge is equal to another, if the from and to nodes are the same.
32
- *
33
- * @param {Edge} edge - Another Edge
34
- * @returns {boolean} - True if Edges are equal, False otherwise
35
- */
36
- isEqual(edge: Edge): boolean;
37
- toString(): string;
38
- /**
39
- * Returns a LineString representation of the Edge
40
- *
41
- * @returns {Feature<LineString>} - LineString representation of the Edge
42
- */
43
- toLineString(): import("geojson").Feature<import("geojson").LineString, import("geojson").GeoJsonProperties>;
44
- /**
45
- * Comparator of two edges.
46
- *
47
- * Implementation of geos::planargraph::DirectedEdge::compareTo.
48
- *
49
- * @param {Edge} edge - Another edge to compare with this one
50
- * @returns {number} -1 if this Edge has a greater angle with the positive x-axis than b,
51
- * 0 if the Edges are colinear,
52
- * 1 otherwise
53
- */
54
- compareTo(edge: Edge): number;
55
- }
@@ -1,78 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const helpers_1 = require("@turf/helpers");
4
- const util_1 = require("./util");
5
- /**
6
- * This class is inspired by GEOS's geos::operation::polygonize::PolygonizeDirectedEdge
7
- */
8
- class Edge {
9
- /**
10
- * @param {Node} from - start node of the Edge
11
- * @param {Node} to - end node of the edge
12
- */
13
- constructor(from, to) {
14
- this.from = from; //< start
15
- this.to = to; //< End
16
- this.next = undefined; //< The edge to be computed after
17
- this.label = undefined; //< Used in order to detect Cut Edges (Bridges)
18
- this.symetric = undefined; //< The symetric edge of this
19
- this.ring = undefined; //< EdgeRing in which the Edge is
20
- this.from.addOuterEdge(this);
21
- this.to.addInnerEdge(this);
22
- }
23
- /**
24
- * Creates or get the symetric Edge.
25
- *
26
- * @returns {Edge} - Symetric Edge.
27
- */
28
- getSymetric() {
29
- if (!this.symetric) {
30
- this.symetric = new Edge(this.to, this.from);
31
- this.symetric.symetric = this;
32
- }
33
- return this.symetric;
34
- }
35
- /**
36
- * Removes edge from from and to nodes.
37
- */
38
- deleteEdge() {
39
- this.from.removeOuterEdge(this);
40
- this.to.removeInnerEdge(this);
41
- }
42
- /**
43
- * Compares Edge equallity.
44
- *
45
- * An edge is equal to another, if the from and to nodes are the same.
46
- *
47
- * @param {Edge} edge - Another Edge
48
- * @returns {boolean} - True if Edges are equal, False otherwise
49
- */
50
- isEqual(edge) {
51
- return this.from.id === edge.from.id && this.to.id === edge.to.id;
52
- }
53
- toString() {
54
- return `Edge { ${this.from.id} -> ${this.to.id} }`;
55
- }
56
- /**
57
- * Returns a LineString representation of the Edge
58
- *
59
- * @returns {Feature<LineString>} - LineString representation of the Edge
60
- */
61
- toLineString() {
62
- return helpers_1.lineString([this.from.coordinates, this.to.coordinates]);
63
- }
64
- /**
65
- * Comparator of two edges.
66
- *
67
- * Implementation of geos::planargraph::DirectedEdge::compareTo.
68
- *
69
- * @param {Edge} edge - Another edge to compare with this one
70
- * @returns {number} -1 if this Edge has a greater angle with the positive x-axis than b,
71
- * 0 if the Edges are colinear,
72
- * 1 otherwise
73
- */
74
- compareTo(edge) {
75
- return util_1.orientationIndex(edge.from.coordinates, edge.to.coordinates, this.to.coordinates);
76
- }
77
- }
78
- exports.default = Edge;