Создание и позиционирование

Работа с Mapbox GL JS строится вокруг создания экземпляра карты, привязанного к DOM-контейнеру и конфигурации начального состояния отображения. В основе лежит объект Map, который управляет WebGL-рендерингом, слоями, источниками данных и интерактивностью.

mapboxgl.accessToken = 'YOUR_ACCESS_TOKEN';

const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v12',
  center: [69.2401, 41.2995],
  zoom: 10
});

Ключевые параметры и их роль:

  • container — идентификатор DOM-элемента или сам элемент, в котором создаётся WebGL-контекст
  • style — ссылка на стиль карты (векторный тайлсет и визуальное оформление)
  • center — начальные координаты [longitude, latitude]
  • zoom — масштаб отображения

Координаты в системе Mapbox всегда задаются в порядке долгота → широта, что критично для корректного позиционирования.


Географическая система координат и модель проекции

В основе позиционирования лежит проекция Web Mercator. Она преобразует сферические координаты в плоскую карту, что позволяет использовать стандартные пиксельные вычисления для рендеринга слоёв.

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

  • долгота (longitude) изменяется по горизонтали
  • широта (latitude) изменяется по вертикали
  • крайние значения ограничены диапазоном [-180, 180] и [-85.0511, 85.0511]

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

const point = map.project([69.2401, 41.2995]);

Он возвращает экранные координаты относительно контейнера карты.

Обратное преобразование:

const lngLat = map.unproject([x, y]);

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

Центр карты определяет географическую точку, находящуюся в середине экрана. Управление центром является базовым механизмом позиционирования.

map.setCenter([69.2401, 41.2995]);

Также используется плавное перемещение:

map.flyTo({
  center: [69.2401, 41.2995],
  zoom: 12,
  speed: 1.2,
  curve: 1.4
});

Методы перемещения:

  • setCenter — мгновенное смещение
  • panTo — анимация смещения без изменения масштаба
  • flyTo — динамическая анимация с изменением траектории
  • easeTo — плавный переход с контролируемой интерполяцией

Масштабирование и уровни детализации

Zoom в Mapbox GL JS представляет собой логарифмическую шкалу детализации.

map.setZoom(8);

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

  • zoom = 0 — глобальный обзор
  • zoom ≈ 10 — городской уровень
  • zoom ≥ 15 — уличный уровень

Изменение масштаба влияет на:

  • плотность тайлов
  • детализацию слоёв
  • видимость объектов

Комбинированное управление:

map.setZoom(14);
map.setCenter([69.2401, 41.2995]);

Поворот, наклон и 3D-позиционирование

Mapbox поддерживает пространственное позиционирование камеры:

map.setBearing(30);
map.setPitch(45);

Параметры:

  • bearing — поворот карты по часовой стрелке (в градусах)
  • pitch — наклон камеры относительно поверхности

Эти параметры влияют на восприятие глубины и особенно важны для 3D-слоёв.

Комбинация камеры:

map.jumpTo({
  center: [69.2401, 41.2995],
  zoom: 13,
  bearing: 60,
  pitch: 50
});

Позиционирование элементов интерфейса

Отдельные элементы карты (маркер, попап, HTML-оверлей) привязываются к географическим координатам.

Маркеры

const marker = new mapboxgl.Marker()
  .setLngLat([69.2401, 41.2995])
  .addTo(map);

Принцип позиционирования:

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

Параметры маркера:

  • offset — смещение относительно точки
  • anchor — точка привязки (top, bottom, center и др.)
new mapboxgl.Marker({ offset: [0, -10] })

Попапы

new mapboxgl.Popup({ offset: 25 })
  .setLngLat([69.2401, 41.2995])
  .setHTML('<div>Точка интереса</div>')
  .addTo(map);

Попап автоматически рассчитывает позицию так, чтобы оставаться видимым в пределах viewport. При нехватке пространства происходит автоматическое смещение.


Преобразование географических координат в экранные

Для сложного UI и кастомных слоёв используется ручное позиционирование через project.

const coords = [69.2401, 41.2995];
const pixel = map.project(coords);

const x = pixel.x;
const y = pixel.y;

Используется в сценариях:

  • кастомные Canvas-слои
  • синхронизация DOM-оверлеев
  • анимации поверх карты

Обратное преобразование:

const lngLat = map.unproject({ x: 200, y: 300 });

Управление границами отображения

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

map.fitBounds([
  [69.0, 41.0],
  [70.0, 42.0]
]);

Принцип:

  • вычисляется минимальный bounding box
  • камера подбирает zoom и center автоматически
  • учитываются padding и aspect ratio

Дополнительные параметры:

map.fitBounds(bounds, {
  padding: 40,
  maxZoom: 14
});

Синхронизация размеров и перерасчёт позиции

Mapbox требует корректного уведомления об изменении размеров контейнера:

map.resize();

Без вызова:

  • нарушается соответствие canvas и DOM
  • смещаются слои и маркеры
  • неверно вычисляется центр

Resize обязателен при:

  • изменении flex/grid layout
  • появлении/скрытии сайдбаров
  • изменении размера окна

Позиционирование слоёв и источников данных

Каждый слой имеет свою геометрическую привязку.

map.addSource('points', {
  type: 'geojson',
  data: {
    type: 'FeatureCollection',
    features: []
  }
});

map.addLayer({
  id: 'points-layer',
  type: 'circle',
  source: 'points',
  paint: {
    'circle-radius': 6,
    'circle-color': '#ff0000'
  }
});

Позиционирование слоёв определяется:

  • геометрией GeoJSON
  • уровнем zoom
  • свойствами layout и paint

Порядок слоёв критичен: верхние слои перекрывают нижние.


Управление относительным позиционированием и anchor-системой

Для UI-элементов используется система anchor-точек:

  • center
  • top
  • bottom
  • left
  • right
  • top-left, top-right, bottom-left, bottom-right

Пример:

new mapboxgl.Marker({ anchor: 'bottom' })

Anchor определяет точку привязки DOM-элемента к координате, что влияет на визуальное выравнивание.


Позиционирование в условиях анимации камеры

При изменении камеры все привязанные объекты пересчитываются в реальном времени.

map.on('move', () => {
  const center = map.getCenter();
});

События, влияющие на позиционирование:

  • move
  • zoom
  • rotate
  • pitch

Каждое изменение камеры запускает перерасчёт матрицы трансформации WebGL.


Работа с экранными координатами и слоями DOM

DOM-оверлеи требуют синхронизации с WebGL-картой:

const overlay = document.createElement('div');
overlay.style.position = 'absolute';

function update() {
  const pos = map.project([69.2401, 41.2995]);
  overlay.style.transform = `translate(${pos.x}px, ${pos.y}px)`;
}

Ключевой принцип:

  • Mapbox рендерит карту в canvas
  • DOM-элементы позиционируются поверх через пиксельные координаты
  • синхронизация выполняется на каждом кадре или событии движения камеры

Ограничение области перемещения карты

map.setMaxBounds([
  [68.0, 40.0],
  [72.0, 43.0]
]);

Эффект:

  • камера не может выйти за пределы bounding box
  • ограничение применяется ко всем типам перемещения

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

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

Позиционирование и производительность

Частые операции позиционирования напрямую связаны с производительностью WebGL:

  • перерасчёт матриц при каждом событии камеры
  • пересборка тайлов при изменении zoom
  • обновление слоёв при изменении источников

Оптимизация достигается через:

  • минимизацию количества DOM-оверлеев
  • использование setData вместо пересоздания source
  • ограничение частоты обработчиков move

Геометрическая модель взаимодействия объектов

Все объекты карты подчиняются единой системе координат:

  • географические координаты (lng/lat)
  • экранные координаты (x/y)
  • мировая WebGL-матрица

Переход между уровнями происходит через цепочку преобразований:

  1. WGS84 координаты
  2. Web Mercator projection
  3. world coordinates
  4. screen projection matrix

Эта модель обеспечивает согласованное позиционирование всех элементов независимо от масштаба и угла камеры.