import { Feature, LineString, Polygon, MultiPolygon, MultiLineString, featureReduce, lineIntersect, getCoords, booleanWithin, point, polygon, featureCollection, combine, polygonToLine, polygonize, booleanPointInPolygon, pointOnFeature, } from "@turf/turf"; import * as jsts from "jsts/dist/jsts.es6.js"; function isValidSplitLine(polygon: Feature, line: Feature) { const intersections = lineIntersect(polygon, line); const lineCoords = getCoords(line); // 两者不交叉 if (intersections.features.length === 0) { return false; } // 截断线的起点或终点在封闭多边形的内部 if ( booleanWithin(point(lineCoords[0]), polygon) || booleanWithin(point(lineCoords[lineCoords.length - 1]), polygon) ) { return false; } return true; } export function splitMultiPolygonByLine(feature: Feature, line: Feature) { const segmentPolygons: Feature[] = []; let hasIntersection = false; feature.geometry.coordinates.forEach((coordinate) => { const _polygon = polygon(coordinate); const subtraction = splitPolygonByLine(_polygon, line); // 被打断 if (Array.isArray(subtraction)) { hasIntersection = true; segmentPolygons.push(...subtraction); } else { segmentPolygons.push(subtraction); } }); const result = combine(featureCollection(segmentPolygons)).features[0] as Feature; result.properties = feature.properties; console.log(result); return hasIntersection ? result : null; } export function splitPolygonByLine( polygon: Feature, line: Feature ): Feature | Feature[] { const parser = new jsts.io.GeoJSONReader(); const writer = new jsts.io.GeoJSONWriter(); if (!isValidSplitLine(polygon, line)) { return polygon; } const polyLine = polygonToLine(polygon) as Feature; const geom = parser.read(polyLine.geometry); const lineGeo = parser.read(line.geometry); const multiLine: Feature = { type: "Feature", geometry: writer.write(geom.union(lineGeo)) as MultiLineString, properties: {}, }; const polygonized = polygonize(multiLine).features.filter((ea) => { return booleanPointInPolygon(pointOnFeature(ea), polygon); }); polygonized.forEach((feat) => (feat.properties = polygon.properties)); return polygonized; }