GPX (GPS Exchange Format) представляет собой XML-формат, предназначенный для хранения и обмена данными GPS-треков, маршрутов и точек интереса. В экосистеме веб-картографии GPX используется как один из наиболее распространённых способов загрузки пользовательских маршрутов в картографические приложения, включая решения на базе OpenLayers.
Структура GPX основана на иерархии XML-элементов, где основными сущностями выступают:
Каждый элемент содержит географические координаты (широта, долгота), а также может включать высоту, временные метки и расширенные метаданные.
Типичный GPX-файл начинается с декларации XML и корневого элемента:
<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="ExampleApp">
<metadata>
<name>Маршрут похода</name>
</metadata>
<wpt lat="52.2297" lon="21.0122">
<name>Точка старта</name>
</wpt>
<trk>
<name>Основной трек</name>
<trkseg>
<trkpt lat="52.2297" lon="21.0122"></trkpt>
<trkpt lat="52.2300" lon="21.0130"></trkpt>
</trkseg>
</trk>
</gpx>
gpx Корневой элемент, определяющий версию формата и пространство данных.
metadata Содержит метаинформацию: название, описание, автора, временные метки.
wpt Одиночная точка с координатами:
trk Группа точек, формирующая линию движения.
trkseg Сегмент трека, позволяющий разделять маршрут на логические части.
trkpt Отдельная точка трека.
OpenLayers поддерживает GPX через модуль ol/format/GPX.
Этот формат используется для чтения и записи геоданных, а также
преобразования их в объекты слоя (Feature), которые могут
быть отображены на карте.
Основная задача GPX-парсера в OpenLayers — преобразование XML-структуры в векторные объекты:
PointLineStringLineStringЗагрузка GPX осуществляется через ol/format/GPX
совместно с источником данных (VectorSource).
import GPX from 'ol/format/GPX.js';
import VectorSource from 'ol/source/Vector.js';
import VectorLayer from 'ol/layer/Vector.js';
const gpxFormat = new GPX();
const vectorSource = new VectorSource({
url: 'route.gpx',
format: gpxFormat
});
const vectorLayer = new VectorLayer({
source: vectorSource
});
При таком подходе OpenLayers автоматически:
Для более гибкой обработки используется метод
readFeatures:
fetch('route.gpx')
.then(response => response.text())
.then(gpxText => {
const features = gpxFormat.readFeatures(gpxText, {
featureProjection: 'EPSG:3857'
});
vectorSource.addFeatures(features);
});
Параметр featureProjection критичен, поскольку GPX
хранит координаты в WGS84 (EPSG:4326), тогда как
большинство веб-карт используют Web Mercator
(EPSG:3857).
OpenLayers автоматически поддерживает трансформацию координат при чтении GPX:
Пример явного указания систем координат:
const features = gpxFormat.readFeatures(gpxText, {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857'
});
Разделение dataProjection и
featureProjection позволяет корректно интерпретировать
данные независимо от источника.
Каждый wpt преобразуется в объект Feature с
геометрией Point.
Пример обработки:
const features = gpxFormat.readFeatures(gpxText);
const waypoints = features.filter(f => f.getGeometry().getType() === 'Point');
Типичные сценарии использования:
Элементы trkseg и trkpt объединяются в
LineString.
const trackFeatures = features.filter(f =>
f.getGeometry().getType() === 'LineString'
);
Треки часто содержат:
rte аналогично преобразуется в линию, но логически
отличается от трека:
GPX поддерживает параметр ele, который может
использоваться для 3D-визуализации.
<trkpt lat="52.2297" lon="21.0122">
<ele>180.5</ele>
</trkpt>
OpenLayers может сохранять высоту как третий компонент координаты:
const features = gpxFormat.readFeatures(gpxText, {
featureProjection: 'EPSG:3857'
});
features.forEach(feature => {
const geom = feature.getGeometry();
const coords = geom.getCoordinates();
});
При наличии Z-значений возможно построение профиля
высот.
После загрузки GPX данные требуют стилизации через Style
API.
import Style from 'ol/style/Style.js';
import Stroke from 'ol/style/Stroke.js';
const trackStyle = new Style({
stroke: new Stroke({
color: '#ff3300',
width: 3
})
});
import CircleStyle from 'ol/style/Circle.js';
import Fill from 'ol/style/Fill.js';
const pointStyle = new Style({
image: new CircleStyle({
radius: 5,
fill: new Fill({ color: '#0066ff' })
})
});
const styleFunction = (feature) => {
const type = feature.getGeometry().getType();
if (type === 'Point') {
return pointStyle;
}
if (type === 'LineString') {
return trackStyle;
}
};
OpenLayers позволяет экспортировать векторные данные обратно в GPX
через writeFeatures.
const gpxString = gpxFormat.writeFeatures(features, {
featureProjection: 'EPSG:3857',
dataProjection: 'EPSG:4326'
});
Полученный XML можно сохранить как файл:
const blob = new Blob([gpxString], { type: 'application/gpx+xml' });
const url = URL.createObjectURL(blob);
GPX-данные часто требуют предварительной обработки:
const filteredCoords = coords.filter((coord, index) => {
if (index === 0) return true;
const prev = coords[index - 1];
const distance = Math.hypot(
coord[0] - prev[0],
coord[1] - prev[1]
);
return distance > 0.00001;
});
const segments = [];
let currentSegment = [];
coords.forEach((coord, i) => {
if (i > 0 && isGap(coord, coords[i - 1])) {
segments.push(currentSegment);
currentSegment = [];
}
currentSegment.push(coord);
});
GPX может содержать расширенные данные:
<extensions>
<speed>12.5</speed>
<temperature>18</temperature>
</extensions>
OpenLayers не интерпретирует расширения автоматически, но позволяет извлекать их через:
const properties = feature.getProperties();
При больших треках возникают ограничения:
Оптимизационные подходы:
renderMode: 'vector'const vectorLayer = new VectorLayer({
renderMode: 'vector',
source: vectorSource
});
GPX часто используется вместе с:
OpenLayers позволяет объединять источники:
const source = new VectorSource({
features: [
...gpxFeatures,
...geoJsonFeatures
]
});
На основе GPX можно вычислять:
Пример вычисления длины:
import { getLength } from 'ol/sphere.js';
const length = getLength(lineString);
Разные устройства GPS формируют GPX по-разному:
Это требует: