GeoJSON source

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

GeoJSON представляет собой стандарт JSON-структуру для описания географических объектов. В контексте Mapbox GL JS поддерживаются основные типы:

  • FeatureCollection — коллекция объектов
  • Feature — отдельный географический объект
  • Геометрии: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon

Минимальная структура выглядит следующим образом:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [37.6173, 55.7558]
      },
      "properties": {
        "title": "Москва"
      }
    }
  ]
}

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

Добавление GeoJSON источника в карту

Для работы с GeoJSON в Mapbox GL JS используется метод addSource. Источник добавляется в стиль карты и становится доступным для слоёв.

map.on('load', () => {
  map.addSource('cities', {
    type: 'geojson',
    data: {
      type: 'FeatureCollection',
      features: [
        {
          type: 'Feature',
          geometry: {
            type: 'Point',
            coordinates: [37.6173, 55.7558]
          },
          properties: {
            name: 'Москва'
          }
        }
      ]
    }
  });
});

После добавления источника его можно использовать в слоях:

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

Способы задания данных GeoJSON источника

Источник может принимать данные в нескольких формах:

Inline GeoJSON

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

data: geojsonObject

URL-источник

GeoJSON может загружаться с сервера:

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

В этом случае Mapbox GL JS автоматически выполняет загрузку и парсинг.

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

GeoJSON-источник поддерживает динамическое обновление:

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

source.setData({
  type: 'FeatureCollection',
  features: updatedFeatures
});

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

Свойства конфигурации GeoJSON источника

GeoJSON источник в Mapbox GL JS поддерживает дополнительные параметры, влияющие на производительность и поведение.

generateId

Добавляет уникальные идентификаторы к объектам, если они отсутствуют:

{
  type: 'geojson',
  data: geojsonData,
  generateId: true
}

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

cluster

Включает кластеризацию точечных объектов:

{
  type: 'geojson',
  data: points,
  cluster: true
}

Кластеризация объединяет близко расположенные точки в один объект.

clusterRadius

Определяет радиус кластеризации в пикселях:

clusterRadius: 50

Чем больше значение, тем агрессивнее объединение точек.

clusterMaxZoom

Определяет максимальный зум, до которого выполняется кластеризация:

clusterMaxZoom: 14

После этого уровня точки отображаются по отдельности.

clusterProperties

Позволяет вычислять агрегированные значения внутри кластера:

clusterProperties: {
  sum: ['+', ['get', 'value']]
}

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

buffer

Указывает количество тайловых пикселей для буферизации:

buffer: 128

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

tolerance

Определяет допустимую погрешность упрощения геометрии:

tolerance: 0.375

Используется для оптимизации сложных линий и полигонов.

maxzoom

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

maxzoom: 18

Использование GeoJSON с фильтрацией слоёв

Слои, использующие GeoJSON источник, поддерживают фильтрацию на основе свойств объектов:

map.addLayer({
  id: 'filtered-cities',
  type: 'circle',
  source: 'cities',
  filter: ['==', ['get', 'country'], 'Russia'],
  paint: {
    'circle-color': '#0000ff'
  }
});

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

Работа с feature-state

Feature-state используется для хранения временного состояния объектов без изменения исходного GeoJSON.

map.setFeatureState(
  { source: 'cities', id: 1 },
  { selected: true }
);

В стиле слоя можно использовать это состояние:

paint: {
  'circle-color': [
    'case',
    ['boolean', ['feature-state', 'selected'], false],
    '#ff0000',
    '#00ff00'
  ]
}

Это позволяет реализовывать выделение объектов, hover-эффекты и интерактивные сценарии.

Особенности обновления больших GeoJSON наборов

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

  • частые вызовы setData могут блокировать рендеринг
  • предпочтительно минимизировать размер GeoJSON
  • использование кластеризации снижает нагрузку на GPU
  • упрощение геометрии через tolerance уменьшает количество вершин

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

Отличия GeoJSON source от других источников

GeoJSON источник отличается от векторных и растровых источников:

  • полностью клиентская обработка данных
  • возможность динамического изменения через JavaScript
  • поддержка feature-state и кластеризации
  • отсутствие необходимости в тайловой структуре

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

Кластеризация и визуализация групп точек

Кластеризация является одним из наиболее мощных инструментов GeoJSON источника. Она позволяет преобразовывать тысячи точек в агрегированные объекты.

Пример отображения кластеров:

map.addLayer({
  id: 'clusters',
  type: 'circle',
  source: 'points',
  filter: ['has', 'point_count'],
  paint: {
    'circle-color': '#51bbd6',
    'circle-radius': 18
  }
});

Отдельно можно отображать количество точек:

map.addLayer({
  id: 'cluster-count',
  type: 'symbol',
  source: 'points',
  filter: ['has', 'point_count'],
  layout: {
    'text-field': '{point_count_abbreviated}',
    'text-size': 12
  }
});

И отдельные точки:

map.addLayer({
  id: 'unclustered-point',
  type: 'circle',
  source: 'points',
  filter: ['!', ['has', 'point_count']],
  paint: {
    'circle-color': '#f28cb1',
    'circle-radius': 6
  }
});

Использование GeoJSON для динамических приложений

GeoJSON источник часто применяется в сценариях, где данные меняются во времени:

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

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

setInterval(() => {
  source.setData(fetchUpdatedGeoJSON());
}, 5000);

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

Производственные ограничения и оптимизация

При использовании GeoJSON источника критично учитывать ограничения браузера и WebGL:

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

Оптимизация обычно включает:

  • сокращение геометрической сложности
  • разделение данных по источникам
  • использование кластеризации
  • переход на vector tiles при масштабировании системы