Создание и добавление векторных объектов

В OpenLayers все векторные объекты представлены через сущности Feature — абстракции, объединяющие геометрию и свойства объекта. Геометрия определяет пространственное положение, а свойства (attributes) описывают семантику: название, тип, идентификаторы, числовые параметры.

Основные компоненты векторного слоя:

  • Feature — единичный объект карты
  • Geometry — геометрия (точка, линия, полигон и т.д.)
  • VectorSource — источник данных
  • VectorLayer — слой отображения

Такая архитектура разделяет хранение данных и их визуализацию, что позволяет гибко управлять отображением и логикой обработки.


Геометрии: основа векторных объектов

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: связывание геометрии и данных

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: хранилище векторных данных

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: отображение векторных данных

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);

Использование GeoJSON для загрузки векторных данных

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 строится на нескольких принципах:

  • данные отделены от отображения
  • источник управляет жизненным циклом объектов
  • слой отвечает только за рендеринг
  • Feature является минимальной единицей логики карты
  • геометрия всегда независима от стиля

Такая структура позволяет масштабировать приложения от простых карт до сложных ГИС-систем с динамическими потоками данных.