如何在OpenLayers 5.3.0中裁剪和显示裁剪的矢量几何图形

时间:2019-08-12 13:31:48

标签: openlayers openlayers-5 turfjs

我必须基于主/限制矢量层裁剪矢量层。绘制时,如果绘制层的某些部分位于限制层外部,则裁剪区域位于限制层外部。

示例1。 如我们所见,底部边框的一部分在限制(紫色层)之外

enter image description here

我想知道是否可以在限制层外部的剪辑区域添加特征

示例2。删除限制层外部的区域(绿色)

enter image description here

我尝试使用(Turf.js)库中的bboxPolygon函数来计算几何。甚至尝试过用booleanWithin来检测绘制的多边形是否在限制层之外,但无济于事。

现在,我想知道是否有可能裁剪区域,然后addfeature渲染限制层内的裁剪区域(如示例2所示)

这是我用来以某种方式检测区域是否被裁剪或是否在限制层内的代码段。

// detect if drawn layers is outside restriction layer
vectorDrawLayer.getSource().on('addfeature', (evt) => {
  let feature = evt.feature;
  //let coordinatess = feature.getGeometry().clone().transform('EPSG:3857', 'EPSG:4326').getCoordinates();

  let geojsonFormat = new GeoJSON();

  let firstGeometryObject = {};
  let secondGeometryObject = {};

  if (vectorDrawLayer.getSource().getState() === 'ready') {
    let firstGeometry = vectorDrawLayer.getSource().getFeatures()[0];
    let secondGeometry = restrictionLayer.getSource().getFeatures()[0];

    firstGeometryObject = geojsonFormat.writeFeatureObject(firstGeometry, { dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857' });

    secondGeometryObject = geojsonFormat.writeFeatureObject(secondGeometry, { dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857' });
  }

  let isWithin = booleanWithin(firstGeometryObject, secondGeometryObject)
  let clipped = bBoxclip(firstGeometryObject, transformedExtent);

  //console.log(JSON.stringify(firstGeometryObject))
  console.log(clipped.geometry.coordinates);
  console.log(isWithin);
})

更新:

我只能使用http://turfjs.org/docs/#intersect提取位于限制层内的多边形,但是现在在渲染仅相交的层时遇到了问题。

最初,我想删除图层源,然后在获得相交的多边形坐标后,我想添加新的相交的多边形几何体(没有外部区域),但是我什么也无法渲染(似乎我缺少了某些东西)

这是代码段:

  let geojsonFormat = new GeoJSON();
  let firstGeometryObject = {};
  let secondGeometryObject = {};
  let feature;
  if (vectorDrawLayer.getSource().getState() === 'ready') {

    let firstGeometry = vectorDrawLayer.getSource().getFeatures()[0];
    let secondGeometry = restrictionLayer.getSource().getFeatures()[0];


    firstGeometryObject = geojsonFormat.writeFeatureObject(firstGeometry, { dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857' });

    secondGeometryObject = geojsonFormat.writeFeatureObject(secondGeometry, { dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857' });

    let intersectTest = intersect(firstGeometryObject, secondGeometryObject);

    let polygon = new Polygon(intersectTest.geometry.coordinates)

    feature = new Feature({
      geometry: polygon,
      name: 'test BlaBla'
    });
    console.log(feature)
    vectorDrawSource.removeFeature(firstGeometry);
    vectorDrawSource.addFeatures(feature);
  }

这里是测试应用程序的链接(更新): https://stackblitz.com/edit/js-vpdnbf

2 个答案:

答案 0 :(得分:1)

如果目标是在面内渲染要素,则可以在图层上使用裁剪滤镜。请参见以下示例https://viglino.github.io/ol-ext/examples/filter/map.filter.crop.html

答案 1 :(得分:0)

好,我知道了。使用intersect函数,通过将转换后的GeoJSON对象传递给函数来获得相交的要素对象。

示例:

let secondGeometryObject = secondGeometryObject = geojsonFormat.writeFeatureObject(secondGeometry, { dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857' });

然后使用相交的要素对象的坐标创建新的多边形。

let intersectPolygon = intersect(firstGeometryObject, secondGeometryObject);

let polygon = new Polygon(intersectPolygon.geometry.coordinates)

然后,我变换了多边形并获取了变换后的坐标('EPSG:4326')

let transformedPoly = polygon.clone().transform('EPSG:4326', 'EPSG:3857').getCoordinates();

最后将新获取的坐标设置为事件功能

evt.feature.getGeometry().setCoordinates(transformedPoly);

或者,我们可以使用类似这样的东西:

// transforming polygon to epsg:3857
let transformedPoly = polygon.clone().transform('EPSG:4326', 'EPSG:3857');
// set newly transformed polygon to feature
evt.feature.setGeometry(transformedPoly);

这是固定的解决方案:

enter image description here

如果有人对如何裁剪和获取坐标有更好的主意,可以随时发表答案,我肯定会赞成:) 希望它可以帮助某人:)

到应用程序的更新链接在这里: https://stackblitz.com/edit/js-vpdnbf