openlayers基于turf实现多边形被线和面切割

 

基于openlayers实现多边形被线和面切割_openlayers 拆分图形_混子zy的博客-CSDN博客 代码优化了切割多面(MultiPolygon)

线切割面或多面:

function drawpolylineFn() {
  //业务需求 为了切割完带有原来的属性
  var _features = oldfeature;
  let drawSourceVector = new ol.VectorSource();
  let drawLineSplit = new ol.Draw({
    source: drawSourceVector,
    type: 'LineString',
    style: new ol.Style({
      image: new ol.Circle({
        radius: 5,
        fill: new ol.Fill({
          color: '#03a9f4',
        }),
      }),
      stroke: new ol.Stroke({
        color: '#03a9f4',
        width: 2,
      }),
      fill: new ol.Fill({
        color: 'rgba(255, 255, 255, 0.7)',
      }),
    }),
  });
  map.addInteraction(drawLineSplit);
  drawLineSplit.on('drawstart', () => {
    map.un(mapOnclick.type, mapOnclick.listener);
  });

  drawLineSplit.on('drawend', (evt) => {
    map.removeInteraction(drawLineSplit);
    let coorArr = evt.feature.getGeometry().getCoordinates();

    let polyDikuai;
    if(evt.feature.getGeometry().getType()=="MultiPolygon"){
        polyDikuai = turf.multiPolygon(coorArr);
    }else{
        polyDikuai = turf.polygon(coorArr);
    }
    polyDikuai.properties = oldfeature.values_.attributes;

    let polyline = turf.lineString(coorArr);
    let result = 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];
        // aaadata = {
        //   type: 'MultiPolygon',
        //   coordinates: [feature.geometry.coordinates],
        // };

        if (feature.geometry && feature.geometry.type && feature.geometry.type === 'Polygon') {
        } else {
          continue;
        }
        // let polygon1 = new ol.Polygon(feature.geometry.coordinates);
        let feature1 = new ol.Feature({
          geometry: new ol.Polygon(feature.geometry.coordinates || []),
          // attributes: _features.values_.attributes,
          attributes: feature,
        });
        feature1.setStyle(
          new ol.Style({
            //填充色
            fill: new ol.Fill({
              color: 'rgba(244, 3, 49, 0.5)',
              // color: 'rgba(255, 255, 255, 0.5)',
            }),
            //边线颜色
            stroke: new ol.Stroke({
              color: '#f40331',
              width: 2,
            }),
            //形状
            // image: new ol.Circle({
            //   radius: 7,
            //   fill: new ol.Fill({
            //     color: '#ffcc33',
            //   }),
            // }),
          }),
        );

        let Area = formatArea(feature.geometry.coordinates);

        // 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 (topvector) {
          topvector.getSource().addFeature(feature1);
        }
      }

      setTimeout(() => {
        topvector.getSource().removeFeature(_features);
      }, 100);
      setTimeout(() => {
        map.on(mapOnclick.type, mapOnclick.listener);
      }, 1000);
    }
  });
}
// 计算图形面积
function formatArea(c) {
  var polygon = turf.polygon(c);

  var area = turf.area(polygon);
  return area;
}

function polygonCut(poly, line, tolerance = 0.000001, toleranceType = 'kilometers') {
  if (line.geometry === void 0 || line.geometry.type.toLowerCase().indexOf('linestring') === -1) {
    // 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 "起点和终点必须在多边形之外";

      return;
    }
  }
  // 2. 计算交点,并把线的点合并
  //计算相交点
  let lineIntersect = turf.lineIntersect(line, poly);

  //获取一个或一组Feature,并将所有位置作为点返回。拆分为点
  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 (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 (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}`;
  });

  //获取一个或多个Feature并创建一个FeatureCollection。
  return turf.featureCollection(pieces);
}

面切割面或多面:

function drawpolygonFn() {
  var _features = oldfeature;
  let drawSourceVector = new ol.VectorSource();
  var drawFaceSplit = new ol.Draw({
    source: drawSourceVector,
    type: 'Polygon',
    style: new ol.Style({
      stroke: new ol.Stroke({
        color: '#03a9f4',
        width: 2,
      }),
      fill: new ol.Fill({
        color: 'rgba(255, 255, 255, 0.7)',
      }),
      image: new ol.Circle({
        radius: 3,
        fill: new ol.Fill({
          color: '#03a9f4',
        }),
      }),
    }),
  });
  map.addInteraction(drawFaceSplit);
  drawFaceSplit.on('drawstart', () => {
    map.un(mapOnclick.type, mapOnclick.listener);
  });
  drawFaceSplit.on('drawend', (evt) => {
    map.removeInteraction(drawFaceSplit);
    let splitResult = [];
    let pointslist = evt.feature.getGeometry().getCoordinates();

    let polyDikuai;
    if(evt.feature.getGeometry().getType()=="MultiPolygon"){
        polyDikuai = turf.multiPolygon(pointslist);
    }else{
        polyDikuai = turf.polygon(pointslist);
    }
    // polyDikuai.properties = oldfeature.values_.attributes;
    let polyDraw = turf.polygon(pointslist);
    //取两个多边形并找到它们的交点。如果它们共享一个边界,返回边界;如果它们不相交,返回undefined。
    let intersection = turf.intersect(polyDikuai, polyDraw);
    debugger;
    //通过从第一个多边形剪裁第二个多边形来查找两个多边形之间的差异。
    let difference1 = turf.difference(polyDikuai, polyDraw);

    // 判断面是否包含面
    let contains = turf.booleanContains(polyDikuai, polyDraw);
    let intersectionArray = intersection.geometry ? intersection.geometry.coordinates : [];
    let differenceArray = difference1.geometry ? difference1.geometry.coordinates : [];
    splitResult.push(intersectionArray);
    if (differenceArray && differenceArray.length > 1 && !contains) {
      for (let item of differenceArray) {
        splitResult.push(item);
      }
    } else {
      splitResult.push(differenceArray);
    }
    if (intersection && splitResult.length > 0) {
      for (let item in splitResult) {
        // let polygonResult = new Polygon(splitResult[item]);
        let featureResult = new ol.Feature({
          geometry: new ol.Polygon(splitResult[item] || []),
          attributes: _features.values_.attributes,
        });
        featureResult.setStyle(
          new ol.Style({
            //填充色
            fill: new ol.Fill({
              color: 'rgba(244, 3, 49, 0.5)',
              // color: 'rgba(255, 255, 255, 0.5)',
            }),
            //边线颜色
            stroke: new ol.Stroke({
              color: '#f40331',
              width: 2,
            }),
            //形状
            // image: new ol.Circle({
            //   radius: 7,
            //   fill: new ol.Fill({
            //     color: '#ffcc33',
            //   }),
            // }),
          }),
        );
        let Area = formatArea(splitResult[item]);

        featureResult.set('Area', Area);
        // featureResult.set('region_name', name);

        if (topvector) {
          topvector.getSource().addFeature(featureResult);
        }
      }

      try {
        setTimeout(() => {
          topvector.getSource().removeFeature(_features);
        }, 100);
        setTimeout(() => {
          map.on(mapOnclick.type, mapOnclick.listener);
        }, 1000);
      } catch (e) {}
    }
  });
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要获取多个多边形的边界,可以使用OpenLayers提供的几种方法。 首先,要确保已经加载了OpenLayers库,并创建了地图。然后,创建多边形要素,并将其添加到矢量图层中。 接下来,可以通过以下几种方法来获取多个多边形的边界: 1. 使用`getBounds()`方法:通过遍历所有多边形要素,可以使用`getBounds()`方法获取每个多边形的边界框。边界框是一个表示多边形边界的矩形区域,可以通过调用`getBounds()`方法获得。使用此方法,可以获取每个多边形的边界框,并进一步处理或显示。 2. 使用`getGeometry().getExtent()`方法:对于每个多边形要素,可以使用`getGeometry().getExtent()`方法获取多边形的边界框。这个方法会返回包含多边形边界的最小矩形范围。通过遍历每个多边形要素并调用此方法,可以获取每个多边形的边界框。 3. 使用`getGeometry().getCoordinates()`方法:可以使用`getGeometry().getCoordinates()`方法来获取多边形的坐标数组。多边形的边界由这些坐标组成。通过遍历每个多边形要素并调用此方法,可以获得每个多边形的坐标数组。然后,可以进一步处理或显示这些坐标。 以上方法可以根据具体需求选择使用。通过遍历多边形要素,并调用适当的方法,可以获取多个多边形的边界信息。根据实际应用,可以进一步处理或显示这些边界信息,实现所需的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值