OpenLayers中线拆分

效果图

绘制线
拆分结果
使用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);
},
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值