{"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 * @function\n * @param {FeatureCollection} pointGrid input points\n * @param {Array} 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} [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} 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,\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>} matrix Grid Data\n * @param {Array} 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} isolines\n */\nfunction createIsoLines(\n matrix: number[][],\n breaks: number[],\n zProperty: string,\n commonProperties: GeoJsonProperties,\n breaksProperties: GeoJsonProperties[]\n): Feature[] {\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} createdIsoLines to be rescaled\n * @param {Array>} matrix Grid Data\n * @param {Object} points Points by Latitude\n * @returns {Array} isolines\n */\nfunction rescaleIsolines(\n createdIsoLines: Feature[],\n matrix: number[][],\n points: FeatureCollection\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>}\n * of the 'property' values\n *\n * @name gridToMatrix\n * @param {FeatureCollection} 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>} 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} points GeoJSON Point features\n * @param {boolean} [flip=false] returns the matrix upside-down\n * @returns {Array>} 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"]}