Создание простых маркеров

В Leaflet маркер представляет собой объект, отображающий точку на карте в заданных географических координатах. Он создаётся через конструктор L.marker() и является частью слоя (layer), который может быть добавлен на карту через метод addTo() или addLayer().

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

Базовая форма создания маркера выглядит следующим образом:

const marker = L.marker([51.505, -0.09]).addTo(map);

Первый аргумент — массив координат [lat, lng], где:

  • lat — широта (latitude)
  • lng — долгота (longitude)

Объект map представляет собой экземпляр карты, созданный через L.map().


Привязка маркера к карте

Маркер сам по себе не отображается до момента добавления в карту. В Leaflet существует несколько способов его интеграции в слой карты.

Использование addTo()

L.marker([51.5, -0.09]).addTo(map);

Метод добавляет маркер непосредственно в указанную карту.

Использование addLayer()

const marker = L.marker([51.5, -0.09]);
marker.addLayer(map);

Оба подхода приводят к одному результату, однако addTo() используется чаще благодаря компактности записи.


Настройки маркера при создании

Конструктор L.marker() поддерживает второй параметр — объект опций, позволяющий управлять поведением и внешним видом.

const marker = L.marker([51.505, -0.09], {
  title: 'Точка интереса',
  opacity: 0.9,
  riseOnHover: true
}).addTo(map);

Основные параметры:

  • title — текст всплывающей подсказки при наведении
  • opacity — прозрачность маркера (0–1)
  • riseOnHover — подъём маркера поверх других при наведении
  • draggable — возможность перетаскивания
  • autoPan — автоматическое смещение карты при выходе маркера за границы видимой области

Перетаскиваемые маркеры

Leaflet поддерживает интерактивное перемещение маркеров, что полезно в задачах редактирования геоданных.

const marker = L.marker([51.505, -0.09], {
  draggable: true
}).addTo(map);

После включения draggable маркер можно перемещать мышью. Положение обновляется автоматически.

Для обработки событий перемещения используется система событий Leaflet:

marker.on('dragend', function (event) {
  const position = event.target.getLatLng();
  console.log(position.lat, position.lng);
});

Получение и изменение координат

Маркер хранит своё текущее положение в объекте LatLng.

Получение координат

const position = marker.getLatLng();

Результат имеет структуру:

{
  lat: 51.505,
  lng: -0.09
}

Обновление позиции

marker.setLatLng([51.51, -0.1]);

Изменение координат мгновенно отражается на карте без необходимости пересоздания объекта.


Привязка всплывающих окон

Одной из основных функций маркеров является отображение информации через popup.

marker.bindPopup("Точка интереса");

Popup открывается при клике на маркер. Содержимое может включать HTML:

marker.bindPopup("<b>Объект</b><br>Описание точки");

Также возможно программное управление:

marker.openPopup();
marker.closePopup();

Обработка событий маркера

Маркер поддерживает стандартную систему событий Leaflet.

Основные события:

  • click — нажатие
  • mouseover — наведение
  • mouseout — уход курсора
  • dragstart — начало перетаскивания
  • dragend — завершение перетаскивания

Пример обработки клика:

marker.on('click', function () {
  console.log('Маркер активирован');
});

Пример обработки наведения:

marker.on('mouseover', function () {
  marker.bindPopup('Информация').openPopup();
});

Массовое создание маркеров

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

const points = [
  [51.5, -0.09],
  [51.51, -0.1],
  [51.49, -0.08]
];

points.forEach(coords => {
  L.marker(coords).addTo(map);
});

Для более сложных структур данных часто применяются массивы объектов:

const places = [
  { name: 'A', coords: [51.5, -0.09] },
  { name: 'B', coords: [51.51, -0.1] }
];

places.forEach(place => {
  L.marker(place.coords)
    .bindPopup(place.name)
    .addTo(map);
});

Управление группами маркеров

При большом количестве точек используется группировка через LayerGroup.

const group = L.layerGroup().addTo(map);

L.marker([51.5, -0.09]).addTo(group);
L.marker([51.51, -0.1]).addTo(group);

Группа позволяет управлять всеми маркерами одновременно:

group.clearLayers();

Взаимодействие с масштабированием карты

Маркер автоматически адаптируется к изменению масштаба, так как привязан к географическим координатам, а не к пикселям.

При перемещении карты положение маркера пересчитывается системой рендеринга Leaflet без дополнительного кода.


Производительность при большом количестве маркеров

При тысячах точек стандартные маркеры начинают снижать производительность из-за DOM-элементов.

Типичные подходы оптимизации:

  • использование LayerGroup
  • кластеризация через MarkerCluster
  • замена маркеров на canvas-слои

Кластеризация реализуется через сторонние расширения и позволяет объединять близкие точки в один визуальный элемент до увеличения масштаба.


Пользовательские свойства маркера

Маркер может хранить произвольные данные через привязку к объекту:

const marker = L.marker([51.5, -0.09], {
  customId: 42,
  type: 'restaurant'
});

Доступ к этим данным осуществляется через options:

console.log(marker.options.customId);

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

Удаление маркера выполняется через метод remove():

marker.remove();

или через карту:

map.removeLayer(marker);

После удаления объект перестаёт участвовать в рендеринге и обработке событий.


Повторное использование маркера

Маркер можно временно убирать и возвращать на карту без пересоздания:

map.removeLayer(marker);
map.addLayer(marker);

Это позволяет эффективно управлять динамическими наборами точек.


Базовая структура взаимодействия

Типичный цикл работы с маркером включает:

  1. Создание через координаты
  2. Добавление в карту
  3. Привязку событий или popup
  4. Возможное обновление координат
  5. Удаление или повторное использование
const marker = L.marker([51.505, -0.09])
  .addTo(map)
  .bindPopup('Точка');

marker.on('click', () => {
  marker.setLatLng([51.51, -0.1]);
});