【问题标题】:Example of limiting a vertex from being dragged outside a polygon in OpenLayers6在 OpenLayers 6 中限制顶点被拖出多边形的示例
【发布时间】:2021-10-07 09:58:03
【问题描述】:

我有以下情况:

基础多边形是我定义应该绘制所有其他多边形的地方。

使用绘图交互时,设置条件选项足以限制点在地图上的放置位置(在我的例子中,是基础多边形)。

问题出在我修改它们的时候。我可以将一个顶点拖到基础多边形之外,我想禁用该行为,但我找不到任何解决方案。

如果我在修改交互上使用绘图交互中的相同条件选项,它只会在放置顶点后禁用拖动。

所以我的问题归结为禁用指定多边形外部的任何多边形的拖动。

编辑 1: 最后我得到了这个:

    const constrainGeometry = (feature: RenderFeature | Feature<Geometry>) => {
      const geometry = feature.getGeometry() as Polygon | undefined;
      if (feature instanceof RenderFeature || geometry === undefined) {
        return geometry;
      }
      const coordinates = geometry.getCoordinates()[0].map((coordinate) => {
        const boundingGeometry = props.boundingFeature.getGeometry();
        if (boundingGeometry) {
          if (boundingGeometry.intersectsCoordinate(coordinate)) {
            return coordinate;
          } else {
            return boundingGeometry.getClosestPoint(coordinate);
          }
        } else {
          return coordinate;
        }
      });
      return new Polygon([coordinates]);
    };

尚未找到使用 TS 的良好解决方案,但目前看来还可以。

【问题讨论】:

    标签: javascript openlayers polygon drag


    【解决方案1】:

    拖动时没有适用的条件。您可以使用受约束的几何来设置特征的样式,并在修改结束时设置该几何。

    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.8.1/css/ol.css" type="text/css">
        <style>
          html, body, .map {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
          }
        </style>
        <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.8.1/build/ol.js"></script>
      </head>
      <body>
        <div id="map" class="map"></div>
        <script type="text/javascript">
    
          const boundingPolygon = ol.geom.Polygon.fromCircle(
            new ol.geom.Circle([0, 0], 1e6),
            5
          );
    
          const constrainGeometry = function(feature) {
            const geometry = feature.getGeometry();
            if (geometry.getType() === 'Polygon') {
              coordinates = geometry.getCoordinates()[0].map(function(coordinate) {
                if (boundingPolygon.intersectsCoordinate(coordinate)) {
                  return coordinate;
                } else {
                  return boundingPolygon.getClosestPoint(coordinate);
                }
              });
              return new ol.geom.Polygon([coordinates]);
            } else {
              return geometry;
            }
          }
    
          const style = new ol.style.Style({
            geometry: constrainGeometry,
            fill: new ol.style.Fill({
              color: 'rgba(255, 255, 255, 0.2)',
            }),
            stroke: new ol.style.Stroke({
              color: '#ffcc33',
              width: 2,
            }),
            image: new ol.style.Circle({
              radius: 7,
              fill: new ol.style.Fill({
                color: '#ffcc33',
              }),
            }),
          });
    
          const vector1 = new ol.layer.Vector({
            source: new ol.source.Vector({
              features: [
                new ol.Feature(boundingPolygon)
              ]
            })
          });
    
          const vector2 = new ol.layer.Vector({
            source: new ol.source.Vector({
              features: [
                new ol.Feature(ol.geom.Polygon.fromExtent([-5e5, -5e5, 5e5, 5e5]))
              ]
            }),
            style: style
          });
    
          const map = new ol.Map({
            target: 'map',
            layers: [
              new ol.layer.Tile({
                source: new ol.source.OSM()
              }),
              vector1,
              vector2
            ],
            view: new ol.View({
              center: [0, 0],
              zoom: 4
            })
          });
    
          const modify = new ol.interaction.Modify({
            source: vector2.getSource()
          });
    
          modify.on('modifyend', function (event) {
            event.features.forEach(function (feature) {
              feature.setGeometry(constrainGeometry(feature));
            });
          });
    
          map.addInteraction(modify);
    
        </script>
      </body>
    </html>

    【讨论】:

    • 感谢您花时间研究它。这种技术可以用于n个顶点的基础多边形吗?这确实是我想要的,但我的多边形可以有超过 4 个点。我还是 OpenLayers 的新手,还在搞清楚这些东西是如何工作的。
    • 我已经能够像这样解决它,但我不知道这是最好的方法:`` js props.map.on('pointermove', (e: MapBrowserEvent) => { if (!condition(e)) { e.stopPropagation(); } }); ```
    • 不规则的边界多边形可以通过用getClosestPoint替换一定程度的钳位来处理。我已经更新了答案。
    • 用你的想法来满足我的需要,它按预期工作。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多