JSON и GeoJSON

Библиотека Kepler.gl предназначена для визуализации пространственных данных, поэтому ключевое значение в её экосистеме имеют форматы JSON и GeoJSON. Через них осуществляется загрузка, обмен, хранение конфигураций карт и представление географических объектов.

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

Понимание структуры этих форматов является обязательным условием эффективной работы с Kepler.gl.


Формат JSON

Общая характеристика

JSON (JavaScript Object Notation) — текстовый формат обмена данными, основанный на синтаксисе объектов JavaScript.

Основные преимущества:

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

JSON состоит из двух базовых структур:

  1. Объект (Object)
  2. Массив (Array)

Объекты

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

Пример:

{
  "city": "Almaty",
  "population": 1977000,
  "country": "Kazakhstan"
}

Здесь:

Ключ Значение
city Almaty
population 1977000
country Kazakhstan

Массивы

Массив содержит набор элементов.

[
  "red",
  "green",
  "blue"
]

Также массив может содержать объекты:

[
  {
    "name": "Point A"
  },
  {
    "name": "Point B"
  }
]

Типы данных JSON

Поддерживаются следующие типы:

{
  "string": "text",
  "number": 123,
  "float": 12.5,
  "boolean": true,
  "nullValue": null,
  "array": [1, 2, 3],
  "object": {
    "key": "value"
  }
}

JSON в экосистеме Kepler.gl

В Kepler.gl JSON применяется в нескольких сценариях:

Конфигурация карты

Каждая настройка визуализации может быть сохранена в JSON.

Пример фрагмента конфигурации:

{
  "version": "v1",
  "config": {
    "visState": {
      "layers": []
    }
  }
}

Такая структура содержит:

  • слои;
  • фильтры;
  • настройки отображения;
  • параметры взаимодействия;
  • состояние интерфейса.

Экспорт состояния карты

Kepler.gl позволяет экспортировать карту полностью:

const mapConfig = keplerGlInstance.getState();

Полученный объект можно сохранить:

const json = JSON.stringify(mapConfig);

или отправить на сервер:

fetch("/api/save", {
  method: "POST",
  body: json
});

Загрузка конфигурации

Восстановление ранее сохранённой карты выполняется через JSON-конфиг:

dispatch(
  addDataToMap({
    datasets: dataset,
    config: savedConfig
  })
);

Ограничения обычного JSON

Хотя JSON может хранить любые данные, он не содержит стандартных правил описания геометрии.

Например:

{
  "latitude": 43.238949,
  "longitude": 76.889709
}

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

  • является ли объект точкой;
  • используется ли географическая система координат;
  • относится ли запись к карте.

Для решения этой проблемы был разработан стандарт GeoJSON.


GeoJSON

Назначение

GeoJSON — открытый стандарт представления пространственных данных на основе JSON.

Он используется для хранения:

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

Kepler.gl поддерживает GeoJSON из коробки без дополнительной обработки.


Базовая структура GeoJSON

Каждый объект обязательно содержит поле:

{
  "type": "Point",
  "coordinates": [76.889709, 43.238949]
}

Ключевые элементы:

Поле Назначение
type Тип геометрии
coordinates Координаты

Система координат

GeoJSON использует порядок:

[longitude, latitude]

а не:

[latitude, longitude]

Правильно:

[76.889709, 43.238949]

Неправильно:

[43.238949, 76.889709]

Это одна из самых распространённых ошибок при загрузке данных в Kepler.gl.


Типы геометрии GeoJSON

Point

Представляет одну точку.

{
  "type": "Point",
  "coordinates": [76.889709, 43.238949]
}

Примеры использования:

  • города;
  • магазины;
  • остановки;
  • датчики;
  • объекты IoT.

MultiPoint

Несколько точек.

{
  "type": "MultiPoint",
  "coordinates": [
    [76.88, 43.23],
    [76.89, 43.24],
    [76.90, 43.25]
  ]
}

Подходит для групп объектов.


LineString

Линия, состоящая из последовательности координат.

{
  "type": "LineString",
  "coordinates": [
    [76.88, 43.23],
    [76.89, 43.24],
    [76.90, 43.25]
  ]
}

Используется для отображения:

  • дорог;
  • маршрутов;
  • кабелей;
  • треков GPS.

MultiLineString

Набор линий.

{
  "type": "MultiLineString",
  "coordinates": [
    [
      [76.88, 43.23],
      [76.89, 43.24]
    ],
    [
      [76.90, 43.25],
      [76.91, 43.26]
    ]
  ]
}

Polygon

Полигон задаёт замкнутую область.

Пример:

{
  "type": "Polygon",
  "coordinates": [
    [
      [76.88, 43.23],
      [76.90, 43.23],
      [76.90, 43.25],
      [76.88, 43.25],
      [76.88, 43.23]
    ]
  ]
}

Последняя точка обязана совпадать с первой.


Полигон с отверстиями

GeoJSON позволяет создавать внутренние области.

{
  "type": "Polygon",
  "coordinates": [
    [
      [0,0],
      [10,0],
      [10,10],
      [0,10],
      [0,0]
    ],
    [
      [3,3],
      [7,3],
      [7,7],
      [3,7],
      [3,3]
    ]
  ]
}

Первый массив описывает внешний контур.

Второй массив формирует отверстие.


MultiPolygon

Набор полигонов.

{
  "type": "MultiPolygon",
  "coordinates": [
    [
      [
        [0,0],
        [10,0],
        [10,10],
        [0,10],
        [0,0]
      ]
    ],
    [
      [
        [20,20],
        [30,20],
        [30,30],
        [20,30],
        [20,20]
      ]
    ]
  ]
}

Применяется для:

  • архипелагов;
  • территорий государств;
  • административных регионов.

Feature

Концепция Feature

В реальных проектах недостаточно хранить только геометрию.

Необходимо также сохранять характеристики объекта:

  • название;
  • население;
  • тип;
  • категорию;
  • статистику.

Для этого используется структура Feature.

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [76.889709, 43.238949]
  },
  "properties": {
    "name": "Almaty",
    "population": 1977000
  }
}

Geometry

Блок geometry содержит пространственные данные.

"geometry": {
  "type": "Point",
  "coordinates": [76.889709, 43.238949]
}

Properties

Блок properties содержит атрибуты.

"properties": {
  "name": "Almaty",
  "population": 1977000,
  "country": "Kazakhstan"
}

Именно эти поля становятся доступны в:

  • всплывающих подсказках;
  • фильтрах;
  • легендах;
  • стилях отображения;
  • цветовых шкалах Kepler.gl.

FeatureCollection

Назначение

Для хранения множества объектов используется FeatureCollection.

Это наиболее распространённый формат GeoJSON.

{
  "type": "FeatureCollection",
  "features": []
}

Пример

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [76.88, 43.23]
      },
      "properties": {
        "name": "Location A"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [76.90, 43.25]
      },
      "properties": {
        "name": "Location B"
      }
    }
  ]
}

Именно такие файлы чаще всего импортируются в Kepler.gl.


Загрузка GeoJSON в Kepler.gl

Импорт через интерфейс

Файл:

data.geojson

может быть загружен через механизм Drag & Drop.

После загрузки Kepler.gl автоматически:

  1. анализирует структуру;
  2. определяет типы геометрии;
  3. строит слой;
  4. создаёт таблицу атрибутов.

Импорт программно

import { addDataToMap } from "@kepler.gl/actions";

dispatch(
  addDataToMap({
    datasets: {
      info: {
        label: "Cities"
      },
      data: geojsonObject
    }
  })
);

Пример объекта

const geojsonObject = {
  type: "FeatureCollection",
  features: [
    {
      type: "Feature",
      geometry: {
        type: "Point",
        coordinates: [76.889709, 43.238949]
      },
      properties: {
        city: "Almaty"
      }
    }
  ]
};

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

Нередко данные поступают из API в обычном JSON.

Исходный формат:

[
  {
    "name": "A",
    "lat": 43.23,
    "lng": 76.88
  },
  {
    "name": "B",
    "lat": 43.25,
    "lng": 76.90
  }
]

Для работы в Kepler.gl их удобно преобразовать в GeoJSON.


Пример преобразования

const geojson = {
  type: "FeatureCollection",
  features: data.map(item => ({
    type: "Feature",
    geometry: {
      type: "Point",
      coordinates: [
        item.lng,
        item.lat
      ]
    },
    properties: {
      name: item.name
    }
  }))
};

Валидация GeoJSON

Перед загрузкой данных важно убедиться в корректности структуры.

Минимальная проверка:

function isGeoJSON(data) {
  return (
    data &&
    typeof data === "object" &&
    data.type
  );
}

Более строгая проверка:

function isFeatureCollection(data) {
  return (
    data.type === "FeatureCollection" &&
    Array.isArray(data.features)
  );
}

Производительность при работе с GeoJSON

Размер файла

GeoJSON является текстовым форматом.

Большие наборы данных могут занимать десятки и сотни мегабайт.

Пример:

10 000 объектов → несколько мегабайт
100 000 объектов → десятки мегабайт
1 000 000 объектов → сотни мегабайт

Упрощение геометрии

Для полигонов рекомендуется уменьшать число вершин.

Например:

50 000 точек контура
↓
2 000 точек контура

Это существенно ускоряет:

  • загрузку;
  • рендеринг;
  • фильтрацию;
  • масштабирование.

Использование атрибутов

Не следует помещать в properties лишние данные.

Плохо:

{
  "properties": {
    "hugeText": "многостраничное описание..."
  }
}

Хорошо:

{
  "properties": {
    "id": 15,
    "name": "Object"
  }
}

Частые ошибки

Перепутаны координаты

Ошибка:

[43.23, 76.88]

Правильно:

[76.88, 43.23]

Незамкнутый полигон

Ошибка:

[
  [0,0],
  [10,0],
  [10,10],
  [0,10]
]

Правильно:

[
  [0,0],
  [10,0],
  [10,10],
  [0,10],
  [0,0]
]

Отсутствует поле type

Ошибка:

{
  "coordinates": [76.88, 43.23]
}

Правильно:

{
  "type": "Point",
  "coordinates": [76.88, 43.23]
}

Неверная структура FeatureCollection

Ошибка:

{
  "type": "FeatureCollection",
  "items": []
}

Правильно:

{
  "type": "FeatureCollection",
  "features": []
}

Сравнение JSON и GeoJSON

Характеристика JSON GeoJSON
Основан на JSON Да Да
Подходит для любых данных Да Частично
Хранит геометрию Нет Да
Поддерживает карты Нет Да
Поддерживается Kepler.gl Да Да
Автоматическое определение объектов карты Нет Да
Стандартизированная структура координат Нет Да

В контексте Kepler.gl обычный JSON чаще применяется для хранения настроек приложения и состояния карты, тогда как GeoJSON выступает основным форматом пространственных данных. Большинство наборов географической информации, импортируемых в карту, представляют собой FeatureCollection, содержащие набор объектов Feature с геометрией и атрибутами, пригодными для фильтрации, стилизации и аналитической визуализации.