dgeoutils 2.0.2 → 2.2.2

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/DPolygon.js CHANGED
@@ -66,7 +66,7 @@ class DPolygon {
66
66
  }
67
67
  return first.findLine(last).getFi();
68
68
  }
69
- static parseFromWKT(wkt, optProps) {
69
+ static parseFromWKT(wkt) {
70
70
  const data = wkt.trim().toUpperCase();
71
71
  let res = new DPolygon();
72
72
  if (data.indexOf('POLYGON') === 0) {
@@ -90,9 +90,6 @@ class DPolygon {
90
90
  if (data.indexOf('POINT') === 0) {
91
91
  res = new DPolygon([DPoint_1.DPoint.parseFromWKT(data)]);
92
92
  }
93
- if (optProps) {
94
- return res.transform(optProps.dataProjection, optProps.featureProjection);
95
- }
96
93
  return res;
97
94
  }
98
95
  static createSquareBySize(size) {
@@ -212,8 +209,8 @@ class DPolygon {
212
209
  const closed = this.deintersection;
213
210
  let sum = 0;
214
211
  for (let i = 1; i < closed.length; i++) {
215
- const cur = closed.p(i);
216
- const prev = closed.p(i - 1);
212
+ const cur = closed.at(i);
213
+ const prev = closed.at(i - 1);
217
214
  sum += prev.x * cur.y - prev.y * cur.x;
218
215
  }
219
216
  return Math.abs(sum / 2) - this.holes.reduce((a, hole) => a + hole.area, 0);
@@ -225,8 +222,8 @@ class DPolygon {
225
222
  const p = this.clone().close();
226
223
  for (let i = 0; i < p.length - 1; i++) {
227
224
  for (let j = i + 2; j < p.length - 1; j++) {
228
- const firstLine = p.p(i).findLine(p.p(i + 1));
229
- const secondLine = p.p(j).findLine(p.p(j + 1));
225
+ const firstLine = p.at(i).findLine(p.at(i + 1));
226
+ const secondLine = p.at(j).findLine(p.at(j + 1));
230
227
  const intersectionPoint = firstLine.intersection(secondLine);
231
228
  if (intersectionPoint &&
232
229
  ![...firstLine.points, ...secondLine.points].some((t) => t.like(intersectionPoint))) {
@@ -249,19 +246,19 @@ class DPolygon {
249
246
  * Get first point
250
247
  */
251
248
  get first() {
252
- return this.p(0);
249
+ return this.at(0);
253
250
  }
254
251
  /**
255
252
  * Get second point
256
253
  */
257
254
  get second() {
258
- return this.p(1);
255
+ return this.at(1);
259
256
  }
260
257
  /**
261
258
  * Get last point
262
259
  */
263
260
  get last() {
264
- return this.p(this.length - 1);
261
+ return this.at(this.length - 1);
265
262
  }
266
263
  /**
267
264
  * Get min area rectangle
@@ -271,21 +268,21 @@ class DPolygon {
271
268
  let resultPolygon = new DPolygon();
272
269
  let resultArea = Infinity;
273
270
  for (let k = 0; k < p.length - 1; k++) {
274
- const l = p.p(k).findLine(p.p(k + 1));
271
+ const l = p.at(k).findLine(p.at(k + 1));
275
272
  let maxWidth = 0;
276
273
  let maxWidthPoint1 = null;
277
274
  let maxWidthPoint2 = null;
278
275
  let maxHeight = 0;
279
276
  let maxHeightPoint = null;
280
277
  for (let i = 0; i < p.length - 1; i++) {
281
- const p1 = l.findPoint(l.findPerpendicular(p.p(i)));
282
- const h = p1.distance(p.p(i));
278
+ const p1 = l.findPoint(l.findPerpendicular(p.at(i)));
279
+ const h = p1.distance(p.at(i));
283
280
  if (h >= maxHeight) {
284
281
  maxHeight = h;
285
- maxHeightPoint = p.p(i);
282
+ maxHeightPoint = p.at(i);
286
283
  }
287
284
  for (let j = i; j < p.length - 1; j++) {
288
- const p2 = l.findPoint(l.findPerpendicular(p.p(j)));
285
+ const p2 = l.findPoint(l.findPerpendicular(p.at(j)));
289
286
  const w = p1.distance(p2);
290
287
  if (w >= maxWidth) {
291
288
  maxWidth = w;
@@ -341,9 +338,9 @@ class DPolygon {
341
338
  p = p.deintersection;
342
339
  l = p.length;
343
340
  for (let i = 1; i < p.length - 1; i++) {
344
- const p1 = p.p(i - 1);
345
- const p2 = p.p(i);
346
- const p3 = p.p(i + 1);
341
+ const p1 = p.at(i - 1);
342
+ const p2 = p.at(i);
343
+ const p3 = p.at(i + 1);
347
344
  const d = p2.findInnerAngle(p1, p3);
348
345
  if (d > Math.PI || DNumbers_1.DNumbers.likeZero(DNumbers_1.DNumbers.rad2Deg(d)) || DNumbers_1.DNumbers.likePI(d) || DNumbers_1.DNumbers.like2PI(d)) {
349
346
  p.removePart(--i, 1);
@@ -363,8 +360,8 @@ class DPolygon {
363
360
  let sum = 0;
364
361
  const p = this.clone().close();
365
362
  for (let i = 1; i < p.length; i++) {
366
- const p1 = p.p(i - 1);
367
- const p2 = p.p(i);
363
+ const p1 = p.at(i - 1);
364
+ const p2 = p.at(i);
368
365
  sum += (p2.x - p1.x) * (p2.y + p1.y);
369
366
  }
370
367
  return sum < 0;
@@ -389,14 +386,15 @@ class DPolygon {
389
386
  /**
390
387
  * Check polygon intersection with line
391
388
  * @param l
389
+ * @param [includeOnly=false]
392
390
  */
393
- intersection(l) {
391
+ intersection(l, includeOnly = false) {
394
392
  const res = [];
395
393
  for (let i = 0; i < this.pPoints.length - 1; i++) {
396
394
  const p1 = this.pPoints[i];
397
395
  const p2 = this.pPoints[i + 1];
398
396
  const line = p1.findLine(p2);
399
- const intersect = line.intersection(l);
397
+ const intersect = line.intersection(l, 0, includeOnly);
400
398
  if (intersect) {
401
399
  res.push(intersect);
402
400
  }
@@ -408,7 +406,9 @@ class DPolygon {
408
406
  * @param newCenter
409
407
  */
410
408
  setCenter(newCenter) {
411
- return this.clone().move(newCenter.clone().move(this.center.minus()));
409
+ return this.loop()
410
+ .move(newCenter.clone().move(this.center.minus()))
411
+ .run();
412
412
  }
413
413
  toWKT() {
414
414
  let h = '';
@@ -420,11 +420,10 @@ class DPolygon {
420
420
  /**
421
421
  * Rotate polygon with center in point {0, 0}
422
422
  * @param a Radians
423
+ * @deprecated Better to use loop
423
424
  */
424
425
  rotate(a) {
425
- this.pPoints = this.pPoints.map((p) => p.rotate(a));
426
- this.holes = this.holes.map((h) => h.rotate(a));
427
- return this;
426
+ return this.map((h) => h.rotate(a));
428
427
  }
429
428
  /**
430
429
  * Filter points
@@ -434,55 +433,70 @@ class DPolygon {
434
433
  this.pPoints = this.pPoints.filter(f);
435
434
  return this;
436
435
  }
436
+ /**
437
+ * @deprecated Better to use loop
438
+ * @param [x=0]
439
+ * @param [y=x]
440
+ */
437
441
  move(x = 0, y) {
438
- this.pPoints = this.pPoints.map((p) => p.move(x, y));
439
- this.holes = this.holes.map((h) => h.move(x, y));
440
- return this;
442
+ return this.map((h) => h.move(x, y));
441
443
  }
444
+ /**
445
+ * @deprecated Better to use loop
446
+ * @param [x=0]
447
+ * @param [y=x]
448
+ */
442
449
  scale(x = 0, y) {
443
- this.pPoints = this.pPoints.map((p) => p.scale(x, y));
444
- this.holes = this.holes.map((h) => h.scale(x, y));
445
- return this;
450
+ return this.map((h) => h.scale(x, y));
446
451
  }
452
+ /**
453
+ * @deprecated Better to use loop
454
+ * @param [x=0]
455
+ * @param [y=x]
456
+ */
447
457
  divide(x = 0, y) {
448
- this.pPoints = this.pPoints.map((p) => p.divide(x, y));
449
- this.holes = this.holes.map((h) => h.divide(x, y));
450
- return this;
458
+ return this.map((h) => h.divide(x, y));
451
459
  }
460
+ /**
461
+ * @deprecated Better to use loop
462
+ */
452
463
  round() {
453
- this.pPoints = this.pPoints.map((p) => p.round());
454
- this.holes = this.holes.map((h) => h.round());
455
- return this;
464
+ return this.map((h) => h.round());
456
465
  }
466
+ /**
467
+ * @deprecated Better to use loop
468
+ */
457
469
  floor() {
458
- this.pPoints = this.pPoints.map((p) => p.floor());
459
- this.holes = this.holes.map((h) => h.floor());
460
- return this;
470
+ return this.map((h) => h.floor());
461
471
  }
472
+ /**
473
+ * @deprecated Better to use loop
474
+ */
462
475
  ceil() {
463
- this.pPoints = this.pPoints.map((p) => p.ceil());
464
- this.holes = this.holes.map((h) => h.ceil());
465
- return this;
476
+ return this.map((h) => h.ceil());
477
+ }
478
+ /**
479
+ * @deprecated Better to use loop
480
+ * @param size
481
+ */
482
+ flipVertically(size) {
483
+ return this.map((h) => h.flipVertically(size));
466
484
  }
485
+ /**
486
+ * @deprecated Better to use loop
487
+ * @param [n=2]
488
+ */
467
489
  toFixed(n = 2) {
468
- this.pPoints = this.pPoints.map((p) => p.toFixed(n));
469
- this.holes = this.holes.map((h) => h.toFixed(n));
470
- return this;
490
+ return this.map((h) => h.toFixed(n));
471
491
  }
472
492
  map(f) {
473
493
  this.pPoints = this.pPoints.map(f);
474
494
  this.holes = this.holes.map((h) => h.map(f));
475
495
  return this;
476
496
  }
477
- p(index, divide = false) {
478
- if (divide) {
479
- let t = index;
480
- while (t < 0) {
481
- t += this.length;
482
- }
483
- return this.pPoints[t % this.length];
484
- }
485
- return this.pPoints[index];
497
+ at(index) {
498
+ const { length } = this;
499
+ return this.points[(index % length + length) % length];
486
500
  }
487
501
  pop() {
488
502
  return this.pPoints.pop();
@@ -505,10 +519,29 @@ class DPolygon {
505
519
  return (this.pPoints.map((r) => r.getValue()) + this.holes
506
520
  .reduce((a, h) => a + h.getValue(), ''));
507
521
  }
508
- transform(from = DPoint_1.PSEUDO_MERCATOR, to = DPoint_1.WORLD_GEODETIC_SYSTEM) {
509
- this.pPoints = this.pPoints.map((r) => r.transform(from, to));
510
- this.holes = this.holes.map((h) => h.transform(from, to));
511
- return this;
522
+ /**
523
+ * @deprecated Better to use loop
524
+ */
525
+ degreeToMeters() {
526
+ return this.map((r) => r.degreeToMeters());
527
+ }
528
+ /**
529
+ * @deprecated Better to use loop
530
+ */
531
+ metersToDegree() {
532
+ return this.map((r) => r.metersToDegree());
533
+ }
534
+ /**
535
+ * @deprecated Better to use loop
536
+ */
537
+ radiansToMeters() {
538
+ return this.map((r) => r.radiansToMeters());
539
+ }
540
+ /**
541
+ * @deprecated Better to use loop
542
+ */
543
+ metersToRadians() {
544
+ return this.map((r) => r.metersToRadians());
512
545
  }
513
546
  toString() {
514
547
  return `(${this.pPoints.map((r) => r.toString()).join(', ')})`;
@@ -536,11 +569,10 @@ class DPolygon {
536
569
  /**
537
570
  * Set `height` (`z`)
538
571
  * @param z
572
+ * @deprecated Better to use loop
539
573
  */
540
574
  height(z) {
541
- this.map((p) => p.height(z));
542
- this.holes = this.holes.map((h) => h.height(z));
543
- return this;
575
+ return this.map((p) => p.height(z));
544
576
  }
545
577
  add(poly) {
546
578
  const res = new DPolygon([...this.points, ...poly.points]).close();
@@ -568,7 +600,7 @@ class DPolygon {
568
600
  if (!(p instanceof DPolygon)) {
569
601
  return false;
570
602
  }
571
- if (this.clone().open().length !== p.clone().open().length || this.holes.length !== p.holes.length) {
603
+ if (this.length !== p.length || this.holes.length !== p.holes.length) {
572
604
  return false;
573
605
  }
574
606
  return (this.same(p) &&
@@ -579,20 +611,18 @@ class DPolygon {
579
611
  * @param p
580
612
  */
581
613
  same(p) {
582
- const pClone = p.clone().open();
583
- const thisClone = this.clone().open();
584
- const thisAsString = thisClone.toString();
585
- return thisClone.points.reduce((a) => {
586
- const f = pClone.shift();
587
- pClone.push(f);
588
- return (a ||
589
- thisAsString === pClone.toString() ||
590
- thisAsString ===
591
- pClone
592
- .clone()
593
- .reverse()
594
- .toString());
595
- }, false);
614
+ const pClone = p.clone().close();
615
+ const thisAsString = this.clone()
616
+ .close()
617
+ .toString();
618
+ for (let i = 0; i < pClone.length; i++) {
619
+ if (thisAsString === pClone.toString() || thisAsString === pClone.clone().reverse()
620
+ .toString()) {
621
+ return true;
622
+ }
623
+ pClone.nextStart();
624
+ }
625
+ return false;
596
626
  }
597
627
  findIndex(p) {
598
628
  return this.points.findIndex((t) => t.equal(p));
@@ -645,7 +675,7 @@ class DPolygon {
645
675
  if (lineWidth) {
646
676
  ctx.lineWidth = lineWidth;
647
677
  }
648
- if (fillColor) {
678
+ if (fillColor || strokeColor) {
649
679
  ctx.beginPath();
650
680
  }
651
681
  this.goByPath(ctx, steps % this.length);
@@ -690,7 +720,7 @@ class DPolygon {
690
720
  const poly = this.deintersection;
691
721
  const intersectionPoints = [];
692
722
  for (let i = 0; i < poly.length - 1; i++) {
693
- const polygonLine = poly.p(i).findLine(poly.p(i + 1));
723
+ const polygonLine = poly.at(i).findLine(poly.at(i + 1));
694
724
  const intersection = line.intersection(polygonLine, CLOSE_TO_INTERSECTION_DISTANCE);
695
725
  if (intersection) {
696
726
  intersectionPoints.push(intersection);
@@ -715,8 +745,8 @@ class DPolygon {
715
745
  return true;
716
746
  }
717
747
  for (let i = 0; i < poly.length - 1; i++) {
718
- const p0 = poly.p(i);
719
- const p1 = poly.p(i + 1);
748
+ const p0 = poly.at(i);
749
+ const p1 = poly.at(i + 1);
720
750
  const polygonLine = p0.findLine(p1);
721
751
  const onBorder = polygonLine.x(p).equal(p) && polygonLine.inRange(p);
722
752
  if (onBorder) {
@@ -740,8 +770,8 @@ class DPolygon {
740
770
  */
741
771
  removeDuplicates() {
742
772
  for (let i = 0; i < this.length - 1; i++) {
743
- const p1 = this.p(i);
744
- const p2 = this.p(i + 1);
773
+ const p1 = this.at(i);
774
+ const p2 = this.at(i + 1);
745
775
  if (p1.equal(p2)) {
746
776
  this.removePart(i, 1);
747
777
  i--;
@@ -885,6 +915,64 @@ class DPolygon {
885
915
  }
886
916
  return res;
887
917
  }
918
+ /**
919
+ * Divide polygon to triangles
920
+ *
921
+ * ![Example](https://edejin.github.io/DGeoUtils/media/examples/toTriangles.png)
922
+ */
923
+ toTriangles() {
924
+ const innerAndNotIntersect = (poly, p1, p2) => {
925
+ const l = p1.findLine(p2);
926
+ const { center } = l;
927
+ const intersections = poly.holes.reduce((a, hole) => a && Boolean(hole.clone().close()
928
+ .intersection(l, true).length), Boolean(poly.clone().close()
929
+ .intersection(l, true).length));
930
+ const contain = poly.holes.reduce((a, hole) => a && !hole
931
+ .contain(center), poly.contain(center));
932
+ return !intersections && contain;
933
+ };
934
+ const getTriangle = (poly) => {
935
+ for (let i = 0; i < poly.length; i++) {
936
+ const p0 = poly.at(0);
937
+ const p1 = poly.at(1);
938
+ const p2 = poly.at(2);
939
+ if (innerAndNotIntersect(poly, p0, p2)) {
940
+ poly.removePart(0, 1);
941
+ return new DPolygon([
942
+ p0.clone(),
943
+ p1.clone(),
944
+ p2.clone()
945
+ ]);
946
+ }
947
+ poly.push(poly.shift());
948
+ }
949
+ return undefined;
950
+ };
951
+ const p = this.clone().clockWise.open();
952
+ while (p.holes.length) {
953
+ const h = p.holes.shift()
954
+ .clone()
955
+ .clockWise
956
+ .reverse()
957
+ .close();
958
+ for (let i = 0; i < p.length; i++) {
959
+ if (innerAndNotIntersect(p, p.first, h.first)) {
960
+ p.insertAfter(0, ...h.points, p.first);
961
+ break;
962
+ }
963
+ p.push(p.shift());
964
+ }
965
+ }
966
+ const res = [];
967
+ while (p.length > 3) {
968
+ const triangle = getTriangle(p);
969
+ if (triangle) {
970
+ res.push(triangle);
971
+ }
972
+ }
973
+ res.push(p);
974
+ return res;
975
+ }
888
976
  simpleIncludeX(p) {
889
977
  const { x } = p;
890
978
  return this.minX <= x && this.maxX >= x;
@@ -917,7 +1005,7 @@ class DPolygon {
917
1005
  const start = this.first;
918
1006
  ctx.moveTo(start.x, start.y);
919
1007
  for (let i = 1; i <= (steps % this.length); i++) {
920
- const { x, y } = this.p(i);
1008
+ const { x, y } = this.at(i);
921
1009
  ctx.lineTo(x, y);
922
1010
  }
923
1011
  }
@@ -933,8 +1021,8 @@ class DPolygon {
933
1021
  const poly = this.deintersection;
934
1022
  let totalFi = 0;
935
1023
  for (let i = 0; i < poly.length - 1; i++) {
936
- const p1 = poly.p(i);
937
- const p2 = poly.p(i + 1);
1024
+ const p1 = poly.at(i);
1025
+ const p2 = poly.at(i + 1);
938
1026
  const line1 = new DLine_1.DLine(p1.x - p.x, p1.y - p.y, 0);
939
1027
  const line2 = new DLine_1.DLine(p2.x - p.x, p2.y - p.y, 0);
940
1028
  const fiDif = line1.findFi(line2);
@@ -1,12 +1,17 @@
1
1
  import { DPolygon } from './DPolygon';
2
2
  import { DPoint, SetterFunction } from './DPoint';
3
+ export declare type LoopFunction = (k: DPoint) => DPoint;
3
4
  export declare class DPolygonLoop {
4
- private f;
5
5
  private readonly parent;
6
+ private pool;
6
7
  constructor(parent: DPolygon);
8
+ private getLoopFunction;
9
+ /**
10
+ * Run loop
11
+ */
12
+ run(): DPolygon;
7
13
  getTileFromCoords(zoom?: number): DPolygonLoop;
8
14
  getCoordsFromTile(zoom?: number): DPolygonLoop;
9
- transform(from?: string, to?: string): DPolygonLoop;
10
15
  height(z: number): DPolygonLoop;
11
16
  setX(x: number | SetterFunction): DPolygonLoop;
12
17
  setY(y: number | SetterFunction): DPolygonLoop;
@@ -19,8 +24,10 @@ export declare class DPolygonLoop {
19
24
  abs(): DPolygonLoop;
20
25
  scale(x?: number | DPoint, y?: number): DPolygonLoop;
21
26
  divide(x?: number | DPoint, y?: number): DPolygonLoop;
22
- asRadians(): DPolygonLoop;
23
- asDegrees(): DPolygonLoop;
27
+ degreeToRadians(): DPolygonLoop;
28
+ radiansToDegrees(): DPolygonLoop;
29
+ radiansToMeters(): DPolygonLoop;
30
+ metersToRadians(): DPolygonLoop;
24
31
  getHipPoint(): DPolygonLoop;
25
32
  getXPoint(): DPolygonLoop;
26
33
  getYPoint(): DPolygonLoop;
@@ -28,5 +35,7 @@ export declare class DPolygonLoop {
28
35
  getHPoint(): DPolygonLoop;
29
36
  setIfLessThan(p: DPoint): DPolygonLoop;
30
37
  minus(): DPolygonLoop;
31
- run(): DPolygon;
38
+ degreeToMeters(): DPolygonLoop;
39
+ metersToDegree(): DPolygonLoop;
40
+ flipVertically(size: DPoint | number): DPolygonLoop;
32
41
  }