dgeoutils 2.2.19 → 2.3.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/dist/{DCircle.d.ts → cjs/DCircle.d.ts} +0 -0
- package/dist/cjs/DCircle.js +102 -0
- package/dist/{DLine.d.ts → cjs/DLine.d.ts} +0 -0
- package/dist/cjs/DLine.js +300 -0
- package/dist/{DNumbers.d.ts → cjs/DNumbers.d.ts} +0 -0
- package/dist/cjs/DNumbers.js +30 -0
- package/dist/{DPlane.d.ts → cjs/DPlane.d.ts} +0 -0
- package/dist/cjs/DPlane.js +132 -0
- package/dist/{DPoint.d.ts → cjs/DPoint.d.ts} +0 -0
- package/dist/cjs/DPoint.js +574 -0
- package/dist/{DPolygon.d.ts → cjs/DPolygon.d.ts} +10 -0
- package/dist/cjs/DPolygon.js +1555 -0
- package/dist/{DPolygonLoop.d.ts → cjs/DPolygonLoop.d.ts} +0 -0
- package/dist/cjs/DPolygonLoop.js +401 -0
- package/dist/{FastSearch.d.ts → cjs/FastSearch.d.ts} +0 -0
- package/dist/cjs/FastSearch.js +53 -0
- package/dist/{TraceMatrix.d.ts → cjs/TraceMatrix.d.ts} +0 -0
- package/dist/cjs/TraceMatrix.js +256 -0
- package/dist/{index.d.ts → cjs/index.d.ts} +0 -0
- package/dist/{index.js → cjs/index.js} +0 -0
- package/dist/{utils.d.ts → cjs/utils.d.ts} +1 -1
- package/dist/cjs/utils.js +191 -0
- package/dist/{DCircle.js → es2015/DCircle.js} +14 -18
- package/dist/{DLine.js → es2015/DLine.js} +25 -29
- package/dist/es2015/DNumbers.js +22 -0
- package/dist/{DPlane.js → es2015/DPlane.js} +22 -26
- package/dist/{DPoint.js → es2015/DPoint.js} +52 -56
- package/dist/{DPolygon.js → es2015/DPolygon.js} +163 -102
- package/dist/{DPolygonLoop.js → es2015/DPolygonLoop.js} +1 -5
- package/dist/{FastSearch.js → es2015/FastSearch.js} +1 -5
- package/dist/{TraceMatrix.js → es2015/TraceMatrix.js} +35 -39
- package/dist/es2015/index.js +13 -0
- package/dist/{utils.js → es2015/utils.js} +26 -36
- package/dist/esm/DCircle.js +99 -0
- package/dist/esm/DLine.js +297 -0
- package/dist/esm/DNumbers.js +27 -0
- package/dist/esm/DPlane.js +129 -0
- package/dist/esm/DPoint.js +571 -0
- package/dist/esm/DPolygon.js +1552 -0
- package/dist/esm/DPolygonLoop.js +398 -0
- package/dist/esm/FastSearch.js +50 -0
- package/dist/esm/TraceMatrix.js +253 -0
- package/dist/esm/index.js +13 -0
- package/dist/esm/utils.js +181 -0
- package/dist/umd/dgeoutils.js +3569 -0
- package/dist/umd/dgeoutils.min.js +1 -0
- package/dist/umd/dgeoutils.min.js.map +1 -0
- package/package.json +18 -11
- package/dist/DNumbers.js +0 -26
|
@@ -1,19 +1,53 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const utils_1 = require("./utils");
|
|
11
|
-
const { buffer: { BufferParameters: { CAP_ROUND, CAP_FLAT, CAP_SQUARE } } } = jsts_1.operation;
|
|
12
|
-
exports.MIN_POINTS_IN_VALID_POLYGON = 3;
|
|
1
|
+
import { DPoint } from './DPoint';
|
|
2
|
+
import { DLine } from './DLine';
|
|
3
|
+
import { DCircle } from './DCircle';
|
|
4
|
+
import { DNumbers } from './DNumbers';
|
|
5
|
+
import { io as jstsIo, operation } from 'jsts';
|
|
6
|
+
import { DPolygonLoop } from './DPolygonLoop';
|
|
7
|
+
import { isDefAndNotNull } from './utils';
|
|
8
|
+
const { buffer: { BufferParameters: { CAP_ROUND, CAP_FLAT, CAP_SQUARE } } } = operation;
|
|
9
|
+
export const MIN_POINTS_IN_VALID_POLYGON = 3;
|
|
13
10
|
const APPROXIMATION_VALUE = 0.1;
|
|
14
11
|
const MAX_CONVEX_ITERATIONS = 100;
|
|
15
12
|
const CLOSE_TO_INTERSECTION_DISTANCE = 0.001;
|
|
16
|
-
|
|
13
|
+
const containCalculator = (poly, p) => {
|
|
14
|
+
const hasSamePoint = poly.points.some((point) => point.equal(p));
|
|
15
|
+
if (hasSamePoint) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
for (const [, , polygonLine] of poly.loopPointsGenerator(true)()) {
|
|
19
|
+
const onBorder = polygonLine.x(p).equal(p) && polygonLine.inRange(p);
|
|
20
|
+
if (onBorder) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
let totalFi = 0;
|
|
25
|
+
for (const [{ x, y }, { x: a, y: b }] of poly.loopPointsGenerator()()) {
|
|
26
|
+
const line1 = new DLine(x - p.x, y - p.y, 0);
|
|
27
|
+
const line2 = new DLine(a - p.x, b - p.y, 0);
|
|
28
|
+
const fiDif = line1.findFi(line2);
|
|
29
|
+
if (line1.vectorProduct(line2).c > 0) {
|
|
30
|
+
totalFi += fiDif;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
totalFi -= fiDif;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const eps = Math.PI / 10000;
|
|
37
|
+
let result = false;
|
|
38
|
+
const absTotalFi = Math.abs(totalFi);
|
|
39
|
+
if (absTotalFi < eps) {
|
|
40
|
+
result = false;
|
|
41
|
+
}
|
|
42
|
+
else if (Math.abs(2 * Math.PI - absTotalFi) < eps) {
|
|
43
|
+
result = true;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
throw new Error('contains2 faild');
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
};
|
|
50
|
+
export class DPolygon {
|
|
17
51
|
constructor(pPoints = []) {
|
|
18
52
|
this.pPoints = pPoints;
|
|
19
53
|
this.properties = {};
|
|
@@ -21,7 +55,7 @@ class DPolygon {
|
|
|
21
55
|
this.searchStore = {};
|
|
22
56
|
}
|
|
23
57
|
static arrayOfTrianglesToVertices(triangles, height) {
|
|
24
|
-
return triangles.map((v) => (
|
|
58
|
+
return triangles.map((v) => (isDefAndNotNull(height) ? v
|
|
25
59
|
.loop()
|
|
26
60
|
.height(height)
|
|
27
61
|
.run() : v)
|
|
@@ -30,7 +64,7 @@ class DPolygon {
|
|
|
30
64
|
}
|
|
31
65
|
static minAreaRectangleSize(poly) {
|
|
32
66
|
const { first, second, last } = poly.clone().open();
|
|
33
|
-
return new
|
|
67
|
+
return new DPoint(first.distance(second), first.distance(last));
|
|
34
68
|
}
|
|
35
69
|
static toDash(poly) {
|
|
36
70
|
let p = new DPolygon();
|
|
@@ -70,7 +104,7 @@ class DPolygon {
|
|
|
70
104
|
const [path, ...holes] = reg.groups.data
|
|
71
105
|
.split('), (')
|
|
72
106
|
.map((p) => new DPolygon(p.split(', ')
|
|
73
|
-
.map((pares) =>
|
|
107
|
+
.map((pares) => DPoint.parse(pares.split(' ').map(Number)))));
|
|
74
108
|
if (holes && holes.length) {
|
|
75
109
|
path.holes = holes;
|
|
76
110
|
}
|
|
@@ -80,18 +114,18 @@ class DPolygon {
|
|
|
80
114
|
const regexp = /LINESTRING \((?<data>(?:(?!\)$).)*?)\)$/miu;
|
|
81
115
|
const reg = regexp.exec(data);
|
|
82
116
|
res = new DPolygon(reg.groups.data
|
|
83
|
-
.split(', ').map((t) =>
|
|
117
|
+
.split(', ').map((t) => DPoint.parse(t.split(' ').map(Number))));
|
|
84
118
|
}
|
|
85
119
|
if (data.indexOf('POINT') === 0) {
|
|
86
|
-
res = new DPolygon([
|
|
120
|
+
res = new DPolygon([DPoint.parseFromWKT(data)]);
|
|
87
121
|
}
|
|
88
122
|
return res;
|
|
89
123
|
}
|
|
90
124
|
static createSquareBySize(size) {
|
|
91
|
-
return new DPolygon([
|
|
125
|
+
return new DPolygon([DPoint.zero(), size.clone().setX(0), size.clone(), size.clone().setY(0)]).close();
|
|
92
126
|
}
|
|
93
127
|
loop() {
|
|
94
|
-
return new
|
|
128
|
+
return new DPolygonLoop(this);
|
|
95
129
|
}
|
|
96
130
|
set points(p) {
|
|
97
131
|
this.pPoints = p;
|
|
@@ -100,16 +134,16 @@ class DPolygon {
|
|
|
100
134
|
return this.pPoints;
|
|
101
135
|
}
|
|
102
136
|
get maxX() {
|
|
103
|
-
return this.
|
|
137
|
+
return this.reduce((a, r) => Math.max(a, r.x), -Infinity);
|
|
104
138
|
}
|
|
105
139
|
get minX() {
|
|
106
|
-
return this.
|
|
140
|
+
return this.reduce((a, r) => Math.min(a, r.x), Infinity);
|
|
107
141
|
}
|
|
108
142
|
get maxY() {
|
|
109
|
-
return this.
|
|
143
|
+
return this.reduce((a, r) => Math.max(a, r.y), -Infinity);
|
|
110
144
|
}
|
|
111
145
|
get minY() {
|
|
112
|
-
return this.
|
|
146
|
+
return this.reduce((a, r) => Math.min(a, r.y), Infinity);
|
|
113
147
|
}
|
|
114
148
|
get center() {
|
|
115
149
|
return this.leftTop.move(this.size.divide(2));
|
|
@@ -129,24 +163,24 @@ class DPolygon {
|
|
|
129
163
|
get extend() {
|
|
130
164
|
const { minX, minY, maxX, maxY } = this;
|
|
131
165
|
return new DPolygon([
|
|
132
|
-
new
|
|
133
|
-
new
|
|
134
|
-
new
|
|
135
|
-
new
|
|
136
|
-
new
|
|
166
|
+
new DPoint(minX, minY),
|
|
167
|
+
new DPoint(maxX, minY),
|
|
168
|
+
new DPoint(maxX, maxY),
|
|
169
|
+
new DPoint(minX, maxY),
|
|
170
|
+
new DPoint(minX, minY)
|
|
137
171
|
]);
|
|
138
172
|
}
|
|
139
173
|
get size() {
|
|
140
174
|
const { w, h } = this;
|
|
141
|
-
return new
|
|
175
|
+
return new DPoint(w, h);
|
|
142
176
|
}
|
|
143
177
|
get leftTop() {
|
|
144
178
|
const { minX, minY } = this;
|
|
145
|
-
return new
|
|
179
|
+
return new DPoint(minX, minY);
|
|
146
180
|
}
|
|
147
181
|
get rightBottom() {
|
|
148
182
|
const { maxX, maxY } = this;
|
|
149
|
-
return new
|
|
183
|
+
return new DPoint(maxX, maxY);
|
|
150
184
|
}
|
|
151
185
|
get length() {
|
|
152
186
|
return this.pPoints.length;
|
|
@@ -156,24 +190,25 @@ class DPolygon {
|
|
|
156
190
|
}
|
|
157
191
|
get perimeter() {
|
|
158
192
|
let p = 0;
|
|
159
|
-
for (
|
|
160
|
-
p +=
|
|
193
|
+
for (const [p1, p2] of this.loopPointsGenerator()()) {
|
|
194
|
+
p += p1.distance(p2);
|
|
161
195
|
}
|
|
162
196
|
return p;
|
|
163
197
|
}
|
|
164
198
|
get area() {
|
|
165
|
-
const closed = this.deintersection;
|
|
166
199
|
let sum = 0;
|
|
167
|
-
for (
|
|
168
|
-
|
|
169
|
-
const prev = closed.at(i - 1);
|
|
170
|
-
sum += prev.x * cur.y - prev.y * cur.x;
|
|
200
|
+
for (const [{ x, y }, { x: a, y: b }] of this.deintersection.loopPointsGenerator()()) {
|
|
201
|
+
sum += x * b - y * a;
|
|
171
202
|
}
|
|
172
203
|
return Math.abs(sum / 2) - this.holes.reduce((a, hole) => a + hole.area, 0);
|
|
173
204
|
}
|
|
174
205
|
get deintersection() {
|
|
175
|
-
|
|
206
|
+
let p = this.clone().close();
|
|
207
|
+
const store = {};
|
|
176
208
|
for (let i = 0; i < p.length - 1; i++) {
|
|
209
|
+
const k = p.at(i).toString();
|
|
210
|
+
store[k] = store[k] || [];
|
|
211
|
+
store[k].push(i);
|
|
177
212
|
for (let j = i + 2; j < p.length - 1; j++) {
|
|
178
213
|
const firstLine = p.at(i).findLine(p.at(i + 1));
|
|
179
214
|
const secondLine = p.at(j).findLine(p.at(j + 1));
|
|
@@ -187,10 +222,27 @@ class DPolygon {
|
|
|
187
222
|
}
|
|
188
223
|
}
|
|
189
224
|
}
|
|
225
|
+
for (const key of Object.keys(store)) {
|
|
226
|
+
const record = store[key];
|
|
227
|
+
if (record.length > 1) {
|
|
228
|
+
for (let j = record.length - 1; j > 0; j--) {
|
|
229
|
+
const origin = p.clone();
|
|
230
|
+
const d = record[j] - record[j - 1];
|
|
231
|
+
if (d > 1) {
|
|
232
|
+
const part = new DPolygon(origin.removePart(record[j - 1], d));
|
|
233
|
+
const allInside = part.reduce((a, e) => a && containCalculator(origin, e), true);
|
|
234
|
+
if (allInside && origin.isClockwise === part.isClockwise) {
|
|
235
|
+
origin.insertAfter(record[j - 1] - 1, ...part.reverse().points);
|
|
236
|
+
p = origin;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
190
242
|
return p;
|
|
191
243
|
}
|
|
192
244
|
get valid() {
|
|
193
|
-
return this.length >
|
|
245
|
+
return this.length > MIN_POINTS_IN_VALID_POLYGON;
|
|
194
246
|
}
|
|
195
247
|
get first() {
|
|
196
248
|
return this.at(0);
|
|
@@ -205,19 +257,18 @@ class DPolygon {
|
|
|
205
257
|
const p = this.convex;
|
|
206
258
|
let resultPolygon = new DPolygon();
|
|
207
259
|
let resultArea = Infinity;
|
|
208
|
-
for (
|
|
209
|
-
const l = p.at(k).findLine(p.at(k + 1));
|
|
260
|
+
for (const [, , l] of p.loopPointsGenerator(true)()) {
|
|
210
261
|
let maxWidth = 0;
|
|
211
262
|
let maxWidthPoint1 = null;
|
|
212
263
|
let maxWidthPoint2 = null;
|
|
213
264
|
let maxHeight = 0;
|
|
214
265
|
let maxHeightPoint = null;
|
|
215
|
-
for (
|
|
216
|
-
const p1 = l.findPoint(l.findPerpendicular(
|
|
217
|
-
const h = p1.distance(
|
|
266
|
+
for (const [z, , , i] of p.loopPointsGenerator()()) {
|
|
267
|
+
const p1 = l.findPoint(l.findPerpendicular(z));
|
|
268
|
+
const h = p1.distance(z);
|
|
218
269
|
if (h >= maxHeight) {
|
|
219
270
|
maxHeight = h;
|
|
220
|
-
maxHeightPoint =
|
|
271
|
+
maxHeightPoint = z;
|
|
221
272
|
}
|
|
222
273
|
for (let j = i; j < p.length - 1; j++) {
|
|
223
274
|
const p2 = l.findPoint(l.findPerpendicular(p.at(j)));
|
|
@@ -260,7 +311,7 @@ class DPolygon {
|
|
|
260
311
|
const p2 = p.first;
|
|
261
312
|
const p3 = p.second;
|
|
262
313
|
const d = p2.findInnerAngle(p1, p3);
|
|
263
|
-
if (d > Math.PI ||
|
|
314
|
+
if (d > Math.PI || DNumbers.likeZero(DNumbers.rad2Deg(d)) || DNumbers.likePI(d) || DNumbers.like2PI(d)) {
|
|
264
315
|
p.removePart(-1, 1);
|
|
265
316
|
}
|
|
266
317
|
else {
|
|
@@ -277,7 +328,7 @@ class DPolygon {
|
|
|
277
328
|
const p2 = p.at(i);
|
|
278
329
|
const p3 = p.at(i + 1);
|
|
279
330
|
const d = p2.findInnerAngle(p1, p3);
|
|
280
|
-
if (d > Math.PI ||
|
|
331
|
+
if (d > Math.PI || DNumbers.likeZero(DNumbers.rad2Deg(d)) || DNumbers.likePI(d) || DNumbers.like2PI(d)) {
|
|
281
332
|
p.removePart(--i, 1);
|
|
282
333
|
}
|
|
283
334
|
}
|
|
@@ -290,11 +341,9 @@ class DPolygon {
|
|
|
290
341
|
}
|
|
291
342
|
get isClockwise() {
|
|
292
343
|
let sum = 0;
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
const p2 = p.at(i);
|
|
297
|
-
sum += (p2.x - p1.x) * (p2.y + p1.y);
|
|
344
|
+
for (const [{ x, y }, { x: a, y: b }] of this.clone().close()
|
|
345
|
+
.loopPointsGenerator()()) {
|
|
346
|
+
sum += (a - x) * (b + y);
|
|
298
347
|
}
|
|
299
348
|
return sum < 0;
|
|
300
349
|
}
|
|
@@ -309,12 +358,12 @@ class DPolygon {
|
|
|
309
358
|
res.holes = [];
|
|
310
359
|
return res;
|
|
311
360
|
}
|
|
361
|
+
reduce(f, v) {
|
|
362
|
+
return this.pPoints.reduce(f, v);
|
|
363
|
+
}
|
|
312
364
|
intersection(l, includeOnly = false) {
|
|
313
365
|
const res = [];
|
|
314
|
-
for (
|
|
315
|
-
const p1 = this.pPoints[i];
|
|
316
|
-
const p2 = this.pPoints[i + 1];
|
|
317
|
-
const line = p1.findLine(p2);
|
|
366
|
+
for (const [, , line] of this.loopPointsGenerator(true)()) {
|
|
318
367
|
const intersect = line.intersection(l, 0, includeOnly);
|
|
319
368
|
if (intersect) {
|
|
320
369
|
res.push(intersect);
|
|
@@ -334,10 +383,10 @@ class DPolygon {
|
|
|
334
383
|
h = `, ${this.holes.map((hole) => hole.toString())
|
|
335
384
|
.join(', ')}`;
|
|
336
385
|
}
|
|
337
|
-
return `POLYGON ((${this.deintersection.
|
|
386
|
+
return `POLYGON ((${this.deintersection.mapArray((r) => `${r.x} ${r.y}${withZ ? ` ${r.z}` : ''}`)
|
|
338
387
|
.join(', ')})${h})`;
|
|
339
388
|
}
|
|
340
|
-
return `LINESTRING (${this.
|
|
389
|
+
return `LINESTRING (${this.mapArray((r) => `${r.x} ${r.y}${withZ ? ` ${r.z}` : ''}`)
|
|
341
390
|
.join(', ')})`;
|
|
342
391
|
}
|
|
343
392
|
filter(f) {
|
|
@@ -345,10 +394,13 @@ class DPolygon {
|
|
|
345
394
|
return this;
|
|
346
395
|
}
|
|
347
396
|
map(f) {
|
|
348
|
-
this.pPoints = this.
|
|
397
|
+
this.pPoints = this.mapArray(f);
|
|
349
398
|
this.holes = this.holes.map((h) => h.map(f));
|
|
350
399
|
return this;
|
|
351
400
|
}
|
|
401
|
+
mapArray(f) {
|
|
402
|
+
return this.pPoints.map(f);
|
|
403
|
+
}
|
|
352
404
|
sort(f) {
|
|
353
405
|
this.points.sort(f);
|
|
354
406
|
return this;
|
|
@@ -379,7 +431,7 @@ class DPolygon {
|
|
|
379
431
|
.reduce((a, h) => a + h.getValue(), ''));
|
|
380
432
|
}
|
|
381
433
|
toString() {
|
|
382
|
-
return `(${this.
|
|
434
|
+
return `(${this.mapArray((r) => r.toString()).join(', ')})`;
|
|
383
435
|
}
|
|
384
436
|
close() {
|
|
385
437
|
const p0 = this.first;
|
|
@@ -433,8 +485,11 @@ class DPolygon {
|
|
|
433
485
|
}
|
|
434
486
|
return false;
|
|
435
487
|
}
|
|
436
|
-
findIndex(
|
|
437
|
-
|
|
488
|
+
findIndex(a) {
|
|
489
|
+
if (a instanceof DPoint) {
|
|
490
|
+
return this.points.findIndex((t) => t.equal(a));
|
|
491
|
+
}
|
|
492
|
+
return this.points.findIndex(a);
|
|
438
493
|
}
|
|
439
494
|
approximation(e = Math.sqrt(this.perimeter) * APPROXIMATION_VALUE) {
|
|
440
495
|
return new DPolygon(this.clone().douglasPeucker(this.pPoints, e));
|
|
@@ -508,11 +563,9 @@ class DPolygon {
|
|
|
508
563
|
}
|
|
509
564
|
const poly = this.deintersection;
|
|
510
565
|
let totalFi = 0;
|
|
511
|
-
for (
|
|
512
|
-
const
|
|
513
|
-
const
|
|
514
|
-
const line1 = new DLine_1.DLine(p1.x - p.x, p1.y - p.y, 0);
|
|
515
|
-
const line2 = new DLine_1.DLine(p2.x - p.x, p2.y - p.y, 0);
|
|
566
|
+
for (const [{ x, y }, { x: a, y: b }] of poly.loopPointsGenerator()()) {
|
|
567
|
+
const line1 = new DLine(x - p.x, y - p.y, 0);
|
|
568
|
+
const line2 = new DLine(a - p.x, b - p.y, 0);
|
|
516
569
|
const fiDif = line1.findFi(line2);
|
|
517
570
|
if (line1.vectorProduct(line2).c > 0) {
|
|
518
571
|
totalFi += fiDif;
|
|
@@ -522,18 +575,14 @@ class DPolygon {
|
|
|
522
575
|
}
|
|
523
576
|
}
|
|
524
577
|
const eps = Math.PI / 10000;
|
|
525
|
-
let result = false;
|
|
526
578
|
const absTotalFi = Math.abs(totalFi);
|
|
527
579
|
if (absTotalFi < eps) {
|
|
528
|
-
|
|
580
|
+
return false;
|
|
529
581
|
}
|
|
530
582
|
else if (Math.abs(2 * Math.PI - absTotalFi) < eps) {
|
|
531
|
-
|
|
532
|
-
}
|
|
533
|
-
else {
|
|
534
|
-
throw new Error('contains2 faild');
|
|
583
|
+
return true;
|
|
535
584
|
}
|
|
536
|
-
|
|
585
|
+
throw new Error('contains2 faild');
|
|
537
586
|
}
|
|
538
587
|
onBorder(p) {
|
|
539
588
|
const simpleInclude = this.simpleInclude(p);
|
|
@@ -543,10 +592,7 @@ class DPolygon {
|
|
|
543
592
|
if (hasSamePoint) {
|
|
544
593
|
return true;
|
|
545
594
|
}
|
|
546
|
-
for (
|
|
547
|
-
const p0 = poly.at(i);
|
|
548
|
-
const p1 = poly.at(i + 1);
|
|
549
|
-
const polygonLine = p0.findLine(p1);
|
|
595
|
+
for (const [, , polygonLine] of poly.loopPointsGenerator(true)()) {
|
|
550
596
|
const onBorder = polygonLine.x(p).equal(p) && polygonLine.inRange(p);
|
|
551
597
|
if (onBorder) {
|
|
552
598
|
return true;
|
|
@@ -573,35 +619,32 @@ class DPolygon {
|
|
|
573
619
|
return this;
|
|
574
620
|
}
|
|
575
621
|
static parse(a) {
|
|
576
|
-
return new DPolygon(a.map((r) =>
|
|
622
|
+
return new DPolygon(a.map((r) => DPoint.parse(r)));
|
|
577
623
|
}
|
|
578
624
|
toArrayOfCoords() {
|
|
579
|
-
return this.
|
|
625
|
+
return this.mapArray((r) => r.toCoords());
|
|
580
626
|
}
|
|
581
627
|
divideToPieces(piecesCount) {
|
|
582
628
|
const { fullLength } = this;
|
|
583
629
|
const pieceLength = fullLength / piecesCount;
|
|
584
630
|
let currentPieceLength = pieceLength;
|
|
585
|
-
for (
|
|
586
|
-
const
|
|
587
|
-
|
|
588
|
-
if (p1.distance(p2) === currentPieceLength) {
|
|
631
|
+
for (const [p1, p2, , i] of this.loopPointsGenerator()()) {
|
|
632
|
+
const d = p1.distance(p2);
|
|
633
|
+
if (d === currentPieceLength) {
|
|
589
634
|
p2.properties.pieceBorder = true;
|
|
590
635
|
currentPieceLength = pieceLength;
|
|
591
|
-
continue;
|
|
592
636
|
}
|
|
593
|
-
if (
|
|
594
|
-
const circle = new
|
|
637
|
+
else if (d - currentPieceLength > 0) {
|
|
638
|
+
const circle = new DCircle(p1, currentPieceLength);
|
|
595
639
|
const line = p1.findLine(p2);
|
|
596
640
|
const intersectionPoint = line.intersectionWithCircle(circle)
|
|
597
641
|
.filter((p) => line.inRange(p, CLOSE_TO_INTERSECTION_DISTANCE))[0];
|
|
598
642
|
intersectionPoint.properties.pieceBorder = true;
|
|
599
643
|
this.insertAfter(i, intersectionPoint);
|
|
600
644
|
currentPieceLength = pieceLength;
|
|
601
|
-
continue;
|
|
602
645
|
}
|
|
603
|
-
|
|
604
|
-
currentPieceLength -=
|
|
646
|
+
else {
|
|
647
|
+
currentPieceLength -= d;
|
|
605
648
|
}
|
|
606
649
|
}
|
|
607
650
|
return this;
|
|
@@ -804,13 +847,24 @@ class DPolygon {
|
|
|
804
847
|
return this.first.equal(this.last);
|
|
805
848
|
}
|
|
806
849
|
buffer(v, quadrantSegments = 64, type = DPolygon.CAP_ROUND) {
|
|
807
|
-
const reader = new
|
|
850
|
+
const reader = new jstsIo.WKTReader();
|
|
808
851
|
const { noHoles, closed } = this;
|
|
809
852
|
const points = reader
|
|
810
853
|
.read(noHoles.toWKT(closed ? DPolygon.WKT_POLYGON : DPolygon.WKT_LINESTRING))
|
|
811
854
|
.buffer(v, quadrantSegments, type)
|
|
812
855
|
.getCoordinates();
|
|
813
|
-
return new DPolygon(points.map(({ x, y }) => new
|
|
856
|
+
return new DPolygon(points.map(({ x, y }) => new DPoint(x, y)));
|
|
857
|
+
}
|
|
858
|
+
sideBuffers(v, quadrantSegments = 64) {
|
|
859
|
+
const { first, last } = this;
|
|
860
|
+
const buffer = this.buffer(v, quadrantSegments, DPolygon.CAP_FLAT).open();
|
|
861
|
+
const [start0, start1] = first.sortByDistance(buffer).points.map((r) => r.properties.index);
|
|
862
|
+
const [end0, end1] = last.sortByDistance(buffer).points.map((r) => r.properties.index);
|
|
863
|
+
const fromPoint = Math.min(Math.max(start0, start1), Math.max(end0, end1));
|
|
864
|
+
const toPoint = Math.max(Math.min(start0, start1), Math.min(end0, end1));
|
|
865
|
+
const linePart = new DPolygon(buffer.removePart(fromPoint - 1, toPoint - fromPoint + 1));
|
|
866
|
+
buffer.unshift(buffer.pop());
|
|
867
|
+
return [linePart, buffer];
|
|
814
868
|
}
|
|
815
869
|
bezier(step = 0.1) {
|
|
816
870
|
const res = new DPolygon();
|
|
@@ -833,13 +887,21 @@ class DPolygon {
|
|
|
833
887
|
.run();
|
|
834
888
|
return this;
|
|
835
889
|
}
|
|
890
|
+
loopPointsGenerator(withLine = false) {
|
|
891
|
+
const that = this;
|
|
892
|
+
return function* () {
|
|
893
|
+
for (let i = 0; i < that.length - 1; i++) {
|
|
894
|
+
const p1 = that.at(i);
|
|
895
|
+
const p2 = that.at(i + 1);
|
|
896
|
+
yield [p1, p2, withLine ? p1.findLine(p2) : undefined, i];
|
|
897
|
+
}
|
|
898
|
+
};
|
|
899
|
+
}
|
|
836
900
|
getBezierPoint(v) {
|
|
837
901
|
if (this.length === 1) {
|
|
838
902
|
return this.first;
|
|
839
903
|
}
|
|
840
|
-
for (
|
|
841
|
-
const p1 = this.at(i);
|
|
842
|
-
const p2 = this.at(i + 1);
|
|
904
|
+
for (const [p1, p2] of this.loopPointsGenerator()()) {
|
|
843
905
|
p1.move(p2.clone().move(p1.clone().minus())
|
|
844
906
|
.scale(v));
|
|
845
907
|
}
|
|
@@ -884,7 +946,7 @@ class DPolygon {
|
|
|
884
946
|
}
|
|
885
947
|
getJSTSGeometry(p, unionThis, unionThat) {
|
|
886
948
|
const unionOrIntersection = unionThat === unionThis;
|
|
887
|
-
const reader = new
|
|
949
|
+
const reader = new jstsIo.WKTReader();
|
|
888
950
|
const a = reader.read(this.noHoles.toWKT());
|
|
889
951
|
const b = reader.read(p.noHoles.toWKT());
|
|
890
952
|
if (!unionOrIntersection) {
|
|
@@ -905,11 +967,11 @@ class DPolygon {
|
|
|
905
967
|
if (coordinates.length) {
|
|
906
968
|
let result = coordinates.reduce((ak, { x, y }, index) => {
|
|
907
969
|
const lastIndex = ak.length - 1;
|
|
908
|
-
const t = new
|
|
970
|
+
const t = new DPoint(x, y);
|
|
909
971
|
const { first } = ak[lastIndex];
|
|
910
972
|
if (t.equal(first)) {
|
|
911
973
|
if (coordinates[index + 1]) {
|
|
912
|
-
const nextPoint = new
|
|
974
|
+
const nextPoint = new DPoint(coordinates[index + 1].x, coordinates[index + 1].y);
|
|
913
975
|
if (ak[lastIndex].length > 1) {
|
|
914
976
|
ak.push(new DPolygon([nextPoint]));
|
|
915
977
|
}
|
|
@@ -919,7 +981,7 @@ class DPolygon {
|
|
|
919
981
|
ak[lastIndex].push(t);
|
|
920
982
|
}
|
|
921
983
|
return ak;
|
|
922
|
-
}, [new DPolygon([new
|
|
984
|
+
}, [new DPolygon([new DPoint(coordinates[0].x, coordinates[0].y)])]);
|
|
923
985
|
if (unionThat && unionThis && result.length > 1) {
|
|
924
986
|
for (const q of result) {
|
|
925
987
|
for (const r of result) {
|
|
@@ -967,7 +1029,6 @@ class DPolygon {
|
|
|
967
1029
|
return null;
|
|
968
1030
|
}
|
|
969
1031
|
}
|
|
970
|
-
exports.DPolygon = DPolygon;
|
|
971
1032
|
DPolygon.CAP_ROUND = CAP_ROUND;
|
|
972
1033
|
DPolygon.CAP_FLAT = CAP_FLAT;
|
|
973
1034
|
DPolygon.CAP_SQUARE = CAP_SQUARE;
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DPolygonLoop = void 0;
|
|
4
1
|
var LoopFunctions;
|
|
5
2
|
(function (LoopFunctions) {
|
|
6
3
|
LoopFunctions[LoopFunctions["getTileFromCoords"] = 0] = "getTileFromCoords";
|
|
@@ -170,7 +167,7 @@ const decodePoolRecord = (a, { functionName, pointArg, numberPointArg, numberArg
|
|
|
170
167
|
}
|
|
171
168
|
return res;
|
|
172
169
|
};
|
|
173
|
-
class DPolygonLoop {
|
|
170
|
+
export class DPolygonLoop {
|
|
174
171
|
constructor(parent) {
|
|
175
172
|
this.parent = parent;
|
|
176
173
|
this.pool = [];
|
|
@@ -393,4 +390,3 @@ class DPolygonLoop {
|
|
|
393
390
|
return this;
|
|
394
391
|
}
|
|
395
392
|
}
|
|
396
|
-
exports.DPolygonLoop = DPolygonLoop;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FastSearch = void 0;
|
|
4
|
-
class FastSearch {
|
|
1
|
+
export class FastSearch {
|
|
5
2
|
constructor() {
|
|
6
3
|
this.searchStore = {};
|
|
7
4
|
}
|
|
@@ -26,4 +23,3 @@ class FastSearch {
|
|
|
26
23
|
return this.searchStore[x][y][z || 'undefined'];
|
|
27
24
|
}
|
|
28
25
|
}
|
|
29
|
-
exports.FastSearch = FastSearch;
|