В Leaflet маркер является базовой сущностью для отображения точечных
объектов на карте. Создание маркера выполняется через конструктор
L.marker, который принимает координаты в формате широты и
долготы.
const marker = L.marker([55.751244, 37.618423]);
Первый аргумент — массив координат [lat, lng]. Внутри
библиотеки координаты нормализуются и преобразуются в систему проекции
карты (обычно Web Mercator).
Маркер сам по себе не отображается на карте до тех пор, пока не будет добавлен в слой карты.
Для отображения маркера используется метод addTo(map)
либо классический способ через addLayer.
marker.addTo(map);
Альтернативный вариант:
map.addLayer(marker);
Разница между подходами заключается в архитектурной семантике:
addTo(map) — принадлежность объекта картеaddLayer(marker) — управление слоями карты как
коллекциейconst position = marker.getLatLng();
console.log(position.lat, position.lng);
Метод getLatLng() возвращает объект LatLng,
содержащий:
lat — широтаlng — долготаmarker.setLatLng([59.934280, 30.335099]);
Также можно передавать объект:
marker.setLatLng({ lat: 59.934280, lng: 30.335099 });
При изменении координат автоматически пересчитывается позиция на экране без необходимости перерисовки всей карты.
Конструктор L.marker принимает второй аргумент — объект
опций.
const marker = L.marker([55.75, 37.61], {
draggable: true,
opacity: 0.8,
zIndexOffset: 1000
});
draggable
opacity
zIndexOffset
autoPan
При включённой опции draggable: true становится доступен
набор событий и методов.
marker.dragging.enable();
marker.dragging.disable();
marker.on('dragstart', () => {
console.log('перетаскивание началось');
});
marker.on('drag', () => {
console.log('маркер движется');
});
marker.on('dragend', () => {
console.log('перетаскивание завершено');
});
События позволяют синхронизировать позицию маркера с внешними данными, например формами ввода координат.
Маркер по умолчанию использует стандартную иконку, но её можно
заменить через setIcon.
const customIcon = L.icon({
iconUrl: 'icon.png',
iconSize: [32, 32],
iconAnchor: [16, 32]
});
marker.setIcon(customIcon);
L.icon() — создание растровой иконкиL.divIcon() — HTML-иконка, создаваемая через DOMПример HTML-иконки:
const htmlIcon = L.divIcon({
html: '<div class="custom-marker"></div>',
className: 'custom-wrapper'
});
marker.setIcon(htmlIcon);
divIcon часто используется для динамических маркеров с
изменяемым содержимым.
marker.bindPopup('Текст всплывающего окна');
Метод bindPopup связывает маркер с окном, которое
открывается при клике.
marker.openPopup();
marker.closePopup();
Также возможно создание независимого popup:
const popup = L.popup().setContent('Информация');
marker.bindPopup(popup);
marker.bindPopup('Текст', {
maxWidth: 200,
closeButton: true,
autoClose: false
});
Tooltip отличается от popup тем, что отображается без клика (или при наведении).
marker.bindTooltip('Подсказка');
marker.openTooltip();
marker.closeTooltip();
marker.bindTooltip('Подсказка', {
direction: 'top',
permanent: false,
opacity: 0.9
});
Основные направления:
topbottomleftrightcenterМаркер поддерживает широкий набор событий, основанных на системе
Evented.
marker.on('click', () => {});
marker.on('mouseover', () => {});
marker.on('mouseout', () => {});
marker.on('add', () => {});
marker.on('remove', () => {});
function handler() {
console.log('click');
}
marker.on('click', handler);
marker.off('click', handler);
map.removeLayer(marker);
map.addLayer(marker);
map.hasLayer(marker);
marker.setZIndexOffset(500);
Это влияет на визуальное перекрытие маркеров при их наложении в одной точке.
marker.setOpacity(0.5);
Возвращение к полной видимости:
marker.setOpacity(1);
Вместо удаления и повторного создания можно обновлять свойства:
marker.setLatLng([60.0, 30.0])
.setOpacity(0.7)
.setIcon(customIcon);
Цепочка методов позволяет минимизировать количество операций над DOM и слоями карты.
Маркер может хранить произвольные данные:
marker.options.id = 123;
marker.options.type = 'shop';
Или через bindPopup с функцией:
marker.bindPopup(() => {
return `ID: ${marker.options.id}`;
});
marker.dragging && marker.dragging.enabled();
const mapInstance = marker._map;
(внутреннее свойство, используется с осторожностью при расширениях)
При большом количестве объектов стандартные маркеры становятся тяжёлыми для DOM. Используются методы оптимизации:
Базовый приём обновления набора маркеров:
markers.forEach(m => {
m.setLatLng(getNewCoords(m));
});
Маркер часто выступает связующим звеном между географией и прикладной логикой:
marker.on('click', () => {
fetch(`/api/point/${marker.options.id}`)
.then(r => r.json())
.then(data => marker.bindPopup(data.name).openPopup());
});
События позволяют строить реактивные интерфейсы без дополнительного слоя управления состоянием.
marker.remove();
Альтернативно:
map.removeLayer(marker);
После удаления объект остаётся в памяти, если на него есть ссылки, но перестаёт участвовать в рендеринге карты.