Spaces:
Sleeping
Sleeping
| ; | |
| Object.defineProperty(exports, '__esModule', { value: true }); | |
| var helpers = require('@turf/helpers'); | |
| /** | |
| * Callback for coordEach | |
| * | |
| * @callback coordEachCallback | |
| * @param {Array<number>} currentCoord The current coordinate being processed. | |
| * @param {number} coordIndex The current index of the coordinate being processed. | |
| * @param {number} featureIndex The current index of the Feature being processed. | |
| * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. | |
| * @param {number} geometryIndex The current index of the Geometry being processed. | |
| */ | |
| /** | |
| * Iterate over coordinates in any GeoJSON object, similar to Array.forEach() | |
| * | |
| * @name coordEach | |
| * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object | |
| * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex) | |
| * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration. | |
| * @returns {void} | |
| * @example | |
| * var features = turf.featureCollection([ | |
| * turf.point([26, 37], {"foo": "bar"}), | |
| * turf.point([36, 53], {"hello": "world"}) | |
| * ]); | |
| * | |
| * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) { | |
| * //=currentCoord | |
| * //=coordIndex | |
| * //=featureIndex | |
| * //=multiFeatureIndex | |
| * //=geometryIndex | |
| * }); | |
| */ | |
| function coordEach(geojson, callback, excludeWrapCoord) { | |
| // Handles null Geometry -- Skips this GeoJSON | |
| if (geojson === null) return; | |
| var j, | |
| k, | |
| l, | |
| geometry, | |
| stopG, | |
| coords, | |
| geometryMaybeCollection, | |
| wrapShrink = 0, | |
| coordIndex = 0, | |
| isGeometryCollection, | |
| type = geojson.type, | |
| isFeatureCollection = type === "FeatureCollection", | |
| isFeature = type === "Feature", | |
| stop = isFeatureCollection ? geojson.features.length : 1; | |
| // This logic may look a little weird. The reason why it is that way | |
| // is because it's trying to be fast. GeoJSON supports multiple kinds | |
| // of objects at its root: FeatureCollection, Features, Geometries. | |
| // This function has the responsibility of handling all of them, and that | |
| // means that some of the `for` loops you see below actually just don't apply | |
| // to certain inputs. For instance, if you give this just a | |
| // Point geometry, then both loops are short-circuited and all we do | |
| // is gradually rename the input until it's called 'geometry'. | |
| // | |
| // This also aims to allocate as few resources as possible: just a | |
| // few numbers and booleans, rather than any temporary arrays as would | |
| // be required with the normalization approach. | |
| for (var featureIndex = 0; featureIndex < stop; featureIndex++) { | |
| geometryMaybeCollection = isFeatureCollection | |
| ? geojson.features[featureIndex].geometry | |
| : isFeature | |
| ? geojson.geometry | |
| : geojson; | |
| isGeometryCollection = geometryMaybeCollection | |
| ? geometryMaybeCollection.type === "GeometryCollection" | |
| : false; | |
| stopG = isGeometryCollection | |
| ? geometryMaybeCollection.geometries.length | |
| : 1; | |
| for (var geomIndex = 0; geomIndex < stopG; geomIndex++) { | |
| var multiFeatureIndex = 0; | |
| var geometryIndex = 0; | |
| geometry = isGeometryCollection | |
| ? geometryMaybeCollection.geometries[geomIndex] | |
| : geometryMaybeCollection; | |
| // Handles null Geometry -- Skips this geometry | |
| if (geometry === null) continue; | |
| coords = geometry.coordinates; | |
| var geomType = geometry.type; | |
| wrapShrink = | |
| excludeWrapCoord && | |
| (geomType === "Polygon" || geomType === "MultiPolygon") | |
| ? 1 | |
| : 0; | |
| switch (geomType) { | |
| case null: | |
| break; | |
| case "Point": | |
| if ( | |
| callback( | |
| coords, | |
| coordIndex, | |
| featureIndex, | |
| multiFeatureIndex, | |
| geometryIndex | |
| ) === false | |
| ) | |
| return false; | |
| coordIndex++; | |
| multiFeatureIndex++; | |
| break; | |
| case "LineString": | |
| case "MultiPoint": | |
| for (j = 0; j < coords.length; j++) { | |
| if ( | |
| callback( | |
| coords[j], | |
| coordIndex, | |
| featureIndex, | |
| multiFeatureIndex, | |
| geometryIndex | |
| ) === false | |
| ) | |
| return false; | |
| coordIndex++; | |
| if (geomType === "MultiPoint") multiFeatureIndex++; | |
| } | |
| if (geomType === "LineString") multiFeatureIndex++; | |
| break; | |
| case "Polygon": | |
| case "MultiLineString": | |
| for (j = 0; j < coords.length; j++) { | |
| for (k = 0; k < coords[j].length - wrapShrink; k++) { | |
| if ( | |
| callback( | |
| coords[j][k], | |
| coordIndex, | |
| featureIndex, | |
| multiFeatureIndex, | |
| geometryIndex | |
| ) === false | |
| ) | |
| return false; | |
| coordIndex++; | |
| } | |
| if (geomType === "MultiLineString") multiFeatureIndex++; | |
| if (geomType === "Polygon") geometryIndex++; | |
| } | |
| if (geomType === "Polygon") multiFeatureIndex++; | |
| break; | |
| case "MultiPolygon": | |
| for (j = 0; j < coords.length; j++) { | |
| geometryIndex = 0; | |
| for (k = 0; k < coords[j].length; k++) { | |
| for (l = 0; l < coords[j][k].length - wrapShrink; l++) { | |
| if ( | |
| callback( | |
| coords[j][k][l], | |
| coordIndex, | |
| featureIndex, | |
| multiFeatureIndex, | |
| geometryIndex | |
| ) === false | |
| ) | |
| return false; | |
| coordIndex++; | |
| } | |
| geometryIndex++; | |
| } | |
| multiFeatureIndex++; | |
| } | |
| break; | |
| case "GeometryCollection": | |
| for (j = 0; j < geometry.geometries.length; j++) | |
| if ( | |
| coordEach(geometry.geometries[j], callback, excludeWrapCoord) === | |
| false | |
| ) | |
| return false; | |
| break; | |
| default: | |
| throw new Error("Unknown Geometry Type"); | |
| } | |
| } | |
| } | |
| } | |
| /** | |
| * Callback for coordReduce | |
| * | |
| * The first time the callback function is called, the values provided as arguments depend | |
| * on whether the reduce method has an initialValue argument. | |
| * | |
| * If an initialValue is provided to the reduce method: | |
| * - The previousValue argument is initialValue. | |
| * - The currentValue argument is the value of the first element present in the array. | |
| * | |
| * If an initialValue is not provided: | |
| * - The previousValue argument is the value of the first element present in the array. | |
| * - The currentValue argument is the value of the second element present in the array. | |
| * | |
| * @callback coordReduceCallback | |
| * @param {*} previousValue The accumulated value previously returned in the last invocation | |
| * of the callback, or initialValue, if supplied. | |
| * @param {Array<number>} currentCoord The current coordinate being processed. | |
| * @param {number} coordIndex The current index of the coordinate being processed. | |
| * Starts at index 0, if an initialValue is provided, and at index 1 otherwise. | |
| * @param {number} featureIndex The current index of the Feature being processed. | |
| * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. | |
| * @param {number} geometryIndex The current index of the Geometry being processed. | |
| */ | |
| /** | |
| * Reduce coordinates in any GeoJSON object, similar to Array.reduce() | |
| * | |
| * @name coordReduce | |
| * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object | |
| * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex) | |
| * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. | |
| * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration. | |
| * @returns {*} The value that results from the reduction. | |
| * @example | |
| * var features = turf.featureCollection([ | |
| * turf.point([26, 37], {"foo": "bar"}), | |
| * turf.point([36, 53], {"hello": "world"}) | |
| * ]); | |
| * | |
| * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) { | |
| * //=previousValue | |
| * //=currentCoord | |
| * //=coordIndex | |
| * //=featureIndex | |
| * //=multiFeatureIndex | |
| * //=geometryIndex | |
| * return currentCoord; | |
| * }); | |
| */ | |
| function coordReduce(geojson, callback, initialValue, excludeWrapCoord) { | |
| var previousValue = initialValue; | |
| coordEach( | |
| geojson, | |
| function ( | |
| currentCoord, | |
| coordIndex, | |
| featureIndex, | |
| multiFeatureIndex, | |
| geometryIndex | |
| ) { | |
| if (coordIndex === 0 && initialValue === undefined) | |
| previousValue = currentCoord; | |
| else | |
| previousValue = callback( | |
| previousValue, | |
| currentCoord, | |
| coordIndex, | |
| featureIndex, | |
| multiFeatureIndex, | |
| geometryIndex | |
| ); | |
| }, | |
| excludeWrapCoord | |
| ); | |
| return previousValue; | |
| } | |
| /** | |
| * Callback for propEach | |
| * | |
| * @callback propEachCallback | |
| * @param {Object} currentProperties The current Properties being processed. | |
| * @param {number} featureIndex The current index of the Feature being processed. | |
| */ | |
| /** | |
| * Iterate over properties in any GeoJSON object, similar to Array.forEach() | |
| * | |
| * @name propEach | |
| * @param {FeatureCollection|Feature} geojson any GeoJSON object | |
| * @param {Function} callback a method that takes (currentProperties, featureIndex) | |
| * @returns {void} | |
| * @example | |
| * var features = turf.featureCollection([ | |
| * turf.point([26, 37], {foo: 'bar'}), | |
| * turf.point([36, 53], {hello: 'world'}) | |
| * ]); | |
| * | |
| * turf.propEach(features, function (currentProperties, featureIndex) { | |
| * //=currentProperties | |
| * //=featureIndex | |
| * }); | |
| */ | |
| function propEach(geojson, callback) { | |
| var i; | |
| switch (geojson.type) { | |
| case "FeatureCollection": | |
| for (i = 0; i < geojson.features.length; i++) { | |
| if (callback(geojson.features[i].properties, i) === false) break; | |
| } | |
| break; | |
| case "Feature": | |
| callback(geojson.properties, 0); | |
| break; | |
| } | |
| } | |
| /** | |
| * Callback for propReduce | |
| * | |
| * The first time the callback function is called, the values provided as arguments depend | |
| * on whether the reduce method has an initialValue argument. | |
| * | |
| * If an initialValue is provided to the reduce method: | |
| * - The previousValue argument is initialValue. | |
| * - The currentValue argument is the value of the first element present in the array. | |
| * | |
| * If an initialValue is not provided: | |
| * - The previousValue argument is the value of the first element present in the array. | |
| * - The currentValue argument is the value of the second element present in the array. | |
| * | |
| * @callback propReduceCallback | |
| * @param {*} previousValue The accumulated value previously returned in the last invocation | |
| * of the callback, or initialValue, if supplied. | |
| * @param {*} currentProperties The current Properties being processed. | |
| * @param {number} featureIndex The current index of the Feature being processed. | |
| */ | |
| /** | |
| * Reduce properties in any GeoJSON object into a single value, | |
| * similar to how Array.reduce works. However, in this case we lazily run | |
| * the reduction, so an array of all properties is unnecessary. | |
| * | |
| * @name propReduce | |
| * @param {FeatureCollection|Feature} geojson any GeoJSON object | |
| * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex) | |
| * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. | |
| * @returns {*} The value that results from the reduction. | |
| * @example | |
| * var features = turf.featureCollection([ | |
| * turf.point([26, 37], {foo: 'bar'}), | |
| * turf.point([36, 53], {hello: 'world'}) | |
| * ]); | |
| * | |
| * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) { | |
| * //=previousValue | |
| * //=currentProperties | |
| * //=featureIndex | |
| * return currentProperties | |
| * }); | |
| */ | |
| function propReduce(geojson, callback, initialValue) { | |
| var previousValue = initialValue; | |
| propEach(geojson, function (currentProperties, featureIndex) { | |
| if (featureIndex === 0 && initialValue === undefined) | |
| previousValue = currentProperties; | |
| else | |
| previousValue = callback(previousValue, currentProperties, featureIndex); | |
| }); | |
| return previousValue; | |
| } | |
| /** | |
| * Callback for featureEach | |
| * | |
| * @callback featureEachCallback | |
| * @param {Feature<any>} currentFeature The current Feature being processed. | |
| * @param {number} featureIndex The current index of the Feature being processed. | |
| */ | |
| /** | |
| * Iterate over features in any GeoJSON object, similar to | |
| * Array.forEach. | |
| * | |
| * @name featureEach | |
| * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object | |
| * @param {Function} callback a method that takes (currentFeature, featureIndex) | |
| * @returns {void} | |
| * @example | |
| * var features = turf.featureCollection([ | |
| * turf.point([26, 37], {foo: 'bar'}), | |
| * turf.point([36, 53], {hello: 'world'}) | |
| * ]); | |
| * | |
| * turf.featureEach(features, function (currentFeature, featureIndex) { | |
| * //=currentFeature | |
| * //=featureIndex | |
| * }); | |
| */ | |
| function featureEach(geojson, callback) { | |
| if (geojson.type === "Feature") { | |
| callback(geojson, 0); | |
| } else if (geojson.type === "FeatureCollection") { | |
| for (var i = 0; i < geojson.features.length; i++) { | |
| if (callback(geojson.features[i], i) === false) break; | |
| } | |
| } | |
| } | |
| /** | |
| * Callback for featureReduce | |
| * | |
| * The first time the callback function is called, the values provided as arguments depend | |
| * on whether the reduce method has an initialValue argument. | |
| * | |
| * If an initialValue is provided to the reduce method: | |
| * - The previousValue argument is initialValue. | |
| * - The currentValue argument is the value of the first element present in the array. | |
| * | |
| * If an initialValue is not provided: | |
| * - The previousValue argument is the value of the first element present in the array. | |
| * - The currentValue argument is the value of the second element present in the array. | |
| * | |
| * @callback featureReduceCallback | |
| * @param {*} previousValue The accumulated value previously returned in the last invocation | |
| * of the callback, or initialValue, if supplied. | |
| * @param {Feature} currentFeature The current Feature being processed. | |
| * @param {number} featureIndex The current index of the Feature being processed. | |
| */ | |
| /** | |
| * Reduce features in any GeoJSON object, similar to Array.reduce(). | |
| * | |
| * @name featureReduce | |
| * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object | |
| * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex) | |
| * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. | |
| * @returns {*} The value that results from the reduction. | |
| * @example | |
| * var features = turf.featureCollection([ | |
| * turf.point([26, 37], {"foo": "bar"}), | |
| * turf.point([36, 53], {"hello": "world"}) | |
| * ]); | |
| * | |
| * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) { | |
| * //=previousValue | |
| * //=currentFeature | |
| * //=featureIndex | |
| * return currentFeature | |
| * }); | |
| */ | |
| function featureReduce(geojson, callback, initialValue) { | |
| var previousValue = initialValue; | |
| featureEach(geojson, function (currentFeature, featureIndex) { | |
| if (featureIndex === 0 && initialValue === undefined) | |
| previousValue = currentFeature; | |
| else previousValue = callback(previousValue, currentFeature, featureIndex); | |
| }); | |
| return previousValue; | |
| } | |
| /** | |
| * Get all coordinates from any GeoJSON object. | |
| * | |
| * @name coordAll | |
| * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object | |
| * @returns {Array<Array<number>>} coordinate position array | |
| * @example | |
| * var features = turf.featureCollection([ | |
| * turf.point([26, 37], {foo: 'bar'}), | |
| * turf.point([36, 53], {hello: 'world'}) | |
| * ]); | |
| * | |
| * var coords = turf.coordAll(features); | |
| * //= [[26, 37], [36, 53]] | |
| */ | |
| function coordAll(geojson) { | |
| var coords = []; | |
| coordEach(geojson, function (coord) { | |
| coords.push(coord); | |
| }); | |
| return coords; | |
| } | |
| /** | |
| * Callback for geomEach | |
| * | |
| * @callback geomEachCallback | |
| * @param {Geometry} currentGeometry The current Geometry being processed. | |
| * @param {number} featureIndex The current index of the Feature being processed. | |
| * @param {Object} featureProperties The current Feature Properties being processed. | |
| * @param {Array<number>} featureBBox The current Feature BBox being processed. | |
| * @param {number|string} featureId The current Feature Id being processed. | |
| */ | |
| /** | |
| * Iterate over each geometry in any GeoJSON object, similar to Array.forEach() | |
| * | |
| * @name geomEach | |
| * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object | |
| * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) | |
| * @returns {void} | |
| * @example | |
| * var features = turf.featureCollection([ | |
| * turf.point([26, 37], {foo: 'bar'}), | |
| * turf.point([36, 53], {hello: 'world'}) | |
| * ]); | |
| * | |
| * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) { | |
| * //=currentGeometry | |
| * //=featureIndex | |
| * //=featureProperties | |
| * //=featureBBox | |
| * //=featureId | |
| * }); | |
| */ | |
| function geomEach(geojson, callback) { | |
| var i, | |
| j, | |
| g, | |
| geometry, | |
| stopG, | |
| geometryMaybeCollection, | |
| isGeometryCollection, | |
| featureProperties, | |
| featureBBox, | |
| featureId, | |
| featureIndex = 0, | |
| isFeatureCollection = geojson.type === "FeatureCollection", | |
| isFeature = geojson.type === "Feature", | |
| stop = isFeatureCollection ? geojson.features.length : 1; | |
| // This logic may look a little weird. The reason why it is that way | |
| // is because it's trying to be fast. GeoJSON supports multiple kinds | |
| // of objects at its root: FeatureCollection, Features, Geometries. | |
| // This function has the responsibility of handling all of them, and that | |
| // means that some of the `for` loops you see below actually just don't apply | |
| // to certain inputs. For instance, if you give this just a | |
| // Point geometry, then both loops are short-circuited and all we do | |
| // is gradually rename the input until it's called 'geometry'. | |
| // | |
| // This also aims to allocate as few resources as possible: just a | |
| // few numbers and booleans, rather than any temporary arrays as would | |
| // be required with the normalization approach. | |
| for (i = 0; i < stop; i++) { | |
| geometryMaybeCollection = isFeatureCollection | |
| ? geojson.features[i].geometry | |
| : isFeature | |
| ? geojson.geometry | |
| : geojson; | |
| featureProperties = isFeatureCollection | |
| ? geojson.features[i].properties | |
| : isFeature | |
| ? geojson.properties | |
| : {}; | |
| featureBBox = isFeatureCollection | |
| ? geojson.features[i].bbox | |
| : isFeature | |
| ? geojson.bbox | |
| : undefined; | |
| featureId = isFeatureCollection | |
| ? geojson.features[i].id | |
| : isFeature | |
| ? geojson.id | |
| : undefined; | |
| isGeometryCollection = geometryMaybeCollection | |
| ? geometryMaybeCollection.type === "GeometryCollection" | |
| : false; | |
| stopG = isGeometryCollection | |
| ? geometryMaybeCollection.geometries.length | |
| : 1; | |
| for (g = 0; g < stopG; g++) { | |
| geometry = isGeometryCollection | |
| ? geometryMaybeCollection.geometries[g] | |
| : geometryMaybeCollection; | |
| // Handle null Geometry | |
| if (geometry === null) { | |
| if ( | |
| callback( | |
| null, | |
| featureIndex, | |
| featureProperties, | |
| featureBBox, | |
| featureId | |
| ) === false | |
| ) | |
| return false; | |
| continue; | |
| } | |
| switch (geometry.type) { | |
| case "Point": | |
| case "LineString": | |
| case "MultiPoint": | |
| case "Polygon": | |
| case "MultiLineString": | |
| case "MultiPolygon": { | |
| if ( | |
| callback( | |
| geometry, | |
| featureIndex, | |
| featureProperties, | |
| featureBBox, | |
| featureId | |
| ) === false | |
| ) | |
| return false; | |
| break; | |
| } | |
| case "GeometryCollection": { | |
| for (j = 0; j < geometry.geometries.length; j++) { | |
| if ( | |
| callback( | |
| geometry.geometries[j], | |
| featureIndex, | |
| featureProperties, | |
| featureBBox, | |
| featureId | |
| ) === false | |
| ) | |
| return false; | |
| } | |
| break; | |
| } | |
| default: | |
| throw new Error("Unknown Geometry Type"); | |
| } | |
| } | |
| // Only increase `featureIndex` per each feature | |
| featureIndex++; | |
| } | |
| } | |
| /** | |
| * Callback for geomReduce | |
| * | |
| * The first time the callback function is called, the values provided as arguments depend | |
| * on whether the reduce method has an initialValue argument. | |
| * | |
| * If an initialValue is provided to the reduce method: | |
| * - The previousValue argument is initialValue. | |
| * - The currentValue argument is the value of the first element present in the array. | |
| * | |
| * If an initialValue is not provided: | |
| * - The previousValue argument is the value of the first element present in the array. | |
| * - The currentValue argument is the value of the second element present in the array. | |
| * | |
| * @callback geomReduceCallback | |
| * @param {*} previousValue The accumulated value previously returned in the last invocation | |
| * of the callback, or initialValue, if supplied. | |
| * @param {Geometry} currentGeometry The current Geometry being processed. | |
| * @param {number} featureIndex The current index of the Feature being processed. | |
| * @param {Object} featureProperties The current Feature Properties being processed. | |
| * @param {Array<number>} featureBBox The current Feature BBox being processed. | |
| * @param {number|string} featureId The current Feature Id being processed. | |
| */ | |
| /** | |
| * Reduce geometry in any GeoJSON object, similar to Array.reduce(). | |
| * | |
| * @name geomReduce | |
| * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object | |
| * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) | |
| * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. | |
| * @returns {*} The value that results from the reduction. | |
| * @example | |
| * var features = turf.featureCollection([ | |
| * turf.point([26, 37], {foo: 'bar'}), | |
| * turf.point([36, 53], {hello: 'world'}) | |
| * ]); | |
| * | |
| * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) { | |
| * //=previousValue | |
| * //=currentGeometry | |
| * //=featureIndex | |
| * //=featureProperties | |
| * //=featureBBox | |
| * //=featureId | |
| * return currentGeometry | |
| * }); | |
| */ | |
| function geomReduce(geojson, callback, initialValue) { | |
| var previousValue = initialValue; | |
| geomEach( | |
| geojson, | |
| function ( | |
| currentGeometry, | |
| featureIndex, | |
| featureProperties, | |
| featureBBox, | |
| featureId | |
| ) { | |
| if (featureIndex === 0 && initialValue === undefined) | |
| previousValue = currentGeometry; | |
| else | |
| previousValue = callback( | |
| previousValue, | |
| currentGeometry, | |
| featureIndex, | |
| featureProperties, | |
| featureBBox, | |
| featureId | |
| ); | |
| } | |
| ); | |
| return previousValue; | |
| } | |
| /** | |
| * Callback for flattenEach | |
| * | |
| * @callback flattenEachCallback | |
| * @param {Feature} currentFeature The current flattened feature being processed. | |
| * @param {number} featureIndex The current index of the Feature being processed. | |
| * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. | |
| */ | |
| /** | |
| * Iterate over flattened features in any GeoJSON object, similar to | |
| * Array.forEach. | |
| * | |
| * @name flattenEach | |
| * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object | |
| * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex) | |
| * @example | |
| * var features = turf.featureCollection([ | |
| * turf.point([26, 37], {foo: 'bar'}), | |
| * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'}) | |
| * ]); | |
| * | |
| * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) { | |
| * //=currentFeature | |
| * //=featureIndex | |
| * //=multiFeatureIndex | |
| * }); | |
| */ | |
| function flattenEach(geojson, callback) { | |
| geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) { | |
| // Callback for single geometry | |
| var type = geometry === null ? null : geometry.type; | |
| switch (type) { | |
| case null: | |
| case "Point": | |
| case "LineString": | |
| case "Polygon": | |
| if ( | |
| callback( | |
| helpers.feature(geometry, properties, { bbox: bbox, id: id }), | |
| featureIndex, | |
| 0 | |
| ) === false | |
| ) | |
| return false; | |
| return; | |
| } | |
| var geomType; | |
| // Callback for multi-geometry | |
| switch (type) { | |
| case "MultiPoint": | |
| geomType = "Point"; | |
| break; | |
| case "MultiLineString": | |
| geomType = "LineString"; | |
| break; | |
| case "MultiPolygon": | |
| geomType = "Polygon"; | |
| break; | |
| } | |
| for ( | |
| var multiFeatureIndex = 0; | |
| multiFeatureIndex < geometry.coordinates.length; | |
| multiFeatureIndex++ | |
| ) { | |
| var coordinate = geometry.coordinates[multiFeatureIndex]; | |
| var geom = { | |
| type: geomType, | |
| coordinates: coordinate, | |
| }; | |
| if ( | |
| callback(helpers.feature(geom, properties), featureIndex, multiFeatureIndex) === | |
| false | |
| ) | |
| return false; | |
| } | |
| }); | |
| } | |
| /** | |
| * Callback for flattenReduce | |
| * | |
| * The first time the callback function is called, the values provided as arguments depend | |
| * on whether the reduce method has an initialValue argument. | |
| * | |
| * If an initialValue is provided to the reduce method: | |
| * - The previousValue argument is initialValue. | |
| * - The currentValue argument is the value of the first element present in the array. | |
| * | |
| * If an initialValue is not provided: | |
| * - The previousValue argument is the value of the first element present in the array. | |
| * - The currentValue argument is the value of the second element present in the array. | |
| * | |
| * @callback flattenReduceCallback | |
| * @param {*} previousValue The accumulated value previously returned in the last invocation | |
| * of the callback, or initialValue, if supplied. | |
| * @param {Feature} currentFeature The current Feature being processed. | |
| * @param {number} featureIndex The current index of the Feature being processed. | |
| * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. | |
| */ | |
| /** | |
| * Reduce flattened features in any GeoJSON object, similar to Array.reduce(). | |
| * | |
| * @name flattenReduce | |
| * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object | |
| * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex) | |
| * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. | |
| * @returns {*} The value that results from the reduction. | |
| * @example | |
| * var features = turf.featureCollection([ | |
| * turf.point([26, 37], {foo: 'bar'}), | |
| * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'}) | |
| * ]); | |
| * | |
| * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) { | |
| * //=previousValue | |
| * //=currentFeature | |
| * //=featureIndex | |
| * //=multiFeatureIndex | |
| * return currentFeature | |
| * }); | |
| */ | |
| function flattenReduce(geojson, callback, initialValue) { | |
| var previousValue = initialValue; | |
| flattenEach( | |
| geojson, | |
| function (currentFeature, featureIndex, multiFeatureIndex) { | |
| if ( | |
| featureIndex === 0 && | |
| multiFeatureIndex === 0 && | |
| initialValue === undefined | |
| ) | |
| previousValue = currentFeature; | |
| else | |
| previousValue = callback( | |
| previousValue, | |
| currentFeature, | |
| featureIndex, | |
| multiFeatureIndex | |
| ); | |
| } | |
| ); | |
| return previousValue; | |
| } | |
| /** | |
| * Callback for segmentEach | |
| * | |
| * @callback segmentEachCallback | |
| * @param {Feature<LineString>} currentSegment The current Segment being processed. | |
| * @param {number} featureIndex The current index of the Feature being processed. | |
| * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. | |
| * @param {number} geometryIndex The current index of the Geometry being processed. | |
| * @param {number} segmentIndex The current index of the Segment being processed. | |
| * @returns {void} | |
| */ | |
| /** | |
| * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach() | |
| * (Multi)Point geometries do not contain segments therefore they are ignored during this operation. | |
| * | |
| * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON | |
| * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) | |
| * @returns {void} | |
| * @example | |
| * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]); | |
| * | |
| * // Iterate over GeoJSON by 2-vertex segments | |
| * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) { | |
| * //=currentSegment | |
| * //=featureIndex | |
| * //=multiFeatureIndex | |
| * //=geometryIndex | |
| * //=segmentIndex | |
| * }); | |
| * | |
| * // Calculate the total number of segments | |
| * var total = 0; | |
| * turf.segmentEach(polygon, function () { | |
| * total++; | |
| * }); | |
| */ | |
| function segmentEach(geojson, callback) { | |
| flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) { | |
| var segmentIndex = 0; | |
| // Exclude null Geometries | |
| if (!feature.geometry) return; | |
| // (Multi)Point geometries do not contain segments therefore they are ignored during this operation. | |
| var type = feature.geometry.type; | |
| if (type === "Point" || type === "MultiPoint") return; | |
| // Generate 2-vertex line segments | |
| var previousCoords; | |
| var previousFeatureIndex = 0; | |
| var previousMultiIndex = 0; | |
| var prevGeomIndex = 0; | |
| if ( | |
| coordEach( | |
| feature, | |
| function ( | |
| currentCoord, | |
| coordIndex, | |
| featureIndexCoord, | |
| multiPartIndexCoord, | |
| geometryIndex | |
| ) { | |
| // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false` | |
| if ( | |
| previousCoords === undefined || | |
| featureIndex > previousFeatureIndex || | |
| multiPartIndexCoord > previousMultiIndex || | |
| geometryIndex > prevGeomIndex | |
| ) { | |
| previousCoords = currentCoord; | |
| previousFeatureIndex = featureIndex; | |
| previousMultiIndex = multiPartIndexCoord; | |
| prevGeomIndex = geometryIndex; | |
| segmentIndex = 0; | |
| return; | |
| } | |
| var currentSegment = helpers.lineString( | |
| [previousCoords, currentCoord], | |
| feature.properties | |
| ); | |
| if ( | |
| callback( | |
| currentSegment, | |
| featureIndex, | |
| multiFeatureIndex, | |
| geometryIndex, | |
| segmentIndex | |
| ) === false | |
| ) | |
| return false; | |
| segmentIndex++; | |
| previousCoords = currentCoord; | |
| } | |
| ) === false | |
| ) | |
| return false; | |
| }); | |
| } | |
| /** | |
| * Callback for segmentReduce | |
| * | |
| * The first time the callback function is called, the values provided as arguments depend | |
| * on whether the reduce method has an initialValue argument. | |
| * | |
| * If an initialValue is provided to the reduce method: | |
| * - The previousValue argument is initialValue. | |
| * - The currentValue argument is the value of the first element present in the array. | |
| * | |
| * If an initialValue is not provided: | |
| * - The previousValue argument is the value of the first element present in the array. | |
| * - The currentValue argument is the value of the second element present in the array. | |
| * | |
| * @callback segmentReduceCallback | |
| * @param {*} previousValue The accumulated value previously returned in the last invocation | |
| * of the callback, or initialValue, if supplied. | |
| * @param {Feature<LineString>} currentSegment The current Segment being processed. | |
| * @param {number} featureIndex The current index of the Feature being processed. | |
| * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. | |
| * @param {number} geometryIndex The current index of the Geometry being processed. | |
| * @param {number} segmentIndex The current index of the Segment being processed. | |
| */ | |
| /** | |
| * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce() | |
| * (Multi)Point geometries do not contain segments therefore they are ignored during this operation. | |
| * | |
| * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON | |
| * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex) | |
| * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. | |
| * @returns {void} | |
| * @example | |
| * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]); | |
| * | |
| * // Iterate over GeoJSON by 2-vertex segments | |
| * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) { | |
| * //= previousSegment | |
| * //= currentSegment | |
| * //= featureIndex | |
| * //= multiFeatureIndex | |
| * //= geometryIndex | |
| * //= segmentIndex | |
| * return currentSegment | |
| * }); | |
| * | |
| * // Calculate the total number of segments | |
| * var initialValue = 0 | |
| * var total = turf.segmentReduce(polygon, function (previousValue) { | |
| * previousValue++; | |
| * return previousValue; | |
| * }, initialValue); | |
| */ | |
| function segmentReduce(geojson, callback, initialValue) { | |
| var previousValue = initialValue; | |
| var started = false; | |
| segmentEach( | |
| geojson, | |
| function ( | |
| currentSegment, | |
| featureIndex, | |
| multiFeatureIndex, | |
| geometryIndex, | |
| segmentIndex | |
| ) { | |
| if (started === false && initialValue === undefined) | |
| previousValue = currentSegment; | |
| else | |
| previousValue = callback( | |
| previousValue, | |
| currentSegment, | |
| featureIndex, | |
| multiFeatureIndex, | |
| geometryIndex, | |
| segmentIndex | |
| ); | |
| started = true; | |
| } | |
| ); | |
| return previousValue; | |
| } | |
| /** | |
| * Callback for lineEach | |
| * | |
| * @callback lineEachCallback | |
| * @param {Feature<LineString>} currentLine The current LineString|LinearRing being processed | |
| * @param {number} featureIndex The current index of the Feature being processed | |
| * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed | |
| * @param {number} geometryIndex The current index of the Geometry being processed | |
| */ | |
| /** | |
| * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries, | |
| * similar to Array.forEach. | |
| * | |
| * @name lineEach | |
| * @param {Geometry|Feature<LineString|Polygon|MultiLineString|MultiPolygon>} geojson object | |
| * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex) | |
| * @example | |
| * var multiLine = turf.multiLineString([ | |
| * [[26, 37], [35, 45]], | |
| * [[36, 53], [38, 50], [41, 55]] | |
| * ]); | |
| * | |
| * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) { | |
| * //=currentLine | |
| * //=featureIndex | |
| * //=multiFeatureIndex | |
| * //=geometryIndex | |
| * }); | |
| */ | |
| function lineEach(geojson, callback) { | |
| // validation | |
| if (!geojson) throw new Error("geojson is required"); | |
| flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) { | |
| if (feature.geometry === null) return; | |
| var type = feature.geometry.type; | |
| var coords = feature.geometry.coordinates; | |
| switch (type) { | |
| case "LineString": | |
| if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) | |
| return false; | |
| break; | |
| case "Polygon": | |
| for ( | |
| var geometryIndex = 0; | |
| geometryIndex < coords.length; | |
| geometryIndex++ | |
| ) { | |
| if ( | |
| callback( | |
| helpers.lineString(coords[geometryIndex], feature.properties), | |
| featureIndex, | |
| multiFeatureIndex, | |
| geometryIndex | |
| ) === false | |
| ) | |
| return false; | |
| } | |
| break; | |
| } | |
| }); | |
| } | |
| /** | |
| * Callback for lineReduce | |
| * | |
| * The first time the callback function is called, the values provided as arguments depend | |
| * on whether the reduce method has an initialValue argument. | |
| * | |
| * If an initialValue is provided to the reduce method: | |
| * - The previousValue argument is initialValue. | |
| * - The currentValue argument is the value of the first element present in the array. | |
| * | |
| * If an initialValue is not provided: | |
| * - The previousValue argument is the value of the first element present in the array. | |
| * - The currentValue argument is the value of the second element present in the array. | |
| * | |
| * @callback lineReduceCallback | |
| * @param {*} previousValue The accumulated value previously returned in the last invocation | |
| * of the callback, or initialValue, if supplied. | |
| * @param {Feature<LineString>} currentLine The current LineString|LinearRing being processed. | |
| * @param {number} featureIndex The current index of the Feature being processed | |
| * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed | |
| * @param {number} geometryIndex The current index of the Geometry being processed | |
| */ | |
| /** | |
| * Reduce features in any GeoJSON object, similar to Array.reduce(). | |
| * | |
| * @name lineReduce | |
| * @param {Geometry|Feature<LineString|Polygon|MultiLineString|MultiPolygon>} geojson object | |
| * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) | |
| * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. | |
| * @returns {*} The value that results from the reduction. | |
| * @example | |
| * var multiPoly = turf.multiPolygon([ | |
| * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]), | |
| * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]]) | |
| * ]); | |
| * | |
| * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) { | |
| * //=previousValue | |
| * //=currentLine | |
| * //=featureIndex | |
| * //=multiFeatureIndex | |
| * //=geometryIndex | |
| * return currentLine | |
| * }); | |
| */ | |
| function lineReduce(geojson, callback, initialValue) { | |
| var previousValue = initialValue; | |
| lineEach( | |
| geojson, | |
| function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) { | |
| if (featureIndex === 0 && initialValue === undefined) | |
| previousValue = currentLine; | |
| else | |
| previousValue = callback( | |
| previousValue, | |
| currentLine, | |
| featureIndex, | |
| multiFeatureIndex, | |
| geometryIndex | |
| ); | |
| } | |
| ); | |
| return previousValue; | |
| } | |
| /** | |
| * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes. | |
| * | |
| * Negative indexes are permitted. | |
| * Point & MultiPoint will always return null. | |
| * | |
| * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry | |
| * @param {Object} [options={}] Optional parameters | |
| * @param {number} [options.featureIndex=0] Feature Index | |
| * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index | |
| * @param {number} [options.geometryIndex=0] Geometry Index | |
| * @param {number} [options.segmentIndex=0] Segment Index | |
| * @param {Object} [options.properties={}] Translate Properties to output LineString | |
| * @param {BBox} [options.bbox={}] Translate BBox to output LineString | |
| * @param {number|string} [options.id={}] Translate Id to output LineString | |
| * @returns {Feature<LineString>} 2-vertex GeoJSON Feature LineString | |
| * @example | |
| * var multiLine = turf.multiLineString([ | |
| * [[10, 10], [50, 30], [30, 40]], | |
| * [[-10, -10], [-50, -30], [-30, -40]] | |
| * ]); | |
| * | |
| * // First Segment (defaults are 0) | |
| * turf.findSegment(multiLine); | |
| * // => Feature<LineString<[[10, 10], [50, 30]]>> | |
| * | |
| * // First Segment of 2nd Multi Feature | |
| * turf.findSegment(multiLine, {multiFeatureIndex: 1}); | |
| * // => Feature<LineString<[[-10, -10], [-50, -30]]>> | |
| * | |
| * // Last Segment of Last Multi Feature | |
| * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1}); | |
| * // => Feature<LineString<[[-50, -30], [-30, -40]]>> | |
| */ | |
| function findSegment(geojson, options) { | |
| // Optional Parameters | |
| options = options || {}; | |
| if (!helpers.isObject(options)) throw new Error("options is invalid"); | |
| var featureIndex = options.featureIndex || 0; | |
| var multiFeatureIndex = options.multiFeatureIndex || 0; | |
| var geometryIndex = options.geometryIndex || 0; | |
| var segmentIndex = options.segmentIndex || 0; | |
| // Find FeatureIndex | |
| var properties = options.properties; | |
| var geometry; | |
| switch (geojson.type) { | |
| case "FeatureCollection": | |
| if (featureIndex < 0) | |
| featureIndex = geojson.features.length + featureIndex; | |
| properties = properties || geojson.features[featureIndex].properties; | |
| geometry = geojson.features[featureIndex].geometry; | |
| break; | |
| case "Feature": | |
| properties = properties || geojson.properties; | |
| geometry = geojson.geometry; | |
| break; | |
| case "Point": | |
| case "MultiPoint": | |
| return null; | |
| case "LineString": | |
| case "Polygon": | |
| case "MultiLineString": | |
| case "MultiPolygon": | |
| geometry = geojson; | |
| break; | |
| default: | |
| throw new Error("geojson is invalid"); | |
| } | |
| // Find SegmentIndex | |
| if (geometry === null) return null; | |
| var coords = geometry.coordinates; | |
| switch (geometry.type) { | |
| case "Point": | |
| case "MultiPoint": | |
| return null; | |
| case "LineString": | |
| if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1; | |
| return helpers.lineString( | |
| [coords[segmentIndex], coords[segmentIndex + 1]], | |
| properties, | |
| options | |
| ); | |
| case "Polygon": | |
| if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex; | |
| if (segmentIndex < 0) | |
| segmentIndex = coords[geometryIndex].length + segmentIndex - 1; | |
| return helpers.lineString( | |
| [ | |
| coords[geometryIndex][segmentIndex], | |
| coords[geometryIndex][segmentIndex + 1], | |
| ], | |
| properties, | |
| options | |
| ); | |
| case "MultiLineString": | |
| if (multiFeatureIndex < 0) | |
| multiFeatureIndex = coords.length + multiFeatureIndex; | |
| if (segmentIndex < 0) | |
| segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1; | |
| return helpers.lineString( | |
| [ | |
| coords[multiFeatureIndex][segmentIndex], | |
| coords[multiFeatureIndex][segmentIndex + 1], | |
| ], | |
| properties, | |
| options | |
| ); | |
| case "MultiPolygon": | |
| if (multiFeatureIndex < 0) | |
| multiFeatureIndex = coords.length + multiFeatureIndex; | |
| if (geometryIndex < 0) | |
| geometryIndex = coords[multiFeatureIndex].length + geometryIndex; | |
| if (segmentIndex < 0) | |
| segmentIndex = | |
| coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1; | |
| return helpers.lineString( | |
| [ | |
| coords[multiFeatureIndex][geometryIndex][segmentIndex], | |
| coords[multiFeatureIndex][geometryIndex][segmentIndex + 1], | |
| ], | |
| properties, | |
| options | |
| ); | |
| } | |
| throw new Error("geojson is invalid"); | |
| } | |
| /** | |
| * Finds a particular Point from a GeoJSON using `@turf/meta` indexes. | |
| * | |
| * Negative indexes are permitted. | |
| * | |
| * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry | |
| * @param {Object} [options={}] Optional parameters | |
| * @param {number} [options.featureIndex=0] Feature Index | |
| * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index | |
| * @param {number} [options.geometryIndex=0] Geometry Index | |
| * @param {number} [options.coordIndex=0] Coord Index | |
| * @param {Object} [options.properties={}] Translate Properties to output Point | |
| * @param {BBox} [options.bbox={}] Translate BBox to output Point | |
| * @param {number|string} [options.id={}] Translate Id to output Point | |
| * @returns {Feature<Point>} 2-vertex GeoJSON Feature Point | |
| * @example | |
| * var multiLine = turf.multiLineString([ | |
| * [[10, 10], [50, 30], [30, 40]], | |
| * [[-10, -10], [-50, -30], [-30, -40]] | |
| * ]); | |
| * | |
| * // First Segment (defaults are 0) | |
| * turf.findPoint(multiLine); | |
| * // => Feature<Point<[10, 10]>> | |
| * | |
| * // First Segment of the 2nd Multi-Feature | |
| * turf.findPoint(multiLine, {multiFeatureIndex: 1}); | |
| * // => Feature<Point<[-10, -10]>> | |
| * | |
| * // Last Segment of last Multi-Feature | |
| * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1}); | |
| * // => Feature<Point<[-30, -40]>> | |
| */ | |
| function findPoint(geojson, options) { | |
| // Optional Parameters | |
| options = options || {}; | |
| if (!helpers.isObject(options)) throw new Error("options is invalid"); | |
| var featureIndex = options.featureIndex || 0; | |
| var multiFeatureIndex = options.multiFeatureIndex || 0; | |
| var geometryIndex = options.geometryIndex || 0; | |
| var coordIndex = options.coordIndex || 0; | |
| // Find FeatureIndex | |
| var properties = options.properties; | |
| var geometry; | |
| switch (geojson.type) { | |
| case "FeatureCollection": | |
| if (featureIndex < 0) | |
| featureIndex = geojson.features.length + featureIndex; | |
| properties = properties || geojson.features[featureIndex].properties; | |
| geometry = geojson.features[featureIndex].geometry; | |
| break; | |
| case "Feature": | |
| properties = properties || geojson.properties; | |
| geometry = geojson.geometry; | |
| break; | |
| case "Point": | |
| case "MultiPoint": | |
| return null; | |
| case "LineString": | |
| case "Polygon": | |
| case "MultiLineString": | |
| case "MultiPolygon": | |
| geometry = geojson; | |
| break; | |
| default: | |
| throw new Error("geojson is invalid"); | |
| } | |
| // Find Coord Index | |
| if (geometry === null) return null; | |
| var coords = geometry.coordinates; | |
| switch (geometry.type) { | |
| case "Point": | |
| return helpers.point(coords, properties, options); | |
| case "MultiPoint": | |
| if (multiFeatureIndex < 0) | |
| multiFeatureIndex = coords.length + multiFeatureIndex; | |
| return helpers.point(coords[multiFeatureIndex], properties, options); | |
| case "LineString": | |
| if (coordIndex < 0) coordIndex = coords.length + coordIndex; | |
| return helpers.point(coords[coordIndex], properties, options); | |
| case "Polygon": | |
| if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex; | |
| if (coordIndex < 0) | |
| coordIndex = coords[geometryIndex].length + coordIndex; | |
| return helpers.point(coords[geometryIndex][coordIndex], properties, options); | |
| case "MultiLineString": | |
| if (multiFeatureIndex < 0) | |
| multiFeatureIndex = coords.length + multiFeatureIndex; | |
| if (coordIndex < 0) | |
| coordIndex = coords[multiFeatureIndex].length + coordIndex; | |
| return helpers.point(coords[multiFeatureIndex][coordIndex], properties, options); | |
| case "MultiPolygon": | |
| if (multiFeatureIndex < 0) | |
| multiFeatureIndex = coords.length + multiFeatureIndex; | |
| if (geometryIndex < 0) | |
| geometryIndex = coords[multiFeatureIndex].length + geometryIndex; | |
| if (coordIndex < 0) | |
| coordIndex = | |
| coords[multiFeatureIndex][geometryIndex].length - coordIndex; | |
| return helpers.point( | |
| coords[multiFeatureIndex][geometryIndex][coordIndex], | |
| properties, | |
| options | |
| ); | |
| } | |
| throw new Error("geojson is invalid"); | |
| } | |
| exports.coordAll = coordAll; | |
| exports.coordEach = coordEach; | |
| exports.coordReduce = coordReduce; | |
| exports.featureEach = featureEach; | |
| exports.featureReduce = featureReduce; | |
| exports.findPoint = findPoint; | |
| exports.findSegment = findSegment; | |
| exports.flattenEach = flattenEach; | |
| exports.flattenReduce = flattenReduce; | |
| exports.geomEach = geomEach; | |
| exports.geomReduce = geomReduce; | |
| exports.lineEach = lineEach; | |
| exports.lineReduce = lineReduce; | |
| exports.propEach = propEach; | |
| exports.propReduce = propReduce; | |
| exports.segmentEach = segmentEach; | |
| exports.segmentReduce = segmentReduce; | |