В архитектуре OpenLayers ключевую роль играет слой форматов
(ol/format), обеспечивающий чтение и запись геоданных в
различных представлениях. Практическая работа с картографическими
сервисами почти всегда требует преобразования данных между форматами, а
также согласования систем координат.
Форматы в OpenLayers представляют собой классы, инкапсулирующие:
ol/Featureol/Feature обратно в строковые или
бинарные форматыБазовая единица обмена в OpenLayers — Feature,
содержащий геометрию (ol/geom) и набор атрибутов.
GeoJSON остаётся наиболее распространённым форматом обмена геоданными
в веб-картографии. В OpenLayers он обрабатывается классом
ol/format/GeoJSON.
import GeoJSON from 'ol/format/GeoJSON';
const geojsonFormat = new GeoJSON();
const features = geojsonFormat.readFeatures(geojsonObject, {
featureProjection: 'EPSG:3857'
});
geojsonObject может быть строкой или объектомfeatureProjection определяет целевую систему координат
картыEPSG:4326, поэтому
часто требуется преобразование в EPSG:3857const 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';
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, используемая
тайловыми картамиФормат WKT используется в ГИС-системах и базах данных (PostGIS,
Oracle Spatial). В OpenLayers он поддерживается через
ol/format/WKT.
import WKT from 'ol/format/WKT';
const wktFormat = new WKT();
const feature = wktFormat.readFeature(
'POINT(30 10)',
{
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857'
}
);
const wkt = wktFormat.writeFeature(feature, {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857'
});
KML применяется в Google Earth и ряде GIS-инструментов. В OpenLayers
используется ol/format/KML.
import KML from 'ol/format/KML';
const kmlFormat = new KML({
extractStyles: true
});
const features = kmlFormat.readFeatures(kmlString, {
featureProjection: 'EPSG:3857'
});
const kml = kmlFormat.writeFeatures(features, {
featureProjection: 'EPSG:3857'
});
GPX используется в навигации и трекинге GPS. В OpenLayers применяется
ol/format/GPX.
import GPX from 'ol/format/GPX';
const gpxFormat = new GPX();
const features = gpxFormat.readFeatures(gpxData, {
featureProjection: 'EPSG:3857'
});
GPX обычно содержит:
trk)rte)wpt)const gpx = gpxFormat.writeFeatures(features, {
featureProjection: 'EPSG:3857'
});
Типичный поток данных в OpenLayers выглядит следующим образом:
Внешний формат (GeoJSON / KML / WKT / GPX)
↓ readFeatures()
ol/Feature[]
↓ трансформация геометрии (proj)
Внутреннее представление карты (EPSG:3857)
↓ отображение слоёв
Vector Layer
↓ взаимодействие пользователя
↓ writeFeatures()
Внешний формат для API / хранения
При работе с несколькими источниками данных часто возникает ситуация:
EPSG:4326EPSG:3857const geojsonFormat = new GeoJSON();
const features = geojsonFormat.readFeatures(data, {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857'
});
Иногда требуется изменить проекцию без перехода через текстовый формат.
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) могут включать стили, которые:
Пример ограничения:
Большинство форматов работают с массивами объектов:
const geojson = {
type: 'FeatureCollection',
features: [...]
};
При больших объёмах данных используется пакетная обработка:
const features = geojsonFormat.readFeatures(geojson, {
featureProjection: 'EPSG:3857'
});
Оптимизация:
Типичный серверный обмен:
const payload = geojsonFormat.writeFeatures(features, {
featureProjection: 'EPSG:3857',
dataProjection: 'EPSG:4326'
});
const features = geojsonFormat.readFeatures(response, {
featureProjection: 'EPSG:3857'
});
OpenLayers позволяет выполнять цепочки преобразований:
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'
});
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'
});
Некоторые форматы содержат вложенные геометрии:
OpenLayers автоматически разворачивает такие структуры в
ol/geom:
const feature = geojsonFormat.readFeature(geojsonObject, {
featureProjection: 'EPSG:3857'
});
const geometry = feature.getGeometry();
На практике встречаются типовые проблемы:
type,
coordinates)При работе с большими наборами данных используется потоковая стратегия:
Форматы напрямую связаны с VectorSource:
import VectorSource from 'ol/source/Vector';
const source = new VectorSource({
features: new GeoJSON().readFeatures(data, {
featureProjection: 'EPSG:3857'
})
});
Любое обновление данных проходит через повторную конвертацию.
Слой форматов выполняет функцию промежуточного адаптера между:
Все операции конвертации сводятся к единому принципу: приведение
данных к Feature и обратное преобразование при
экспорте.