@turf/isobands 7.1.0 → 7.3.0
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 +323 -29
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +2 -2
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +323 -29
- package/dist/esm/index.js.map +1 -1
- package/package.json +24 -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
|
@@ -34,8 +34,7 @@ var _meta = require('@turf/meta');
|
|
|
34
34
|
|
|
35
35
|
function gridToMatrix(grid, options) {
|
|
36
36
|
options = options || {};
|
|
37
|
-
if (!_helpers.isObject.call(void 0, options))
|
|
38
|
-
throw new Error("options is invalid");
|
|
37
|
+
if (!_helpers.isObject.call(void 0, options)) throw new Error("options is invalid");
|
|
39
38
|
var zProperty = options.zProperty || "elevation";
|
|
40
39
|
var flip = options.flip;
|
|
41
40
|
var flags = options.flags;
|
|
@@ -47,12 +46,9 @@ function gridToMatrix(grid, options) {
|
|
|
47
46
|
var row = [];
|
|
48
47
|
for (var c = 0; c < pointRow.length; c++) {
|
|
49
48
|
var point = pointRow[c];
|
|
50
|
-
if (point.properties[zProperty])
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
row.push(0);
|
|
54
|
-
if (flags === true)
|
|
55
|
-
point.properties.matrixPosition = [r, c];
|
|
49
|
+
if (point.properties[zProperty]) row.push(point.properties[zProperty]);
|
|
50
|
+
else row.push(0);
|
|
51
|
+
if (flags === true) point.properties.matrixPosition = [r, c];
|
|
56
52
|
}
|
|
57
53
|
matrix.push(row);
|
|
58
54
|
}
|
|
@@ -62,8 +58,7 @@ function sortPointsByLatLng(points, flip) {
|
|
|
62
58
|
var pointsByLatitude = {};
|
|
63
59
|
_meta.featureEach.call(void 0, points, function(point) {
|
|
64
60
|
var lat = _invariant.getCoords.call(void 0, point)[1];
|
|
65
|
-
if (!pointsByLatitude[lat])
|
|
66
|
-
pointsByLatitude[lat] = [];
|
|
61
|
+
if (!pointsByLatitude[lat]) pointsByLatitude[lat] = [];
|
|
67
62
|
pointsByLatitude[lat].push(point);
|
|
68
63
|
});
|
|
69
64
|
var orderedRowsByLatitude = Object.keys(pointsByLatitude).map(function(lat) {
|
|
@@ -74,33 +69,36 @@ function sortPointsByLatLng(points, flip) {
|
|
|
74
69
|
return rowOrderedByLongitude;
|
|
75
70
|
});
|
|
76
71
|
var pointMatrix = orderedRowsByLatitude.sort(function(a, b) {
|
|
77
|
-
if (flip)
|
|
78
|
-
|
|
79
|
-
else
|
|
80
|
-
return _invariant.getCoords.call(void 0, b[0])[1] - _invariant.getCoords.call(void 0, a[0])[1];
|
|
72
|
+
if (flip) return _invariant.getCoords.call(void 0, a[0])[1] - _invariant.getCoords.call(void 0, b[0])[1];
|
|
73
|
+
else return _invariant.getCoords.call(void 0, b[0])[1] - _invariant.getCoords.call(void 0, a[0])[1];
|
|
81
74
|
});
|
|
82
75
|
return pointMatrix;
|
|
83
76
|
}
|
|
84
77
|
|
|
85
78
|
// index.ts
|
|
86
|
-
var _marchingsquares = require('marchingsquares');
|
|
87
79
|
function isobands(pointGrid, breaks, options) {
|
|
88
80
|
options = options || {};
|
|
89
|
-
if (!_helpers.isObject.call(void 0, options))
|
|
90
|
-
throw new Error("options is invalid");
|
|
81
|
+
if (!_helpers.isObject.call(void 0, options)) throw new Error("options is invalid");
|
|
91
82
|
const zProperty = options.zProperty || "elevation";
|
|
92
83
|
const commonProperties = options.commonProperties || {};
|
|
93
84
|
const breaksProperties = options.breaksProperties || [];
|
|
94
85
|
_invariant.collectionOf.call(void 0, pointGrid, "Point", "Input must contain Points");
|
|
95
|
-
if (!breaks)
|
|
96
|
-
|
|
97
|
-
if (!Array.isArray(breaks))
|
|
98
|
-
throw new Error("breaks is not an Array");
|
|
86
|
+
if (!breaks) throw new Error("breaks is required");
|
|
87
|
+
if (!Array.isArray(breaks)) throw new Error("breaks is not an Array");
|
|
99
88
|
if (!_helpers.isObject.call(void 0, commonProperties))
|
|
100
89
|
throw new Error("commonProperties is not an Object");
|
|
101
90
|
if (!Array.isArray(breaksProperties))
|
|
102
91
|
throw new Error("breaksProperties is not an Array");
|
|
103
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
|
+
}
|
|
104
102
|
let contours = createContourLines(matrix, breaks, zProperty);
|
|
105
103
|
contours = rescaleContours(contours, matrix, pointGrid);
|
|
106
104
|
const multipolygons = contours.map((contour, index) => {
|
|
@@ -119,19 +117,299 @@ function isobands(pointGrid, breaks, options) {
|
|
|
119
117
|
}
|
|
120
118
|
function createContourLines(matrix, breaks, property) {
|
|
121
119
|
const contours = [];
|
|
120
|
+
let prevSegments;
|
|
122
121
|
for (let i = 1; i < breaks.length; i++) {
|
|
123
|
-
|
|
122
|
+
if (i === 1) {
|
|
123
|
+
prevSegments = getSegments(matrix, +breaks[0]);
|
|
124
|
+
}
|
|
124
125
|
const upperBand = +breaks[i];
|
|
125
|
-
const
|
|
126
|
-
const
|
|
127
|
-
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) {
|
|
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
|
+
}
|
|
128
150
|
contours.push({
|
|
129
|
-
groupedRings,
|
|
151
|
+
groupedRings: polygons,
|
|
130
152
|
[property]: lowerBand + "-" + upperBand
|
|
131
153
|
});
|
|
154
|
+
prevSegments = segments;
|
|
132
155
|
}
|
|
133
156
|
return contours;
|
|
134
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
|
+
}
|
|
135
413
|
function rescaleContours(contours, matrix, points) {
|
|
136
414
|
const gridBbox = _bbox.bbox.call(void 0, points);
|
|
137
415
|
const originalWidth = gridBbox[2] - gridBbox[0];
|
|
@@ -179,10 +457,15 @@ function groupNestedRings(orderedLinearRings) {
|
|
|
179
457
|
group.push(lrList[i].lrCoordinates);
|
|
180
458
|
lrList[i].grouped = true;
|
|
181
459
|
const outerMostPoly = _helpers.polygon.call(void 0, [lrList[i].lrCoordinates]);
|
|
182
|
-
for (let j = i + 1; j < lrList.length; j++) {
|
|
460
|
+
OUTER: for (let j = i + 1; j < lrList.length; j++) {
|
|
183
461
|
if (!lrList[j].grouped) {
|
|
184
462
|
const lrPoly = _helpers.polygon.call(void 0, [lrList[j].lrCoordinates]);
|
|
185
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
|
+
}
|
|
186
469
|
group.push(lrList[j].lrCoordinates);
|
|
187
470
|
lrList[j].grouped = true;
|
|
188
471
|
}
|
|
@@ -211,9 +494,20 @@ function allGrouped(list) {
|
|
|
211
494
|
}
|
|
212
495
|
return true;
|
|
213
496
|
}
|
|
214
|
-
|
|
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;
|
|
215
509
|
|
|
216
510
|
|
|
217
511
|
|
|
218
|
-
exports.default =
|
|
512
|
+
exports.default = index_default; exports.isobands = isobands;
|
|
219
513
|
//# sourceMappingURL=index.cjs.map
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../index.ts","../../lib/grid-to-matrix.js"],"names":["collectionOf","isObject"],"mappings":"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","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 * @name isobands\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 or all below the threshold.\n // If everything is below, we shold add the entire bounding box as a polygon.\n // see https://github.com/Turfjs/turf/issues/1797\n if (polygons.length === 0 && matrix[0][0] < upperBand) {\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 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
|
@@ -4,8 +4,8 @@ import { FeatureCollection, Point, GeoJsonProperties, MultiPolygon } from 'geojs
|
|
|
4
4
|
* Takes a square or rectangular grid {@link FeatureCollection} of {@link Point} features with z-values and an array of
|
|
5
5
|
* value breaks and generates filled contour isobands.
|
|
6
6
|
*
|
|
7
|
-
* @
|
|
8
|
-
* @param {FeatureCollection<Point>} pointGrid input points - must be square or rectangular
|
|
7
|
+
* @function
|
|
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
|
@@ -4,8 +4,8 @@ import { FeatureCollection, Point, GeoJsonProperties, MultiPolygon } from 'geojs
|
|
|
4
4
|
* Takes a square or rectangular grid {@link FeatureCollection} of {@link Point} features with z-values and an array of
|
|
5
5
|
* value breaks and generates filled contour isobands.
|
|
6
6
|
*
|
|
7
|
-
* @
|
|
8
|
-
* @param {FeatureCollection<Point>} pointGrid input points - must be square or rectangular
|
|
7
|
+
* @function
|
|
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
|
@@ -34,8 +34,7 @@ import { featureEach } from "@turf/meta";
|
|
|
34
34
|
import { isObject } from "@turf/helpers";
|
|
35
35
|
function gridToMatrix(grid, options) {
|
|
36
36
|
options = options || {};
|
|
37
|
-
if (!isObject(options))
|
|
38
|
-
throw new Error("options is invalid");
|
|
37
|
+
if (!isObject(options)) throw new Error("options is invalid");
|
|
39
38
|
var zProperty = options.zProperty || "elevation";
|
|
40
39
|
var flip = options.flip;
|
|
41
40
|
var flags = options.flags;
|
|
@@ -47,12 +46,9 @@ function gridToMatrix(grid, options) {
|
|
|
47
46
|
var row = [];
|
|
48
47
|
for (var c = 0; c < pointRow.length; c++) {
|
|
49
48
|
var point = pointRow[c];
|
|
50
|
-
if (point.properties[zProperty])
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
row.push(0);
|
|
54
|
-
if (flags === true)
|
|
55
|
-
point.properties.matrixPosition = [r, c];
|
|
49
|
+
if (point.properties[zProperty]) row.push(point.properties[zProperty]);
|
|
50
|
+
else row.push(0);
|
|
51
|
+
if (flags === true) point.properties.matrixPosition = [r, c];
|
|
56
52
|
}
|
|
57
53
|
matrix.push(row);
|
|
58
54
|
}
|
|
@@ -62,8 +58,7 @@ function sortPointsByLatLng(points, flip) {
|
|
|
62
58
|
var pointsByLatitude = {};
|
|
63
59
|
featureEach(points, function(point) {
|
|
64
60
|
var lat = getCoords(point)[1];
|
|
65
|
-
if (!pointsByLatitude[lat])
|
|
66
|
-
pointsByLatitude[lat] = [];
|
|
61
|
+
if (!pointsByLatitude[lat]) pointsByLatitude[lat] = [];
|
|
67
62
|
pointsByLatitude[lat].push(point);
|
|
68
63
|
});
|
|
69
64
|
var orderedRowsByLatitude = Object.keys(pointsByLatitude).map(function(lat) {
|
|
@@ -74,33 +69,36 @@ function sortPointsByLatLng(points, flip) {
|
|
|
74
69
|
return rowOrderedByLongitude;
|
|
75
70
|
});
|
|
76
71
|
var pointMatrix = orderedRowsByLatitude.sort(function(a, b) {
|
|
77
|
-
if (flip)
|
|
78
|
-
|
|
79
|
-
else
|
|
80
|
-
return getCoords(b[0])[1] - getCoords(a[0])[1];
|
|
72
|
+
if (flip) return getCoords(a[0])[1] - getCoords(b[0])[1];
|
|
73
|
+
else return getCoords(b[0])[1] - getCoords(a[0])[1];
|
|
81
74
|
});
|
|
82
75
|
return pointMatrix;
|
|
83
76
|
}
|
|
84
77
|
|
|
85
78
|
// index.ts
|
|
86
|
-
import { isoBands } from "marchingsquares";
|
|
87
79
|
function isobands(pointGrid, breaks, options) {
|
|
88
80
|
options = options || {};
|
|
89
|
-
if (!isObject2(options))
|
|
90
|
-
throw new Error("options is invalid");
|
|
81
|
+
if (!isObject2(options)) throw new Error("options is invalid");
|
|
91
82
|
const zProperty = options.zProperty || "elevation";
|
|
92
83
|
const commonProperties = options.commonProperties || {};
|
|
93
84
|
const breaksProperties = options.breaksProperties || [];
|
|
94
85
|
collectionOf2(pointGrid, "Point", "Input must contain Points");
|
|
95
|
-
if (!breaks)
|
|
96
|
-
|
|
97
|
-
if (!Array.isArray(breaks))
|
|
98
|
-
throw new Error("breaks is not an Array");
|
|
86
|
+
if (!breaks) throw new Error("breaks is required");
|
|
87
|
+
if (!Array.isArray(breaks)) throw new Error("breaks is not an Array");
|
|
99
88
|
if (!isObject2(commonProperties))
|
|
100
89
|
throw new Error("commonProperties is not an Object");
|
|
101
90
|
if (!Array.isArray(breaksProperties))
|
|
102
91
|
throw new Error("breaksProperties is not an Array");
|
|
103
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
|
+
}
|
|
104
102
|
let contours = createContourLines(matrix, breaks, zProperty);
|
|
105
103
|
contours = rescaleContours(contours, matrix, pointGrid);
|
|
106
104
|
const multipolygons = contours.map((contour, index) => {
|
|
@@ -119,19 +117,299 @@ function isobands(pointGrid, breaks, options) {
|
|
|
119
117
|
}
|
|
120
118
|
function createContourLines(matrix, breaks, property) {
|
|
121
119
|
const contours = [];
|
|
120
|
+
let prevSegments;
|
|
122
121
|
for (let i = 1; i < breaks.length; i++) {
|
|
123
|
-
|
|
122
|
+
if (i === 1) {
|
|
123
|
+
prevSegments = getSegments(matrix, +breaks[0]);
|
|
124
|
+
}
|
|
124
125
|
const upperBand = +breaks[i];
|
|
125
|
-
const
|
|
126
|
-
const
|
|
127
|
-
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) {
|
|
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
|
+
}
|
|
128
150
|
contours.push({
|
|
129
|
-
groupedRings,
|
|
151
|
+
groupedRings: polygons,
|
|
130
152
|
[property]: lowerBand + "-" + upperBand
|
|
131
153
|
});
|
|
154
|
+
prevSegments = segments;
|
|
132
155
|
}
|
|
133
156
|
return contours;
|
|
134
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
|
+
}
|
|
135
413
|
function rescaleContours(contours, matrix, points) {
|
|
136
414
|
const gridBbox = bbox(points);
|
|
137
415
|
const originalWidth = gridBbox[2] - gridBbox[0];
|
|
@@ -179,10 +457,15 @@ function groupNestedRings(orderedLinearRings) {
|
|
|
179
457
|
group.push(lrList[i].lrCoordinates);
|
|
180
458
|
lrList[i].grouped = true;
|
|
181
459
|
const outerMostPoly = polygon([lrList[i].lrCoordinates]);
|
|
182
|
-
for (let j = i + 1; j < lrList.length; j++) {
|
|
460
|
+
OUTER: for (let j = i + 1; j < lrList.length; j++) {
|
|
183
461
|
if (!lrList[j].grouped) {
|
|
184
462
|
const lrPoly = polygon([lrList[j].lrCoordinates]);
|
|
185
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
|
+
}
|
|
186
469
|
group.push(lrList[j].lrCoordinates);
|
|
187
470
|
lrList[j].grouped = true;
|
|
188
471
|
}
|
|
@@ -211,9 +494,20 @@ function allGrouped(list) {
|
|
|
211
494
|
}
|
|
212
495
|
return true;
|
|
213
496
|
}
|
|
214
|
-
|
|
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;
|
|
215
509
|
export {
|
|
216
|
-
|
|
510
|
+
index_default as default,
|
|
217
511
|
isobands
|
|
218
512
|
};
|
|
219
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 * @name isobands\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 or all below the threshold.\n // If everything is below, we shold add the entire bounding box as a polygon.\n // see https://github.com/Turfjs/turf/issues/1797\n if (polygons.length === 0 && matrix[0][0] < upperBand) {\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 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.0",
|
|
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": {
|
|
@@ -57,33 +58,32 @@
|
|
|
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.0",
|
|
62
|
+
"@turf/point-grid": "7.3.0",
|
|
63
|
+
"@turf/random": "7.3.0",
|
|
64
|
+
"@turf/rhumb-destination": "7.3.0",
|
|
65
|
+
"@turf/truncate": "7.3.0",
|
|
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
70
|
"npm-run-all": "^4.1.5",
|
|
70
|
-
"tape": "^5.
|
|
71
|
-
"tsup": "^8.0
|
|
72
|
-
"tsx": "^4.
|
|
73
|
-
"typescript": "^5.
|
|
74
|
-
"write-json-file": "^
|
|
71
|
+
"tape": "^5.9.0",
|
|
72
|
+
"tsup": "^8.4.0",
|
|
73
|
+
"tsx": "^4.19.4",
|
|
74
|
+
"typescript": "^5.8.3",
|
|
75
|
+
"write-json-file": "^6.0.0"
|
|
75
76
|
},
|
|
76
77
|
"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": "
|
|
78
|
+
"@turf/area": "7.3.0",
|
|
79
|
+
"@turf/bbox": "7.3.0",
|
|
80
|
+
"@turf/boolean-point-in-polygon": "7.3.0",
|
|
81
|
+
"@turf/explode": "7.3.0",
|
|
82
|
+
"@turf/helpers": "7.3.0",
|
|
83
|
+
"@turf/invariant": "7.3.0",
|
|
84
|
+
"@turf/meta": "7.3.0",
|
|
84
85
|
"@types/geojson": "^7946.0.10",
|
|
85
|
-
"
|
|
86
|
-
"tslib": "^2.6.2"
|
|
86
|
+
"tslib": "^2.8.1"
|
|
87
87
|
},
|
|
88
|
-
"gitHead": "
|
|
88
|
+
"gitHead": "9f58a103e8f9a587ab640307ed03ba5233913ddd"
|
|
89
89
|
}
|