From e6b4004f320f094e30dbb5658713c3474f70d057 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 26 Jul 2017 09:51:46 -0400 Subject: [PATCH 01/13] Support Null geometries --- packages/turf-helpers/index.js | 3 ++- packages/turf-helpers/test.js | 7 ++++++ packages/turf-invariant/index.d.ts | 2 +- packages/turf-invariant/index.js | 13 ++++++----- packages/turf-invariant/test.js | 14 ++++++++++++ packages/turf-invariant/types.ts | 28 ++++++++++++++++++++++++ packages/turf-meta/index.js | 35 ++++++++++++++++++------------ packages/turf-meta/test.js | 28 +++++++++++++++++++++++- 8 files changed, 108 insertions(+), 22 deletions(-) create mode 100644 packages/turf-invariant/types.ts diff --git a/packages/turf-helpers/index.js b/packages/turf-helpers/index.js index 3c8a6517a6..d626536235 100644 --- a/packages/turf-helpers/index.js +++ b/packages/turf-helpers/index.js @@ -16,7 +16,7 @@ * //=feature */ function feature(geometry, properties) { - if (!geometry) throw new Error('No geometry passed'); + if (geometry === undefined) throw new Error('No geometry passed'); return { type: 'Feature', @@ -248,6 +248,7 @@ function multiPolygon(coordinates, properties) { */ function geometryCollection(geometries, properties) { if (!geometries) throw new Error('geometries is required'); + if (!Array.isArray(geometries)) throw new Error('geometries must be an Array'); return feature({ type: 'GeometryCollection', diff --git a/packages/turf-helpers/test.js b/packages/turf-helpers/test.js index dc709cbc28..c0db9bfe94 100644 --- a/packages/turf-helpers/test.js +++ b/packages/turf-helpers/test.js @@ -385,3 +385,10 @@ test('convertArea', t => { t.end(); }); + +// https://github.com/Turfjs/turf/issues/853 +test('null geometries', t => { + t.equal(feature(null).geometry, null); + t.equal(featureCollection([feature(null)]).features[0].geometry, null); + t.end(); +}) \ No newline at end of file diff --git a/packages/turf-invariant/index.d.ts b/packages/turf-invariant/index.d.ts index 527950c85b..6a59077df1 100644 --- a/packages/turf-invariant/index.d.ts +++ b/packages/turf-invariant/index.d.ts @@ -38,7 +38,7 @@ export function containsNumber(coordinates: any[]): boolean; /** * http://turfjs.org/docs/ */ -export function getGeom(geojson: GeometryCollection | GeometryObject | Feature): boolean; +export function getGeom(geojson: GeometryCollection | GeometryObject | Feature): GeometryObject; /** * http://turfjs.org/docs/ diff --git a/packages/turf-invariant/index.js b/packages/turf-invariant/index.js index ff1c87591b..73292440ef 100644 --- a/packages/turf-invariant/index.js +++ b/packages/turf-invariant/index.js @@ -140,7 +140,7 @@ function collectionOf(featureCollection, type, name) { * Get Geometry from Feature or Geometry Object * * @param {Feature|Geometry} geojson GeoJSON Feature or Geometry Object - * @returns {Geometry} GeoJSON Geometry Object + * @returns {Geometry|null} GeoJSON Geometry Object * @throws {Error} if geojson is not a Feature or Geometry Object * @example * var point = { @@ -155,8 +155,9 @@ function collectionOf(featureCollection, type, name) { * //={"type": "Point", "coordinates": [110, 40]} */ function getGeom(geojson) { - if (!geojson) throw new Error(' is required'); - if (geojson.geometry) return geojson.geometry; + if (geojson === undefined) throw new Error(' is required'); + if (geojson === null) return null; + if (geojson.geometry !== undefined) return geojson.geometry; if (geojson.coordinates || geojson.geometries) return geojson; throw new Error(' must be a Feature or Geometry Object'); } @@ -165,7 +166,7 @@ function getGeom(geojson) { * Get Geometry Type from Feature or Geometry Object * * @param {Feature|Geometry} geojson GeoJSON Feature or Geometry Object - * @returns {string} GeoJSON Geometry Type + * @returns {string|null} GeoJSON Geometry Type * @throws {Error} if geojson is not a Feature or Geometry Object * @example * var point = { @@ -180,7 +181,9 @@ function getGeom(geojson) { * //="Point" */ function getGeomType(geojson) { - return getGeom(geojson).type; + var geom = getGeom(geojson); + if (geom === null) return null; + return (geom) ? geom.type : undefined; } module.exports = { diff --git a/packages/turf-invariant/test.js b/packages/turf-invariant/test.js index 19874b6af0..05dbb57cb6 100644 --- a/packages/turf-invariant/test.js +++ b/packages/turf-invariant/test.js @@ -208,3 +208,17 @@ test('invariant#getGeomType', t => { t.throws(() => invariant.getGeomType(collection, 'featureCollection not valid')); t.end(); }); + +// https://github.com/Turfjs/turf/issues/853 +test('null geometries', t => { + const nullFeature = { + type: 'Feature', + properties: {}, + geometry: null + } + t.equal(invariant.getGeom(null), null); + t.equal(invariant.getGeomType(null), null); + t.equal(invariant.getGeom(nullFeature), null); + t.equal(invariant.getGeomType(nullFeature), null); + t.end(); +}); diff --git a/packages/turf-invariant/types.ts b/packages/turf-invariant/types.ts new file mode 100644 index 0000000000..33255ac3b9 --- /dev/null +++ b/packages/turf-invariant/types.ts @@ -0,0 +1,28 @@ +import {point, lineString, polygon, geometryCollection, featureCollection} from '@turf/helpers' +import * as invariant from './' + +const pt = point([0, 0]) +const line = lineString([[0, 0], [1, 1]]) +const poly = polygon([[[0, 0], [1, 1], [2, 2], [0, 0]]]) +const gc = geometryCollection([pt.geometry, line.geometry, poly.geometry]) +const fc = featureCollection([pt, line, poly]) + +/** + * getGeomType + */ +// invariant.getGeomType(fc) // Argument of type 'FeatureCollection' is not assignable to parameter of type +invariant.getGeomType(gc) +invariant.getGeomType(pt) +invariant.getGeomType(poly) +invariant.getGeomType(line) +invariant.getGeomType(pt.geometry) + +/** + * getGeom + */ +// invariant.getGeom(fc) // Argument of type 'FeatureCollection' is not assignable to parameter of type +invariant.getGeom(gc) +invariant.getGeom(pt) +invariant.getGeom(line) +invariant.getGeom(poly) +invariant.getGeom(pt.geometry) diff --git a/packages/turf-meta/index.js b/packages/turf-meta/index.js index 5b49e5651d..c901a4eddb 100644 --- a/packages/turf-meta/index.js +++ b/packages/turf-meta/index.js @@ -544,28 +544,33 @@ function geomEach(geojson, callback) { (isFeature ? geojson.geometry : geojson)); geometryProperties = (isFeatureCollection ? geojson.features[i].properties : (isFeature ? geojson.properties : {})); - isGeometryCollection = geometryMaybeCollection.type === 'GeometryCollection'; + isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false; stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1; for (g = 0; g < stopG; g++) { geometry = isGeometryCollection ? geometryMaybeCollection.geometries[g] : geometryMaybeCollection; - - if (geometry.type === 'Point' || - geometry.type === 'LineString' || - geometry.type === 'MultiPoint' || - geometry.type === 'Polygon' || - geometry.type === 'MultiLineString' || - geometry.type === 'MultiPolygon') { + var type = (geometry === null) ? null : geometry.type; + switch (type) { + case null: + case 'Point': + case 'LineString': + case 'MultiPoint': + case 'Polygon': + case 'MultiLineString': + case 'MultiPolygon': { callback(geometry, currentIndex, geometryProperties); currentIndex++; - } else if (geometry.type === 'GeometryCollection') { + break; + } + case 'GeometryCollection': { for (j = 0; j < geometry.geometries.length; j++) { callback(geometry.geometries[j], currentIndex, geometryProperties); currentIndex++; } - } else { - throw new Error('Unknown Geometry Type'); + break; + } + default: throw new Error('Unknown Geometry Type'); } } } @@ -693,9 +698,11 @@ function geomReduce(geojson, callback, initialValue) { */ function flattenEach(geojson, callback) { geomEach(geojson, function (geometry, index, properties) { + var type = (geometry === null) ? null : geometry.type; // Callback for single geometry - switch (geometry.type) { + switch (type) { + case null: case 'Point': case 'LineString': case 'Polygon': @@ -706,7 +713,7 @@ function flattenEach(geojson, callback) { var geomType; // Callback for multi-geometry - switch (geometry.type) { + switch (type) { case 'MultiPoint': geomType = 'Point'; break; @@ -813,7 +820,7 @@ function flattenReduce(geojson, callback, initialValue) { * @returns {Feature} GeoJSON Feature */ function feature(geometry, properties) { - if (!geometry) throw new Error('No geometry passed'); + if (geometry === undefined) throw new Error('No geometry passed'); return { type: 'Feature', diff --git a/packages/turf-meta/test.js b/packages/turf-meta/test.js index 97482e2332..3c139319b8 100644 --- a/packages/turf-meta/test.js +++ b/packages/turf-meta/test.js @@ -1,6 +1,14 @@ const test = require('tape'); -const {lineString} = require('@turf/helpers'); +const {lineString, feature, featureCollection} = require('@turf/helpers'); const meta = require('./'); +const { + featureEach, + featureReduce, + flattenEach, + flattenReduce, + geomEach, + geomReduce +} = require('./'); const pointGeometry = { type: 'Point', @@ -408,3 +416,21 @@ test('flattenReduce#previous-feature+initialValue', t => { t.deepEqual(sum, features[features.length - 1]); t.end(); }); + +// https://github.com/Turfjs/turf/issues/853 +test('null geometries', t => { + const fc = featureCollection([ + feature(null), + feature(null) + ]); + // Each operations + featureEach(fc, feature => t.equal(feature.geometry, null)); + geomEach(fc, geometry => t.equal(geometry, null)); + flattenEach(fc, feature => t.equal(feature.geometry, null)); + + // Reduce operations + t.equal(featureReduce(fc, prev => prev += 1, 0), 2); + t.equal(geomReduce(fc, prev => prev += 1, 0), 2); + t.equal(flattenReduce(fc, prev => prev += 1, 0), 2); + t.end(); +}) \ No newline at end of file From 25ca919101eb805d047c04529425d57781d54fc9 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 26 Jul 2017 10:58:02 -0400 Subject: [PATCH 02/13] Add coordEach & coordReduce to null geometry support --- packages/turf-meta/index.js | 61 +++++++++++++++++++++---------------- packages/turf-meta/test.js | 20 +++++++----- 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/packages/turf-meta/index.js b/packages/turf-meta/index.js index c901a4eddb..d3a0f228ec 100644 --- a/packages/turf-meta/index.js +++ b/packages/turf-meta/index.js @@ -48,64 +48,73 @@ function coordEach(geojson, callback, excludeWrapCoord) { wrapShrink = 0, currentIndex = 0, isGeometryCollection, - isFeatureCollection = geojson.type === 'FeatureCollection', - isFeature = geojson.type === 'Feature', + type = (geojson) ? geojson.type : null, + 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. + // 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)); - isGeometryCollection = geometryMaybeCollection.type === 'GeometryCollection'; + isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false; stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1; for (g = 0; g < stopG; g++) { geometry = isGeometryCollection ? geometryMaybeCollection.geometries[g] : geometryMaybeCollection; - coords = geometry.coordinates; + coords = (geometry === null) ? null : geometry.coordinates; + var geomType = (geometry === null) ? null : geometry.type; - wrapShrink = (excludeWrapCoord && - (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon')) ? - 1 : 0; + wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0; - if (geometry.type === 'Point') { + switch (geomType) { + case null: + return; + case 'Point': callback(coords, currentIndex); currentIndex++; - } else if (geometry.type === 'LineString' || geometry.type === 'MultiPoint') { + break; + case 'LineString': + case 'MultiPoint': for (j = 0; j < coords.length; j++) { callback(coords[j], currentIndex); currentIndex++; } - } else if (geometry.type === 'Polygon' || geometry.type === 'MultiLineString') { + 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], currentIndex); currentIndex++; } - } else if (geometry.type === 'MultiPolygon') { + 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], currentIndex); currentIndex++; } - } else if (geometry.type === 'GeometryCollection') { + break; + case 'GeometryCollection': for (j = 0; j < geometry.geometries.length; j++) coordEach(geometry.geometries[j], callback, excludeWrapCoord); - } else { - throw new Error('Unknown Geometry Type'); + break; + default: throw new Error('Unknown Geometry Type'); } } } diff --git a/packages/turf-meta/test.js b/packages/turf-meta/test.js index 3c139319b8..7a8fea0a6f 100644 --- a/packages/turf-meta/test.js +++ b/packages/turf-meta/test.js @@ -7,7 +7,9 @@ const { flattenEach, flattenReduce, geomEach, - geomReduce + geomReduce, + coordEach, + coordReduce } = require('./'); const pointGeometry = { @@ -424,13 +426,15 @@ test('null geometries', t => { feature(null) ]); // Each operations - featureEach(fc, feature => t.equal(feature.geometry, null)); - geomEach(fc, geometry => t.equal(geometry, null)); - flattenEach(fc, feature => t.equal(feature.geometry, null)); + featureEach(fc, feature => t.equal(feature.geometry, null, 'featureEach')); + geomEach(fc, geometry => t.equal(geometry, null, 'geomEach')); + flattenEach(fc, feature => t.equal(feature.geometry, null, 'flattenEach')); + coordEach(fc, () => {}, 'coordEach'); // Reduce operations - t.equal(featureReduce(fc, prev => prev += 1, 0), 2); - t.equal(geomReduce(fc, prev => prev += 1, 0), 2); - t.equal(flattenReduce(fc, prev => prev += 1, 0), 2); + t.equal(featureReduce(fc, prev => prev += 1, 0), 2, 'featureReduce'); + t.equal(geomReduce(fc, prev => prev += 1, 0), 2, 'geomReduce'); + t.equal(flattenReduce(fc, prev => prev += 1, 0), 2, 'flattenReduce'); + t.equal(coordReduce(fc, prev => prev += 1, 0), 0, 'coordReduce'); t.end(); -}) \ No newline at end of file +}); From 11fb27a5745d8adec9615d5e94d3f55187a5d589 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 26 Jul 2017 11:24:07 -0400 Subject: [PATCH 03/13] Add null geometry tests for `@turf/bbox` --- packages/turf-bbox/test.js | 129 +++++++++---------- packages/turf-bbox/test/FeatureCollection.js | 39 ------ packages/turf-bbox/test/LineString.js | 21 --- packages/turf-bbox/test/MultiLineString.js | 25 ---- packages/turf-bbox/test/MultiPolygon.js | 75 ----------- packages/turf-bbox/test/Point.js | 10 -- packages/turf-bbox/test/Polygon.js | 26 ---- 7 files changed, 60 insertions(+), 265 deletions(-) delete mode 100644 packages/turf-bbox/test/FeatureCollection.js delete mode 100644 packages/turf-bbox/test/LineString.js delete mode 100644 packages/turf-bbox/test/MultiLineString.js delete mode 100644 packages/turf-bbox/test/MultiPolygon.js delete mode 100644 packages/turf-bbox/test/Point.js delete mode 100644 packages/turf-bbox/test/Polygon.js diff --git a/packages/turf-bbox/test.js b/packages/turf-bbox/test.js index 10038521f3..761f00c000 100644 --- a/packages/turf-bbox/test.js +++ b/packages/turf-bbox/test.js @@ -1,72 +1,63 @@ -var test = require('tape'); -var fs = require('fs'); -var extent = require('./'); - -// test data -var fc = require('./test/FeatureCollection'); -var pt = require('./test/Point'); -var line = require('./test/LineString'); -var poly = require('./test/Polygon'); -var multiLine = require('./test/MultiLineString'); -var multiPoly = require('./test/MultiPolygon'); - -test('extent', function(t){ - // FeatureCollection - var fcExtent = extent(fc); - - t.ok(fcExtent, 'FeatureCollection'); - t.equal(fcExtent[0], 20); - t.equal(fcExtent[1], -10); - t.equal(fcExtent[2], 130); - t.equal(fcExtent[3], 4); - - // Point - var ptExtent = extent(pt); - t.ok(ptExtent, 'Point'); - t.equal(ptExtent[0], 102); - t.equal(ptExtent[1], 0.5); - t.equal(ptExtent[2], 102); - t.equal(ptExtent[3], 0.5); - - // Line - var lineExtent = extent(line); - - t.ok(lineExtent, 'Line'); - t.equal(lineExtent[0], 102); - t.equal(lineExtent[1], -10); - t.equal(lineExtent[2], 130); - t.equal(lineExtent[3], 4); - - // Polygon - var polyExtent = extent(poly); - - t.ok(polyExtent, 'Polygon'); - t.equal(polyExtent[0], 100); - t.equal(polyExtent[1], 0); - t.equal(polyExtent[2], 101); - t.equal(polyExtent[3], 1); - - // MultiLineString - var multiLineExtent = extent(multiLine); - - t.ok(multiLineExtent, 'MultiLineString'); - t.equal(multiLineExtent[0], 100); - t.equal(multiLineExtent[1], 0); - t.equal(multiLineExtent[2], 103); - t.equal(multiLineExtent[3], 3); - - // MultiPolygon - var multiPolyExtent = extent(multiPoly); - - t.ok(multiPolyExtent, 'MultiPolygon'); - t.equal(multiPolyExtent[0], 100); - t.equal(multiPolyExtent[1], 0); - t.equal(multiPolyExtent[2], 103); - t.equal(multiPolyExtent[3], 3); +const test = require('tape'); +const { + point, + lineString, + polygon, + feature, + featureCollection, + multiPolygon, + multiLineString} = require('@turf/helpers'); +const bbox = require('./'); + +// Fixtures +const pt = point([102.0, 0.5]); +const line = lineString([[102.0, -10.0], [103.0, 1.0], [104.0, 0.0], [130.0, 4.0]]); +const poly = polygon([[[101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0], [101.0, 0.0]]]); +const multiLine = multiLineString([ + [[100.0, 0.0], [101.0, 1.0]], + [[102.0, 2.0], [103.0, 3.0]] +]); +const multiPoly = multiPolygon([ + [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]], + [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]] +]); +const fc = featureCollection([pt, line, poly, multiLine, multiPoly]); + +test('bbox', t => { + // FeatureCollection + const fcBBox = bbox(fc); + t.deepEqual(fcBBox, [100, -10, 130, 4], 'featureCollection'); + + // Point + const ptBBox = bbox(pt); + t.deepEqual(ptBBox, [102, 0.5, 102, 0.5], 'point'); + + // Line + const lineBBox = bbox(line); + t.deepEqual(lineBBox, [102, -10, 130, 4], 'lineString'); + + // Polygon + const polyExtent = bbox(poly); + t.deepEqual(polyExtent, [100, 0, 101, 1], 'polygon'); + + // MultiLineString + const multiLineBBox = bbox(multiLine); + t.deepEqual(multiLineBBox, [100, 0, 103, 3], 'multiLineString'); + + // MultiPolygon + const multiPolyBBox = bbox(multiPoly); + t.deepEqual(multiPolyBBox, [100, 0, 103, 3], 'multiPolygon'); + + + t.end(); +}); - t.throws(function() { - var multiPolyExtent = extent({}); - }, /Unknown Geometry Type/, 'unknown geometry type error'); +test('bbox -- throws', t => { + t.throws(() => bbox({}), /Unknown Geometry Type/, 'unknown geometry type error'); + t.end(); +}); - t.end(); +test('bbox -- null geometries', t => { + t.deepEqual(bbox(feature(null)), [Infinity, Infinity, -Infinity, -Infinity]); + t.end(); }); diff --git a/packages/turf-bbox/test/FeatureCollection.js b/packages/turf-bbox/test/FeatureCollection.js deleted file mode 100644 index 89a859f2bc..0000000000 --- a/packages/turf-bbox/test/FeatureCollection.js +++ /dev/null @@ -1,39 +0,0 @@ -module.exports = { - 'type': 'FeatureCollection', - 'features': [ - { - 'type': 'Feature', - 'geometry': { - 'type': 'Point', - 'coordinates': [102.0, 0.5] - }, - 'properties': { - } - }, - { - 'type': 'Feature', - 'geometry': { - 'type': 'LineString', - 'coordinates': [ - [102.0, -10.0], [103.0, 1.0], [104.0, 0.0], [130.0, 4.0] - ] - }, - 'properties': { - } - }, - { - 'type': 'Feature', - 'geometry': { - 'type': 'Polygon', - 'coordinates': [ - [ - [20.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], - [100.0, 0.0] - ] - ] - }, - 'properties': { - } - } - ] -}; diff --git a/packages/turf-bbox/test/LineString.js b/packages/turf-bbox/test/LineString.js deleted file mode 100644 index 10ee8da151..0000000000 --- a/packages/turf-bbox/test/LineString.js +++ /dev/null @@ -1,21 +0,0 @@ -module.exports = { - 'type': 'LineString', - 'coordinates': [ - [ - 102.0, - -10.0 - ], - [ - 103.0, - 1.0 - ], - [ - 104.0, - 0.0 - ], - [ - 130.0, - 4.0 - ] - ] -}; diff --git a/packages/turf-bbox/test/MultiLineString.js b/packages/turf-bbox/test/MultiLineString.js deleted file mode 100644 index 43e742a373..0000000000 --- a/packages/turf-bbox/test/MultiLineString.js +++ /dev/null @@ -1,25 +0,0 @@ -module.exports = { - 'type': 'MultiLineString', - 'coordinates': [ - [ - [ - 100.0, - 0.0 - ], - [ - 101.0, - 1.0 - ] - ], - [ - [ - 102.0, - 2.0 - ], - [ - 103.0, - 3.0 - ] - ] - ] -}; diff --git a/packages/turf-bbox/test/MultiPolygon.js b/packages/turf-bbox/test/MultiPolygon.js deleted file mode 100644 index e21cd8a469..0000000000 --- a/packages/turf-bbox/test/MultiPolygon.js +++ /dev/null @@ -1,75 +0,0 @@ -module.exports = { - 'type': 'MultiPolygon', - 'coordinates': [ - [ - [ - [ - 102.0, - 2.0 - ], - [ - 103.0, - 2.0 - ], - [ - 103.0, - 3.0 - ], - [ - 102.0, - 3.0 - ], - [ - 102.0, - 2.0 - ] - ] - ], - [ - [ - [ - 100.0, - 0.0 - ], - [ - 101.0, - 0.0 - ], - [ - 101.0, - 1.0 - ], - [ - 100.0, - 1.0 - ], - [ - 100.0, - 0.0 - ] - ], - [ - [ - 100.2, - 0.2 - ], - [ - 100.8, - 0.2 - ], - [ - 100.8, - 0.8 - ], - [ - 100.2, - 0.8 - ], - [ - 100.2, - 0.2 - ] - ] - ] - ] -}; diff --git a/packages/turf-bbox/test/Point.js b/packages/turf-bbox/test/Point.js deleted file mode 100644 index f25c36270f..0000000000 --- a/packages/turf-bbox/test/Point.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - 'type': 'Feature', - 'geometry': { - 'type': 'Point', - 'coordinates': [ - 102.0, - 0.5 - ] - } -}; diff --git a/packages/turf-bbox/test/Polygon.js b/packages/turf-bbox/test/Polygon.js deleted file mode 100644 index 437c3ad518..0000000000 --- a/packages/turf-bbox/test/Polygon.js +++ /dev/null @@ -1,26 +0,0 @@ -module.exports = { - 'type': 'Feature', - 'geometry': { - 'type': 'Polygon', - 'coordinates': [ - [ - [ - 101.0, - 0.0 - ], - [ - 101.0, - 1.0 - ], - [ - 100.0, - 1.0 - ], - [ - 100.0, - 0.0 - ] - ] - ] - } -}; From 060df66e0b099798c064b0ad15ef9fa5fbc0a381 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 26 Jul 2017 13:02:52 -0400 Subject: [PATCH 04/13] Throw error if null is input https://github.com/Turfjs/turf/pull/866\#pullrequestreview-52398355 --- packages/turf-invariant/index.js | 9 ++++----- packages/turf-invariant/test.js | 10 +++++----- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/turf-invariant/index.js b/packages/turf-invariant/index.js index 9da0831018..97c7bdf9c8 100644 --- a/packages/turf-invariant/index.js +++ b/packages/turf-invariant/index.js @@ -165,11 +165,10 @@ function collectionOf(featureCollection, type, name) { * //={"type": "Point", "coordinates": [110, 40]} */ function getGeom(geojson) { - if (geojson === undefined) throw new Error(' is required'); - if (geojson === null) return null; + if (!geojson) throw new Error('geojson is required'); if (geojson.geometry !== undefined) return geojson.geometry; if (geojson.coordinates || geojson.geometries) return geojson; - throw new Error(' must be a Feature or Geometry Object'); + throw new Error('geojson must be a valid Feature or Geometry Object'); } /** @@ -191,9 +190,9 @@ function getGeom(geojson) { * //="Point" */ function getGeomType(geojson) { + if (!geojson) throw new Error('geojson is required'); var geom = getGeom(geojson); - if (geom === null) return null; - return (geom) ? geom.type : undefined; + if (geom) return geom.type; } module.exports = { diff --git a/packages/turf-invariant/test.js b/packages/turf-invariant/test.js index 05dbb57cb6..efc595cbda 100644 --- a/packages/turf-invariant/test.js +++ b/packages/turf-invariant/test.js @@ -215,10 +215,10 @@ test('null geometries', t => { type: 'Feature', properties: {}, geometry: null - } - t.equal(invariant.getGeom(null), null); - t.equal(invariant.getGeomType(null), null); - t.equal(invariant.getGeom(nullFeature), null); - t.equal(invariant.getGeomType(nullFeature), null); + }; + t.throws(() => invariant.getGeom(null), /geojson is required/, 'getGeom => geojson is required'); + t.throws(() => invariant.getGeomType(null), /geojson is required/, 'getGeomType => geojson is required'); + t.equal(invariant.getGeom(nullFeature), null, 'getGeom => null'); + t.equal(invariant.getGeomType(nullFeature), undefined, 'getGeomType => undefined'); t.end(); }); From 2b4fb44464f9c0c848c676c67ceed9a203114e93 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 26 Jul 2017 13:11:29 -0400 Subject: [PATCH 05/13] Add getCoord & getCoords tests --- packages/turf-invariant/index.js | 28 ++++++++++++++-------------- packages/turf-invariant/test.js | 3 +++ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/packages/turf-invariant/index.js b/packages/turf-invariant/index.js index 97c7bdf9c8..92de081ab7 100644 --- a/packages/turf-invariant/index.js +++ b/packages/turf-invariant/index.js @@ -29,29 +29,29 @@ function getCoord(obj) { * Unwrap coordinates from a Feature, Geometry Object or an Array of numbers * * @name getCoords - * @param {Array|Geometry|Feature} obj any value - * @returns {Array} coordinates + * @param {Array|Geometry|Feature} geojson GeoJSON object + * @returns {Array} coordinates * @example * var poly = turf.polygon([[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]]); * * var coord = turf.getCoords(poly); * //= [[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]] */ -function getCoords(obj) { - if (!obj) throw new Error('No obj passed'); +function getCoords(geojson) { + if (!geojson) throw new Error('geojson is required'); var coordinates; // Array of numbers - if (obj.length) { - coordinates = obj; + if (geojson.length) { + coordinates = geojson; // Geometry Object - } else if (obj.coordinates) { - coordinates = obj.coordinates; + } else if (geojson.coordinates) { + coordinates = geojson.coordinates; // Feature - } else if (obj.geometry && obj.geometry.coordinates) { - coordinates = obj.geometry.coordinates; + } else if (geojson.geometry && geojson.geometry.coordinates) { + coordinates = geojson.geometry.coordinates; } // Checks if coordinates contains a number if (coordinates) { @@ -149,8 +149,8 @@ function collectionOf(featureCollection, type, name) { /** * Get Geometry from Feature or Geometry Object * - * @param {Feature|Geometry} geojson GeoJSON Feature or Geometry Object - * @returns {Geometry|null} GeoJSON Geometry Object + * @param {Feature|Geometry} geojson GeoJSON Feature or Geometry Object + * @returns {Geometry|null} GeoJSON Geometry Object * @throws {Error} if geojson is not a Feature or Geometry Object * @example * var point = { @@ -174,8 +174,8 @@ function getGeom(geojson) { /** * Get Geometry Type from Feature or Geometry Object * - * @param {Feature|Geometry} geojson GeoJSON Feature or Geometry Object - * @returns {string|null} GeoJSON Geometry Type + * @param {Feature|Geometry} geojson GeoJSON Feature or Geometry Object + * @returns {string} GeoJSON Geometry Type * @throws {Error} if geojson is not a Feature or Geometry Object * @example * var point = { diff --git a/packages/turf-invariant/test.js b/packages/turf-invariant/test.js index efc595cbda..83c5aaf26f 100644 --- a/packages/turf-invariant/test.js +++ b/packages/turf-invariant/test.js @@ -218,6 +218,9 @@ test('null geometries', t => { }; t.throws(() => invariant.getGeom(null), /geojson is required/, 'getGeom => geojson is required'); t.throws(() => invariant.getGeomType(null), /geojson is required/, 'getGeomType => geojson is required'); + t.throws(() => invariant.getCoords(nullFeature), /No valid coordinates/, 'getCoords => No valid coordinates'); + t.throws(() => invariant.getCoord(nullFeature), /No valid coordinates/, 'getCoord => No valid coordinates'); + t.equal(invariant.getGeom(nullFeature), null, 'getGeom => null'); t.equal(invariant.getGeomType(nullFeature), undefined, 'getGeomType => undefined'); t.end(); From d972c1fdcbe4dedbb345b5bfd88e8b84ae637280 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 26 Jul 2017 13:14:47 -0400 Subject: [PATCH 06/13] Update JSDocs --- packages/turf-invariant/index.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/turf-invariant/index.js b/packages/turf-invariant/index.js index 92de081ab7..4c81b6a42a 100644 --- a/packages/turf-invariant/index.js +++ b/packages/turf-invariant/index.js @@ -2,7 +2,7 @@ * Unwrap a coordinate from a Point Feature, Geometry or a single coordinate. * * @name getCoord - * @param {Array|Geometry|Feature} obj any value + * @param {Array|Geometry|Feature} obj Object * @returns {Array} coordinates * @example * var pt = turf.point([10, 10]); @@ -11,7 +11,7 @@ * //= [10, 10] */ function getCoord(obj) { - if (!obj) throw new Error('No obj passed'); + if (!obj) throw new Error('obj is required'); var coordinates = getCoords(obj); @@ -29,7 +29,7 @@ function getCoord(obj) { * Unwrap coordinates from a Feature, Geometry Object or an Array of numbers * * @name getCoords - * @param {Array|Geometry|Feature} geojson GeoJSON object + * @param {Array|Geometry|Feature} obj Object * @returns {Array} coordinates * @example * var poly = turf.polygon([[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]]); @@ -37,21 +37,21 @@ function getCoord(obj) { * var coord = turf.getCoords(poly); * //= [[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]] */ -function getCoords(geojson) { - if (!geojson) throw new Error('geojson is required'); +function getCoords(obj) { + if (!obj) throw new Error('obj is required'); var coordinates; // Array of numbers - if (geojson.length) { - coordinates = geojson; + if (obj.length) { + coordinates = obj; // Geometry Object - } else if (geojson.coordinates) { - coordinates = geojson.coordinates; + } else if (obj.coordinates) { + coordinates = obj.coordinates; // Feature - } else if (geojson.geometry && geojson.geometry.coordinates) { - coordinates = geojson.geometry.coordinates; + } else if (obj.geometry && obj.geometry.coordinates) { + coordinates = obj.geometry.coordinates; } // Checks if coordinates contains a number if (coordinates) { From 42f837c0b574d9c1cfac58a12ab6e69a7b60016d Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 26 Jul 2017 13:51:10 -0400 Subject: [PATCH 07/13] Add more Meta null testing --- packages/turf-meta/index.js | 11 ++++++----- packages/turf-meta/test.js | 26 ++++++++++++++++++++------ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/packages/turf-meta/index.js b/packages/turf-meta/index.js index 86ff3a2e27..9002e6a6a6 100644 --- a/packages/turf-meta/index.js +++ b/packages/turf-meta/index.js @@ -66,7 +66,7 @@ function coordEach(geojson, callback, excludeWrapCoord) { switch (geomType) { case null: - return; + break; case 'Point': callback(coords, currentIndex); currentIndex++; @@ -433,6 +433,8 @@ function geomEach(geojson, callback) { var type = (geometry === null) ? null : geometry.type; switch (type) { case null: + currentIndex++; + break; case 'Point': case 'LineString': case 'MultiPoint': @@ -546,11 +548,10 @@ function geomReduce(geojson, callback, initialValue) { */ function flattenEach(geojson, callback) { geomEach(geojson, function (geometry, index, properties) { - var type = (geometry === null) ? null : geometry.type; + if (geometry === null) return; // Callback for single geometry - switch (type) { - case null: + switch (geometry.type) { case 'Point': case 'LineString': case 'Polygon': @@ -561,7 +562,7 @@ function flattenEach(geojson, callback) { var geomType; // Callback for multi-geometry - switch (type) { + switch (geometry.type) { case 'MultiPoint': geomType = 'Point'; break; diff --git a/packages/turf-meta/test.js b/packages/turf-meta/test.js index 7a8fea0a6f..415e085de1 100644 --- a/packages/turf-meta/test.js +++ b/packages/turf-meta/test.js @@ -1,5 +1,5 @@ const test = require('tape'); -const {lineString, feature, featureCollection} = require('@turf/helpers'); +const {point, lineString, feature, featureCollection} = require('@turf/helpers'); const meta = require('./'); const { featureEach, @@ -425,16 +425,30 @@ test('null geometries', t => { feature(null), feature(null) ]); + // Each operations featureEach(fc, feature => t.equal(feature.geometry, null, 'featureEach')); - geomEach(fc, geometry => t.equal(geometry, null, 'geomEach')); - flattenEach(fc, feature => t.equal(feature.geometry, null, 'flattenEach')); - coordEach(fc, () => {}, 'coordEach'); + geomEach(fc, () => t.fail('no geometries should be found')); + flattenEach(fc, () => t.fail('no features should be found')); + coordEach(fc, () => t.fail('no coordinates should be found')); // Reduce operations t.equal(featureReduce(fc, prev => prev += 1, 0), 2, 'featureReduce'); - t.equal(geomReduce(fc, prev => prev += 1, 0), 2, 'geomReduce'); - t.equal(flattenReduce(fc, prev => prev += 1, 0), 2, 'flattenReduce'); + t.equal(geomReduce(fc, prev => prev += 1, 0), 0, 'geomReduce'); + t.equal(flattenReduce(fc, prev => prev += 1, 0), 0, 'flattenReduce'); t.equal(coordReduce(fc, prev => prev += 1, 0), 0, 'coordReduce'); t.end(); }); + +test('null geometries -- index', t => { + const fc = featureCollection([ + feature(null), // index 0 + point([0, 0]), // index 1 + feature(null), // index 2 + lineString([0, 0]) // index 3 + ]); + t.deepEqual(meta.coordReduce(fc, (prev, coords, i) => prev.concat(i), []), [0, 1, 2], 'coordReduce'); + t.deepEqual(meta.geomReduce(fc, (prev, geom, i) => prev.concat(i), []), [1, 3], 'geomReduce'); + t.deepEqual(meta.flattenReduce(fc, (prev, feature, i) => prev.concat(i), []), [1, 3], 'flattenReduce'); + t.end(); +}); From 72f21912d7aebed13e0decdf214405a4abd3e4ec Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 26 Jul 2017 14:43:45 -0400 Subject: [PATCH 08/13] fix tests --- packages/turf-meta/test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/turf-meta/test.js b/packages/turf-meta/test.js index ad729d27a3..dbf0775325 100644 --- a/packages/turf-meta/test.js +++ b/packages/turf-meta/test.js @@ -450,6 +450,7 @@ test('null geometries -- index', t => { t.deepEqual(meta.coordReduce(fc, (prev, coords, i) => prev.concat(i), []), [0, 1, 2], 'coordReduce'); t.deepEqual(meta.geomReduce(fc, (prev, geom, i) => prev.concat(i), []), [1, 3], 'geomReduce'); t.deepEqual(meta.flattenReduce(fc, (prev, feature, i) => prev.concat(i), []), [1, 3], 'flattenReduce'); + t.end(); }); test('segmentEach', t => { From d653e8f6acd745e3acabc3721e50c1e067c4d17b Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 27 Jul 2017 10:16:25 -0400 Subject: [PATCH 09/13] do NOT exclude null geometries from geomEach & flattenEach --- packages/turf-meta/index.js | 13 ++++++------- packages/turf-meta/test.js | 16 ++++++++-------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/packages/turf-meta/index.js b/packages/turf-meta/index.js index 1135de09ef..49767634f8 100644 --- a/packages/turf-meta/index.js +++ b/packages/turf-meta/index.js @@ -435,8 +435,6 @@ function geomEach(geojson, callback) { var type = (geometry === null) ? null : geometry.type; switch (type) { case null: - currentIndex++; - break; case 'Point': case 'LineString': case 'MultiPoint': @@ -547,10 +545,10 @@ function geomReduce(geojson, callback, initialValue) { */ function flattenEach(geojson, callback) { geomEach(geojson, function (geometry, index, properties) { - if (geometry === null) return; - // Callback for single geometry - switch (geometry.type) { + var type = (geometry === null) ? null : geometry.type; + switch (type) { + case null: case 'Point': case 'LineString': case 'Polygon': @@ -561,7 +559,7 @@ function flattenEach(geojson, callback) { var geomType; // Callback for multi-geometry - switch (geometry.type) { + switch (type) { case 'MultiPoint': geomType = 'Point'; break; @@ -678,6 +676,8 @@ function flattenReduce(geojson, callback, initialValue) { function segmentEach(geojson, callback) { flattenEach(geojson, function (feature, currentIndex) { var currentSubIndex = 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; @@ -752,7 +752,6 @@ function segmentReduce(geojson, callback, initialValue) { return previousValue; } - /** * Create Feature * @turf/helpers diff --git a/packages/turf-meta/test.js b/packages/turf-meta/test.js index dbf0775325..01faccde17 100644 --- a/packages/turf-meta/test.js +++ b/packages/turf-meta/test.js @@ -428,14 +428,14 @@ test('null geometries', t => { // Each operations featureEach(fc, feature => t.equal(feature.geometry, null, 'featureEach')); - geomEach(fc, () => t.fail('no geometries should be found')); - flattenEach(fc, () => t.fail('no features should be found')); + geomEach(fc, geometry => t.equal(geometry, null), 'geomEach'); + flattenEach(fc, feature => t.equal(feature.geometry, null, 'flattenEach')); coordEach(fc, () => t.fail('no coordinates should be found')); // Reduce operations t.equal(featureReduce(fc, prev => prev += 1, 0), 2, 'featureReduce'); - t.equal(geomReduce(fc, prev => prev += 1, 0), 0, 'geomReduce'); - t.equal(flattenReduce(fc, prev => prev += 1, 0), 0, 'flattenReduce'); + t.equal(geomReduce(fc, prev => prev += 1, 0), 2, 'geomReduce'); + t.equal(flattenReduce(fc, prev => prev += 1, 0), 2, 'flattenReduce'); t.equal(coordReduce(fc, prev => prev += 1, 0), 0, 'coordReduce'); t.end(); }); @@ -445,11 +445,11 @@ test('null geometries -- index', t => { feature(null), // index 0 point([0, 0]), // index 1 feature(null), // index 2 - lineString([0, 0]) // index 3 + lineString([[1, 1], [0, 0]]) // index 3 ]); - t.deepEqual(meta.coordReduce(fc, (prev, coords, i) => prev.concat(i), []), [0, 1, 2], 'coordReduce'); - t.deepEqual(meta.geomReduce(fc, (prev, geom, i) => prev.concat(i), []), [1, 3], 'geomReduce'); - t.deepEqual(meta.flattenReduce(fc, (prev, feature, i) => prev.concat(i), []), [1, 3], 'flattenReduce'); + t.deepEqual(meta.coordReduce(fc, (prev, coords, coordIndex) => prev.concat(coordIndex), []), [0, 1, 2], 'coordReduce'); + t.deepEqual(meta.geomReduce(fc, (prev, geom, featureIndex) => prev.concat(featureIndex), []), [0, 1, 2, 3], 'geomReduce'); + t.deepEqual(meta.flattenReduce(fc, (prev, feature, featureIndex) => prev.concat(featureIndex), []), [0, 1, 2, 3], 'flattenReduce'); t.end(); }); From 8fbee2fa1f10b6866ad6949d92876e5f99427686 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 27 Jul 2017 10:58:59 -0400 Subject: [PATCH 10/13] Add tests for bbox-clip --- packages/turf-bbox-clip/test.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/turf-bbox-clip/test.js b/packages/turf-bbox-clip/test.js index fa66c6b89a..f7852cdfe6 100644 --- a/packages/turf-bbox-clip/test.js +++ b/packages/turf-bbox-clip/test.js @@ -1,11 +1,11 @@ -const test = require('tape'); const fs = require('fs'); +const test = require('tape'); const path = require('path'); const load = require('load-json-file'); const write = require('write-json-file'); +const {point, feature} = require('@turf/helpers'); const turfBBox = require('@turf/bbox'); -const featureCollection = require('@turf/helpers').featureCollection; -const point = require('@turf/helpers').point; +const {featureCollection} = require('@turf/helpers'); const bboxClip = require('./'); const directories = { @@ -34,8 +34,8 @@ test('turf-bbox-clip', t => { t.end(); }); -test('turf-bbox-clip errors', t => { - t.throws(() => bboxClip(point([5, 10]), [-180, -90, 180, 90])); +test('turf-bbox-clip -- throws', t => { + t.throws(() => bboxClip(point([5, 10]), [-180, -90, 180, 90]), /geometry Point not supported/); t.end(); }); @@ -48,3 +48,8 @@ function colorize(feature, color = '#F00', width = 6) { }; return feature; } + +test('turf-bbox-clip -- null geometries', t => { + t.throws(() => bboxClip(feature(null), [-180, -90, 180, 90]), /No valid coordinates/); + t.end(); +}); From e1714d9352f33505ccc9a2d66132d343b0b06b28 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 27 Jul 2017 11:01:10 -0400 Subject: [PATCH 11/13] Refactor tests to ES6 bbox-polygon --- packages/turf-bbox-polygon/test.js | 31 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/packages/turf-bbox-polygon/test.js b/packages/turf-bbox-polygon/test.js index 282fbf2396..90e9f77625 100644 --- a/packages/turf-bbox-polygon/test.js +++ b/packages/turf-bbox-polygon/test.js @@ -1,21 +1,22 @@ -var test = require('tape') -var bboxPolygon = require('./') +const test = require('tape'); +const bboxPolygon = require('./'); -test('bboxPolygon', function(t){ - t.plan(2); +test('bboxPolygon', t => { + t.plan(2); - var poly = bboxPolygon([0,0,10,10]); + const poly = bboxPolygon([0, 0, 10, 10]); - t.ok(poly.geometry.coordinates, 'should take a bbox and return the equivalent polygon feature'); - t.equal(poly.geometry.type, 'Polygon', 'should be a Polygon geometry type'); + t.ok(poly.geometry.coordinates, 'should take a bbox and return the equivalent polygon feature'); + t.equal(poly.geometry.type, 'Polygon', 'should be a Polygon geometry type'); }); -test('bboxPolygon valid geojson', function (t) { - var poly = bboxPolygon([0,0,10,10]), - coordinates = poly.geometry.coordinates; - t.ok(poly, 'should be valid geojson.'); - t.equal(coordinates[0].length, 5); - t.equal(coordinates[0][0][0], coordinates[0][coordinates.length - 1][0]); - t.equal(coordinates[0][0][1], coordinates[0][coordinates.length - 1][1]); - t.end(); +test('bboxPolygon valid geojson', t => { + const poly = bboxPolygon([0, 0, 10, 10]); + const coordinates = poly.geometry.coordinates; + + t.ok(poly, 'should be valid geojson.'); + t.equal(coordinates[0].length, 5); + t.equal(coordinates[0][0][0], coordinates[0][coordinates.length - 1][0]); + t.equal(coordinates[0][0][1], coordinates[0][coordinates.length - 1][1]); + t.end(); }); From b2a99a511a7b861b072720fb7d6eaf41ec695f34 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 27 Jul 2017 12:03:30 -0400 Subject: [PATCH 12/13] Extract null Geometry handling from @turf/meta --- packages/turf-meta/index.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/turf-meta/index.js b/packages/turf-meta/index.js index 49767634f8..e9c6ef5f99 100644 --- a/packages/turf-meta/index.js +++ b/packages/turf-meta/index.js @@ -27,12 +27,14 @@ * }); */ function coordEach(geojson, callback, excludeWrapCoord) { + // Handles null Geometry -- Skips this GeoJSON + if (geojson === null) return; var i, j, k, g, l, geometry, stopG, coords, geometryMaybeCollection, wrapShrink = 0, currentIndex = 0, isGeometryCollection, - type = (geojson) ? geojson.type : null, + type = geojson.type, isFeatureCollection = type === 'FeatureCollection', isFeature = type === 'Feature', stop = isFeatureCollection ? geojson.features.length : 1; @@ -59,8 +61,11 @@ function coordEach(geojson, callback, excludeWrapCoord) { for (g = 0; g < stopG; g++) { geometry = isGeometryCollection ? geometryMaybeCollection.geometries[g] : geometryMaybeCollection; - coords = (geometry === null) ? null : geometry.coordinates; - var geomType = (geometry === null) ? null : geometry.type; + + // 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; From c1edd39658d1f2dae611eb6106a4cb609aa9ab8d Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 27 Jul 2017 12:09:53 -0400 Subject: [PATCH 13/13] Add tests for GeometryCollection CC: @stebogit https://github.com/Turfjs/turf/pull/866#discussion_r129873661 --- packages/turf-helpers/test.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/turf-helpers/test.js b/packages/turf-helpers/test.js index c0db9bfe94..99bb81110d 100644 --- a/packages/turf-helpers/test.js +++ b/packages/turf-helpers/test.js @@ -387,8 +387,11 @@ test('convertArea', t => { }); // https://github.com/Turfjs/turf/issues/853 +// https://github.com/Turfjs/turf/pull/866#discussion_r129873661 test('null geometries', t => { - t.equal(feature(null).geometry, null); - t.equal(featureCollection([feature(null)]).features[0].geometry, null); + t.equal(feature(null).geometry, null, 'feature'); + t.equal(featureCollection([feature(null)]).features[0].geometry, null, 'featureCollection'); + t.equal(geometryCollection([feature(null).geometry]).geometry.geometries[0], null, 'geometryCollection'); + t.equal(geometryCollection([]).geometry.geometries.length, 0, 'geometryCollection -- empty'); t.end(); -}) \ No newline at end of file +});