@turf/isolines 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 [isolines][3].
9
9
 
10
10
  ### Parameters
11
11
 
12
- * `pointGrid` **[FeatureCollection][1]<[Point][2]>** input points
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][4]<[number][5]>** values of `zProperty` where to draw isolines
14
14
  * `options` **[Object][6]** Optional parameters (optional, default `{}`)
15
15
 
@@ -20,7 +20,6 @@ var _bbox = require('@turf/bbox');
20
20
  var _meta = require('@turf/meta');
21
21
  var _invariant = require('@turf/invariant');
22
22
  var _helpers = require('@turf/helpers');
23
- var _marchingsquares = require('marchingsquares');
24
23
 
25
24
  // lib/grid-to-matrix.js
26
25
 
@@ -28,8 +27,7 @@ var _marchingsquares = require('marchingsquares');
28
27
 
29
28
  function gridToMatrix(grid, options) {
30
29
  options = options || {};
31
- if (!_helpers.isObject.call(void 0, options))
32
- throw new Error("options is invalid");
30
+ if (!_helpers.isObject.call(void 0, options)) throw new Error("options is invalid");
33
31
  var zProperty = options.zProperty || "elevation";
34
32
  var flip = options.flip;
35
33
  var flags = options.flags;
@@ -41,12 +39,9 @@ function gridToMatrix(grid, options) {
41
39
  var row = [];
42
40
  for (var c = 0; c < pointRow.length; c++) {
43
41
  var point = pointRow[c];
44
- if (point.properties[zProperty])
45
- row.push(point.properties[zProperty]);
46
- else
47
- row.push(0);
48
- if (flags === true)
49
- point.properties.matrixPosition = [r, c];
42
+ if (point.properties[zProperty]) row.push(point.properties[zProperty]);
43
+ else row.push(0);
44
+ if (flags === true) point.properties.matrixPosition = [r, c];
50
45
  }
51
46
  matrix.push(row);
52
47
  }
@@ -56,8 +51,7 @@ function sortPointsByLatLng(points, flip) {
56
51
  var pointsByLatitude = {};
57
52
  _meta.featureEach.call(void 0, points, function(point) {
58
53
  var lat = _invariant.getCoords.call(void 0, point)[1];
59
- if (!pointsByLatitude[lat])
60
- pointsByLatitude[lat] = [];
54
+ if (!pointsByLatitude[lat]) pointsByLatitude[lat] = [];
61
55
  pointsByLatitude[lat].push(point);
62
56
  });
63
57
  var orderedRowsByLatitude = Object.keys(pointsByLatitude).map(function(lat) {
@@ -68,10 +62,8 @@ function sortPointsByLatLng(points, flip) {
68
62
  return rowOrderedByLongitude;
69
63
  });
70
64
  var pointMatrix = orderedRowsByLatitude.sort(function(a, b) {
71
- if (flip)
72
- return _invariant.getCoords.call(void 0, a[0])[1] - _invariant.getCoords.call(void 0, b[0])[1];
73
- else
74
- return _invariant.getCoords.call(void 0, b[0])[1] - _invariant.getCoords.call(void 0, a[0])[1];
65
+ if (flip) return _invariant.getCoords.call(void 0, a[0])[1] - _invariant.getCoords.call(void 0, b[0])[1];
66
+ else return _invariant.getCoords.call(void 0, b[0])[1] - _invariant.getCoords.call(void 0, a[0])[1];
75
67
  });
76
68
  return pointMatrix;
77
69
  }
@@ -79,21 +71,27 @@ function sortPointsByLatLng(points, flip) {
79
71
  // index.ts
80
72
  function isolines(pointGrid, breaks, options) {
81
73
  options = options || {};
82
- if (!_helpers.isObject.call(void 0, options))
83
- throw new Error("options is invalid");
74
+ if (!_helpers.isObject.call(void 0, options)) throw new Error("options is invalid");
84
75
  const zProperty = options.zProperty || "elevation";
85
76
  const commonProperties = options.commonProperties || {};
86
77
  const breaksProperties = options.breaksProperties || [];
87
78
  _invariant.collectionOf.call(void 0, pointGrid, "Point", "Input must contain Points");
88
- if (!breaks)
89
- throw new Error("breaks is required");
90
- if (!Array.isArray(breaks))
91
- throw new Error("breaks must be an Array");
79
+ if (!breaks) throw new Error("breaks is required");
80
+ if (!Array.isArray(breaks)) throw new Error("breaks must be an Array");
92
81
  if (!_helpers.isObject.call(void 0, commonProperties))
93
82
  throw new Error("commonProperties must be an Object");
94
83
  if (!Array.isArray(breaksProperties))
95
84
  throw new Error("breaksProperties must be an Array");
96
85
  const matrix = gridToMatrix(pointGrid, { zProperty, flip: true });
86
+ const dx = matrix[0].length;
87
+ if (matrix.length < 2 || dx < 2) {
88
+ throw new Error("Matrix of points must be at least 2x2");
89
+ }
90
+ for (let i = 1; i < matrix.length; i++) {
91
+ if (matrix[i].length !== dx) {
92
+ throw new Error("Matrix of points is not uniform in the x dimension");
93
+ }
94
+ }
97
95
  const createdIsoLines = createIsoLines(
98
96
  matrix,
99
97
  breaks,
@@ -110,14 +108,191 @@ function createIsoLines(matrix, breaks, zProperty, commonProperties, breaksPrope
110
108
  const threshold = +breaks[i];
111
109
  const properties = __spreadValues(__spreadValues({}, commonProperties), breaksProperties[i]);
112
110
  properties[zProperty] = threshold;
113
- const isoline = _helpers.multiLineString.call(void 0,
114
- _marchingsquares.isoContours.call(void 0, matrix, threshold, { linearRing: false, noFrame: true }),
115
- properties
116
- );
111
+ const isoline = _helpers.multiLineString.call(void 0, isoContours(matrix, threshold), properties);
117
112
  results.push(isoline);
118
113
  }
119
114
  return results;
120
115
  }
116
+ function isoContours(matrix, threshold) {
117
+ const segments = [];
118
+ const dy = matrix.length;
119
+ const dx = matrix[0].length;
120
+ for (let y = 0; y < dy - 1; y++) {
121
+ for (let x = 0; x < dx - 1; x++) {
122
+ const tr = matrix[y + 1][x + 1];
123
+ const br = matrix[y][x + 1];
124
+ const bl = matrix[y][x];
125
+ const tl = matrix[y + 1][x];
126
+ let grid = (tl >= threshold ? 8 : 0) | (tr >= threshold ? 4 : 0) | (br >= threshold ? 2 : 0) | (bl >= threshold ? 1 : 0);
127
+ switch (grid) {
128
+ case 0:
129
+ continue;
130
+ case 1:
131
+ segments.push([
132
+ [x + frac(bl, br), y],
133
+ [x, y + frac(bl, tl)]
134
+ ]);
135
+ break;
136
+ case 2:
137
+ segments.push([
138
+ [x + 1, y + frac(br, tr)],
139
+ [x + frac(bl, br), y]
140
+ ]);
141
+ break;
142
+ case 3:
143
+ segments.push([
144
+ [x + 1, y + frac(br, tr)],
145
+ [x, y + frac(bl, tl)]
146
+ ]);
147
+ break;
148
+ case 4:
149
+ segments.push([
150
+ [x + frac(tl, tr), y + 1],
151
+ [x + 1, y + frac(br, tr)]
152
+ ]);
153
+ break;
154
+ case 5: {
155
+ const avg = (tl + tr + br + bl) / 4;
156
+ const above = avg >= threshold;
157
+ if (above) {
158
+ segments.push(
159
+ [
160
+ [x + frac(tl, tr), y + 1],
161
+ [x, y + frac(bl, tl)]
162
+ ],
163
+ [
164
+ [x + frac(bl, br), y],
165
+ [x + 1, y + frac(br, tr)]
166
+ ]
167
+ );
168
+ } else {
169
+ segments.push(
170
+ [
171
+ [x + frac(tl, tr), y + 1],
172
+ [x + 1, y + frac(br, tr)]
173
+ ],
174
+ [
175
+ [x + frac(bl, br), y],
176
+ [x, y + frac(bl, tl)]
177
+ ]
178
+ );
179
+ }
180
+ break;
181
+ }
182
+ case 6:
183
+ segments.push([
184
+ [x + frac(tl, tr), y + 1],
185
+ [x + frac(bl, br), y]
186
+ ]);
187
+ break;
188
+ case 7:
189
+ segments.push([
190
+ [x + frac(tl, tr), y + 1],
191
+ [x, y + frac(bl, tl)]
192
+ ]);
193
+ break;
194
+ case 8:
195
+ segments.push([
196
+ [x, y + frac(bl, tl)],
197
+ [x + frac(tl, tr), y + 1]
198
+ ]);
199
+ break;
200
+ case 9:
201
+ segments.push([
202
+ [x + frac(bl, br), y],
203
+ [x + frac(tl, tr), y + 1]
204
+ ]);
205
+ break;
206
+ case 10: {
207
+ const avg = (tl + tr + br + bl) / 4;
208
+ const above = avg >= threshold;
209
+ if (above) {
210
+ segments.push(
211
+ [
212
+ [x, y + frac(bl, tl)],
213
+ [x + frac(bl, br), y]
214
+ ],
215
+ [
216
+ [x + 1, y + frac(br, tr)],
217
+ [x + frac(tl, tr), y + 1]
218
+ ]
219
+ );
220
+ } else {
221
+ segments.push(
222
+ [
223
+ [x, y + frac(bl, tl)],
224
+ [x + frac(tl, tr), y + 1]
225
+ ],
226
+ [
227
+ [x + 1, y + frac(br, tr)],
228
+ [x + frac(bl, br), y]
229
+ ]
230
+ );
231
+ }
232
+ break;
233
+ }
234
+ case 11:
235
+ segments.push([
236
+ [x + 1, y + frac(br, tr)],
237
+ [x + frac(tl, tr), y + 1]
238
+ ]);
239
+ break;
240
+ case 12:
241
+ segments.push([
242
+ [x, y + frac(bl, tl)],
243
+ [x + 1, y + frac(br, tr)]
244
+ ]);
245
+ break;
246
+ case 13:
247
+ segments.push([
248
+ [x + frac(bl, br), y],
249
+ [x + 1, y + frac(br, tr)]
250
+ ]);
251
+ break;
252
+ case 14:
253
+ segments.push([
254
+ [x, y + frac(bl, tl)],
255
+ [x + frac(bl, br), y]
256
+ ]);
257
+ break;
258
+ case 15:
259
+ continue;
260
+ }
261
+ }
262
+ }
263
+ const contours = [];
264
+ while (segments.length > 0) {
265
+ const contour = [...segments.shift()];
266
+ contours.push(contour);
267
+ let found;
268
+ do {
269
+ found = false;
270
+ for (let i = 0; i < segments.length; i++) {
271
+ const segment = segments[i];
272
+ if (segment[0][0] === contour[contour.length - 1][0] && segment[0][1] === contour[contour.length - 1][1]) {
273
+ found = true;
274
+ contour.push(segment[1]);
275
+ segments.splice(i, 1);
276
+ break;
277
+ }
278
+ if (segment[1][0] === contour[0][0] && segment[1][1] === contour[0][1]) {
279
+ found = true;
280
+ contour.unshift(segment[0]);
281
+ segments.splice(i, 1);
282
+ break;
283
+ }
284
+ }
285
+ } while (found);
286
+ }
287
+ return contours;
288
+ function frac(z0, z1) {
289
+ if (z0 === z1) {
290
+ return 0.5;
291
+ }
292
+ let t = (threshold - z0) / (z1 - z0);
293
+ return t > 1 ? 1 : t < 0 ? 0 : t;
294
+ }
295
+ }
121
296
  function rescaleIsolines(createdIsoLines, matrix, points) {
122
297
  const gridBbox = _bbox.bbox.call(void 0, points);
123
298
  const originalWidth = gridBbox[2] - gridBbox[0];
@@ -137,9 +312,9 @@ function rescaleIsolines(createdIsoLines, matrix, points) {
137
312
  });
138
313
  return createdIsoLines;
139
314
  }
140
- var turf_isolines_default = isolines;
315
+ var index_default = isolines;
141
316
 
142
317
 
143
318
 
144
- exports.default = turf_isolines_default; exports.isolines = isolines;
319
+ exports.default = index_default; exports.isolines = isolines;
145
320
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../index.ts","../../lib/grid-to-matrix.js"],"names":["collectionOf","isObject"],"mappings":"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","sourcesContent":["import { bbox } from \"@turf/bbox\";\nimport { coordEach } from \"@turf/meta\";\nimport { collectionOf } from \"@turf/invariant\";\nimport { multiLineString, featureCollection, isObject } from \"@turf/helpers\";\n// @ts-expect-error Legacy JS library with no types defined\nimport { isoContours } from \"marchingsquares\";\nimport { gridToMatrix } from \"./lib/grid-to-matrix.js\";\nimport {\n FeatureCollection,\n Point,\n MultiLineString,\n Feature,\n GeoJsonProperties,\n} from \"geojson\";\n\n/**\n * Takes a grid {@link FeatureCollection} of {@link Point} features with z-values and an array of\n * value breaks and generates [isolines](https://en.wikipedia.org/wiki/Contour_line).\n *\n * @name isolines\n * @param {FeatureCollection<Point>} pointGrid input points\n * @param {Array<number>} breaks values of `zProperty` where to draw isolines\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 {Object} [options.commonProperties={}] GeoJSON properties passed to ALL isolines\n * @param {Array<Object>} [options.breaksProperties=[]] GeoJSON properties passed, in order, to the correspondent isoline;\n * the breaks array will define the order in which the isolines are created\n * @returns {FeatureCollection<MultiLineString>} a FeatureCollection of {@link MultiLineString} features representing isolines\n * @example\n * // create a grid of points with random z-values in their properties\n * var extent = [0, 30, 20, 50];\n * var cellWidth = 100;\n * var pointGrid = turf.pointGrid(extent, cellWidth, {units: 'miles'});\n *\n * for (var i = 0; i < pointGrid.features.length; i++) {\n * pointGrid.features[i].properties.temperature = Math.random() * 10;\n * }\n * var breaks = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n *\n * var lines = turf.isolines(pointGrid, breaks, {zProperty: 'temperature'});\n *\n * //addToMap\n * var addToMap = [lines];\n */\nfunction isolines(\n pointGrid: FeatureCollection<Point>,\n breaks: number[],\n options?: {\n zProperty?: string;\n commonProperties?: GeoJsonProperties;\n breaksProperties?: GeoJsonProperties[];\n }\n) {\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 // Input 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 must be an Array\");\n if (!isObject(commonProperties))\n throw new Error(\"commonProperties must be an Object\");\n if (!Array.isArray(breaksProperties))\n throw new Error(\"breaksProperties must be an Array\");\n\n // Isoline methods\n const matrix = gridToMatrix(pointGrid, { zProperty: zProperty, flip: true });\n const createdIsoLines = createIsoLines(\n matrix,\n breaks,\n zProperty,\n commonProperties,\n breaksProperties\n );\n const scaledIsolines = rescaleIsolines(createdIsoLines, matrix, pointGrid);\n\n return featureCollection(scaledIsolines);\n}\n\n/**\n * Creates the isolines lines (featuresCollection of MultiLineString 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 isolines 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 BreakProps\n * @param {string} zProperty name of the z-values property\n * @param {Object} [commonProperties={}] GeoJSON properties passed to ALL isolines\n * @param {Object} [breaksProperties=[]] GeoJSON properties passed to the correspondent isoline\n * @returns {Array<MultiLineString>} isolines\n */\nfunction createIsoLines(\n matrix: number[][],\n breaks: number[],\n zProperty: string,\n commonProperties: GeoJsonProperties,\n breaksProperties: GeoJsonProperties[]\n): Feature<MultiLineString>[] {\n const results = [];\n for (let i = 0; i < breaks.length; i++) {\n const threshold = +breaks[i]; // make sure it's a number\n\n const properties = { ...commonProperties, ...breaksProperties[i] };\n properties[zProperty] = threshold;\n // Pass options to marchingsquares lib to reproduce historical turf\n // behaviour.\n const isoline = multiLineString(\n isoContours(matrix, threshold, { linearRing: false, noFrame: true }),\n properties\n );\n\n results.push(isoline);\n }\n return results;\n}\n\n/**\n * Translates and scales isolines\n *\n * @private\n * @param {Array<MultiLineString>} createdIsoLines to be rescaled\n * @param {Array<Array<number>>} matrix Grid Data\n * @param {Object} points Points by Latitude\n * @returns {Array<MultiLineString>} isolines\n */\nfunction rescaleIsolines(\n createdIsoLines: Feature<MultiLineString>[],\n matrix: number[][],\n points: FeatureCollection<Point>\n) {\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\n // get number of cells per side\n const matrixWidth = matrix[0].length - 1;\n const matrixHeight = matrix.length - 1;\n\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 const resize = (point: number[]) => {\n point[0] = point[0] * scaleX + x0;\n point[1] = point[1] * scaleY + y0;\n };\n\n // resize and shift each point/line of the createdIsoLines\n createdIsoLines.forEach((isoline) => {\n coordEach(isoline, resize);\n });\n return createdIsoLines;\n}\n\nexport { isolines };\nexport default isolines;\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-isolines/dist/cjs/index.cjs","../../index.ts","../../lib/grid-to-matrix.js"],"names":["isObject","collectionOf"],"mappings":"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","file":"/home/runner/work/turf/turf/packages/turf-isolines/dist/cjs/index.cjs","sourcesContent":[null,"import { bbox } from \"@turf/bbox\";\nimport { coordEach } from \"@turf/meta\";\nimport { collectionOf } from \"@turf/invariant\";\nimport { multiLineString, featureCollection, isObject } from \"@turf/helpers\";\nimport { gridToMatrix } from \"./lib/grid-to-matrix.js\";\nimport {\n FeatureCollection,\n Point,\n MultiLineString,\n Feature,\n GeoJsonProperties,\n Position,\n} from \"geojson\";\n\n/**\n * Takes a grid {@link FeatureCollection} of {@link Point} features with z-values and an array of\n * value breaks and generates [isolines](https://en.wikipedia.org/wiki/Contour_line).\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 values of `zProperty` where to draw isolines\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 {Object} [options.commonProperties={}] GeoJSON properties passed to ALL isolines\n * @param {Array<Object>} [options.breaksProperties=[]] GeoJSON properties passed, in order, to the correspondent isoline;\n * the breaks array will define the order in which the isolines are created\n * @returns {FeatureCollection<MultiLineString>} a FeatureCollection of {@link MultiLineString} features representing isolines\n * @example\n * // create a grid of points with random z-values in their properties\n * var extent = [0, 30, 20, 50];\n * var cellWidth = 100;\n * var pointGrid = turf.pointGrid(extent, cellWidth, {units: 'miles'});\n *\n * for (var i = 0; i < pointGrid.features.length; i++) {\n * pointGrid.features[i].properties.temperature = Math.random() * 10;\n * }\n * var breaks = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n *\n * var lines = turf.isolines(pointGrid, breaks, {zProperty: 'temperature'});\n *\n * //addToMap\n * var addToMap = [lines];\n */\nfunction isolines(\n pointGrid: FeatureCollection<Point>,\n breaks: number[],\n options?: {\n zProperty?: string;\n commonProperties?: GeoJsonProperties;\n breaksProperties?: GeoJsonProperties[];\n }\n) {\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 // Input 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 must be an Array\");\n if (!isObject(commonProperties))\n throw new Error(\"commonProperties must be an Object\");\n if (!Array.isArray(breaksProperties))\n throw new Error(\"breaksProperties must be an Array\");\n\n // Isoline 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 const createdIsoLines = createIsoLines(\n matrix,\n breaks,\n zProperty,\n commonProperties,\n breaksProperties\n );\n const scaledIsolines = rescaleIsolines(createdIsoLines, matrix, pointGrid);\n\n return featureCollection(scaledIsolines);\n}\n\n/**\n * Creates the isolines lines (featuresCollection of MultiLineString 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 isolines 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 BreakProps\n * @param {string} zProperty name of the z-values property\n * @param {Object} [commonProperties={}] GeoJSON properties passed to ALL isolines\n * @param {Object} [breaksProperties=[]] GeoJSON properties passed to the correspondent isoline\n * @returns {Array<MultiLineString>} isolines\n */\nfunction createIsoLines(\n matrix: number[][],\n breaks: number[],\n zProperty: string,\n commonProperties: GeoJsonProperties,\n breaksProperties: GeoJsonProperties[]\n): Feature<MultiLineString>[] {\n const results = [];\n for (let i = 0; i < breaks.length; i++) {\n const threshold = +breaks[i]; // make sure it's a number\n\n const properties = { ...commonProperties, ...breaksProperties[i] };\n properties[zProperty] = threshold;\n const isoline = multiLineString(isoContours(matrix, threshold), properties);\n\n results.push(isoline);\n }\n return results;\n}\n\nfunction isoContours(\n matrix: ReadonlyArray<ReadonlyArray<number>>,\n threshold: number\n): Position[][] {\n // see https://en.wikipedia.org/wiki/Marching_squares\n const segments: [Position, Position][] = [];\n\n const dy = matrix.length;\n const dx = matrix[0].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 const contours: Position[][] = [];\n\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 } while (found);\n }\n\n return contours;\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 * Translates and scales isolines\n *\n * @private\n * @param {Array<MultiLineString>} createdIsoLines to be rescaled\n * @param {Array<Array<number>>} matrix Grid Data\n * @param {Object} points Points by Latitude\n * @returns {Array<MultiLineString>} isolines\n */\nfunction rescaleIsolines(\n createdIsoLines: Feature<MultiLineString>[],\n matrix: number[][],\n points: FeatureCollection<Point>\n) {\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\n // get number of cells per side\n const matrixWidth = matrix[0].length - 1;\n const matrixHeight = matrix.length - 1;\n\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 const resize = (point: number[]) => {\n point[0] = point[0] * scaleX + x0;\n point[1] = point[1] * scaleY + y0;\n };\n\n // resize and shift each point/line of the createdIsoLines\n createdIsoLines.forEach((isoline) => {\n coordEach(isoline, resize);\n });\n return createdIsoLines;\n}\n\nexport { isolines };\nexport default isolines;\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, MultiLineString } from 'ge
4
4
  * Takes a grid {@link FeatureCollection} of {@link Point} features with z-values and an array of
5
5
  * value breaks and generates [isolines](https://en.wikipedia.org/wiki/Contour_line).
6
6
  *
7
- * @name isolines
8
- * @param {FeatureCollection<Point>} pointGrid input points
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 values of `zProperty` where to draw isolines
10
10
  * @param {Object} [options={}] Optional parameters
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, MultiLineString } from 'ge
4
4
  * Takes a grid {@link FeatureCollection} of {@link Point} features with z-values and an array of
5
5
  * value breaks and generates [isolines](https://en.wikipedia.org/wiki/Contour_line).
6
6
  *
7
- * @name isolines
8
- * @param {FeatureCollection<Point>} pointGrid input points
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 values of `zProperty` where to draw isolines
10
10
  * @param {Object} [options={}] Optional parameters
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
@@ -20,7 +20,6 @@ import { bbox } from "@turf/bbox";
20
20
  import { coordEach } from "@turf/meta";
21
21
  import { collectionOf as collectionOf2 } from "@turf/invariant";
22
22
  import { multiLineString, featureCollection, isObject as isObject2 } from "@turf/helpers";
23
- import { isoContours } from "marchingsquares";
24
23
 
25
24
  // lib/grid-to-matrix.js
26
25
  import { getCoords, collectionOf } from "@turf/invariant";
@@ -28,8 +27,7 @@ import { featureEach } from "@turf/meta";
28
27
  import { isObject } from "@turf/helpers";
29
28
  function gridToMatrix(grid, options) {
30
29
  options = options || {};
31
- if (!isObject(options))
32
- throw new Error("options is invalid");
30
+ if (!isObject(options)) throw new Error("options is invalid");
33
31
  var zProperty = options.zProperty || "elevation";
34
32
  var flip = options.flip;
35
33
  var flags = options.flags;
@@ -41,12 +39,9 @@ function gridToMatrix(grid, options) {
41
39
  var row = [];
42
40
  for (var c = 0; c < pointRow.length; c++) {
43
41
  var point = pointRow[c];
44
- if (point.properties[zProperty])
45
- row.push(point.properties[zProperty]);
46
- else
47
- row.push(0);
48
- if (flags === true)
49
- point.properties.matrixPosition = [r, c];
42
+ if (point.properties[zProperty]) row.push(point.properties[zProperty]);
43
+ else row.push(0);
44
+ if (flags === true) point.properties.matrixPosition = [r, c];
50
45
  }
51
46
  matrix.push(row);
52
47
  }
@@ -56,8 +51,7 @@ function sortPointsByLatLng(points, flip) {
56
51
  var pointsByLatitude = {};
57
52
  featureEach(points, function(point) {
58
53
  var lat = getCoords(point)[1];
59
- if (!pointsByLatitude[lat])
60
- pointsByLatitude[lat] = [];
54
+ if (!pointsByLatitude[lat]) pointsByLatitude[lat] = [];
61
55
  pointsByLatitude[lat].push(point);
62
56
  });
63
57
  var orderedRowsByLatitude = Object.keys(pointsByLatitude).map(function(lat) {
@@ -68,10 +62,8 @@ function sortPointsByLatLng(points, flip) {
68
62
  return rowOrderedByLongitude;
69
63
  });
70
64
  var pointMatrix = orderedRowsByLatitude.sort(function(a, b) {
71
- if (flip)
72
- return getCoords(a[0])[1] - getCoords(b[0])[1];
73
- else
74
- return getCoords(b[0])[1] - getCoords(a[0])[1];
65
+ if (flip) return getCoords(a[0])[1] - getCoords(b[0])[1];
66
+ else return getCoords(b[0])[1] - getCoords(a[0])[1];
75
67
  });
76
68
  return pointMatrix;
77
69
  }
@@ -79,21 +71,27 @@ function sortPointsByLatLng(points, flip) {
79
71
  // index.ts
80
72
  function isolines(pointGrid, breaks, options) {
81
73
  options = options || {};
82
- if (!isObject2(options))
83
- throw new Error("options is invalid");
74
+ if (!isObject2(options)) throw new Error("options is invalid");
84
75
  const zProperty = options.zProperty || "elevation";
85
76
  const commonProperties = options.commonProperties || {};
86
77
  const breaksProperties = options.breaksProperties || [];
87
78
  collectionOf2(pointGrid, "Point", "Input must contain Points");
88
- if (!breaks)
89
- throw new Error("breaks is required");
90
- if (!Array.isArray(breaks))
91
- throw new Error("breaks must be an Array");
79
+ if (!breaks) throw new Error("breaks is required");
80
+ if (!Array.isArray(breaks)) throw new Error("breaks must be an Array");
92
81
  if (!isObject2(commonProperties))
93
82
  throw new Error("commonProperties must be an Object");
94
83
  if (!Array.isArray(breaksProperties))
95
84
  throw new Error("breaksProperties must be an Array");
96
85
  const matrix = gridToMatrix(pointGrid, { zProperty, flip: true });
86
+ const dx = matrix[0].length;
87
+ if (matrix.length < 2 || dx < 2) {
88
+ throw new Error("Matrix of points must be at least 2x2");
89
+ }
90
+ for (let i = 1; i < matrix.length; i++) {
91
+ if (matrix[i].length !== dx) {
92
+ throw new Error("Matrix of points is not uniform in the x dimension");
93
+ }
94
+ }
97
95
  const createdIsoLines = createIsoLines(
98
96
  matrix,
99
97
  breaks,
@@ -110,14 +108,191 @@ function createIsoLines(matrix, breaks, zProperty, commonProperties, breaksPrope
110
108
  const threshold = +breaks[i];
111
109
  const properties = __spreadValues(__spreadValues({}, commonProperties), breaksProperties[i]);
112
110
  properties[zProperty] = threshold;
113
- const isoline = multiLineString(
114
- isoContours(matrix, threshold, { linearRing: false, noFrame: true }),
115
- properties
116
- );
111
+ const isoline = multiLineString(isoContours(matrix, threshold), properties);
117
112
  results.push(isoline);
118
113
  }
119
114
  return results;
120
115
  }
116
+ function isoContours(matrix, threshold) {
117
+ const segments = [];
118
+ const dy = matrix.length;
119
+ const dx = matrix[0].length;
120
+ for (let y = 0; y < dy - 1; y++) {
121
+ for (let x = 0; x < dx - 1; x++) {
122
+ const tr = matrix[y + 1][x + 1];
123
+ const br = matrix[y][x + 1];
124
+ const bl = matrix[y][x];
125
+ const tl = matrix[y + 1][x];
126
+ let grid = (tl >= threshold ? 8 : 0) | (tr >= threshold ? 4 : 0) | (br >= threshold ? 2 : 0) | (bl >= threshold ? 1 : 0);
127
+ switch (grid) {
128
+ case 0:
129
+ continue;
130
+ case 1:
131
+ segments.push([
132
+ [x + frac(bl, br), y],
133
+ [x, y + frac(bl, tl)]
134
+ ]);
135
+ break;
136
+ case 2:
137
+ segments.push([
138
+ [x + 1, y + frac(br, tr)],
139
+ [x + frac(bl, br), y]
140
+ ]);
141
+ break;
142
+ case 3:
143
+ segments.push([
144
+ [x + 1, y + frac(br, tr)],
145
+ [x, y + frac(bl, tl)]
146
+ ]);
147
+ break;
148
+ case 4:
149
+ segments.push([
150
+ [x + frac(tl, tr), y + 1],
151
+ [x + 1, y + frac(br, tr)]
152
+ ]);
153
+ break;
154
+ case 5: {
155
+ const avg = (tl + tr + br + bl) / 4;
156
+ const above = avg >= threshold;
157
+ if (above) {
158
+ segments.push(
159
+ [
160
+ [x + frac(tl, tr), y + 1],
161
+ [x, y + frac(bl, tl)]
162
+ ],
163
+ [
164
+ [x + frac(bl, br), y],
165
+ [x + 1, y + frac(br, tr)]
166
+ ]
167
+ );
168
+ } else {
169
+ segments.push(
170
+ [
171
+ [x + frac(tl, tr), y + 1],
172
+ [x + 1, y + frac(br, tr)]
173
+ ],
174
+ [
175
+ [x + frac(bl, br), y],
176
+ [x, y + frac(bl, tl)]
177
+ ]
178
+ );
179
+ }
180
+ break;
181
+ }
182
+ case 6:
183
+ segments.push([
184
+ [x + frac(tl, tr), y + 1],
185
+ [x + frac(bl, br), y]
186
+ ]);
187
+ break;
188
+ case 7:
189
+ segments.push([
190
+ [x + frac(tl, tr), y + 1],
191
+ [x, y + frac(bl, tl)]
192
+ ]);
193
+ break;
194
+ case 8:
195
+ segments.push([
196
+ [x, y + frac(bl, tl)],
197
+ [x + frac(tl, tr), y + 1]
198
+ ]);
199
+ break;
200
+ case 9:
201
+ segments.push([
202
+ [x + frac(bl, br), y],
203
+ [x + frac(tl, tr), y + 1]
204
+ ]);
205
+ break;
206
+ case 10: {
207
+ const avg = (tl + tr + br + bl) / 4;
208
+ const above = avg >= threshold;
209
+ if (above) {
210
+ segments.push(
211
+ [
212
+ [x, y + frac(bl, tl)],
213
+ [x + frac(bl, br), y]
214
+ ],
215
+ [
216
+ [x + 1, y + frac(br, tr)],
217
+ [x + frac(tl, tr), y + 1]
218
+ ]
219
+ );
220
+ } else {
221
+ segments.push(
222
+ [
223
+ [x, y + frac(bl, tl)],
224
+ [x + frac(tl, tr), y + 1]
225
+ ],
226
+ [
227
+ [x + 1, y + frac(br, tr)],
228
+ [x + frac(bl, br), y]
229
+ ]
230
+ );
231
+ }
232
+ break;
233
+ }
234
+ case 11:
235
+ segments.push([
236
+ [x + 1, y + frac(br, tr)],
237
+ [x + frac(tl, tr), y + 1]
238
+ ]);
239
+ break;
240
+ case 12:
241
+ segments.push([
242
+ [x, y + frac(bl, tl)],
243
+ [x + 1, y + frac(br, tr)]
244
+ ]);
245
+ break;
246
+ case 13:
247
+ segments.push([
248
+ [x + frac(bl, br), y],
249
+ [x + 1, y + frac(br, tr)]
250
+ ]);
251
+ break;
252
+ case 14:
253
+ segments.push([
254
+ [x, y + frac(bl, tl)],
255
+ [x + frac(bl, br), y]
256
+ ]);
257
+ break;
258
+ case 15:
259
+ continue;
260
+ }
261
+ }
262
+ }
263
+ const contours = [];
264
+ while (segments.length > 0) {
265
+ const contour = [...segments.shift()];
266
+ contours.push(contour);
267
+ let found;
268
+ do {
269
+ found = false;
270
+ for (let i = 0; i < segments.length; i++) {
271
+ const segment = segments[i];
272
+ if (segment[0][0] === contour[contour.length - 1][0] && segment[0][1] === contour[contour.length - 1][1]) {
273
+ found = true;
274
+ contour.push(segment[1]);
275
+ segments.splice(i, 1);
276
+ break;
277
+ }
278
+ if (segment[1][0] === contour[0][0] && segment[1][1] === contour[0][1]) {
279
+ found = true;
280
+ contour.unshift(segment[0]);
281
+ segments.splice(i, 1);
282
+ break;
283
+ }
284
+ }
285
+ } while (found);
286
+ }
287
+ return contours;
288
+ function frac(z0, z1) {
289
+ if (z0 === z1) {
290
+ return 0.5;
291
+ }
292
+ let t = (threshold - z0) / (z1 - z0);
293
+ return t > 1 ? 1 : t < 0 ? 0 : t;
294
+ }
295
+ }
121
296
  function rescaleIsolines(createdIsoLines, matrix, points) {
122
297
  const gridBbox = bbox(points);
123
298
  const originalWidth = gridBbox[2] - gridBbox[0];
@@ -137,9 +312,9 @@ function rescaleIsolines(createdIsoLines, matrix, points) {
137
312
  });
138
313
  return createdIsoLines;
139
314
  }
140
- var turf_isolines_default = isolines;
315
+ var index_default = isolines;
141
316
  export {
142
- turf_isolines_default as default,
317
+ index_default as default,
143
318
  isolines
144
319
  };
145
320
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../index.ts","../../lib/grid-to-matrix.js"],"sourcesContent":["import { bbox } from \"@turf/bbox\";\nimport { coordEach } from \"@turf/meta\";\nimport { collectionOf } from \"@turf/invariant\";\nimport { multiLineString, featureCollection, isObject } from \"@turf/helpers\";\n// @ts-expect-error Legacy JS library with no types defined\nimport { isoContours } from \"marchingsquares\";\nimport { gridToMatrix } from \"./lib/grid-to-matrix.js\";\nimport {\n FeatureCollection,\n Point,\n MultiLineString,\n Feature,\n GeoJsonProperties,\n} from \"geojson\";\n\n/**\n * Takes a grid {@link FeatureCollection} of {@link Point} features with z-values and an array of\n * value breaks and generates [isolines](https://en.wikipedia.org/wiki/Contour_line).\n *\n * @name isolines\n * @param {FeatureCollection<Point>} pointGrid input points\n * @param {Array<number>} breaks values of `zProperty` where to draw isolines\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 {Object} [options.commonProperties={}] GeoJSON properties passed to ALL isolines\n * @param {Array<Object>} [options.breaksProperties=[]] GeoJSON properties passed, in order, to the correspondent isoline;\n * the breaks array will define the order in which the isolines are created\n * @returns {FeatureCollection<MultiLineString>} a FeatureCollection of {@link MultiLineString} features representing isolines\n * @example\n * // create a grid of points with random z-values in their properties\n * var extent = [0, 30, 20, 50];\n * var cellWidth = 100;\n * var pointGrid = turf.pointGrid(extent, cellWidth, {units: 'miles'});\n *\n * for (var i = 0; i < pointGrid.features.length; i++) {\n * pointGrid.features[i].properties.temperature = Math.random() * 10;\n * }\n * var breaks = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n *\n * var lines = turf.isolines(pointGrid, breaks, {zProperty: 'temperature'});\n *\n * //addToMap\n * var addToMap = [lines];\n */\nfunction isolines(\n pointGrid: FeatureCollection<Point>,\n breaks: number[],\n options?: {\n zProperty?: string;\n commonProperties?: GeoJsonProperties;\n breaksProperties?: GeoJsonProperties[];\n }\n) {\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 // Input 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 must be an Array\");\n if (!isObject(commonProperties))\n throw new Error(\"commonProperties must be an Object\");\n if (!Array.isArray(breaksProperties))\n throw new Error(\"breaksProperties must be an Array\");\n\n // Isoline methods\n const matrix = gridToMatrix(pointGrid, { zProperty: zProperty, flip: true });\n const createdIsoLines = createIsoLines(\n matrix,\n breaks,\n zProperty,\n commonProperties,\n breaksProperties\n );\n const scaledIsolines = rescaleIsolines(createdIsoLines, matrix, pointGrid);\n\n return featureCollection(scaledIsolines);\n}\n\n/**\n * Creates the isolines lines (featuresCollection of MultiLineString 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 isolines 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 BreakProps\n * @param {string} zProperty name of the z-values property\n * @param {Object} [commonProperties={}] GeoJSON properties passed to ALL isolines\n * @param {Object} [breaksProperties=[]] GeoJSON properties passed to the correspondent isoline\n * @returns {Array<MultiLineString>} isolines\n */\nfunction createIsoLines(\n matrix: number[][],\n breaks: number[],\n zProperty: string,\n commonProperties: GeoJsonProperties,\n breaksProperties: GeoJsonProperties[]\n): Feature<MultiLineString>[] {\n const results = [];\n for (let i = 0; i < breaks.length; i++) {\n const threshold = +breaks[i]; // make sure it's a number\n\n const properties = { ...commonProperties, ...breaksProperties[i] };\n properties[zProperty] = threshold;\n // Pass options to marchingsquares lib to reproduce historical turf\n // behaviour.\n const isoline = multiLineString(\n isoContours(matrix, threshold, { linearRing: false, noFrame: true }),\n properties\n );\n\n results.push(isoline);\n }\n return results;\n}\n\n/**\n * Translates and scales isolines\n *\n * @private\n * @param {Array<MultiLineString>} createdIsoLines to be rescaled\n * @param {Array<Array<number>>} matrix Grid Data\n * @param {Object} points Points by Latitude\n * @returns {Array<MultiLineString>} isolines\n */\nfunction rescaleIsolines(\n createdIsoLines: Feature<MultiLineString>[],\n matrix: number[][],\n points: FeatureCollection<Point>\n) {\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\n // get number of cells per side\n const matrixWidth = matrix[0].length - 1;\n const matrixHeight = matrix.length - 1;\n\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 const resize = (point: number[]) => {\n point[0] = point[0] * scaleX + x0;\n point[1] = point[1] * scaleY + y0;\n };\n\n // resize and shift each point/line of the createdIsoLines\n createdIsoLines.forEach((isoline) => {\n coordEach(isoline, resize);\n });\n return createdIsoLines;\n}\n\nexport { isolines };\nexport default isolines;\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,iBAAiB;AAC1B,SAAS,gBAAAA,qBAAoB;AAC7B,SAAS,iBAAiB,mBAAmB,YAAAC,iBAAgB;AAE7D,SAAS,mBAAmB;;;ACL5B,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;;;AD3DA,SAAS,SACP,WACA,QACA,SAKA;AAEA,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,yBAAyB;AACrE,MAAI,CAACD,UAAS,gBAAgB;AAC5B,UAAM,IAAI,MAAM,oCAAoC;AACtD,MAAI,CAAC,MAAM,QAAQ,gBAAgB;AACjC,UAAM,IAAI,MAAM,mCAAmC;AAGrD,QAAM,SAAS,aAAa,WAAW,EAAE,WAAsB,MAAM,KAAK,CAAC;AAC3E,QAAM,kBAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,iBAAiB,gBAAgB,iBAAiB,QAAQ,SAAS;AAEzE,SAAO,kBAAkB,cAAc;AACzC;AAiBA,SAAS,eACP,QACA,QACA,WACA,kBACA,kBAC4B;AAC5B,QAAM,UAAU,CAAC;AACjB,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,YAAY,CAAC,OAAO,CAAC;AAE3B,UAAM,aAAa,kCAAK,mBAAqB,iBAAiB,CAAC;AAC/D,eAAW,SAAS,IAAI;AAGxB,UAAM,UAAU;AAAA,MACd,YAAY,QAAQ,WAAW,EAAE,YAAY,OAAO,SAAS,KAAK,CAAC;AAAA,MACnE;AAAA,IACF;AAEA,YAAQ,KAAK,OAAO;AAAA,EACtB;AACA,SAAO;AACT;AAWA,SAAS,gBACP,iBACA,QACA,QACA;AAEA,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;AAGrB,QAAM,cAAc,OAAO,CAAC,EAAE,SAAS;AACvC,QAAM,eAAe,OAAO,SAAS;AAGrC,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,iBAAiB;AAEhC,QAAM,SAAS,CAAC,UAAoB;AAClC,UAAM,CAAC,IAAI,MAAM,CAAC,IAAI,SAAS;AAC/B,UAAM,CAAC,IAAI,MAAM,CAAC,IAAI,SAAS;AAAA,EACjC;AAGA,kBAAgB,QAAQ,CAAC,YAAY;AACnC,cAAU,SAAS,MAAM;AAAA,EAC3B,CAAC;AACD,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 { coordEach } from \"@turf/meta\";\nimport { collectionOf } from \"@turf/invariant\";\nimport { multiLineString, featureCollection, isObject } from \"@turf/helpers\";\nimport { gridToMatrix } from \"./lib/grid-to-matrix.js\";\nimport {\n FeatureCollection,\n Point,\n MultiLineString,\n Feature,\n GeoJsonProperties,\n Position,\n} from \"geojson\";\n\n/**\n * Takes a grid {@link FeatureCollection} of {@link Point} features with z-values and an array of\n * value breaks and generates [isolines](https://en.wikipedia.org/wiki/Contour_line).\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 values of `zProperty` where to draw isolines\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 {Object} [options.commonProperties={}] GeoJSON properties passed to ALL isolines\n * @param {Array<Object>} [options.breaksProperties=[]] GeoJSON properties passed, in order, to the correspondent isoline;\n * the breaks array will define the order in which the isolines are created\n * @returns {FeatureCollection<MultiLineString>} a FeatureCollection of {@link MultiLineString} features representing isolines\n * @example\n * // create a grid of points with random z-values in their properties\n * var extent = [0, 30, 20, 50];\n * var cellWidth = 100;\n * var pointGrid = turf.pointGrid(extent, cellWidth, {units: 'miles'});\n *\n * for (var i = 0; i < pointGrid.features.length; i++) {\n * pointGrid.features[i].properties.temperature = Math.random() * 10;\n * }\n * var breaks = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n *\n * var lines = turf.isolines(pointGrid, breaks, {zProperty: 'temperature'});\n *\n * //addToMap\n * var addToMap = [lines];\n */\nfunction isolines(\n pointGrid: FeatureCollection<Point>,\n breaks: number[],\n options?: {\n zProperty?: string;\n commonProperties?: GeoJsonProperties;\n breaksProperties?: GeoJsonProperties[];\n }\n) {\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 // Input 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 must be an Array\");\n if (!isObject(commonProperties))\n throw new Error(\"commonProperties must be an Object\");\n if (!Array.isArray(breaksProperties))\n throw new Error(\"breaksProperties must be an Array\");\n\n // Isoline 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 const createdIsoLines = createIsoLines(\n matrix,\n breaks,\n zProperty,\n commonProperties,\n breaksProperties\n );\n const scaledIsolines = rescaleIsolines(createdIsoLines, matrix, pointGrid);\n\n return featureCollection(scaledIsolines);\n}\n\n/**\n * Creates the isolines lines (featuresCollection of MultiLineString 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 isolines 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 BreakProps\n * @param {string} zProperty name of the z-values property\n * @param {Object} [commonProperties={}] GeoJSON properties passed to ALL isolines\n * @param {Object} [breaksProperties=[]] GeoJSON properties passed to the correspondent isoline\n * @returns {Array<MultiLineString>} isolines\n */\nfunction createIsoLines(\n matrix: number[][],\n breaks: number[],\n zProperty: string,\n commonProperties: GeoJsonProperties,\n breaksProperties: GeoJsonProperties[]\n): Feature<MultiLineString>[] {\n const results = [];\n for (let i = 0; i < breaks.length; i++) {\n const threshold = +breaks[i]; // make sure it's a number\n\n const properties = { ...commonProperties, ...breaksProperties[i] };\n properties[zProperty] = threshold;\n const isoline = multiLineString(isoContours(matrix, threshold), properties);\n\n results.push(isoline);\n }\n return results;\n}\n\nfunction isoContours(\n matrix: ReadonlyArray<ReadonlyArray<number>>,\n threshold: number\n): Position[][] {\n // see https://en.wikipedia.org/wiki/Marching_squares\n const segments: [Position, Position][] = [];\n\n const dy = matrix.length;\n const dx = matrix[0].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 const contours: Position[][] = [];\n\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 } while (found);\n }\n\n return contours;\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 * Translates and scales isolines\n *\n * @private\n * @param {Array<MultiLineString>} createdIsoLines to be rescaled\n * @param {Array<Array<number>>} matrix Grid Data\n * @param {Object} points Points by Latitude\n * @returns {Array<MultiLineString>} isolines\n */\nfunction rescaleIsolines(\n createdIsoLines: Feature<MultiLineString>[],\n matrix: number[][],\n points: FeatureCollection<Point>\n) {\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\n // get number of cells per side\n const matrixWidth = matrix[0].length - 1;\n const matrixHeight = matrix.length - 1;\n\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 const resize = (point: number[]) => {\n point[0] = point[0] * scaleX + x0;\n point[1] = point[1] * scaleY + y0;\n };\n\n // resize and shift each point/line of the createdIsoLines\n createdIsoLines.forEach((isoline) => {\n coordEach(isoline, resize);\n });\n return createdIsoLines;\n}\n\nexport { isolines };\nexport default isolines;\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"]}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@turf/isolines",
3
- "version": "7.1.0",
4
- "description": "turf isolines module",
3
+ "version": "7.3.0",
4
+ "description": "Generate contour lines from a grid of data.",
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,30 +58,29 @@
57
58
  "test:types": "tsc --esModuleInterop --module node16 --moduleResolution node16 --noEmit --strict types.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/bbox": "^7.1.0",
78
- "@turf/helpers": "^7.1.0",
79
- "@turf/invariant": "^7.1.0",
80
- "@turf/meta": "^7.1.0",
78
+ "@turf/bbox": "7.3.0",
79
+ "@turf/helpers": "7.3.0",
80
+ "@turf/invariant": "7.3.0",
81
+ "@turf/meta": "7.3.0",
81
82
  "@types/geojson": "^7946.0.10",
82
- "marchingsquares": "^1.3.3",
83
- "tslib": "^2.6.2"
83
+ "tslib": "^2.8.1"
84
84
  },
85
- "gitHead": "68915eeebc9278bb40dec3f1034499698a0561ef"
85
+ "gitHead": "9f58a103e8f9a587ab640307ed03ba5233913ddd"
86
86
  }