Google Maps V3:仅在视口中显示标记 - 清除标记问题
Posted
技术标签:
【中文标题】Google Maps V3:仅在视口中显示标记 - 清除标记问题【英文标题】:Google Maps V3: Only show markers in viewport - Clear markers issue 【发布时间】:2011-02-25 23:22:05 【问题描述】:我喜欢使用可以处理大量标记(超过 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);
)
这很好用,但是,当前代码不再卸载不在视口中的标记。除此之外,它会再次加载已经加载的标记,这在将地图移动到同一区域的视图时间时会非常快地减慢地图速度。
所以当视口发生变化时,我喜欢在加载新标记之前先清除整个地图。最好的方法是什么?
【问题讨论】:
嘿@jeff,感谢编辑!我只是想让您知道,您实际上可以通过添加javascript
标记,使用出现在右侧的“编辑标记”链接,将语法突出显示添加到问题的答案中标签。祝你好运! :)
Marker Clusterer 在处理这么多标记时可能很有用。
您可以通过 map.getBounds().toUrlValue().split(',')
保存上面的几行代码,并为您的角落提供一个不错的数组。
【参考方案1】:
您需要向地图添加另一个事件侦听器:
google.maps.event.addListener(map,'bounds_changed', removeMarkers);
请参阅here 了解有关从谷歌地图中删除所有标记的更多信息 - 不幸的是,我认为这不能通过一个电话来完成。所以你将不得不编写 removeMarkers 或类似的东西,它必须遍历地图上的所有标记,像这样单独删除它们:
markersArray[i].setMap(null);
我不知道在删除之前检查标记是否在视口中是否更快:
map.getBounds();
Read more about Google Map API v3 events
【讨论】:
感谢您的回复!为什么我必须使用'bounds_changed'?我现在使用的事件监听器('Tilesloaded')似乎做同样的事情,每次视口改变时调用函数 loadMapFromCurrentBounds()。我试过markersArray[i].setMap(null);但它不起作用。除此之外,我喜欢只清除不再出现在视口中的标记的解决方案......我将在今晚晚些时候尝试上传一个示例! 另外,如果您只是稍微移动地图,即如果您的移动不会导致新的图块被加载到视口中,tilesloaded 可能不会触发【参考方案2】:您可能想查看此线程。丹尼尔很好地回答了这个问题。
What's the most efficient way to create routes on google maps from gps files?
此外,bounds_changed 是调用您的函数的第一个机会。瓦片加载,将被不断调用。视口可能包含多个图块来填充视口。
或者,您也可以执行 setVisible(false)。
为了移除标记,您可能需要移除监听器。
google.maps.event.clearInstanceListeners(marker);
marker.setMap(null);
markers.remove(marker);
delete marker;
【讨论】:
【参考方案3】:由于以下解释,使用 'tilesloaded' 或 'bounds_changed' 将是非常错误的,并且会导致不情愿的连续射击。相反,您可能希望使用“空闲”事件,一旦用户停止平移/缩放,该事件就会触发。
google.maps.event.addListener(map, 'idle', loadMapFromCurrentBounds);
https://developers.google.com/maps/articles/toomanymarkers#viewportmarkermanagement
【讨论】:
【参考方案4】:这篇文章很好地介绍了它: Dynamically loading thousands of markers in Google Maps
动态加载标记,直到达到阈值 保留已添加标记的哈希表 达到阈值后,移除当前不在视口内的标记 当用户缩小地图时从地图上移除所有标记,并且在用户缩小到合理水平之前不要加载任何标记
【讨论】:
试试这个链接xyzzyb.tumblr.com/post/10317033064/…【参考方案5】:您的原始函数似乎有很多代码。我会做这样的事情:
if( map.getBounds().contains(markers[i].getPosition()) )
myMarkerDisplayFunction(markers[i]);
【讨论】:
【参考方案6】:您可能想从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)).
【讨论】:
以上是关于Google Maps V3:仅在视口中显示标记 - 清除标记问题的主要内容,如果未能解决你的问题,请参考以下文章