Карты Google V3: показывать только маркеры в окне просмотра - очистить маркеры
Мне нравится создавать карту с Google Maps, которая может обрабатывать большое количество маркеров (более 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);
});
}
Когда событие "patchloaded" закончено, я использую 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);
}
})
}
Это отлично работает, однако текущий код не разгружает маркеры, которые больше не находятся в окне просмотра. Кроме того, он снова загружает маркеры, которые уже загружены, что очень быстро замедляет работу карты при перемещении карты в режиме просмотра в той же области.
Поэтому, когда изменяется окно просмотра, мне нравится сначала очистить всю карту, прежде чем загружать новые маркеры. Каков наилучший способ сделать это?
Ответы
Ответ 1
Вам нужно добавить еще один Event Listener к карте:
google.maps.event.addListener(map,'bounds_changed', removeMarkers);
Подробнее см. здесь для удаления всех маркеров с карты Google. К сожалению, я не думаю, что это можно сделать с помощью одного вызова. Таким образом, вам придется писать removeMarkers или что-то подобное, которое должно будет проходить через все маркеры на карте, удаляя их отдельно:
markersArray[i].setMap(null);
Я не знаю, быстрее ли проверять, находится ли маркер в окне просмотра, перед удалением с помощью:
map.getBounds();
Подробнее о событиях Google Map API v3
Ответ 2
Вы можете проверить эту тему. Даниэль ответил на это довольно хорошо.
Каков наиболее эффективный способ создания маршрутов на картах google из gps файлов?
Кроме того, bounds_changed - это первая возможность вызвать вашу функцию. которые будут вызываться постоянно. Видовое окно может содержать более одной плитки для заполнения области просмотра.
В качестве альтернативы вы также можете сделать setVisible (false).
Чтобы удалить маркер, вам может потребоваться удалить слушателей.
google.maps.event.clearInstanceListeners(marker);
marker.setMap(null);
markers.remove(marker);
delete marker;
Ответ 3
Из-за следующих объяснений с использованием "patchloaded" или "bounds_changed" было бы очень неправильно и вызвать нежелательные непрерывные стрельбы. Вместо этого вы захотите использовать событие "idle", которое будет срабатывать, когда пользователь остановит панорамирование/масштабирование.
google.maps.event.addListener(карта, 'idle', loadMapFromCurrentBounds);
https://developers.google.com/maps/articles/toomanymarkers#viewportmarkermanagement
Ответ 4
Эта статья проходит через это довольно красиво:
Динамическая загрузка тысяч маркеров в Картах Google
- динамически загружать маркеры, пока мы не достигнем порога
- сохранить хэш-таблицу уже добавленных маркеров
- после достижения порогового значения удалите маркеры, которые в настоящее время находятся в пределах области просмотра.
- удалите все маркеры с карты, когда пользователь уменьшил масштаб, и не загружайте маркеры до тех пор, пока пользователь не достигнет разумного уровня.
Ответ 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)).