使用Openlayers6画框,与已有的框去重

268 阅读1分钟

Openlayers官方链接:openlayers.org/en/latest/e…

  1. Openlayers6提供了绘制点、线、面、圆等功能,如下图所示:

image.png 实现上图画框的代码如下:

const modify = new Modify({source: source}); map.addInteraction(modify);

let draw, snap; const typeSelect = document.getElementById('type');

function addInteractions() {

draw = new Draw({ source: source, type: typeSelect.value, });

map.addInteraction(draw);

snap = new Snap({source: source});

map.addInteraction(snap);

}

typeSelect.onchange = function () {

map.removeInteraction(draw);

map.removeInteraction(snap);

addInteractions();

};

addInteractions();

  1. 在画框之前,已经有了一些框数据,再画框时,需要与已经有的框进行去重,实现方法有两种:
  • 使用Geoserver实现,Geoserver的filter参数可以发地理计算函数,如st_intersection

  • 使用Openlayers6和turf.js实现,先安装turf.js, npm i @turf/turf,代码开头引入import * as turf from '@turf/turf'

    第二种方法在这篇文章里给出了示例,文章链接是cloud.tencent.com/developer/a… 这篇文章里的代码放到本地一看,竟然不对,大概得原因是示例中openlayers版本交旧,使用最新的Openlayers6需要进行修改。 3.先看代码

const removeOverlappingAreasWithExistingFeatures = (feature: any) => { const format = new GeoJSON(); let count: number = 0;

checkVectorSourceRef.current?.getFeatures().forEach((existingFeature: any) => {
  const featureGeojson = JSON.parse(new GeoJSON().writeFeature(feature)); //feature转换成Geojson
  const existingFeatureGeojson = JSON.parse(new GeoJSON().writeFeature(existingFeature));

  if (
    existingFeatureGeojson.geometry &&
    existingFeatureGeojson.geometry.type &&
    existingFeatureGeojson.geometry.type !== 'Polygon'
  )
    return;

  var featurePoly = turf.feature(featureGeojson.geometry); //turf.feature(feature.getGeometry())
  var existingFeaturePoly = turf.feature(existingFeatureGeojson.geometry);

  const intersection = turf.intersect(featurePoly, existingFeaturePoly);
  if (intersection) {
    var difference = turf.difference(featurePoly, intersection);
    if (difference) {
      count++;
      if (
        difference.geometry &&
        difference.geometry.coordinates &&
        difference.geometry.coordinates.length
      ) {
        difference!.geometry.coordinates = difference!.geometry.coordinates.filter(
          (coordinate: any) => coordinate.length > 0,
        );

        feature.setGeometry(format.readFeature(difference).getGeometry());
      }
    }
  }
});

if (count > 0) {
  message.warning('与现有框有重叠,已去除重叠区域!');
}
return feature;

};

最关键是的是这两句:

const featureGeojson = JSON.parse(new GeoJSON().writeFeature(feature)); //feature转换成Geojson     
const existingFeatureGeojson = JSON.parse(new GeoJSON().writeFeature(existingFeature));

由于前端数据格式都是VectorSource中保存的feature,而turf.js是面向GeoJSON种数据格式的,所以需要先进行一下转换。wenku.baidu.com/view/274e83… 这篇文章给出了方法,函数将重复部分去除,修改完形状后返回。

参考资料: wenku.baidu.com/view/274e83…

turfjs.org/

cloud.tencent.com/developer/a…