dgeoutils 2.2.4 → 2.2.8
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 +0 -28
- package/dist/DCircle.js +0 -30
- package/dist/DLine.d.ts +5 -58
- package/dist/DLine.js +48 -128
- package/dist/DPoint.d.ts +2 -129
- package/dist/DPoint.js +4 -50
- package/dist/DPolygon.d.ts +12 -171
- package/dist/DPolygon.js +104 -178
- package/dist/DPolygonLoop.d.ts +2 -72
- package/dist/DPolygonLoop.js +35 -34
- package/dist/TraceMatrix.d.ts +1 -1
- package/dist/TraceMatrix.js +1 -2
- package/dist/utils.js +0 -3
- package/package.json +2 -2
package/dist/DPolygon.js
CHANGED
|
@@ -1,38 +1,36 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DPolygon = exports.MIN_POINTS_IN_VALID_POLYGON = void 0;
|
|
4
|
-
/* eslint-disable max-lines */
|
|
5
4
|
const DPoint_1 = require("./DPoint");
|
|
6
5
|
const DLine_1 = require("./DLine");
|
|
7
6
|
const DCircle_1 = require("./DCircle");
|
|
8
7
|
const DNumbers_1 = require("./DNumbers");
|
|
9
8
|
const jsts_1 = require("jsts");
|
|
10
9
|
const DPolygonLoop_1 = require("./DPolygonLoop");
|
|
10
|
+
const { buffer: { BufferParameters: { CAP_ROUND, CAP_FLAT, CAP_SQUARE } } } = jsts_1.operation;
|
|
11
11
|
exports.MIN_POINTS_IN_VALID_POLYGON = 3;
|
|
12
12
|
const APPROXIMATION_VALUE = 0.1;
|
|
13
13
|
const MAX_CONVEX_ITERATIONS = 100;
|
|
14
14
|
const CLOSE_TO_INTERSECTION_DISTANCE = 0.001;
|
|
15
15
|
class DPolygon {
|
|
16
|
-
// eslint-disable-next-line no-useless-constructor,no-empty-function
|
|
17
16
|
constructor(pPoints = []) {
|
|
18
17
|
this.pPoints = pPoints;
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
18
|
this.properties = {};
|
|
21
19
|
this.holes = [];
|
|
22
20
|
this.searchStore = {};
|
|
23
21
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
static arrayOfTrianglesToVertices(triangles, height = 0) {
|
|
23
|
+
return triangles.map((v) => v
|
|
24
|
+
.loop()
|
|
25
|
+
.height(height)
|
|
26
|
+
.run()
|
|
27
|
+
.toArrayOfCoords())
|
|
28
|
+
.flat(2);
|
|
29
|
+
}
|
|
28
30
|
static minAreaRectangleSize(poly) {
|
|
29
31
|
const { first, second, last } = poly.clone().open();
|
|
30
32
|
return new DPoint_1.DPoint(first.distance(second), first.distance(last));
|
|
31
33
|
}
|
|
32
|
-
/**
|
|
33
|
-
* Slice line string to dashes.
|
|
34
|
-
* @param poly should be `divideToPieces` at first
|
|
35
|
-
*/
|
|
36
34
|
static toDash(poly) {
|
|
37
35
|
let p = new DPolygon();
|
|
38
36
|
const result = [p];
|
|
@@ -52,10 +50,6 @@ class DPolygon {
|
|
|
52
50
|
}
|
|
53
51
|
return result;
|
|
54
52
|
}
|
|
55
|
-
/**
|
|
56
|
-
* Get min area rectangle direction
|
|
57
|
-
* @param poly should be `minAreaRectangle`
|
|
58
|
-
*/
|
|
59
53
|
static minAreaRectangleDirection(poly) {
|
|
60
54
|
const { first, second, last } = poly.clone().open();
|
|
61
55
|
if (!first || !second || !last) {
|
|
@@ -116,39 +110,21 @@ class DPolygon {
|
|
|
116
110
|
get minY() {
|
|
117
111
|
return this.pPoints.reduce((a, r) => Math.min(a, r.y), Infinity);
|
|
118
112
|
}
|
|
119
|
-
/**
|
|
120
|
-
* Get center coordinates
|
|
121
|
-
*/
|
|
122
113
|
get center() {
|
|
123
114
|
return this.leftTop.move(this.size.divide(2));
|
|
124
115
|
}
|
|
125
|
-
/**
|
|
126
|
-
* Difference between `maxY` and `minY`. Equal `ΔY` (`dY`)
|
|
127
|
-
*/
|
|
128
116
|
get h() {
|
|
129
117
|
return this.maxY - this.minY;
|
|
130
118
|
}
|
|
131
|
-
/**
|
|
132
|
-
* Difference between `maxX` and `minX`. Equal `ΔX` (`dX`)
|
|
133
|
-
*/
|
|
134
119
|
get w() {
|
|
135
120
|
return this.maxX - this.minX;
|
|
136
121
|
}
|
|
137
|
-
/**
|
|
138
|
-
* Difference between `maxY` and `minY`. Equal `height` (`h`)
|
|
139
|
-
*/
|
|
140
122
|
get dY() {
|
|
141
123
|
return this.h;
|
|
142
124
|
}
|
|
143
|
-
/**
|
|
144
|
-
* Difference between `maxX` and `minX`. Equal `width` (`w`)
|
|
145
|
-
*/
|
|
146
125
|
get dX() {
|
|
147
126
|
return this.w;
|
|
148
127
|
}
|
|
149
|
-
/**
|
|
150
|
-
* Get closed extend polygon
|
|
151
|
-
*/
|
|
152
128
|
get extend() {
|
|
153
129
|
const { minX, minY, maxX, maxY } = this;
|
|
154
130
|
return new DPolygon([
|
|
@@ -159,42 +135,24 @@ class DPolygon {
|
|
|
159
135
|
new DPoint_1.DPoint(minX, minY)
|
|
160
136
|
]);
|
|
161
137
|
}
|
|
162
|
-
/**
|
|
163
|
-
* Point with `width` value as `x` and `height` value as `y`
|
|
164
|
-
*/
|
|
165
138
|
get size() {
|
|
166
139
|
const { w, h } = this;
|
|
167
140
|
return new DPoint_1.DPoint(w, h);
|
|
168
141
|
}
|
|
169
|
-
/**
|
|
170
|
-
* Point with minimal `x` and `y`
|
|
171
|
-
*/
|
|
172
142
|
get leftTop() {
|
|
173
143
|
const { minX, minY } = this;
|
|
174
144
|
return new DPoint_1.DPoint(minX, minY);
|
|
175
145
|
}
|
|
176
|
-
/**
|
|
177
|
-
* Point with maximal `x` and `y`
|
|
178
|
-
*/
|
|
179
146
|
get rightBottom() {
|
|
180
147
|
const { maxX, maxY } = this;
|
|
181
148
|
return new DPoint_1.DPoint(maxX, maxY);
|
|
182
149
|
}
|
|
183
|
-
/**
|
|
184
|
-
* Next point index
|
|
185
|
-
*/
|
|
186
150
|
get length() {
|
|
187
151
|
return this.pPoints.length;
|
|
188
152
|
}
|
|
189
|
-
/**
|
|
190
|
-
* Get length of line string.
|
|
191
|
-
*/
|
|
192
153
|
get fullLength() {
|
|
193
154
|
return this.clone().open().perimeter;
|
|
194
155
|
}
|
|
195
|
-
/**
|
|
196
|
-
* Get perimeter.
|
|
197
|
-
*/
|
|
198
156
|
get perimeter() {
|
|
199
157
|
let p = 0;
|
|
200
158
|
for (let i = 1; i < this.pPoints.length; i++) {
|
|
@@ -202,9 +160,6 @@ class DPolygon {
|
|
|
202
160
|
}
|
|
203
161
|
return p;
|
|
204
162
|
}
|
|
205
|
-
/**
|
|
206
|
-
* Get polygon area
|
|
207
|
-
*/
|
|
208
163
|
get area() {
|
|
209
164
|
const closed = this.deintersection;
|
|
210
165
|
let sum = 0;
|
|
@@ -215,9 +170,6 @@ class DPolygon {
|
|
|
215
170
|
}
|
|
216
171
|
return Math.abs(sum / 2) - this.holes.reduce((a, hole) => a + hole.area, 0);
|
|
217
172
|
}
|
|
218
|
-
/**
|
|
219
|
-
* Get deintesected polygon.
|
|
220
|
-
*/
|
|
221
173
|
get deintersection() {
|
|
222
174
|
const p = this.clone().close();
|
|
223
175
|
for (let i = 0; i < p.length - 1; i++) {
|
|
@@ -236,33 +188,18 @@ class DPolygon {
|
|
|
236
188
|
}
|
|
237
189
|
return p;
|
|
238
190
|
}
|
|
239
|
-
/**
|
|
240
|
-
* Check if polygon contain more than three points
|
|
241
|
-
*/
|
|
242
191
|
get valid() {
|
|
243
192
|
return this.length > exports.MIN_POINTS_IN_VALID_POLYGON;
|
|
244
193
|
}
|
|
245
|
-
/**
|
|
246
|
-
* Get first point
|
|
247
|
-
*/
|
|
248
194
|
get first() {
|
|
249
195
|
return this.at(0);
|
|
250
196
|
}
|
|
251
|
-
/**
|
|
252
|
-
* Get second point
|
|
253
|
-
*/
|
|
254
197
|
get second() {
|
|
255
198
|
return this.at(1);
|
|
256
199
|
}
|
|
257
|
-
/**
|
|
258
|
-
* Get last point
|
|
259
|
-
*/
|
|
260
200
|
get last() {
|
|
261
201
|
return this.at(this.length - 1);
|
|
262
202
|
}
|
|
263
|
-
/**
|
|
264
|
-
* Get min area rectangle
|
|
265
|
-
*/
|
|
266
203
|
get minAreaRectangle() {
|
|
267
204
|
const p = this.convex;
|
|
268
205
|
let resultPolygon = new DPolygon();
|
|
@@ -310,9 +247,6 @@ class DPolygon {
|
|
|
310
247
|
}
|
|
311
248
|
return resultPolygon;
|
|
312
249
|
}
|
|
313
|
-
/**
|
|
314
|
-
* Get convex polygon
|
|
315
|
-
*/
|
|
316
250
|
get convex() {
|
|
317
251
|
let p = this.clone().open();
|
|
318
252
|
const { isClockwise } = p;
|
|
@@ -353,9 +287,6 @@ class DPolygon {
|
|
|
353
287
|
}
|
|
354
288
|
return p;
|
|
355
289
|
}
|
|
356
|
-
/**
|
|
357
|
-
* Check polygon direction
|
|
358
|
-
*/
|
|
359
290
|
get isClockwise() {
|
|
360
291
|
let sum = 0;
|
|
361
292
|
const p = this.clone().close();
|
|
@@ -366,28 +297,17 @@ class DPolygon {
|
|
|
366
297
|
}
|
|
367
298
|
return sum < 0;
|
|
368
299
|
}
|
|
369
|
-
/**
|
|
370
|
-
* Get clockwise polygon
|
|
371
|
-
*/
|
|
372
300
|
get clockWise() {
|
|
373
301
|
if (this.isClockwise) {
|
|
374
302
|
return this.clone();
|
|
375
303
|
}
|
|
376
304
|
return this.clone().reverse();
|
|
377
305
|
}
|
|
378
|
-
/**
|
|
379
|
-
* Get polygon clone without holes
|
|
380
|
-
*/
|
|
381
306
|
get noHoles() {
|
|
382
307
|
const res = this.clone();
|
|
383
308
|
res.holes = [];
|
|
384
309
|
return res;
|
|
385
310
|
}
|
|
386
|
-
/**
|
|
387
|
-
* Check polygon intersection with line
|
|
388
|
-
* @param l
|
|
389
|
-
* @param [includeOnly=false]
|
|
390
|
-
*/
|
|
391
311
|
intersection(l, includeOnly = false) {
|
|
392
312
|
const res = [];
|
|
393
313
|
for (let i = 0; i < this.pPoints.length - 1; i++) {
|
|
@@ -401,26 +321,24 @@ class DPolygon {
|
|
|
401
321
|
}
|
|
402
322
|
return res;
|
|
403
323
|
}
|
|
404
|
-
/**
|
|
405
|
-
* Set polygon center
|
|
406
|
-
* @param newCenter
|
|
407
|
-
*/
|
|
408
324
|
setCenter(newCenter) {
|
|
409
325
|
return this.loop()
|
|
410
326
|
.move(newCenter.clone().move(this.center.minus()))
|
|
411
327
|
.run();
|
|
412
328
|
}
|
|
413
|
-
toWKT() {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
329
|
+
toWKT(type = DPolygon.WKT_POLYGON) {
|
|
330
|
+
if (type === DPolygon.WKT_POLYGON) {
|
|
331
|
+
let h = '';
|
|
332
|
+
if (this.holes && this.holes.length) {
|
|
333
|
+
h = `, ${this.holes.map((hole) => hole.toString())
|
|
334
|
+
.join(', ')}`;
|
|
335
|
+
}
|
|
336
|
+
return `POLYGON ((${this.deintersection.pPoints.map((r) => `${r.x} ${r.y}`)
|
|
337
|
+
.join(', ')})${h})`;
|
|
417
338
|
}
|
|
418
|
-
return `
|
|
339
|
+
return `LINESTRING (${this.pPoints.map((r) => `${r.x} ${r.y}`)
|
|
340
|
+
.join(', ')})`;
|
|
419
341
|
}
|
|
420
|
-
/**
|
|
421
|
-
* Filter points
|
|
422
|
-
* @param f
|
|
423
|
-
*/
|
|
424
342
|
filter(f) {
|
|
425
343
|
this.pPoints = this.pPoints.filter(f);
|
|
426
344
|
return this;
|
|
@@ -458,22 +376,16 @@ class DPolygon {
|
|
|
458
376
|
toString() {
|
|
459
377
|
return `(${this.pPoints.map((r) => r.toString()).join(', ')})`;
|
|
460
378
|
}
|
|
461
|
-
/**
|
|
462
|
-
* Add to the end of polygon point equal to first point if it not exist
|
|
463
|
-
*/
|
|
464
379
|
close() {
|
|
465
380
|
const p0 = this.first;
|
|
466
|
-
if (p0 && !
|
|
381
|
+
if (p0 && !this.closed) {
|
|
467
382
|
this.push(p0.clone());
|
|
468
383
|
}
|
|
469
384
|
return this;
|
|
470
385
|
}
|
|
471
|
-
/**
|
|
472
|
-
* Remove from the end of polygon point equal to first point if it exist
|
|
473
|
-
*/
|
|
474
386
|
open() {
|
|
475
387
|
const p = this.first;
|
|
476
|
-
if (this.length > 2 && p &&
|
|
388
|
+
if (this.length > 2 && p && this.closed) {
|
|
477
389
|
this.pop();
|
|
478
390
|
}
|
|
479
391
|
return this;
|
|
@@ -483,10 +395,6 @@ class DPolygon {
|
|
|
483
395
|
res.holes = [...this.holes, ...poly.holes].map((h) => h.clone());
|
|
484
396
|
return res;
|
|
485
397
|
}
|
|
486
|
-
/**
|
|
487
|
-
* Check if has point in list of points
|
|
488
|
-
* @param p
|
|
489
|
-
*/
|
|
490
398
|
has(p) {
|
|
491
399
|
return this.pPoints.some((q) => q.equal(p));
|
|
492
400
|
}
|
|
@@ -496,10 +404,6 @@ class DPolygon {
|
|
|
496
404
|
res.properties = this.properties;
|
|
497
405
|
return res;
|
|
498
406
|
}
|
|
499
|
-
/**
|
|
500
|
-
* Check is it fully equal.
|
|
501
|
-
* @param p
|
|
502
|
-
*/
|
|
503
407
|
equal(p) {
|
|
504
408
|
if (!(p instanceof DPolygon)) {
|
|
505
409
|
return false;
|
|
@@ -510,10 +414,6 @@ class DPolygon {
|
|
|
510
414
|
return (this.same(p) &&
|
|
511
415
|
this.holes.reduce((a, hole) => a && p.holes.some((pHoles) => pHoles.same(hole)), true));
|
|
512
416
|
}
|
|
513
|
-
/**
|
|
514
|
-
* Check is polygons are same. They can be with different directions and different start points.
|
|
515
|
-
* @param p
|
|
516
|
-
*/
|
|
517
417
|
same(p) {
|
|
518
418
|
const pClone = p.clone().close();
|
|
519
419
|
const thisAsString = this.clone()
|
|
@@ -531,11 +431,6 @@ class DPolygon {
|
|
|
531
431
|
findIndex(p) {
|
|
532
432
|
return this.points.findIndex((t) => t.equal(p));
|
|
533
433
|
}
|
|
534
|
-
/**
|
|
535
|
-
* Get polygon approximation by
|
|
536
|
-
* [Ramer–Douglas–Peucker algorithm](https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm)
|
|
537
|
-
* @param [e=Math.sqrt(this.perimeter)*APPROXIMATION_VALUE]
|
|
538
|
-
*/
|
|
539
434
|
approximation(e = Math.sqrt(this.perimeter) * APPROXIMATION_VALUE) {
|
|
540
435
|
return new DPolygon(this.clone().douglasPeucker(this.pPoints, e));
|
|
541
436
|
}
|
|
@@ -545,10 +440,6 @@ class DPolygon {
|
|
|
545
440
|
removePart(index, count) {
|
|
546
441
|
return this.pPoints.splice(index + 1, count);
|
|
547
442
|
}
|
|
548
|
-
/**
|
|
549
|
-
* Check intersection with other polygon
|
|
550
|
-
* @param p
|
|
551
|
-
*/
|
|
552
443
|
hasSimpleIntersection(p) {
|
|
553
444
|
const extend1 = this.extend;
|
|
554
445
|
const extend2 = p.extend;
|
|
@@ -558,10 +449,6 @@ class DPolygon {
|
|
|
558
449
|
const in2 = extend2points.some((t) => extend1.simpleInclude(t));
|
|
559
450
|
return in1 || in2;
|
|
560
451
|
}
|
|
561
|
-
/**
|
|
562
|
-
* Check if it possible to include point
|
|
563
|
-
* @param p
|
|
564
|
-
*/
|
|
565
452
|
simpleInclude(p) {
|
|
566
453
|
return this.simpleIncludeX(p) && this.simpleIncludeY(p);
|
|
567
454
|
}
|
|
@@ -605,12 +492,6 @@ class DPolygon {
|
|
|
605
492
|
ctx.fill();
|
|
606
493
|
ctx.globalCompositeOperation = old;
|
|
607
494
|
}
|
|
608
|
-
/**
|
|
609
|
-
* Check if contain point
|
|
610
|
-
* @param p
|
|
611
|
-
* @param [isBorderInside=false]
|
|
612
|
-
* @param [move=(0,0)] Ignore this parameter
|
|
613
|
-
*/
|
|
614
495
|
contain(p, isBorderInside = false, move = DPoint_1.DPoint.zero()) {
|
|
615
496
|
const simpleInclude = this.simpleInclude(p);
|
|
616
497
|
if (!simpleInclude) {
|
|
@@ -636,10 +517,6 @@ class DPolygon {
|
|
|
636
517
|
}
|
|
637
518
|
return intersectionPoints.length % 2 === 1;
|
|
638
519
|
}
|
|
639
|
-
/**
|
|
640
|
-
* Check if point on border
|
|
641
|
-
* @param p
|
|
642
|
-
*/
|
|
643
520
|
onBorder(p) {
|
|
644
521
|
const simpleInclude = this.simpleInclude(p);
|
|
645
522
|
if (simpleInclude) {
|
|
@@ -660,18 +537,12 @@ class DPolygon {
|
|
|
660
537
|
}
|
|
661
538
|
return false;
|
|
662
539
|
}
|
|
663
|
-
/**
|
|
664
|
-
* Change start point to second point
|
|
665
|
-
*/
|
|
666
540
|
nextStart() {
|
|
667
541
|
this.open();
|
|
668
542
|
this.push(this.shift());
|
|
669
543
|
this.close();
|
|
670
544
|
return this;
|
|
671
545
|
}
|
|
672
|
-
/**
|
|
673
|
-
* Remove duplicates points
|
|
674
|
-
*/
|
|
675
546
|
removeDuplicates() {
|
|
676
547
|
for (let i = 0; i < this.length - 1; i++) {
|
|
677
548
|
const p1 = this.at(i);
|
|
@@ -686,17 +557,9 @@ class DPolygon {
|
|
|
686
557
|
static parse(a) {
|
|
687
558
|
return new DPolygon(a.map((r) => DPoint_1.DPoint.parse(r)));
|
|
688
559
|
}
|
|
689
|
-
/**
|
|
690
|
-
* Transform to array of coordinates for [OpenLayers](https://openlayers.org/) or
|
|
691
|
-
* [GeoJSON](https://en.wikipedia.org/wiki/GeoJSON)
|
|
692
|
-
*/
|
|
693
560
|
toArrayOfCoords() {
|
|
694
561
|
return this.pPoints.map((r) => r.toCoords());
|
|
695
562
|
}
|
|
696
|
-
/**
|
|
697
|
-
* Divide line string to pieces by length
|
|
698
|
-
* @param piecesCount
|
|
699
|
-
*/
|
|
700
563
|
divideToPieces(piecesCount) {
|
|
701
564
|
const { fullLength } = this;
|
|
702
565
|
const pieceLength = fullLength / piecesCount;
|
|
@@ -749,13 +612,8 @@ class DPolygon {
|
|
|
749
612
|
}
|
|
750
613
|
return this.searchStore[x][y][z || 'undefined'];
|
|
751
614
|
}
|
|
752
|
-
/**
|
|
753
|
-
* Get line string as line string with growing length. For animation.
|
|
754
|
-
*/
|
|
755
615
|
get growingPiecesGenerator() {
|
|
756
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias,consistent-this
|
|
757
616
|
const polygon = this;
|
|
758
|
-
// eslint-disable-next-line func-names
|
|
759
617
|
return function* () {
|
|
760
618
|
const r = new DPolygon();
|
|
761
619
|
for (const p of polygon.pPoints) {
|
|
@@ -789,10 +647,9 @@ class DPolygon {
|
|
|
789
647
|
return this.simpleLogicFunction(p, true, false);
|
|
790
648
|
}
|
|
791
649
|
smartUnion(p) {
|
|
792
|
-
var _a;
|
|
793
650
|
const res = this.clone().simpleUnion(p);
|
|
794
651
|
if (res) {
|
|
795
|
-
let allHoles = [...this.holes, ...p.holes, ...
|
|
652
|
+
let allHoles = [...this.holes, ...p.holes, ...res.holes].map((h) => h.clone());
|
|
796
653
|
for (const a of allHoles) {
|
|
797
654
|
for (const b of allHoles) {
|
|
798
655
|
if (a.equal(b)) {
|
|
@@ -801,12 +658,7 @@ class DPolygon {
|
|
|
801
658
|
const r = a.simpleUnion(b);
|
|
802
659
|
if (r) {
|
|
803
660
|
allHoles = allHoles.filter((v) => !v.equal(a) && !v.equal(b));
|
|
804
|
-
|
|
805
|
-
allHoles = [...allHoles, ...r];
|
|
806
|
-
}
|
|
807
|
-
else {
|
|
808
|
-
allHoles.push(r);
|
|
809
|
-
}
|
|
661
|
+
allHoles.push(r);
|
|
810
662
|
}
|
|
811
663
|
}
|
|
812
664
|
}
|
|
@@ -814,11 +666,6 @@ class DPolygon {
|
|
|
814
666
|
}
|
|
815
667
|
return res;
|
|
816
668
|
}
|
|
817
|
-
/**
|
|
818
|
-
* Divide polygon to triangles
|
|
819
|
-
*
|
|
820
|
-
* 
|
|
821
|
-
*/
|
|
822
669
|
toTriangles() {
|
|
823
670
|
const innerAndNotIntersect = (poly, p1, p2) => {
|
|
824
671
|
const l = p1.findLine(p2);
|
|
@@ -872,6 +719,81 @@ class DPolygon {
|
|
|
872
719
|
res.push(p);
|
|
873
720
|
return res;
|
|
874
721
|
}
|
|
722
|
+
getTrianglesPointIndexes() {
|
|
723
|
+
const innerAndNotIntersect = (poly, p1, p2) => {
|
|
724
|
+
const l = p1.findLine(p2);
|
|
725
|
+
const { center } = l;
|
|
726
|
+
const intersections = poly.holes.reduce((a, hole) => a && Boolean(hole.clone().close()
|
|
727
|
+
.intersection(l, true).length), Boolean(poly.clone().close()
|
|
728
|
+
.intersection(l, true).length));
|
|
729
|
+
const contain = poly.holes.reduce((a, hole) => a && !hole
|
|
730
|
+
.contain(center), poly.contain(center));
|
|
731
|
+
return !intersections && contain;
|
|
732
|
+
};
|
|
733
|
+
const getTriangle = (poly) => {
|
|
734
|
+
for (let i = 0; i < poly.length; i++) {
|
|
735
|
+
const p0 = poly.at(0);
|
|
736
|
+
const p1 = poly.at(1);
|
|
737
|
+
const p2 = poly.at(2);
|
|
738
|
+
if (innerAndNotIntersect(poly, p0, p2)) {
|
|
739
|
+
poly.removePart(0, 1);
|
|
740
|
+
return [
|
|
741
|
+
p0.properties.index,
|
|
742
|
+
p1.properties.index,
|
|
743
|
+
p2.properties.index
|
|
744
|
+
];
|
|
745
|
+
}
|
|
746
|
+
poly.push(poly.shift());
|
|
747
|
+
}
|
|
748
|
+
return undefined;
|
|
749
|
+
};
|
|
750
|
+
let p = this.clone();
|
|
751
|
+
let index = 0;
|
|
752
|
+
p.points.forEach((f) => {
|
|
753
|
+
f.properties.index = index++;
|
|
754
|
+
});
|
|
755
|
+
p.holes.forEach((h) => {
|
|
756
|
+
h.pPoints.forEach((f) => {
|
|
757
|
+
f.properties.index = index++;
|
|
758
|
+
});
|
|
759
|
+
});
|
|
760
|
+
p = p.clockWise.open();
|
|
761
|
+
while (p.holes.length) {
|
|
762
|
+
const h = p.holes.shift()
|
|
763
|
+
.clone()
|
|
764
|
+
.clockWise
|
|
765
|
+
.reverse()
|
|
766
|
+
.close();
|
|
767
|
+
for (let i = 0; i < p.length; i++) {
|
|
768
|
+
if (innerAndNotIntersect(p, p.first, h.first)) {
|
|
769
|
+
p.insertAfter(0, ...h.points, p.first);
|
|
770
|
+
break;
|
|
771
|
+
}
|
|
772
|
+
p.push(p.shift());
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
const res = [];
|
|
776
|
+
while (p.length > 3) {
|
|
777
|
+
const triangle = getTriangle(p);
|
|
778
|
+
if (triangle) {
|
|
779
|
+
res.push(...triangle);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
res.push(...p.points.map((f) => f.properties.index));
|
|
783
|
+
return res;
|
|
784
|
+
}
|
|
785
|
+
get closed() {
|
|
786
|
+
return this.first.equal(this.last);
|
|
787
|
+
}
|
|
788
|
+
buffer(v, quadrantSegments = 64, type = DPolygon.CAP_ROUND) {
|
|
789
|
+
const reader = new jsts_1.io.WKTReader();
|
|
790
|
+
const { noHoles, closed } = this;
|
|
791
|
+
const points = reader
|
|
792
|
+
.read(noHoles.toWKT(closed ? DPolygon.WKT_POLYGON : DPolygon.WKT_LINESTRING))
|
|
793
|
+
.buffer(v, quadrantSegments, type)
|
|
794
|
+
.getCoordinates();
|
|
795
|
+
return new DPolygon(points.map(({ x, y }) => new DPoint_1.DPoint(x, y)));
|
|
796
|
+
}
|
|
875
797
|
simpleIncludeX(p) {
|
|
876
798
|
const { x } = p;
|
|
877
799
|
return this.minX <= x && this.maxX >= x;
|
|
@@ -932,7 +854,6 @@ class DPolygon {
|
|
|
932
854
|
totalFi -= fiDif;
|
|
933
855
|
}
|
|
934
856
|
}
|
|
935
|
-
// eslint-disable-next-line no-magic-numbers
|
|
936
857
|
const eps = Math.PI / 10000;
|
|
937
858
|
let result = false;
|
|
938
859
|
const absTotalFi = Math.abs(totalFi);
|
|
@@ -1033,3 +954,8 @@ class DPolygon {
|
|
|
1033
954
|
}
|
|
1034
955
|
}
|
|
1035
956
|
exports.DPolygon = DPolygon;
|
|
957
|
+
DPolygon.CAP_ROUND = CAP_ROUND;
|
|
958
|
+
DPolygon.CAP_FLAT = CAP_FLAT;
|
|
959
|
+
DPolygon.CAP_SQUARE = CAP_SQUARE;
|
|
960
|
+
DPolygon.WKT_LINESTRING = 'LINESTRING';
|
|
961
|
+
DPolygon.WKT_POLYGON = 'POLYGON';
|
package/dist/DPolygonLoop.d.ts
CHANGED
|
@@ -6,92 +6,30 @@ export declare class DPolygonLoop {
|
|
|
6
6
|
private pool;
|
|
7
7
|
constructor(parent: DPolygon);
|
|
8
8
|
private getLoopFunction;
|
|
9
|
-
/**
|
|
10
|
-
* Run loop
|
|
11
|
-
*/
|
|
12
9
|
run(): DPolygon;
|
|
13
|
-
/**
|
|
14
|
-
* @param zoom default value would be `z` of point
|
|
15
|
-
*/
|
|
16
10
|
getTileFromCoords(zoom?: number): DPolygonLoop;
|
|
17
|
-
/**
|
|
18
|
-
* @param zoom default value would be `z` of point
|
|
19
|
-
*/
|
|
20
11
|
getCoordsFromTile(zoom?: number): DPolygonLoop;
|
|
21
12
|
height(z: number): DPolygonLoop;
|
|
22
|
-
/**
|
|
23
|
-
* Set `x` value
|
|
24
|
-
* @param x
|
|
25
|
-
*/
|
|
26
13
|
setX(x: number): DPolygonLoop;
|
|
27
|
-
/**
|
|
28
|
-
* Transform `x` value by function
|
|
29
|
-
* @param f
|
|
30
|
-
*/
|
|
31
14
|
setX(f: SetterFunction): DPolygonLoop;
|
|
32
|
-
/**
|
|
33
|
-
* Set `y` value
|
|
34
|
-
* @param y
|
|
35
|
-
*/
|
|
36
15
|
setY(y: number): DPolygonLoop;
|
|
37
|
-
/**
|
|
38
|
-
* Transform `y` value by function
|
|
39
|
-
* @param f
|
|
40
|
-
*/
|
|
41
16
|
setY(f: SetterFunction): DPolygonLoop;
|
|
17
|
+
setZ(z: number): DPolygonLoop;
|
|
18
|
+
setZ(f: SetterFunction): DPolygonLoop;
|
|
42
19
|
rotate(a: number): DPolygonLoop;
|
|
43
|
-
/**
|
|
44
|
-
* Add `v` to `x` and `y`
|
|
45
|
-
* @param v
|
|
46
|
-
*/
|
|
47
20
|
move(v: number): DPolygonLoop;
|
|
48
|
-
/**
|
|
49
|
-
* Add `p.x` to `x` field and `p.y` to `y` field.
|
|
50
|
-
* @param p
|
|
51
|
-
*/
|
|
52
21
|
move(p: DPoint): DPolygonLoop;
|
|
53
|
-
/**
|
|
54
|
-
* Add `x` to `x` field and `y` to `y` field.
|
|
55
|
-
* @param x
|
|
56
|
-
* @param y
|
|
57
|
-
*/
|
|
58
22
|
move(x: number, y: number): DPolygonLoop;
|
|
59
23
|
round(): DPolygonLoop;
|
|
60
24
|
ceil(): DPolygonLoop;
|
|
61
25
|
floor(): DPolygonLoop;
|
|
62
26
|
toFixed(n?: number): DPolygonLoop;
|
|
63
27
|
abs(): DPolygonLoop;
|
|
64
|
-
/**
|
|
65
|
-
* Multiply `v` to `x` and `y`
|
|
66
|
-
* @param v
|
|
67
|
-
*/
|
|
68
28
|
scale(v: number): DPolygonLoop;
|
|
69
|
-
/**
|
|
70
|
-
* Multiply `p.x` to `x` field and `p.y` to `y` field.
|
|
71
|
-
* @param p
|
|
72
|
-
*/
|
|
73
29
|
scale(p: DPoint): DPolygonLoop;
|
|
74
|
-
/**
|
|
75
|
-
* Multiply `x` to `x` field and `y` to `y` field.
|
|
76
|
-
* @param x
|
|
77
|
-
* @param y
|
|
78
|
-
*/
|
|
79
30
|
scale(x: number, y: number): DPolygonLoop;
|
|
80
|
-
/**
|
|
81
|
-
* Divide `x` and `y` to `v`
|
|
82
|
-
* @param v
|
|
83
|
-
*/
|
|
84
31
|
divide(v: number): DPolygonLoop;
|
|
85
|
-
/**
|
|
86
|
-
* Divide `x` field to `p.x` and `y` field to `p.y`.
|
|
87
|
-
* @param p
|
|
88
|
-
*/
|
|
89
32
|
divide(p: DPoint): DPolygonLoop;
|
|
90
|
-
/**
|
|
91
|
-
* Divide `x` field to `x` and `y` field to `y`.
|
|
92
|
-
* @param x
|
|
93
|
-
* @param y
|
|
94
|
-
*/
|
|
95
33
|
divide(x: number, y: number): DPolygonLoop;
|
|
96
34
|
degreeToRadians(): DPolygonLoop;
|
|
97
35
|
radiansToDegrees(): DPolygonLoop;
|
|
@@ -106,14 +44,6 @@ export declare class DPolygonLoop {
|
|
|
106
44
|
minus(): DPolygonLoop;
|
|
107
45
|
degreeToMeters(): DPolygonLoop;
|
|
108
46
|
metersToDegree(): DPolygonLoop;
|
|
109
|
-
/**
|
|
110
|
-
* Flip vertically
|
|
111
|
-
* @param size canvas size
|
|
112
|
-
*/
|
|
113
47
|
flipVertically(size: DPoint): DPolygonLoop;
|
|
114
|
-
/**
|
|
115
|
-
* Flip vertically
|
|
116
|
-
* @param height canvas height
|
|
117
|
-
*/
|
|
118
48
|
flipVertically(height: number): DPolygonLoop;
|
|
119
49
|
}
|