当两个子多边形共享边或顶点时使用 Openlayers 修改多多边形

问题描述 投票:0回答:1

我希望能够在 Openlayers 中修改由多个子多边形组成的多多边形。我已经激活了标准的修改交互,并且在拖动线上时拖动两个顶点并创建新的线段效果很好。不过在编辑操作的时候好像不一致。

行为非常不合常理。对于某些顶点,它将拖动所有连接的顶点(所需的行为),如下所示:

对于其他位置,它只会拖动一些顶点,而不是所有顶点:

拖动以添加新段时,它不会(总是,但有时)修改两个子实体:

这是重现意外行为的代码:

var multiPolygon = {
  "type": "FeatureCollection",
  "features": [{
      "type": "Feature",
      "properties": {
        "id": "1.1"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              1193836.0495014254,
              8383930.129123866
            ],
            [
              1193847.7380479588,
              8383914.044627354
            ],
            [
              1193861.7086440534,
              8383894.250081073
            ],
            [
              1193873.9649199897,
              8383877.232589948
            ],
            [
              1193883.717211206,
              8383863.628916129
            ],
            [
              1193894.5047360454,
              8383944.666907605
            ],
            [
              1193881.5012495161,
              8383963.164657038
            ],
            [
              1193860.4841296545,
              8383947.813224077
            ],
            [
              1193843.674886545,
              8383935.594306091
            ],
            [
              1193836.0495014254,
              8383930.129123866
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "id": "2.1"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              1193883.717211206,
              8383863.628916128
            ],
            [
              1193889.0153151448,
              8383856.238480768
            ],
            [
              1193890.5403921688,
              8383857.260414857
            ],
            [
              1193909.1752749276,
              8383870.745514915
            ],
            [
              1193929.301838863,
              8383884.8526888145
            ],
            [
              1193934.6451744211,
              8383888.740497403
            ],
            [
              1193929.168255474,
              8383896.316176012
            ],
            [
              1193903.787411573,
              8383931.462094758
            ],
            [
              1193894.5047360454,
              8383944.666907605
            ],
            [
              1193883.717211206,
              8383863.628916128
            ]
          ]
        ]
      }
    }
  ]
}

const styleFunction = () => {
  const style = [
    new ol.style.Style({
      stroke: new ol.style.Stroke({
        color: 'rgba(0,0,255,0.4)',
        width: 2,
      }),
      fill: new ol.style.Fill({
        color: `rgba(0,0,255,0.2)`,
      }),
    }),
    new ol.style.Style({
      image: new ol.style.Circle({
        radius: 3,
        fill: new ol.style.Fill({
          color: 'rgba(0,0,255,0.4)',
        }),
      }),
      geometry: function(feature) {
        // return the coordinates of the first ring of the polygon
        const type = feature.getGeometry().getType();
        let coordinates;
        if (type === 'Polygon') {
          coordinates = feature.getGeometry().getCoordinates()[0];
        } else if (type === 'MultiPolygon') {
          const coordArray = feature.getGeometry().getCoordinates();
          coordinates = [];
          coordArray.forEach((ring) => {
            coordinates.push(...ring[0]);
          });
        }
        return new ol.geom.MultiPoint(coordinates);
      },
    }),
  ];
  return style;
};

var multiPolygonFeatures = new ol.format.GeoJSON().readFeatures(multiPolygon);
var vectorSource = new ol.source.Vector({
  features: multiPolygonFeatures,
});

var viewCenter = [1193887, 8383870];
var view = new ol.View({
  projection: 'EPSG:3857',
  center: viewCenter,
  zoom: 18,
});

var map = new ol.Map({
  layers: [
    new ol.layer.Tile({
      source: new ol.source.OSM()
    }),
    new ol.layer.Vector({
      source: vectorSource,
      style: styleFunction
    })
  ],
  target: 'map',
  view: view,
});


const modify = new ol.interaction.Modify({
  source: vectorSource
});
map.addInteraction(modify);
html,
body,
.map {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}

.ol-dragbox {
  background-color: rgba(255, 255, 255, 0.4);
  border-color: rgba(100, 150, 0, 1);
}
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>
<div id="map" class="map"></div>

openlayers openlayers-8
1个回答
0
投票

在详细检查原始数据(多边形数据)后,我了解到修改交互需要多边形顶点共享完全相同的坐标(甚至小数点后第十位)才能触发共享编辑。我相信捕捉会检测到如此微小的差异。我的这个假设显然是错误的。

在我上面的代码中,那些不支持共享编辑的顶点的最后一位数字不同。

通过更改源(GeoJSON)的生成方式,并向其添加一些舍入,它可以按预期工作。

© www.soinside.com 2019 - 2024. All rights reserved.