连接并扩展谷歌地图上的多边形编辑功能
Hooking into and extending the polygon editing function on a Google Map
在我的用例中,我们允许用户在地图上定义"区域"(多边形)。基本的多边形编辑功能,通过设置editable: true
,工作得很好。但是,我需要一些额外的功能。
例如,当用户开始拖动一个顶点时,我想突出显示其他多边形上附近的顶点,如果用户拖动其中一个顶点,它将"捕捉"他们正在拖动的顶点的纬度/lng,使其与被拖动的顶点相同。
是否有人成功地在编辑过程中插入了一些"额外"的代码?在这些顶点句柄上是否有任何中间事件被触发(当拖动,鼠标移动等),我可以钩入,解释,并在地图上绘制一些额外的东西?我所希望的是有人可以告诉我"哦,如果polygon.obfuscatedVariable
设置,那些是拖动手柄,你可以监听鼠标移动在polygon.obfuscatedVariable[3]
上,检索晚/长,等等。"hack和临时的解决方案是可以接受的:因为内置的编辑是如此接近我想要的,我真的不想从头开始重新创建它。
我已经忘记了这个问题,但这是我们解决这个问题的方法。希望这对你有帮助!
短版:
当mousedown
出现在形状上时,检查它是否在顶点上,如果是,使用elementFromPoint
保存对表示顶点句柄的实际HTML <div>
的引用。在随后的mousemove
和mouseup
事件中,您可以轮询该<div>
的屏幕位置,并将其与地图上其他点的位置进行比较。
长版:
我已经从我们的应用程序中抽出了相关的函数,所以你需要忽略一些特定的函数和对象等,但这确实显示了我们的工作"快照到点"实现。
首先,我们将做像素到后期的转换,所以你需要一个简单的覆盖定义的地方(你总是需要一个做这些计算):
_this.editor.overlay = new g.maps.OverlayView();
_this.editor.overlay.draw = function () {};
_this.editor.overlay.setMap(This.map);
现在,每当我们在地图上初始化一个形状时,我们都会为它添加一个mousedown
事件处理程序。
g.maps.event.addListener(_this.shape, 'mousedown', function (event) {
if (event.vertex >= 0) {
var pixel = _this.editor.overlay.getProjection().fromLatLngToContainerPixel(_this.shape.getPath().getAt(event.vertex));
var offset = _this.mapElement.offset();
var handle = document.elementFromPoint(pixel.x + offset.left, pixel.y + offset.top);
if (handle) {
_this.dragHandle = $(handle);
_this.snappablePoints = _this.editor.snappablePoints(_this);
} else {
_this.dragHandle = null;
_this.snappablePoints = null;
}
}
});
(您将注意到对snappablePoints
的调用,这只是一个内部实用程序函数,用于收集对该点有效的所有点。我们在这里这样做是因为在每个mousemove
上执行循环将是一个昂贵的循环。
现在,在形状的mousemove
监听器中,因为我们保存了对<div>
的引用,我们可以轮询它的屏幕位置,并将其与地图上其他点的屏幕位置进行比较。如果一个点在一定的像素范围内(我认为我们的是8像素),我们保存它,并悬停一个小图标,告诉用户我们要捕捉。
g.maps.event.addListener(this.shape, 'mousemove', function (event) {
var projection, pixel, pixel2, offset, dist, i;
if (event.vertex >= 0 && this.dragHandle) {
// If dragHandle is set and we're moving over a vertex, we must be dragging an
// editable polygon point.
offset = this.editor.mapElement.offset();
pixel = {
x: this.dragHandle.offset().left - offset.left + this.dragHandle.width() / 2,
y: this.dragHandle.offset().top - offset.top + this.dragHandle.height() / 2
};
// Search through all previously saved snappable points, looking for one within the snap radius.
projection = this.editor.overlay.getProjection();
this.snapToPoint = null;
for(i = 0; i < this.snappablePoints.length; i++) {
pixel2 = projection.fromLatLngToContainerPixel(this.snappablePoints[i]);
dist = (pixel.x - pixel2.x) * (pixel.x - pixel2.x) + (pixel.y - pixel2.y) * (pixel.y - pixel2.y);
if (dist <= SNAP_RADIUS) {
this.snapToPoint = this.snappablePoints[i];
$('#zone-editor #snapping').css('left', pixel.x + 10 + offset.left).css('top', pixel.y - 12 + offset.top).show();
break;
}
}
if (!this.snapToPoint) {
$('#zone-editor #snapping').hide();
}
});
当用户停止移动鼠标时进行一些清理:
g.maps.event.addListener(this.shape, 'mouseup', function (event) {
// Immediately clear dragHandle, so that everybody knows we aren't dragging any more.
// We'll let the path updated event deal with any actual snapping or point saving.
_this.dragHandle = null;
$('#zone-editor #snapping').hide();
});
最后,我们实际处理了"捕捉",这实际上只是形状路径上的事件侦听器中的一小部分逻辑。
g.maps.event.addListener(this.shape.getPath(), 'set_at', function (index, element) {
if (this.snapToPoint) {
// The updated point was dragged by the user, and we have a snap-to point.
// Overwrite the recently saved point and let another path update trigger.
var point = this.snapToPoint;
this.snapToPoint = null;
this.shape.getPath().setAt(index, point);
} else {
// Update our internal list of points and hit the server
this.refreshPoints();
this.save();
};
// Clear any junk variables whenever the path is updated
this.dragHandle = null;
this.snapToPoint = null;
this.snappablePoints = null;
});
鳍。
- CKEditor Widget-阻止编辑可编辑元素本身
- 如何在angularJS中编辑时,如果DB中的值为true,则设置复选框,如果值为false,则取消选中复选框
- 高亮显示时编辑文本大小和颜色
- 剑道UI内联编辑:如何在点击其他按钮时隐藏按钮
- 将事件聚焦/模糊在可编辑内容的元素上
- 编辑HTML表的源数据
- SVG/JavaScript:尝试选择和更改多边形点
- ExtJS网格单元格编辑器,防止焦点松动问题
- 如何在googlemapapiv3中获取新编辑的多边形坐标
- 谷歌地图可编辑多边形过滤器 从set_at事件中拖动事件
- 如何在传单中编辑多边形后获得修改和原始的geojson点
- 编辑多边形后如何获取多边形的新坐标
- 编辑谷歌地球多边形
- 使4000点的多边形在谷歌地图v3中可编辑
- 获取可编辑多边形点的单击事件(Google Maps API v3)
- 谷歌地图api v3:为编辑后的多边形添加自定义撤消/重做功能
- 谷歌地图api v3:点击一个按钮使多边形不可编辑
- 在leaflet.js和leaflet.snap中编辑多边形
- 连接并扩展谷歌地图上的多边形编辑功能
- 如何在传单中使用edit .poly.js编辑多边形