all these changes

This commit is contained in:
Jake Kasper
2026-04-09 13:19:47 -05:00
parent e83a51a051
commit 65315f36d1
39102 changed files with 7932979 additions and 567 deletions

20
frontend/node_modules/@turf/isolines/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2017 TurfJS
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

86
frontend/node_modules/@turf/isolines/README.md generated vendored Normal file
View File

@@ -0,0 +1,86 @@
# @turf/isolines
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
## isolines
Takes a grid [FeatureCollection][1] of [Point][2] features with z-values and an array of
value breaks and generates [isolines][3].
**Parameters**
- `pointGrid` **[FeatureCollection][4]&lt;[Point][5]>** input points
- `breaks` **[Array][6]&lt;[number][7]>** values of `zProperty` where to draw isolines
- `options` **[Object][8]** Optional parameters (optional, default `{}`)
- `options.zProperty` **[string][9]** the property name in `points` from which z-values will be pulled (optional, default `'elevation'`)
- `options.commonProperties` **[Object][8]** GeoJSON properties passed to ALL isolines (optional, default `{}`)
- `options.breaksProperties` **[Array][6]&lt;[Object][8]>** GeoJSON properties passed, in order, to the correspondent isoline;
the breaks array will define the order in which the isolines are created (optional, default `[]`)
**Examples**
```javascript
// create a grid of points with random z-values in their properties
var extent = [0, 30, 20, 50];
var cellWidth = 100;
var pointGrid = turf.pointGrid(extent, cellWidth, {units: 'miles'});
for (var i = 0; i < pointGrid.features.length; i++) {
pointGrid.features[i].properties.temperature = Math.random() * 10;
}
var breaks = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var lines = turf.isolines(pointGrid, breaks, {zProperty: 'temperature'});
//addToMap
var addToMap = [lines];
```
Returns **[FeatureCollection][4]&lt;[MultiLineString][10]>** a FeatureCollection of [MultiLineString][11] features representing isolines
[1]: https://tools.ietf.org/html/rfc7946#section-3.3
[2]: https://tools.ietf.org/html/rfc7946#section-3.1.2
[3]: http://en.wikipedia.org/wiki/Isoline
[4]: https://tools.ietf.org/html/rfc7946#section-3.3
[5]: https://tools.ietf.org/html/rfc7946#section-3.1.2
[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
[10]: https://tools.ietf.org/html/rfc7946#section-3.1.5
[11]: https://tools.ietf.org/html/rfc7946#section-3.1.5
<!-- This file is automatically generated. Please don't edit it directly:
if you find an error, edit the source file (likely index.js), and re-run
./scripts/generate-readmes in the turf project. -->
---
This module is part of the [Turfjs project](http://turfjs.org/), an open source
module collection dedicated to geographic algorithms. It is maintained in the
[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create
PRs and issues.
### Installation
Install this module individually:
```sh
$ npm install @turf/isolines
```
Or install the Turf module that includes it as a function:
```sh
$ npm install @turf/turf
```

647
frontend/node_modules/@turf/isolines/dist/es/index.js generated vendored Executable file
View File

@@ -0,0 +1,647 @@
import bbox from '@turf/bbox';
import { featureEach, coordEach } from '@turf/meta';
import { collectionOf, getCoords } from '@turf/invariant';
import { isObject, featureCollection, multiLineString } from '@turf/helpers';
import objectAssign from 'object-assign';
/**
* @license GNU Affero General Public License.
* Copyright (c) 2015, 2015 Ronny Lorenz <ronny@tbi.univie.ac.at>
* v. 1.2.0
* https://github.com/RaumZeit/MarchingSquares.js
*
* MarchingSquaresJS is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MarchingSquaresJS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* As additional permission under GNU Affero General Public License version 3
* section 7, third-party projects (personal or commercial) may distribute,
* include, or link against UNMODIFIED VERSIONS of MarchingSquaresJS without the
* requirement that said third-party project for that reason alone becomes
* subject to any requirement of the GNU Affero General Public License version 3.
* Any modifications to MarchingSquaresJS, however, must be shared with the public
* and made available.
*
* In summary this:
* - allows you to use MarchingSquaresJS at no cost
* - allows you to use MarchingSquaresJS for both personal and commercial purposes
* - allows you to distribute UNMODIFIED VERSIONS of MarchingSquaresJS under any
* license as long as this license notice is included
* - enables you to keep the source code of your program that uses MarchingSquaresJS
* undisclosed
* - forces you to share any modifications you have made to MarchingSquaresJS,
* e.g. bug-fixes
*
* You should have received a copy of the GNU Affero General Public License
* along with MarchingSquaresJS. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Compute the isocontour(s) of a scalar 2D field given
* a certain threshold by applying the Marching Squares
* Algorithm. The function returns a list of path coordinates
*/
var defaultSettings = {
successCallback: null,
verbose: false,
};
var settings = {};
function isoContours(data, threshold, options) {
/* process options */
options = options ? options : {};
var optionKeys = Object.keys(defaultSettings);
for (var i = 0; i < optionKeys.length; i++) {
var key = optionKeys[i];
var val = options[key];
val =
typeof val !== "undefined" && val !== null ? val : defaultSettings[key];
settings[key] = val;
}
if (settings.verbose)
console.log(
"MarchingSquaresJS-isoContours: computing isocontour for " + threshold
);
var ret = contourGrid2Paths(computeContourGrid(data, threshold));
if (typeof settings.successCallback === "function")
settings.successCallback(ret);
return ret;
}
/*
Thats all for the public interface, below follows the actual
implementation
*/
/*
################################
Isocontour implementation below
################################
*/
/* assume that x1 == 1 && x0 == 0 */
function interpolateX(y, y0, y1) {
return (y - y0) / (y1 - y0);
}
/* compute the isocontour 4-bit grid */
function computeContourGrid(data, threshold) {
var rows = data.length - 1;
var cols = data[0].length - 1;
var ContourGrid = { rows: rows, cols: cols, cells: [] };
for (var j = 0; j < rows; ++j) {
ContourGrid.cells[j] = [];
for (var i = 0; i < cols; ++i) {
/* compose the 4-bit corner representation */
var cval = 0;
var tl = data[j + 1][i];
var tr = data[j + 1][i + 1];
var br = data[j][i + 1];
var bl = data[j][i];
if (isNaN(tl) || isNaN(tr) || isNaN(br) || isNaN(bl)) {
continue;
}
cval |= tl >= threshold ? 8 : 0;
cval |= tr >= threshold ? 4 : 0;
cval |= br >= threshold ? 2 : 0;
cval |= bl >= threshold ? 1 : 0;
/* resolve ambiguity for cval == 5 || 10 via averaging */
var flipped = false;
if (cval === 5 || cval === 10) {
var average = (tl + tr + br + bl) / 4;
if (cval === 5 && average < threshold) {
cval = 10;
flipped = true;
} else if (cval === 10 && average < threshold) {
cval = 5;
flipped = true;
}
}
/* add cell to ContourGrid if it contains edges */
if (cval !== 0 && cval !== 15) {
var top, bottom, left, right;
top = bottom = left = right = 0.5;
/* interpolate edges of cell */
if (cval === 1) {
left = 1 - interpolateX(threshold, tl, bl);
bottom = 1 - interpolateX(threshold, br, bl);
} else if (cval === 2) {
bottom = interpolateX(threshold, bl, br);
right = 1 - interpolateX(threshold, tr, br);
} else if (cval === 3) {
left = 1 - interpolateX(threshold, tl, bl);
right = 1 - interpolateX(threshold, tr, br);
} else if (cval === 4) {
top = interpolateX(threshold, tl, tr);
right = interpolateX(threshold, br, tr);
} else if (cval === 5) {
top = interpolateX(threshold, tl, tr);
right = interpolateX(threshold, br, tr);
bottom = 1 - interpolateX(threshold, br, bl);
left = 1 - interpolateX(threshold, tl, bl);
} else if (cval === 6) {
bottom = interpolateX(threshold, bl, br);
top = interpolateX(threshold, tl, tr);
} else if (cval === 7) {
left = 1 - interpolateX(threshold, tl, bl);
top = interpolateX(threshold, tl, tr);
} else if (cval === 8) {
left = interpolateX(threshold, bl, tl);
top = 1 - interpolateX(threshold, tr, tl);
} else if (cval === 9) {
bottom = 1 - interpolateX(threshold, br, bl);
top = 1 - interpolateX(threshold, tr, tl);
} else if (cval === 10) {
top = 1 - interpolateX(threshold, tr, tl);
right = 1 - interpolateX(threshold, tr, br);
bottom = interpolateX(threshold, bl, br);
left = interpolateX(threshold, bl, tl);
} else if (cval === 11) {
top = 1 - interpolateX(threshold, tr, tl);
right = 1 - interpolateX(threshold, tr, br);
} else if (cval === 12) {
left = interpolateX(threshold, bl, tl);
right = interpolateX(threshold, br, tr);
} else if (cval === 13) {
bottom = 1 - interpolateX(threshold, br, bl);
right = interpolateX(threshold, br, tr);
} else if (cval === 14) {
left = interpolateX(threshold, bl, tl);
bottom = interpolateX(threshold, bl, br);
} else {
console.log(
"MarchingSquaresJS-isoContours: Illegal cval detected: " + cval
);
}
ContourGrid.cells[j][i] = {
cval: cval,
flipped: flipped,
top: top,
right: right,
bottom: bottom,
left: left,
};
}
}
}
return ContourGrid;
}
function isSaddle(cell) {
return cell.cval === 5 || cell.cval === 10;
}
function isTrivial(cell) {
return cell.cval === 0 || cell.cval === 15;
}
function clearCell(cell) {
if (!isTrivial(cell) && cell.cval !== 5 && cell.cval !== 10) {
cell.cval = 15;
}
}
function getXY(cell, edge) {
if (edge === "top") {
return [cell.top, 1.0];
} else if (edge === "bottom") {
return [cell.bottom, 0.0];
} else if (edge === "right") {
return [1.0, cell.right];
} else if (edge === "left") {
return [0.0, cell.left];
}
}
function contourGrid2Paths(grid) {
var paths = [];
var path_idx = 0;
var epsilon = 1e-7;
grid.cells.forEach(function (g, j) {
g.forEach(function (gg, i) {
if (typeof gg !== "undefined" && !isSaddle(gg) && !isTrivial(gg)) {
var p = tracePath(grid.cells, j, i);
var merged = false;
/* we may try to merge paths at this point */
if (p.info === "mergeable") {
/*
search backwards through the path array to find an entry
that starts with where the current path ends...
*/
var x = p.path[p.path.length - 1][0],
y = p.path[p.path.length - 1][1];
for (var k = path_idx - 1; k >= 0; k--) {
if (
Math.abs(paths[k][0][0] - x) <= epsilon &&
Math.abs(paths[k][0][1] - y) <= epsilon
) {
for (var l = p.path.length - 2; l >= 0; --l) {
paths[k].unshift(p.path[l]);
}
merged = true;
break;
}
}
}
if (!merged) paths[path_idx++] = p.path;
}
});
});
return paths;
}
/*
construct consecutive line segments from starting cell by
walking arround the enclosed area clock-wise
*/
function tracePath(grid, j, i) {
var maxj = grid.length;
var p = [];
var dxContour = [0, 0, 1, 1, 0, 0, 0, 0, -1, 0, 1, 1, -1, 0, -1, 0];
var dyContour = [0, -1, 0, 0, 1, 1, 1, 1, 0, -1, 0, 0, 0, -1, 0, 0];
var dx, dy;
var startEdge = [
"none",
"left",
"bottom",
"left",
"right",
"none",
"bottom",
"left",
"top",
"top",
"none",
"top",
"right",
"right",
"bottom",
"none",
];
var nextEdge = [
"none",
"bottom",
"right",
"right",
"top",
"top",
"top",
"top",
"left",
"bottom",
"right",
"right",
"left",
"bottom",
"left",
"none",
];
var edge;
var currentCell = grid[j][i];
var cval = currentCell.cval;
var edge = startEdge[cval];
var pt = getXY(currentCell, edge);
/* push initial segment */
p.push([i + pt[0], j + pt[1]]);
edge = nextEdge[cval];
pt = getXY(currentCell, edge);
p.push([i + pt[0], j + pt[1]]);
clearCell(currentCell);
/* now walk arround the enclosed area in clockwise-direction */
var k = i + dxContour[cval];
var l = j + dyContour[cval];
var prev_cval = cval;
while (k >= 0 && l >= 0 && l < maxj && (k != i || l != j)) {
currentCell = grid[l][k];
if (typeof currentCell === "undefined") {
/* path ends here */
//console.log(k + " " + l + " is undefined, stopping path!");
break;
}
cval = currentCell.cval;
if (cval === 0 || cval === 15) {
return { path: p, info: "mergeable" };
}
edge = nextEdge[cval];
dx = dxContour[cval];
dy = dyContour[cval];
if (cval === 5 || cval === 10) {
/* select upper or lower band, depending on previous cells cval */
if (cval === 5) {
if (currentCell.flipped) {
/* this is actually a flipped case 10 */
if (dyContour[prev_cval] === -1) {
edge = "left";
dx = -1;
dy = 0;
} else {
edge = "right";
dx = 1;
dy = 0;
}
} else {
/* real case 5 */
if (dxContour[prev_cval] === -1) {
edge = "bottom";
dx = 0;
dy = -1;
}
}
} else if (cval === 10) {
if (currentCell.flipped) {
/* this is actually a flipped case 5 */
if (dxContour[prev_cval] === -1) {
edge = "top";
dx = 0;
dy = 1;
} else {
edge = "bottom";
dx = 0;
dy = -1;
}
} else {
/* real case 10 */
if (dyContour[prev_cval] === 1) {
edge = "left";
dx = -1;
dy = 0;
}
}
}
}
pt = getXY(currentCell, edge);
p.push([k + pt[0], l + pt[1]]);
clearCell(currentCell);
k += dx;
l += dy;
prev_cval = cval;
}
return { path: p, info: "closed" };
}
/**
* Takes a {@link Point} grid and returns a correspondent matrix {Array<Array<number>>}
* of the 'property' values
*
* @name gridToMatrix
* @param {FeatureCollection<Point>} grid of points
* @param {Object} [options={}] Optional parameters
* @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled
* @param {boolean} [options.flip=false] returns the matrix upside-down
* @param {boolean} [options.flags=false] flags, adding a `matrixPosition` array field ([row, column]) to its properties,
* the grid points with coordinates on the matrix
* @returns {Array<Array<number>>} matrix of property values
* @example
* var extent = [-70.823364, -33.553984, -70.473175, -33.302986];
* var cellSize = 3;
* var grid = turf.pointGrid(extent, cellSize);
* // add a random property to each point between 0 and 60
* for (var i = 0; i < grid.features.length; i++) {
* grid.features[i].properties.elevation = (Math.random() * 60);
* }
* gridToMatrix(grid);
* //= [
* [ 1, 13, 10, 9, 10, 13, 18],
* [34, 8, 5, 4, 5, 8, 13],
* [10, 5, 2, 1, 2, 5, 4],
* [ 0, 4, 56, 19, 1, 4, 9],
* [10, 5, 2, 1, 2, 5, 10],
* [57, 8, 5, 4, 5, 0, 57],
* [ 3, 13, 10, 9, 5, 13, 18],
* [18, 13, 10, 9, 78, 13, 18]
* ]
*/
function gridToMatrix(grid, options) {
// Optional parameters
options = options || {};
if (!isObject(options)) throw new Error("options is invalid");
var zProperty = options.zProperty || "elevation";
var flip = options.flip;
var flags = options.flags;
// validation
collectionOf(grid, "Point", "input must contain Points");
var pointsMatrix = sortPointsByLatLng(grid, flip);
var matrix = [];
// create property matrix from sorted points
// looping order matters here
for (var r = 0; r < pointsMatrix.length; r++) {
var pointRow = pointsMatrix[r];
var row = [];
for (var c = 0; c < pointRow.length; c++) {
var point = pointRow[c];
// Check if zProperty exist
if (point.properties[zProperty]) row.push(point.properties[zProperty]);
else row.push(0);
// add flags
if (flags === true) point.properties.matrixPosition = [r, c];
}
matrix.push(row);
}
return matrix;
}
/**
* Sorts points by latitude and longitude, creating a 2-dimensional array of points
*
* @private
* @param {FeatureCollection<Point>} points GeoJSON Point features
* @param {boolean} [flip=false] returns the matrix upside-down
* @returns {Array<Array<Point>>} points ordered by latitude and longitude
*/
function sortPointsByLatLng(points, flip) {
var pointsByLatitude = {};
// divide points by rows with the same latitude
featureEach(points, function (point) {
var lat = getCoords(point)[1];
if (!pointsByLatitude[lat]) pointsByLatitude[lat] = [];
pointsByLatitude[lat].push(point);
});
// sort points (with the same latitude) by longitude
var orderedRowsByLatitude = Object.keys(pointsByLatitude).map(function (lat) {
var row = pointsByLatitude[lat];
var rowOrderedByLongitude = row.sort(function (a, b) {
return getCoords(a)[0] - getCoords(b)[0];
});
return rowOrderedByLongitude;
});
// sort rows (of points with the same latitude) by latitude
var pointMatrix = orderedRowsByLatitude.sort(function (a, b) {
if (flip) return getCoords(a[0])[1] - getCoords(b[0])[1];
else return getCoords(b[0])[1] - getCoords(a[0])[1];
});
return pointMatrix;
}
/**
* Takes a grid {@link FeatureCollection} of {@link Point} features with z-values and an array of
* value breaks and generates [isolines](https://en.wikipedia.org/wiki/Contour_line).
*
* @name isolines
* @param {FeatureCollection<Point>} pointGrid input points
* @param {Array<number>} breaks values of `zProperty` where to draw isolines
* @param {Object} [options={}] Optional parameters
* @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled
* @param {Object} [options.commonProperties={}] GeoJSON properties passed to ALL isolines
* @param {Array<Object>} [options.breaksProperties=[]] GeoJSON properties passed, in order, to the correspondent isoline;
* the breaks array will define the order in which the isolines are created
* @returns {FeatureCollection<MultiLineString>} a FeatureCollection of {@link MultiLineString} features representing isolines
* @example
* // create a grid of points with random z-values in their properties
* var extent = [0, 30, 20, 50];
* var cellWidth = 100;
* var pointGrid = turf.pointGrid(extent, cellWidth, {units: 'miles'});
*
* for (var i = 0; i < pointGrid.features.length; i++) {
* pointGrid.features[i].properties.temperature = Math.random() * 10;
* }
* var breaks = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
*
* var lines = turf.isolines(pointGrid, breaks, {zProperty: 'temperature'});
*
* //addToMap
* var addToMap = [lines];
*/
function isolines(pointGrid, breaks, options) {
// Optional parameters
options = options || {};
if (!isObject(options)) throw new Error("options is invalid");
var zProperty = options.zProperty || "elevation";
var commonProperties = options.commonProperties || {};
var breaksProperties = options.breaksProperties || [];
// Input validation
collectionOf(pointGrid, "Point", "Input must contain Points");
if (!breaks) throw new Error("breaks is required");
if (!Array.isArray(breaks)) throw new Error("breaks must be an Array");
if (!isObject(commonProperties))
throw new Error("commonProperties must be an Object");
if (!Array.isArray(breaksProperties))
throw new Error("breaksProperties must be an Array");
// Isoline methods
var matrix = gridToMatrix(pointGrid, { zProperty: zProperty, flip: true });
var createdIsoLines = createIsoLines(
matrix,
breaks,
zProperty,
commonProperties,
breaksProperties
);
var scaledIsolines = rescaleIsolines(createdIsoLines, matrix, pointGrid);
return featureCollection(scaledIsolines);
}
/**
* Creates the isolines lines (featuresCollection of MultiLineString features) from the 2D data grid
*
* Marchingsquares process the grid data as a 3D representation of a function on a 2D plane, therefore it
* assumes the points (x-y coordinates) are one 'unit' distance. The result of the isolines function needs to be
* rescaled, with turfjs, to the original area and proportions on the map
*
* @private
* @param {Array<Array<number>>} matrix Grid Data
* @param {Array<number>} breaks Breaks
* @param {string} zProperty name of the z-values property
* @param {Object} [commonProperties={}] GeoJSON properties passed to ALL isolines
* @param {Object} [breaksProperties=[]] GeoJSON properties passed to the correspondent isoline
* @returns {Array<MultiLineString>} isolines
*/
function createIsoLines(
matrix,
breaks,
zProperty,
commonProperties,
breaksProperties
) {
var results = [];
for (var i = 1; i < breaks.length; i++) {
var threshold = +breaks[i]; // make sure it's a number
var properties = objectAssign({}, commonProperties, breaksProperties[i]);
properties[zProperty] = threshold;
var isoline = multiLineString(isoContours(matrix, threshold), properties);
results.push(isoline);
}
return results;
}
/**
* Translates and scales isolines
*
* @private
* @param {Array<MultiLineString>} createdIsoLines to be rescaled
* @param {Array<Array<number>>} matrix Grid Data
* @param {Object} points Points by Latitude
* @returns {Array<MultiLineString>} isolines
*/
function rescaleIsolines(createdIsoLines, matrix, points) {
// get dimensions (on the map) of the original grid
var gridBbox = bbox(points); // [ minX, minY, maxX, maxY ]
var originalWidth = gridBbox[2] - gridBbox[0];
var originalHeigth = gridBbox[3] - gridBbox[1];
// get origin, which is the first point of the last row on the rectangular data on the map
var x0 = gridBbox[0];
var y0 = gridBbox[1];
// get number of cells per side
var matrixWidth = matrix[0].length - 1;
var matrixHeight = matrix.length - 1;
// calculate the scaling factor between matrix and rectangular grid on the map
var scaleX = originalWidth / matrixWidth;
var scaleY = originalHeigth / matrixHeight;
var resize = function (point) {
point[0] = point[0] * scaleX + x0;
point[1] = point[1] * scaleY + y0;
};
// resize and shift each point/line of the createdIsoLines
createdIsoLines.forEach(function (isoline) {
coordEach(isoline, resize);
});
return createdIsoLines;
}
export default isolines;

View File

@@ -0,0 +1 @@
{"type":"module"}

655
frontend/node_modules/@turf/isolines/dist/js/index.js generated vendored Executable file
View File

@@ -0,0 +1,655 @@
'use strict';
var bbox = require('@turf/bbox');
var meta = require('@turf/meta');
var invariant = require('@turf/invariant');
var helpers = require('@turf/helpers');
var objectAssign = require('object-assign');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var bbox__default = /*#__PURE__*/_interopDefaultLegacy(bbox);
var objectAssign__default = /*#__PURE__*/_interopDefaultLegacy(objectAssign);
/**
* @license GNU Affero General Public License.
* Copyright (c) 2015, 2015 Ronny Lorenz <ronny@tbi.univie.ac.at>
* v. 1.2.0
* https://github.com/RaumZeit/MarchingSquares.js
*
* MarchingSquaresJS is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MarchingSquaresJS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* As additional permission under GNU Affero General Public License version 3
* section 7, third-party projects (personal or commercial) may distribute,
* include, or link against UNMODIFIED VERSIONS of MarchingSquaresJS without the
* requirement that said third-party project for that reason alone becomes
* subject to any requirement of the GNU Affero General Public License version 3.
* Any modifications to MarchingSquaresJS, however, must be shared with the public
* and made available.
*
* In summary this:
* - allows you to use MarchingSquaresJS at no cost
* - allows you to use MarchingSquaresJS for both personal and commercial purposes
* - allows you to distribute UNMODIFIED VERSIONS of MarchingSquaresJS under any
* license as long as this license notice is included
* - enables you to keep the source code of your program that uses MarchingSquaresJS
* undisclosed
* - forces you to share any modifications you have made to MarchingSquaresJS,
* e.g. bug-fixes
*
* You should have received a copy of the GNU Affero General Public License
* along with MarchingSquaresJS. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Compute the isocontour(s) of a scalar 2D field given
* a certain threshold by applying the Marching Squares
* Algorithm. The function returns a list of path coordinates
*/
var defaultSettings = {
successCallback: null,
verbose: false,
};
var settings = {};
function isoContours(data, threshold, options) {
/* process options */
options = options ? options : {};
var optionKeys = Object.keys(defaultSettings);
for (var i = 0; i < optionKeys.length; i++) {
var key = optionKeys[i];
var val = options[key];
val =
typeof val !== "undefined" && val !== null ? val : defaultSettings[key];
settings[key] = val;
}
if (settings.verbose)
console.log(
"MarchingSquaresJS-isoContours: computing isocontour for " + threshold
);
var ret = contourGrid2Paths(computeContourGrid(data, threshold));
if (typeof settings.successCallback === "function")
settings.successCallback(ret);
return ret;
}
/*
Thats all for the public interface, below follows the actual
implementation
*/
/*
################################
Isocontour implementation below
################################
*/
/* assume that x1 == 1 && x0 == 0 */
function interpolateX(y, y0, y1) {
return (y - y0) / (y1 - y0);
}
/* compute the isocontour 4-bit grid */
function computeContourGrid(data, threshold) {
var rows = data.length - 1;
var cols = data[0].length - 1;
var ContourGrid = { rows: rows, cols: cols, cells: [] };
for (var j = 0; j < rows; ++j) {
ContourGrid.cells[j] = [];
for (var i = 0; i < cols; ++i) {
/* compose the 4-bit corner representation */
var cval = 0;
var tl = data[j + 1][i];
var tr = data[j + 1][i + 1];
var br = data[j][i + 1];
var bl = data[j][i];
if (isNaN(tl) || isNaN(tr) || isNaN(br) || isNaN(bl)) {
continue;
}
cval |= tl >= threshold ? 8 : 0;
cval |= tr >= threshold ? 4 : 0;
cval |= br >= threshold ? 2 : 0;
cval |= bl >= threshold ? 1 : 0;
/* resolve ambiguity for cval == 5 || 10 via averaging */
var flipped = false;
if (cval === 5 || cval === 10) {
var average = (tl + tr + br + bl) / 4;
if (cval === 5 && average < threshold) {
cval = 10;
flipped = true;
} else if (cval === 10 && average < threshold) {
cval = 5;
flipped = true;
}
}
/* add cell to ContourGrid if it contains edges */
if (cval !== 0 && cval !== 15) {
var top, bottom, left, right;
top = bottom = left = right = 0.5;
/* interpolate edges of cell */
if (cval === 1) {
left = 1 - interpolateX(threshold, tl, bl);
bottom = 1 - interpolateX(threshold, br, bl);
} else if (cval === 2) {
bottom = interpolateX(threshold, bl, br);
right = 1 - interpolateX(threshold, tr, br);
} else if (cval === 3) {
left = 1 - interpolateX(threshold, tl, bl);
right = 1 - interpolateX(threshold, tr, br);
} else if (cval === 4) {
top = interpolateX(threshold, tl, tr);
right = interpolateX(threshold, br, tr);
} else if (cval === 5) {
top = interpolateX(threshold, tl, tr);
right = interpolateX(threshold, br, tr);
bottom = 1 - interpolateX(threshold, br, bl);
left = 1 - interpolateX(threshold, tl, bl);
} else if (cval === 6) {
bottom = interpolateX(threshold, bl, br);
top = interpolateX(threshold, tl, tr);
} else if (cval === 7) {
left = 1 - interpolateX(threshold, tl, bl);
top = interpolateX(threshold, tl, tr);
} else if (cval === 8) {
left = interpolateX(threshold, bl, tl);
top = 1 - interpolateX(threshold, tr, tl);
} else if (cval === 9) {
bottom = 1 - interpolateX(threshold, br, bl);
top = 1 - interpolateX(threshold, tr, tl);
} else if (cval === 10) {
top = 1 - interpolateX(threshold, tr, tl);
right = 1 - interpolateX(threshold, tr, br);
bottom = interpolateX(threshold, bl, br);
left = interpolateX(threshold, bl, tl);
} else if (cval === 11) {
top = 1 - interpolateX(threshold, tr, tl);
right = 1 - interpolateX(threshold, tr, br);
} else if (cval === 12) {
left = interpolateX(threshold, bl, tl);
right = interpolateX(threshold, br, tr);
} else if (cval === 13) {
bottom = 1 - interpolateX(threshold, br, bl);
right = interpolateX(threshold, br, tr);
} else if (cval === 14) {
left = interpolateX(threshold, bl, tl);
bottom = interpolateX(threshold, bl, br);
} else {
console.log(
"MarchingSquaresJS-isoContours: Illegal cval detected: " + cval
);
}
ContourGrid.cells[j][i] = {
cval: cval,
flipped: flipped,
top: top,
right: right,
bottom: bottom,
left: left,
};
}
}
}
return ContourGrid;
}
function isSaddle(cell) {
return cell.cval === 5 || cell.cval === 10;
}
function isTrivial(cell) {
return cell.cval === 0 || cell.cval === 15;
}
function clearCell(cell) {
if (!isTrivial(cell) && cell.cval !== 5 && cell.cval !== 10) {
cell.cval = 15;
}
}
function getXY(cell, edge) {
if (edge === "top") {
return [cell.top, 1.0];
} else if (edge === "bottom") {
return [cell.bottom, 0.0];
} else if (edge === "right") {
return [1.0, cell.right];
} else if (edge === "left") {
return [0.0, cell.left];
}
}
function contourGrid2Paths(grid) {
var paths = [];
var path_idx = 0;
var epsilon = 1e-7;
grid.cells.forEach(function (g, j) {
g.forEach(function (gg, i) {
if (typeof gg !== "undefined" && !isSaddle(gg) && !isTrivial(gg)) {
var p = tracePath(grid.cells, j, i);
var merged = false;
/* we may try to merge paths at this point */
if (p.info === "mergeable") {
/*
search backwards through the path array to find an entry
that starts with where the current path ends...
*/
var x = p.path[p.path.length - 1][0],
y = p.path[p.path.length - 1][1];
for (var k = path_idx - 1; k >= 0; k--) {
if (
Math.abs(paths[k][0][0] - x) <= epsilon &&
Math.abs(paths[k][0][1] - y) <= epsilon
) {
for (var l = p.path.length - 2; l >= 0; --l) {
paths[k].unshift(p.path[l]);
}
merged = true;
break;
}
}
}
if (!merged) paths[path_idx++] = p.path;
}
});
});
return paths;
}
/*
construct consecutive line segments from starting cell by
walking arround the enclosed area clock-wise
*/
function tracePath(grid, j, i) {
var maxj = grid.length;
var p = [];
var dxContour = [0, 0, 1, 1, 0, 0, 0, 0, -1, 0, 1, 1, -1, 0, -1, 0];
var dyContour = [0, -1, 0, 0, 1, 1, 1, 1, 0, -1, 0, 0, 0, -1, 0, 0];
var dx, dy;
var startEdge = [
"none",
"left",
"bottom",
"left",
"right",
"none",
"bottom",
"left",
"top",
"top",
"none",
"top",
"right",
"right",
"bottom",
"none",
];
var nextEdge = [
"none",
"bottom",
"right",
"right",
"top",
"top",
"top",
"top",
"left",
"bottom",
"right",
"right",
"left",
"bottom",
"left",
"none",
];
var edge;
var currentCell = grid[j][i];
var cval = currentCell.cval;
var edge = startEdge[cval];
var pt = getXY(currentCell, edge);
/* push initial segment */
p.push([i + pt[0], j + pt[1]]);
edge = nextEdge[cval];
pt = getXY(currentCell, edge);
p.push([i + pt[0], j + pt[1]]);
clearCell(currentCell);
/* now walk arround the enclosed area in clockwise-direction */
var k = i + dxContour[cval];
var l = j + dyContour[cval];
var prev_cval = cval;
while (k >= 0 && l >= 0 && l < maxj && (k != i || l != j)) {
currentCell = grid[l][k];
if (typeof currentCell === "undefined") {
/* path ends here */
//console.log(k + " " + l + " is undefined, stopping path!");
break;
}
cval = currentCell.cval;
if (cval === 0 || cval === 15) {
return { path: p, info: "mergeable" };
}
edge = nextEdge[cval];
dx = dxContour[cval];
dy = dyContour[cval];
if (cval === 5 || cval === 10) {
/* select upper or lower band, depending on previous cells cval */
if (cval === 5) {
if (currentCell.flipped) {
/* this is actually a flipped case 10 */
if (dyContour[prev_cval] === -1) {
edge = "left";
dx = -1;
dy = 0;
} else {
edge = "right";
dx = 1;
dy = 0;
}
} else {
/* real case 5 */
if (dxContour[prev_cval] === -1) {
edge = "bottom";
dx = 0;
dy = -1;
}
}
} else if (cval === 10) {
if (currentCell.flipped) {
/* this is actually a flipped case 5 */
if (dxContour[prev_cval] === -1) {
edge = "top";
dx = 0;
dy = 1;
} else {
edge = "bottom";
dx = 0;
dy = -1;
}
} else {
/* real case 10 */
if (dyContour[prev_cval] === 1) {
edge = "left";
dx = -1;
dy = 0;
}
}
}
}
pt = getXY(currentCell, edge);
p.push([k + pt[0], l + pt[1]]);
clearCell(currentCell);
k += dx;
l += dy;
prev_cval = cval;
}
return { path: p, info: "closed" };
}
/**
* Takes a {@link Point} grid and returns a correspondent matrix {Array<Array<number>>}
* of the 'property' values
*
* @name gridToMatrix
* @param {FeatureCollection<Point>} grid of points
* @param {Object} [options={}] Optional parameters
* @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled
* @param {boolean} [options.flip=false] returns the matrix upside-down
* @param {boolean} [options.flags=false] flags, adding a `matrixPosition` array field ([row, column]) to its properties,
* the grid points with coordinates on the matrix
* @returns {Array<Array<number>>} matrix of property values
* @example
* var extent = [-70.823364, -33.553984, -70.473175, -33.302986];
* var cellSize = 3;
* var grid = turf.pointGrid(extent, cellSize);
* // add a random property to each point between 0 and 60
* for (var i = 0; i < grid.features.length; i++) {
* grid.features[i].properties.elevation = (Math.random() * 60);
* }
* gridToMatrix(grid);
* //= [
* [ 1, 13, 10, 9, 10, 13, 18],
* [34, 8, 5, 4, 5, 8, 13],
* [10, 5, 2, 1, 2, 5, 4],
* [ 0, 4, 56, 19, 1, 4, 9],
* [10, 5, 2, 1, 2, 5, 10],
* [57, 8, 5, 4, 5, 0, 57],
* [ 3, 13, 10, 9, 5, 13, 18],
* [18, 13, 10, 9, 78, 13, 18]
* ]
*/
function gridToMatrix(grid, options) {
// Optional parameters
options = options || {};
if (!helpers.isObject(options)) throw new Error("options is invalid");
var zProperty = options.zProperty || "elevation";
var flip = options.flip;
var flags = options.flags;
// validation
invariant.collectionOf(grid, "Point", "input must contain Points");
var pointsMatrix = sortPointsByLatLng(grid, flip);
var matrix = [];
// create property matrix from sorted points
// looping order matters here
for (var r = 0; r < pointsMatrix.length; r++) {
var pointRow = pointsMatrix[r];
var row = [];
for (var c = 0; c < pointRow.length; c++) {
var point = pointRow[c];
// Check if zProperty exist
if (point.properties[zProperty]) row.push(point.properties[zProperty]);
else row.push(0);
// add flags
if (flags === true) point.properties.matrixPosition = [r, c];
}
matrix.push(row);
}
return matrix;
}
/**
* Sorts points by latitude and longitude, creating a 2-dimensional array of points
*
* @private
* @param {FeatureCollection<Point>} points GeoJSON Point features
* @param {boolean} [flip=false] returns the matrix upside-down
* @returns {Array<Array<Point>>} points ordered by latitude and longitude
*/
function sortPointsByLatLng(points, flip) {
var pointsByLatitude = {};
// divide points by rows with the same latitude
meta.featureEach(points, function (point) {
var lat = invariant.getCoords(point)[1];
if (!pointsByLatitude[lat]) pointsByLatitude[lat] = [];
pointsByLatitude[lat].push(point);
});
// sort points (with the same latitude) by longitude
var orderedRowsByLatitude = Object.keys(pointsByLatitude).map(function (lat) {
var row = pointsByLatitude[lat];
var rowOrderedByLongitude = row.sort(function (a, b) {
return invariant.getCoords(a)[0] - invariant.getCoords(b)[0];
});
return rowOrderedByLongitude;
});
// sort rows (of points with the same latitude) by latitude
var pointMatrix = orderedRowsByLatitude.sort(function (a, b) {
if (flip) return invariant.getCoords(a[0])[1] - invariant.getCoords(b[0])[1];
else return invariant.getCoords(b[0])[1] - invariant.getCoords(a[0])[1];
});
return pointMatrix;
}
/**
* Takes a grid {@link FeatureCollection} of {@link Point} features with z-values and an array of
* value breaks and generates [isolines](https://en.wikipedia.org/wiki/Contour_line).
*
* @name isolines
* @param {FeatureCollection<Point>} pointGrid input points
* @param {Array<number>} breaks values of `zProperty` where to draw isolines
* @param {Object} [options={}] Optional parameters
* @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled
* @param {Object} [options.commonProperties={}] GeoJSON properties passed to ALL isolines
* @param {Array<Object>} [options.breaksProperties=[]] GeoJSON properties passed, in order, to the correspondent isoline;
* the breaks array will define the order in which the isolines are created
* @returns {FeatureCollection<MultiLineString>} a FeatureCollection of {@link MultiLineString} features representing isolines
* @example
* // create a grid of points with random z-values in their properties
* var extent = [0, 30, 20, 50];
* var cellWidth = 100;
* var pointGrid = turf.pointGrid(extent, cellWidth, {units: 'miles'});
*
* for (var i = 0; i < pointGrid.features.length; i++) {
* pointGrid.features[i].properties.temperature = Math.random() * 10;
* }
* var breaks = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
*
* var lines = turf.isolines(pointGrid, breaks, {zProperty: 'temperature'});
*
* //addToMap
* var addToMap = [lines];
*/
function isolines(pointGrid, breaks, options) {
// Optional parameters
options = options || {};
if (!helpers.isObject(options)) throw new Error("options is invalid");
var zProperty = options.zProperty || "elevation";
var commonProperties = options.commonProperties || {};
var breaksProperties = options.breaksProperties || [];
// Input validation
invariant.collectionOf(pointGrid, "Point", "Input must contain Points");
if (!breaks) throw new Error("breaks is required");
if (!Array.isArray(breaks)) throw new Error("breaks must be an Array");
if (!helpers.isObject(commonProperties))
throw new Error("commonProperties must be an Object");
if (!Array.isArray(breaksProperties))
throw new Error("breaksProperties must be an Array");
// Isoline methods
var matrix = gridToMatrix(pointGrid, { zProperty: zProperty, flip: true });
var createdIsoLines = createIsoLines(
matrix,
breaks,
zProperty,
commonProperties,
breaksProperties
);
var scaledIsolines = rescaleIsolines(createdIsoLines, matrix, pointGrid);
return helpers.featureCollection(scaledIsolines);
}
/**
* Creates the isolines lines (featuresCollection of MultiLineString features) from the 2D data grid
*
* Marchingsquares process the grid data as a 3D representation of a function on a 2D plane, therefore it
* assumes the points (x-y coordinates) are one 'unit' distance. The result of the isolines function needs to be
* rescaled, with turfjs, to the original area and proportions on the map
*
* @private
* @param {Array<Array<number>>} matrix Grid Data
* @param {Array<number>} breaks Breaks
* @param {string} zProperty name of the z-values property
* @param {Object} [commonProperties={}] GeoJSON properties passed to ALL isolines
* @param {Object} [breaksProperties=[]] GeoJSON properties passed to the correspondent isoline
* @returns {Array<MultiLineString>} isolines
*/
function createIsoLines(
matrix,
breaks,
zProperty,
commonProperties,
breaksProperties
) {
var results = [];
for (var i = 1; i < breaks.length; i++) {
var threshold = +breaks[i]; // make sure it's a number
var properties = objectAssign__default['default']({}, commonProperties, breaksProperties[i]);
properties[zProperty] = threshold;
var isoline = helpers.multiLineString(isoContours(matrix, threshold), properties);
results.push(isoline);
}
return results;
}
/**
* Translates and scales isolines
*
* @private
* @param {Array<MultiLineString>} createdIsoLines to be rescaled
* @param {Array<Array<number>>} matrix Grid Data
* @param {Object} points Points by Latitude
* @returns {Array<MultiLineString>} isolines
*/
function rescaleIsolines(createdIsoLines, matrix, points) {
// get dimensions (on the map) of the original grid
var gridBbox = bbox__default['default'](points); // [ minX, minY, maxX, maxY ]
var originalWidth = gridBbox[2] - gridBbox[0];
var originalHeigth = gridBbox[3] - gridBbox[1];
// get origin, which is the first point of the last row on the rectangular data on the map
var x0 = gridBbox[0];
var y0 = gridBbox[1];
// get number of cells per side
var matrixWidth = matrix[0].length - 1;
var matrixHeight = matrix.length - 1;
// calculate the scaling factor between matrix and rectangular grid on the map
var scaleX = originalWidth / matrixWidth;
var scaleY = originalHeigth / matrixHeight;
var resize = function (point) {
point[0] = point[0] * scaleX + x0;
point[1] = point[1] * scaleY + y0;
};
// resize and shift each point/line of the createdIsoLines
createdIsoLines.forEach(function (isoline) {
meta.coordEach(isoline, resize);
});
return createdIsoLines;
}
module.exports = isolines;
module.exports.default = isolines;

19
frontend/node_modules/@turf/isolines/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,19 @@
import {
Point,
MultiLineString,
FeatureCollection,
Properties,
} from "@turf/helpers";
/**
* http://turfjs.org/docs/#isolines
*/
export default function isolines(
points: FeatureCollection<Point, any>,
breaks: number[],
options?: {
zProperty?: string;
commonProperties?: Properties;
breaksProperties?: Properties[];
}
): FeatureCollection<MultiLineString>;

75
frontend/node_modules/@turf/isolines/package.json generated vendored Normal file
View File

@@ -0,0 +1,75 @@
{
"name": "@turf/isolines",
"version": "6.5.0",
"description": "turf isolines module",
"author": "Turf Authors",
"contributors": [
"Stefano Borghi <@stebogit>"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/Turfjs/turf/issues"
},
"homepage": "https://github.com/Turfjs/turf",
"repository": {
"type": "git",
"url": "git://github.com/Turfjs/turf.git"
},
"funding": "https://opencollective.com/turf",
"publishConfig": {
"access": "public"
},
"keywords": [
"turf",
"geojson",
"isolines",
"contours",
"elevation",
"topography"
],
"main": "dist/js/index.js",
"module": "dist/es/index.js",
"exports": {
"./package.json": "./package.json",
".": {
"import": "./dist/es/index.js",
"require": "./dist/js/index.js"
}
},
"types": "index.d.ts",
"sideEffects": false,
"files": [
"dist",
"index.d.ts"
],
"scripts": {
"bench": "node -r esm bench.js",
"build": "rollup -c ../../rollup.config.js && echo '{\"type\":\"module\"}' > dist/es/package.json",
"docs": "node ../../scripts/generate-readmes",
"test": "npm-run-all test:*",
"test:tape": "node -r esm test.js",
"test:types": "tsc --esModuleInterop --noEmit types.ts"
},
"devDependencies": {
"@turf/envelope": "^6.5.0",
"@turf/point-grid": "^6.5.0",
"@turf/random": "^6.5.0",
"@turf/rhumb-destination": "^6.5.0",
"@turf/truncate": "^6.5.0",
"benchmark": "*",
"load-json-file": "*",
"matrix-to-grid": "*",
"npm-run-all": "*",
"rollup": "*",
"tape": "*",
"write-json-file": "*"
},
"dependencies": {
"@turf/bbox": "^6.5.0",
"@turf/helpers": "^6.5.0",
"@turf/invariant": "^6.5.0",
"@turf/meta": "^6.5.0",
"object-assign": "*"
},
"gitHead": "5375941072b90d489389db22b43bfe809d5e451e"
}