dgeoutils 2.2.3 → 2.2.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.
package/dist/DLine.d.ts CHANGED
@@ -4,9 +4,16 @@ export declare class DLine {
4
4
  a: number;
5
5
  b: number;
6
6
  c: number;
7
- p1: DPoint;
8
- p2: DPoint;
9
- constructor(a?: number, b?: number, c?: number, p1?: DPoint, p2?: DPoint);
7
+ begin: DPoint;
8
+ end: DPoint;
9
+ /**
10
+ * @param a
11
+ * @param b
12
+ * @param c
13
+ * @param [begin=DPoint.zero()]
14
+ * @param [end=DPoint.zero()]
15
+ */
16
+ constructor(a: number, b: number, c: number, begin?: DPoint, end?: DPoint);
10
17
  clone(): DLine;
11
18
  findPerpendicular(p: DPoint): DLine;
12
19
  perpendicularDistance(p: DPoint): number;
@@ -80,10 +87,10 @@ export declare class DLine {
80
87
  * @param l
81
88
  * @param delta
82
89
  */
83
- findFi(l: DLine, delta?: number): number;
90
+ findFi({ a, b }: DLine, delta?: number): number;
84
91
  /**
85
92
  * [Cross product](https://en.wikipedia.org/wiki/Cross_product)
86
- * @param l
93
+ * @param l {DLine}
87
94
  */
88
- vectorProduct(l: DLine): DLine;
95
+ vectorProduct({ a, b, c }: DLine): DLine;
89
96
  }
package/dist/DLine.js CHANGED
@@ -3,36 +3,44 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DLine = void 0;
4
4
  const DPoint_1 = require("./DPoint");
5
5
  const utils_1 = require("./utils");
6
+ // eslint-disable-next-line padded-blocks
6
7
  class DLine {
8
+ /**
9
+ * @param a
10
+ * @param b
11
+ * @param c
12
+ * @param [begin=DPoint.zero()]
13
+ * @param [end=DPoint.zero()]
14
+ */
7
15
  // eslint-disable-next-line no-useless-constructor
8
- constructor(a = 0, b = 0, c = 0, p1 = DPoint_1.DPoint.zero(), p2 = DPoint_1.DPoint.zero()
16
+ constructor(a, b, c, begin = DPoint_1.DPoint.zero(), end = DPoint_1.DPoint.zero()
9
17
  // eslint-disable-next-line no-empty-function
10
18
  ) {
11
19
  this.a = a;
12
20
  this.b = b;
13
21
  this.c = c;
14
- this.p1 = p1;
15
- this.p2 = p2;
22
+ this.begin = begin;
23
+ this.end = end;
16
24
  }
17
25
  clone() {
18
- return new DLine(this.a, this.b, this.c, this.p1.clone(), this.p2.clone());
26
+ return new DLine(this.a, this.b, this.c, this.begin.clone(), this.end.clone());
19
27
  }
20
28
  findPerpendicular(p) {
21
29
  (0, utils_1.checkFunction)('findPerpendicular')
22
- .checkArgument('this.p1')
23
- .shouldBeMeters(this.p1)
24
- .checkArgument('this.p2')
25
- .shouldBeMeters(this.p2)
30
+ .checkArgument('this.begin')
31
+ .shouldBeMeters(this.begin)
32
+ .checkArgument('this.end')
33
+ .shouldBeMeters(this.end)
26
34
  .checkArgument('p')
27
35
  .shouldBeMeters(p);
28
36
  return new DLine(-this.b, this.a, this.b * p.x - this.a * p.y);
29
37
  }
30
38
  perpendicularDistance(p) {
31
39
  (0, utils_1.checkFunction)('perpendicularDistance')
32
- .checkArgument('this.p1')
33
- .shouldBeMeters(this.p1)
34
- .checkArgument('this.p2')
35
- .shouldBeMeters(this.p2)
40
+ .checkArgument('this.begin')
41
+ .shouldBeMeters(this.begin)
42
+ .checkArgument('this.end')
43
+ .shouldBeMeters(this.end)
36
44
  .checkArgument('p')
37
45
  .shouldBeMeters(p);
38
46
  const perpendicularLine = this.findPerpendicular(p);
@@ -61,10 +69,10 @@ class DLine {
61
69
  const per = this.findPerpendicular(center);
62
70
  const t = this.intersection(per, Infinity);
63
71
  let distance = t.distance(center);
64
- if (this.p1.equal(center)) {
72
+ if (this.begin.equal(center)) {
65
73
  distance = 0;
66
74
  }
67
- if (this.p2.equal(center)) {
75
+ if (this.end.equal(center)) {
68
76
  distance = 0;
69
77
  }
70
78
  if (distance < r) {
@@ -74,25 +82,25 @@ class DLine {
74
82
  const move = Math.sqrt(r * r - ct * ct);
75
83
  // Mean "|" x = const
76
84
  if (this.isParallelY) {
77
- t.x = this.p1.x;
85
+ t.x = this.begin.x;
78
86
  const r1 = t.clone().move(0, -move);
79
87
  const r2 = t.clone().move(0, move);
80
88
  return [r1, r2];
81
89
  }
82
90
  // Mean "-" y = const
83
91
  if (this.isParallelX) {
84
- t.y = this.p1.y;
92
+ t.y = this.begin.y;
85
93
  const r1 = t.clone().move(move, 0);
86
94
  const r2 = t.clone().move(-move, 0);
87
95
  return [r1, r2];
88
96
  }
89
97
  }
90
- if (this.p1.like(center)) {
91
- const p = this.p1.clone();
98
+ if (this.begin.like(center)) {
99
+ const p = this.begin.clone();
92
100
  return [this.movePoint(p, r), this.movePoint(p, -r)];
93
101
  }
94
- if (this.p2.like(center)) {
95
- const p = this.p2.clone();
102
+ if (this.end.like(center)) {
103
+ const p = this.end.clone();
96
104
  return [this.movePoint(p, r), this.movePoint(p, -r)];
97
105
  }
98
106
  const s = a * a + b * b;
@@ -125,16 +133,16 @@ class DLine {
125
133
  * @param [d=0]
126
134
  */
127
135
  insideRange(p, d = 0) {
128
- const { p1, p2 } = this;
129
- return this.inRange(p, d) && !p1.like(p, 0.00001) && !p2.like(p, 0.00001);
136
+ const { begin, end } = this;
137
+ return this.inRange(p, d) && !begin.like(p, 0.00001) && !end.like(p, 0.00001);
130
138
  }
131
139
  get center() {
132
- return this.p1
140
+ return this.begin
133
141
  .clone()
134
- .setIfLessThan(this.p2)
135
- .move(this.p2
142
+ .setIfLessThan(this.end)
143
+ .move(this.end
136
144
  .clone()
137
- .move(this.p1
145
+ .move(this.begin
138
146
  .clone()
139
147
  .minus())
140
148
  .abs()
@@ -142,16 +150,16 @@ class DLine {
142
150
  .divide(2));
143
151
  }
144
152
  get minX() {
145
- return Math.min(this.p1.x, this.p2.x);
153
+ return Math.min(this.begin.x, this.end.x);
146
154
  }
147
155
  get minY() {
148
- return Math.min(this.p1.y, this.p2.y);
156
+ return Math.min(this.begin.y, this.end.y);
149
157
  }
150
158
  get maxX() {
151
- return Math.max(this.p1.x, this.p2.x);
159
+ return Math.max(this.begin.x, this.end.x);
152
160
  }
153
161
  get maxY() {
154
- return Math.max(this.p1.y, this.p2.y);
162
+ return Math.max(this.begin.y, this.end.y);
155
163
  }
156
164
  toString() {
157
165
  return `(${this.a}, ${this.b}, ${this.c})`;
@@ -241,47 +249,26 @@ class DLine {
241
249
  * Get lines segment start and end points as array
242
250
  */
243
251
  get points() {
244
- return [this.p1, this.p2];
252
+ return [this.begin, this.end];
245
253
  }
246
254
  /**
247
255
  * Get line segment direction (from start point to end point)
248
256
  */
249
257
  getFi() {
250
258
  (0, utils_1.checkFunction)('getFi')
251
- .checkArgument('this.p1')
252
- .shouldBeMeters(this.p1)
253
- .checkArgument('this.p2')
254
- .shouldBeMeters(this.p2);
255
- const l = new DLine(0, 1, 0);
256
- const result = this.findFi(l);
257
- if (this.p1.x === this.p2.x) {
258
- if (this.p1.y === this.p2.y) {
259
- return 0;
260
- }
261
- else if (this.p1.y < this.p2.y) {
262
- return Math.PI + Math.PI / 2;
263
- }
264
- return Math.PI / 2;
265
- }
266
- else if (this.p1.x < this.p2.x) {
267
- if (this.p1.y === this.p2.y) {
268
- return 0;
269
- }
270
- else if (this.p1.y < this.p2.y) {
271
- return Math.PI - result + Math.PI;
272
- }
273
- return result;
274
- }
275
- if (this.p1.y === this.p2.y) {
276
- return Math.PI;
259
+ .checkArgument('this.begin')
260
+ .shouldBeMeters(this.begin)
261
+ .checkArgument('this.end')
262
+ .shouldBeMeters(this.end);
263
+ const { x, y } = this.end.clone().move(this.begin.clone().minus());
264
+ let v = Math.atan2(y, x) - Math.PI;
265
+ if (v > 0) {
266
+ v = Math.PI - v;
277
267
  }
278
- else if (this.p1.y < this.p2.y) {
279
- return Math.PI - result + Math.PI;
280
- }
281
- return result;
268
+ return (Math.PI - v) % (Math.PI * 2);
282
269
  }
283
270
  toWKT() {
284
- const { p1: { x: x1, y: y1 }, p2: { x: x2, y: y2 } } = this;
271
+ const { begin: { x: x1, y: y1 }, end: { x: x2, y: y2 } } = this;
285
272
  return `LINESTRING (${x1} ${y1}, ${x2} ${y2})`;
286
273
  }
287
274
  /**
@@ -291,7 +278,7 @@ class DLine {
291
278
  */
292
279
  movePoint(p, d) {
293
280
  const fi = this.findFi(new DLine(1, 0, 0));
294
- const td = this.p1.distance(this.p2) / 2;
281
+ const td = this.begin.distance(this.end) / 2;
295
282
  const dcosT = td * Math.cos(fi);
296
283
  const dsinT = td * Math.sin(fi);
297
284
  const p1T = new DPoint_1.DPoint(p.x - dsinT, p.y - dcosT);
@@ -310,8 +297,9 @@ class DLine {
310
297
  * @param l
311
298
  * @param delta
312
299
  */
313
- findFi(l, delta = 1.0001) {
314
- let val = (this.a * l.a + this.b * l.b) / (Math.sqrt(this.a * this.a + this.b * this.b) * Math.sqrt(l.a * l.a + l.b * l.b));
300
+ findFi({ a, b }, delta = 1.0001) {
301
+ const { a: q, b: w } = this;
302
+ let val = (q * a + w * b) / (Math.sqrt(q * q + w * w) * Math.sqrt(a * a + b * b));
315
303
  if (val > 1 && val < delta) {
316
304
  val = 1;
317
305
  }
@@ -322,13 +310,11 @@ class DLine {
322
310
  }
323
311
  /**
324
312
  * [Cross product](https://en.wikipedia.org/wiki/Cross_product)
325
- * @param l
313
+ * @param l {DLine}
326
314
  */
327
- vectorProduct(l) {
328
- const i = this.b * l.c - this.c * l.b;
329
- const j = this.c * l.a - this.a * l.c;
330
- const k = this.a * l.b - this.b * l.a;
331
- return new DLine(i, j, k);
315
+ vectorProduct({ a, b, c }) {
316
+ const { a: q, b: w, c: e } = this;
317
+ return new DLine(w * c - e * b, e * a - q * c, q * b - w * a);
332
318
  }
333
319
  }
334
320
  exports.DLine = DLine;
package/dist/DPoint.d.ts CHANGED
@@ -24,15 +24,18 @@ export declare class DPoint {
24
24
  */
25
25
  constructor();
26
26
  /**
27
+ * Create point
27
28
  * @param xy - `x` and `y` value
28
29
  */
29
30
  constructor(xy: number);
30
31
  /**
32
+ * Create point
31
33
  * @param x - lng, meters to East, radians to East or width
32
34
  * @param y - lat, meters to North, radians to North or height
33
35
  */
34
36
  constructor(x: number, y: number);
35
37
  /**
38
+ * Create point
36
39
  * @param x - lng, meters to East, radians to East or width
37
40
  * @param y - lat, meters to North, radians to North or height
38
41
  * @param z - height
@@ -80,6 +83,16 @@ export declare class DPoint {
80
83
  * @param f
81
84
  */
82
85
  setX(f: SetterFunction): DPoint;
86
+ /**
87
+ * Set `z` value
88
+ * @param z
89
+ */
90
+ setZ(z: number): DPoint;
91
+ /**
92
+ * Transform `z` value by function
93
+ * @param f
94
+ */
95
+ setZ(f: SetterFunction): DPoint;
83
96
  /**
84
97
  * Set `y` value
85
98
  * @param y
package/dist/DPoint.js CHANGED
@@ -152,6 +152,10 @@ class DPoint {
152
152
  this.x = typeof x === 'number' ? x : x(this);
153
153
  return this;
154
154
  }
155
+ setZ(z) {
156
+ this.z = typeof z === 'number' ? z : z(this);
157
+ return this;
158
+ }
155
159
  setY(y) {
156
160
  this.y = typeof y === 'number' ? y : y(this);
157
161
  return this;
@@ -11,6 +11,39 @@ export declare class DPolygon {
11
11
  holes: DPolygon[];
12
12
  private searchStore;
13
13
  constructor(pPoints?: DPoint[]);
14
+ /**
15
+ * Specifies a round line buffer end cap style.
16
+ */
17
+ static CAP_ROUND: number;
18
+ /**
19
+ * Specifies a flat line buffer end cap style.
20
+ */
21
+ static CAP_FLAT: number;
22
+ /**
23
+ * Specifies a square line buffer end cap style.
24
+ */
25
+ static CAP_SQUARE: number;
26
+ /**
27
+ * Transform array of triangles to Three.JS vertices
28
+ *
29
+ * ```
30
+ * const geometry = new THREE.BufferGeometry();
31
+ * // create a simple square shape. We duplicate the top left and bottom right
32
+ * // vertices because each vertex needs to appear once per triangle.
33
+ * const vertices = new Float32Array( DPolygon.arrayOfTrianglesToVertices(triangles, 10) );
34
+ *
35
+ * // itemSize = 3 because there are 3 values (components) per vertex
36
+ * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
37
+ * const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
38
+ * mesh = new THREE.Mesh( geometry, material );
39
+ *
40
+ * scene.add( mesh );
41
+ * ```
42
+ *
43
+ * @param triangles
44
+ * @param [height=0]
45
+ */
46
+ static arrayOfTrianglesToVertices(triangles: DPolygon[], height?: number): number[];
14
47
  /**
15
48
  * Get size of min area rectangle.
16
49
  * @param poly should be `minAreaRectangle`
@@ -138,13 +171,19 @@ export declare class DPolygon {
138
171
  * @param newCenter
139
172
  */
140
173
  setCenter(newCenter: DPoint): DPolygon;
141
- toWKT(): string;
174
+ static WKT_LINESTRING: string;
175
+ static WKT_POLYGON: string;
176
+ /**
177
+ * @param [type = DPolygon.WKT_POLYGON] Available values `DPolygon.WKT_POLYGON`, `DPolygon.WKT_LINESTRING`
178
+ */
179
+ toWKT(type?: string): string;
142
180
  /**
143
181
  * Filter points
144
182
  * @param f
145
183
  */
146
184
  filter(f: (p: DPoint) => boolean): DPolygon;
147
- map(f: (r: DPoint, index?: number) => DPoint): DPolygon;
185
+ map(f: (r: DPoint) => DPoint): DPolygon;
186
+ map(f: (r: DPoint, index: number) => DPoint): DPolygon;
148
187
  at(index: number): DPoint;
149
188
  pop(): DPoint;
150
189
  push(...args: DPoint[]): number;
@@ -260,6 +299,17 @@ export declare class DPolygon {
260
299
  * ![Example](https://edejin.github.io/DGeoUtils/media/examples/toTriangles.png)
261
300
  */
262
301
  toTriangles(): DPolygon[];
302
+ /**
303
+ * Divide polygon to triangles and return points indexes
304
+ */
305
+ getTrianglesPointIndexes(): number[];
306
+ get closed(): boolean;
307
+ /**
308
+ * @param v
309
+ * @param [quadrantSegments=64]
310
+ * @param [type=DPolygon.CAP_ROUND] DPolygon.CAP_ROUND || DPolygon.CAP_FLAT || DPolygon.CAP_SQUARE
311
+ */
312
+ buffer(v: number, quadrantSegments?: number, type?: number): DPolygon;
263
313
  private simpleIncludeX;
264
314
  private simpleIncludeY;
265
315
  private douglasPeucker;
package/dist/DPolygon.js CHANGED
@@ -8,6 +8,7 @@ const DCircle_1 = require("./DCircle");
8
8
  const DNumbers_1 = require("./DNumbers");
9
9
  const jsts_1 = require("jsts");
10
10
  const DPolygonLoop_1 = require("./DPolygonLoop");
11
+ const { buffer: { BufferParameters: { CAP_ROUND, CAP_FLAT, CAP_SQUARE } } } = jsts_1.operation;
11
12
  exports.MIN_POINTS_IN_VALID_POLYGON = 3;
12
13
  const APPROXIMATION_VALUE = 0.1;
13
14
  const MAX_CONVEX_ITERATIONS = 100;
@@ -21,6 +22,34 @@ class DPolygon {
21
22
  this.holes = [];
22
23
  this.searchStore = {};
23
24
  }
25
+ /**
26
+ * Transform array of triangles to Three.JS vertices
27
+ *
28
+ * ```
29
+ * const geometry = new THREE.BufferGeometry();
30
+ * // create a simple square shape. We duplicate the top left and bottom right
31
+ * // vertices because each vertex needs to appear once per triangle.
32
+ * const vertices = new Float32Array( DPolygon.arrayOfTrianglesToVertices(triangles, 10) );
33
+ *
34
+ * // itemSize = 3 because there are 3 values (components) per vertex
35
+ * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
36
+ * const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
37
+ * mesh = new THREE.Mesh( geometry, material );
38
+ *
39
+ * scene.add( mesh );
40
+ * ```
41
+ *
42
+ * @param triangles
43
+ * @param [height=0]
44
+ */
45
+ static arrayOfTrianglesToVertices(triangles, height = 0) {
46
+ return triangles.map((v) => v
47
+ .loop()
48
+ .height(height)
49
+ .run()
50
+ .toArrayOfCoords())
51
+ .flat(2);
52
+ }
24
53
  /**
25
54
  * Get size of min area rectangle.
26
55
  * @param poly should be `minAreaRectangle`
@@ -410,12 +439,21 @@ class DPolygon {
410
439
  .move(newCenter.clone().move(this.center.minus()))
411
440
  .run();
412
441
  }
413
- toWKT() {
414
- let h = '';
415
- if (this.holes && this.holes.length) {
416
- h = `, ${this.holes.map((hole) => hole.toString()).join(', ')}`;
442
+ /**
443
+ * @param [type = DPolygon.WKT_POLYGON] Available values `DPolygon.WKT_POLYGON`, `DPolygon.WKT_LINESTRING`
444
+ */
445
+ toWKT(type = DPolygon.WKT_POLYGON) {
446
+ if (type === DPolygon.WKT_POLYGON) {
447
+ let h = '';
448
+ if (this.holes && this.holes.length) {
449
+ h = `, ${this.holes.map((hole) => hole.toString())
450
+ .join(', ')}`;
451
+ }
452
+ return `POLYGON ((${this.deintersection.pPoints.map((r) => `${r.x} ${r.y}`)
453
+ .join(', ')})${h})`;
417
454
  }
418
- return `POLYGON ((${this.deintersection.pPoints.map((r) => `${r.x} ${r.y}`).join(', ')})${h})`;
455
+ return `LINESTRING (${this.pPoints.map((r) => `${r.x} ${r.y}`)
456
+ .join(', ')})`;
419
457
  }
420
458
  /**
421
459
  * Filter points
@@ -463,7 +501,7 @@ class DPolygon {
463
501
  */
464
502
  close() {
465
503
  const p0 = this.first;
466
- if (p0 && !p0.equal(this.last)) {
504
+ if (p0 && !this.closed) {
467
505
  this.push(p0.clone());
468
506
  }
469
507
  return this;
@@ -473,7 +511,7 @@ class DPolygon {
473
511
  */
474
512
  open() {
475
513
  const p = this.first;
476
- if (this.length > 2 && p && p.equal(this.last)) {
514
+ if (this.length > 2 && p && this.closed) {
477
515
  this.pop();
478
516
  }
479
517
  return this;
@@ -789,10 +827,9 @@ class DPolygon {
789
827
  return this.simpleLogicFunction(p, true, false);
790
828
  }
791
829
  smartUnion(p) {
792
- var _a;
793
830
  const res = this.clone().simpleUnion(p);
794
831
  if (res) {
795
- let allHoles = [...this.holes, ...p.holes, ...((_a = res.holes) !== null && _a !== void 0 ? _a : [])].map((h) => h.clone());
832
+ let allHoles = [...this.holes, ...p.holes, ...res.holes].map((h) => h.clone());
796
833
  for (const a of allHoles) {
797
834
  for (const b of allHoles) {
798
835
  if (a.equal(b)) {
@@ -801,12 +838,7 @@ class DPolygon {
801
838
  const r = a.simpleUnion(b);
802
839
  if (r) {
803
840
  allHoles = allHoles.filter((v) => !v.equal(a) && !v.equal(b));
804
- if (Array.isArray(r)) {
805
- allHoles = [...allHoles, ...r];
806
- }
807
- else {
808
- allHoles.push(r);
809
- }
841
+ allHoles.push(r);
810
842
  }
811
843
  }
812
844
  }
@@ -872,6 +904,89 @@ class DPolygon {
872
904
  res.push(p);
873
905
  return res;
874
906
  }
907
+ /**
908
+ * Divide polygon to triangles and return points indexes
909
+ */
910
+ getTrianglesPointIndexes() {
911
+ const innerAndNotIntersect = (poly, p1, p2) => {
912
+ const l = p1.findLine(p2);
913
+ const { center } = l;
914
+ const intersections = poly.holes.reduce((a, hole) => a && Boolean(hole.clone().close()
915
+ .intersection(l, true).length), Boolean(poly.clone().close()
916
+ .intersection(l, true).length));
917
+ const contain = poly.holes.reduce((a, hole) => a && !hole
918
+ .contain(center), poly.contain(center));
919
+ return !intersections && contain;
920
+ };
921
+ const getTriangle = (poly) => {
922
+ for (let i = 0; i < poly.length; i++) {
923
+ const p0 = poly.at(0);
924
+ const p1 = poly.at(1);
925
+ const p2 = poly.at(2);
926
+ if (innerAndNotIntersect(poly, p0, p2)) {
927
+ poly.removePart(0, 1);
928
+ return [
929
+ p0.properties.index,
930
+ p1.properties.index,
931
+ p2.properties.index
932
+ ];
933
+ }
934
+ poly.push(poly.shift());
935
+ }
936
+ return undefined;
937
+ };
938
+ let p = this.clone();
939
+ let index = 0;
940
+ p.points.forEach((f) => {
941
+ f.properties.index = index++;
942
+ });
943
+ p.holes.forEach((h) => {
944
+ h.pPoints.forEach((f) => {
945
+ f.properties.index = index++;
946
+ });
947
+ });
948
+ p = p.clockWise.open();
949
+ while (p.holes.length) {
950
+ const h = p.holes.shift()
951
+ .clone()
952
+ .clockWise
953
+ .reverse()
954
+ .close();
955
+ for (let i = 0; i < p.length; i++) {
956
+ if (innerAndNotIntersect(p, p.first, h.first)) {
957
+ p.insertAfter(0, ...h.points, p.first);
958
+ break;
959
+ }
960
+ p.push(p.shift());
961
+ }
962
+ }
963
+ const res = [];
964
+ while (p.length > 3) {
965
+ const triangle = getTriangle(p);
966
+ if (triangle) {
967
+ res.push(...triangle);
968
+ }
969
+ }
970
+ res.push(...p.points.map((f) => f.properties.index));
971
+ return res;
972
+ }
973
+ get closed() {
974
+ return this.first.equal(this.last);
975
+ }
976
+ /**
977
+ * @param v
978
+ * @param [quadrantSegments=64]
979
+ * @param [type=DPolygon.CAP_ROUND] DPolygon.CAP_ROUND || DPolygon.CAP_FLAT || DPolygon.CAP_SQUARE
980
+ */
981
+ buffer(v, quadrantSegments = 64, type = DPolygon.CAP_ROUND) {
982
+ const reader = new jsts_1.io.WKTReader();
983
+ const { noHoles, closed } = this;
984
+ const points = reader
985
+ .read(noHoles.toWKT(closed ? DPolygon.WKT_POLYGON : DPolygon.WKT_LINESTRING))
986
+ .buffer(v, quadrantSegments, type)
987
+ .getCoordinates();
988
+ return new DPolygon(points.map(({ x, y }) => new DPoint_1.DPoint(x, y)));
989
+ }
875
990
  simpleIncludeX(p) {
876
991
  const { x } = p;
877
992
  return this.minX <= x && this.maxX >= x;
@@ -1033,3 +1148,17 @@ class DPolygon {
1033
1148
  }
1034
1149
  }
1035
1150
  exports.DPolygon = DPolygon;
1151
+ /**
1152
+ * Specifies a round line buffer end cap style.
1153
+ */
1154
+ DPolygon.CAP_ROUND = CAP_ROUND;
1155
+ /**
1156
+ * Specifies a flat line buffer end cap style.
1157
+ */
1158
+ DPolygon.CAP_FLAT = CAP_FLAT;
1159
+ /**
1160
+ * Specifies a square line buffer end cap style.
1161
+ */
1162
+ DPolygon.CAP_SQUARE = CAP_SQUARE;
1163
+ DPolygon.WKT_LINESTRING = 'LINESTRING';
1164
+ DPolygon.WKT_POLYGON = 'POLYGON';
@@ -39,6 +39,16 @@ export declare class DPolygonLoop {
39
39
  * @param f
40
40
  */
41
41
  setY(f: SetterFunction): DPolygonLoop;
42
+ /**
43
+ * Set `z` value
44
+ * @param z
45
+ */
46
+ setZ(z: number): DPolygonLoop;
47
+ /**
48
+ * Transform `z` value by function
49
+ * @param f
50
+ */
51
+ setZ(f: SetterFunction): DPolygonLoop;
42
52
  rotate(a: number): DPolygonLoop;
43
53
  /**
44
54
  * Add `v` to `x` and `y`
@@ -8,33 +8,35 @@ var LoopFunctions;
8
8
  LoopFunctions[LoopFunctions["height"] = 2] = "height";
9
9
  LoopFunctions[LoopFunctions["setX"] = 3] = "setX";
10
10
  LoopFunctions[LoopFunctions["setY"] = 4] = "setY";
11
- LoopFunctions[LoopFunctions["rotate"] = 5] = "rotate";
12
- LoopFunctions[LoopFunctions["move"] = 6] = "move";
13
- LoopFunctions[LoopFunctions["round"] = 7] = "round";
14
- LoopFunctions[LoopFunctions["ceil"] = 8] = "ceil";
15
- LoopFunctions[LoopFunctions["floor"] = 9] = "floor";
16
- LoopFunctions[LoopFunctions["toFixed"] = 10] = "toFixed";
17
- LoopFunctions[LoopFunctions["abs"] = 11] = "abs";
18
- LoopFunctions[LoopFunctions["scale"] = 12] = "scale";
19
- LoopFunctions[LoopFunctions["divide"] = 13] = "divide";
20
- LoopFunctions[LoopFunctions["degreeToRadians"] = 14] = "degreeToRadians";
21
- LoopFunctions[LoopFunctions["radiansToDegrees"] = 15] = "radiansToDegrees";
22
- LoopFunctions[LoopFunctions["radiansToMeters"] = 16] = "radiansToMeters";
23
- LoopFunctions[LoopFunctions["metersToRadians"] = 17] = "metersToRadians";
24
- LoopFunctions[LoopFunctions["hipPoint"] = 18] = "hipPoint";
25
- LoopFunctions[LoopFunctions["xPoint"] = 19] = "xPoint";
26
- LoopFunctions[LoopFunctions["yPoint"] = 20] = "yPoint";
27
- LoopFunctions[LoopFunctions["wPoint"] = 21] = "wPoint";
28
- LoopFunctions[LoopFunctions["hPoint"] = 22] = "hPoint";
29
- LoopFunctions[LoopFunctions["setIfLessThan"] = 23] = "setIfLessThan";
30
- LoopFunctions[LoopFunctions["minus"] = 24] = "minus";
31
- LoopFunctions[LoopFunctions["degreeToMeters"] = 25] = "degreeToMeters";
32
- LoopFunctions[LoopFunctions["metersToDegree"] = 26] = "metersToDegree";
33
- LoopFunctions[LoopFunctions["flipVertically"] = 27] = "flipVertically";
11
+ LoopFunctions[LoopFunctions["setZ"] = 5] = "setZ";
12
+ LoopFunctions[LoopFunctions["rotate"] = 6] = "rotate";
13
+ LoopFunctions[LoopFunctions["move"] = 7] = "move";
14
+ LoopFunctions[LoopFunctions["round"] = 8] = "round";
15
+ LoopFunctions[LoopFunctions["ceil"] = 9] = "ceil";
16
+ LoopFunctions[LoopFunctions["floor"] = 10] = "floor";
17
+ LoopFunctions[LoopFunctions["toFixed"] = 11] = "toFixed";
18
+ LoopFunctions[LoopFunctions["abs"] = 12] = "abs";
19
+ LoopFunctions[LoopFunctions["scale"] = 13] = "scale";
20
+ LoopFunctions[LoopFunctions["divide"] = 14] = "divide";
21
+ LoopFunctions[LoopFunctions["degreeToRadians"] = 15] = "degreeToRadians";
22
+ LoopFunctions[LoopFunctions["radiansToDegrees"] = 16] = "radiansToDegrees";
23
+ LoopFunctions[LoopFunctions["radiansToMeters"] = 17] = "radiansToMeters";
24
+ LoopFunctions[LoopFunctions["metersToRadians"] = 18] = "metersToRadians";
25
+ LoopFunctions[LoopFunctions["hipPoint"] = 19] = "hipPoint";
26
+ LoopFunctions[LoopFunctions["xPoint"] = 20] = "xPoint";
27
+ LoopFunctions[LoopFunctions["yPoint"] = 21] = "yPoint";
28
+ LoopFunctions[LoopFunctions["wPoint"] = 22] = "wPoint";
29
+ LoopFunctions[LoopFunctions["hPoint"] = 23] = "hPoint";
30
+ LoopFunctions[LoopFunctions["setIfLessThan"] = 24] = "setIfLessThan";
31
+ LoopFunctions[LoopFunctions["minus"] = 25] = "minus";
32
+ LoopFunctions[LoopFunctions["degreeToMeters"] = 26] = "degreeToMeters";
33
+ LoopFunctions[LoopFunctions["metersToDegree"] = 27] = "metersToDegree";
34
+ LoopFunctions[LoopFunctions["flipVertically"] = 28] = "flipVertically";
34
35
  })(LoopFunctions || (LoopFunctions = {}));
35
36
  // eslint-disable-next-line complexity
36
37
  const decodePoolRecord = (a, { functionName, pointArg, numberPointArg, numberArg, setterArg }) => {
37
38
  let res = a;
39
+ // eslint-disable-next-line default-case
38
40
  switch (functionName) {
39
41
  case LoopFunctions.getTileFromCoords:
40
42
  res = (k) => a(k)
@@ -56,6 +58,10 @@ const decodePoolRecord = (a, { functionName, pointArg, numberPointArg, numberArg
56
58
  res = (k) => a(k)
57
59
  .setY(setterArg);
58
60
  break;
61
+ case LoopFunctions.setZ:
62
+ res = (k) => a(k)
63
+ .setZ(setterArg);
64
+ break;
59
65
  case LoopFunctions.rotate:
60
66
  res = (k) => a(k)
61
67
  .rotate(numberArg);
@@ -148,11 +154,11 @@ const decodePoolRecord = (a, { functionName, pointArg, numberPointArg, numberArg
148
154
  res = (k) => a(k)
149
155
  .flipVertically(numberPointArg);
150
156
  break;
151
- default:
152
157
  }
153
158
  return res;
154
159
  };
155
160
  class DPolygonLoop {
161
+ // eslint-disable-next-line no-empty-function,no-useless-constructor
156
162
  constructor(parent) {
157
163
  this.parent = parent;
158
164
  this.pool = [];
@@ -207,6 +213,13 @@ class DPolygonLoop {
207
213
  });
208
214
  return this;
209
215
  }
216
+ setZ(z) {
217
+ this.pool.push({
218
+ functionName: LoopFunctions.setZ,
219
+ setterArg: z
220
+ });
221
+ return this;
222
+ }
210
223
  rotate(a) {
211
224
  this.pool.push({
212
225
  functionName: LoopFunctions.rotate,
@@ -6,8 +6,8 @@ export declare enum TraceMatrixValues {
6
6
  }
7
7
  declare type SimpleMatrix = TraceMatrixValues[][];
8
8
  export declare class TraceMatrix {
9
- private readonly m;
10
9
  private readonly size;
10
+ private readonly m;
11
11
  constructor(size: DPoint, f: (p: DPoint) => TraceMatrixValues);
12
12
  fullMatrixTrace(): DPolygon[];
13
13
  private reverseMatrix;
@@ -25,6 +25,7 @@ const setByPosition = (m, p, value) => {
25
25
  };
26
26
  class TraceMatrix {
27
27
  constructor(size, f) {
28
+ this.size = size;
28
29
  this.findGroupByIndex = (m, s) => {
29
30
  const res = new DPolygon_1.DPolygon();
30
31
  if (s && getByPosition(m, s) === TraceMatrixValues.t) {
@@ -146,7 +147,6 @@ class TraceMatrix {
146
147
  const t = this.reverseMatrix(tmpMatrix);
147
148
  return this.totalCountInMatrix(t) ? t : null;
148
149
  };
149
- this.size = size;
150
150
  this.m = TraceMatrix.createMatrix(this.size, f);
151
151
  }
152
152
  fullMatrixTrace() {
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export * from './DPoint';
5
5
  export * from './DPolygon';
6
6
  export * from './FastSearch';
7
7
  export * from './TraceMatrix';
8
+ export * from './DPolygonLoop';
8
9
  export declare const DGeo: {
9
10
  DEBUG: boolean;
10
11
  };
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ __exportStar(require("./DPoint"), exports);
18
18
  __exportStar(require("./DPolygon"), exports);
19
19
  __exportStar(require("./FastSearch"), exports);
20
20
  __exportStar(require("./TraceMatrix"), exports);
21
+ __exportStar(require("./DPolygonLoop"), exports);
21
22
  exports.DGeo = {
22
23
  DEBUG: false
23
24
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dgeoutils",
3
- "version": "2.2.3",
3
+ "version": "2.2.7",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "build": "node_modules/.bin/tsc",
@@ -56,4 +56,4 @@
56
56
  "type": "git",
57
57
  "url": "https://github.com/edejin/DGeoUtils"
58
58
  }
59
- }
59
+ }