There might be simpler way of solving this problem by using some library, but one possible way with only Turf.js would be to:
- create array of outer liner rings and array of inner linear rings of polygon (with later reverse coordinate order);
- create multi polygon from outer linear rings and mask it;
- get linear rings of created masked polygon and append saved inner liner rings;
- create multi polygon from this array of rings.
Code could then look something like this:
var coords = turf.getCoords(polygon);
var outerRings = [];
var innerRings = [];
coords.forEach(function(polyCoords) {
polyCoords.forEach(function(linearRing, i) {
if (i == 0)
outerRings.push(linearRing);
else {
var poly = turf.rewind(turf.polygon([linearRing]));
innerRings.push(turf.getCoords(poly)[0]);
}
})
});
var outerRingsPoly = turf.multiPolygon([outerRings]);
var maskedOuterRingsPoly = turf.mask(outerRingsPoly);
var maskedOuterRings = turf.getCoords(maskedOuterRingsPoly);
var allRings = maskedOuterRings.concat(innerRings);
var finalPoly = turf.multiPolygon([allRings]);
Result then looks like this:
EDIT: When testing again with GeoJSON with several holes, turf.js complained executing var coords = turf.getCoords(polygon)
, so I had to change logic a bit.
Here is modified code:
var outerRings = [];
var innerRings = [];
turf.geomEach(polygon, function(geom) {
geom.coordinates[0].forEach(function(linearRing, i) {
if (i == 0)
outerRings.push(linearRing);
else {
var poly = turf.rewind(turf.polygon([linearRing]));
innerRings.push(turf.getCoords(poly)[0]);
}
});
});
var outerRingsPoly = turf.multiPolygon([outerRings]);
var maskedOuterRingsPoly = turf.mask(outerRingsPoly);
var maskedOuterRings = turf.getCoords(maskedOuterRingsPoly);
var allRings = maskedOuterRings.concat(innerRings);
var finalPoly = turf.multiPolygon([allRings]);
And here the result:
mask
method states that it "returns a polygon exterior ring with holes". What you want to have is "antihole" in a hole, whichmask
is not capable of. Such a polygon would be multipolygon, see stackoverflow.com/questions/74660981/….