【问题标题】:openPopup() in leaflet map using custom link click使用自定义链接单击传单地图中的 openPopup()
【发布时间】:2017-02-07 03:08:10
【问题描述】:

我正在尝试触发传单地图中的标记弹出窗口,但没有运气。我正在使用集群图,它可以正常工作并在用户单击标记时打开弹出窗口。我需要扩展这个,例如通过 url 传递参数并在页面加载时根据 url 参数值打开特定标记。我正在使用以下代码进行地图聚类。

        var latlng = L.latLng(-30.81881, 116.16596);
    var map = L.map('lmap', { center: latlng, zoom: 6 });
    var lcontrol = new L.control.layers();
    var eb = new L.control.layers();


    //clear map first
    clearMap();
    //resize the map
    map.invalidateSize(true);
    //load the map once all layers cleared
    loadMap();
    //reset the map size on dom ready
    map.invalidateSize(true);
function loadMap() {

        var markers_array = [];

        var roadMutant = L.gridLayer.googleMutant({
            type: 'roadmap' // valid values are 'roadmap', 'satellite', 'terrain' and 'hybrid'
        }).addTo(map);


        //add the control on the map

       lcontrol= L.control.layers({
            Roadmap: roadMutant

        }, {}, {
            collapsed: false
        }).addTo(map);

    var markers = L.markerClusterGroup({chunkedLoading: true, spiderfyOnMaxZoom: true, maxClusterRadius: 80, showCoverageOnHover: true });

    //clear markers and remove all layers
    markers.clearLayers();


    $.ajax({
        type: "GET",
        url: appUrl + "/Home/map", 
        data: {'atype': st},
        dataType: 'json',
        contentType: 'application/x-www-form-urlencoded',
        success: function (data) {

            $.each(data, function (i, item) {
                var img = (item.IconUrl).replace("~", "");
                var Icon = L.icon({ iconUrl: img, iconSize: [42, 42] });

                var marker = L.marker(L.latLng(item.Latitude, item.Longitude), { icon: Icon }, { title: item.Name });
                var content = "<div class='infoDiv'><h3><img src='" + appUrl + img + "' width='24' />" + item.Name + "</h3><p>" + item.Title + "</p><a href='#' data-value='" + item.AlertId + "' class='btn btn-success btn-sm alertInfo' data-toggle='modal' data-target='#alertDetails'>Details</a></div>";
                marker.bindPopup(content);
                markers.addLayer(marker);
                //add the marker to array
                markers_array.push(marker);

            });

        }

    })
   .done(function () {
       $(".loadingOverlay").hide();
       map.invalidateSize(true);
   });

    //add the markers to the map
   map.addLayer(markers);

}

我尝试实现以下自定义点击事件,但没有成功。

function markerFunction(id) {
       alert(markers_array.length);

       for (var i = 0; i < markers.length; ++i) {
           var mid = markers_array[i]["_leaflet_id"];

           if (mid == id) {
                alert("opening " + id);
               map.markers(id).openPopup();

               }
           }
          }
    //trigger on link click
   $("a").click(function () {
       var id = $(this).attr("id");
       alert(id);
       markerFunction(id);

   });

非常感谢您的帮助。提前致谢。

【问题讨论】:

  • 参见 GIS SE 上的 Zoom to and Spiderfy MarkerClusterGroup, open popup of target marker(但省略了 spiderfy 部分)
  • 感谢您的帮助。我已经尝试过了,但它不起作用。 code var target = markers.getLayer(markers_array[id]) markers.zoomToShowLayer(target, function () { target.openPopup(); })
  • 请确保您首先尽可能多地调试您的代码。编辑您的问题,而不是在评论中发布代码。如果可能,请在在线编辑工具上重现您的问题,使用SO built-in code snippet、Plunker、JSFiddle、JSBin 等。所有这些都将帮助您更快地获得支持,如果不能让您自己找到解决方案。

标签: javascript jquery google-maps leaflet markerclusterer


【解决方案1】:

loadMap() 异步获取其数据。任何与该数据(或从该数据派生的任何东西)一起工作的东西都必须以考虑到异步性的方式进行,通常在链式.then() 中。

就目前而言,标记是异步创建的,但点击处理程序是独立定义和附加的。通过从loadMap() 返回的承诺传递markers_array(和markers?)将允许在附加点完全填充必要的标记数据并带入点击处理程序的范围。

我会这样写:

var latlng = L.latLng(-30.81881, 116.16596);
var map = L.map('lmap', { center: latlng, zoom: 6 });
var lcontrol = new L.control.layers(); // necessary?
var eb = new L.control.layers(); // necessary?

clearMap(); // why, it's only just been created?
map.invalidateSize(true);
loadMap(map).then(function(obj) {
    $(".loadingOverlay").hide();
    map.invalidateSize(true); // again?

    $("a").click(function(e) { // jQuery selector probably needs to be more specific
        e.preventDefault();
        var id = $(this).attr('id');
        for(var i=0; i<obj.markers_array.length; ++i) {
            if(obj.markers_array[i]._leaflet_id == id) {
                map.markers(id).openPopup(); // if `map.markers` is correct, maybe you don't need obj.markers?
                break; // break out of `for` loop on success.
            }
        }
    });
    return obj;
});

function loadMap(map) {
    var roadMutant = L.gridLayer.googleMutant({ type: 'roadmap' }).addTo(map);
    var lcontrol = L.control.layers({Roadmap: roadMutant}, {}, {collapsed: false}).addTo(map);

    return $.ajax({
        type: 'GET',
        url: appUrl + '/Home/map', 
        data: {'atype': st},
        dataType: 'json',
        contentType: 'application/x-www-form-urlencoded'
    }).then(function (data) {
        var markers = L.markerClusterGroup({chunkedLoading: true, spiderfyOnMaxZoom: true, maxClusterRadius: 80, showCoverageOnHover: true });
        markers.clearLayers();
        var markers_array = $.map(data, function(item) {
            var img = (item.IconUrl).replace("~", "");
            var Icon = L.icon({ iconUrl: img, iconSize: [42, 42] });
            var marker = L.marker(L.latLng(item.Latitude, item.Longitude), { icon: Icon }, { title: item.Name });
            var content = "<div class='infoDiv'><h3><img src='" + appUrl + img + "' width='24' />" + item.Name + "</h3><p>" + item.Title + "</p><a href='#' data-value='" + item.AlertId + "' class='btn btn-success btn-sm alertInfo' data-toggle='modal' data-target='#alertDetails'>Details</a></div>";
            marker.bindPopup(content);
            markers.addLayer(marker);
            return marker;
        });
        map.addLayer(markers); //add the markers to the map
        // If both 'markers_array' and 'markers' are needed later, then bundle them into an object.
        // If not, then simply return one or other of those variables.
        return {
            'markers_array': markers_array,
            'markers': markers
        };
    });
}

细节需要检查,但整体模式应该是正确的。

【讨论】:

  • 您好 Roamer,非常感谢您的帮助。当我尝试obj.markers(id).openPopup(); 时,我在调试窗口中收到TypeError: t.markers is not a function 我错过了什么。
  • 那是我不确定的。试试obj.markers_array[i].openPopup();
  • 再次感谢,我已经尝试过同样的错误。无论如何,我想出了替代解决方案。
  • 查看文档,您不应该同时需要markersmarkers_array,因为可以使用markers.getAllChildMarkers() 获得数组(如果需要)。因此,只需从 loadMap 的内部函数return markers 并相应地调整loadMap(map).then(...)(期望markers 而不是obj)。在那之后,它可能就像markers.getLayer(id).openPopup() 一样简单——很难说——文档有点模糊。
  • 我很想知道您的替代解决方案是什么。
【解决方案2】:

在这方面花了太多时间之后,我想出了一个不同的方法。通过 URL 将参数作为哈希 (#) 值传递。使用 jQuery 选择器获取值并获取该记录的数据,然后在地图上打开弹出窗口。这是我的第二个代码块 -

$(function () {
           var hash = window.location.hash.substr(1);// "90aab585-1641-43e9-9979-1b53d6118faa";
           
           if (!hash) return false;
          
           //show loading
           $(".loadingOverlay").show();


           $.ajax({
               type: "GET",
               url: appUrl + "/Home/GetAlert/"+hash, 
               dataType: 'json',
               contentType: 'application/x-www-form-urlencoded',
               success: function (data) {
                   if (!data.status)
                   {
                       $('#msg').html(data.message).attr("class","alert alert-warning");
                       $(".loadingOverlay").hide();
                       return false;
                   }
                   $.each(data.message, function (i, item) {
                      
                       var popupLoc = new L.LatLng(item.Latitude, item.Longitude);
                       var popupContent = "<div class='infoDiv'><h3><img src='" + appUrl + img + "' width='24' />" + item.Name + "</h3><p>" + item.Title + "</p><a href='#' data-value='" + item.AlertId + "' class='btn btn-success btn-sm alertInfo' data-toggle='modal' data-target='#alertDetails'>Details</a></div>";

                       //initialize the popup;
                     var popup = new L.Popup();
                       //set latlng
                       popup.setLatLng(popupLoc);
                       //set content
                       popup.setContent(popupContent);
                       map.setView(new L.LatLng(item.Latitude, item.Longitude), 8);
                      //display popup
                       map.addLayer(popup);
                      
                   });

               }

           })
       .done(function () {
           $(".loadingOverlay").hide();        
           map.invalidateSize(true);
       });
          
       });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 2016-10-05
    • 1970-01-01
    相关资源
    最近更新 更多