Удаление маркеров с карты

Маркеры являются одним из наиболее часто используемых объектов в Google Maps JavaScript API. Они применяются для отображения точек интереса, адресов, результатов поиска, объектов недвижимости, транспортных средств и множества других сущностей. В процессе работы приложения нередко возникает необходимость удалять маркеры с карты.

Удаление маркеров используется в следующих ситуациях:

  • обновление результатов поиска;
  • фильтрация отображаемых объектов;
  • очистка карты перед загрузкой новых данных;
  • динамическое изменение интерфейса;
  • удаление временных меток пользователя;
  • оптимизация производительности при большом количестве объектов.

Важно понимать различие между удалением маркера с карты и удалением самого объекта маркера из памяти.


Скрытие маркера через setMap(null)

Основным способом удаления маркера с карты является передача значения null в метод setMap().

Пример создания маркера:

const marker = new google.maps.Marker({
    position: {
        lat: 55.751244,
        lng: 37.618423
    },
    map: map,
    title: "Москва"
});

Удаление с карты:

marker.setMap(null);

После выполнения данной команды:

  • маркер перестает отображаться;
  • карта больше не управляет этим объектом;
  • экземпляр маркера продолжает существовать в памяти.

Скрытый маркер можно вернуть обратно.

marker.setMap(map);

Такой подход особенно полезен, когда предполагается повторное использование объекта.


Разница между скрытием и уничтожением маркера

Рассмотрим пример:

const marker = new google.maps.Marker({
    position: { lat: 55.75, lng: 37.61 },
    map: map
});

Удаление с карты:

marker.setMap(null);

Объект все еще существует:

console.log(marker.getPosition());

Если необходимо полностью избавиться от маркера, обычно удаляют ссылку на него:

marker.setMap(null);
marker = null;

Однако объявление через const не позволит присвоить новое значение.

Правильный вариант:

let marker = new google.maps.Marker({
    position: { lat: 55.75, lng: 37.61 },
    map: map
});

marker.setMap(null);
marker = null;

После удаления всех ссылок сборщик мусора JavaScript сможет освободить память.


Удаление маркера по событию

Часто удаление происходит после взаимодействия пользователя с объектом.

Например, удаление по клику на маркер:

const marker = new google.maps.Marker({
    position: {
        lat: 55.75,
        lng: 37.61
    },
    map: map
});

marker.addListener("click", () => {
    marker.setMap(null);
});

После нажатия маркер исчезнет с карты.


Удаление нескольких маркеров

В большинстве приложений используется не один, а множество маркеров.

Для их хранения обычно применяется массив.

Создание массива:

const markers = [];

Добавление маркеров:

locations.forEach(location => {
    const marker = new google.maps.Marker({
        position: location,
        map: map
    });

    markers.push(marker);
});

Удаление всех маркеров:

for (let i = 0; i < markers.length; i++) {
    markers[i].setMap(null);
}

Более современный вариант:

markers.forEach(marker => {
    marker.setMap(null);
});

Все объекты будут скрыты одновременно.


Функция очистки карты

При работе с большим количеством объектов удобно вынести очистку в отдельную функцию.

function clearMarkers() {
    markers.forEach(marker => {
        marker.setMap(null);
    });
}

Использование:

clearMarkers();

Такой подход делает код более читаемым и удобным для сопровождения.


Полное удаление массива маркеров

После удаления объектов с карты массив может по-прежнему содержать ссылки на них.

Пример:

function clearMarkers() {
    markers.forEach(marker => {
        marker.setMap(null);
    });
}

После выполнения:

console.log(markers.length);

Количество элементов останется прежним.

Для полного удаления ссылок:

function deleteMarkers() {
    markers.forEach(marker => {
        marker.setMap(null);
    });

    markers.length = 0;
}

Либо:

markers.splice(0, markers.length);

Или:

markers = [];

Последний вариант возможен только если массив объявлен через let.


Удаление части маркеров

Нередко требуется удалить не все объекты, а только определенную группу.

Пример удаления первого маркера:

markers[0].setMap(null);

Удаление по индексу:

const index = 3;

markers[index].setMap(null);

markers.splice(index, 1);

Удаление происходит в два этапа:

  1. Маркер убирается с карты.
  2. Ссылка удаляется из массива.

Удаление маркеров по условию

Предположим, что каждый маркер содержит дополнительные данные.

const marker = new google.maps.Marker({
    position: location.position,
    map: map
});

marker.category = location.category;

Удаление всех маркеров определенной категории:

markers.forEach(marker => {
    if (marker.category === "restaurant") {
        marker.setMap(null);
    }
});

Можно одновременно удалить их из массива:

for (let i = markers.length - 1; i >= 0; i--) {
    if (markers[i].category === "restaurant") {
        markers[i].setMap(null);
        markers.splice(i, 1);
    }
}

Обход массива с конца предотвращает проблемы со смещением индексов.


Удаление старых результатов поиска

Один из наиболее распространенных сценариев.

Допустим, пользователь выполняет новый поиск объектов.

Перед добавлением новых маркеров необходимо очистить старые.

function performSearch() {

    markers.forEach(marker => {
        marker.setMap(null);
    });

    markers.length = 0;

    searchResults.forEach(result => {

        const marker = new google.maps.Marker({
            position: result.location,
            map: map
        });

        markers.push(marker);
    });
}

Подобная схема широко применяется в картах недвижимости, каталогах организаций и туристических сервисах.


Удаление маркеров при смене масштаба

Иногда определенные объекты должны отображаться только на крупных масштабах.

map.addListener("zoom_changed", () => {

    const zoom = map.getZoom();

    markers.forEach(marker => {

        if (zoom < 10) {
            marker.setMap(null);
        } else {
            marker.setMap(map);
        }

    });

});

При уменьшении масштаба карта автоматически очищается от лишних объектов.


Удаление маркеров при смене границ карты

Google Maps позволяет получать текущую область просмотра.

map.addListener("idle", () => {

    const bounds = map.getBounds();

    markers.forEach(marker => {

        if (!bounds.contains(marker.getPosition())) {
            marker.setMap(null);
        }

    });

});

В результате отображаются только маркеры внутри видимой области.

Такой подход особенно полезен при работе с тысячами объектов.


Удаление маркеров через пользовательский интерфейс

Часто очистка карты привязывается к кнопке.

HTML:

<button id="clear-map">
    Очистить карту
</button>

Jav * aScript:

document
    .getElementById("clear-map")
    .addEventListener("click", () => {

        markers.forEach(marker => {
            marker.setMap(null);
        });

        markers.length = 0;

    });

После нажатия все маркеры будут удалены.


Работа с AdvancedMarkerElement

В новых версиях Google Maps рекомендуется использовать AdvancedMarkerElement.

Создание:

const marker = new google.maps.marker.AdvancedMarkerElement({
    map: map,
    position: {
        lat: 55.75,
        lng: 37.61
    }
});

Удаление выполняется аналогичным образом:

marker.map = null;

Возврат на карту:

marker.map = map;

Принцип работы остается тем же: объект скрывается, но продолжает существовать в памяти.


Частые ошибки

Удаление только из массива

Неправильно:

markers.splice(index, 1);

Маркер исчезнет из массива, но останется на карте.

Правильно:

markers[index].setMap(null);
markers.splice(index, 1);

Очистка массива без удаления объектов

Неправильно:

markers.length = 0;

Маркеры продолжат отображаться.

Правильно:

markers.forEach(marker => {
    marker.setMap(null);
});

markers.length = 0;

Создание дубликатов после нового поиска

Неправильно:

searchResults.forEach(result => {
    createMarker(result);
});

Каждый новый поиск будет добавлять новые объекты поверх старых.

Правильно:

clearMarkers();

searchResults.forEach(result => {
    createMarker(result);
});

Потеря ссылки на маркер

Неправильно:

marker = null;

Если до этого не был вызван:

marker.setMap(null);

объект может продолжать отображаться на карте.

Правильная последовательность:

marker.setMap(null);
marker = null;

Рекомендуемая архитектура управления маркерами

Для крупных проектов удобно централизовать работу с маркерами.

let markers = [];

function addMarker(position) {

    const marker = new google.maps.Marker({
        position,
        map
    });

    markers.push(marker);
}

function clearMarkers() {

    markers.forEach(marker => {
        marker.setMap(null);
    });
}

function deleteMarkers() {

    clearMarkers();

    markers = [];
}

Подобная структура позволяет:

  • легко очищать карту;
  • предотвращать утечки памяти;
  • быстро обновлять результаты поиска;
  • централизованно управлять всеми объектами;
  • упрощать поддержку и развитие приложения.