Работа с GeoJSON

GeoJSON представляет собой стандартный формат описания географических данных на основе JSON. В контексте Deck.gl он используется как основной способ загрузки и визуализации векторных пространственных объектов: точек, линий и полигонов. Поддержка GeoJSON реализована через специализированный слой GeoJsonLayer, который абстрагирует обработку геометрии, стилизацию и интерактивность.

Структура GeoJSON и её интерпретация

GeoJSON поддерживает несколько типов геометрий:

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

В Deck.gl каждый Feature интерпретируется как отдельный визуальный объект с доступом к свойствам через properties.

Пример базового GeoJSON:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [76.8865, 43.2389]
      },
      "properties": {
        "name": "Алматы"
      }
    }
  ]
}

Deck.gl использует координаты в формате [longitude, latitude], что соответствует стандарту GeoJSON.

GeoJsonLayer как основной инструмент визуализации

Слой GeoJsonLayer является универсальным механизмом рендеринга GeoJSON-данных. Он автоматически разбивает входной набор данных на подслои:

  • ScatterplotLayer для точек
  • PathLayer для линий
  • PolygonLayer для полигонов

Базовая конфигурация слоя:

import {GeoJsonLayer} from '@deck.gl/layers';

const layer = new GeoJsonLayer({
  id: 'geojson-layer',
  data: 'https://example.com/data.geojson',
  filled: true,
  stroked: true,
  pointRadiusMinPixels: 4,
  getFillColor: [200, 0, 80, 180],
  getLineColor: [0, 0, 0, 255],
  pickable: true
});

Параметр data может принимать:

  • URL до GeoJSON-файла
  • объект GeoJSON
  • функцию, возвращающую данные

Механизм обработки геометрий

Внутри Deck.gl GeoJSON преобразуется в набор векторных примитивов. Каждый тип геометрии проходит этапы:

  1. Парсинг GeoJSON
  2. Нормализация координат
  3. Преобразование в внутренние форматы Deck.gl
  4. Генерация геометрии для WebGL-рендеринга

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

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

Работа с атрибутами и свойствами

Каждый объект GeoJSON содержит properties, которые используются для динамической стилизации:

const layer = new GeoJsonLayer({
  id: 'cities',
  data,
  getFillColor: f => {
    const population = f.properties.population;
    return population > 1000000 ? [255, 0, 0] : [0, 128, 255];
  },
  getRadius: f => Math.sqrt(f.properties.population) / 100
});

Функции getFillColor, getLineColor, getRadius и аналогичные выполняются на уровне каждого объекта, обеспечивая гибкую привязку визуальных параметров к данным.

Обработка вложенных структур Multi-геометрий

GeoJSON допускает вложенные структуры, которые Deck.gl разворачивает в отдельные сущности:

  • MultiPolygon преобразуется в набор полигонов
  • MultiLineString — в набор линий

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

Интерактивность и picking

GeoJsonLayer поддерживает механизм picking — определение объекта под курсором. Это достигается через уникальную идентификацию каждого примитива на GPU-уровне.

const layer = new GeoJsonLayer({
  id: 'interactive-geojson',
  data,
  pickable: true,
  onClick: info => {
    if (info.object) {
      console.log(info.object.properties);
    }
  },
  onHover: info => {
    console.log(info.coordinate);
  }
});

Объект info содержит:

  • object — исходный Feature
  • coordinate — координаты точки взаимодействия
  • x, y — экранные координаты
  • layer — ссылка на слой

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

Deck.gl позволяет выполнять фильтрацию объектов без изменения исходного GeoJSON:

const layer = new GeoJsonLayer({
  id: 'filtered',
  data,
  filterRange: [0, 100],
  getFilterValue: f => f.properties.value,
  filterEnabled: true
});

Фильтрация может применяться как к числовым значениям, так и к временным меткам при использовании временных расширений.

Стилизация линий и полигонов

Для линий доступны параметры:

  • getLineColor
  • getLineWidth
  • lineWidthMinPixels
getLineColor: f => [0, 0, 0, 200],
getLineWidth: f => f.properties.importance * 2

Для полигонов:

  • getFillColor
  • getLineColor
  • extruded
  • getElevation

Extrusion позволяет создавать 3D-объекты:

const layer = new GeoJsonLayer({
  id: 'extruded-polygons',
  data,
  extruded: true,
  getElevation: f => f.properties.height,
  getFillColor: [100, 150, 200]
});

Работа с масштабированием и производительностью

GeoJSON может содержать десятки тысяч объектов, что требует оптимизации. Deck.gl применяет несколько подходов:

  • батчинг геометрии на уровне GPU
  • использование Typed Arrays
  • кеширование триангуляции
  • ленивую обработку данных

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

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

Deck.gl работает в Web Mercator проекции (EPSG:3857). GeoJSON обычно использует WGS84 (EPSG:4326). Преобразование координат выполняется автоматически:

  • долгота → X
  • широта → Y

Для 3D-режимов добавляется ось Z, получаемая из атрибутов данных.

Интеграция с Mapbox и базовыми картами

GeoJsonLayer часто используется поверх базовой карты Mapbox или других тайловых слоёв:

import {DeckGL} from '@deck.gl/react';
import {Map} from 'react-map-gl';

<DeckGL
  initialViewState={viewState}
  controller={true}
  layers={[geoJsonLayer]}
>
  <Map mapboxAccessToken={TOKEN} />
</DeckGL>

Deck.gl выступает как слой визуализации поверх карты, не вмешиваясь в управление тайлами.

Обработка больших GeoJSON файлов

При работе с большими наборами данных применяется потоковая загрузка через @loaders.gl/geojson. Это позволяет:

  • парсить данные инкрементально
  • избегать блокировки основного потока
  • уменьшать время первого рендеринга
import {load} from '@loaders.gl/core';
import {GeoJSONLoader} from '@loaders.gl/geojson';

const data = await load(url, GeoJSONLoader);

Кастомизация поведения через accessors

Accessors позволяют вычислять параметры на основе сложной логики:

getFillColor: feature => {
  const type = feature.properties.type;

  switch (type) {
    case 'park':
      return [0, 200, 0];
    case 'water':
      return [0, 100, 255];
    default:
      return [200, 200, 200];
  }
}

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

3D-визуализация GeoJSON объектов

GeoJsonLayer поддерживает рендеринг в 3D пространстве через extrusion и elevation:

  • здания как экструдированные полигоны
  • ландшафтные данные как поверхности
  • статистические показатели как высоты столбцов

При этом геометрия остаётся основанной на GeoJSON, а визуальная интерпретация задаётся слоями.

Обработка ошибок и валидация данных

GeoJSON может содержать некорректные координаты или незамкнутые полигоны. Deck.gl выполняет частичную защиту:

  • игнорирование повреждённых Feature
  • пропуск некорректных координат
  • логирование ошибок в консоль

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

Комбинирование GeoJSON с другими слоями

GeoJsonLayer часто используется вместе с:

  • TextLayer для подписей
  • IconLayer для маркеров
  • ArcLayer для связей между точками
  • HeatmapLayer для плотности данных

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