Управление viewport

В Mapbox GL JS под viewport понимается текущее состояние отображаемой области карты: центр, масштаб, наклон, поворот и границы видимой области. Вся визуализация карты строится вокруг этого состояния, а любое взаимодействие пользователя или программное изменение приводит к перерасчёту и перерисовке сцены.

Viewport в Mapbox GL JS не является статичным параметром — это динамическая структура, которая постоянно синхронизируется с внутренним состоянием рендерера WebGL.


Основные компоненты viewport

Viewport формируется набором взаимосвязанных параметров:

center

Координаты центра карты в формате [lng, lat].

map.setCenter([73.3678, 49.8064]);

Центр определяет точку, относительно которой выполняются все трансформации тайлов и слоёв.


zoom

Уровень масштабирования определяет детализацию отображения.

map.setZoom(10);

Особенности поведения:

  • увеличение zoom увеличивает детализацию
  • дробные значения используются для плавного масштабирования
  • диапазон обычно ограничен стилем карты

bearing

Поворот карты вокруг вертикальной оси (в градусах).

map.setBearing(45);
  • 0° — север сверху
  • положительное значение — вращение по часовой стрелке
  • влияет на ориентацию всех слоёв

pitch

Наклон карты, создающий перспективное и псевдо-3D отображение.

map.setPitch(60);
  • 0° — строго вид сверху
  • 60–80° — выраженная перспектива
  • используется для визуализации высотных данных и 3D-слоёв

Объект Map и управление viewport

Основной объект управления состоянием viewport — экземпляр mapboxgl.Map.

const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v12',
  center: [73.3678, 49.8064],
  zoom: 9,
  bearing: 0,
  pitch: 0
});

Все параметры viewport можно задавать:

  • при инициализации
  • динамически через методы
  • через анимационные переходы

Мгновенное изменение viewport

Mapbox GL JS предоставляет методы синхронного изменения состояния карты без анимации.

setCenter

map.setCenter([72.9, 40.5]);

setZoom

map.setZoom(12);

setBearing

map.setBearing(90);

setPitch

map.setPitch(45);

setView (комбинированное управление)

map.jumpTo({
  center: [72.9, 40.5],
  zoom: 11,
  bearing: 30,
  pitch: 20
});

jumpTo изменяет viewport мгновенно, без интерполяции.


Анимационное управление viewport

Для плавного изменения состояния используется анимация.

easeTo

map.easeTo({
  center: [73.2, 49.9],
  zoom: 12,
  duration: 2000,
  easing: (t) => t
});

Характеристики:

  • интерполяция всех параметров viewport
  • управление длительностью
  • возможность задания функции easing

flyTo

map.flyTo({
  center: [73.2, 49.9],
  zoom: 13,
  speed: 1.2,
  curve: 1.5
});

Особенности:

  • имитация полёта камеры
  • дугообразная траектория
  • автоматическая оптимизация перехода

Ограничение viewport через bounds

Viewport может быть ограничен географическими рамками.

map.setMaxBounds([
  [72.0, 49.0],
  [74.0, 50.5]
]);

Это предотвращает выход камеры за заданную область.

Применение:

  • корпоративные карты
  • региональные сервисы
  • ограниченные зоны визуализации

Получение текущего состояния viewport

getCenter

const center = map.getCenter();

getZoom

const zoom = map.getZoom();

getBearing

const bearing = map.getBearing();

getPitch

const pitch = map.getPitch();

Viewport и bounding box

Для анализа видимой области используется getBounds.

const bounds = map.getBounds();

Возвращает:

  • северо-восточную точку
  • юго-западную точку

Применение:

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

Преобразование координат в viewport

Mapbox GL JS предоставляет инструменты преобразования между географическими и экранными координатами.

project (lng/lat → pixel)

const point = map.project([73.3678, 49.8064]);

Используется для:

  • позиционирования HTML-оверлеев
  • кастомных UI элементов
  • синхронизации слоёв

unproject (pixel → lng/lat)

const lngLat = map.unproject([100, 200]);

Применение:

  • обработка кликов
  • кастомные взаимодействия
  • геопривязка интерфейса

События изменения viewport

Viewport в Mapbox GL JS сопровождается набором событий.

move

Срабатывает при любом изменении положения карты.

map.on('move', () => {
  console.log(map.getCenter());
});

moveend

Срабатывает после завершения перемещения.

map.on('moveend', () => {
  console.log('viewport стабилизирован');
});

zoom / zoomend

map.on('zoom', () => {});
map.on('zoomend', () => {});

rotate / pitch

map.on('rotate', () => {});
map.on('pitch', () => {});

Синхронизация viewport с внешним состоянием

Viewport часто связывается с UI состоянием приложения.

Типовой подход:

  • хранение состояния в переменных или store
  • обновление при событиях карты
  • обратное управление через set* методы
let state = {
  center: null,
  zoom: null
};

map.on('move', () => {
  state.center = map.getCenter();
  state.zoom = map.getZoom();
});

Ограничения и особенности поведения viewport

1. Плавность обновлений

Все изменения viewport проходят через WebGL pipeline, поэтому:

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

2. Зависимость zoom от resolution

Zoom не линейно связан с масштабом карты, а экспоненциально влияет на детализацию тайлов.

3. Bearing и pitch влияют на производительность

При высоких значениях:

  • увеличивается нагрузка на GPU
  • усложняется отрисовка слоёв

Комбинированные трансформации viewport

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

map.easeTo({
  center: [73.1, 49.8],
  zoom: 14,
  bearing: 60,
  pitch: 70,
  duration: 3000
});

Такие трансформации используются для:

  • 3D презентаций
  • навигационных сценариев
  • демонстрации объектов

Viewport и камера WebGL

Внутри Mapbox GL JS viewport транслируется в параметры виртуальной камеры:

  • position
  • orientation
  • projection matrix

Каждое изменение viewport вызывает пересчёт матриц трансформации и перерасчёт тайловой сетки.


Производственные сценарии управления viewport

Автоподстройка под данные

map.fitBounds([
  [72.5, 49.2],
  [73.9, 50.1]
]);

Используется при:

  • отображении маршрутов
  • выделении регионов
  • масштабировании под выборку данных

Программная навигация

map.flyTo({
  center: feature.geometry.coordinates,
  zoom: 15
});

Применяется для:

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

Интерактивное управление

Viewport может управляться жестами:

  • pan (перемещение)
  • pinch (масштаб)
  • rotate (вращение)

Mapbox GL JS автоматически преобразует эти жесты в изменения центра, zoom, bearing и pitch.


Взаимодействие viewport и слоёв

Viewport напрямую влияет на:

  • видимость слоёв
  • кластеризацию данных
  • отрисовку label-слоёв
  • динамическое обновление источников данных

При изменении viewport происходит перерасчёт:

  • геометрии
  • столкновений текстов
  • видимых тайлов