Загрузка данных в Mapbox

Визуализация данных в Mapbox GL JS строится вокруг концепции источников (sources). Источник определяет, откуда карта получает данные и в каком формате они поступают в рендеринг. Каждый источник описывается один раз и затем может использоваться в одном или нескольких слоях (layers). Архитектура разделяет данные и их отображение, что позволяет гибко управлять визуализацией без дублирования информации.

Mapbox предоставляет инфраструктуру для хранения и доставки геоданных, включая векторные тайлы и tilesets, однако Mapbox GL JS поддерживает и полностью независимые источники, такие как GeoJSON и внешние API.


Добавление источников через addSource

Основной метод подключения данных — map.addSource. Он регистрирует источник в экземпляре карты и делает его доступным для слоёв.

map.on('load', () => {
  map.addSource('cities', {
    type: 'geojson',
    data: 'https://example.com/cities.geojson'
  });
});

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

Источники бывают разных типов, и от типа зависит структура конфигурации.


GeoJSON как основной формат динамических данных

GeoJSON — наиболее универсальный формат для загрузки пользовательских данных. Он подходит для точек, линий и полигонов.

map.addSource('earthquakes', {
  type: 'geojson',
  data: {
    type: 'FeatureCollection',
    features: [
      {
        type: 'Feature',
        geometry: {
          type: 'Point',
          coordinates: [37.62, 55.75]
        },
        properties: {
          magnitude: 4.2
        }
      }
    ]
  }
});

GeoJSON может быть как встроенным объектом, так и URL-адресом. Во втором случае данные загружаются асинхронно и автоматически обновляются при изменении ресурса.


Обновление данных через setData

Для источников типа GeoJSON предусмотрено динамическое обновление без пересоздания источника.

const source = map.getSource('earthquakes');

source.setData({
  type: 'FeatureCollection',
  features: [
    {
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: [30.31, 59.93]
      },
      properties: {
        magnitude: 3.8
      }
    }
  ]
});

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


Векторные тайлы (vector tiles)

Векторные тайлы представляют собой оптимизированный способ доставки больших объёмов геоданных. Они разделяют данные на фрагменты (tiles), которые загружаются по мере необходимости.

map.addSource('buildings', {
  type: 'vector',
  url: 'mapbox://examples.8fgz4egr'
});

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

map.addLayer({
  id: 'building-fill',
  type: 'fill-extrusion',
  source: 'buildings',
  'source-layer': 'building',
  paint: {
    'fill-extrusion-color': '#aaa',
    'fill-extrusion-height': 50
  }
});

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


Растровые источники

Растровые данные представляют собой изображения, разделённые на тайлы. Они используются для спутниковых снимков, тепловых карт или любых предрендеренных визуализаций.

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

Растровые источники не содержат семантики объектов — они отображают готовую графику.


Image source для одиночных изображений

Источник типа image позволяет наложить одно изображение на карту с привязкой к координатам.

map.addSource('overlay', {
  type: 'image',
  url: 'https://example.com/image.png',
  coordinates: [
    [-80, 35],
    [-70, 35],
    [-70, 45],
    [-80, 45]
  ]
});

Этот тип часто применяется для исторических карт, схем или пользовательских наложений.


Видео-источники

Mapbox GL JS поддерживает видео как источник данных, где каждый кадр интерпретируется как текстура.

map.addSource('drone', {
  type: 'video',
  urls: [
    'https://example.com/video.mp4'
  ],
  coordinates: [
    [-122.5155, 37.5634],
    [-122.5140, 37.5634],
    [-122.5140, 37.5647],
    [-122.5155, 37.5647]
  ]
});

Видео-источники применяются в аналитике и визуализации потоковых данных.


Кластеризация GeoJSON

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

map.addSource('incidents', {
  type: 'geojson',
  data: '/incidents.geojson',
  cluster: true,
  clusterMaxZoom: 14,
  clusterRadius: 50
});

Кластеры доступны как отдельные точки с дополнительными свойствами:

  • point_count — количество объединённых точек
  • cluster — флаг принадлежности к кластеру

Отдельные слои могут визуализировать кластеры и отдельные точки одновременно.


Фильтрация и доступ к данным источника

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

map.addLayer({
  id: 'large-earthquakes',
  type: 'circle',
  source: 'earthquakes',
  filter: ['>=', ['get', 'magnitude'], 5],
  paint: {
    'circle-radius': 8,
    'circle-color': 'red'
  }
});

Фильтры работают на GPU-уровне и позволяют избегать лишних вычислений в JavaScript.


Динамическая подмена источников

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

map.removeSource('cities');

map.addSource('cities', {
  type: 'geojson',
  data: '/new-cities.geojson'
});

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


Прокси и трансформация запросов

При работе с защищёнными API или нестандартными заголовками применяется transformRequest.

const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v12',
  transformRequest: (url, resourceType) => {
    return {
      url: url,
      headers: {
        'Authorization': 'Bearer TOKEN'
      }
    };
  }
});

Это позволяет контролировать все сетевые запросы, включая загрузку тайлов и GeoJSON.


Асинхронная загрузка и кэширование

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

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


Приоритеты загрузки и производительность

Система рендеринга распределяет приоритеты загрузки:

  • текущий viewport получает максимальный приоритет
  • соседние тайлы загружаются с пониженным приоритетом
  • вне экрана данные не запрашиваются

Это обеспечивает стабильную интерактивность даже при сложных слоях.


Использование внешних API как источников данных

Источники могут ссылаться на динамические API, возвращающие GeoJSON.

map.addSource('traffic', {
  type: 'geojson',
  data: 'https://api.example.com/traffic?bbox={bbox}'
});

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


Работа с большими датасетами

При работе с миллионами объектов основное значение имеет выбор типа источника:

  • GeoJSON — для небольших и средних наборов
  • Vector tiles — для масштабируемых систем
  • Raster — для предрендеренной визуализации

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