29

我喜欢使用可以处理大量标记(超过 10.000 个)的 Google 地图创建地图。为了不减慢地图的速度,我创建了一个 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);
    }); 
}

当事件 '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);
        }
    })
}

这很好用,但是,当前代码不再卸载不在视口中的标记。除此之外,它会再次加载已加载的标记,这在将地图移动到同一区域的视图时间时会非常快地减慢地图速度。

所以当视口发生变化时,我喜欢在加载新标记之前先清除整个地图。做这个的最好方式是什么?

4

6 回答 6

17

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

google.maps.event.addListener(map,'bounds_changed', removeMarkers);

有关从谷歌地图中删除所有标记的更多信息,请参见此处- 不幸的是,我认为它不能通过一个电话来完成。所以你必须编写 removeMarkers 或类似的东西,它必须遍历地图上的所有标记,像这样单独删除它们:

 markersArray[i].setMap(null);

我不知道在删除之前检查标记是否在视口中是否更快:

 map.getBounds();

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

于 2010-06-01T10:01:41.333 回答
6

你可能想看看这个线程。丹尼尔很好地回答了这个问题。

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

此外, bounds_changed 是调用您的函数的第一个机会。瓦片加载,将被不断调用。视口可能包含多个图块来填充视口。

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

为了删除标记,您可能需要删除侦听器。

google.maps.event.clearInstanceListeners(marker);
marker.setMap(null);
markers.remove(marker);
delete marker;
于 2010-07-20T19:24:13.647 回答
6

由于以下解释,使用 'tilesloaded' 或 'bounds_changed' 将是非常错误的,并导致不情愿的连续射击。相反,您可能希望使用“空闲”事件,一旦用户停止平移/缩放,该事件就会触发。

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

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

于 2013-11-22T11:00:15.843 回答
4

这篇文章很好地完成了它: 在谷歌地图中动态加载数千个标记

  • 动态加载标记,直到达到阈值
  • 保留已添加的标记的哈希表
  • 达到阈值后,删除当前不在视口内的标记
  • 当用户缩小时从地图中删除所有标记,并且在用户缩小到合理水平之前不要加载任何标记
于 2012-04-20T11:52:43.037 回答
2

您的原始功能似乎有很多代码。我会做这样的事情:

if( map.getBounds().contains(markers[i].getPosition()) ) {
   myMarkerDisplayFunction(markers[i]);
}
于 2012-07-23T23:57:14.463 回答
0

您可能想从Google查看此文档。它解释了你需要什么:

With the new list of markers you can remove the current markers 
(marker.setMap(null)) that are on the map and 
add the new ones (marker.setMap(map)).
于 2013-02-27T05:31:49.273 回答