Attribution и схема тайлов

Роль атрибуции в картографическом рендеринге

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

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

Основной механизм — AttributionControl, который автоматически собирает метаданные из стиля карты и источников данных.

Контроль атрибуции в интерфейсе

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

const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v12'
});

map.addControl(new mapboxgl.AttributionControl({
  compact: true,
  customAttribution: 'Данные дополнены внутренними источниками'
}));

Параметр compact управляет режимом отображения: в сжатом виде атрибуция сворачивается в минимальный интерфейсный элемент, раскрывающийся при взаимодействии.

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

Атрибуция на уровне стиля

Стиль карты в Mapbox GL JS описывается JSON-структурой, где каждый источник (source) может содержать поле attribution.

Пример источника:

{
  "type": "vector",
  "url": "mapbox://mapbox.mapbox-streets-v8",
  "attribution": "© OpenStreetMap contributors"
}

Во время рендеринга движок собирает все уникальные строки атрибуции и формирует итоговый набор, исключая дубликаты.

Динамическая агрегация атрибуции

При изменении стиля или добавлении слоёв атрибуция пересчитывается в реальном времени. Это важно при:

  • переключении между источниками данных;
  • добавлении пользовательских GeoJSON слоёв;
  • подключении внешних тайловых серверов;
  • изменении visibility слоёв.

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

Атрибуция и TileJSON

Многие источники в Mapbox GL JS используют формат TileJSON, где атрибуция задаётся явно:

{
  "tilejson": "2.2.0",
  "tiles": ["https://example.com/tiles/{z}/{x}/{y}.pbf"],
  "attribution": "© Example Data Provider"
}

При загрузке такого источника библиотека извлекает поле attribution и добавляет его в общий список.


Схема тайлов

Базовая модель XYZ

В основе работы тайловой системы лежит схема XYZ, используемая в веб-картографии. Пространство делится на квадратные тайлы фиксированного размера (обычно 512×512 или 256×256 пикселей), индексируемые тремя координатами:

  • z — уровень масштабирования (zoom level)
  • x — координата по горизонтали
  • y — координата по вертикали

В Mapbox GL JS эта схема реализуется через URL-шаблоны:

https://example.com/tiles/{z}/{x}/{y}.pbf

При изменении масштаба увеличивается z, а количество тайлов экспоненциально растёт.

Web Mercator и проекция

Система тайлов основана на проекции Web Mercator (EPSG:3857), которая преобразует сферические координаты в плоскую карту.

Ключевые свойства:

  • широта ограничена диапазоном примерно ±85.0511°
  • долгота нормализуется в диапазон ±180°
  • карта становится квадратной в пространстве проекции

Это позволяет равномерно разрезать карту на тайлы одинакового размера на каждом уровне zoom.

Иерархия тайлов

Каждый следующий уровень масштаба удваивает детализацию:

  • z = 0 → 1 тайл
  • z = 1 → 2×2 = 4 тайла
  • z = 2 → 4×4 = 16 тайлов
  • z = n → 2ⁿ × 2ⁿ тайлов

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

Типы тайловых источников

В Mapbox GL JS поддерживаются разные типы источников данных:

vector

Векторные тайлы в формате .pbf, содержащие геометрию и атрибуты объектов.

map.addSource('buildings', {
  type: 'vector',
  url: 'mapbox://mapbox.3d-buildings'
});

raster

Растровые изображения (PNG/JPEG), уже отрендеренные сервером.

map.addSource('satellite', {
  type: 'raster',
  tiles: ['https://example.com/satellite/{z}/{x}/{y}.png'],
  tileSize: 256
});

raster-dem

Цифровые модели рельефа, используемые для 3D-эффектов.

geojson

Данные в формате GeoJSON, загружаемые целиком или потоково.

image

Одиночные изображения с геопривязкой.

video

Видео, наложенное на географические координаты.

Процесс загрузки тайлов

Рендеринг карты в Mapbox GL JS происходит через асинхронный pipeline:

  1. Определение текущего viewport (bbox экрана)
  2. Вычисление необходимых tile coordinates
  3. Формирование URL запросов
  4. Загрузка тайлов через HTTP/2
  5. Декодирование данных (PBF или изображение)
  6. Передача в WebGL worker thread
  7. Растеризация и компоновка слоёв

Ключевая особенность — использование Web Workers, которые разгружают основной поток браузера.

Координатная система тайлов

Каждый тайл в XYZ-системе можно рассматривать как локальную систему координат:

  • (0,0) — верхний левый угол
  • (1,1) — нижний правый угол
  • внутри тайла геометрия нормализуется

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

Векторные тайлы и слойность данных

Векторные тайлы содержат несколько слоёв данных внутри одного файла .pbf. Каждый слой может представлять:

  • дороги
  • здания
  • водоёмы
  • административные границы

При рендеринге Mapbox GL JS фильтрует слои по стилю и применяет layout и paint свойства.

Кэширование и повторное использование

Тайлы активно кэшируются:

  • браузерный HTTP cache
  • внутренний кэш Mapbox GL JS
  • GPU буферы WebGL

Повторное использование тайлов снижает количество сетевых запросов при панорамировании и масштабировании.

Привязка стиля к тайловой схеме

Стиль карты определяет источники, которые в свою очередь определяют тайловую схему. Связь реализуется через:

"sources": {
  "composite": {
    "type": "vector",
    "url": "mapbox://mapbox.mapbox-streets-v8"
  }
}

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

Масштабирование и плавность переходов

При изменении zoom уровня Mapbox GL JS использует:

  • интерполяцию между тайлами разных уровней
  • overzooming (растягивание тайлов)
  • preloading соседних тайлов

Это позволяет избегать «пустых областей» при быстром масштабировании.

Система приоритетов загрузки

Тайлы загружаются по приоритету:

  1. центр экрана
  2. ближайшие к viewport области
  3. периферийные зоны

Такой подход обеспечивает визуально стабильное отображение карты даже при медленном соединении.