Viewport — это видимая область карты, отображаемая внутри контейнера. Управление viewport является одной из ключевых задач при разработке картографических интерфейсов. Именно viewport определяет:
В Leaflet управление viewport осуществляется через объект карты
(L.Map) и набор специализированных методов.
При создании карты обычно задаются начальный центр и масштаб:
const map = L.map('map').setView([55.751244, 37.618423], 10);
Здесь:
55.751244 — широта;37.618423 — долгота;10 — уровень масштабирования.Метод setView() одновременно изменяет центр карты и
масштаб.
Для получения координат центра используется метод
getCenter():
const center = map.getCenter();
console.log(center.lat);
console.log(center.lng);
Результат представляет собой объект типа LatLng:
{
lat: 55.751244,
lng: 37.618423
}
Подобная информация часто применяется для:
Для перемещения карты без изменения масштаба применяется метод
panTo():
map.panTo([59.9386, 30.3141]);
Карта плавно переместится к указанным координатам.
Пример перехода к Санкт-Петербургу:
map.panTo([59.9386, 30.3141]);
Преимущества метода:
Если анимация не требуется, используется setView():
map.setView([59.9386, 30.3141], map.getZoom());
Либо можно изменить только центр:
map.setView(
[59.9386, 30.3141],
map.getZoom(),
{
animate: false
}
);
Такой способ часто применяется:
Для изменения уровня масштабирования используется метод
setZoom():
map.setZoom(12);
Карта останется в том же центре, но изменит масштаб.
const zoom = map.getZoom();
console.log(zoom);
Например:
if (map.getZoom() > 15) {
console.log('Детальный режим');
}
map.zoomIn();
На несколько уровней:
map.zoomIn(3);
map.zoomOut();
На несколько уровней:
map.zoomOut(2);
Наиболее универсальный способ управления viewport:
map.setView(
[48.8566, 2.3522],
13
);
Переход к Парижу с масштабом 13.
Также доступны дополнительные параметры:
map.setView(
[48.8566, 2.3522],
13,
{
animate: true,
duration: 2
}
);
Leaflet поддерживает эффект плавного перелёта через метод
flyTo().
map.flyTo(
[40.7128, -74.0060],
12
);
Результат напоминает навигацию в геоинформационных сервисах.
map.flyTo(
[40.7128, -74.0060],
12,
{
duration: 3
}
);
Параметр duration задаёт длительность анимации в
секундах.
Переход к маркеру после клика:
marker.on('click', () => {
map.flyTo(
marker.getLatLng(),
15
);
});
Такой подход широко используется в:
Viewport может определяться не только центром, но и прямоугольной областью.
Для этого используется объект LatLngBounds.
Создание границ:
const bounds = L.latLngBounds(
[55.5, 37.2],
[56.0, 38.0]
);
Метод fitBounds() автоматически подбирает центр и
масштаб:
map.fitBounds(bounds);
Leaflet вычислит оптимальный viewport таким образом, чтобы вся область была видна.
const group = L.featureGroup([
marker1,
marker2,
marker3
]);
map.fitBounds(
group.getBounds()
);
Это один из самых распространённых сценариев работы.
Преимущества:
Иногда объекты не должны касаться краёв карты.
Для этого используются внутренние поля:
map.fitBounds(
bounds,
{
padding: [50, 50]
}
);
Или разные значения по осям:
map.fitBounds(
bounds,
{
paddingTopLeft: [20, 50],
paddingBottomRight: [20, 50]
}
);
Подобный подход особенно полезен при наличии боковых панелей интерфейса.
Метод:
const bounds = map.getBounds();
Получение координат:
console.log(bounds.getNorth());
console.log(bounds.getSouth());
console.log(bounds.getEast());
console.log(bounds.getWest());
Результат может выглядеть следующим образом:
North: 56.21
South: 55.31
East: 38.44
West: 36.72
const visible = map.getBounds().contains(
[55.75, 37.61]
);
console.log(visible);
Результат:
true
Подобная проверка часто используется при:
Иногда требуется запретить пользователю покидать определённую территорию.
Создаются границы:
const bounds = L.latLngBounds(
[54.0, 36.0],
[57.0, 39.0]
);
Затем задаётся ограничение:
map.setMaxBounds(bounds);
Теперь карта не сможет быть перемещена за пределы области.
Минимальный и максимальный уровни задаются при создании карты:
const map = L.map('map', {
minZoom: 5,
maxZoom: 18
});
Либо динамически:
map.setMinZoom(7);
map.setMaxZoom(16);
Это позволяет контролировать детализацию отображения данных.
Иногда требуется сдвинуть карту относительно текущего положения.
Для этого используется panBy():
map.panBy([200, 100]);
Где:
Отрицательные значения перемещают карту в противоположную сторону:
map.panBy([-150, 0]);
Размер видимой области можно узнать через:
const size = map.getSize();
console.log(size.x);
console.log(size.y);
Пример:
{
x: 1200,
y: 800
}
Информация полезна при:
Географическая точка может быть переведена в координаты экрана.
const point = map.latLngToContainerPoint(
[55.75, 37.61]
);
console.log(point);
Результат:
{
x: 450,
y: 300
}
Это позволяет размещать собственные HTML-элементы поверх карты.
Обратная операция:
const latlng = map.containerPointToLatLng(
[450, 300]
);
console.log(latlng);
Подобное преобразование используется в инструментах рисования и пользовательских интерфейсах.
Событие move вызывается во время движения:
map.on('move', () => {
console.log('Карта движется');
});
map.on('moveend', () => {
console.log('Перемещение завершено');
});
Это наиболее популярное событие для загрузки данных.
Пример:
map.on('moveend', () => {
loadObjects(
map.getBounds()
);
});
Во время изменения:
map.on('zoom', () => {
console.log(map.getZoom());
});
После завершения:
map.on('zoomend', () => {
console.log('Масштаб изменён');
});
Распространённый паттерн:
function updateData() {
const bounds = map.getBounds();
fetch(`/api/objects?bbox=${
bounds.getWest()
},${
bounds.getSouth()
},${
bounds.getEast()
},${
bounds.getNorth()
}`);
}
map.on('moveend', updateData);
Сервер получает только данные, находящиеся внутри видимой области карты.
Преимущества подхода:
Сохранение состояния:
const state = {
center: map.getCenter(),
zoom: map.getZoom()
};
Восстановление:
map.setView(
state.center,
state.zoom
);
Для хранения между сессиями можно использовать
localStorage:
localStorage.setItem(
'mapState',
JSON.stringify({
center: map.getCenter(),
zoom: map.getZoom()
})
);
Загрузка:
const state = JSON.parse(
localStorage.getItem('mapState')
);
if (state) {
map.setView(
state.center,
state.zoom
);
}
| Метод | Назначение |
|---|---|
setView() |
Установка центра и масштаба |
getCenter() |
Получение центра карты |
panTo() |
Плавное перемещение |
panBy() |
Смещение на заданное количество пикселей |
flyTo() |
Анимированный перелёт |
setZoom() |
Установка масштаба |
zoomIn() |
Увеличение масштаба |
zoomOut() |
Уменьшение масштаба |
fitBounds() |
Отобразить область целиком |
getBounds() |
Получить видимые границы |
setMaxBounds() |
Ограничить перемещение |
getSize() |
Размер viewport |
latLngToContainerPoint() |
Координаты → пиксели |
containerPointToLatLng() |
Пиксели → координаты |
Грамотное управление viewport позволяет создавать отзывчивые картографические приложения, автоматически подстраивающие масштаб и положение карты под отображаемые данные, действия пользователя и особенности интерфейса.