OpenLayers предоставляет мощный механизм работы с векторными данными, который лежит в основе большинства интерактивных картографических приложений. Векторные слои позволяют отображать геометрические объекты — точки, линии и полигоны — с гибкой стилизацией, динамическим обновлением и привязкой к данным из различных источников.
Векторный слой в OpenLayers строится на взаимодействии трёх ключевых компонентов:
Слой отвечает за визуализацию, источник — за хранение и загрузку данных, а объект Feature — за представление конкретной геометрии с атрибутами.
Базовая структура выглядит следующим образом:
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';
const feature = new Feature({
geometry: new Point([0, 0]),
});
const source = new VectorSource({
features: [feature],
});
const layer = new VectorLayer({
source: source,
});
Векторные слои работают с несколькими типами геометрий:
Каждый тип геометрии поддерживает пространственные операции, такие как трансформации координат и вычисление длины или площади.
Пример линии:
import LineString from 'ol/geom/LineString';
const line = new LineString([
[0, 0],
[10, 10],
[20, 0],
]);
VectorSource поддерживает несколько способов загрузки данных:
const source = new VectorSource({
features: [feature1, feature2],
});
source.addFeature(new Feature({
geometry: new Point([100, 100]),
}));
OpenLayers поддерживает загрузку данных через форматные парсеры:
Пример загрузки GeoJSON:
import GeoJSON from 'ol/format/GeoJSON';
const source = new VectorSource({
url: 'data/points.geojson',
format: new GeoJSON(),
});
GeoJSON является наиболее распространённым форматом для векторных слоёв. Он позволяет описывать геометрии и свойства объектов в стандартизированном JSON-формате.
Пример структуры:
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [30, 50]
},
"properties": {
"name": "Объект"
}
}
При загрузке OpenLayers автоматически преобразует координаты в объекты Feature.
Стилизация определяет визуальное представление объектов слоя. Она
задаётся через ol/style.
Основные элементы стиля:
Пример стиля полигона:
import Style from 'ol/style/Style';
import Fill from 'ol/style/Fill';
import Stroke from 'ol/style/Stroke';
const style = new Style({
fill: new Fill({
color: 'rgba(0, 150, 255, 0.3)',
}),
stroke: new Stroke({
color: '#3399CC',
width: 2,
}),
});
Применение стиля к слою:
const layer = new VectorLayer({
source: source,
style: style,
});
Стиль может задаваться функцией, что позволяет изменять внешний вид объектов в зависимости от их свойств.
const layer = new VectorLayer({
source: source,
style: function (feature) {
const type = feature.get('type');
if (type === 'city') {
return cityStyle;
}
return defaultStyle;
},
});
Такой подход применяется для тематических карт и визуализации данных.
VectorLayer поддерживает взаимодействие через события и выбор объектов.
map.forEachFeatureAtPixel(pixel, function (feature) {
console.log(feature.getProperties());
});
Выделение часто реализуется изменением стиля:
feature.setStyle(highlightStyle);
VectorSource позволяет динамически обновлять данные без перезагрузки карты.
setInterval(() => {
const feature = new Feature({
geometry: new Point([Math.random() * 100, Math.random() * 100]),
});
source.addFeature(feature);
}, 1000);
Такой механизм используется для отображения движущихся объектов, сенсорных данных и трекинга.
При работе с большим количеством объектов важно управлять источником данных:
source.clear();
Удаление отдельных объектов:
source.removeFeature(feature);
Эффективное управление объектами напрямую влияет на производительность визуализации.
Геометрии векторных слоёв поддерживают операции:
Пример вычисления площади полигона:
import Polygon from 'ol/geom/Polygon';
const polygon = new Polygon([
[
[0, 0],
[10, 0],
[10, 10],
[0, 10],
[0, 0],
],
]);
const area = polygon.getArea();
При большом количестве точек используется кластеризация через
Cluster source.
import Cluster from 'ol/source/Cluster';
const clusterSource = new Cluster({
distance: 40,
source: source,
});
Кластеры позволяют объединять близко расположенные объекты в группы, снижая нагрузку на рендеринг.
Основные факторы оптимизации:
VectorLayer может работать в Canvas и WebGL режимах, что влияет на скорость отрисовки.
При работе с тысячами объектов рекомендуется:
Пример фильтрации:
const filtered = source.getFeatures().filter((f) => {
return f.get('population') > 100000;
});
Атрибуты Feature используются для создания тематических карт.
const styleFunction = (feature) => {
const value = feature.get('value');
return new Style({
fill: new Fill({
color: value > 50 ? 'red' : 'green',
}),
});
};
Такой подход используется в картограммах и аналитических визуализациях.
VectorLayer и VectorSource поддерживают события:
Пример:
source.on('addfeature', function (event) {
console.log('Добавлен объект:', event.feature);
});
События позволяют строить реактивные интерфейсы поверх карты.
VectorSource может автоматически преобразовывать координаты между системами (например, EPSG:4326 и EPSG:3857).
import { fromLonLat } from 'ol/proj';
const feature = new Feature({
geometry: new Point(fromLonLat([30, 50])),
});
Корректная работа с проекциями критична для точного отображения данных.
Карты часто содержат несколько векторных слоёв:
map.addLayer(pointLayer);
map.addLayer(routeLayer);
map.addLayer(boundaryLayer);
Порядок добавления влияет на порядок отображения.
VectorLayer использует механизм diff-рендеринга: обновляются только изменённые объекты. Это снижает нагрузку при частых изменениях данных.
При изменении стиля или источника происходит перерасчёт отображения слоя.
VectorLayer часто интегрируется с UI-компонентами:
Каждое изменение в интерфейсе может приводить к обновлению источника данных и перерисовке слоя.