效果图
使用turf进行处理
方法参数说明:layer 图层对象,选中的图元feature,layerID 图层ID
polylineFn(layer, features, layerID) {
let self = this;
let drawSourceVector = new VectorSource();
self.drawLineSplit = new Draw({
source: drawSourceVector,
type: "LineString",
style: new Style({
image: new sCircle({
radius: 5,
fill: new Fill({
color: "#03a9f4",
}),
}),
stroke: new Stroke({
color: "#03a9f4",
width: 2,
}),
fill: new Fill({
color: "rgba(255, 255, 255, 0.7)",
}),
}),
});
window.map.addInteraction(self.drawLineSplit);
// 监听绘制结束事件
self.drawLineSplit.on("drawend", (evt) => {
window.map.removeInteraction(self.drawLineSplit);
let featureGeoJson = JSON.parse(
new GeoJSON().writeFeature(evtFeature)
);
//第一个多边形数据(模拟选中地块边界数据)
let coorArr = [];
for (let i = 0; i < featureGeoJson.geometry.coordinates.length; i++) {
let coor = featureGeoJson.geometry.coordinates[i];
coorArr.push(coor);
}
let polyDikuai = turf.polygon(this.coordinates);
let polyline = turf.lineString(coorArr);
let result = self.polygonCut(polyDikuai, polyline);
//绘出结果 绘制出多个个多边形
if (result && result.features && result.features.length > 0) {
for (let f = 0; f < result.features.length; f++) {
let feature = result.features[f];
if (
feature.geometry &&
feature.geometry.type &&
feature.geometry.type === "Polygon"
) {
} else {
continue;
}
let polygon1 = new Polygon(feature.geometry.coordinates);
let feature1 = new Feature(polygon1);
let Area = getPolygonArea(feature1);
let length = getPolygonLength(feature1);
let name =
features.get("region_name") === undefined
? ("采集地块-" + Area)
: features.get("region_name");
feature1.set("Area", Area);
feature1.set("Length", length);
feature1.set("region_name", name);
if (layer) {
// console.log("featureResult:", feature1);
layer.getSource().addFeature(feature1);
}
}
setTimeout(() => {
layer.getSource().removeFeature(features);
}, 100);
}
});
},
// 线拆分逻辑处理
polygonCut(poly, line, tolerance = 0.000001, toleranceType = "kilometers") {
// 1. 条件判断
if (poly.geometry === void 0 || poly.geometry.type !== "Polygon") {
console.warn("传入的必须为polygon");
// throw "传入的必须为polygon";
return
}
if (
line.geometry === void 0 ||
line.geometry.type.toLowerCase().indexOf("linestring") === -1
) {
console.warn("传入的必须为linestring");
// throw "传入的必须为linestring";
return
}
if (line.geometry.type === "LineString") {
if (
turf.booleanPointInPolygon(turf.point(line.geometry.coordinates[0]), poly) ||
turf.booleanPointInPolygon(turf.point(line.geometry.coordinates[line.geometry.coordinates.length - 1]), poly)
) {
// throw "起点和终点必须在多边形之外";
this.$toast("起点和终点必须在多边形之外");
return
}
}
// 2. 计算交点,并把线的点合并
let lineIntersect = turf.lineIntersect(line, poly);
const lineExp = turf.explode(line);
for (let i = 0; i < lineExp.features.length - 1; i++) {
lineIntersect.features.push(
turf.point(lineExp.features[i].geometry.coordinates)
);
}
// 3. 计算线的缓冲区
const lineBuffer = turf.buffer(line, tolerance, {
units: toleranceType,
});
// 4. 计算线缓冲和多边形的difference,返回"MultiPolygon",所以将其拆开
const _body = turf.difference(poly, lineBuffer);
let pieces = [];
if (_body.geometry.type === "Polygon") {
pieces.push(turf.polygon(_body.geometry.coordinates));
} else {
_body.geometry.coordinates.forEach(function (a) {
pieces.push(turf.polygon(a));
});
}
// 5. 处理点数据
// for (p in pieces) {
for (let p = 0; p < pieces.length; p++) {
const piece = pieces[p];
for (let c in piece.geometry.coordinates[0]) {
const coord = piece.geometry.coordinates[0][c];
const p = turf.point(coord);
for (let lp in lineIntersect.features) {
const lpoint = lineIntersect.features[lp];
if (turf.distance(lpoint, p, toleranceType) <= tolerance * 2) {
piece.geometry.coordinates[0][c] = lpoint.geometry.coordinates;
}
}
}
}
// 6. 过滤掉重复点
// // for (p in pieces) {
// for (let p=0;p<pieces.length; p++) {
// const coords = pieces[p].geometry.coordinates[0];
// pieces[p].geometry.coordinates[0] = filterDuplicatePoints(coords);
// }
// 7. 将属性赋予每一个polygon,并处理id
pieces.forEach((a, index) => {
a.properties = Object.assign({}, poly.properties);
a.properties.id += `-${index}`;
});
return turf.featureCollection(pieces);
},