Конвертация между форматами

В архитектуре OpenLayers ключевую роль играет слой форматов (ol/format), обеспечивающий чтение и запись геоданных в различных представлениях. Практическая работа с картографическими сервисами почти всегда требует преобразования данных между форматами, а также согласования систем координат.

Форматы в OpenLayers представляют собой классы, инкапсулирующие:

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

Базовая единица обмена в OpenLayers — Feature, содержащий геометрию (ol/geom) и набор атрибутов.


Конвертация GeoJSON ↔︎ Feature

GeoJSON остаётся наиболее распространённым форматом обмена геоданными в веб-картографии. В OpenLayers он обрабатывается классом ol/format/GeoJSON.

Чтение GeoJSON

import GeoJSON from 'ol/format/GeoJSON';

const geojsonFormat = new GeoJSON();

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

Ключевые аспекты чтения

  • geojsonObject может быть строкой или объектом
  • featureProjection определяет целевую систему координат карты
  • по умолчанию GeoJSON использует EPSG:4326, поэтому часто требуется преобразование в EPSG:3857

Запись GeoJSON

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

Основные параметры

  • featureProjection — текущая система координат объектов
  • dataProjection — целевая система координат выходного GeoJSON

Типичный сценарий: карта работает в Web Mercator, но сервер ожидает WGS84.


Преобразование систем координат

Модуль ol/proj обеспечивает фундаментальные операции трансформации координат.

Базовые функции

import { fromLonLat, toLonLat, transform } from 'ol/proj';

Перевод из WGS84 в Web Mercator

const coord = fromLonLat([69.6, 42.8]);

Эквивалент:

transform([69.6, 42.8], 'EPSG:4326', 'EPSG:3857');

Обратное преобразование

const lonLat = toLonLat([7740000, 5200000]);

Смысл преобразований

  • EPSG:4326 — географические координаты (долгота/широта)
  • EPSG:3857 — проекция Web Mercator, используемая тайловыми картами
  • все визуальные слои в большинстве картографических приложений используют 3857

WKT (Well-Known Text)

Формат WKT используется в ГИС-системах и базах данных (PostGIS, Oracle Spatial). В OpenLayers он поддерживается через ol/format/WKT.

Чтение WKT

import WKT from 'ol/format/WKT';

const wktFormat = new WKT();

const feature = wktFormat.readFeature(
  'POINT(30 10)',
  {
    dataProjection: 'EPSG:4326',
    featureProjection: 'EPSG:3857'
  }
);

Запись WKT

const wkt = wktFormat.writeFeature(feature, {
  dataProjection: 'EPSG:4326',
  featureProjection: 'EPSG:3857'
});

Особенности WKT

  • компактное текстовое представление геометрии
  • не поддерживает сложные атрибуты (только геометрия)
  • широко используется в SQL-запросах
  • менее удобен для веба по сравнению с GeoJSON

KML (Keyhole Markup Language)

KML применяется в Google Earth и ряде GIS-инструментов. В OpenLayers используется ol/format/KML.

Чтение KML

import KML from 'ol/format/KML';

const kmlFormat = new KML({
  extractStyles: true
});

const features = kmlFormat.readFeatures(kmlString, {
  featureProjection: 'EPSG:3857'
});

Запись KML

const kml = kmlFormat.writeFeatures(features, {
  featureProjection: 'EPSG:3857'
});

Особенности KML

  • поддерживает стилизацию (цвет, иконки, линии)
  • включает описание объектов (balloon popups)
  • ориентирован на 3D и Google Earth
  • XML-структура увеличивает размер данных

GPX (GPS Exchange Format)

GPX используется в навигации и трекинге GPS. В OpenLayers применяется ol/format/GPX.

Чтение GPX

import GPX from 'ol/format/GPX';

const gpxFormat = new GPX();

const features = gpxFormat.readFeatures(gpxData, {
  featureProjection: 'EPSG:3857'
});

Содержимое GPX

GPX обычно содержит:

  • треки (trk)
  • точки маршрута (rte)
  • путевые точки (wpt)

Запись GPX

const gpx = gpxFormat.writeFeatures(features, {
  featureProjection: 'EPSG:3857'
});

Особенности GPX

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

Обобщённая схема преобразования данных

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

Внешний формат (GeoJSON / KML / WKT / GPX)
        ↓ readFeatures()
ol/Feature[]
        ↓ трансформация геометрии (proj)
Внутреннее представление карты (EPSG:3857)
        ↓ отображение слоёв
Vector Layer
        ↓ взаимодействие пользователя
        ↓ writeFeatures()
Внешний формат для API / хранения

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

При работе с несколькими источниками данных часто возникает ситуация:

  • GeoJSON приходит в EPSG:4326
  • WMS слой в EPSG:3857
  • пользовательские координаты в локальной проекции

Пример унификации

const geojsonFormat = new GeoJSON();

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

Преобразование Feature → Feature без сериализации

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

import { transformGeometry } from 'ol/format/Feature';

Практический подход:

import { transform } from 'ol/proj';

geometry.applyTransform((coords, coords2, stride) => {
  for (let i = 0; i < coords.length; i += stride) {
    const [x, y] = transform(
      [coords[i], coords[i + 1]],
      'EPSG:4326',
      'EPSG:3857'
    );

    coords2[i] = x;
    coords2[i + 1] = y;
  }
});

Форматы и стили: влияние на конвертацию

Некоторые форматы (KML, GeoJSON Extended) могут включать стили, которые:

  • не всегда поддерживаются при обратной записи
  • могут теряться при преобразовании в WKT или GPX
  • требуют ручной обработки

Пример ограничения:

  • GeoJSON → сохраняет свойства, но не стили
  • KML → сохраняет стили, но сложен для серверной обработки
  • WKT → теряет всё, кроме геометрии

FeatureCollection и пакетная обработка

Большинство форматов работают с массивами объектов:

const geojson = {
  type: 'FeatureCollection',
  features: [...]
};

При больших объёмах данных используется пакетная обработка:

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

Оптимизация:

  • минимизация пересчётов проекций
  • повторное использование форматов
  • кэширование результатов парсинга

Сериализация и десериализация в API

Типичный серверный обмен:

От клиента к серверу

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

От сервера к клиенту

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

Преобразование между форматами

OpenLayers позволяет выполнять цепочки преобразований:

GeoJSON → WKT

const geojsonFormat = new GeoJSON();
const wktFormat = new WKT();

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

const wkt = wktFormat.writeFeature(features[0], {
  featureProjection: 'EPSG:3857',
  dataProjection: 'EPSG:4326'
});

KML → GeoJSON

const kmlFormat = new KML();
const geojsonFormat = new GeoJSON();

const features = kmlFormat.readFeatures(kmlData, {
  featureProjection: 'EPSG:3857'
});

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

Работа с вложенными структурами данных

Некоторые форматы содержат вложенные геометрии:

  • MultiPolygon
  • MultiLineString
  • GeometryCollection

OpenLayers автоматически разворачивает такие структуры в ol/geom:

const feature = geojsonFormat.readFeature(geojsonObject, {
  featureProjection: 'EPSG:3857'
});

const geometry = feature.getGeometry();

Ошибки и несовместимости форматов

На практике встречаются типовые проблемы:

  • несоответствие CRS (Coordinate Reference System)
  • отсутствие обязательных полей (type, coordinates)
  • некорректный порядок координат (lat/lon vs lon/lat)
  • потеря точности при преобразованиях
  • несовместимость расширений KML

Масштабируемая обработка потоков данных

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

  • разбиение FeatureCollection
  • частичная десериализация
  • ленивое преобразование геометрии
  • минимизация операций reprojection

Взаимодействие форматов с векторными слоями

Форматы напрямую связаны с VectorSource:

import VectorSource from 'ol/source/Vector';

const source = new VectorSource({
  features: new GeoJSON().readFeatures(data, {
    featureProjection: 'EPSG:3857'
  })
});

Любое обновление данных проходит через повторную конвертацию.


Роль форматов в архитектуре картографического приложения

Слой форматов выполняет функцию промежуточного адаптера между:

  • API (REST / GraphQL / WFS)
  • локальными источниками данных
  • файловыми системами (KML, GPX)
  • визуализацией на карте
  • пользовательским вводом

Все операции конвертации сводятся к единому принципу: приведение данных к Feature и обратное преобразование при экспорте.