使用Turf.js通过LineString分割多边形时仅生成单个多边形的问题求助
Turf.js通过LineString分割多边形时仅生成单个多边形的问题求助
我正在做一个项目,需要用LineString把一个多边形分割成两个独立的多边形,目前用Turf.js来处理相交、分割和多边形化这类几何操作。虽然我确认输入的几何数据看起来是正确的,但turf.polygonize函数始终只生成一个有效多边形,达不到我需要两个的要求。下面是我的具体场景、实现代码以及遇到的问题。
预期输出
用一条与多边形相交的LineString,将原多边形精确分割成两个有效的多边形。
我的实现代码
dividePolygon() { try { const featureGroup = new L.FeatureGroup(this.layers); this.map.addLayer(featureGroup); this.selectedPlots.forEach(plot => { featureGroup.addLayer(plot); }); const drawControl = new L.Control.Draw({ edit: { featureGroup: featureGroup, }, draw: { polyline: { shapeOptions: { color: 'red', weight: 4, }, }, }, }); this.map.addControl(drawControl); this.map.on(L.Draw.Event.CREATED, (e: any) => { const drawnLineLayer = e.layer as L.Polyline; featureGroup.eachLayer((layer: L.Layer) => { const plotGeoJSON = (layer as L.Polygon).toGeoJSON() as Feature<Polygon>; const drawnLineGeoJSON = drawnLineLayer.toGeoJSON() as Feature<LineString>; const intersectionPoints = turf.lineIntersect(drawnLineGeoJSON, plotGeoJSON); if (intersectionPoints.features.length > 0) { console.log("Original Polygon Coordinates:", plotGeoJSON.geometry.coordinates); console.log("Intersection Points: ", intersectionPoints); // Slice the line segment inside the polygon const slicedLine = turf.lineSlice( turf.point(intersectionPoints.features[0].geometry.coordinates), turf.point(intersectionPoints.features[1].geometry.coordinates), drawnLineGeoJSON ); console.log("Sliced Line Coordinates:", slicedLine); const splitPolygons = this.splitPolygonWithLine(plotGeoJSON, slicedLine); if (splitPolygons && splitPolygons.length === 2) { // Updated polygons on the map const newPlot1Layer = L.geoJSON(splitPolygons[0]).addTo(this.map); const newPlot2Layer = L.geoJSON(splitPolygons[1]).addTo(this.map); // Remove the original polygon from the map this.map.removeLayer(layer); } else { console.error('Error: The polygon was not split into exactly two polygons.'); } } }); }); } catch (error) { console.error('Error while dividing the polygon:', error); } } splitPolygonWithLine(polygon: Feature<Polygon>, line: Feature<LineString>): Feature<Polygon>[] | null { if (!turf.booleanIntersects(line, polygon)) { console.error("Error: Line does not intersect the polygon."); return null; } try { const flippedPolygon = turf.flip(polygon); const flippedLine = turf.flip(line); const polygonBoundary = turf.polygonToLine(flippedPolygon) as Feature<LineString>; // Split the polygon boundary using the slicing line const splitLines = turf.lineSplit(polygonBoundary, flippedLine); if (splitLines.features.length < 2) { console.error("Error: Unable to split the polygon boundary into two parts."); return null; } // Combine split lines with the slicing line to form the full boundary const combinedLines = turf.featureCollection([ ...splitLines.features, flippedLine, ]); const splitPolygons = turf.polygonize(combinedLines); // Ensure polygons are closed loops splitPolygons.features.forEach(poly => { const coords = poly.geometry.coordinates[0]; if (coords[0][0] !== coords[coords.length - 1][0] || coords[0][1] !== coords[coords.length - 1][1]) { coords.push(coords[0]); // Close the loop if necessary } }); const validPolygons = splitPolygons.features.filter(poly => { const area = turf.area(poly); return area > 0 && turf.booleanWithin(turf.centroid(poly), flippedPolygon); }); // Ensure we have exactly two valid polygons if (validPolygons.length === 2) { return validPolygons.map(poly => turf.flip(poly)); } else { console.error("Error: Did not generate exactly two valid polygons. Found:", validPolygons.length); return null; } } catch (error) { console.error("Error during polygon split:", error); return null; } }
核心问题
执行分割并调用turf.polygonize方法后,我只得到了一个多边形,而不是预期的两个。控制台输出的错误信息是:
Error: Did not generate exactly two valid polygons. Found: 1
即使相交点和分割后的线段看起来都是正确的,但最后合并线段并多边形化的步骤始终无法得到我想要的结果。
补充信息
下面是我测试时用到的几何数据:
flippedPolygon
{ "type": "Feature", "properties": {}, "geometry": { "type": "Polygon", "coordinates": [ [ [ 48.347445, 4.112343 ], [ 48.347496, 4.112406 ], [ 48.347836, 4.112835 ], [ 48.34798, 4.113035 ], [ 48.348278, 4.113461 ], [ 48.348149, 4.113679 ], [ 48.347672, 4.114473 ], [ 48.347133, 4.115373 ], [ 48.346583, 4.116293 ], [ 48.346129, 4.11705 ], [ 48.345695, 4.117775 ], [ 48.345222, 4.118562 ], [ 48.344637, 4.119537 ], [ 48.344299, 4.120098 ], [ 48.344169, 4.119938 ], [ 48.343821, 4.119506 ], [ 48.343497, 4.119104 ], [ 48.343437, 4.119035 ], [ 48.343434, 4.118924 ], [ 48.343633, 4.118593 ], [ 48.343799, 4.118312 ], [ 48.34406, 4.117874 ], [ 48.344221, 4.117605 ], [ 48.344413, 4.117285 ], [ 48.34454, 4.117072 ], [ 48.344822, 4.116602 ], [ 48.34496, 4.116371 ], [ 48.345241, 4.115902 ], [ 48.345391, 4.11565 ], [ 48.345711, 4.115113 ], [ 48.346046, 4.114551 ], [ 48.346387, 4.113982 ], [ 48.346797, 4.113296 ], [ 48.347209, 4.112606 ], [ 48.347363, 4.112344 ], [ 48.347445, 4.112343 ] ] ] } }
flippedLine
{ "type": "Feature", "properties": {}, "geometry": { "type": "LineString", "coordinates": [ [ 48.34542127624858, 4.115599208013975 ], [ 48.34619290725344, 4.116943456469385 ] ] } }
备注:内容来源于stack exchange,提问作者Suhaib Janjua
相关产品推荐
相关产品推荐

