好的,这是我的问题,我会用图片来说明它更容易。
我需要用户绘制一些表示覆盖区域的多边形。
多边形需要有固定数量的点(顶点),因为它稍后会进入处理算法,如果多边形可以包含很多点,那么它会非常慢。
无论如何,在我的例子中,我们坚持使用六边形(6分) 用户需要能够拖动多边形并对其进行修改,但不能更改点数。
我尝试为多边形设置editable: true
选项,它工作正常,但它给了我图片上显示的情况。它为每个点创建一个句柄,并在每个点之间的中间创建另一个句柄(半透明)。现在,如果用户移动该半透明点,它将向多边形添加另一个点(顶点),并在新创建的线的中间添加另外两个手柄。这给了我们一个7点多边形。
最好的选择是删除那些半透明手柄,这样用户只能拖动多边形点,这样他就不会影响总点数。
我可以使用谷歌地图可编辑选项实现这一目标吗?
答案 0 :(得分:4)
由于似乎没有人有更好的解决方案,我将我的解决方案标记为已接受,以防有人遇到同样的问题。不是很漂亮,但完成工作
到目前为止,我发现的唯一解决方案是在绘制多边形后手动隐藏手柄。这里的问题是句柄没有任何CSS类或id,所以我必须隐藏所有不透明度为0.5的div(句柄的不透明度)。它有效,但考虑到其他东西可能具有相同的不透明度并且不需要隐藏,这是非常危险的。
// variables
var map, path, color;
polygon = new google.maps.Polygon({
paths: path,
strokeColor: color,
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: color,
fillOpacity: 0.10,
editable: true,
});
polygon.setMap(map);
setTimeout(function(){ map.find('div[style*=opacity: 0.5]').hide(); }, 50);
答案 1 :(得分:4)
实现您想要的另一种方法是放弃多边形的内置编辑功能并自行实现。这更加强大和灵活。
首先,不要让多边形可编辑。接下来,为多边形的每个角制作一个标记。最后,让每个标记都可拖动,并在其上设置一个事件监听器"拖动"事件来更新多边形。
制作标记并添加事件监听器:
for (var i=0; i<coordinates.length; i++){
marker_options.position = coordinates[i];
var point = new google.maps.Marker(marker_options);
google.maps.event.addListener(point, "drag", update_polygon_closure(polygon, i));
}
其中update_polygon_closure定义为:
function update_polygon_closure(polygon, i){
return function(event){
polygon.getPath().setAt(i, event.latLng);
}
}
完整代码位于jsfiddle:https://jsfiddle.net/3L140cg3/16/
答案 2 :(得分:2)
作为@ zolakt答案的略微改进,你可以隐藏多边形上的中点div并添加一个mousedown事件监听器来跟踪点击中点以防止拖动和更改多边形:
// hide the midpoints (note that users can still click where the hidden midpoint
// divs are and drag to edit the polygon
$('#multi_markers div[style*="opacity: 0.5"]').hide();
// get the paths for the current polygon
var octopusPaths = HotelLib.octopusPolygon.getPaths();
// track when a polygon midpoint is clicked on
google.maps.event.addListener(HotelLib.octopusPolygon, 'mousedown', function(mdEvent) {
// if a midpoint is clicked on, mdEvent.edge will have an integer value
if(mdEvent.edge || (mdEvent.edge == 0)){
// immediately reset the polygon to its former paths
// effectively disabling the drag to edit functionality
HotelLib.octopusPolygon.setPaths(octopusPaths);
// hide the midpoints again since re-setting the polygon paths
// will show the midpoints
$('#multi_markers div[style*="opacity: 0.5"]').hide();
}
});
答案 3 :(得分:1)
我刚刚为此创建了一个替代解决方案,而无需摆弄 setTimeout
或折线创建。这也是一个有点全球性的解决方案,因此您基本上可以将其放入任何使用 Google 地图的既定程序中。
我们将使用 MutationObserver 来观察这些中点节点何时出现在 DOM 上,然后立即隐藏它们。当某些内容设置为可编辑时,它们应该开始出现。
基本上只是在地图初始化后把它放在任何地方:
var editMidpointNodeObserver = new MutationObserver(function(list, observer)
{
if($('#mapwrapper div[style*="opacity: 0.5"]').parent('div[style*="cursor: pointer"]').length > 0)
{
$('#mapwrapper div[style*="opacity: 0.5"]').parent('div[style*="cursor: pointer"]').remove();
}
});
editMidpointNodeObserver.observe($('#mapwrapper')[0], { childList: true, subtree: true });
将 #mapwrapper
更改为您的 Google 地图包装元素的任何 ID。我在这里使用 jQuery,因此 $('#mapwrapper')[0]
将 jQuery 对象转换为原生 DOM 对象。应该也可以在没有 jQuery 的情况下工作,我假设您知道如何将其转换为 vanilla js。
我们也直接删除了节点,因此无需担心用户会意外或以其他方式点击不可见的节点。
所有浏览器都应该支持 MutationObserver:https://caniuse.com/mutationobserver