Импорт данных

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

Базовая модель выглядит так: сначала в карту добавляется источник через addSource, затем на основе этого источника создаётся один или несколько слоёв через addLayer. Такая архитектура позволяет повторно использовать один набор данных для разных визуальных представлений.


Основные типы источников данных

GeoJSON source

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

map.on('load', () => {
  map.addSource('cities', {
    type: 'geojson',
    data: {
      type: 'FeatureCollection',
      features: [
        {
          type: 'Feature',
          geometry: {
            type: 'Point',
            coordinates: [69.2401, 41.2995]
          },
          properties: {
            name: 'Tashkent'
          }
        }
      ]
    }
  });
});

GeoJSON-источник может быть:

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

Особенность GeoJSON — полная гибкость, но при больших объёмах данных возможны ограничения производительности.


Vector Tile Source

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

map.addSource('streets', {
  type: 'vector',
  url: 'mapbox://mapbox.mapbox-streets-v8'
});

Векторные источники обеспечивают:

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

В экосистеме Mapbox именно векторные тайлы являются стандартом для базовых карт.


Raster Tile Source

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

map.addSource('satellite', {
  type: 'raster',
  url: 'mapbox://mapbox.satellite',
  tileSize: 256
});

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


Image Source

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

map.addSource('overlay', {
  type: 'image',
  url: '/overlay.png',
  coordinates: [
    [69.0, 41.4],
    [69.3, 41.4],
    [69.3, 41.2],
    [69.0, 41.2]
  ]
});

Подходит для:

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

Video Source

Позволяет накладывать видео на географическую область.

map.addSource('drone-video', {
  type: 'video',
  urls: ['video.mp4'],
  coordinates: [
    [69.0, 41.4],
    [69.3, 41.4],
    [69.3, 41.2],
    [69.0, 41.2]
  ]
});

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

Метод addSource является центральной точкой интеграции данных.

map.addSource('points', {
  type: 'geojson',
  data: '/data/points.geojson'
});

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

  • источник добавляется один раз
  • повторное добавление с тем же ID вызывает ошибку
  • обновление данных выполняется через setData
const source = map.getSource('points');
source.setData(newGeojson);

Динамическое обновление данных

GeoJSON-источники поддерживают обновление без перезагрузки карты.

Типичный сценарий — получение данных с сервера:

async function updateData() {
  const res = await fetch('/api/points');
  const geojson = await res.json();

  map.getSource('points').setData(geojson);
}

Это позволяет реализовывать:

  • live-трекинг объектов
  • обновляемые дашборды
  • потоковые геоданные

Кластеризация данных

Для больших наборов точек используется кластеризация:

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

Кластеры позволяют:

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

Слой кластеров обычно строится в несколько уровней:

  • слой кластеров
  • слой числа объектов
  • слой одиночных точек

Преобразование внешних данных в GeoJSON

Часто данные приходят в формате CSV или JSON API. Их необходимо преобразовать:

function csvToGeoJSON(rows) {
  return {
    type: 'FeatureCollection',
    features: rows.map(row => ({
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: [parseFloat(row.lng), parseFloat(row.lat)]
      },
      properties: row
    }))
  };
}

После преобразования данные подключаются как обычный GeoJSON-источник.


Работа с URL-источниками

Mapbox GL JS поддерживает загрузку данных напрямую по URL:

map.addSource('places', {
  type: 'geojson',
  data: 'https://example.com/data.geojson'
});

При этом важно учитывать:

  • CORS-заголовки
  • кеширование
  • размер ответа

Для больших файлов предпочтительнее использовать векторные тайлы.


Векторные тайлы и идентификаторы слоёв

Векторный источник может содержать несколько слоёв данных:

map.addSource('composite', {
  type: 'vector',
  url: 'mapbox://mapbox.mapbox-streets-v8'
});

При создании слоя указывается конкретный подслой:

map.addLayer({
  id: 'road-layer',
  type: 'line',
  source: 'composite',
  'source-layer': 'road'
});

Фильтрация данных на уровне слоя

Хотя источник хранит данные целиком, фильтрация выполняется в слоях:

map.addLayer({
  id: 'filtered-points',
  type: 'circle',
  source: 'points',
  filter: ['==', ['get', 'type'], 'restaurant']
});

Фильтры позволяют:

  • сегментировать данные
  • строить тематические карты
  • уменьшать визуальный шум

Обновление структуры источников

Источники можно удалять и заменять:

if (map.getSource('points')) {
  map.removeSource('points');
}

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

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

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

При работе с большими наборами данных критично учитывать:

  • размер GeoJSON-файла
  • частоту обновлений
  • количество объектов
  • использование кластеризации

Рекомендуемые практики:

  • переход на vector tiles при >50k объектов
  • минимизация properties
  • отказ от тяжёлых вычислений в браузере
  • предобработка данных на сервере

Потоковая загрузка данных

В некоторых сценариях данные поступают непрерывно:

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

socket.on('message', (msg) => {
  const data = JSON.parse(msg);
  source.setData(data);
});

Такая архитектура применяется в:

  • системах мониторинга транспорта
  • IoT-картах
  • аналитических панелях в реальном времени

Интеграция с внешними API

Источники часто формируются на основе API-запросов:

fetch('/api/locations')
  .then(res => res.json())
  .then(data => {
    map.getSource('locations').setData(data);
  });

При проектировании важно учитывать:

  • задержки сети
  • частоту обновлений
  • синхронизацию состояния карты и данных

Итоговая модель работы с данными

В Mapbox GL JS вся система импорта данных сводится к трём уровням:

  • источник данных (GeoJSON, vector, raster, image, video)
  • обработка и обновление (setData, фильтры, кластеризация)
  • визуализация (layers)

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