Привязка к координатам

Координатная система в Mapbox GL JS основана на долгоживущем веб-стандарте представления геоданных через долготу и широту. Все визуальные сущности на карте — от центра вида до отдельных точек, линий и полигонов — привязываются к географическим координатам, а не к пикселям экрана. Это фундаментальный принцип, определяющий поведение всей системы рендеринга и взаимодействия.

Основная единица работы — пара значений [долгота, широта], где:

  • долгота (longitude) задаёт положение по оси восток–запад,
  • широта (latitude) задаёт положение по оси север–юг.

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

const center = [37.6173, 55.7558]; // Москва: [lng, lat]

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

Привязка центра карты к координатам

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

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

Изменение центра приводит не к перемещению объектов, а к изменению виртуальной камеры, которая «смотрит» на разные участки глобальной координатной плоскости.

Ключевая особенность заключается в том, что координаты объектов остаются неизменными, а изменяется только матрица трансформации вида.

Маркеры и их географическая привязка

Каждый маркер в Mapbox GL JS жёстко связан с координатами. Он не существует в системе пикселей, пока не будет отрисован.

new mapboxgl.Marker()
  .setLngLat([37.6173, 55.7558])
  .addTo(map);

Метод setLngLat закрепляет элемент за конкретной географической точкой. При изменении масштаба или перемещении карты маркер автоматически пересчитывает своё экранное положение.

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

географические координаты → мировые координаты → экранные координаты

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

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

Из координат в экранные пиксели

const pixel = map.project([37.6173, 55.7558]);

Результат содержит координаты в пикселях относительно контейнера карты. Это используется для позиционирования пользовательских HTML-элементов поверх карты.

Из пикселей в координаты

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

Этот механизм особенно важен при обработке событий мыши, когда необходимо определить географическую точку клика.

Обработка событий и привязка к месту клика

Каждое событие взаимодействия с картой содержит уже рассчитанные координаты:

map.on('click', (e) => {
  console.log(e.lngLat);
});

e.lngLat представляет собой объект с полями lng и lat, что избавляет от необходимости ручного преобразования пикселей в географические значения.

Эта модель обеспечивает строгую географическую привязку всех пользовательских действий.

Работа с источниками данных GeoJSON

GeoJSON является основным форматом хранения геометрии. Все координаты внутри GeoJSON также задаются в формате [longitude, latitude].

map.addSource('points', {
  type: 'geojson',
  data: {
    type: 'FeatureCollection',
    features: [
      {
        type: 'Feature',
        geometry: {
          type: 'Point',
          coordinates: [37.6173, 55.7558]
        }
      }
    ]
  }
});

Любой слой, использующий этот источник, автоматически интерпретирует координаты и размещает объекты в географическом пространстве.

Привязка слоёв к координатам

Слои (layers) не содержат координат напрямую. Они опираются на источники данных, которые уже включают геометрию.

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

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

Камера и географическая трансформация

Камера карты описывается тремя основными параметрами:

  • центр (center)
  • масштаб (zoom)
  • угол поворота (bearing)
map.flyTo({
  center: [37.6173, 55.7558],
  zoom: 12,
  bearing: 30
});

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

Важно, что координаты объектов не изменяются при анимации камеры — изменяется только способ их проекции.

Ограничение области отображения координатами

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

map.setMaxBounds([
  [29.0, 59.0],
  [31.0, 60.5]
]);

Здесь задаётся прямоугольная область в географических координатах, за пределы которой камера не может перемещаться.

Привязка HTML-элементов к координатам

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

const el = document.createElement('div');
el.className = 'custom-marker';

new mapboxgl.Marker(el)
  .setLngLat([37.6173, 55.7558])
  .addTo(map);

Такой подход позволяет синхронизировать географическое положение с кастомной визуализацией.

Попапы и их географическое позиционирование

Всплывающие окна также привязываются к координатам и автоматически смещаются относительно точки якоря.

new mapboxgl.Popup()
  .setLngLat([37.6173, 55.7558])
  .setHTML('Точка интереса')
  .addTo(map);

Позиционирование попапа зависит от текущего масштаба и положения камеры, но его географическая привязка остаётся неизменной.

Области и границы (bounds)

Границы карты задаются двумя угловыми точками:

  • юго-западный угол
  • северо-восточный угол
const bounds = [
  [37.0, 55.0],
  [38.0, 56.0]
];

map.fitBounds(bounds);

Метод fitBounds вычисляет оптимальный центр и масштаб, чтобы вся область была полностью видна.

Математическая основа привязки

Внутри Mapbox GL JS используется Web Mercator projection. Она переводит сферические координаты в плоскую систему координат, пригодную для отображения на экране.

Упрощённая схема преобразования:

широта/долгота → сферическая модель → проекция Меркатора → мировые координаты → экранные координаты

Именно эта цепочка обеспечивает корректное масштабирование и непрерывность карты при любом уровне zoom.

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

При увеличении масштаба координаты не изменяются, но увеличивается плотность их отображения. Один и тот же географический участок при zoom 5 и zoom 15 представляет собой разные размеры в пикселях, хотя координаты остаются фиксированными.

Это создаёт эффект бесшовного масштабирования без потери географической точности.

Координаты в событиях перетаскивания и жестов

При обработке drag-событий карта постоянно пересчитывает центральные координаты:

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

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

Синхронизация нескольких карт через координаты

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

mapA.on('move', () => {
  mapB.setCenter(mapA.getCenter());
});

Здесь географические координаты выступают единственным источником истины, обеспечивая идентичное отображение разных экземпляров карты.