2

好的,这是我的问题,我会放一张图片来说明它更容易。 谷歌地图可编辑六边形

我需要用户绘制一些多边形,代表覆盖区域。

多边形需要有固定数量的点(顶点),因为它稍后会进入处理算法,如果多边形可以包含很多点,它会非常慢。

无论如何,在我的例子中,让我们坚持六边形(6 分)。
用户需要能够拖动多边形并对其进行修改,但不能更改点数。

我尝试editable: true为多边形设置选项,它工作正常,但它给了我图片上显示的情况。它为每个点创建一个句柄,并在每个点之间的中间创建另一个句柄(半透明)。现在,如果用户移动该半透明点,它将向多边形添加另一个点(顶点),并在新创建的线的中间添加额外的两个手柄。这给了我们一个 7 点多边形。

最好的选择是删除那些半透明的手柄,这样用户只能拖动多边形点,这样他就不会影响点的总数。

我可以使用谷歌地图可编辑选项来实现这一点吗?

4

4 回答 4

8

实现您想要的另一种方法是放弃多边形的内置编辑能力并自己实现它。这更加强大和灵活。

首先,不要使多边形可编辑。接下来,为多边形的每个角制作一个标记。最后,使每个标记可拖动并在其“拖动”事件上设置一个事件侦听器以更新多边形。

制作标记并添加事件监听器:

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/

于 2015-06-27T22:04:23.563 回答
5

由于似乎没有人有更好的解决方案,我将我的解决方法标记为已接受,以防有人偶然发现同样的问题。不是很漂亮,但可以完成工作

到目前为止,我发现的唯一解决方案是在绘制多边形后手动隐藏句柄。这里的问题是句柄没有任何 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);
于 2012-04-08T21:59:00.023 回答
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();

    }

});
于 2017-01-05T09:26:43.523 回答
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 Maps 包装器元素的 id。我在这里使用 jQuery,因此$('#mapwrapper')[0]将 jQuery 对象转换为本机 DOM 对象。没有 jQuery 也应该可以工作,我假设你知道如何将它转换为 vanilla js。

我们也只是直接删除节点,因此无需担心用户会意外或以其他方式单击不可见的节点。

所有浏览器都应该支持 MutationObserver:https ://caniuse.com/mutationobserver

于 2021-01-08T13:19:01.953 回答