Google地图有绘图库来绘制折线和多边形等内容。
此功能的示例如下:http://gmaps-samples-v3.googlecode.com/svn-history/r282/trunk/drawing/drawing-tools.html
在绘制和编辑多边形时,我希望能够删除路径上的一个点/顶点。 API文档似乎没有任何暗示。
答案 0 :(得分:35)
Google地图现在为从多边形或折线触发的事件提供“PolyMouseEvent”回调对象。
为了建立一个涉及右键单击的解决方案的其他答案,您需要做的就是最新版本的V3 API中的以下内容:
// this assumes `my_poly` is an normal google.maps.Polygon or Polyline
var deleteNode = function(mev) {
if (mev.vertex != null) {
my_poly.getPath().removeAt(mev.vertex);
}
}
google.maps.event.addListener(my_poly, 'rightclick', deleteNode);
你会注意到,关于我们是否接近这一点的任何复杂计算都不再是必要的,因为Google Maps API现在告诉我们点击了哪个顶点。
注意:这仅在折线/多边形处于编辑模式时才有效。(当您可能要删除的顶点可见时。)
最后,您可以考虑使用点击或双击事件。 “点击”非常智能,不会在拖动时触发,但使用单击触发器可能仍会让您的某些用户感到惊讶。
答案 1 :(得分:26)
目前这是一项杰出的功能请求(Google承认),issue 3760。
这是我的解决方案:http://jsbin.com/ajimur/10。它使用一个向传入的多边形添加删除按钮的功能(在撤消按钮下面)。
或者,有人提出了这种方法:right-click to delete closest vertex,它工作得很好,但在UI技巧方面有些缺乏。我构建了链接中的代码,以检查点击是否在节点的内部(或在节点的1个像素内) - 在JSBin中:http://jsbin.com/ajimur/。
编辑:正如Amr Bekhit指出的那样 - 这种方法目前已被破解,因为事件需要附加到多边形。
答案 2 :(得分:16)
我发现Sean的代码非常简单和有用。我刚刚添加了一个限制器,当用户只剩下3个节点时停止删除。没有它,用户只能进入一个节点,不能再编辑:
my_poly.addListener('rightclick', function(mev){
if (mev.vertex != null && this.getPath().getLength() > 3) {
this.getPath().removeAt(mev.vertex);
}
});
答案 3 :(得分:8)
我遇到了需要从包含多个路径的多边形中删除节点的情况。这是Sean和Evil代码的修改:
shape.addListener('rightclick', function(event){
if(event.path != null && event.vertex != null){
var path = this.getPaths().getAt(event.path);
if(path.getLength() > 3){
path.removeAt(event.vertex);
}
}
});
答案 4 :(得分:2)
以为我会做出贡献,因为我也在寻找解决方案,这是我的实施:
if (m_event.hasOwnProperty('edge') && m_event.edge >= 0 &&
GeofenceService.polygon.getPath().getLength() > 3) {
GeofenceService.polygon.getPath().removeAt(m_event.edge);
return;
}
if (m_event.hasOwnProperty('vertex') && m_event.vertex >= 0 &&
GeofenceService.polygon.getPath().getLength() > 3) {
GeofenceService.polygon.getPath().removeAt(m_event.vertex);
return;
}
这允许处理顶点节点和边缘节点的删除,并且通过检查路径长度>保持最小的三角形形成多边形。 3。
答案 5 :(得分:0)
2020更新
Google在其文档中提供了此示例的工作演示,演示了如何通过右键单击顶点以显示“删除”菜单来删除顶点或直线上的点。
以及完整性代码(请参见其Github repo);
function initialize() {
const mapOptions = {
zoom: 3,
center: new google.maps.LatLng(0, -180),
mapTypeId: "terrain",
};
const map = new google.maps.Map(document.getElementById("map"), mapOptions);
const flightPlanCoordinates = [
new google.maps.LatLng(37.772323, -122.214897),
new google.maps.LatLng(21.291982, -157.821856),
new google.maps.LatLng(-18.142599, 178.431),
new google.maps.LatLng(-27.46758, 153.027892),
];
const flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
editable: true,
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2,
map: map,
});
/**
* A menu that lets a user delete a selected vertex of a path.
*/
class DeleteMenu extends google.maps.OverlayView {
constructor() {
super();
this.div_ = document.createElement("div");
this.div_.className = "delete-menu";
this.div_.innerHTML = "Delete";
const menu = this;
google.maps.event.addDomListener(this.div_, "click", () => {
menu.removeVertex();
});
}
onAdd() {
const deleteMenu = this;
const map = this.getMap();
this.getPanes().floatPane.appendChild(this.div_);
// mousedown anywhere on the map except on the menu div will close the
// menu.
this.divListener_ = google.maps.event.addDomListener(
map.getDiv(),
"mousedown",
(e) => {
if (e.target != deleteMenu.div_) {
deleteMenu.close();
}
},
true
);
}
onRemove() {
if (this.divListener_) {
google.maps.event.removeListener(this.divListener_);
}
this.div_.parentNode.removeChild(this.div_);
// clean up
this.set("position", null);
this.set("path", null);
this.set("vertex", null);
}
close() {
this.setMap(null);
}
draw() {
const position = this.get("position");
const projection = this.getProjection();
if (!position || !projection) {
return;
}
const point = projection.fromLatLngToDivPixel(position);
this.div_.style.top = point.y + "px";
this.div_.style.left = point.x + "px";
}
/**
* Opens the menu at a vertex of a given path.
*/
open(map, path, vertex) {
this.set("position", path.getAt(vertex));
this.set("path", path);
this.set("vertex", vertex);
this.setMap(map);
this.draw();
}
/**
* Deletes the vertex from the path.
*/
removeVertex() {
const path = this.get("path");
const vertex = this.get("vertex");
if (!path || vertex == undefined) {
this.close();
return;
}
path.removeAt(vertex);
this.close();
}
}
const deleteMenu = new DeleteMenu();
google.maps.event.addListener(flightPath, "rightclick", (e) => {
// Check if click was on a vertex control point
if (e.vertex == undefined) {
return;
}
deleteMenu.open(map, flightPath.getPath(), e.vertex);
});
}