Подтвердить что ты не робот

Карты 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);
        }
    })
}

Это отлично работает, однако текущий код не разгружает маркеры, которые больше не находятся в окне просмотра. Кроме того, он снова загружает маркеры, которые уже загружены, что очень быстро замедляет работу карты при перемещении карты в режиме просмотра в той же области.

Поэтому, когда изменяется окно просмотра, мне нравится сначала очистить всю карту, прежде чем загружать новые маркеры. Каков наилучший способ сделать это?

4b9b3361

Ответ 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)).