How delete vertex (node) on Polygon with Hole (Google Maps V3)

本秂侑毒 提交于 2019-12-02 04:55:01

One of your issues is polygon with a hole in it has multiple (in this case two) paths, and you aren't adding listeners for changes on both paths. Below is a proof of concept, it isn't perfect, sometimes markers are orphaned, but should be a starting point. Double click on the blue markers underneath the vertices to delete them (I couldn't get your "X" to reliably work).

proof of concept fiddle

updated proof of concept with white markers

code snippet:

var G = google.maps;
var zoom = 8;
var centerPoint = new G.LatLng(37.286172, -121.80929);
var map;


$(function() {
  // create options object
  var myOptions = {
    center: centerPoint,
    zoom: zoom,
    mapTypeId: G.MapTypeId.ROADMAP
  };

  // create map with options
  map = new G.Map($("#map_canvas")[0], myOptions);

  addPolygon(map);
});


function addPolygon(map) {
  var paths = [
    [new G.LatLng(37.686172, -122.20929),
      new G.LatLng(37.696172, -121.40929),
      new G.LatLng(36.706172, -121.40929),
      new G.LatLng(36.716172, -122.20929),
      new G.LatLng(37.686172, -122.20929)
    ],

    [new G.LatLng(37.486172, -122.00929),
      new G.LatLng(37.086172, -122.00929),
      new G.LatLng(37.086172, -121.60929),
      new G.LatLng(37.486172, -121.60929),
      new G.LatLng(37.486172, -122.00929)
    ]
  ];

  poly = new G.Polygon({
    clickable: false,
    paths: paths,
    map: map
  });
  polygonBinder(poly);
  poly.setEditable(true);
  G.event.addListener(poly.getPaths().getAt(0), 'insert_at', addClickMarker0);
  G.event.addListener(poly.getPaths().getAt(1), 'insert_at', addClickMarker1);
}

function polygonBinder(poly) {
  poly.binder0 = new MVCArrayBinder(poly.getPaths().getAt(0));
  poly.binder1 = new MVCArrayBinder(poly.getPaths().getAt(1));
  poly.markers = [];
  for (var i = 0; i < poly.getPaths().getLength(); i++) {
    poly.markers[i] = [];
    for (var j = 0; j < poly.getPaths().getAt(i).getLength(); j++) {
      var mark = new G.Marker({
        map: map,
        icon: {
          path: G.SymbolPath.CIRCLE,
          scale: 8,
          strokeWeight: 2,
          strokeColor: 'blue',
          fillColor: 'blue',
          fillOpacity: 1
        },
        draggable: true,
        title: "double click to delete [" + i + "," + j + "]",
        position: poly.getPaths().getAt(i).getAt(j)
      });
      poly.markers[i][j] = mark;
      mark.bindTo('position', poly["binder" + i], (j).toString());
      G.event.addListener(mark, "dblclick", deleteMark);
    }
  }

}

function addClickMarker0(index) {
  addClickMarker(index, 0);
}

function addClickMarker1(index) {
  addClickMarker(index, 1);
}

function deleteMark(evt) {
  var minDist = Number.MAX_VALUE;
  var minPathIdx = -1;
  var minIdx = -1;
  var i, j;
  for (i = 0; i < poly.getPaths().getLength(); i++) {
    for (j = 0; j < poly.getPaths().getAt(i).getLength(); j++) {
      var distance = G.geometry.spherical.computeDistanceBetween(evt.latLng, poly.getPaths().getAt(i).getAt(j));
      if (distance < minDist) {
        minDist = distance;
        minPathIdx = i;
        minIdx = j;
      }
      if (distance < 10) {
        document.getElementById('info').innerHTML = "deleted path=" + i + " idx=" + j + " dist<10 minDist=" + minDist + " meters";
        poly.getPaths().getAt(i).removeAt(j);
        break;
      }
    }
  }
  if ((i == poly.getPaths().getLength()) && (j == poly.getPaths(i - 1).getLength())) {
    poly.getPaths().getAt(minPathIdx).removeAt(minIdx);
    document.getElementById('info').innerHTML = "deleted path=" + minPathIdx + " idx=" + minIdx + " dist=" + minDist + " meters";
  }
  this.setMap(null);
}

function addClickMarker(index, pathIdx) {
  var path = this;
  // rebind binder
  for (var i = 0; i < poly.markers[pathIdx].length; i++) {
    poly.markers[pathIdx][i].setMap(null);
  }
  poly.markers[pathIdx] = [];
  for (var i = 0; i < poly.getPaths().getAt(pathIdx).getLength(); i++) {
    var mark = new G.Marker({
      map: map,
      icon: {
        path: G.SymbolPath.CIRCLE,
        scale: 8,
        strokeWeight: 2,
        strokeColor: 'blue',
        fillColor: 'blue',
        fillOpacity: 1
      },
      draggable: true,
      title: "double click to delete [" + pathIdx + "," + i + "]",
      position: poly.getPaths().getAt(pathIdx).getAt(i)
    });
    poly.markers[pathIdx][i] = mark;
    mark.bindTo('position', poly["binder" + pathIdx], (i).toString());
    G.event.addListener(mark, "dblclick", deleteMark);
  }
}

function MVCArrayBinder(mvcArray) {
  this.array_ = mvcArray;
}
MVCArrayBinder.prototype = new google.maps.MVCObject();
MVCArrayBinder.prototype.get = function(key) {
  if (!isNaN(parseInt(key))) {
    return this.array_.getAt(parseInt(key));
  } else {
    this.array_.get(key);
  }
}
MVCArrayBinder.prototype.set = function(key, val) {
  if (!isNaN(parseInt(key))) {
    this.array_.setAt(parseInt(key), val);
  } else {
    this.array_.set(key, val);
  }
}
html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?libraries=drawing,geometry"></script>
<div id="info"></div>
<div id="map_canvas" style="width:100%; height:100%"></div>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!