В OpenLayers все векторные объекты представлены через сущности Feature — абстракции, объединяющие геометрию и свойства объекта. Геометрия определяет пространственное положение, а свойства (attributes) описывают семантику: название, тип, идентификаторы, числовые параметры.
Основные компоненты векторного слоя:
Такая архитектура разделяет хранение данных и их визуализацию, что позволяет гибко управлять отображением и логикой обработки.
OpenLayers поддерживает несколько базовых типов геометрий:
Point — точкаLineString — линияPolygon — полигонCircle — кругMultiPoint, MultiLineString,
MultiPolygon — коллекции геометрийGeometryCollection — произвольные наборы геометрийСоздание геометрий выполняется через модуль ol/geom.
import Point from 'ol/geom/Point';
import LineString from 'ol/geom/LineString';
import Polygon from 'ol/geom/Polygon';
const point = new Point([30.5, 50.45]);
const line = new LineString([
[30.0, 50.0],
[31.0, 51.0]
]);
const polygon = new Polygon([[
[30.0, 50.0],
[31.0, 50.0],
[31.0, 51.0],
[30.0, 50.0]
]]);
Координаты задаются в системе координат карты (обычно EPSG:3857 после трансформации, либо EPSG:4326 до проекции).
Feature объединяет геометрию и атрибуты:
import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';
const feature = new Feature({
geometry: new Point([30.5, 50.45]),
name: 'Объект A',
id: 1
});
Геометрию можно задавать и отдельно:
const feature = new Feature();
feature.setGeometry(new Point([30.5, 50.45]));
feature.setProperties({
name: 'Объект B',
type: 'marker'
});
Ключевой метод:
setGeometry() — установка геометрииgetGeometry() — получение геометрииsetProperties() — массовое добавление атрибутовget() — доступ к конкретному свойствуVectorSource — контейнер для Feature-объектов. Он не отвечает за отображение, только за хранение и управление данными.
import VectorSource from 'ol/source/Vector';
const source = new VectorSource({
features: []
});
Добавление объектов:
source.addFeature(feature);
Добавление массива объектов:
source.addFeatures([feature1, feature2, feature3]);
Удаление:
source.removeFeature(feature);
Очистка:
source.clear();
Поиск:
const features = source.getFeatures();
const found = source.getFeatureById(1);
VectorLayer связывает источник данных с картой и отвечает за визуализацию.
import VectorLayer from 'ol/layer/Vector';
const vectorLayer = new VectorLayer({
source: source
});
Добавление слоя на карту:
import Map from 'ol/Map';
import View from 'ol/View';
const map = new Map({
target: 'map',
layers: [vectorLayer],
view: new View({
center: [0, 0],
zoom: 2
})
});
Полный цикл создания объекта:
import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import Map from 'ol/Map';
import View from 'ol/View';
const feature = new Feature({
geometry: new Point([30.5, 50.45]),
name: 'Город'
});
const source = new VectorSource({
features: [feature]
});
const layer = new VectorLayer({
source: source
});
const map = new Map({
target: 'map',
layers: [layer],
view: new View({
center: [30.5, 50.45],
zoom: 6
})
});
Векторные данные часто создаются во время работы приложения: по клику пользователя, по API-запросу или при обработке событий.
Добавление точки по клику:
import Point from 'ol/geom/Point';
import Feature from 'ol/Feature';
map.on('click', function (event) {
const coordinate = event.coordinate;
const feature = new Feature({
geometry: new Point(coordinate)
});
source.addFeature(feature);
});
Каждому Feature можно назначить уникальный идентификатор:
feature.setId(1001);
После этого доступ становится быстрым и удобным:
const f = source.getFeatureById(1001);
Идентификаторы важны при синхронизации с сервером и работе с GeoJSON.
При работе с большими наборами данных удобно генерировать массив Feature:
const features = [];
for (let i = 0; i < 1000; i++) {
const feature = new Feature({
geometry: new Point([
30 + Math.random(),
50 + Math.random()
])
});
feature.setId(i);
features.push(feature);
}
source.addFeatures(features);
OpenLayers поддерживает формат GeoJSON через
ol/format/GeoJSON.
import GeoJSON from 'ol/format/GeoJSON';
const format = new GeoJSON();
const features = format.readFeatures(geojsonObject, {
featureProjection: 'EPSG:3857'
});
source.addFeatures(features);
Вывод обратно в GeoJSON:
const geojson = format.writeFeatures(source.getFeatures(), {
featureProjection: 'EPSG:3857'
});
Хотя стилизация относится к отдельной теме, она тесно связана с созданием объектов.
import Style from 'ol/style/Style';
import CircleStyle from 'ol/style/Circle';
import Fill from 'ol/style/Fill';
import Stroke from 'ol/style/Stroke';
const style = new Style({
image: new CircleStyle({
radius: 6,
fill: new Fill({ color: 'red' }),
stroke: new Stroke({ color: 'black', width: 1 })
})
});
vectorLayer.setStyle(style);
Можно задавать стиль на уровне Feature:
feature.setStyle(style);
VectorSource поддерживает события, позволяющие реагировать на изменения:
source.on('addfeature', function (event) {
console.log('Добавлен объект', event.feature);
});
source.on('removefeature', function (event) {
console.log('Удалён объект', event.feature);
});
Также можно отслеживать изменения геометрии:
feature.getGeometry().on('change', function () {
console.log('Геометрия изменена');
});
Для интерактивного изменения используется Modify
interaction:
import Modify from 'ol/interaction/Modify';
const modify = new Modify({
source: source
});
map.addInteraction(modify);
После этого пользователь может перемещать вершины геометрий, изменяя объекты напрямую.
При работе с тысячами объектов важны методы оптимизации:
Очистка и перезаполнение источника:
source.clear();
source.addFeatures(newFeatures);
Геометрии можно изменять напрямую:
const geometry = feature.getGeometry();
geometry.setCoordinates([
[30.0, 50.0],
[31.0, 51.0]
]);
Для точек:
geometry.setCoordinates([32.0, 52.0]);
Изменения автоматически отражаются на карте.
Векторная модель OpenLayers строится на нескольких принципах:
Такая структура позволяет масштабировать приложения от простых карт до сложных ГИС-систем с динамическими потоками данных.