Парсинг и запись GeoJSON

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

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

  • Feature — объект с геометрией и набором атрибутов

  • FeatureCollection — коллекция объектов

  • Геометрии:

    • Point
    • LineString
    • Polygon
    • MultiPoint
    • MultiLineString
    • MultiPolygon
    • GeometryCollection

Структура Feature:

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [30.5, 50.5]
  },
  "properties": {
    "name": "Объект",
    "id": 1
  }
}

Структура FeatureCollection:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [30.5, 50.5]
      },
      "properties": {
        "name": "A"
      }
    }
  ]
}

Механизм работы GeoJSON в OpenLayers

В OpenLayers работа с GeoJSON реализуется через модуль форматов, где основным инструментом выступает класс ol/format/GeoJSON.

Он выполняет две ключевые операции:

  • Чтение (parse) GeoJSON → объекты OpenLayers
  • Запись (serialize) объектов OpenLayers → GeoJSON

Ключевая особенность заключается в преобразовании между:

  • геометриями GeoJSON
  • внутренними объектами ol/geom/*
  • объектами ol/Feature

Класс ol.format.GeoJSON

Основной класс для работы с GeoJSON:

import GeoJSON from 'ol/format/GeoJSON';

Создание экземпляра:

const geojsonFormat = new GeoJSON();

Поддерживаемые операции:

  • readFeature()
  • readFeatures()
  • readGeometry()
  • writeFeature()
  • writeFeatures()
  • writeGeometry()

Чтение GeoJSON: преобразование в Feature

Чтение одного объекта:

const feature = geojsonFormat.readFeature(geojsonObject);

Чтение коллекции:

const features = geojsonFormat.readFeatures(geojsonObject);

При чтении выполняется:

  • создание ol.Feature
  • преобразование координат в проекцию карты
  • восстановление атрибутов properties

Работа с VectorSource

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

import VectorSource from 'ol/source/Vector';

const source = new VectorSource({
  features: geojsonFormat.readFeatures(geojsonObject)
});

или более компактно:

const source = new VectorSource({
  features: new GeoJSON().readFeatures(geojsonObject)
});

Далее источник подключается к векторному слою:

import VectorLayer from 'ol/layer/Vector';

const layer = new VectorLayer({
  source: source
});

Проекции при чтении GeoJSON

GeoJSON по спецификации использует координаты в WGS84 (EPSG:4326), тогда как карты OpenLayers часто работают в EPSG:3857.

Несоответствие устраняется параметрами:

const features = geojsonFormat.readFeatures(geojsonObject, {
  dataProjection: 'EPSG:4326',
  featureProjection: 'EPSG:3857'
});

dataProjection — исходная система координат GeoJSON featureProjection — целевая система координат карты

Игнорирование проекций приводит к смещению объектов и некорректному отображению.


Чтение геометрии отдельно

Возможна работа только с геометрией без Feature:

const geometry = geojsonFormat.readGeometry(geojsonGeometryObject);

Применение:

  • вычисления
  • анализ расстояний
  • геометрическая обработка без атрибутов

Запись объектов OpenLayers в GeoJSON

Обратное преобразование выполняется методами writeFeature и writeFeatures.

Запись одного объекта:

const geojson = geojsonFormat.writeFeature(feature);

Запись массива:

const geojson = geojsonFormat.writeFeatures(features);

Результат — строка JSON или объект (в зависимости от параметров).


Контроль системы координат при записи

При сериализации также требуется указание проекций:

const geojson = geojsonFormat.writeFeatures(features, {
  dataProjection: 'EPSG:4326',
  featureProjection: 'EPSG:3857'
});

Здесь выполняется обратное преобразование:

  • из внутренней проекции карты
  • в стандарт GeoJSON

Запись геометрии

const geometryGeoJSON = geojsonFormat.writeGeometry(geometry);

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

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

Настройка формата GeoJSON

Конструктор ol.format.GeoJSON поддерживает параметры:

const format = new GeoJSON({
  featureProjection: 'EPSG:3857',
  dataProjection: 'EPSG:4326',
  geometryName: 'geometry'
});

Параметр geometryName определяет поле, где хранится геометрия, если структура отличается от стандартной.


Работа с кастомными properties

GeoJSON позволяет хранить произвольные атрибуты в properties. OpenLayers сохраняет их без изменений.

Пример:

const feature = new Feature({
  geometry: new Point([0, 0]),
  name: 'Объект',
  type: 'marker'
});

При сериализации:

const json = geojsonFormat.writeFeature(feature);

результат:

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [0, 0]
  },
  "properties": {
    "name": "Объект",
    "type": "marker"
  }
}

Чтение GeoJSON из строки

OpenLayers поддерживает прямой парсинг строкового JSON:

const features = geojsonFormat.readFeatures(geojsonString);

Внутри выполняется:

  • JSON.parse
  • преобразование в объекты OpenLayers

Асинхронная загрузка GeoJSON

Чаще всего GeoJSON поступает с сервера:

fetch('/data/points.geojson')
  .then(response => response.json())
  .then(data => {
    const features = geojsonFormat.readFeatures(data);
    source.addFeatures(features);
  });

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


Особенности сериализации больших наборов данных

При работе с крупными коллекциями:

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

Оптимизация достигается через:

  • частичную загрузку данных
  • кластеризацию
  • использование tile-based источников вместо полного GeoJSON

Ограничения и особенности формата

При работе с GeoJSON в OpenLayers учитываются особенности стандарта:

  • поддерживается только геометрия в виде координатных массивов
  • нет поддержки кривых (Bezier, spline) в нативном виде
  • координаты всегда в порядке [x, y] (долгота, широта)
  • порядок координат фиксирован и не зависит от локали

Типичные причины некорректного отображения данных

На практике ошибки возникают из-за:

  • отсутствия указания featureProjection
  • неверного dataProjection
  • перепутанного порядка координат
  • передачи строк вместо объектов GeoJSON
  • несоответствия структуры FeatureCollection

Корректная работа формата напрямую зависит от согласованности системы координат и структуры входных данных.