I have need to split a polygon into multiple polygons based on the line strings drawn on the polygon. I have come across another post that splits a polygon into two based one line string. If a new line is drawn then the existing lines are ignored and the polygon is split into two based on the new line. What I want to achieve is 'split a polygon into multiple polygons based on multiple line.
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib = '© <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors';
var osm = L.tileLayer(osmUrl, { maxZoom: 18, attribution: osmAttrib });
var drawnItems = L.featureGroup();
var map = new L.Map('map', { center: new L.LatLng(51.505, -0.04), zoom: 13 });
osm.addTo(map);
drawnItems.addTo(map);
map.addControl(new L.Control.Draw({
draw: {
marker: false,
circle: false,
circlemarker: false,
rectangle: false,
polygon: {
allowIntersection: false,
showArea: true
}
}
}));
function cutPolygon(polygon, line, direction, id) {
var i = -1;
var j;
var polyCoords = [];
var retVal = null;
if ((polygon.type != 'Polygon') || (line.type != 'LineString')) return retVal;
if (line.coordinates.length != 2) return retVal;
var intersectPoints = turf.lineIntersect(polygon, line);
var nPoints = intersectPoints.features.length;
if ((nPoints == 0) || ((nPoints % 2) != 0)) return retVal;
var offsetLine = turf.lineOffset(line, (0.01 * direction), {units: 'kilometers'});
var thickLineCorners = turf.featureCollection([line, offsetLine]);
var thickLinePolygon = turf.convex(turf.explode(thickLineCorners));
var clipped = turf.difference(polygon, thickLinePolygon);
for (j = 0; j < clipped.geometry.coordinates.length; j++) {
var polyg = turf.polygon(clipped.geometry.coordinates[j]);
var overlap = turf.lineOverlap(polyg, line, {tolerance: 0.005});
if (overlap.features.length > 0) {
polyCoords[++i] = turf.coordAll(polyg);
};
};
if (i == 0)
retVal = turf.polygon(polyCoords, {id: id});
else if (i > 0) {
retVal = turf.multiPolygon([polyCoords], {id: id});
}
return retVal;
};
var polygons = [];
var layers = [];
map.on(L.Draw.Event.CREATED, function (event) {
var layer = event.layer;
drawnItems.addLayer(layer);
var geojson = layer.toGeoJSON();
var geom = turf.getGeom(geojson);
if (geom.type == 'Polygon')
polygons.push(geom);
else if (geom.type == 'LineString') {
var line = geom;
layers.forEach(function (layer, index) {
layer.remove();
});
layers = [];
polygons.forEach(function (polygon, index) {
var layer;
var upperCut = cutPolygon(polygon, line, 1, 'upper');
if (upperCut != null) {
layer = L.geoJSON(upperCut, {
style: function(feature) {
return {color: 'green' };
}
}).addTo(map);
layers.push(layer);
};
var lowerCut = cutPolygon(polygon, line, -1, 'lower');
if (lowerCut != null) {
layer = L.geoJSON(lowerCut, {
style: function(feature) {
return {color: 'yellow' };
}
}).addTo(map);
layers.push(layer);
};
});
};
});
I want the polygon split into 12 polygons. now it's just two(green & yellow).
I got this from this here
Best Answer
Update: See improved split method here: Splitting a polygon by multiple linestrings leaflet and turf.js
Code mentioned in the question was produced as kind of a proof of concept that polygons can be splitted with Turf.js library (see Client-Side Polygon split) It's not very robust and thoroughly tested.
Below is modified code which allows to split polygons multiple times with lines that have multiple points. Again it not robust and thoroughly tested, just a basic proof of concept.
At each step (split) the following layers and arrays are updated:
drawnPolygons
contains all polygons, split and unsplitdrawnLines
contains all lines used for splittingpolygons
contains all polygons that correspond todrawnPolygons
layerThe main part of the code:
Working JSFiddle is available at https://jsfiddle.net/TomazicM/x1a4d9ho/.