@turf/isobands 7.2.0 → 7.3.1
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/README.md +1 -1
- package/dist/cjs/index.cjs +313 -9
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +313 -9
- package/dist/esm/index.js.map +1 -1
- package/package.json +23 -24
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ value breaks and generates filled contour isobands.
|
|
|
9
9
|
|
|
10
10
|
### Parameters
|
|
11
11
|
|
|
12
|
-
* `pointGrid` **[FeatureCollection][1]<[Point][2]>** input points - must be square or rectangular
|
|
12
|
+
* `pointGrid` **[FeatureCollection][1]<[Point][2]>** input points - must be square or rectangular and already gridded. That is, to have consistent x and y dimensions and be at least 2x2 in size.
|
|
13
13
|
* `breaks` **[Array][3]<[number][4]>** where to draw contours
|
|
14
14
|
* `options` **[Object][5]** options on output (optional, default `{}`)
|
|
15
15
|
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -76,7 +76,6 @@ function sortPointsByLatLng(points, flip) {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
// index.ts
|
|
79
|
-
var _marchingsquares = require('marchingsquares');
|
|
80
79
|
function isobands(pointGrid, breaks, options) {
|
|
81
80
|
options = options || {};
|
|
82
81
|
if (!_helpers.isObject.call(void 0, options)) throw new Error("options is invalid");
|
|
@@ -91,6 +90,15 @@ function isobands(pointGrid, breaks, options) {
|
|
|
91
90
|
if (!Array.isArray(breaksProperties))
|
|
92
91
|
throw new Error("breaksProperties is not an Array");
|
|
93
92
|
const matrix = gridToMatrix(pointGrid, { zProperty, flip: true });
|
|
93
|
+
const dx = matrix[0].length;
|
|
94
|
+
if (matrix.length < 2 || dx < 2) {
|
|
95
|
+
throw new Error("Matrix of points must be at least 2x2");
|
|
96
|
+
}
|
|
97
|
+
for (let i = 1; i < matrix.length; i++) {
|
|
98
|
+
if (matrix[i].length !== dx) {
|
|
99
|
+
throw new Error("Matrix of points is not uniform in the x dimension");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
94
102
|
let contours = createContourLines(matrix, breaks, zProperty);
|
|
95
103
|
contours = rescaleContours(contours, matrix, pointGrid);
|
|
96
104
|
const multipolygons = contours.map((contour, index) => {
|
|
@@ -109,19 +117,299 @@ function isobands(pointGrid, breaks, options) {
|
|
|
109
117
|
}
|
|
110
118
|
function createContourLines(matrix, breaks, property) {
|
|
111
119
|
const contours = [];
|
|
120
|
+
let prevSegments;
|
|
112
121
|
for (let i = 1; i < breaks.length; i++) {
|
|
113
|
-
|
|
122
|
+
if (i === 1) {
|
|
123
|
+
prevSegments = getSegments(matrix, +breaks[0]);
|
|
124
|
+
}
|
|
114
125
|
const upperBand = +breaks[i];
|
|
115
|
-
const
|
|
116
|
-
const
|
|
117
|
-
const
|
|
126
|
+
const lowerBand = +breaks[i - 1];
|
|
127
|
+
const segments = getSegments(matrix, upperBand);
|
|
128
|
+
const reverseSegments = segments.map(
|
|
129
|
+
(segment) => (
|
|
130
|
+
// note that we (in-place) reverse the array result of .map and not the original segment itself.
|
|
131
|
+
segment.map((pos) => [pos[0], pos[1]]).reverse()
|
|
132
|
+
)
|
|
133
|
+
);
|
|
134
|
+
const rings = assembleRings(prevSegments.concat(reverseSegments), matrix);
|
|
135
|
+
const orderedRings = orderByArea(rings);
|
|
136
|
+
const polygons = groupNestedRings(orderedRings);
|
|
137
|
+
if (polygons.length === 0 && matrix[0][0] < upperBand && matrix[0][0] >= lowerBand) {
|
|
138
|
+
const dx = matrix[0].length;
|
|
139
|
+
const dy = matrix.length;
|
|
140
|
+
polygons.push([
|
|
141
|
+
[
|
|
142
|
+
[0, 0],
|
|
143
|
+
[dx - 1, 0],
|
|
144
|
+
[dx - 1, dy - 1],
|
|
145
|
+
[0, dy - 1],
|
|
146
|
+
[0, 0]
|
|
147
|
+
]
|
|
148
|
+
]);
|
|
149
|
+
}
|
|
118
150
|
contours.push({
|
|
119
|
-
groupedRings,
|
|
151
|
+
groupedRings: polygons,
|
|
120
152
|
[property]: lowerBand + "-" + upperBand
|
|
121
153
|
});
|
|
154
|
+
prevSegments = segments;
|
|
122
155
|
}
|
|
123
156
|
return contours;
|
|
124
157
|
}
|
|
158
|
+
function getSegments(matrix, threshold) {
|
|
159
|
+
const segments = [];
|
|
160
|
+
const dx = matrix[0].length;
|
|
161
|
+
const dy = matrix.length;
|
|
162
|
+
for (let y = 0; y < dy - 1; y++) {
|
|
163
|
+
for (let x = 0; x < dx - 1; x++) {
|
|
164
|
+
const tr = matrix[y + 1][x + 1];
|
|
165
|
+
const br = matrix[y][x + 1];
|
|
166
|
+
const bl = matrix[y][x];
|
|
167
|
+
const tl = matrix[y + 1][x];
|
|
168
|
+
let grid = (tl >= threshold ? 8 : 0) | (tr >= threshold ? 4 : 0) | (br >= threshold ? 2 : 0) | (bl >= threshold ? 1 : 0);
|
|
169
|
+
switch (grid) {
|
|
170
|
+
case 0:
|
|
171
|
+
continue;
|
|
172
|
+
case 1:
|
|
173
|
+
segments.push([
|
|
174
|
+
[x + frac(bl, br), y],
|
|
175
|
+
[x, y + frac(bl, tl)]
|
|
176
|
+
]);
|
|
177
|
+
break;
|
|
178
|
+
case 2:
|
|
179
|
+
segments.push([
|
|
180
|
+
[x + 1, y + frac(br, tr)],
|
|
181
|
+
[x + frac(bl, br), y]
|
|
182
|
+
]);
|
|
183
|
+
break;
|
|
184
|
+
case 3:
|
|
185
|
+
segments.push([
|
|
186
|
+
[x + 1, y + frac(br, tr)],
|
|
187
|
+
[x, y + frac(bl, tl)]
|
|
188
|
+
]);
|
|
189
|
+
break;
|
|
190
|
+
case 4:
|
|
191
|
+
segments.push([
|
|
192
|
+
[x + frac(tl, tr), y + 1],
|
|
193
|
+
[x + 1, y + frac(br, tr)]
|
|
194
|
+
]);
|
|
195
|
+
break;
|
|
196
|
+
case 5: {
|
|
197
|
+
const avg = (tl + tr + br + bl) / 4;
|
|
198
|
+
const above = avg >= threshold;
|
|
199
|
+
if (above) {
|
|
200
|
+
segments.push(
|
|
201
|
+
[
|
|
202
|
+
[x + frac(tl, tr), y + 1],
|
|
203
|
+
[x, y + frac(bl, tl)]
|
|
204
|
+
],
|
|
205
|
+
[
|
|
206
|
+
[x + frac(bl, br), y],
|
|
207
|
+
[x + 1, y + frac(br, tr)]
|
|
208
|
+
]
|
|
209
|
+
);
|
|
210
|
+
} else {
|
|
211
|
+
segments.push(
|
|
212
|
+
[
|
|
213
|
+
[x + frac(tl, tr), y + 1],
|
|
214
|
+
[x + 1, y + frac(br, tr)]
|
|
215
|
+
],
|
|
216
|
+
[
|
|
217
|
+
[x + frac(bl, br), y],
|
|
218
|
+
[x, y + frac(bl, tl)]
|
|
219
|
+
]
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
case 6:
|
|
225
|
+
segments.push([
|
|
226
|
+
[x + frac(tl, tr), y + 1],
|
|
227
|
+
[x + frac(bl, br), y]
|
|
228
|
+
]);
|
|
229
|
+
break;
|
|
230
|
+
case 7:
|
|
231
|
+
segments.push([
|
|
232
|
+
[x + frac(tl, tr), y + 1],
|
|
233
|
+
[x, y + frac(bl, tl)]
|
|
234
|
+
]);
|
|
235
|
+
break;
|
|
236
|
+
case 8:
|
|
237
|
+
segments.push([
|
|
238
|
+
[x, y + frac(bl, tl)],
|
|
239
|
+
[x + frac(tl, tr), y + 1]
|
|
240
|
+
]);
|
|
241
|
+
break;
|
|
242
|
+
case 9:
|
|
243
|
+
segments.push([
|
|
244
|
+
[x + frac(bl, br), y],
|
|
245
|
+
[x + frac(tl, tr), y + 1]
|
|
246
|
+
]);
|
|
247
|
+
break;
|
|
248
|
+
case 10: {
|
|
249
|
+
const avg = (tl + tr + br + bl) / 4;
|
|
250
|
+
const above = avg >= threshold;
|
|
251
|
+
if (above) {
|
|
252
|
+
segments.push(
|
|
253
|
+
[
|
|
254
|
+
[x, y + frac(bl, tl)],
|
|
255
|
+
[x + frac(bl, br), y]
|
|
256
|
+
],
|
|
257
|
+
[
|
|
258
|
+
[x + 1, y + frac(br, tr)],
|
|
259
|
+
[x + frac(tl, tr), y + 1]
|
|
260
|
+
]
|
|
261
|
+
);
|
|
262
|
+
} else {
|
|
263
|
+
segments.push(
|
|
264
|
+
[
|
|
265
|
+
[x, y + frac(bl, tl)],
|
|
266
|
+
[x + frac(tl, tr), y + 1]
|
|
267
|
+
],
|
|
268
|
+
[
|
|
269
|
+
[x + 1, y + frac(br, tr)],
|
|
270
|
+
[x + frac(bl, br), y]
|
|
271
|
+
]
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
case 11:
|
|
277
|
+
segments.push([
|
|
278
|
+
[x + 1, y + frac(br, tr)],
|
|
279
|
+
[x + frac(tl, tr), y + 1]
|
|
280
|
+
]);
|
|
281
|
+
break;
|
|
282
|
+
case 12:
|
|
283
|
+
segments.push([
|
|
284
|
+
[x, y + frac(bl, tl)],
|
|
285
|
+
[x + 1, y + frac(br, tr)]
|
|
286
|
+
]);
|
|
287
|
+
break;
|
|
288
|
+
case 13:
|
|
289
|
+
segments.push([
|
|
290
|
+
[x + frac(bl, br), y],
|
|
291
|
+
[x + 1, y + frac(br, tr)]
|
|
292
|
+
]);
|
|
293
|
+
break;
|
|
294
|
+
case 14:
|
|
295
|
+
segments.push([
|
|
296
|
+
[x, y + frac(bl, tl)],
|
|
297
|
+
[x + frac(bl, br), y]
|
|
298
|
+
]);
|
|
299
|
+
break;
|
|
300
|
+
case 15:
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return segments;
|
|
306
|
+
function frac(z0, z1) {
|
|
307
|
+
if (z0 === z1) {
|
|
308
|
+
return 0.5;
|
|
309
|
+
}
|
|
310
|
+
let t = (threshold - z0) / (z1 - z0);
|
|
311
|
+
return t > 1 ? 1 : t < 0 ? 0 : t;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function assembleRings(segments, matrix) {
|
|
315
|
+
const dy = matrix.length;
|
|
316
|
+
const dx = matrix[0].length;
|
|
317
|
+
const contours = [];
|
|
318
|
+
const result = [];
|
|
319
|
+
while (segments.length > 0) {
|
|
320
|
+
const contour = [...segments.shift()];
|
|
321
|
+
contours.push(contour);
|
|
322
|
+
let found;
|
|
323
|
+
do {
|
|
324
|
+
found = false;
|
|
325
|
+
for (let i = 0; i < segments.length; i++) {
|
|
326
|
+
const segment = segments[i];
|
|
327
|
+
if (segment[0][0] === contour[contour.length - 1][0] && segment[0][1] === contour[contour.length - 1][1]) {
|
|
328
|
+
found = true;
|
|
329
|
+
contour.push(segment[1]);
|
|
330
|
+
segments.splice(i, 1);
|
|
331
|
+
break;
|
|
332
|
+
}
|
|
333
|
+
if (segment[1][0] === contour[0][0] && segment[1][1] === contour[0][1]) {
|
|
334
|
+
found = true;
|
|
335
|
+
contour.unshift(segment[0]);
|
|
336
|
+
segments.splice(i, 1);
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
} while (found);
|
|
341
|
+
}
|
|
342
|
+
while (contours.length > 0) {
|
|
343
|
+
const contour = contours[0];
|
|
344
|
+
if (contour[0][0] === contour[contour.length - 1][0] && contour[0][1] === contour[contour.length - 1][1]) {
|
|
345
|
+
result.push(contour);
|
|
346
|
+
contours.shift();
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
const end = contour[contour.length - 1];
|
|
350
|
+
let match;
|
|
351
|
+
let corner;
|
|
352
|
+
if (end[0] === 0 && end[1] !== 0) {
|
|
353
|
+
match = getAdjacentContour(
|
|
354
|
+
contours,
|
|
355
|
+
(contour2) => contour2[0][0] === 0 && contour2[0][1] < end[1],
|
|
356
|
+
// left side, below end
|
|
357
|
+
(a, b) => b[0][1] - a[0][1]
|
|
358
|
+
// prefer positions to the top
|
|
359
|
+
);
|
|
360
|
+
corner = [0, 0];
|
|
361
|
+
} else if (end[1] === 0 && end[0] !== dx - 1) {
|
|
362
|
+
match = getAdjacentContour(
|
|
363
|
+
contours,
|
|
364
|
+
(contour2) => contour2[0][1] === 0 && contour2[0][0] > end[0],
|
|
365
|
+
// bottom side, right of end
|
|
366
|
+
(a, b) => a[0][0] - b[0][0]
|
|
367
|
+
// prefer positions to the left
|
|
368
|
+
);
|
|
369
|
+
corner = [dx - 1, 0];
|
|
370
|
+
} else if (end[0] === dx - 1 && end[1] !== dy - 1) {
|
|
371
|
+
match = getAdjacentContour(
|
|
372
|
+
contours,
|
|
373
|
+
(contour2) => contour2[0][0] === dx - 1 && contour2[0][1] > end[1],
|
|
374
|
+
// right side, above end
|
|
375
|
+
(a, b) => a[0][1] - b[0][1]
|
|
376
|
+
// prefer positions to the bottom
|
|
377
|
+
);
|
|
378
|
+
corner = [dx - 1, dy - 1];
|
|
379
|
+
} else if (end[1] === dy - 1 && end[0] !== 0) {
|
|
380
|
+
match = getAdjacentContour(
|
|
381
|
+
contours,
|
|
382
|
+
(contour2) => contour2[0][1] === dy - 1 && contour2[0][0] < end[0],
|
|
383
|
+
// top side, left of end
|
|
384
|
+
(a, b) => b[0][0] - a[0][0]
|
|
385
|
+
// prefer positions to the right
|
|
386
|
+
);
|
|
387
|
+
corner = [0, dy - 1];
|
|
388
|
+
} else {
|
|
389
|
+
throw new Error("Contour not closed but is not along an edge");
|
|
390
|
+
}
|
|
391
|
+
if (match === -1) {
|
|
392
|
+
contour.push(corner);
|
|
393
|
+
} else if (match === 0) {
|
|
394
|
+
contour.push([contour[0][0], contour[0][1]]);
|
|
395
|
+
result.push(contour);
|
|
396
|
+
contours.shift();
|
|
397
|
+
} else {
|
|
398
|
+
const matchedContour = contours[match];
|
|
399
|
+
contours.splice(match, 1);
|
|
400
|
+
for (const p of matchedContour) {
|
|
401
|
+
contour.push(p);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
for (let i = 0; i < result.length; i++) {
|
|
406
|
+
if (result[i].length < 4) {
|
|
407
|
+
result.splice(i, 1);
|
|
408
|
+
i--;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return result;
|
|
412
|
+
}
|
|
125
413
|
function rescaleContours(contours, matrix, points) {
|
|
126
414
|
const gridBbox = _bbox.bbox.call(void 0, points);
|
|
127
415
|
const originalWidth = gridBbox[2] - gridBbox[0];
|
|
@@ -169,10 +457,15 @@ function groupNestedRings(orderedLinearRings) {
|
|
|
169
457
|
group.push(lrList[i].lrCoordinates);
|
|
170
458
|
lrList[i].grouped = true;
|
|
171
459
|
const outerMostPoly = _helpers.polygon.call(void 0, [lrList[i].lrCoordinates]);
|
|
172
|
-
for (let j = i + 1; j < lrList.length; j++) {
|
|
460
|
+
OUTER: for (let j = i + 1; j < lrList.length; j++) {
|
|
173
461
|
if (!lrList[j].grouped) {
|
|
174
462
|
const lrPoly = _helpers.polygon.call(void 0, [lrList[j].lrCoordinates]);
|
|
175
463
|
if (isInside(lrPoly, outerMostPoly)) {
|
|
464
|
+
for (let k = 1; k < group.length; k++) {
|
|
465
|
+
if (isInside(lrPoly, _helpers.polygon.call(void 0, [group[k]]))) {
|
|
466
|
+
continue OUTER;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
176
469
|
group.push(lrList[j].lrCoordinates);
|
|
177
470
|
lrList[j].grouped = true;
|
|
178
471
|
}
|
|
@@ -201,9 +494,20 @@ function allGrouped(list) {
|
|
|
201
494
|
}
|
|
202
495
|
return true;
|
|
203
496
|
}
|
|
204
|
-
|
|
497
|
+
function getAdjacentContour(contours, test, sort) {
|
|
498
|
+
let match = -1;
|
|
499
|
+
for (let j = 0; j < contours.length; j++) {
|
|
500
|
+
if (test(contours[j])) {
|
|
501
|
+
if (match === -1 || sort(contours[match], contours[j]) > 0) {
|
|
502
|
+
match = j;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return match;
|
|
507
|
+
}
|
|
508
|
+
var index_default = isobands;
|
|
205
509
|
|
|
206
510
|
|
|
207
511
|
|
|
208
|
-
exports.default =
|
|
512
|
+
exports.default = index_default; exports.isobands = isobands;
|
|
209
513
|
//# sourceMappingURL=index.cjs.map
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/turf/turf/packages/turf-isobands/dist/cjs/index.cjs","../../index.ts","../../lib/grid-to-matrix.js"],"names":["isObject","collectionOf"],"mappings":"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","file":"/home/runner/work/turf/turf/packages/turf-isobands/dist/cjs/index.cjs","sourcesContent":[null,"import { bbox } from \"@turf/bbox\";\nimport { area } from \"@turf/area\";\nimport { booleanPointInPolygon } from \"@turf/boolean-point-in-polygon\";\nimport { explode } from \"@turf/explode\";\nimport { collectionOf } from \"@turf/invariant\";\nimport {\n polygon,\n multiPolygon,\n featureCollection,\n isObject,\n} from \"@turf/helpers\";\n\nimport {\n FeatureCollection,\n Point,\n GeoJsonProperties,\n MultiPolygon,\n Position,\n Polygon,\n Feature,\n} from \"geojson\";\n\nimport { gridToMatrix } from \"./lib/grid-to-matrix.js\";\nimport { isoBands } from \"marchingsquares\";\n\ntype GroupRingProps = { [prop: string]: string };\ntype GroupedRings =\n | {\n groupedRings: Position[][][];\n }\n | GroupRingProps;\n\n/**\n * Takes a square or rectangular grid {@link FeatureCollection} of {@link Point} features with z-values and an array of\n * value breaks and generates filled contour isobands.\n *\n * @function\n * @param {FeatureCollection<Point>} pointGrid input points - must be square or rectangular\n * @param {Array<number>} breaks where to draw contours\n * @param {Object} [options={}] options on output\n * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled\n * @param {Object} [options.commonProperties={}] GeoJSON properties passed to ALL isobands\n * @param {Array<Object>} [options.breaksProperties=[]] GeoJSON properties passed, in order, to the correspondent isoband (order defined by breaks)\n * @returns {FeatureCollection<MultiPolygon>} a FeatureCollection of {@link MultiPolygon} features representing isobands\n */\nfunction isobands(\n pointGrid: FeatureCollection<Point>,\n breaks: number[],\n options?: {\n zProperty?: string;\n commonProperties?: GeoJsonProperties;\n breaksProperties?: GeoJsonProperties[];\n }\n): FeatureCollection<MultiPolygon> {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error(\"options is invalid\");\n const zProperty = options.zProperty || \"elevation\";\n const commonProperties = options.commonProperties || {};\n const breaksProperties = options.breaksProperties || [];\n\n // Validation\n collectionOf(pointGrid, \"Point\", \"Input must contain Points\");\n if (!breaks) throw new Error(\"breaks is required\");\n if (!Array.isArray(breaks)) throw new Error(\"breaks is not an Array\");\n if (!isObject(commonProperties))\n throw new Error(\"commonProperties is not an Object\");\n if (!Array.isArray(breaksProperties))\n throw new Error(\"breaksProperties is not an Array\");\n\n // Isoband methods\n const matrix = gridToMatrix(pointGrid, { zProperty: zProperty, flip: true });\n let contours = createContourLines(matrix, breaks, zProperty);\n contours = rescaleContours(contours, matrix, pointGrid);\n\n const multipolygons = contours.map((contour, index) => {\n if (breaksProperties[index] && !isObject(breaksProperties[index])) {\n throw new Error(\"Each mappedProperty is required to be an Object\");\n }\n // collect all properties\n const contourProperties = {\n ...commonProperties,\n ...breaksProperties[index],\n };\n\n contourProperties[zProperty] = (contour as GroupRingProps)[zProperty];\n\n const multiP = multiPolygon(\n contour.groupedRings as Position[][][],\n contourProperties\n );\n return multiP;\n });\n\n return featureCollection(multipolygons);\n}\n\n/**\n * Creates the contours lines (featuresCollection of polygon features) from the 2D data grid\n *\n * Marchingsquares process the grid data as a 3D representation of a function on a 2D plane, therefore it\n * assumes the points (x-y coordinates) are one 'unit' distance. The result of the IsoBands function needs to be\n * rescaled, with turfjs, to the original area and proportions on the map\n *\n * @private\n * @param {Array<Array<number>>} matrix Grid Data\n * @param {Array<number>} breaks Breaks\n * @param {string} [property='elevation'] Property\n * @returns {Array<any>} contours\n */\nfunction createContourLines(\n matrix: number[][],\n breaks: number[],\n property: string\n): GroupedRings[] {\n const contours: GroupedRings[] = [];\n for (let i = 1; i < breaks.length; i++) {\n const lowerBand = +breaks[i - 1]; // make sure the breaks value is a number\n const upperBand = +breaks[i];\n\n const isobandsCoords = isoBands(matrix, lowerBand, upperBand - lowerBand);\n // as per GeoJson rules for creating a Polygon, make sure the first element\n // in the array of LinearRings represents the exterior ring (i.e. biggest area),\n // and any subsequent elements represent interior rings (i.e. smaller area);\n // this avoids rendering issues of the MultiPolygons on the map\n const nestedRings = orderByArea(isobandsCoords);\n const groupedRings = groupNestedRings(nestedRings);\n\n contours.push({\n groupedRings: groupedRings as Position[][][],\n [property]: lowerBand + \"-\" + upperBand,\n });\n }\n return contours;\n}\n\n/**\n * Transform isobands of 2D grid to polygons for the map\n *\n * @private\n * @param {Array<any>} contours Contours\n * @param {Array<Array<number>>} matrix Grid Data\n * @param {Object} points Points by Latitude\n * @returns {Array<any>} contours\n */\nfunction rescaleContours(\n contours: GroupedRings[],\n matrix: number[][],\n points: FeatureCollection<Point>\n): GroupedRings[] {\n // get dimensions (on the map) of the original grid\n const gridBbox = bbox(points); // [ minX, minY, maxX, maxY ]\n const originalWidth = gridBbox[2] - gridBbox[0];\n const originalHeigth = gridBbox[3] - gridBbox[1];\n\n // get origin, which is the first point of the last row on the rectangular data on the map\n const x0 = gridBbox[0];\n const y0 = gridBbox[1];\n // get number of cells per side\n const matrixWidth = matrix[0].length - 1;\n const matrixHeight = matrix.length - 1;\n // calculate the scaling factor between matrix and rectangular grid on the map\n const scaleX = originalWidth / matrixWidth;\n const scaleY = originalHeigth / matrixHeight;\n\n // resize and shift each point/line of the isobands\n return contours.map(function (contour) {\n contour.groupedRings = (contour.groupedRings as Position[][][]).map(\n function (lineRingSet) {\n return lineRingSet.map(function (lineRing) {\n return lineRing.map((point: Position) => [\n point[0] * scaleX + x0,\n point[1] * scaleY + y0,\n ]);\n });\n }\n );\n\n return contour;\n });\n}\n\n/* utility functions */\n\n/**\n * Returns an array of coordinates (of LinearRings) in descending order by area\n *\n * @private\n * @param {Array<LineString>} ringsCoords array of closed LineString\n * @returns {Array} array of the input LineString ordered by area\n */\nfunction orderByArea(ringsCoords: Position[][]): Position[][] {\n const ringsWithArea = ringsCoords.map(function (coords) {\n // associate each lineRing with its area\n return { ring: coords, area: area(polygon([coords])) };\n });\n ringsWithArea.sort(function (a, b) {\n // bigger --> smaller\n return b.area - a.area;\n });\n // create a new array of linearRings coordinates ordered by their area\n return ringsWithArea.map(function (x) {\n return x.ring;\n });\n}\n\n/**\n * Returns an array of arrays of coordinates, each representing\n * a set of (coordinates of) nested LinearRings,\n * i.e. the first ring contains all the others\n *\n * @private\n * @param {Array} orderedLinearRings array of coordinates (of LinearRings) in descending order by area\n * @returns {Array<Array>} Array of coordinates of nested LinearRings\n */\nfunction groupNestedRings(orderedLinearRings: Position[][]): Position[][][] {\n // create a list of the (coordinates of) LinearRings\n const lrList = orderedLinearRings.map((lr) => {\n return { lrCoordinates: lr, grouped: false };\n });\n const groupedLinearRingsCoords: Position[][][] = [];\n\n while (!allGrouped(lrList)) {\n for (let i = 0; i < lrList.length; i++) {\n if (!lrList[i].grouped) {\n // create new group starting with the larger not already grouped ring\n const group: Position[][] = [];\n group.push(lrList[i].lrCoordinates);\n lrList[i].grouped = true;\n const outerMostPoly = polygon([lrList[i].lrCoordinates]);\n // group all the rings contained by the outermost ring\n for (let j = i + 1; j < lrList.length; j++) {\n if (!lrList[j].grouped) {\n const lrPoly = polygon([lrList[j].lrCoordinates]);\n if (isInside(lrPoly, outerMostPoly)) {\n group.push(lrList[j].lrCoordinates);\n lrList[j].grouped = true;\n }\n }\n }\n // insert the new group\n groupedLinearRingsCoords.push(group);\n }\n }\n }\n return groupedLinearRingsCoords;\n}\n\n/**\n * @private\n * @param {Polygon} testPolygon polygon of interest\n * @param {Polygon} targetPolygon polygon you want to compare with\n * @returns {boolean} true if test-Polygon is inside target-Polygon\n */\nfunction isInside(\n testPolygon: Feature<Polygon>,\n targetPolygon: Feature<Polygon>\n): boolean {\n const points = explode(testPolygon);\n for (let i = 0; i < points.features.length; i++) {\n if (!booleanPointInPolygon(points.features[i], targetPolygon)) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * @private\n * @param {Array<Object>} list list of objects which might contain the 'group' attribute\n * @returns {boolean} true if all the objects in the list are marked as grouped\n */\nfunction allGrouped(\n list: { grouped: boolean; lrCoordinates: Position[] }[]\n): boolean {\n for (let i = 0; i < list.length; i++) {\n if (list[i].grouped === false) {\n return false;\n }\n }\n return true;\n}\n\nexport { isobands };\nexport default isobands;\n","import { getCoords, collectionOf } from \"@turf/invariant\";\nimport { featureEach } from \"@turf/meta\";\nimport { isObject } from \"@turf/helpers\";\n\n/**\n * Takes a {@link Point} grid and returns a correspondent matrix {Array<Array<number>>}\n * of the 'property' values\n *\n * @name gridToMatrix\n * @param {FeatureCollection<Point>} grid of points\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled\n * @param {boolean} [options.flip=false] returns the matrix upside-down\n * @param {boolean} [options.flags=false] flags, adding a `matrixPosition` array field ([row, column]) to its properties,\n * the grid points with coordinates on the matrix\n * @returns {Array<Array<number>>} matrix of property values\n * @example\n * var extent = [-70.823364, -33.553984, -70.473175, -33.302986];\n * var cellSize = 3;\n * var grid = turf.pointGrid(extent, cellSize);\n * // add a random property to each point between 0 and 60\n * for (var i = 0; i < grid.features.length; i++) {\n * grid.features[i].properties.elevation = (Math.random() * 60);\n * }\n * gridToMatrix(grid);\n * //= [\n * [ 1, 13, 10, 9, 10, 13, 18],\n * [34, 8, 5, 4, 5, 8, 13],\n * [10, 5, 2, 1, 2, 5, 4],\n * [ 0, 4, 56, 19, 1, 4, 9],\n * [10, 5, 2, 1, 2, 5, 10],\n * [57, 8, 5, 4, 5, 0, 57],\n * [ 3, 13, 10, 9, 5, 13, 18],\n * [18, 13, 10, 9, 78, 13, 18]\n * ]\n */\nfunction gridToMatrix(grid, options) {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error(\"options is invalid\");\n var zProperty = options.zProperty || \"elevation\";\n var flip = options.flip;\n var flags = options.flags;\n\n // validation\n collectionOf(grid, \"Point\", \"input must contain Points\");\n\n var pointsMatrix = sortPointsByLatLng(grid, flip);\n\n var matrix = [];\n // create property matrix from sorted points\n // looping order matters here\n for (var r = 0; r < pointsMatrix.length; r++) {\n var pointRow = pointsMatrix[r];\n var row = [];\n for (var c = 0; c < pointRow.length; c++) {\n var point = pointRow[c];\n // Check if zProperty exist\n if (point.properties[zProperty]) row.push(point.properties[zProperty]);\n else row.push(0);\n // add flags\n if (flags === true) point.properties.matrixPosition = [r, c];\n }\n matrix.push(row);\n }\n\n return matrix;\n}\n\n/**\n * Sorts points by latitude and longitude, creating a 2-dimensional array of points\n *\n * @private\n * @param {FeatureCollection<Point>} points GeoJSON Point features\n * @param {boolean} [flip=false] returns the matrix upside-down\n * @returns {Array<Array<Point>>} points ordered by latitude and longitude\n */\nfunction sortPointsByLatLng(points, flip) {\n var pointsByLatitude = {};\n\n // divide points by rows with the same latitude\n featureEach(points, function (point) {\n var lat = getCoords(point)[1];\n if (!pointsByLatitude[lat]) pointsByLatitude[lat] = [];\n pointsByLatitude[lat].push(point);\n });\n\n // sort points (with the same latitude) by longitude\n var orderedRowsByLatitude = Object.keys(pointsByLatitude).map(function (lat) {\n var row = pointsByLatitude[lat];\n var rowOrderedByLongitude = row.sort(function (a, b) {\n return getCoords(a)[0] - getCoords(b)[0];\n });\n return rowOrderedByLongitude;\n });\n\n // sort rows (of points with the same latitude) by latitude\n var pointMatrix = orderedRowsByLatitude.sort(function (a, b) {\n if (flip) return getCoords(a[0])[1] - getCoords(b[0])[1];\n else return getCoords(b[0])[1] - getCoords(a[0])[1];\n });\n\n return pointMatrix;\n}\n\nexport { gridToMatrix };\nexport default gridToMatrix;\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/turf/turf/packages/turf-isobands/dist/cjs/index.cjs","../../index.ts","../../lib/grid-to-matrix.js"],"names":["isObject","collectionOf","contour"],"mappings":"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","file":"/home/runner/work/turf/turf/packages/turf-isobands/dist/cjs/index.cjs","sourcesContent":[null,"import { bbox } from \"@turf/bbox\";\nimport { area } from \"@turf/area\";\nimport { booleanPointInPolygon } from \"@turf/boolean-point-in-polygon\";\nimport { explode } from \"@turf/explode\";\nimport { collectionOf } from \"@turf/invariant\";\nimport {\n polygon,\n multiPolygon,\n featureCollection,\n isObject,\n} from \"@turf/helpers\";\n\nimport {\n FeatureCollection,\n Point,\n GeoJsonProperties,\n MultiPolygon,\n Position,\n Polygon,\n Feature,\n} from \"geojson\";\nimport { gridToMatrix } from \"./lib/grid-to-matrix.js\";\n\ntype GroupRingProps = { [prop: string]: string };\ntype GroupedRings =\n | {\n groupedRings: Position[][][];\n }\n | GroupRingProps;\n\n/**\n * Takes a square or rectangular grid {@link FeatureCollection} of {@link Point} features with z-values and an array of\n * value breaks and generates filled contour isobands.\n *\n * @function\n * @param {FeatureCollection<Point>} pointGrid input points - must be square or rectangular and already gridded. That is, to have consistent x and y dimensions and be at least 2x2 in size.\n * @param {Array<number>} breaks where to draw contours\n * @param {Object} [options={}] options on output\n * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled\n * @param {Object} [options.commonProperties={}] GeoJSON properties passed to ALL isobands\n * @param {Array<Object>} [options.breaksProperties=[]] GeoJSON properties passed, in order, to the correspondent isoband (order defined by breaks)\n * @returns {FeatureCollection<MultiPolygon>} a FeatureCollection of {@link MultiPolygon} features representing isobands\n */\nfunction isobands(\n pointGrid: FeatureCollection<Point>,\n breaks: number[],\n options?: {\n zProperty?: string;\n commonProperties?: GeoJsonProperties;\n breaksProperties?: GeoJsonProperties[];\n }\n): FeatureCollection<MultiPolygon> {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error(\"options is invalid\");\n const zProperty = options.zProperty || \"elevation\";\n const commonProperties = options.commonProperties || {};\n const breaksProperties = options.breaksProperties || [];\n\n // Validation\n collectionOf(pointGrid, \"Point\", \"Input must contain Points\");\n if (!breaks) throw new Error(\"breaks is required\");\n if (!Array.isArray(breaks)) throw new Error(\"breaks is not an Array\");\n if (!isObject(commonProperties))\n throw new Error(\"commonProperties is not an Object\");\n if (!Array.isArray(breaksProperties))\n throw new Error(\"breaksProperties is not an Array\");\n\n // Isoband methods\n const matrix = gridToMatrix(pointGrid, { zProperty: zProperty, flip: true });\n\n // A quick note on what 'top' and 'bottom' mean in coordinate system of `matrix`:\n // Remember that the southern hemisphere is represented by negative numbers,\n // so a matrix Y of 0 is actually the *bottom*, and a Y of dy - 1 is the *top*.\n\n // check that the resulting matrix has consistent x and y dimensions and\n // has at least a 2x2 size so that we can actually build grid squares\n const dx = matrix[0].length;\n if (matrix.length < 2 || dx < 2) {\n throw new Error(\"Matrix of points must be at least 2x2\");\n }\n for (let i = 1; i < matrix.length; i++) {\n if (matrix[i].length !== dx) {\n throw new Error(\"Matrix of points is not uniform in the x dimension\");\n }\n }\n\n let contours = createContourLines(matrix, breaks, zProperty);\n contours = rescaleContours(contours, matrix, pointGrid);\n\n const multipolygons = contours.map((contour, index) => {\n if (breaksProperties[index] && !isObject(breaksProperties[index])) {\n throw new Error(\"Each mappedProperty is required to be an Object\");\n }\n // collect all properties\n const contourProperties = {\n ...commonProperties,\n ...breaksProperties[index],\n };\n\n contourProperties[zProperty] = (contour as GroupRingProps)[zProperty];\n\n const multiP = multiPolygon(\n contour.groupedRings as Position[][][],\n contourProperties\n );\n return multiP;\n });\n\n return featureCollection(multipolygons);\n}\n\n/**\n * Creates the contours lines (featuresCollection of polygon features) from the 2D data grid\n *\n * Marchingsquares process the grid data as a 3D representation of a function on a 2D plane, therefore it\n * assumes the points (x-y coordinates) are one 'unit' distance. The result of the IsoBands function needs to be\n * rescaled, with turfjs, to the original area and proportions on the map\n *\n * @private\n * @param {Array<Array<number>>} matrix Grid Data\n * @param {Array<number>} breaks Breaks\n * @param {string} [property='elevation'] Property\n * @returns {Array<any>} contours\n */\nfunction createContourLines(\n matrix: number[][],\n breaks: number[],\n property: string\n): GroupedRings[] {\n const contours: GroupedRings[] = [];\n\n let prevSegments: Position[][];\n for (let i = 1; i < breaks.length; i++) {\n // the first time through this loop, we need to create the segments for the first break\n if (i === 1) {\n prevSegments = getSegments(matrix, +breaks[0]);\n }\n\n const upperBand = +breaks[i]; // make sure the breaks value is a number\n const lowerBand = +breaks[i - 1];\n const segments = getSegments(matrix, upperBand);\n\n // We will use breaks[i]'s rings to help close breaks[i-1]'s rings.\n // breaks[i]'s rings are clockwise from the point of view of breaks[i - 1] and must be reversed for proper counterclockwise ordering.\n // At the same time, we clone each Position, so that we don't use the same Position Array instance in different output geometries.\n const reverseSegments = segments.map((segment) =>\n // note that we (in-place) reverse the array result of .map and not the original segment itself.\n segment.map((pos) => [pos[0], pos[1]]).reverse()\n );\n\n // use the segments from breaks[i-1] and breaks[i] to create rings, which will\n // then be combined into polygons in the next steps.\n const rings = assembleRings(prevSegments!.concat(reverseSegments), matrix);\n\n // as per GeoJson rules for creating a Polygon, make sure the first element\n // in the array of LinearRings represents the exterior ring (i.e. biggest area),\n // and any subsequent elements represent interior rings (i.e. smaller area);\n // this avoids rendering issues of the MultiPolygons on the map\n const orderedRings = orderByArea(rings);\n const polygons = groupNestedRings(orderedRings);\n\n // If we got no polygons, we can infer that the values are either all above, below, or between the thresholds.\n // If everything is between, we need a polygon that covers the entire grid\n // see https://github.com/Turfjs/turf/issues/1797, https://github.com/Turfjs/turf/issues/2956\n if (\n polygons.length === 0 &&\n matrix[0][0] < upperBand &&\n matrix[0][0] >= lowerBand\n ) {\n const dx = matrix[0].length;\n const dy = matrix.length;\n polygons.push([\n [\n [0, 0],\n [dx - 1, 0],\n [dx - 1, dy - 1],\n [0, dy - 1],\n [0, 0],\n ],\n ]);\n }\n\n // this can add an entry where groupedRings is exactly an empty array\n contours.push({\n groupedRings: polygons,\n [property]: lowerBand + \"-\" + upperBand,\n });\n\n prevSegments = segments;\n }\n\n return contours;\n}\n\n/**\n * Run marching squares across the matrix and calculate the implied counterclockwise ordered line segments from each cell.\n * @see https://en.wikipedia.org/wiki/Marching_squares for an visualization of the different cases\n * @private\n */\nfunction getSegments(\n matrix: ReadonlyArray<ReadonlyArray<number>>,\n threshold: number\n): [Position, Position][] {\n const segments: [Position, Position][] = [];\n\n const dx = matrix[0].length;\n const dy = matrix.length;\n\n for (let y = 0; y < dy - 1; y++) {\n for (let x = 0; x < dx - 1; x++) {\n const tr = matrix[y + 1][x + 1];\n const br = matrix[y][x + 1];\n const bl = matrix[y][x];\n const tl = matrix[y + 1][x];\n\n let grid =\n (tl >= threshold ? 8 : 0) |\n (tr >= threshold ? 4 : 0) |\n (br >= threshold ? 2 : 0) |\n (bl >= threshold ? 1 : 0);\n\n switch (grid) {\n case 0:\n continue;\n case 1:\n segments.push([\n [x + frac(bl, br), y],\n [x, y + frac(bl, tl)],\n ]);\n break;\n case 2:\n segments.push([\n [x + 1, y + frac(br, tr)],\n [x + frac(bl, br), y],\n ]);\n break;\n case 3:\n segments.push([\n [x + 1, y + frac(br, tr)],\n [x, y + frac(bl, tl)],\n ]);\n break;\n case 4:\n segments.push([\n [x + frac(tl, tr), y + 1],\n [x + 1, y + frac(br, tr)],\n ]);\n break;\n case 5: {\n // use the average of the 4 corners to differentiate the saddle case and correctly honor the counter-clockwise winding\n const avg = (tl + tr + br + bl) / 4;\n const above = avg >= threshold;\n\n if (above) {\n segments.push(\n [\n [x + frac(tl, tr), y + 1],\n [x, y + frac(bl, tl)],\n ],\n [\n [x + frac(bl, br), y],\n [x + 1, y + frac(br, tr)],\n ]\n );\n } else {\n segments.push(\n [\n [x + frac(tl, tr), y + 1],\n [x + 1, y + frac(br, tr)],\n ],\n [\n [x + frac(bl, br), y],\n [x, y + frac(bl, tl)],\n ]\n );\n }\n break;\n }\n case 6:\n segments.push([\n [x + frac(tl, tr), y + 1],\n [x + frac(bl, br), y],\n ]);\n break;\n case 7:\n segments.push([\n [x + frac(tl, tr), y + 1],\n [x, y + frac(bl, tl)],\n ]);\n break;\n case 8:\n segments.push([\n [x, y + frac(bl, tl)],\n [x + frac(tl, tr), y + 1],\n ]);\n break;\n case 9:\n segments.push([\n [x + frac(bl, br), y],\n [x + frac(tl, tr), y + 1],\n ]);\n break;\n case 10: {\n const avg = (tl + tr + br + bl) / 4;\n const above = avg >= threshold;\n\n if (above) {\n segments.push(\n [\n [x, y + frac(bl, tl)],\n [x + frac(bl, br), y],\n ],\n [\n [x + 1, y + frac(br, tr)],\n [x + frac(tl, tr), y + 1],\n ]\n );\n } else {\n segments.push(\n [\n [x, y + frac(bl, tl)],\n [x + frac(tl, tr), y + 1],\n ],\n [\n [x + 1, y + frac(br, tr)],\n [x + frac(bl, br), y],\n ]\n );\n }\n break;\n }\n case 11:\n segments.push([\n [x + 1, y + frac(br, tr)],\n [x + frac(tl, tr), y + 1],\n ]);\n break;\n case 12:\n segments.push([\n [x, y + frac(bl, tl)],\n [x + 1, y + frac(br, tr)],\n ]);\n break;\n case 13:\n segments.push([\n [x + frac(bl, br), y],\n [x + 1, y + frac(br, tr)],\n ]);\n break;\n case 14:\n segments.push([\n [x, y + frac(bl, tl)],\n [x + frac(bl, br), y],\n ]);\n break;\n case 15:\n // all above\n continue;\n }\n }\n }\n\n return segments;\n\n // get the linear interpolation fraction of how far z is between z0 and z1\n // See https://github.com/fschutt/marching-squares/blob/master/src/lib.rs\n function frac(z0: number, z1: number): number {\n if (z0 === z1) {\n return 0.5;\n }\n\n let t = (threshold - z0) / (z1 - z0);\n return t > 1 ? 1 : t < 0 ? 0 : t;\n }\n}\n\n/**\n * Create a list of closed rings from the combined segments from breaks[i] and breaks[i-1].\n * @private\n */\nfunction assembleRings(\n segments: Position[][],\n matrix: number[][]\n): Position[][] {\n const dy = matrix.length;\n const dx = matrix[0].length;\n\n const contours: Position[][] = [];\n const result: Position[][] = [];\n\n // Assemble contiguous line segments into contours. These are at least LineStrings,\n // but for features that do not touch the edge of the matrix, they will actually wind up\n // being an entirely closed LinearRing.\n while (segments.length > 0) {\n const contour: Position[] = [...segments.shift()!];\n contours.push(contour);\n\n let found: boolean;\n do {\n found = false;\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n // add the segment's end point to the end of the contour\n if (\n segment[0][0] === contour[contour.length - 1][0] &&\n segment[0][1] === contour[contour.length - 1][1]\n ) {\n found = true;\n contour.push(segment[1]);\n segments.splice(i, 1);\n break;\n }\n // add the segment's start point to the start of the contour\n if (\n segment[1][0] === contour[0][0] &&\n segment[1][1] === contour[0][1]\n ) {\n found = true;\n contour.unshift(segment[0]);\n segments.splice(i, 1);\n break;\n }\n\n // note that because the segments are all guaranteed to be counterclockwise,\n // we do not join segment start to end of the contour or segment end to the start of contour\n }\n\n // if we reach here with found === false, that means that no remaining segments can be\n // added to our contour. We begin again creating the next indepdenent contour.\n } while (found);\n }\n\n // Now we loop again, taking the contours and ensuring that all of them are closed rings.\n // Using segments from two different breaks[], and enforcing closed polygons are the\n // two the major difference between the implementation of @turf/isolines and @turf/isobands.\n while (contours.length > 0) {\n const contour = contours[0];\n\n // if a contour is closed, store it in the results and move to the next contour\n if (\n contour[0][0] === contour[contour.length - 1][0] &&\n contour[0][1] === contour[contour.length - 1][1]\n ) {\n result.push(contour);\n contours.shift();\n continue;\n }\n\n // A contour that is not already closed is guaranteed to touch the bounding box of the matrix.\n // We know that the polygon is ordered counter-clockwise, so we just need to follow\n // the bounding box in a counterclockwise direction, looking for a contour to append.\n // We may need to insert new positions along the corners, but we will eventually close the ring.\n\n const end = contour[contour.length - 1];\n\n let match: number;\n let corner: Position;\n if (end[0] === 0 && end[1] !== 0) {\n // left side\n match = getAdjacentContour(\n contours,\n (contour) => contour[0][0] === 0 && contour[0][1] < end[1], // left side, below end\n (a, b) => b[0][1] - a[0][1] // prefer positions to the top\n );\n corner = [0, 0]; // bottom left corner\n } else if (end[1] === 0 && end[0] !== dx - 1) {\n // bottom side\n match = getAdjacentContour(\n contours,\n (contour) => contour[0][1] === 0 && contour[0][0] > end[0], // bottom side, right of end\n (a, b) => a[0][0] - b[0][0] // prefer positions to the left\n );\n corner = [dx - 1, 0]; // bottom right corner\n } else if (end[0] === dx - 1 && end[1] !== dy - 1) {\n // right side\n match = getAdjacentContour(\n contours,\n (contour) => contour[0][0] === dx - 1 && contour[0][1] > end[1], // right side, above end\n (a, b) => a[0][1] - b[0][1] // prefer positions to the bottom\n );\n corner = [dx - 1, dy - 1]; // top right corner\n } else if (end[1] === dy - 1 && end[0] !== 0) {\n // top side\n match = getAdjacentContour(\n contours,\n (contour) => contour[0][1] === dy - 1 && contour[0][0] < end[0], // top side, left of end\n (a, b) => b[0][0] - a[0][0] // prefer positions to the right\n );\n corner = [0, dy - 1]; // top left corner\n } else {\n throw new Error(\"Contour not closed but is not along an edge\");\n }\n\n if (match === -1) {\n // we did not match a contour on this side, so we add a point in the corner to\n // continue creating our linestring in counterclockwise order. The next\n // run of the loop will continue trying to assemble the current contour on the next side.\n contour.push(corner);\n } else if (match === 0) {\n // We looped back to a contour, and it was ourself. That means that we finished closing the ring.\n // Add the contour to the result and remove it from the contours list to start working\n // on the next contour.\n contour.push([contour[0][0], contour[0][1]]);\n result.push(contour);\n contours.shift();\n } else {\n // We matched a contour, but it is not the one we're currently closing.\n // That means that we get to add its points to our own, and remove that contour entirely.\n // On the next loop, we'll continue trying to close the same contour, but this time from\n // the final Position in contour will be the end of contours[match].\n const matchedContour = contours[match];\n contours.splice(match, 1);\n for (const p of matchedContour) {\n contour.push(p);\n }\n }\n }\n\n // If we get *just* a corner we close it immediately with itself, which results in\n // a 2 point 'ring', which has zero area. We omit these before returning.\n for (let i = 0; i < result.length; i++) {\n if (result[i].length < 4) {\n result.splice(i, 1);\n i--;\n }\n }\n\n return result;\n}\n\n/**\n * Transform isobands of 2D grid to polygons for the map\n *\n * @private\n * @param {Array<any>} contours Contours\n * @param {Array<Array<number>>} matrix Grid Data\n * @param {Object} points Points by Latitude\n * @returns {Array<any>} contours\n */\nfunction rescaleContours(\n contours: GroupedRings[],\n matrix: number[][],\n points: FeatureCollection<Point>\n): GroupedRings[] {\n // get dimensions (on the map) of the original grid\n const gridBbox = bbox(points); // [ minX, minY, maxX, maxY ]\n const originalWidth = gridBbox[2] - gridBbox[0];\n const originalHeigth = gridBbox[3] - gridBbox[1];\n\n // get origin, which is the first point of the last row on the rectangular data on the map\n const x0 = gridBbox[0];\n const y0 = gridBbox[1];\n // get number of cells per side\n const matrixWidth = matrix[0].length - 1;\n const matrixHeight = matrix.length - 1;\n // calculate the scaling factor between matrix and rectangular grid on the map\n const scaleX = originalWidth / matrixWidth;\n const scaleY = originalHeigth / matrixHeight;\n\n // resize and shift each point/line of the isobands\n return contours.map(function (contour) {\n contour.groupedRings = (contour.groupedRings as Position[][][]).map(\n function (lineRingSet) {\n return lineRingSet.map(function (lineRing) {\n return lineRing.map((point: Position) => [\n point[0] * scaleX + x0,\n point[1] * scaleY + y0,\n ]);\n });\n }\n );\n\n return contour;\n });\n}\n\n/* utility functions */\n\n/**\n * Returns an array of coordinates (of LinearRings) in descending order by area\n *\n * @private\n * @param {Array<LineString>} ringsCoords array of closed LineString\n * @returns {Array} array of the input LineString ordered by area\n */\nfunction orderByArea(ringsCoords: Position[][]): Position[][] {\n const ringsWithArea = ringsCoords.map(function (coords) {\n // associate each lineRing with its area\n return { ring: coords, area: area(polygon([coords])) };\n });\n ringsWithArea.sort(function (a, b) {\n // bigger --> smaller\n return b.area - a.area;\n });\n // create a new array of linearRings coordinates ordered by their area\n return ringsWithArea.map(function (x) {\n return x.ring;\n });\n}\n\n/**\n * Returns an array of arrays of coordinates, each representing\n * a set of (coordinates of) nested LinearRings,\n * i.e. the first ring contains all the others\n *\n * @private\n * @param {Array} orderedLinearRings array of coordinates (of LinearRings) in descending order by area\n * @returns {Array<Array>} Array of coordinates of nested LinearRings\n */\nfunction groupNestedRings(orderedLinearRings: Position[][]): Position[][][] {\n // create a list of the (coordinates of) LinearRings\n const lrList = orderedLinearRings.map((lr) => {\n return { lrCoordinates: lr, grouped: false };\n });\n const groupedLinearRingsCoords: Position[][][] = [];\n\n while (!allGrouped(lrList)) {\n for (let i = 0; i < lrList.length; i++) {\n if (!lrList[i].grouped) {\n // create new group starting with the larger not already grouped ring\n const group: Position[][] = [];\n group.push(lrList[i].lrCoordinates);\n lrList[i].grouped = true;\n const outerMostPoly = polygon([lrList[i].lrCoordinates]);\n // group all the rings contained by the outermost ring\n OUTER: for (let j = i + 1; j < lrList.length; j++) {\n if (!lrList[j].grouped) {\n const lrPoly = polygon([lrList[j].lrCoordinates]);\n if (isInside(lrPoly, outerMostPoly)) {\n // we cannot group any linear rings that are contained in hole rings for this group\n for (let k = 1; k < group.length; k++) {\n if (isInside(lrPoly, polygon([group[k]]))) {\n continue OUTER;\n }\n }\n group.push(lrList[j].lrCoordinates);\n lrList[j].grouped = true;\n }\n }\n }\n // insert the new group\n groupedLinearRingsCoords.push(group);\n }\n }\n }\n return groupedLinearRingsCoords;\n}\n\n/**\n * @private\n * @param {Polygon} testPolygon polygon of interest\n * @param {Polygon} targetPolygon polygon you want to compare with\n * @returns {boolean} true if test-Polygon is inside target-Polygon\n */\nfunction isInside(\n testPolygon: Feature<Polygon>,\n targetPolygon: Feature<Polygon>\n): boolean {\n const points = explode(testPolygon);\n for (let i = 0; i < points.features.length; i++) {\n if (!booleanPointInPolygon(points.features[i], targetPolygon)) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * @private\n * @param {Array<Object>} list list of objects which might contain the 'group' attribute\n * @returns {boolean} true if all the objects in the list are marked as grouped\n */\nfunction allGrouped(\n list: { grouped: boolean; lrCoordinates: Position[] }[]\n): boolean {\n for (let i = 0; i < list.length; i++) {\n if (list[i].grouped === false) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Utility function to help close contours into rings\n *\n * @private\n * @param contours The list of contours\n * @param test Return true if a contour is a candidate for being joined\n * @param sort Compare two candidates, returning a positive number will swap the best match from a to b\n * @returns An index of the contour to join, or -1 if no contour was found\n */\nfunction getAdjacentContour(\n contours: Position[][],\n test: (contour: Position[]) => boolean,\n sort: (a: Position[], b: Position[]) => number\n): number {\n let match = -1;\n for (let j = 0; j < contours.length; j++) {\n if (test(contours[j])) {\n if (match === -1 || sort(contours[match], contours[j]) > 0) {\n match = j;\n }\n }\n }\n\n return match;\n}\n\nexport { isobands };\nexport default isobands;\n","import { getCoords, collectionOf } from \"@turf/invariant\";\nimport { featureEach } from \"@turf/meta\";\nimport { isObject } from \"@turf/helpers\";\n\n/**\n * Takes a {@link Point} grid and returns a correspondent matrix {Array<Array<number>>}\n * of the 'property' values\n *\n * @name gridToMatrix\n * @param {FeatureCollection<Point>} grid of points\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled\n * @param {boolean} [options.flip=false] returns the matrix upside-down\n * @param {boolean} [options.flags=false] flags, adding a `matrixPosition` array field ([row, column]) to its properties,\n * the grid points with coordinates on the matrix\n * @returns {Array<Array<number>>} matrix of property values\n * @example\n * var extent = [-70.823364, -33.553984, -70.473175, -33.302986];\n * var cellSize = 3;\n * var grid = turf.pointGrid(extent, cellSize);\n * // add a random property to each point between 0 and 60\n * for (var i = 0; i < grid.features.length; i++) {\n * grid.features[i].properties.elevation = (Math.random() * 60);\n * }\n * gridToMatrix(grid);\n * //= [\n * [ 1, 13, 10, 9, 10, 13, 18],\n * [34, 8, 5, 4, 5, 8, 13],\n * [10, 5, 2, 1, 2, 5, 4],\n * [ 0, 4, 56, 19, 1, 4, 9],\n * [10, 5, 2, 1, 2, 5, 10],\n * [57, 8, 5, 4, 5, 0, 57],\n * [ 3, 13, 10, 9, 5, 13, 18],\n * [18, 13, 10, 9, 78, 13, 18]\n * ]\n */\nfunction gridToMatrix(grid, options) {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error(\"options is invalid\");\n var zProperty = options.zProperty || \"elevation\";\n var flip = options.flip;\n var flags = options.flags;\n\n // validation\n collectionOf(grid, \"Point\", \"input must contain Points\");\n\n var pointsMatrix = sortPointsByLatLng(grid, flip);\n\n var matrix = [];\n // create property matrix from sorted points\n // looping order matters here\n for (var r = 0; r < pointsMatrix.length; r++) {\n var pointRow = pointsMatrix[r];\n var row = [];\n for (var c = 0; c < pointRow.length; c++) {\n var point = pointRow[c];\n // Check if zProperty exist\n if (point.properties[zProperty]) row.push(point.properties[zProperty]);\n else row.push(0);\n // add flags\n if (flags === true) point.properties.matrixPosition = [r, c];\n }\n matrix.push(row);\n }\n\n return matrix;\n}\n\n/**\n * Sorts points by latitude and longitude, creating a 2-dimensional array of points\n *\n * @private\n * @param {FeatureCollection<Point>} points GeoJSON Point features\n * @param {boolean} [flip=false] returns the matrix upside-down\n * @returns {Array<Array<Point>>} points ordered by latitude and longitude\n */\nfunction sortPointsByLatLng(points, flip) {\n var pointsByLatitude = {};\n\n // divide points by rows with the same latitude\n featureEach(points, function (point) {\n var lat = getCoords(point)[1];\n if (!pointsByLatitude[lat]) pointsByLatitude[lat] = [];\n pointsByLatitude[lat].push(point);\n });\n\n // sort points (with the same latitude) by longitude\n var orderedRowsByLatitude = Object.keys(pointsByLatitude).map(function (lat) {\n var row = pointsByLatitude[lat];\n var rowOrderedByLongitude = row.sort(function (a, b) {\n return getCoords(a)[0] - getCoords(b)[0];\n });\n return rowOrderedByLongitude;\n });\n\n // sort rows (of points with the same latitude) by latitude\n var pointMatrix = orderedRowsByLatitude.sort(function (a, b) {\n if (flip) return getCoords(a[0])[1] - getCoords(b[0])[1];\n else return getCoords(b[0])[1] - getCoords(a[0])[1];\n });\n\n return pointMatrix;\n}\n\nexport { gridToMatrix };\nexport default gridToMatrix;\n"]}
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ import { FeatureCollection, Point, GeoJsonProperties, MultiPolygon } from 'geojs
|
|
|
5
5
|
* value breaks and generates filled contour isobands.
|
|
6
6
|
*
|
|
7
7
|
* @function
|
|
8
|
-
* @param {FeatureCollection<Point>} pointGrid input points - must be square or rectangular
|
|
8
|
+
* @param {FeatureCollection<Point>} pointGrid input points - must be square or rectangular and already gridded. That is, to have consistent x and y dimensions and be at least 2x2 in size.
|
|
9
9
|
* @param {Array<number>} breaks where to draw contours
|
|
10
10
|
* @param {Object} [options={}] options on output
|
|
11
11
|
* @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { FeatureCollection, Point, GeoJsonProperties, MultiPolygon } from 'geojs
|
|
|
5
5
|
* value breaks and generates filled contour isobands.
|
|
6
6
|
*
|
|
7
7
|
* @function
|
|
8
|
-
* @param {FeatureCollection<Point>} pointGrid input points - must be square or rectangular
|
|
8
|
+
* @param {FeatureCollection<Point>} pointGrid input points - must be square or rectangular and already gridded. That is, to have consistent x and y dimensions and be at least 2x2 in size.
|
|
9
9
|
* @param {Array<number>} breaks where to draw contours
|
|
10
10
|
* @param {Object} [options={}] options on output
|
|
11
11
|
* @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled
|
package/dist/esm/index.js
CHANGED
|
@@ -76,7 +76,6 @@ function sortPointsByLatLng(points, flip) {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
// index.ts
|
|
79
|
-
import { isoBands } from "marchingsquares";
|
|
80
79
|
function isobands(pointGrid, breaks, options) {
|
|
81
80
|
options = options || {};
|
|
82
81
|
if (!isObject2(options)) throw new Error("options is invalid");
|
|
@@ -91,6 +90,15 @@ function isobands(pointGrid, breaks, options) {
|
|
|
91
90
|
if (!Array.isArray(breaksProperties))
|
|
92
91
|
throw new Error("breaksProperties is not an Array");
|
|
93
92
|
const matrix = gridToMatrix(pointGrid, { zProperty, flip: true });
|
|
93
|
+
const dx = matrix[0].length;
|
|
94
|
+
if (matrix.length < 2 || dx < 2) {
|
|
95
|
+
throw new Error("Matrix of points must be at least 2x2");
|
|
96
|
+
}
|
|
97
|
+
for (let i = 1; i < matrix.length; i++) {
|
|
98
|
+
if (matrix[i].length !== dx) {
|
|
99
|
+
throw new Error("Matrix of points is not uniform in the x dimension");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
94
102
|
let contours = createContourLines(matrix, breaks, zProperty);
|
|
95
103
|
contours = rescaleContours(contours, matrix, pointGrid);
|
|
96
104
|
const multipolygons = contours.map((contour, index) => {
|
|
@@ -109,19 +117,299 @@ function isobands(pointGrid, breaks, options) {
|
|
|
109
117
|
}
|
|
110
118
|
function createContourLines(matrix, breaks, property) {
|
|
111
119
|
const contours = [];
|
|
120
|
+
let prevSegments;
|
|
112
121
|
for (let i = 1; i < breaks.length; i++) {
|
|
113
|
-
|
|
122
|
+
if (i === 1) {
|
|
123
|
+
prevSegments = getSegments(matrix, +breaks[0]);
|
|
124
|
+
}
|
|
114
125
|
const upperBand = +breaks[i];
|
|
115
|
-
const
|
|
116
|
-
const
|
|
117
|
-
const
|
|
126
|
+
const lowerBand = +breaks[i - 1];
|
|
127
|
+
const segments = getSegments(matrix, upperBand);
|
|
128
|
+
const reverseSegments = segments.map(
|
|
129
|
+
(segment) => (
|
|
130
|
+
// note that we (in-place) reverse the array result of .map and not the original segment itself.
|
|
131
|
+
segment.map((pos) => [pos[0], pos[1]]).reverse()
|
|
132
|
+
)
|
|
133
|
+
);
|
|
134
|
+
const rings = assembleRings(prevSegments.concat(reverseSegments), matrix);
|
|
135
|
+
const orderedRings = orderByArea(rings);
|
|
136
|
+
const polygons = groupNestedRings(orderedRings);
|
|
137
|
+
if (polygons.length === 0 && matrix[0][0] < upperBand && matrix[0][0] >= lowerBand) {
|
|
138
|
+
const dx = matrix[0].length;
|
|
139
|
+
const dy = matrix.length;
|
|
140
|
+
polygons.push([
|
|
141
|
+
[
|
|
142
|
+
[0, 0],
|
|
143
|
+
[dx - 1, 0],
|
|
144
|
+
[dx - 1, dy - 1],
|
|
145
|
+
[0, dy - 1],
|
|
146
|
+
[0, 0]
|
|
147
|
+
]
|
|
148
|
+
]);
|
|
149
|
+
}
|
|
118
150
|
contours.push({
|
|
119
|
-
groupedRings,
|
|
151
|
+
groupedRings: polygons,
|
|
120
152
|
[property]: lowerBand + "-" + upperBand
|
|
121
153
|
});
|
|
154
|
+
prevSegments = segments;
|
|
122
155
|
}
|
|
123
156
|
return contours;
|
|
124
157
|
}
|
|
158
|
+
function getSegments(matrix, threshold) {
|
|
159
|
+
const segments = [];
|
|
160
|
+
const dx = matrix[0].length;
|
|
161
|
+
const dy = matrix.length;
|
|
162
|
+
for (let y = 0; y < dy - 1; y++) {
|
|
163
|
+
for (let x = 0; x < dx - 1; x++) {
|
|
164
|
+
const tr = matrix[y + 1][x + 1];
|
|
165
|
+
const br = matrix[y][x + 1];
|
|
166
|
+
const bl = matrix[y][x];
|
|
167
|
+
const tl = matrix[y + 1][x];
|
|
168
|
+
let grid = (tl >= threshold ? 8 : 0) | (tr >= threshold ? 4 : 0) | (br >= threshold ? 2 : 0) | (bl >= threshold ? 1 : 0);
|
|
169
|
+
switch (grid) {
|
|
170
|
+
case 0:
|
|
171
|
+
continue;
|
|
172
|
+
case 1:
|
|
173
|
+
segments.push([
|
|
174
|
+
[x + frac(bl, br), y],
|
|
175
|
+
[x, y + frac(bl, tl)]
|
|
176
|
+
]);
|
|
177
|
+
break;
|
|
178
|
+
case 2:
|
|
179
|
+
segments.push([
|
|
180
|
+
[x + 1, y + frac(br, tr)],
|
|
181
|
+
[x + frac(bl, br), y]
|
|
182
|
+
]);
|
|
183
|
+
break;
|
|
184
|
+
case 3:
|
|
185
|
+
segments.push([
|
|
186
|
+
[x + 1, y + frac(br, tr)],
|
|
187
|
+
[x, y + frac(bl, tl)]
|
|
188
|
+
]);
|
|
189
|
+
break;
|
|
190
|
+
case 4:
|
|
191
|
+
segments.push([
|
|
192
|
+
[x + frac(tl, tr), y + 1],
|
|
193
|
+
[x + 1, y + frac(br, tr)]
|
|
194
|
+
]);
|
|
195
|
+
break;
|
|
196
|
+
case 5: {
|
|
197
|
+
const avg = (tl + tr + br + bl) / 4;
|
|
198
|
+
const above = avg >= threshold;
|
|
199
|
+
if (above) {
|
|
200
|
+
segments.push(
|
|
201
|
+
[
|
|
202
|
+
[x + frac(tl, tr), y + 1],
|
|
203
|
+
[x, y + frac(bl, tl)]
|
|
204
|
+
],
|
|
205
|
+
[
|
|
206
|
+
[x + frac(bl, br), y],
|
|
207
|
+
[x + 1, y + frac(br, tr)]
|
|
208
|
+
]
|
|
209
|
+
);
|
|
210
|
+
} else {
|
|
211
|
+
segments.push(
|
|
212
|
+
[
|
|
213
|
+
[x + frac(tl, tr), y + 1],
|
|
214
|
+
[x + 1, y + frac(br, tr)]
|
|
215
|
+
],
|
|
216
|
+
[
|
|
217
|
+
[x + frac(bl, br), y],
|
|
218
|
+
[x, y + frac(bl, tl)]
|
|
219
|
+
]
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
case 6:
|
|
225
|
+
segments.push([
|
|
226
|
+
[x + frac(tl, tr), y + 1],
|
|
227
|
+
[x + frac(bl, br), y]
|
|
228
|
+
]);
|
|
229
|
+
break;
|
|
230
|
+
case 7:
|
|
231
|
+
segments.push([
|
|
232
|
+
[x + frac(tl, tr), y + 1],
|
|
233
|
+
[x, y + frac(bl, tl)]
|
|
234
|
+
]);
|
|
235
|
+
break;
|
|
236
|
+
case 8:
|
|
237
|
+
segments.push([
|
|
238
|
+
[x, y + frac(bl, tl)],
|
|
239
|
+
[x + frac(tl, tr), y + 1]
|
|
240
|
+
]);
|
|
241
|
+
break;
|
|
242
|
+
case 9:
|
|
243
|
+
segments.push([
|
|
244
|
+
[x + frac(bl, br), y],
|
|
245
|
+
[x + frac(tl, tr), y + 1]
|
|
246
|
+
]);
|
|
247
|
+
break;
|
|
248
|
+
case 10: {
|
|
249
|
+
const avg = (tl + tr + br + bl) / 4;
|
|
250
|
+
const above = avg >= threshold;
|
|
251
|
+
if (above) {
|
|
252
|
+
segments.push(
|
|
253
|
+
[
|
|
254
|
+
[x, y + frac(bl, tl)],
|
|
255
|
+
[x + frac(bl, br), y]
|
|
256
|
+
],
|
|
257
|
+
[
|
|
258
|
+
[x + 1, y + frac(br, tr)],
|
|
259
|
+
[x + frac(tl, tr), y + 1]
|
|
260
|
+
]
|
|
261
|
+
);
|
|
262
|
+
} else {
|
|
263
|
+
segments.push(
|
|
264
|
+
[
|
|
265
|
+
[x, y + frac(bl, tl)],
|
|
266
|
+
[x + frac(tl, tr), y + 1]
|
|
267
|
+
],
|
|
268
|
+
[
|
|
269
|
+
[x + 1, y + frac(br, tr)],
|
|
270
|
+
[x + frac(bl, br), y]
|
|
271
|
+
]
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
case 11:
|
|
277
|
+
segments.push([
|
|
278
|
+
[x + 1, y + frac(br, tr)],
|
|
279
|
+
[x + frac(tl, tr), y + 1]
|
|
280
|
+
]);
|
|
281
|
+
break;
|
|
282
|
+
case 12:
|
|
283
|
+
segments.push([
|
|
284
|
+
[x, y + frac(bl, tl)],
|
|
285
|
+
[x + 1, y + frac(br, tr)]
|
|
286
|
+
]);
|
|
287
|
+
break;
|
|
288
|
+
case 13:
|
|
289
|
+
segments.push([
|
|
290
|
+
[x + frac(bl, br), y],
|
|
291
|
+
[x + 1, y + frac(br, tr)]
|
|
292
|
+
]);
|
|
293
|
+
break;
|
|
294
|
+
case 14:
|
|
295
|
+
segments.push([
|
|
296
|
+
[x, y + frac(bl, tl)],
|
|
297
|
+
[x + frac(bl, br), y]
|
|
298
|
+
]);
|
|
299
|
+
break;
|
|
300
|
+
case 15:
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return segments;
|
|
306
|
+
function frac(z0, z1) {
|
|
307
|
+
if (z0 === z1) {
|
|
308
|
+
return 0.5;
|
|
309
|
+
}
|
|
310
|
+
let t = (threshold - z0) / (z1 - z0);
|
|
311
|
+
return t > 1 ? 1 : t < 0 ? 0 : t;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function assembleRings(segments, matrix) {
|
|
315
|
+
const dy = matrix.length;
|
|
316
|
+
const dx = matrix[0].length;
|
|
317
|
+
const contours = [];
|
|
318
|
+
const result = [];
|
|
319
|
+
while (segments.length > 0) {
|
|
320
|
+
const contour = [...segments.shift()];
|
|
321
|
+
contours.push(contour);
|
|
322
|
+
let found;
|
|
323
|
+
do {
|
|
324
|
+
found = false;
|
|
325
|
+
for (let i = 0; i < segments.length; i++) {
|
|
326
|
+
const segment = segments[i];
|
|
327
|
+
if (segment[0][0] === contour[contour.length - 1][0] && segment[0][1] === contour[contour.length - 1][1]) {
|
|
328
|
+
found = true;
|
|
329
|
+
contour.push(segment[1]);
|
|
330
|
+
segments.splice(i, 1);
|
|
331
|
+
break;
|
|
332
|
+
}
|
|
333
|
+
if (segment[1][0] === contour[0][0] && segment[1][1] === contour[0][1]) {
|
|
334
|
+
found = true;
|
|
335
|
+
contour.unshift(segment[0]);
|
|
336
|
+
segments.splice(i, 1);
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
} while (found);
|
|
341
|
+
}
|
|
342
|
+
while (contours.length > 0) {
|
|
343
|
+
const contour = contours[0];
|
|
344
|
+
if (contour[0][0] === contour[contour.length - 1][0] && contour[0][1] === contour[contour.length - 1][1]) {
|
|
345
|
+
result.push(contour);
|
|
346
|
+
contours.shift();
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
const end = contour[contour.length - 1];
|
|
350
|
+
let match;
|
|
351
|
+
let corner;
|
|
352
|
+
if (end[0] === 0 && end[1] !== 0) {
|
|
353
|
+
match = getAdjacentContour(
|
|
354
|
+
contours,
|
|
355
|
+
(contour2) => contour2[0][0] === 0 && contour2[0][1] < end[1],
|
|
356
|
+
// left side, below end
|
|
357
|
+
(a, b) => b[0][1] - a[0][1]
|
|
358
|
+
// prefer positions to the top
|
|
359
|
+
);
|
|
360
|
+
corner = [0, 0];
|
|
361
|
+
} else if (end[1] === 0 && end[0] !== dx - 1) {
|
|
362
|
+
match = getAdjacentContour(
|
|
363
|
+
contours,
|
|
364
|
+
(contour2) => contour2[0][1] === 0 && contour2[0][0] > end[0],
|
|
365
|
+
// bottom side, right of end
|
|
366
|
+
(a, b) => a[0][0] - b[0][0]
|
|
367
|
+
// prefer positions to the left
|
|
368
|
+
);
|
|
369
|
+
corner = [dx - 1, 0];
|
|
370
|
+
} else if (end[0] === dx - 1 && end[1] !== dy - 1) {
|
|
371
|
+
match = getAdjacentContour(
|
|
372
|
+
contours,
|
|
373
|
+
(contour2) => contour2[0][0] === dx - 1 && contour2[0][1] > end[1],
|
|
374
|
+
// right side, above end
|
|
375
|
+
(a, b) => a[0][1] - b[0][1]
|
|
376
|
+
// prefer positions to the bottom
|
|
377
|
+
);
|
|
378
|
+
corner = [dx - 1, dy - 1];
|
|
379
|
+
} else if (end[1] === dy - 1 && end[0] !== 0) {
|
|
380
|
+
match = getAdjacentContour(
|
|
381
|
+
contours,
|
|
382
|
+
(contour2) => contour2[0][1] === dy - 1 && contour2[0][0] < end[0],
|
|
383
|
+
// top side, left of end
|
|
384
|
+
(a, b) => b[0][0] - a[0][0]
|
|
385
|
+
// prefer positions to the right
|
|
386
|
+
);
|
|
387
|
+
corner = [0, dy - 1];
|
|
388
|
+
} else {
|
|
389
|
+
throw new Error("Contour not closed but is not along an edge");
|
|
390
|
+
}
|
|
391
|
+
if (match === -1) {
|
|
392
|
+
contour.push(corner);
|
|
393
|
+
} else if (match === 0) {
|
|
394
|
+
contour.push([contour[0][0], contour[0][1]]);
|
|
395
|
+
result.push(contour);
|
|
396
|
+
contours.shift();
|
|
397
|
+
} else {
|
|
398
|
+
const matchedContour = contours[match];
|
|
399
|
+
contours.splice(match, 1);
|
|
400
|
+
for (const p of matchedContour) {
|
|
401
|
+
contour.push(p);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
for (let i = 0; i < result.length; i++) {
|
|
406
|
+
if (result[i].length < 4) {
|
|
407
|
+
result.splice(i, 1);
|
|
408
|
+
i--;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return result;
|
|
412
|
+
}
|
|
125
413
|
function rescaleContours(contours, matrix, points) {
|
|
126
414
|
const gridBbox = bbox(points);
|
|
127
415
|
const originalWidth = gridBbox[2] - gridBbox[0];
|
|
@@ -169,10 +457,15 @@ function groupNestedRings(orderedLinearRings) {
|
|
|
169
457
|
group.push(lrList[i].lrCoordinates);
|
|
170
458
|
lrList[i].grouped = true;
|
|
171
459
|
const outerMostPoly = polygon([lrList[i].lrCoordinates]);
|
|
172
|
-
for (let j = i + 1; j < lrList.length; j++) {
|
|
460
|
+
OUTER: for (let j = i + 1; j < lrList.length; j++) {
|
|
173
461
|
if (!lrList[j].grouped) {
|
|
174
462
|
const lrPoly = polygon([lrList[j].lrCoordinates]);
|
|
175
463
|
if (isInside(lrPoly, outerMostPoly)) {
|
|
464
|
+
for (let k = 1; k < group.length; k++) {
|
|
465
|
+
if (isInside(lrPoly, polygon([group[k]]))) {
|
|
466
|
+
continue OUTER;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
176
469
|
group.push(lrList[j].lrCoordinates);
|
|
177
470
|
lrList[j].grouped = true;
|
|
178
471
|
}
|
|
@@ -201,9 +494,20 @@ function allGrouped(list) {
|
|
|
201
494
|
}
|
|
202
495
|
return true;
|
|
203
496
|
}
|
|
204
|
-
|
|
497
|
+
function getAdjacentContour(contours, test, sort) {
|
|
498
|
+
let match = -1;
|
|
499
|
+
for (let j = 0; j < contours.length; j++) {
|
|
500
|
+
if (test(contours[j])) {
|
|
501
|
+
if (match === -1 || sort(contours[match], contours[j]) > 0) {
|
|
502
|
+
match = j;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return match;
|
|
507
|
+
}
|
|
508
|
+
var index_default = isobands;
|
|
205
509
|
export {
|
|
206
|
-
|
|
510
|
+
index_default as default,
|
|
207
511
|
isobands
|
|
208
512
|
};
|
|
209
513
|
//# sourceMappingURL=index.js.map
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../index.ts","../../lib/grid-to-matrix.js"],"sourcesContent":["import { bbox } from \"@turf/bbox\";\nimport { area } from \"@turf/area\";\nimport { booleanPointInPolygon } from \"@turf/boolean-point-in-polygon\";\nimport { explode } from \"@turf/explode\";\nimport { collectionOf } from \"@turf/invariant\";\nimport {\n polygon,\n multiPolygon,\n featureCollection,\n isObject,\n} from \"@turf/helpers\";\n\nimport {\n FeatureCollection,\n Point,\n GeoJsonProperties,\n MultiPolygon,\n Position,\n Polygon,\n Feature,\n} from \"geojson\";\n\nimport { gridToMatrix } from \"./lib/grid-to-matrix.js\";\nimport { isoBands } from \"marchingsquares\";\n\ntype GroupRingProps = { [prop: string]: string };\ntype GroupedRings =\n | {\n groupedRings: Position[][][];\n }\n | GroupRingProps;\n\n/**\n * Takes a square or rectangular grid {@link FeatureCollection} of {@link Point} features with z-values and an array of\n * value breaks and generates filled contour isobands.\n *\n * @function\n * @param {FeatureCollection<Point>} pointGrid input points - must be square or rectangular\n * @param {Array<number>} breaks where to draw contours\n * @param {Object} [options={}] options on output\n * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled\n * @param {Object} [options.commonProperties={}] GeoJSON properties passed to ALL isobands\n * @param {Array<Object>} [options.breaksProperties=[]] GeoJSON properties passed, in order, to the correspondent isoband (order defined by breaks)\n * @returns {FeatureCollection<MultiPolygon>} a FeatureCollection of {@link MultiPolygon} features representing isobands\n */\nfunction isobands(\n pointGrid: FeatureCollection<Point>,\n breaks: number[],\n options?: {\n zProperty?: string;\n commonProperties?: GeoJsonProperties;\n breaksProperties?: GeoJsonProperties[];\n }\n): FeatureCollection<MultiPolygon> {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error(\"options is invalid\");\n const zProperty = options.zProperty || \"elevation\";\n const commonProperties = options.commonProperties || {};\n const breaksProperties = options.breaksProperties || [];\n\n // Validation\n collectionOf(pointGrid, \"Point\", \"Input must contain Points\");\n if (!breaks) throw new Error(\"breaks is required\");\n if (!Array.isArray(breaks)) throw new Error(\"breaks is not an Array\");\n if (!isObject(commonProperties))\n throw new Error(\"commonProperties is not an Object\");\n if (!Array.isArray(breaksProperties))\n throw new Error(\"breaksProperties is not an Array\");\n\n // Isoband methods\n const matrix = gridToMatrix(pointGrid, { zProperty: zProperty, flip: true });\n let contours = createContourLines(matrix, breaks, zProperty);\n contours = rescaleContours(contours, matrix, pointGrid);\n\n const multipolygons = contours.map((contour, index) => {\n if (breaksProperties[index] && !isObject(breaksProperties[index])) {\n throw new Error(\"Each mappedProperty is required to be an Object\");\n }\n // collect all properties\n const contourProperties = {\n ...commonProperties,\n ...breaksProperties[index],\n };\n\n contourProperties[zProperty] = (contour as GroupRingProps)[zProperty];\n\n const multiP = multiPolygon(\n contour.groupedRings as Position[][][],\n contourProperties\n );\n return multiP;\n });\n\n return featureCollection(multipolygons);\n}\n\n/**\n * Creates the contours lines (featuresCollection of polygon features) from the 2D data grid\n *\n * Marchingsquares process the grid data as a 3D representation of a function on a 2D plane, therefore it\n * assumes the points (x-y coordinates) are one 'unit' distance. The result of the IsoBands function needs to be\n * rescaled, with turfjs, to the original area and proportions on the map\n *\n * @private\n * @param {Array<Array<number>>} matrix Grid Data\n * @param {Array<number>} breaks Breaks\n * @param {string} [property='elevation'] Property\n * @returns {Array<any>} contours\n */\nfunction createContourLines(\n matrix: number[][],\n breaks: number[],\n property: string\n): GroupedRings[] {\n const contours: GroupedRings[] = [];\n for (let i = 1; i < breaks.length; i++) {\n const lowerBand = +breaks[i - 1]; // make sure the breaks value is a number\n const upperBand = +breaks[i];\n\n const isobandsCoords = isoBands(matrix, lowerBand, upperBand - lowerBand);\n // as per GeoJson rules for creating a Polygon, make sure the first element\n // in the array of LinearRings represents the exterior ring (i.e. biggest area),\n // and any subsequent elements represent interior rings (i.e. smaller area);\n // this avoids rendering issues of the MultiPolygons on the map\n const nestedRings = orderByArea(isobandsCoords);\n const groupedRings = groupNestedRings(nestedRings);\n\n contours.push({\n groupedRings: groupedRings as Position[][][],\n [property]: lowerBand + \"-\" + upperBand,\n });\n }\n return contours;\n}\n\n/**\n * Transform isobands of 2D grid to polygons for the map\n *\n * @private\n * @param {Array<any>} contours Contours\n * @param {Array<Array<number>>} matrix Grid Data\n * @param {Object} points Points by Latitude\n * @returns {Array<any>} contours\n */\nfunction rescaleContours(\n contours: GroupedRings[],\n matrix: number[][],\n points: FeatureCollection<Point>\n): GroupedRings[] {\n // get dimensions (on the map) of the original grid\n const gridBbox = bbox(points); // [ minX, minY, maxX, maxY ]\n const originalWidth = gridBbox[2] - gridBbox[0];\n const originalHeigth = gridBbox[3] - gridBbox[1];\n\n // get origin, which is the first point of the last row on the rectangular data on the map\n const x0 = gridBbox[0];\n const y0 = gridBbox[1];\n // get number of cells per side\n const matrixWidth = matrix[0].length - 1;\n const matrixHeight = matrix.length - 1;\n // calculate the scaling factor between matrix and rectangular grid on the map\n const scaleX = originalWidth / matrixWidth;\n const scaleY = originalHeigth / matrixHeight;\n\n // resize and shift each point/line of the isobands\n return contours.map(function (contour) {\n contour.groupedRings = (contour.groupedRings as Position[][][]).map(\n function (lineRingSet) {\n return lineRingSet.map(function (lineRing) {\n return lineRing.map((point: Position) => [\n point[0] * scaleX + x0,\n point[1] * scaleY + y0,\n ]);\n });\n }\n );\n\n return contour;\n });\n}\n\n/* utility functions */\n\n/**\n * Returns an array of coordinates (of LinearRings) in descending order by area\n *\n * @private\n * @param {Array<LineString>} ringsCoords array of closed LineString\n * @returns {Array} array of the input LineString ordered by area\n */\nfunction orderByArea(ringsCoords: Position[][]): Position[][] {\n const ringsWithArea = ringsCoords.map(function (coords) {\n // associate each lineRing with its area\n return { ring: coords, area: area(polygon([coords])) };\n });\n ringsWithArea.sort(function (a, b) {\n // bigger --> smaller\n return b.area - a.area;\n });\n // create a new array of linearRings coordinates ordered by their area\n return ringsWithArea.map(function (x) {\n return x.ring;\n });\n}\n\n/**\n * Returns an array of arrays of coordinates, each representing\n * a set of (coordinates of) nested LinearRings,\n * i.e. the first ring contains all the others\n *\n * @private\n * @param {Array} orderedLinearRings array of coordinates (of LinearRings) in descending order by area\n * @returns {Array<Array>} Array of coordinates of nested LinearRings\n */\nfunction groupNestedRings(orderedLinearRings: Position[][]): Position[][][] {\n // create a list of the (coordinates of) LinearRings\n const lrList = orderedLinearRings.map((lr) => {\n return { lrCoordinates: lr, grouped: false };\n });\n const groupedLinearRingsCoords: Position[][][] = [];\n\n while (!allGrouped(lrList)) {\n for (let i = 0; i < lrList.length; i++) {\n if (!lrList[i].grouped) {\n // create new group starting with the larger not already grouped ring\n const group: Position[][] = [];\n group.push(lrList[i].lrCoordinates);\n lrList[i].grouped = true;\n const outerMostPoly = polygon([lrList[i].lrCoordinates]);\n // group all the rings contained by the outermost ring\n for (let j = i + 1; j < lrList.length; j++) {\n if (!lrList[j].grouped) {\n const lrPoly = polygon([lrList[j].lrCoordinates]);\n if (isInside(lrPoly, outerMostPoly)) {\n group.push(lrList[j].lrCoordinates);\n lrList[j].grouped = true;\n }\n }\n }\n // insert the new group\n groupedLinearRingsCoords.push(group);\n }\n }\n }\n return groupedLinearRingsCoords;\n}\n\n/**\n * @private\n * @param {Polygon} testPolygon polygon of interest\n * @param {Polygon} targetPolygon polygon you want to compare with\n * @returns {boolean} true if test-Polygon is inside target-Polygon\n */\nfunction isInside(\n testPolygon: Feature<Polygon>,\n targetPolygon: Feature<Polygon>\n): boolean {\n const points = explode(testPolygon);\n for (let i = 0; i < points.features.length; i++) {\n if (!booleanPointInPolygon(points.features[i], targetPolygon)) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * @private\n * @param {Array<Object>} list list of objects which might contain the 'group' attribute\n * @returns {boolean} true if all the objects in the list are marked as grouped\n */\nfunction allGrouped(\n list: { grouped: boolean; lrCoordinates: Position[] }[]\n): boolean {\n for (let i = 0; i < list.length; i++) {\n if (list[i].grouped === false) {\n return false;\n }\n }\n return true;\n}\n\nexport { isobands };\nexport default isobands;\n","import { getCoords, collectionOf } from \"@turf/invariant\";\nimport { featureEach } from \"@turf/meta\";\nimport { isObject } from \"@turf/helpers\";\n\n/**\n * Takes a {@link Point} grid and returns a correspondent matrix {Array<Array<number>>}\n * of the 'property' values\n *\n * @name gridToMatrix\n * @param {FeatureCollection<Point>} grid of points\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled\n * @param {boolean} [options.flip=false] returns the matrix upside-down\n * @param {boolean} [options.flags=false] flags, adding a `matrixPosition` array field ([row, column]) to its properties,\n * the grid points with coordinates on the matrix\n * @returns {Array<Array<number>>} matrix of property values\n * @example\n * var extent = [-70.823364, -33.553984, -70.473175, -33.302986];\n * var cellSize = 3;\n * var grid = turf.pointGrid(extent, cellSize);\n * // add a random property to each point between 0 and 60\n * for (var i = 0; i < grid.features.length; i++) {\n * grid.features[i].properties.elevation = (Math.random() * 60);\n * }\n * gridToMatrix(grid);\n * //= [\n * [ 1, 13, 10, 9, 10, 13, 18],\n * [34, 8, 5, 4, 5, 8, 13],\n * [10, 5, 2, 1, 2, 5, 4],\n * [ 0, 4, 56, 19, 1, 4, 9],\n * [10, 5, 2, 1, 2, 5, 10],\n * [57, 8, 5, 4, 5, 0, 57],\n * [ 3, 13, 10, 9, 5, 13, 18],\n * [18, 13, 10, 9, 78, 13, 18]\n * ]\n */\nfunction gridToMatrix(grid, options) {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error(\"options is invalid\");\n var zProperty = options.zProperty || \"elevation\";\n var flip = options.flip;\n var flags = options.flags;\n\n // validation\n collectionOf(grid, \"Point\", \"input must contain Points\");\n\n var pointsMatrix = sortPointsByLatLng(grid, flip);\n\n var matrix = [];\n // create property matrix from sorted points\n // looping order matters here\n for (var r = 0; r < pointsMatrix.length; r++) {\n var pointRow = pointsMatrix[r];\n var row = [];\n for (var c = 0; c < pointRow.length; c++) {\n var point = pointRow[c];\n // Check if zProperty exist\n if (point.properties[zProperty]) row.push(point.properties[zProperty]);\n else row.push(0);\n // add flags\n if (flags === true) point.properties.matrixPosition = [r, c];\n }\n matrix.push(row);\n }\n\n return matrix;\n}\n\n/**\n * Sorts points by latitude and longitude, creating a 2-dimensional array of points\n *\n * @private\n * @param {FeatureCollection<Point>} points GeoJSON Point features\n * @param {boolean} [flip=false] returns the matrix upside-down\n * @returns {Array<Array<Point>>} points ordered by latitude and longitude\n */\nfunction sortPointsByLatLng(points, flip) {\n var pointsByLatitude = {};\n\n // divide points by rows with the same latitude\n featureEach(points, function (point) {\n var lat = getCoords(point)[1];\n if (!pointsByLatitude[lat]) pointsByLatitude[lat] = [];\n pointsByLatitude[lat].push(point);\n });\n\n // sort points (with the same latitude) by longitude\n var orderedRowsByLatitude = Object.keys(pointsByLatitude).map(function (lat) {\n var row = pointsByLatitude[lat];\n var rowOrderedByLongitude = row.sort(function (a, b) {\n return getCoords(a)[0] - getCoords(b)[0];\n });\n return rowOrderedByLongitude;\n });\n\n // sort rows (of points with the same latitude) by latitude\n var pointMatrix = orderedRowsByLatitude.sort(function (a, b) {\n if (flip) return getCoords(a[0])[1] - getCoords(b[0])[1];\n else return getCoords(b[0])[1] - getCoords(a[0])[1];\n });\n\n return pointMatrix;\n}\n\nexport { gridToMatrix };\nexport default gridToMatrix;\n"],"mappings":"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","names":["collectionOf","isObject","isObject","collectionOf"]}
|
|
1
|
+
{"version":3,"sources":["../../index.ts","../../lib/grid-to-matrix.js"],"sourcesContent":["import { bbox } from \"@turf/bbox\";\nimport { area } from \"@turf/area\";\nimport { booleanPointInPolygon } from \"@turf/boolean-point-in-polygon\";\nimport { explode } from \"@turf/explode\";\nimport { collectionOf } from \"@turf/invariant\";\nimport {\n polygon,\n multiPolygon,\n featureCollection,\n isObject,\n} from \"@turf/helpers\";\n\nimport {\n FeatureCollection,\n Point,\n GeoJsonProperties,\n MultiPolygon,\n Position,\n Polygon,\n Feature,\n} from \"geojson\";\nimport { gridToMatrix } from \"./lib/grid-to-matrix.js\";\n\ntype GroupRingProps = { [prop: string]: string };\ntype GroupedRings =\n | {\n groupedRings: Position[][][];\n }\n | GroupRingProps;\n\n/**\n * Takes a square or rectangular grid {@link FeatureCollection} of {@link Point} features with z-values and an array of\n * value breaks and generates filled contour isobands.\n *\n * @function\n * @param {FeatureCollection<Point>} pointGrid input points - must be square or rectangular and already gridded. That is, to have consistent x and y dimensions and be at least 2x2 in size.\n * @param {Array<number>} breaks where to draw contours\n * @param {Object} [options={}] options on output\n * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled\n * @param {Object} [options.commonProperties={}] GeoJSON properties passed to ALL isobands\n * @param {Array<Object>} [options.breaksProperties=[]] GeoJSON properties passed, in order, to the correspondent isoband (order defined by breaks)\n * @returns {FeatureCollection<MultiPolygon>} a FeatureCollection of {@link MultiPolygon} features representing isobands\n */\nfunction isobands(\n pointGrid: FeatureCollection<Point>,\n breaks: number[],\n options?: {\n zProperty?: string;\n commonProperties?: GeoJsonProperties;\n breaksProperties?: GeoJsonProperties[];\n }\n): FeatureCollection<MultiPolygon> {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error(\"options is invalid\");\n const zProperty = options.zProperty || \"elevation\";\n const commonProperties = options.commonProperties || {};\n const breaksProperties = options.breaksProperties || [];\n\n // Validation\n collectionOf(pointGrid, \"Point\", \"Input must contain Points\");\n if (!breaks) throw new Error(\"breaks is required\");\n if (!Array.isArray(breaks)) throw new Error(\"breaks is not an Array\");\n if (!isObject(commonProperties))\n throw new Error(\"commonProperties is not an Object\");\n if (!Array.isArray(breaksProperties))\n throw new Error(\"breaksProperties is not an Array\");\n\n // Isoband methods\n const matrix = gridToMatrix(pointGrid, { zProperty: zProperty, flip: true });\n\n // A quick note on what 'top' and 'bottom' mean in coordinate system of `matrix`:\n // Remember that the southern hemisphere is represented by negative numbers,\n // so a matrix Y of 0 is actually the *bottom*, and a Y of dy - 1 is the *top*.\n\n // check that the resulting matrix has consistent x and y dimensions and\n // has at least a 2x2 size so that we can actually build grid squares\n const dx = matrix[0].length;\n if (matrix.length < 2 || dx < 2) {\n throw new Error(\"Matrix of points must be at least 2x2\");\n }\n for (let i = 1; i < matrix.length; i++) {\n if (matrix[i].length !== dx) {\n throw new Error(\"Matrix of points is not uniform in the x dimension\");\n }\n }\n\n let contours = createContourLines(matrix, breaks, zProperty);\n contours = rescaleContours(contours, matrix, pointGrid);\n\n const multipolygons = contours.map((contour, index) => {\n if (breaksProperties[index] && !isObject(breaksProperties[index])) {\n throw new Error(\"Each mappedProperty is required to be an Object\");\n }\n // collect all properties\n const contourProperties = {\n ...commonProperties,\n ...breaksProperties[index],\n };\n\n contourProperties[zProperty] = (contour as GroupRingProps)[zProperty];\n\n const multiP = multiPolygon(\n contour.groupedRings as Position[][][],\n contourProperties\n );\n return multiP;\n });\n\n return featureCollection(multipolygons);\n}\n\n/**\n * Creates the contours lines (featuresCollection of polygon features) from the 2D data grid\n *\n * Marchingsquares process the grid data as a 3D representation of a function on a 2D plane, therefore it\n * assumes the points (x-y coordinates) are one 'unit' distance. The result of the IsoBands function needs to be\n * rescaled, with turfjs, to the original area and proportions on the map\n *\n * @private\n * @param {Array<Array<number>>} matrix Grid Data\n * @param {Array<number>} breaks Breaks\n * @param {string} [property='elevation'] Property\n * @returns {Array<any>} contours\n */\nfunction createContourLines(\n matrix: number[][],\n breaks: number[],\n property: string\n): GroupedRings[] {\n const contours: GroupedRings[] = [];\n\n let prevSegments: Position[][];\n for (let i = 1; i < breaks.length; i++) {\n // the first time through this loop, we need to create the segments for the first break\n if (i === 1) {\n prevSegments = getSegments(matrix, +breaks[0]);\n }\n\n const upperBand = +breaks[i]; // make sure the breaks value is a number\n const lowerBand = +breaks[i - 1];\n const segments = getSegments(matrix, upperBand);\n\n // We will use breaks[i]'s rings to help close breaks[i-1]'s rings.\n // breaks[i]'s rings are clockwise from the point of view of breaks[i - 1] and must be reversed for proper counterclockwise ordering.\n // At the same time, we clone each Position, so that we don't use the same Position Array instance in different output geometries.\n const reverseSegments = segments.map((segment) =>\n // note that we (in-place) reverse the array result of .map and not the original segment itself.\n segment.map((pos) => [pos[0], pos[1]]).reverse()\n );\n\n // use the segments from breaks[i-1] and breaks[i] to create rings, which will\n // then be combined into polygons in the next steps.\n const rings = assembleRings(prevSegments!.concat(reverseSegments), matrix);\n\n // as per GeoJson rules for creating a Polygon, make sure the first element\n // in the array of LinearRings represents the exterior ring (i.e. biggest area),\n // and any subsequent elements represent interior rings (i.e. smaller area);\n // this avoids rendering issues of the MultiPolygons on the map\n const orderedRings = orderByArea(rings);\n const polygons = groupNestedRings(orderedRings);\n\n // If we got no polygons, we can infer that the values are either all above, below, or between the thresholds.\n // If everything is between, we need a polygon that covers the entire grid\n // see https://github.com/Turfjs/turf/issues/1797, https://github.com/Turfjs/turf/issues/2956\n if (\n polygons.length === 0 &&\n matrix[0][0] < upperBand &&\n matrix[0][0] >= lowerBand\n ) {\n const dx = matrix[0].length;\n const dy = matrix.length;\n polygons.push([\n [\n [0, 0],\n [dx - 1, 0],\n [dx - 1, dy - 1],\n [0, dy - 1],\n [0, 0],\n ],\n ]);\n }\n\n // this can add an entry where groupedRings is exactly an empty array\n contours.push({\n groupedRings: polygons,\n [property]: lowerBand + \"-\" + upperBand,\n });\n\n prevSegments = segments;\n }\n\n return contours;\n}\n\n/**\n * Run marching squares across the matrix and calculate the implied counterclockwise ordered line segments from each cell.\n * @see https://en.wikipedia.org/wiki/Marching_squares for an visualization of the different cases\n * @private\n */\nfunction getSegments(\n matrix: ReadonlyArray<ReadonlyArray<number>>,\n threshold: number\n): [Position, Position][] {\n const segments: [Position, Position][] = [];\n\n const dx = matrix[0].length;\n const dy = matrix.length;\n\n for (let y = 0; y < dy - 1; y++) {\n for (let x = 0; x < dx - 1; x++) {\n const tr = matrix[y + 1][x + 1];\n const br = matrix[y][x + 1];\n const bl = matrix[y][x];\n const tl = matrix[y + 1][x];\n\n let grid =\n (tl >= threshold ? 8 : 0) |\n (tr >= threshold ? 4 : 0) |\n (br >= threshold ? 2 : 0) |\n (bl >= threshold ? 1 : 0);\n\n switch (grid) {\n case 0:\n continue;\n case 1:\n segments.push([\n [x + frac(bl, br), y],\n [x, y + frac(bl, tl)],\n ]);\n break;\n case 2:\n segments.push([\n [x + 1, y + frac(br, tr)],\n [x + frac(bl, br), y],\n ]);\n break;\n case 3:\n segments.push([\n [x + 1, y + frac(br, tr)],\n [x, y + frac(bl, tl)],\n ]);\n break;\n case 4:\n segments.push([\n [x + frac(tl, tr), y + 1],\n [x + 1, y + frac(br, tr)],\n ]);\n break;\n case 5: {\n // use the average of the 4 corners to differentiate the saddle case and correctly honor the counter-clockwise winding\n const avg = (tl + tr + br + bl) / 4;\n const above = avg >= threshold;\n\n if (above) {\n segments.push(\n [\n [x + frac(tl, tr), y + 1],\n [x, y + frac(bl, tl)],\n ],\n [\n [x + frac(bl, br), y],\n [x + 1, y + frac(br, tr)],\n ]\n );\n } else {\n segments.push(\n [\n [x + frac(tl, tr), y + 1],\n [x + 1, y + frac(br, tr)],\n ],\n [\n [x + frac(bl, br), y],\n [x, y + frac(bl, tl)],\n ]\n );\n }\n break;\n }\n case 6:\n segments.push([\n [x + frac(tl, tr), y + 1],\n [x + frac(bl, br), y],\n ]);\n break;\n case 7:\n segments.push([\n [x + frac(tl, tr), y + 1],\n [x, y + frac(bl, tl)],\n ]);\n break;\n case 8:\n segments.push([\n [x, y + frac(bl, tl)],\n [x + frac(tl, tr), y + 1],\n ]);\n break;\n case 9:\n segments.push([\n [x + frac(bl, br), y],\n [x + frac(tl, tr), y + 1],\n ]);\n break;\n case 10: {\n const avg = (tl + tr + br + bl) / 4;\n const above = avg >= threshold;\n\n if (above) {\n segments.push(\n [\n [x, y + frac(bl, tl)],\n [x + frac(bl, br), y],\n ],\n [\n [x + 1, y + frac(br, tr)],\n [x + frac(tl, tr), y + 1],\n ]\n );\n } else {\n segments.push(\n [\n [x, y + frac(bl, tl)],\n [x + frac(tl, tr), y + 1],\n ],\n [\n [x + 1, y + frac(br, tr)],\n [x + frac(bl, br), y],\n ]\n );\n }\n break;\n }\n case 11:\n segments.push([\n [x + 1, y + frac(br, tr)],\n [x + frac(tl, tr), y + 1],\n ]);\n break;\n case 12:\n segments.push([\n [x, y + frac(bl, tl)],\n [x + 1, y + frac(br, tr)],\n ]);\n break;\n case 13:\n segments.push([\n [x + frac(bl, br), y],\n [x + 1, y + frac(br, tr)],\n ]);\n break;\n case 14:\n segments.push([\n [x, y + frac(bl, tl)],\n [x + frac(bl, br), y],\n ]);\n break;\n case 15:\n // all above\n continue;\n }\n }\n }\n\n return segments;\n\n // get the linear interpolation fraction of how far z is between z0 and z1\n // See https://github.com/fschutt/marching-squares/blob/master/src/lib.rs\n function frac(z0: number, z1: number): number {\n if (z0 === z1) {\n return 0.5;\n }\n\n let t = (threshold - z0) / (z1 - z0);\n return t > 1 ? 1 : t < 0 ? 0 : t;\n }\n}\n\n/**\n * Create a list of closed rings from the combined segments from breaks[i] and breaks[i-1].\n * @private\n */\nfunction assembleRings(\n segments: Position[][],\n matrix: number[][]\n): Position[][] {\n const dy = matrix.length;\n const dx = matrix[0].length;\n\n const contours: Position[][] = [];\n const result: Position[][] = [];\n\n // Assemble contiguous line segments into contours. These are at least LineStrings,\n // but for features that do not touch the edge of the matrix, they will actually wind up\n // being an entirely closed LinearRing.\n while (segments.length > 0) {\n const contour: Position[] = [...segments.shift()!];\n contours.push(contour);\n\n let found: boolean;\n do {\n found = false;\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n // add the segment's end point to the end of the contour\n if (\n segment[0][0] === contour[contour.length - 1][0] &&\n segment[0][1] === contour[contour.length - 1][1]\n ) {\n found = true;\n contour.push(segment[1]);\n segments.splice(i, 1);\n break;\n }\n // add the segment's start point to the start of the contour\n if (\n segment[1][0] === contour[0][0] &&\n segment[1][1] === contour[0][1]\n ) {\n found = true;\n contour.unshift(segment[0]);\n segments.splice(i, 1);\n break;\n }\n\n // note that because the segments are all guaranteed to be counterclockwise,\n // we do not join segment start to end of the contour or segment end to the start of contour\n }\n\n // if we reach here with found === false, that means that no remaining segments can be\n // added to our contour. We begin again creating the next indepdenent contour.\n } while (found);\n }\n\n // Now we loop again, taking the contours and ensuring that all of them are closed rings.\n // Using segments from two different breaks[], and enforcing closed polygons are the\n // two the major difference between the implementation of @turf/isolines and @turf/isobands.\n while (contours.length > 0) {\n const contour = contours[0];\n\n // if a contour is closed, store it in the results and move to the next contour\n if (\n contour[0][0] === contour[contour.length - 1][0] &&\n contour[0][1] === contour[contour.length - 1][1]\n ) {\n result.push(contour);\n contours.shift();\n continue;\n }\n\n // A contour that is not already closed is guaranteed to touch the bounding box of the matrix.\n // We know that the polygon is ordered counter-clockwise, so we just need to follow\n // the bounding box in a counterclockwise direction, looking for a contour to append.\n // We may need to insert new positions along the corners, but we will eventually close the ring.\n\n const end = contour[contour.length - 1];\n\n let match: number;\n let corner: Position;\n if (end[0] === 0 && end[1] !== 0) {\n // left side\n match = getAdjacentContour(\n contours,\n (contour) => contour[0][0] === 0 && contour[0][1] < end[1], // left side, below end\n (a, b) => b[0][1] - a[0][1] // prefer positions to the top\n );\n corner = [0, 0]; // bottom left corner\n } else if (end[1] === 0 && end[0] !== dx - 1) {\n // bottom side\n match = getAdjacentContour(\n contours,\n (contour) => contour[0][1] === 0 && contour[0][0] > end[0], // bottom side, right of end\n (a, b) => a[0][0] - b[0][0] // prefer positions to the left\n );\n corner = [dx - 1, 0]; // bottom right corner\n } else if (end[0] === dx - 1 && end[1] !== dy - 1) {\n // right side\n match = getAdjacentContour(\n contours,\n (contour) => contour[0][0] === dx - 1 && contour[0][1] > end[1], // right side, above end\n (a, b) => a[0][1] - b[0][1] // prefer positions to the bottom\n );\n corner = [dx - 1, dy - 1]; // top right corner\n } else if (end[1] === dy - 1 && end[0] !== 0) {\n // top side\n match = getAdjacentContour(\n contours,\n (contour) => contour[0][1] === dy - 1 && contour[0][0] < end[0], // top side, left of end\n (a, b) => b[0][0] - a[0][0] // prefer positions to the right\n );\n corner = [0, dy - 1]; // top left corner\n } else {\n throw new Error(\"Contour not closed but is not along an edge\");\n }\n\n if (match === -1) {\n // we did not match a contour on this side, so we add a point in the corner to\n // continue creating our linestring in counterclockwise order. The next\n // run of the loop will continue trying to assemble the current contour on the next side.\n contour.push(corner);\n } else if (match === 0) {\n // We looped back to a contour, and it was ourself. That means that we finished closing the ring.\n // Add the contour to the result and remove it from the contours list to start working\n // on the next contour.\n contour.push([contour[0][0], contour[0][1]]);\n result.push(contour);\n contours.shift();\n } else {\n // We matched a contour, but it is not the one we're currently closing.\n // That means that we get to add its points to our own, and remove that contour entirely.\n // On the next loop, we'll continue trying to close the same contour, but this time from\n // the final Position in contour will be the end of contours[match].\n const matchedContour = contours[match];\n contours.splice(match, 1);\n for (const p of matchedContour) {\n contour.push(p);\n }\n }\n }\n\n // If we get *just* a corner we close it immediately with itself, which results in\n // a 2 point 'ring', which has zero area. We omit these before returning.\n for (let i = 0; i < result.length; i++) {\n if (result[i].length < 4) {\n result.splice(i, 1);\n i--;\n }\n }\n\n return result;\n}\n\n/**\n * Transform isobands of 2D grid to polygons for the map\n *\n * @private\n * @param {Array<any>} contours Contours\n * @param {Array<Array<number>>} matrix Grid Data\n * @param {Object} points Points by Latitude\n * @returns {Array<any>} contours\n */\nfunction rescaleContours(\n contours: GroupedRings[],\n matrix: number[][],\n points: FeatureCollection<Point>\n): GroupedRings[] {\n // get dimensions (on the map) of the original grid\n const gridBbox = bbox(points); // [ minX, minY, maxX, maxY ]\n const originalWidth = gridBbox[2] - gridBbox[0];\n const originalHeigth = gridBbox[3] - gridBbox[1];\n\n // get origin, which is the first point of the last row on the rectangular data on the map\n const x0 = gridBbox[0];\n const y0 = gridBbox[1];\n // get number of cells per side\n const matrixWidth = matrix[0].length - 1;\n const matrixHeight = matrix.length - 1;\n // calculate the scaling factor between matrix and rectangular grid on the map\n const scaleX = originalWidth / matrixWidth;\n const scaleY = originalHeigth / matrixHeight;\n\n // resize and shift each point/line of the isobands\n return contours.map(function (contour) {\n contour.groupedRings = (contour.groupedRings as Position[][][]).map(\n function (lineRingSet) {\n return lineRingSet.map(function (lineRing) {\n return lineRing.map((point: Position) => [\n point[0] * scaleX + x0,\n point[1] * scaleY + y0,\n ]);\n });\n }\n );\n\n return contour;\n });\n}\n\n/* utility functions */\n\n/**\n * Returns an array of coordinates (of LinearRings) in descending order by area\n *\n * @private\n * @param {Array<LineString>} ringsCoords array of closed LineString\n * @returns {Array} array of the input LineString ordered by area\n */\nfunction orderByArea(ringsCoords: Position[][]): Position[][] {\n const ringsWithArea = ringsCoords.map(function (coords) {\n // associate each lineRing with its area\n return { ring: coords, area: area(polygon([coords])) };\n });\n ringsWithArea.sort(function (a, b) {\n // bigger --> smaller\n return b.area - a.area;\n });\n // create a new array of linearRings coordinates ordered by their area\n return ringsWithArea.map(function (x) {\n return x.ring;\n });\n}\n\n/**\n * Returns an array of arrays of coordinates, each representing\n * a set of (coordinates of) nested LinearRings,\n * i.e. the first ring contains all the others\n *\n * @private\n * @param {Array} orderedLinearRings array of coordinates (of LinearRings) in descending order by area\n * @returns {Array<Array>} Array of coordinates of nested LinearRings\n */\nfunction groupNestedRings(orderedLinearRings: Position[][]): Position[][][] {\n // create a list of the (coordinates of) LinearRings\n const lrList = orderedLinearRings.map((lr) => {\n return { lrCoordinates: lr, grouped: false };\n });\n const groupedLinearRingsCoords: Position[][][] = [];\n\n while (!allGrouped(lrList)) {\n for (let i = 0; i < lrList.length; i++) {\n if (!lrList[i].grouped) {\n // create new group starting with the larger not already grouped ring\n const group: Position[][] = [];\n group.push(lrList[i].lrCoordinates);\n lrList[i].grouped = true;\n const outerMostPoly = polygon([lrList[i].lrCoordinates]);\n // group all the rings contained by the outermost ring\n OUTER: for (let j = i + 1; j < lrList.length; j++) {\n if (!lrList[j].grouped) {\n const lrPoly = polygon([lrList[j].lrCoordinates]);\n if (isInside(lrPoly, outerMostPoly)) {\n // we cannot group any linear rings that are contained in hole rings for this group\n for (let k = 1; k < group.length; k++) {\n if (isInside(lrPoly, polygon([group[k]]))) {\n continue OUTER;\n }\n }\n group.push(lrList[j].lrCoordinates);\n lrList[j].grouped = true;\n }\n }\n }\n // insert the new group\n groupedLinearRingsCoords.push(group);\n }\n }\n }\n return groupedLinearRingsCoords;\n}\n\n/**\n * @private\n * @param {Polygon} testPolygon polygon of interest\n * @param {Polygon} targetPolygon polygon you want to compare with\n * @returns {boolean} true if test-Polygon is inside target-Polygon\n */\nfunction isInside(\n testPolygon: Feature<Polygon>,\n targetPolygon: Feature<Polygon>\n): boolean {\n const points = explode(testPolygon);\n for (let i = 0; i < points.features.length; i++) {\n if (!booleanPointInPolygon(points.features[i], targetPolygon)) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * @private\n * @param {Array<Object>} list list of objects which might contain the 'group' attribute\n * @returns {boolean} true if all the objects in the list are marked as grouped\n */\nfunction allGrouped(\n list: { grouped: boolean; lrCoordinates: Position[] }[]\n): boolean {\n for (let i = 0; i < list.length; i++) {\n if (list[i].grouped === false) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Utility function to help close contours into rings\n *\n * @private\n * @param contours The list of contours\n * @param test Return true if a contour is a candidate for being joined\n * @param sort Compare two candidates, returning a positive number will swap the best match from a to b\n * @returns An index of the contour to join, or -1 if no contour was found\n */\nfunction getAdjacentContour(\n contours: Position[][],\n test: (contour: Position[]) => boolean,\n sort: (a: Position[], b: Position[]) => number\n): number {\n let match = -1;\n for (let j = 0; j < contours.length; j++) {\n if (test(contours[j])) {\n if (match === -1 || sort(contours[match], contours[j]) > 0) {\n match = j;\n }\n }\n }\n\n return match;\n}\n\nexport { isobands };\nexport default isobands;\n","import { getCoords, collectionOf } from \"@turf/invariant\";\nimport { featureEach } from \"@turf/meta\";\nimport { isObject } from \"@turf/helpers\";\n\n/**\n * Takes a {@link Point} grid and returns a correspondent matrix {Array<Array<number>>}\n * of the 'property' values\n *\n * @name gridToMatrix\n * @param {FeatureCollection<Point>} grid of points\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled\n * @param {boolean} [options.flip=false] returns the matrix upside-down\n * @param {boolean} [options.flags=false] flags, adding a `matrixPosition` array field ([row, column]) to its properties,\n * the grid points with coordinates on the matrix\n * @returns {Array<Array<number>>} matrix of property values\n * @example\n * var extent = [-70.823364, -33.553984, -70.473175, -33.302986];\n * var cellSize = 3;\n * var grid = turf.pointGrid(extent, cellSize);\n * // add a random property to each point between 0 and 60\n * for (var i = 0; i < grid.features.length; i++) {\n * grid.features[i].properties.elevation = (Math.random() * 60);\n * }\n * gridToMatrix(grid);\n * //= [\n * [ 1, 13, 10, 9, 10, 13, 18],\n * [34, 8, 5, 4, 5, 8, 13],\n * [10, 5, 2, 1, 2, 5, 4],\n * [ 0, 4, 56, 19, 1, 4, 9],\n * [10, 5, 2, 1, 2, 5, 10],\n * [57, 8, 5, 4, 5, 0, 57],\n * [ 3, 13, 10, 9, 5, 13, 18],\n * [18, 13, 10, 9, 78, 13, 18]\n * ]\n */\nfunction gridToMatrix(grid, options) {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error(\"options is invalid\");\n var zProperty = options.zProperty || \"elevation\";\n var flip = options.flip;\n var flags = options.flags;\n\n // validation\n collectionOf(grid, \"Point\", \"input must contain Points\");\n\n var pointsMatrix = sortPointsByLatLng(grid, flip);\n\n var matrix = [];\n // create property matrix from sorted points\n // looping order matters here\n for (var r = 0; r < pointsMatrix.length; r++) {\n var pointRow = pointsMatrix[r];\n var row = [];\n for (var c = 0; c < pointRow.length; c++) {\n var point = pointRow[c];\n // Check if zProperty exist\n if (point.properties[zProperty]) row.push(point.properties[zProperty]);\n else row.push(0);\n // add flags\n if (flags === true) point.properties.matrixPosition = [r, c];\n }\n matrix.push(row);\n }\n\n return matrix;\n}\n\n/**\n * Sorts points by latitude and longitude, creating a 2-dimensional array of points\n *\n * @private\n * @param {FeatureCollection<Point>} points GeoJSON Point features\n * @param {boolean} [flip=false] returns the matrix upside-down\n * @returns {Array<Array<Point>>} points ordered by latitude and longitude\n */\nfunction sortPointsByLatLng(points, flip) {\n var pointsByLatitude = {};\n\n // divide points by rows with the same latitude\n featureEach(points, function (point) {\n var lat = getCoords(point)[1];\n if (!pointsByLatitude[lat]) pointsByLatitude[lat] = [];\n pointsByLatitude[lat].push(point);\n });\n\n // sort points (with the same latitude) by longitude\n var orderedRowsByLatitude = Object.keys(pointsByLatitude).map(function (lat) {\n var row = pointsByLatitude[lat];\n var rowOrderedByLongitude = row.sort(function (a, b) {\n return getCoords(a)[0] - getCoords(b)[0];\n });\n return rowOrderedByLongitude;\n });\n\n // sort rows (of points with the same latitude) by latitude\n var pointMatrix = orderedRowsByLatitude.sort(function (a, b) {\n if (flip) return getCoords(a[0])[1] - getCoords(b[0])[1];\n else return getCoords(b[0])[1] - getCoords(a[0])[1];\n });\n\n return pointMatrix;\n}\n\nexport { gridToMatrix };\nexport default gridToMatrix;\n"],"mappings":"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","names":["collectionOf","isObject","isObject","collectionOf","contour"]}
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turf/isobands",
|
|
3
|
-
"version": "7.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "7.3.1",
|
|
4
|
+
"description": "Takes a grid of values (GeoJSON format) and a set of threshold ranges. It outputs polygons that group areas within those ranges, effectively creating filled contour isobands.",
|
|
5
5
|
"author": "Turf Authors",
|
|
6
6
|
"contributors": [
|
|
7
|
-
"Stefano Borghi <@stebogit>"
|
|
7
|
+
"Stefano Borghi <@stebogit>",
|
|
8
|
+
"Matt Fedderly <@mfedderly>"
|
|
8
9
|
],
|
|
9
10
|
"license": "MIT",
|
|
10
11
|
"bugs": {
|
|
@@ -53,37 +54,35 @@
|
|
|
53
54
|
"bench": "tsx bench.ts",
|
|
54
55
|
"build": "tsup --config ../../tsup.config.ts",
|
|
55
56
|
"docs": "tsx ../../scripts/generate-readmes.ts",
|
|
56
|
-
"test": "
|
|
57
|
+
"test": "pnpm run /test:.*/",
|
|
57
58
|
"test:tape": "tsx test.ts"
|
|
58
59
|
},
|
|
59
60
|
"devDependencies": {
|
|
60
|
-
"@turf/envelope": "
|
|
61
|
-
"@turf/point-grid": "
|
|
62
|
-
"@turf/random": "
|
|
63
|
-
"@turf/rhumb-destination": "
|
|
64
|
-
"@turf/truncate": "
|
|
61
|
+
"@turf/envelope": "7.3.1",
|
|
62
|
+
"@turf/point-grid": "7.3.1",
|
|
63
|
+
"@turf/random": "7.3.1",
|
|
64
|
+
"@turf/rhumb-destination": "7.3.1",
|
|
65
|
+
"@turf/truncate": "7.3.1",
|
|
65
66
|
"@types/benchmark": "^2.1.5",
|
|
66
|
-
"@types/tape": "^
|
|
67
|
+
"@types/tape": "^5.8.1",
|
|
67
68
|
"benchmark": "^2.1.4",
|
|
68
69
|
"load-json-file": "^7.0.1",
|
|
69
|
-
"npm-run-all": "^4.1.5",
|
|
70
70
|
"tape": "^5.9.0",
|
|
71
|
-
"tsup": "^8.
|
|
72
|
-
"tsx": "^4.19.
|
|
73
|
-
"typescript": "^5.
|
|
74
|
-
"write-json-file": "^
|
|
71
|
+
"tsup": "^8.4.0",
|
|
72
|
+
"tsx": "^4.19.4",
|
|
73
|
+
"typescript": "^5.8.3",
|
|
74
|
+
"write-json-file": "^6.0.0"
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
|
-
"@turf/area": "
|
|
78
|
-
"@turf/bbox": "
|
|
79
|
-
"@turf/boolean-point-in-polygon": "
|
|
80
|
-
"@turf/explode": "
|
|
81
|
-
"@turf/helpers": "
|
|
82
|
-
"@turf/invariant": "
|
|
83
|
-
"@turf/meta": "
|
|
77
|
+
"@turf/area": "7.3.1",
|
|
78
|
+
"@turf/bbox": "7.3.1",
|
|
79
|
+
"@turf/boolean-point-in-polygon": "7.3.1",
|
|
80
|
+
"@turf/explode": "7.3.1",
|
|
81
|
+
"@turf/helpers": "7.3.1",
|
|
82
|
+
"@turf/invariant": "7.3.1",
|
|
83
|
+
"@turf/meta": "7.3.1",
|
|
84
84
|
"@types/geojson": "^7946.0.10",
|
|
85
|
-
"marchingsquares": "^1.3.3",
|
|
86
85
|
"tslib": "^2.8.1"
|
|
87
86
|
},
|
|
88
|
-
"gitHead": "
|
|
87
|
+
"gitHead": "b7f1b4eafb760431e03955499d8eac9489438219"
|
|
89
88
|
}
|