Leaflet 传单-重叠多段线的工具提示

Leaflet 传单-重叠多段线的工具提示,leaflet,tooltip,polyline,overlapping,Leaflet,Tooltip,Polyline,Overlapping,背景: 我正在为徒步旅行开发一个基于web的地图应用程序。因此,基于传单的地图提供了有标签的徒步旅行路线。由于任何徒步旅行路线都可以是多条路线的一部分,因此路线(分别是代表路线的对应多段线)可以重叠 问题: 每条管线都有其工具提示(由鼠标悬停{sticky:true}触发),显示其标签,该标签按预期适用于非重叠多段线,但一旦两条或多条管线重叠,只有“顶部”多段线才会打开其工具提示。这种行为本身并不坏,但由于所有路由都同样重要,我希望在指针位置显示路由的所有标签(或者最多显示5个标签+x)。我找不

背景:
我正在为徒步旅行开发一个基于web的地图应用程序。因此,基于传单的地图提供了有标签的徒步旅行路线。由于任何徒步旅行路线都可以是多条路线的一部分,因此路线(分别是代表路线的对应多段线)可以重叠

问题:
每条管线都有其工具提示(由鼠标悬停{sticky:true}触发),显示其标签,该标签按预期适用于非重叠多段线,但一旦两条或多条管线重叠,只有“顶部”多段线才会打开其工具提示。这种行为本身并不坏,但由于所有路由都同样重要,我希望在指针位置显示路由的所有标签(或者最多显示5个标签+x)。我找不到与此主题相关的任何问题

我的尝试:
-为所有管线创建要素编组,将工具提示绑定到该编组,希望工具提示功能提供一个跨越指针位置的所有多段线的数组。事实证明,我只得到顶部多段线的信息
-我在地图上的mousemove事件中也尝试了同样的方法,但没有成功
-将指针的layerPoint坐标与所有管线的环和零件放置点阵列进行比较,以找到匹配的layerPoint,但成功率仅为5%,因为这些layerPoint仅覆盖多段线的实际点,而不覆盖两点之间的连接。此外,每个多段线周围都有一个边距,在指针接触到多段线之前触发tolltip(我猜这也会改善触摸动作)
-边距问题的一个解决方案是在将每个多段线点与指针坐标进行比较之前,向每个多段线点添加正边距和负边距,这样可以改善结果,但不能解决主要问题

旁注:
-所有管线都绘制到单个画布中

长话短说,我需要外部帮助来实现目标。也许你们中的一些人有一个想法或者可以提供一个解决方案。欢迎您的任何意见

**更新:***
一个有效但效率很低的解决方案如下

方法:
计算从指针到视口中所有管线的最短距离。如果从指针到管线的距离低于某个阈值,请将其添加到应显示的管线标签数组中

步骤:
1.)将空白工具提示绑定到包含所有管线的功能组
2.)使用以下函数将mousemove事件绑定到功能组

var routesFeatureGroup = L.featureGroup(routesGroup)
    .bindTooltip('', {sticky: true})
    .on('mousemove', function(e){
        var routeLabels   = [e.layer.options.label]; // add triggering route's label by default
        var mouseCoordAbs = el.$map.project(e.latlng);

        $.each(vars.objectsInViewport.routes, function(i, v){
            if (e.layer.options.id != el.$routes[i].options.id && el.$routes[i]._pxBounds.contains(e.layerPoint)){
                var nearestLatlngOnPolyline = getNearestPolylinePoint(e.latlng, el.$routes[i]);
                var polyPointCoordAbs = el.$map.project(nearestLatlngOnPolyline);

                var distToMouseX = polyPointCoordAbs.x - mouseCoordAbs.x;
                var distToMouseY = polyPointCoordAbs.y - mouseCoordAbs.y;
                var distToMouse  = Math.sqrt(distToMouseX*distToMouseX + distToMouseY*distToMouseY);

                if (distToMouse < 15) {
                    routeLabels.push(el.$routes[i].options.label);
                }
             }
        })

        var routesFeatureGroup.setTooltipContent(routeLabels.join('<br>'));
    })

我可以给你一个如何做到这一点的想法,但我不是100%肯定它会做的工作。有一个(映射框)可以告诉您一个点是否在多边形内,并返回包含该点的所有多边形

如果此插件不适用于多段线,您可以从多段线创建多边形,只需从最后一点返回到第一点并闭合该线(我不确定这是否适合您的解决方案)。例如,如果连接点的多段线为[0,1,2,…n-1,n],则返回连接[n与n-1,n-1与n-2,…1与0]。这样,您将拥有相同的多段线形状,但它将是一个多边形。这不是最优化的解决方案,而是使用已知可用插件的快速修复方案

获得所有工具提示后,可以为每个多边形/多段线一次打开所有工具提示。或者打开一些辅助工具提示,用户可以在其中选择要打开的工具提示


我希望这有帮助!如果你找到了更好的解决方案(或者找到了一个插件),请在这里发布。

我可以告诉你如何做到这一点,但我不能100%肯定它能完成这项工作。有一个(映射框)可以告诉您一个点是否在多边形内,并返回包含该点的所有多边形

如果此插件不适用于多段线,您可以从多段线创建多边形,只需从最后一点返回到第一点并闭合该线(我不确定这是否适合您的解决方案)。例如,如果连接点的多段线为[0,1,2,…n-1,n],则返回连接[n与n-1,n-1与n-2,…1与0]。这样,您将拥有相同的多段线形状,但它将是一个多边形。这不是最优化的解决方案,而是使用已知可用插件的快速修复方案

获得所有工具提示后,可以为每个多边形/多段线一次打开所有工具提示。或者打开一些辅助工具提示,用户可以在其中选择要打开的工具提示


我希望这有帮助!如果你找到了更好的解决方案(或者找到了一个插件来完成这项工作),请在这里发布。

我看到了传单pip插件(多边形中的点),但我认为这种方法存在以下问题:通过将最后一个点与第一个点连接,多边形覆盖的区域比具有“权重”的多段线大得多。想象一条长的圆形路线(开始=结束),在这种情况下,路线内的所有点都将匹配正,无论光标距离该路线是2px还是400px。我在原来的文章中添加了一个可能但代价高昂的解决方案,该解决方案正在发挥作用。不,我不是说你要将最后一个点与第一个点连接起来,但例如,如果你有[0,1,2,3,4…n-1,n]个点代表你的多段线,那么你可以向后连接[n与n-1,n-1与n-2,…1与0]。我知道这不是一个优化的解决方案,但它是一个使用已知插件的快速修复。啊,感谢您的澄清。这可能会起作用,除了“问题”之外,这种方法没有考虑多段线的边距/权重,这会触发工具提示,使该功能更可用。我看到了传单pip插件(多边形中的点),但我认为这种方法存在以下问题:通过将最后一点与第一点连接,多边形覆盖了一个区域,我
var tooltipTimeout;
var routesFeatureGroup = L.featureGroup(routesGroup)
    .bindTooltip('', {sticky: true})
    .on('mousemove', function(e){
        clearTimeout(tooltipTimeout);

        tooltipTimeout = setTimeout(function(){
            // collect labels
            // ...
        },50);
    .on('mouseout', function(){
        clearTimeout(tooltipTimeout);
    })