turf-buffer icon indicating copy to clipboard operation
turf-buffer copied to clipboard

Buffered result loses a polygon from a MultiPolygon

Open liebrand opened this issue 9 years ago • 2 comments

The following code shows a bug, where the original feature collection contains a multipolygon with two shapes, but the resulting buffered output only has one of those polygons

var pt = {
  "type": "FeatureCollection",
  "features": [{
    "type": "Feature",
    "properties": {},
    "geometry": {
      "type": "MultiPolygon",
      "coordinates": [
        [
          [
            [-122.28068729011625, 37.533846],
            [-122.321643, 37.533846],
            [-122.34964211167777, 37.533846],
            [-122.3221531, 37.5477641],
            [-122.3004556, 37.55875],
            [-122.28068729011625, 37.533846]
          ]
        ],
        [
          [
            [-122.39372234835123, 37.533846],
            [-122.519032, 37.533846],
            [-122.519464, 37.534918],
            [-122.519755, 37.545632],
            [-122.39372234835123, 37.533846]
          ]
        ]
      ]
    }
  }]
};

var unit = 'meters';
var buffered = turf.buffer(pt, 20, unit);

//=result

liebrand avatar Dec 20 '15 21:12 liebrand

Note, this is a very ugly hack/fix to this problem. Looks like the underlying jsts is not doing the right thing, so instead I just buffer each polygon inside the MultiPolygon separately. Obviously not the ultimate solution, but it unblocks me for now until a proper fix is made:

var bufferOp = function(feature, radius) {
  var reader = new jsts.io.GeoJSONReader();
  var parser = new jsts.io.GeoJSONParser();
  var geom, buffered, polyCoord, polyGeom;

  var mulitCoords = [];
  if (feature.geometry.type === 'MultiPolygon') {
    // Work around a bug where jsts drops entire polygons from multipolygons
    for (var i = 0; i < feature.geometry.coordinates.length; i++) {
      polyCoord = feature.geometry.coordinates[i];
      polyGeom = {
        type: 'Polygon',
        coordinates: polyCoord
      };
      geom = reader.read(JSON.stringify(polyGeom));
      buffered = geom.buffer(radius);
      buffered = parser.write(buffered);
      mulitCoords.push(buffered.coordinates);
    }
    buffered.type = 'MultiPolygon';
    buffered.coordinates = mulitCoords;
  } else {
    geom = reader.read(JSON.stringify(feature.geometry));
    buffered = geom.buffer(radius);
    buffered = parser.write(buffered);
  }

  return {
    type: 'Feature',
    geometry: buffered,
    properties: feature.properties
  };
};

liebrand avatar Dec 20 '15 22:12 liebrand

(note: my hack can produce geojson which is subsequently not able to be merged with turf-merge (causes an exception to be thrown by jsts. I'm not raising that as a bug, since I suspect my hack isn't quite right... )

liebrand avatar Dec 20 '15 23:12 liebrand