@dra2020/baseclient 1.0.48 → 1.0.49

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.
@@ -21,16 +21,66 @@ export function polyDistance(poly: any, x: number, y: number): number
21
21
  let pp = P.polyNormalize(poly);
22
22
  if (pp == null) return 0;
23
23
 
24
- let forEachPointPair = (iter: any) => {
25
- PP.polyPackEachRing(pp, (b: Float64Array, iPoly, iRing: number, iOffset: number, nPoints: number) => {
26
- let iFirst = iOffset;
27
- let iLast = iOffset + nPoints * 2;
28
- let iSecond = iLast - 2;
29
- for (; iFirst < iLast; iSecond = iFirst, iFirst += 2)
30
- iter(iPoly, iRing, b[iFirst], b[iFirst+1], b[iSecond], b[iSecond+1]);
31
- });
32
- };
33
- return pointToPolygonDist(x, y, forEachPointPair);
24
+ // First find if it is contained in one of the outer polygons, or outside all outer polygons
25
+ let iContaining = -1;
26
+ let maxOutside = - Infinity;
27
+ let minInside = Infinity;
28
+ let noholes = true;
29
+ PP.polyPackEachRing(pp, (b: Float64Array, iPoly: number, iRing: number, iOffset: number, nPoints: number) => {
30
+ // If we have determined we are inside this polygon, keep track of whether it has holes
31
+ if (iContaining == iPoly && iRing > 0)
32
+ noholes = false;
33
+ // Don't process rings
34
+ if (iRing > 0) return;
35
+ // OK, get distance
36
+ let forEachPointPair = (iter: any) => {
37
+ PP.polyPackEachRing(pp, (b: Float64Array, iInteriorPoly: number, iRing: number, iOffset: number, nPoints: number) => {
38
+ if (iRing || iInteriorPoly != iPoly) return;
39
+ let iFirst = iOffset;
40
+ let iLast = iOffset + nPoints * 2;
41
+ let iSecond = iLast - 2;
42
+ for (; iFirst < iLast; iSecond = iFirst, iFirst += 2)
43
+ iter(b[iFirst], b[iFirst+1], b[iSecond], b[iSecond+1]);
44
+ });
45
+ };
46
+ let dist = pointToPolygonDist(x, y, forEachPointPair);
47
+ // If inside, is it closest inside (deal with multipolygons that self-contain - think filled donut)
48
+ if (dist > 0 && dist < minInside)
49
+ {
50
+ iContaining = iPoly;
51
+ minInside = dist;
52
+ noholes = true;
53
+ }
54
+ else if (dist < 0)
55
+ maxOutside = Math.max(maxOutside, dist);
56
+ });
57
+ if (iContaining < 0)
58
+ return maxOutside;
59
+ if (noholes)
60
+ return minInside;
61
+
62
+ // OK, now need to worry about holes in the polygon it is contained in
63
+ PP.polyPackEachRing(pp, (b: Float64Array, iPoly: number, iRing: number, iOffset: number, nPoints: number) => {
64
+ // Only want to look at the holes for the containing polygon
65
+ if (iPoly != iContaining || iRing == 0) return;
66
+ // Compute distance to those holes
67
+ let forEachPointPair = (iter: any) => {
68
+ PP.polyPackEachRing(pp, (b: Float64Array, iInteriorPoly: number, iRing: number, iOffset: number, nPoints: number) => {
69
+ if (iInteriorPoly != iContaining || iRing == 0) return;
70
+ let iFirst = iOffset;
71
+ let iLast = iOffset + nPoints * 2;
72
+ let iSecond = iLast - 2;
73
+ for (; iFirst < iLast; iSecond = iFirst, iFirst += 2)
74
+ iter(b[iFirst], b[iFirst+1], b[iSecond], b[iSecond+1]);
75
+ });
76
+ };
77
+ // Negate distance since dealing with holes
78
+ let dist = - pointToPolygonDist(x, y, forEachPointPair);
79
+ // We take the min to either get a negative value (inside hole) or a smaller positive value
80
+ // (outside hole but close to hole boundary).
81
+ minInside = Math.min(minInside, dist);
82
+ });
83
+ return minInside;
34
84
  }
35
85
 
36
86
  //
@@ -69,7 +119,7 @@ export function polyLabel(poly: any, precision?: number, debug?: boolean): PolyL
69
119
  let iLast = iOffset + nPoints * 2;
70
120
  let iSecond = iLast - 2;
71
121
  for (; iFirst < iLast; iSecond = iFirst, iFirst += 2)
72
- iter(iPoly, iRing, b[iFirst], b[iFirst+1], b[iSecond], b[iSecond+1]);
122
+ iter(b[iFirst], b[iFirst+1], b[iSecond], b[iSecond+1]);
73
123
  });
74
124
  };
75
125
 
@@ -164,38 +214,15 @@ class Cell
164
214
  // signed distance from point to polygon outline (negative if point is outside)
165
215
  function pointToPolygonDist(x: number, y: number, forEachPointPair: any): number
166
216
  {
167
- let iPolyLast = -1;
168
- let iRingLast = -1;
169
217
  let inside = false;
170
- let thisInside = false;
171
- let useInside = false;
172
- let isHole = false;
173
- let minDistSq: number = Infinity;
218
+ let minDistSq = Infinity;
174
219
 
175
- forEachPointPair((iPoly: number, iRing: number, ax: number, ay: number, bx: number, by: number) => {
176
- if (iPoly != iPolyLast || iRing != iRingLast)
177
- {
178
- if (useInside)
179
- inside = isHole ? ! thisInside : thisInside;
180
- iPolyLast = iPoly;
181
- iRingLast = iRing;
182
- thisInside = false;
183
- useInside = false;
184
- isHole = false;
185
- }
220
+ forEachPointPair((ax: number, ay: number, bx: number, by: number) => {
186
221
  if ((ay > y !== by > y) && (x < (bx - ax) * (y - ay) / (by - ay) + ax))
187
- thisInside = !thisInside;
222
+ inside = !inside;
188
223
 
189
- let thisDistSq = getSegDistSq(x, y, ax, ay, bx, by);
190
- if (thisDistSq < minDistSq)
191
- {
192
- minDistSq = thisDistSq;
193
- useInside = true;
194
- isHole = iRing != 0;
195
- }
224
+ minDistSq = Math.min(minDistSq, getSegDistSq(x, y, ax, ay, bx, by));
196
225
  });
197
- if (useInside)
198
- inside = isHole ? ! thisInside : thisInside;
199
226
 
200
227
  return (inside ? 1 : -1) * Math.sqrt(minDistSq);
201
228
  }
@@ -209,7 +236,7 @@ function getCentroidCell(forEachPointPair: any): Cell
209
236
  let fx: number;
210
237
  let fy: number;
211
238
 
212
- forEachPointPair((iPoly: number, iRing: number, ax: number, ay: number, bx: number, by: number) => {
239
+ forEachPointPair((ax: number, ay: number, bx: number, by: number) => {
213
240
  if (fx === undefined) fx = ax, fy = ay;
214
241
  let f: number = ax * by - bx * ay;
215
242
  x += (ax + bx) * f;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dra2020/baseclient",
3
- "version": "1.0.48",
3
+ "version": "1.0.49",
4
4
  "description": "Utility functions for Javascript projects.",
5
5
  "main": "dist/baseclient.js",
6
6
  "types": "./dist/all/all.d.ts",