首页 > 解决方案 > 谷歌地图内部多边形上的事件

问题描述

我正在尝试创建一个实用程序,用户可以在其中创建 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>

标签: javascriptgoogle-mapsdictionarypolygon

解决方案


在将内部路径添加到外部多边形,您需要将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;
}

更新的代码片段:

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>


推荐阅读