我从Ian Grainger采用了这个例子(解决方案),但我添加了一个带内孔的Polygon。
This example适用于外顶点路径,但不适用于内顶点路径。
我需要为内部和外部节点实现事件监听器,因为在内部顶点上的fire事件中,删除外部顶点。它效果不好。
有人可以提供一些如何解决这个问题的样本吗?
答案 0 :(得分:1)
你的一个问题是带有一个洞的多边形有多个(在这种情况下是两个)路径,并且你不会为两条路径上的变化添加监听器。下面是一个概念证明,它不是完美的,有时标记是孤立的,但应该是一个起点。双击顶点下方的蓝色标记将其删除(我无法让您的" X"可靠地工作)。
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;