From 76aa786c58638ed6ec21a8b19bad1b1c43f4dd2b Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 27 Jul 2017 15:32:36 -0400 Subject: [PATCH] Implement featureIndex in coordEach & coordReduce --- packages/turf-meta/index.d.ts | 4 +-- packages/turf-meta/index.js | 51 +++++++++++++++++----------- packages/turf-meta/test.js | 62 ++++++++++++++++++++++++++++++++--- 3 files changed, 91 insertions(+), 26 deletions(-) diff --git a/packages/turf-meta/index.d.ts b/packages/turf-meta/index.d.ts index 0009cbef84..233c537b66 100644 --- a/packages/turf-meta/index.d.ts +++ b/packages/turf-meta/index.d.ts @@ -16,12 +16,12 @@ export type AllGeoJSON = Feature | Features | GeometryObject | Geometr /** * http://turfjs.org/docs/#coordreduce */ -export function coordReduce(geojson: AllGeoJSON, callback: (previousValue: any, currentCoord: number[], coordIndex: number) => void, initialValue?: any): void; +export function coordReduce(geojson: AllGeoJSON, callback: (previousValue: any, currentCoord: number[], coordIndex: number, featureIndex: number, featureSubIndex: number) => void, initialValue?: any): void; /** * http://turfjs.org/docs/#coordeach */ -export function coordEach(geojson: AllGeoJSON, callback: (currentCoord: number[], coordIndex: number) => void): void; +export function coordEach(geojson: AllGeoJSON, callback: (currentCoord: number[], coordIndex: number, featureIndex: number, featureSubIndex: number) => void): void; /** * http://turfjs.org/docs/#propeach diff --git a/packages/turf-meta/index.js b/packages/turf-meta/index.js index 3bf2248fe1..6f8d2ff4c9 100644 --- a/packages/turf-meta/index.js +++ b/packages/turf-meta/index.js @@ -2,9 +2,11 @@ * Callback for coordEach * * @callback coordEachCallback - * @param {Array} currentCoord The current coordinates being processed. - * @param {number} coordIndex The index of the current element being processed in the - * array.Starts at index 0, if an initialValue is provided, and at index 1 otherwise. + * @param {Array} currentCoord The current coordinate being processed. + * @param {number} coordIndex The current index of the coordinate being processed. + * Starts at index 0. + * @param {number} featureIndex The current index of the feature being processed. + * @param {number} featureSubIndex The current subIndex of the feature being processed. */ /** @@ -12,7 +14,7 @@ * * @name coordEach * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object - * @param {Function} callback a method that takes (currentCoord, coordIndex) + * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, featureSubIndex) * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration. * @example * var features = turf.featureCollection([ @@ -20,15 +22,17 @@ * turf.point([36, 53], {"hello": "world"}) * ]); * - * turf.coordEach(features, function (currentCoord, coordIndex) { + * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, featureSubIndex) { * //=currentCoord * //=coordIndex + * //=featureIndex + * //=featureSubIndex * }); */ function coordEach(geojson, callback, excludeWrapCoord) { // Handles null Geometry -- Skips this GeoJSON if (geojson === null) return; - var i, j, k, g, l, geometry, stopG, coords, + var featureIndex, geometryIndex, j, k, l, geometry, stopG, coords, geometryMaybeCollection, wrapShrink = 0, coordIndex = 0, @@ -50,16 +54,17 @@ function coordEach(geojson, callback, excludeWrapCoord) { // 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++) { + for (featureIndex = 0; featureIndex < stop; featureIndex++) { + var featureSubIndex = 0; - geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry : + geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry : (isFeature ? geojson.geometry : geojson)); isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false; stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1; - for (g = 0; g < stopG; g++) { + for (geometryIndex = 0; geometryIndex < stopG; geometryIndex++) { geometry = isGeometryCollection ? - geometryMaybeCollection.geometries[g] : geometryMaybeCollection; + geometryMaybeCollection.geometries[geometryIndex] : geometryMaybeCollection; // Handles null Geometry -- Skips this geometry if (geometry === null) continue; @@ -72,30 +77,34 @@ function coordEach(geojson, callback, excludeWrapCoord) { case null: break; case 'Point': - callback(coords, coordIndex); + callback(coords, coordIndex, featureIndex, featureSubIndex); coordIndex++; + featureSubIndex++; break; case 'LineString': case 'MultiPoint': for (j = 0; j < coords.length; j++) { - callback(coords[j], coordIndex); + callback(coords[j], coordIndex, featureIndex, featureSubIndex); coordIndex++; + featureSubIndex++; } break; case 'Polygon': case 'MultiLineString': for (j = 0; j < coords.length; j++) for (k = 0; k < coords[j].length - wrapShrink; k++) { - callback(coords[j][k], coordIndex); + callback(coords[j][k], coordIndex, featureIndex, featureSubIndex); coordIndex++; + featureSubIndex++; } break; case 'MultiPolygon': for (j = 0; j < coords.length; j++) for (k = 0; k < coords[j].length; k++) for (l = 0; l < coords[j][k].length - wrapShrink; l++) { - callback(coords[j][k][l], coordIndex); + callback(coords[j][k][l], coordIndex, featureIndex, featureSubIndex); coordIndex++; + featureSubIndex++; } break; case 'GeometryCollection': @@ -126,8 +135,10 @@ function coordEach(geojson, callback, excludeWrapCoord) { * @param {*} previousValue The accumulated value previously returned in the last invocation * of the callback, or initialValue, if supplied. * @param {Array} currentCoord The current coordinate being processed. - * @param {number} coordIndex The index of the current element being processed in the - * array.Starts at index 0, if an initialValue is provided, and at index 1 otherwise. + * @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} featureSubIndex The current subIndex of the feature being processed. */ /** @@ -145,18 +156,20 @@ function coordEach(geojson, callback, excludeWrapCoord) { * turf.point([36, 53], {"hello": "world"}) * ]); * - * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex) { + * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, featureSubIndex) { * //=previousValue * //=currentCoord * //=coordIndex + * //=featureIndex + * //=featureSubIndex * return currentCoord; * }); */ function coordReduce(geojson, callback, initialValue, excludeWrapCoord) { var previousValue = initialValue; - coordEach(geojson, function (currentCoord, coordIndex) { + coordEach(geojson, function (currentCoord, coordIndex, featureIndex, featureSubIndex) { if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord; - else previousValue = callback(previousValue, currentCoord, coordIndex); + else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, featureSubIndex); }, excludeWrapCoord); return previousValue; } diff --git a/packages/turf-meta/test.js b/packages/turf-meta/test.js index 910a35dbce..11b75f349f 100644 --- a/packages/turf-meta/test.js +++ b/packages/turf-meta/test.js @@ -499,11 +499,14 @@ const geojsonSegments = featureCollection([ test('segmentEach -- index & subIndex', t => { const index = []; const subIndex = []; - // Segment Each + let total = 0; + meta.segmentEach(geojsonSegments, (segment, featureIndex, featureSubIndex) => { index.push(featureIndex); subIndex.push(featureSubIndex); + total++; }); + t.equal(total, 8, 'total'); t.deepEqual(index, [1, 1, 2, 2, 2, 2, 4, 4], 'index'); t.deepEqual(subIndex, [0, 1, 0, 1, 2, 3, 0, 1], 'subIndex'); t.end(); @@ -512,12 +515,61 @@ test('segmentEach -- index & subIndex', t => { test('segmentReduce -- index & subIndex', t => { const index = []; const subIndex = []; - // Segment Each - meta.segmentReduce(geojsonSegments, (previousValue, segment, featureIndex, featureSubIndex) => { + + const total = meta.segmentReduce(geojsonSegments, (previousValue, segment, featureIndex, featureSubIndex) => { index.push(featureIndex); subIndex.push(featureSubIndex); - }); + previousValue++; + return previousValue; + }, 0); + + t.equal(total, 8, 'total'); t.deepEqual(index, [1, 1, 2, 2, 2, 2, 4, 4], 'index'); t.deepEqual(subIndex, [0, 1, 0, 1, 2, 3, 0, 1], 'subIndex'); t.end(); -}); \ No newline at end of file +}); + +const geojsonCoords = featureCollection([ + point([0, 1]), + lineString([[0, 0], [2, 2], [4, 4]]), + point([2, 2]) +]); + +test('coordEach -- index & subIndex', t => { + const coordIndexes = []; + const featureIndexes = []; + const featureSubIndexes = []; + let total = 0; + + meta.coordEach(geojsonCoords, (coord, coordIndex, featureIndex, featureSubIndex) => { + coordIndexes.push(coordIndex); + featureIndexes.push(featureIndex); + featureSubIndexes.push(featureSubIndex); + total++; + }); + t.equal(total, 5, 'total'); + t.deepEqual(coordIndexes, [0, 1, 2, 3, 4], 'coordIndex'); + t.deepEqual(featureIndexes, [0, 1, 1, 1, 2], 'featureIndex'); + t.deepEqual(featureSubIndexes, [0, 0, 1, 2, 0], 'featureSubIndex'); + t.end(); +}); + +test('coordEach -- index & subIndex', t => { + const coordIndexes = []; + const featureIndexes = []; + const featureSubIndexes = []; + + const total = meta.coordReduce(geojsonCoords, (previousValue, coord, coordIndex, featureIndex, featureSubIndex) => { + coordIndexes.push(coordIndex); + featureIndexes.push(featureIndex); + featureSubIndexes.push(featureSubIndex); + previousValue++; + return previousValue; + }, 0); + + t.equal(total, 5); + t.deepEqual(coordIndexes, [0, 1, 2, 3, 4], 'coordIndex'); + t.deepEqual(featureIndexes, [0, 1, 1, 1, 2], 'featureIndex'); + t.deepEqual(featureSubIndexes, [0, 0, 1, 2, 0], 'featureSubIndex'); + t.end(); +});