Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle empty geometries as undefined @turf/buffer #746

Merged
merged 2 commits into from
May 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/turf-buffer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Calculates a buffer for input features for a given radius. Units supported are m

**Parameters**

- `feature` **([FeatureCollection](http://geojson.org/geojson-spec.html#feature-collection-objects) \| [Feature](http://geojson.org/geojson-spec.html#feature-objects)<any>)** input to be buffered
- `radius` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** distance to draw the buffer
- `feature` **([FeatureCollection](http://geojson.org/geojson-spec.html#feature-collection-objects) \| [Geometry](http://geojson.org/geojson-spec.html#geometry) \| [Feature](http://geojson.org/geojson-spec.html#feature-objects)<any>)** input to be buffered
- `radius` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** distance to draw the buffer (negative values are allowed)
- `units` **\[[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** any of the options supported by turf units (optional, default `kilometers`)
- `steps` **\[[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)]** number of steps (optional, default `64`)

Expand All @@ -28,7 +28,7 @@ var buffered = turf.buffer(point, 500, 'miles');
var addToMap = [point, buffered]
```

Returns **([FeatureCollection](http://geojson.org/geojson-spec.html#feature-collection-objects) \| [Feature](http://geojson.org/geojson-spec.html#feature-objects)<([Polygon](http://geojson.org/geojson-spec.html#polygon) \| [MultiPolygon](http://geojson.org/geojson-spec.html#multipolygon))>)** buffered features
Returns **([FeatureCollection](http://geojson.org/geojson-spec.html#feature-collection-objects) \| [Feature](http://geojson.org/geojson-spec.html#feature-objects)<([Polygon](http://geojson.org/geojson-spec.html#polygon) \| [MultiPolygon](http://geojson.org/geojson-spec.html#multipolygon))> | [undefined](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined))** buffered features

<!-- This file is automatically generated. Please don't edit it directly:
if you find an error, edit the source file (likely index.js), and re-run
Expand Down
6 changes: 3 additions & 3 deletions packages/turf-buffer/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ interface Buffer {
/**
* http://turfjs.org/docs/#buffer
*/
<Geom extends Point|LineString|Polygon>(feature: Feature<Geom>|Geom, radius?: number, unit?: Units, steps?: number): Feature<Polygon>;
<Geom extends MultiPoint|MultiLineString|MultiPolygon>(feature: Feature<Geom>|Geom, radius?: number, unit?: Units, steps?: number): Feature<MultiPolygon>;
<Geom extends Point|LineString|Polygon>(feature: Feature<Geom>|Geom, radius?: number, unit?: Units, steps?: number): Feature<Polygon> | undefined;
<Geom extends MultiPoint|MultiLineString|MultiPolygon>(feature: Feature<Geom>|Geom, radius?: number, unit?: Units, steps?: number): Feature<MultiPolygon> | undefined;
<Geom extends Point|LineString|Polygon>(feature: FeatureCollection<Geom>, radius?: number, unit?: Units, steps?: number): FeatureCollection<Polygon>;
<Geom extends MultiPoint|MultiLineString|MultiPolygon>(feature: FeatureCollection<Geom>, radius?: number, unit?: Units, steps?: number): FeatureCollection<MultiPolygon>;
(feature: FeatureCollection<any>|FeatureGeometryCollection|GeometryCollection, radius?: number, unit?: Units, steps?: number): FeatureCollection<Polygon|MultiPolygon>;
(feature: Feature<any>|GeometryObject, radius?: number, unit?: Units, steps?: number): Feature<Polygon|MultiPolygon>;
(feature: Feature<any>|GeometryObject, radius?: number, unit?: Units, steps?: number): Feature<Polygon|MultiPolygon> | undefined;
}
declare const buffer: Buffer;
declare namespace buffer {}
Expand Down
35 changes: 27 additions & 8 deletions packages/turf-buffer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ var distanceToRadians = helpers.distanceToRadians;
* Calculates a buffer for input features for a given radius. Units supported are miles, kilometers, and degrees.
*
* @name buffer
* @param {FeatureCollection|Feature<any>} feature input to be buffered
* @param {number} radius distance to draw the buffer
* @param {FeatureCollection|Geometry|Feature<any>} feature input to be buffered
* @param {number} radius distance to draw the buffer (negative values are allowed)
* @param {string} [units=kilometers] any of the options supported by turf units
* @param {number} [steps=64] number of steps
* @return {FeatureCollection|Feature<Polygon|MultiPolygon>} buffered features
* @return {FeatureCollection|Feature<Polygon|MultiPolygon>|undefined} buffered features
* @example
* var point = {
* "type": "Feature",
Expand Down Expand Up @@ -53,14 +53,18 @@ module.exports = function (geojson, radius, units, steps) {
switch (geojson.type) {
case 'GeometryCollection':
geomEach(geojson, function (geometry) {
results.push(buffer(geometry, radius, units, steps));
var buffered = buffer(geometry, radius, units, steps);
if (buffered) results.push(buffered);
});
return featureCollection(results);
case 'FeatureCollection':
featureEach(geojson, function (feature) {
featureEach(buffer(feature, radius, units, steps), function (buffered) {
results.push(buffered);
});
var multiBuffered = buffer(feature, radius, units, steps);
if (multiBuffered) {
featureEach(multiBuffered, function (buffered) {
if (buffered) results.push(buffered);
});
}
});
return featureCollection(results);
}
Expand Down Expand Up @@ -88,7 +92,8 @@ function buffer(geojson, radius, units, steps) {
case 'GeometryCollection':
var results = [];
geomEach(geojson, function (geometry) {
results.push(buffer(geometry, radius, units, steps));
var buffered = buffer(geometry, radius, units, steps);
if (buffered) results.push(buffered);
});
return featureCollection(results);
}
Expand All @@ -108,11 +113,25 @@ function buffer(geojson, radius, units, steps) {
var writer = new jsts.io.GeoJSONWriter();
buffered = writer.write(buffered);

// Detect if empty geometries
if (coordsIsNaN(buffered.coordinates)) return undefined;

// Unproject coordinates (convert to Degrees)
buffered.coordinates = unprojectCoords(buffered.coordinates, projection);
return feature(buffered, properties);
}

/**
* Coordinates isNaN
*
* @private
* @param {Array<any>} coords GeoJSON Coordinates
* @returns {Boolean} if NaN exists
*/
function coordsIsNaN(coords) {
if (Array.isArray(coords[0])) return coordsIsNaN(coords[0]);
return isNaN(coords[0]);
}

/**
* Project coordinates to projection
Expand Down
10 changes: 10 additions & 0 deletions packages/turf-buffer/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ test('turf-buffer - Prevent Input Mutation', t => {
t.end();
});

// /~https://github.com/Turfjs/turf/issues/745
// /~https://github.com/Turfjs/turf/pull/736#issuecomment-301937747
test('turf-buffer - morphological closing', t => {
const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]);

t.equal(buffer(poly, -500, 'miles'), undefined, 'empty geometry should be undefined');
t.deepEqual(buffer(featureCollection([poly]), -500, 'miles'), featureCollection([]), 'empty geometries should be an empty FeatureCollection');
t.end();
});

function colorize(feature, color = '#F00') {
if (feature.properties) {
feature.properties.stroke = color;
Expand Down