AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 77119486
Accepted
hansmei
hansmei
Asked: 2023-09-17 04:25:29 +0800 CST2023-09-17 04:25:29 +0800 CST 2023-09-17 04:25:29 +0800 CST

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

  • 772

我希望能够修改 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
  • 2 2 个回答
  • 19 Views

2 个回答

  • Voted
  1. hansmei
    2023-09-17T04:54:20+08:002023-09-17T04:54:20+08:00

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

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

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

    • 0
  2. Best Answer
    MoonE
    2023-09-17T05:08:27+08:002023-09-17T05:08:27+08:00

    两个多边形之间只有一个坐标完全匹配,另一个坐标的最后一位数字不同。

    修改交互将更新同一位置处每个几何体的一个坐标。(旧版本的 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.628916129
                ],
                [
                  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.628916129
                ]
              ]
            ]
          }
        }
      ]
    }
    
    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>

    • 0

相关问题

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    使用 <font color="#xxx"> 突出显示 html 中的代码

    • 2 个回答
  • Marko Smith

    为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类?

    • 1 个回答
  • Marko Smith

    您可以使用花括号初始化列表作为(默认)模板参数吗?

    • 2 个回答
  • Marko Smith

    为什么列表推导式在内部创建一个函数?

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 个回答
  • Marko Smith

    为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)?

    • 4 个回答
  • Marko Smith

    为什么库中不调用全局变量的构造函数?

    • 1 个回答
  • Marko Smith

    std::common_reference_with 在元组上的行为不一致。哪个是对的?

    • 1 个回答
  • Marko Smith

    C++17 中 std::byte 只能按位运算?

    • 1 个回答
  • Martin Hope
    fbrereto 为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 您可以使用花括号初始化列表作为(默认)模板参数吗? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi 为什么列表推导式在内部创建一个函数? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A fmt 格式 %H:%M:%S 不带小数 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python C++20 的 std::views::filter 未正确过滤视图 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute 为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa 为什么库中不调用全局变量的构造函数? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis std::common_reference_with 在元组上的行为不一致。哪个是对的? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev 为什么编译器在这里错过矢量化? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan C++17 中 std::byte 只能按位运算? 2023-08-17 17:13:58 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve