@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 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
 
@@ -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
- row.push(point.properties[zProperty]);
52
- else
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
- return _invariant.getCoords.call(void 0, a[0])[1] - _invariant.getCoords.call(void 0, b[0])[1];
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
- throw new Error("breaks is required");
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
- const lowerBand = +breaks[i - 1];
122
+ if (i === 1) {
123
+ prevSegments = getSegments(matrix, +breaks[0]);
124
+ }
124
125
  const upperBand = +breaks[i];
125
- const isobandsCoords = _marchingsquares.isoBands.call(void 0, matrix, lowerBand, upperBand - lowerBand);
126
- const nestedRings = orderByArea(isobandsCoords);
127
- const groupedRings = groupNestedRings(nestedRings);
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
- var turf_isobands_default = isobands;
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 = turf_isobands_default; exports.isobands = isobands;
512
+ exports.default = index_default; exports.isobands = isobands;
219
513
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../index.ts","../../lib/grid-to-matrix.js"],"names":["collectionOf","isObject"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,SAAS,YAAY;AACrB,SAAS,YAAY;AACrB,SAAS,6BAA6B;AACtC,SAAS,eAAe;AACxB,SAAS,gBAAAA,qBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAAC;AAAA,OACK;;;ACVP,SAAS,WAAW,oBAAoB;AACxC,SAAS,mBAAmB;AAC5B,SAAS,gBAAgB;AAkCzB,SAAS,aAAa,MAAM,SAAS;AAEnC,YAAU,WAAW,CAAC;AACtB,MAAI,CAAC,SAAS,OAAO;AAAG,UAAM,IAAI,MAAM,oBAAoB;AAC5D,MAAI,YAAY,QAAQ,aAAa;AACrC,MAAI,OAAO,QAAQ;AACnB,MAAI,QAAQ,QAAQ;AAGpB,eAAa,MAAM,SAAS,2BAA2B;AAEvD,MAAI,eAAe,mBAAmB,MAAM,IAAI;AAEhD,MAAI,SAAS,CAAC;AAGd,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,QAAI,WAAW,aAAa,CAAC;AAC7B,QAAI,MAAM,CAAC;AACX,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAI,QAAQ,SAAS,CAAC;AAEtB,UAAI,MAAM,WAAW,SAAS;AAAG,YAAI,KAAK,MAAM,WAAW,SAAS,CAAC;AAAA;AAChE,YAAI,KAAK,CAAC;AAEf,UAAI,UAAU;AAAM,cAAM,WAAW,iBAAiB,CAAC,GAAG,CAAC;AAAA,IAC7D;AACA,WAAO,KAAK,GAAG;AAAA,EACjB;AAEA,SAAO;AACT;AAUA,SAAS,mBAAmB,QAAQ,MAAM;AACxC,MAAI,mBAAmB,CAAC;AAGxB,cAAY,QAAQ,SAAU,OAAO;AACnC,QAAI,MAAM,UAAU,KAAK,EAAE,CAAC;AAC5B,QAAI,CAAC,iBAAiB,GAAG;AAAG,uBAAiB,GAAG,IAAI,CAAC;AACrD,qBAAiB,GAAG,EAAE,KAAK,KAAK;AAAA,EAClC,CAAC;AAGD,MAAI,wBAAwB,OAAO,KAAK,gBAAgB,EAAE,IAAI,SAAU,KAAK;AAC3E,QAAI,MAAM,iBAAiB,GAAG;AAC9B,QAAI,wBAAwB,IAAI,KAAK,SAAU,GAAG,GAAG;AACnD,aAAO,UAAU,CAAC,EAAE,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC;AAAA,IACzC,CAAC;AACD,WAAO;AAAA,EACT,CAAC;AAGD,MAAI,cAAc,sBAAsB,KAAK,SAAU,GAAG,GAAG;AAC3D,QAAI;AAAM,aAAO,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC;AAAA;AAClD,aAAO,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC;AAAA,EACpD,CAAC;AAED,SAAO;AACT;;;ADhFA,SAAS,gBAAgB;AAsBzB,SAAS,SACP,WACA,QACA,SAKiC;AAEjC,YAAU,WAAW,CAAC;AACtB,MAAI,CAACA,UAAS,OAAO;AAAG,UAAM,IAAI,MAAM,oBAAoB;AAC5D,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,mBAAmB,QAAQ,oBAAoB,CAAC;AACtD,QAAM,mBAAmB,QAAQ,oBAAoB,CAAC;AAGtD,EAAAD,cAAa,WAAW,SAAS,2BAA2B;AAC5D,MAAI,CAAC;AAAQ,UAAM,IAAI,MAAM,oBAAoB;AACjD,MAAI,CAAC,MAAM,QAAQ,MAAM;AAAG,UAAM,IAAI,MAAM,wBAAwB;AACpE,MAAI,CAACC,UAAS,gBAAgB;AAC5B,UAAM,IAAI,MAAM,mCAAmC;AACrD,MAAI,CAAC,MAAM,QAAQ,gBAAgB;AACjC,UAAM,IAAI,MAAM,kCAAkC;AAGpD,QAAM,SAAS,aAAa,WAAW,EAAE,WAAsB,MAAM,KAAK,CAAC;AAC3E,MAAI,WAAW,mBAAmB,QAAQ,QAAQ,SAAS;AAC3D,aAAW,gBAAgB,UAAU,QAAQ,SAAS;AAEtD,QAAM,gBAAgB,SAAS,IAAI,CAAC,SAAS,UAAU;AACrD,QAAI,iBAAiB,KAAK,KAAK,CAACA,UAAS,iBAAiB,KAAK,CAAC,GAAG;AACjE,YAAM,IAAI,MAAM,iDAAiD;AAAA,IACnE;AAEA,UAAM,oBAAoB,kCACrB,mBACA,iBAAiB,KAAK;AAG3B,sBAAkB,SAAS,IAAK,QAA2B,SAAS;AAEpE,UAAM,SAAS;AAAA,MACb,QAAQ;AAAA,MACR;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AAED,SAAO,kBAAkB,aAAa;AACxC;AAeA,SAAS,mBACP,QACA,QACA,UACgB;AAChB,QAAM,WAA2B,CAAC;AAClC,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,YAAY,CAAC,OAAO,IAAI,CAAC;AAC/B,UAAM,YAAY,CAAC,OAAO,CAAC;AAE3B,UAAM,iBAAiB,SAAS,QAAQ,WAAW,YAAY,SAAS;AAKxE,UAAM,cAAc,YAAY,cAAc;AAC9C,UAAM,eAAe,iBAAiB,WAAW;AAEjD,aAAS,KAAK;AAAA,MACZ;AAAA,MACA,CAAC,QAAQ,GAAG,YAAY,MAAM;AAAA,IAChC,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAWA,SAAS,gBACP,UACA,QACA,QACgB;AAEhB,QAAM,WAAW,KAAK,MAAM;AAC5B,QAAM,gBAAgB,SAAS,CAAC,IAAI,SAAS,CAAC;AAC9C,QAAM,iBAAiB,SAAS,CAAC,IAAI,SAAS,CAAC;AAG/C,QAAM,KAAK,SAAS,CAAC;AACrB,QAAM,KAAK,SAAS,CAAC;AAErB,QAAM,cAAc,OAAO,CAAC,EAAE,SAAS;AACvC,QAAM,eAAe,OAAO,SAAS;AAErC,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,iBAAiB;AAGhC,SAAO,SAAS,IAAI,SAAU,SAAS;AACrC,YAAQ,eAAgB,QAAQ,aAAgC;AAAA,MAC9D,SAAU,aAAa;AACrB,eAAO,YAAY,IAAI,SAAU,UAAU;AACzC,iBAAO,SAAS,IAAI,CAAC,UAAoB;AAAA,YACvC,MAAM,CAAC,IAAI,SAAS;AAAA,YACpB,MAAM,CAAC,IAAI,SAAS;AAAA,UACtB,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AACH;AAWA,SAAS,YAAY,aAAyC;AAC5D,QAAM,gBAAgB,YAAY,IAAI,SAAU,QAAQ;AAEtD,WAAO,EAAE,MAAM,QAAQ,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE;AAAA,EACvD,CAAC;AACD,gBAAc,KAAK,SAAU,GAAG,GAAG;AAEjC,WAAO,EAAE,OAAO,EAAE;AAAA,EACpB,CAAC;AAED,SAAO,cAAc,IAAI,SAAU,GAAG;AACpC,WAAO,EAAE;AAAA,EACX,CAAC;AACH;AAWA,SAAS,iBAAiB,oBAAkD;AAE1E,QAAM,SAAS,mBAAmB,IAAI,CAAC,OAAO;AAC5C,WAAO,EAAE,eAAe,IAAI,SAAS,MAAM;AAAA,EAC7C,CAAC;AACD,QAAM,2BAA2C,CAAC;AAElD,SAAO,CAAC,WAAW,MAAM,GAAG;AAC1B,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAI,CAAC,OAAO,CAAC,EAAE,SAAS;AAEtB,cAAM,QAAsB,CAAC;AAC7B,cAAM,KAAK,OAAO,CAAC,EAAE,aAAa;AAClC,eAAO,CAAC,EAAE,UAAU;AACpB,cAAM,gBAAgB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;AAEvD,iBAAS,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AAC1C,cAAI,CAAC,OAAO,CAAC,EAAE,SAAS;AACtB,kBAAM,SAAS,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;AAChD,gBAAI,SAAS,QAAQ,aAAa,GAAG;AACnC,oBAAM,KAAK,OAAO,CAAC,EAAE,aAAa;AAClC,qBAAO,CAAC,EAAE,UAAU;AAAA,YACtB;AAAA,UACF;AAAA,QACF;AAEA,iCAAyB,KAAK,KAAK;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAQA,SAAS,SACP,aACA,eACS;AACT,QAAM,SAAS,QAAQ,WAAW;AAClC,WAAS,IAAI,GAAG,IAAI,OAAO,SAAS,QAAQ,KAAK;AAC/C,QAAI,CAAC,sBAAsB,OAAO,SAAS,CAAC,GAAG,aAAa,GAAG;AAC7D,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAOA,SAAS,WACP,MACS;AACT,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,KAAK,CAAC,EAAE,YAAY,OAAO;AAC7B,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAGA,IAAO,wBAAQ","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"]}
@@ -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
- * @name isobands
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
@@ -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
- * @name isobands
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
- row.push(point.properties[zProperty]);
52
- else
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
- return getCoords(a[0])[1] - getCoords(b[0])[1];
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
- throw new Error("breaks is required");
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
- const lowerBand = +breaks[i - 1];
122
+ if (i === 1) {
123
+ prevSegments = getSegments(matrix, +breaks[0]);
124
+ }
124
125
  const upperBand = +breaks[i];
125
- const isobandsCoords = isoBands(matrix, lowerBand, upperBand - lowerBand);
126
- const nestedRings = orderByArea(isobandsCoords);
127
- const groupedRings = groupNestedRings(nestedRings);
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
- var turf_isobands_default = isobands;
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
- turf_isobands_default as default,
510
+ index_default as default,
217
511
  isobands
218
512
  };
219
513
  //# sourceMappingURL=index.js.map
@@ -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":";;;;;;;;;;;;;;;;;;AAAA,SAAS,YAAY;AACrB,SAAS,YAAY;AACrB,SAAS,6BAA6B;AACtC,SAAS,eAAe;AACxB,SAAS,gBAAAA,qBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAAC;AAAA,OACK;;;ACVP,SAAS,WAAW,oBAAoB;AACxC,SAAS,mBAAmB;AAC5B,SAAS,gBAAgB;AAkCzB,SAAS,aAAa,MAAM,SAAS;AAEnC,YAAU,WAAW,CAAC;AACtB,MAAI,CAAC,SAAS,OAAO;AAAG,UAAM,IAAI,MAAM,oBAAoB;AAC5D,MAAI,YAAY,QAAQ,aAAa;AACrC,MAAI,OAAO,QAAQ;AACnB,MAAI,QAAQ,QAAQ;AAGpB,eAAa,MAAM,SAAS,2BAA2B;AAEvD,MAAI,eAAe,mBAAmB,MAAM,IAAI;AAEhD,MAAI,SAAS,CAAC;AAGd,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,QAAI,WAAW,aAAa,CAAC;AAC7B,QAAI,MAAM,CAAC;AACX,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAI,QAAQ,SAAS,CAAC;AAEtB,UAAI,MAAM,WAAW,SAAS;AAAG,YAAI,KAAK,MAAM,WAAW,SAAS,CAAC;AAAA;AAChE,YAAI,KAAK,CAAC;AAEf,UAAI,UAAU;AAAM,cAAM,WAAW,iBAAiB,CAAC,GAAG,CAAC;AAAA,IAC7D;AACA,WAAO,KAAK,GAAG;AAAA,EACjB;AAEA,SAAO;AACT;AAUA,SAAS,mBAAmB,QAAQ,MAAM;AACxC,MAAI,mBAAmB,CAAC;AAGxB,cAAY,QAAQ,SAAU,OAAO;AACnC,QAAI,MAAM,UAAU,KAAK,EAAE,CAAC;AAC5B,QAAI,CAAC,iBAAiB,GAAG;AAAG,uBAAiB,GAAG,IAAI,CAAC;AACrD,qBAAiB,GAAG,EAAE,KAAK,KAAK;AAAA,EAClC,CAAC;AAGD,MAAI,wBAAwB,OAAO,KAAK,gBAAgB,EAAE,IAAI,SAAU,KAAK;AAC3E,QAAI,MAAM,iBAAiB,GAAG;AAC9B,QAAI,wBAAwB,IAAI,KAAK,SAAU,GAAG,GAAG;AACnD,aAAO,UAAU,CAAC,EAAE,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC;AAAA,IACzC,CAAC;AACD,WAAO;AAAA,EACT,CAAC;AAGD,MAAI,cAAc,sBAAsB,KAAK,SAAU,GAAG,GAAG;AAC3D,QAAI;AAAM,aAAO,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC;AAAA;AAClD,aAAO,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC;AAAA,EACpD,CAAC;AAED,SAAO;AACT;;;ADhFA,SAAS,gBAAgB;AAsBzB,SAAS,SACP,WACA,QACA,SAKiC;AAEjC,YAAU,WAAW,CAAC;AACtB,MAAI,CAACC,UAAS,OAAO;AAAG,UAAM,IAAI,MAAM,oBAAoB;AAC5D,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,mBAAmB,QAAQ,oBAAoB,CAAC;AACtD,QAAM,mBAAmB,QAAQ,oBAAoB,CAAC;AAGtD,EAAAC,cAAa,WAAW,SAAS,2BAA2B;AAC5D,MAAI,CAAC;AAAQ,UAAM,IAAI,MAAM,oBAAoB;AACjD,MAAI,CAAC,MAAM,QAAQ,MAAM;AAAG,UAAM,IAAI,MAAM,wBAAwB;AACpE,MAAI,CAACD,UAAS,gBAAgB;AAC5B,UAAM,IAAI,MAAM,mCAAmC;AACrD,MAAI,CAAC,MAAM,QAAQ,gBAAgB;AACjC,UAAM,IAAI,MAAM,kCAAkC;AAGpD,QAAM,SAAS,aAAa,WAAW,EAAE,WAAsB,MAAM,KAAK,CAAC;AAC3E,MAAI,WAAW,mBAAmB,QAAQ,QAAQ,SAAS;AAC3D,aAAW,gBAAgB,UAAU,QAAQ,SAAS;AAEtD,QAAM,gBAAgB,SAAS,IAAI,CAAC,SAAS,UAAU;AACrD,QAAI,iBAAiB,KAAK,KAAK,CAACA,UAAS,iBAAiB,KAAK,CAAC,GAAG;AACjE,YAAM,IAAI,MAAM,iDAAiD;AAAA,IACnE;AAEA,UAAM,oBAAoB,kCACrB,mBACA,iBAAiB,KAAK;AAG3B,sBAAkB,SAAS,IAAK,QAA2B,SAAS;AAEpE,UAAM,SAAS;AAAA,MACb,QAAQ;AAAA,MACR;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AAED,SAAO,kBAAkB,aAAa;AACxC;AAeA,SAAS,mBACP,QACA,QACA,UACgB;AAChB,QAAM,WAA2B,CAAC;AAClC,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,YAAY,CAAC,OAAO,IAAI,CAAC;AAC/B,UAAM,YAAY,CAAC,OAAO,CAAC;AAE3B,UAAM,iBAAiB,SAAS,QAAQ,WAAW,YAAY,SAAS;AAKxE,UAAM,cAAc,YAAY,cAAc;AAC9C,UAAM,eAAe,iBAAiB,WAAW;AAEjD,aAAS,KAAK;AAAA,MACZ;AAAA,MACA,CAAC,QAAQ,GAAG,YAAY,MAAM;AAAA,IAChC,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAWA,SAAS,gBACP,UACA,QACA,QACgB;AAEhB,QAAM,WAAW,KAAK,MAAM;AAC5B,QAAM,gBAAgB,SAAS,CAAC,IAAI,SAAS,CAAC;AAC9C,QAAM,iBAAiB,SAAS,CAAC,IAAI,SAAS,CAAC;AAG/C,QAAM,KAAK,SAAS,CAAC;AACrB,QAAM,KAAK,SAAS,CAAC;AAErB,QAAM,cAAc,OAAO,CAAC,EAAE,SAAS;AACvC,QAAM,eAAe,OAAO,SAAS;AAErC,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,iBAAiB;AAGhC,SAAO,SAAS,IAAI,SAAU,SAAS;AACrC,YAAQ,eAAgB,QAAQ,aAAgC;AAAA,MAC9D,SAAU,aAAa;AACrB,eAAO,YAAY,IAAI,SAAU,UAAU;AACzC,iBAAO,SAAS,IAAI,CAAC,UAAoB;AAAA,YACvC,MAAM,CAAC,IAAI,SAAS;AAAA,YACpB,MAAM,CAAC,IAAI,SAAS;AAAA,UACtB,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AACH;AAWA,SAAS,YAAY,aAAyC;AAC5D,QAAM,gBAAgB,YAAY,IAAI,SAAU,QAAQ;AAEtD,WAAO,EAAE,MAAM,QAAQ,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE;AAAA,EACvD,CAAC;AACD,gBAAc,KAAK,SAAU,GAAG,GAAG;AAEjC,WAAO,EAAE,OAAO,EAAE;AAAA,EACpB,CAAC;AAED,SAAO,cAAc,IAAI,SAAU,GAAG;AACpC,WAAO,EAAE;AAAA,EACX,CAAC;AACH;AAWA,SAAS,iBAAiB,oBAAkD;AAE1E,QAAM,SAAS,mBAAmB,IAAI,CAAC,OAAO;AAC5C,WAAO,EAAE,eAAe,IAAI,SAAS,MAAM;AAAA,EAC7C,CAAC;AACD,QAAM,2BAA2C,CAAC;AAElD,SAAO,CAAC,WAAW,MAAM,GAAG;AAC1B,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAI,CAAC,OAAO,CAAC,EAAE,SAAS;AAEtB,cAAM,QAAsB,CAAC;AAC7B,cAAM,KAAK,OAAO,CAAC,EAAE,aAAa;AAClC,eAAO,CAAC,EAAE,UAAU;AACpB,cAAM,gBAAgB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;AAEvD,iBAAS,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AAC1C,cAAI,CAAC,OAAO,CAAC,EAAE,SAAS;AACtB,kBAAM,SAAS,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;AAChD,gBAAI,SAAS,QAAQ,aAAa,GAAG;AACnC,oBAAM,KAAK,OAAO,CAAC,EAAE,aAAa;AAClC,qBAAO,CAAC,EAAE,UAAU;AAAA,YACtB;AAAA,UACF;AAAA,QACF;AAEA,iCAAyB,KAAK,KAAK;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAQA,SAAS,SACP,aACA,eACS;AACT,QAAM,SAAS,QAAQ,WAAW;AAClC,WAAS,IAAI,GAAG,IAAI,OAAO,SAAS,QAAQ,KAAK;AAC/C,QAAI,CAAC,sBAAsB,OAAO,SAAS,CAAC,GAAG,aAAa,GAAG;AAC7D,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAOA,SAAS,WACP,MACS;AACT,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,KAAK,CAAC,EAAE,YAAY,OAAO;AAC7B,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAGA,IAAO,wBAAQ;","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.1.0",
4
- "description": "turf isobands module",
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": "^7.1.0",
61
- "@turf/point-grid": "^7.1.0",
62
- "@turf/random": "^7.1.0",
63
- "@turf/rhumb-destination": "^7.1.0",
64
- "@turf/truncate": "^7.1.0",
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": "^4.2.32",
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.7.2",
71
- "tsup": "^8.0.1",
72
- "tsx": "^4.6.2",
73
- "typescript": "^5.2.2",
74
- "write-json-file": "^5.0.0"
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": "^7.1.0",
78
- "@turf/bbox": "^7.1.0",
79
- "@turf/boolean-point-in-polygon": "^7.1.0",
80
- "@turf/explode": "^7.1.0",
81
- "@turf/helpers": "^7.1.0",
82
- "@turf/invariant": "^7.1.0",
83
- "@turf/meta": "^7.1.0",
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
- "marchingsquares": "^1.3.3",
86
- "tslib": "^2.6.2"
86
+ "tslib": "^2.8.1"
87
87
  },
88
- "gitHead": "68915eeebc9278bb40dec3f1034499698a0561ef"
88
+ "gitHead": "9f58a103e8f9a587ab640307ed03ba5233913ddd"
89
89
  }