如何删除带孔的多边形上的顶点(节点)(Google Maps V3)

时间:2016-03-04 04:01:08

标签: google-maps-api-3 polygon

我从Ian Grainger采用了这个例子(解决方案),但我添加了一个带内孔的Polygon。

This example适用于外顶点路径,但不适用于内顶点路径。

我需要为内部和外部节点实现事件监听器,因为在内部顶点上的fire事件中,删除外部顶点。它效果不好。

有人可以提供一些如何解决这个问题的样本吗?

1 个答案:

答案 0 :(得分:1)

你的一个问题是带有一个洞的多边形有多个(在这种情况下是两个)路径,并且你不会为两条路径上的变化添加监听器。下面是一个概念证明,它不是完美的,有时标记是孤立的,但应该是一个起点。双击顶点下方的蓝色标记将其删除(我无法让您的" X"可靠地工作)。

proof of concept fiddle

updated proof of concept with white markers

代码段



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);
  }
}
&#13;
html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0
}
&#13;
<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>
&#13;
&#13;
&#13;