Google Maps V3:仅在视口中显示标记 - 清除标记问题

Thi*_*ijs 29 javascript google-maps google-maps-api-3 google-maps-markers

我喜欢使用谷歌地图创建一个可以处理大量标记(超过10,000)的地图.为了不减慢地图速度,我创建了一个XML文件,它只输出当前视口内的标记.

首先,我使用initialize()来设置地图选项:

function initialize() {
    var myLatlng = new google.maps.LatLng(51.25503952021694,3.27392578125);
    var myOptions = {
        zoom: 8,
        center: myLatlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

    google.maps.event.addListener(map, 'tilesloaded', function () {
    loadMapFromCurrentBounds(map);
    }); 
}
Run Code Online (Sandbox Code Playgroud)

当事件'tilesloaded'完成后,我使用loadMapFromCurrentBounds(),这个函数将获取当前边界并向XML文件发送请求以显示当前视口内的标记:

function loadMapFromCurrentBounds(map) {

    // First, determine the map bounds
    var bounds = map.getBounds();

    // Then the points
    var swPoint = bounds.getSouthWest();
    var nePoint = bounds.getNorthEast();

    // Now, each individual coordinate
    var swLat = swPoint.lat();
    var swLng = swPoint.lng();
    var neLat = nePoint.lat();
    var neLng = nePoint.lng();

    downloadUrl("mapsxml.php?swLat="+swLat+"&swLng="+swLng+"&neLat="+neLat+"&neLng="+neLng+"", function(data) {
        var xml = parseXml(data);
        var markers = xml.documentElement.getElementsByTagName("marker");
        var infoWindow = new google.maps.InfoWindow; 

        for (var i = 0; i < markers.length; i++) {
            var address = markers[i].getAttribute("address");
            var type = markers[i].getAttribute("type");
            var name = markers[i].getAttribute("name");

            var point = new google.maps.LatLng( 
            parseFloat(markers[i].getAttribute("lat")),
            parseFloat(markers[i].getAttribute("lng"))
            );

            var html = "<b>" + name + "</b> <br/>" + address;
            var icon = customIcons[type] || {};

            var marker = new google.maps.Marker({
            map: map,
            position: point,
            icon: icon.icon,
            shadow: icon.shadow});

            bindInfoWindow(marker, map, infoWindow, html);
        }
    })
}
Run Code Online (Sandbox Code Playgroud)

这工作得很好,但是,当前代码不会卸载不再出现在视口中的标记.除此之外,它再次加载已经加载的标记,当在同一区域中移动地图查看时间时,会非常快地减慢地图的速度.

因此,当视口发生变化时,我希望在加载新标记之前先清除整个地图.做这个的最好方式是什么?

Pau*_*ens 15

您需要向地图添加另一个事件侦听器:

google.maps.event.addListener(map,'bounds_changed', removeMarkers);
Run Code Online (Sandbox Code Playgroud)

有关从谷歌地图中删除所有标记的更多信息,请参阅此处 - 不幸的是,我不认为可以通过一次调用完成.所以你必须编写removeMarkers或类似的东西,它们必须遍历地图上的所有标记,逐个删除它们,如下所示:

 markersArray[i].setMap(null);
Run Code Online (Sandbox Code Playgroud)

我不知道在使用以下方法删除之前检查标记是否在视口中是否更快:

 map.getBounds();
Run Code Online (Sandbox Code Playgroud)

阅读有关Google Map API v3事件的更多信息

  • 另外,如果你只是稍微移动一下地图,也就是说,如果你的移动不会导致新的图块被加载到视口中,那么tileloaded可能不会触发 (2认同)

Cra*_*gma 6

您可能想要查看此主题.丹尼尔很好地回答了这个问题.

从gps文件在谷歌地图上创建路线的最有效方法是什么?

此外,bounds_changed是第一次调用函数的机会.tilesloaded,将不断调用.视口可能包含多个图块以填充视口.

或者,您也可以执行setVisible(false).

要删除标记,您可能需要删除侦听器.

google.maps.event.clearInstanceListeners(marker);
marker.setMap(null);
markers.remove(marker);
delete marker;
Run Code Online (Sandbox Code Playgroud)


web*_*kie 5

本文对此进行了很好的介绍:\n在 Google 地图中动态加载数千个标记

\n\n
\n
    \n
  • 动态加载标记,直到达到阈值
  • \n
  • 保留已添加标记的哈希表
  • \n
  • 达到阈值后,删除当前位于视口内的\xe2\x80\x99t 标记
  • \n
  • 当用户缩小时从地图中删除所有标记,并且在用户缩放回合理级别之前不加载任何标记
  • \n
\n
\n

  • 试试这个链接http://xyzzyb.tumblr.com/post/10317033064/dynamically-loading-thousands-of-markers-in-google-maps (3认同)

小智 5

由于使用'tilesloaded'或'bounds_changed'的以下解释将是非常错误的并且导致不愿意连续发射.相反,你会想要使用'idle'事件,一旦用户停止平移/缩放就会触发该事件.

google.maps.event.addListener(map,'idle',loadMapFromCurrentBounds);

https://developers.google.com/maps/articles/toomanymarkers#viewportmarkermanagement