Работа с пользовательскими GeoJSON файлами

Nivo предоставляет набор компонентов для построения географических визуализаций на основе SVG и Canvas, где ключевым источником данных выступают GeoJSON и TopoJSON структуры. Работа с пользовательскими GeoJSON файлами требует согласования геометрической модели данных, идентификаторов объектов и механизма сопоставления с прикладными данными, используемыми для раскраски, фильтрации и интерактивных событий.

GeoJSON представляет собой формат описания географических объектов в виде JSON-структуры, включающей тип объекта, набор координат и дополнительные свойства.

Основные типы объектов:

  • FeatureCollection — коллекция географических объектов
  • Feature — отдельный объект с геометрией и свойствами
  • Geometry — геометрическое описание (Polygon, MultiPolygon, Point и др.)

Типичный пользовательский GeoJSON имеет следующую структуру:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "id": "region-1",
      "properties": {
        "name": "Region A"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [45.0, 55.0],
            [46.0, 55.0],
            [46.0, 56.0],
            [45.0, 56.0],
            [45.0, 55.0]
          ]
        ]
      }
    }
  ]
}

Ключевым аспектом для интеграции с Nivo является поле id или стабильное значение в properties, которое используется для связывания геометрии с данными визуализации.

Механизм сопоставления данных в Nivo

В географических компонентах Nivo (например, ResponsiveChoropleth) визуализация строится на принципе join-операции между геометрией и набором данных.

Каждый элемент данных должен содержать идентификатор, совпадающий с feature.id или выбранным полем через valueFormat.

Пример набора данных:

const data = [
  { id: "region-1", value: 42 },
  { id: "region-2", value: 87 }
]

При рендеринге происходит сопоставление:

  • GeoJSON Feature → id
  • Data item → id
  • результат → цвет, tooltip, интерактивность

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

Подключение пользовательского GeoJSON

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

import { ResponsiveChoropleth } from '@nivo/geo'
import geoData from './customRegions.geojson'

const MyMap = ({ data }) => (
  <ResponsiveChoropleth
    data={data}
    features={geoData.features}
    projectionScale={120}
    projectionTranslation={[0.5, 0.5]}
    valueFormat=".2f"
  />
)

Важное ограничение заключается в том, что Nivo ожидает массив features, а не полный GeoJSON-объект. Поэтому при использовании FeatureCollection необходимо передавать geoData.features.

Работа с нестандартными идентификаторами

Во многих пользовательских GeoJSON файлах отсутствует поле id. В таком случае идентификатор формируется из properties.

Типичный вариант:

const getFeatureId = feature => feature.properties.code

В Nivo это учитывается через кастомную настройку:

<ResponsiveChoropleth
  features={geoData.features}
  data={data}
  match={(feature, datum) => feature.properties.code === datum.id}
/>

Подобный подход обеспечивает гибкость, но требует строгой консистентности входных данных.

Преобразование TopoJSON в GeoJSON

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

import { feature } from 'topojson-client'

const geoData = feature(topoJsonData, topoJsonData.objects.regions)

После преобразования структура становится совместимой с компонентами Nivo, которые работают только с GeoJSON.

Управление проекциями

Географические компоненты Nivo используют d3-geo проекции. Для пользовательских GeoJSON важно корректно настроить масштаб и центрирование.

Ключевые параметры:

  • projectionScale — масштаб отображения
  • projectionTranslation — смещение центра
  • projectionRotation — поворот карты

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

<ResponsiveChoropleth
  features={geoData.features}
  data={data}
  projectionScale={150}
  projectionTranslation={[0.5, 0.5]}
  projectionRotation={[0, 0, 0]}
/>

Неправильная настройка приводит к смещению или обрезанию геометрии за пределами viewport.

Обогащение геометрии пользовательскими свойствами

GeoJSON может содержать дополнительные поля в properties, которые используются для:

  • отображения tooltip
  • кастомной логики окрашивания
  • фильтрации объектов

Пример:

"properties": {
  "name": "Region A",
  "population": 120000,
  "category": "urban"
}

Использование в tooltip:

tooltip={({ feature }) => (
  <div>
    <strong>{feature.properties.name}</strong>
    <div>{feature.properties.population}</div>
  </div>
)}

Кастомизация цвета на основе GeoJSON и данных

Цветовая логика в Nivo строится на значениях value, но может быть расширена через функцию colors.

<ResponsiveChoropleth
  data={data}
  features={geoData.features}
  colors={d => {
    if (!d.value) return '#eee'
    if (d.value > 80) return '#ff0000'
    if (d.value > 40) return '#ffa500'
    return '#00ff00'
  }}
/>

При этом d представляет объединённый объект, содержащий геометрию и значение.

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

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

Используются подходы:

  • упрощение геометрии через topojson simplify
  • переход на Canvas-рендеринг
  • разбиение карты на регионы (lazy loading)

Canvas-режим в Nivo снижает нагрузку на DOM:

<ResponsiveChoropleth
  features={geoData.features}
  data={data}
  renderMode="canvas"
/>

Интерактивные события на пользовательских GeoJSON

GeoJSON объекты в Nivo поддерживают события:

  • onClick
  • onMouseEnter
  • onMouseLeave
<ResponsiveChoropleth
  features={geoData.features}
  data={data}
  onCl ick={feature => {
    console.log(feature.id)
  }}
/>

Интерактивность напрямую зависит от корректности сопоставления id.

Фильтрация и предобработка GeoJSON

Перед передачей данных в визуализацию часто выполняется фильтрация:

const filteredFeatures = geoData.features.filter(
  f => f.properties.type !== 'water'
)

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

Согласование CRS и координатных систем

GeoJSON предполагает WGS84 (EPSG:4326). Несоответствие системы координат приводит к некорректному отображению.

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