【问题标题】:Events on Google maps inner polygon谷歌地图内多边形上的事件
【发布时间】:2021-06-30 19:02:13
【问题描述】:

我正在尝试创建一个实用程序,用户可以在其中创建 polgon 的内孔。这段代码工作正常。但是我无法在拉伸或移动内环的顶点时捕获事件。

如何制作: 使用处理程序创建多边形。 在多边形内绘制另一个 polgon。 你会看到它是一个洞。

进一步选择多边形并拉伸点。您将在拉伸外部多边形时收到警报。我希望内部多边形具有相同的行为(也就是说内部多边形上的触发事件)。我在这里做错了什么。请帮忙。

下面的一段代码:

var selectedShape;
///Function for selecting a shape
function setSelection(shape) {
  clearSelection();
  selectedShape = shape;
  shape.setEditable(true);
}

//Clear the selection of a polygon.
function clearSelection() {
  if (selectedShape) {
    selectedShape.setEditable(false);
    selectedShape = null;
  }
}

//Check if Polygon is inside Polygon****
function isPolygonInsidePolygon(innerPolygon, outerPolygon) {
    var points = innerPolygon.getPath().getArray();

    for (var i = 0; i < points.length; i++) {
      if (!google.maps.geometry.poly.containsLocation(points[i], outerPolygon)) {
        return false;
      }
    }
    return true;
  }

//Rewind Co-ords for Creating Hole
  function rewindRing(ring, dir) {
    var area = 0;
    for (var i = 0, len = ring.length, j = len - 1; i < len; j = i++) {
      area += ((ring[i].lng() - ring[j].lng()) * (ring[j].lat() + ring[i].lat()));
    }
    
    if (area >= 0 !== !dir)
      ring.reverse();
    return ring;
  }

function initialize() {
    var overlayArr=[];
    var map = new google.maps.Map(document.getElementById('polymap'), {
    zoom: 14,
    center: new google.maps.LatLng(28.631162, 77.213313),
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    disableDefaultUI: true,
    zoomControl: true,
    fullscreenControl: true
    });

    var polyOptions = {
    strokeWeight: 0,
    fillOpacity: 0.45,
    editable: true
    };


      // Creates a drawing manager attached to the map that allows the user to draw
      // markers, lines, and shapes.
    drawingManager = new google.maps.drawing.DrawingManager({
    drawingMode: google.maps.drawing.OverlayType.POLYGON,
    drawingControlOptions: {
    drawingModes: [google.maps.drawing.OverlayType.POLYGON]
    },
    markerOptions: {
    draggable: true
    },
    polylineOptions: {
    editable: true
    },
    rectangleOptions: polyOptions,
    circleOptions: polyOptions,
    polygonOptions: polyOptions,
    map: map
    });


    google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
    if (e.type != google.maps.drawing.OverlayType.MARKER) {

        //New Addition
        var path = e.overlay.getPath().getArray()
        path = rewindRing(path, true);
        newPoly = new google.maps.Polygon({
        path: path,
        })
        var found = false;
        for (var i = 0; i < overlayArr.length; i++) {
          if (isPolygonInsidePolygon(e.overlay, overlayArr[i])) {
            found = true;
            var path = e.overlay.getPath().getArray();
            path = rewindRing(path, false);
            overlayArr[i].getPaths().push(new google.maps.MVCArray(path));
            e.overlay.setMap(null);
            break;
          }
        }
         if(!found) {
          overlayArr.push(e.overlay);
        }

        var newShape = e.overlay;
        newShape.type = e.type;
        google.maps.event.addListener(newShape, 'click', function() {setSelection(newShape);});
        }
        setSelection(newShape);
    });

    google.maps.event.addListener(drawingManager, 'polygoncomplete', function (polygon) {
        for (var i = 0; i < selectedShape.getPaths().getLength(); i++) {
                google.maps.event.addListener(selectedShape.getPaths().getAt(i), 'set_at', function() {
                alert("complete called");
                });
                google.maps.event.addListener(selectedShape.getPaths().getAt(i), 'click', function() {
                alert("complete called");
                });
                google.maps.event.addListener(selectedShape.getPaths().getAt(i), 'dragend', function() {
                alert("complete called");
                });
                google.maps.event.addListener(selectedShape.getPaths().getAt(i), 'insert_at', function() {
                alert("complete called");
                });
                google.maps.event.addListener(selectedShape.getPaths().getAt(i), 'remove_at', function() {
                alert("complete called");
                });
                }
            });
}
<div id="polymap" style="height:300px;"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBIc-PhM9_Uwpjbks0WPvtkKYagOXTk12A&libraries=drawing&callback=initialize&" async defer></script>

【问题讨论】:

    标签: javascript google-maps dictionary polygon


    【解决方案1】:

    您需要将insert_atremove_atset_at 事件侦听器添加到内部路径您将其添加到外部多边形之后。

    相关问题:

    在代码决定将其添加到外部多边形的地方,添加内部路径的事件侦听器(在这种情况下,它只会添加一个新路径):

    if (isPolygonInsidePolygon(e.overlay, overlayArr[i])) {
      found = true;
      var path = e.overlay.getPath().getArray();
      path = rewindRing(path, false);
      var newPathIdx = overlayArr[i].getPaths().getLength(); // index of added path
      overlayArr[i].getPaths().push(new google.maps.MVCArray(path));
      e.overlay.setMap(null);
                  
      google.maps.event.addListener(selectedShape.getPaths().getAt(newPathIdx), 'set_at', function() {
        alert("inner path set_at called");
      });
      google.maps.event.addListener(selectedShape.getPaths().getAt(newPathIdx), 'insert_at', function() {
        alert("inner path insert_at called");
      });
      google.maps.event.addListener(selectedShape.getPaths().getAt(newPathIdx), 'remove_at', function() {
        alert("inner path remove_at called");
      });
      break;
    }
    

    更新代码 sn-p:

    var selectedShape;
    ///Function for selecting a shape
    function setSelection(shape) {
      clearSelection();
      selectedShape = shape;
      shape.setEditable(true);
    }
    
    //Clear the selection of a polygon.
    function clearSelection() {
      if (selectedShape) {
        selectedShape.setEditable(false);
        selectedShape = null;
      }
    }
    
    //Check if Polygon is inside Polygon****
    function isPolygonInsidePolygon(innerPolygon, outerPolygon) {
      var points = innerPolygon.getPath().getArray();
    
      for (var i = 0; i < points.length; i++) {
        if (!google.maps.geometry.poly.containsLocation(points[i], outerPolygon)) {
          return false;
        }
      }
      return true;
    }
    
    //Rewind Co-ords for Creating Hole
    function rewindRing(ring, dir) {
      var area = 0;
      for (var i = 0, len = ring.length, j = len - 1; i < len; j = i++) {
        area += ((ring[i].lng() - ring[j].lng()) * (ring[j].lat() + ring[i].lat()));
      }
    
      if (area >= 0 !== !dir)
        ring.reverse();
      return ring;
    }
    
    function initialize() {
      var overlayArr = [];
      var map = new google.maps.Map(document.getElementById('polymap'), {
        zoom: 14,
        center: new google.maps.LatLng(28.631162, 77.213313),
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        disableDefaultUI: true,
        zoomControl: true,
        fullscreenControl: true
      });
    
      var polyOptions = {
        strokeWeight: 0,
        fillOpacity: 0.45,
        editable: true
      };
    
    
      // Creates a drawing manager attached to the map that allows the user to draw
      // markers, lines, and shapes.
      drawingManager = new google.maps.drawing.DrawingManager({
        drawingMode: google.maps.drawing.OverlayType.POLYGON,
        drawingControlOptions: {
          drawingModes: [google.maps.drawing.OverlayType.POLYGON]
        },
        markerOptions: {
          draggable: true
        },
        polylineOptions: {
          editable: true
        },
        rectangleOptions: polyOptions,
        circleOptions: polyOptions,
        polygonOptions: polyOptions,
        map: map
      });
    
    
      google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
        if (e.type != google.maps.drawing.OverlayType.MARKER) {
    
          //New Addition
          var path = e.overlay.getPath().getArray()
          path = rewindRing(path, true);
          newPoly = new google.maps.Polygon({
            path: path,
          })
          var found = false;
          for (var i = 0; i < overlayArr.length; i++) {
            if (isPolygonInsidePolygon(e.overlay, overlayArr[i])) {
              found = true;
              var path = e.overlay.getPath().getArray();
              path = rewindRing(path, false);
              var newPathIdx = overlayArr[i].getPaths().getLength();
              overlayArr[i].getPaths().push(new google.maps.MVCArray(path));
              e.overlay.setMap(null);
              console.log("isPolygonInsidePolygon, paths=" + overlayArr[i].getPaths().getLength());
              google.maps.event.addListener(selectedShape.getPaths().getAt(newPathIdx), 'set_at', function() {
                alert("inner path set_at called");
              });
              google.maps.event.addListener(selectedShape.getPaths().getAt(newPathIdx), 'insert_at', function() {
                alert("inner path insert_at called");
              });
              google.maps.event.addListener(selectedShape.getPaths().getAt(newPathIdx), 'remove_at', function() {
                alert("inner path remove_at called");
              });
              break;
            }
          }
          if (!found) {
            overlayArr.push(e.overlay);
          }
    
          var newShape = e.overlay;
          newShape.type = e.type;
          google.maps.event.addListener(newShape, 'click', function() {
            setSelection(newShape);
          });
        }
        setSelection(newShape);
      });
    
      google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) {
        console.log("polygoncomplete, paths=" + selectedShape.getPaths().getLength());
        for (var i = 0; i < selectedShape.getPaths().getLength(); i++) {
          google.maps.event.addListener(selectedShape.getPaths().getAt(i), 'set_at', function() {
            alert("set_at called");
          });
          google.maps.event.addListener(selectedShape.getPaths().getAt(i), 'insert_at', function() {
            alert("insert_at called");
          });
          google.maps.event.addListener(selectedShape.getPaths().getAt(i), 'remove_at', function() {
            alert("remove_at called");
          });
        }
      });
    }
    <div id="polymap" style="height:300px;"></div>
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBIc-PhM9_Uwpjbks0WPvtkKYagOXTk12A&libraries=drawing&callback=initialize&" async defer></script>

    【讨论】:

    • 如何去除特定的孔。例如,hole1.setMap(null)。但这使它成为多边形。这适用于需要在 dblClick 上删除已创建的孔或使用某些上下文菜单的特定用例
    • 这是一个新的和不同的问题,请务必在该问题中提供minimal reproducible example,以证明您的问题(尽管参考此问题的上下文不会有什么坏处)
    • 我添加了带有完整上下文的新问题Link
    • 我添加了一个针对我所面临问题的新问题。但已被社区关闭。看不出有什么具体原因。让我失望。
    猜你喜欢
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 2011-12-03
    • 2012-06-15
    相关资源
    最近更新 更多