Векторные слои

OpenLayers предоставляет мощный механизм работы с векторными данными, который лежит в основе большинства интерактивных картографических приложений. Векторные слои позволяют отображать геометрические объекты — точки, линии и полигоны — с гибкой стилизацией, динамическим обновлением и привязкой к данным из различных источников.

Архитектура векторного слоя

Векторный слой в OpenLayers строится на взаимодействии трёх ключевых компонентов:

  • ol/layer/Vector — слой отображения
  • ol/source/Vector — источник данных
  • ol/Feature — геометрический объект

Слой отвечает за визуализацию, источник — за хранение и загрузку данных, а объект 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,
});

Геометрические типы данных

Векторные слои работают с несколькими типами геометрий:

  • Point — точечные объекты (метки, маркеры)
  • LineString — линии (маршруты, дороги)
  • Polygon — полигоны (границы, зоны)
  • MultiPoint, MultiLineString, MultiPolygon — коллекции геометрий

Каждый тип геометрии поддерживает пространственные операции, такие как трансформации координат и вычисление длины или площади.

Пример линии:

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
  • KML
  • GPX
  • WKT

Пример загрузки GeoJSON:

import GeoJSON from 'ol/format/GeoJSON';

const source = new VectorSource({
  url: 'data/points.geojson',
  format: new GeoJSON(),
});

Работа с GeoJSON

GeoJSON является наиболее распространённым форматом для векторных слоёв. Он позволяет описывать геометрии и свойства объектов в стандартизированном JSON-формате.

Пример структуры:

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [30, 50]
  },
  "properties": {
    "name": "Объект"
  }
}

При загрузке OpenLayers автоматически преобразует координаты в объекты Feature.

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

Стилизация определяет визуальное представление объектов слоя. Она задаётся через ol/style.

Основные элементы стиля:

  • Fill — заливка
  • Stroke — линия контура
  • Circle — точечные символы
  • Icon — изображения

Пример стиля полигона:

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

Кластеры позволяют объединять близко расположенные объекты в группы, снижая нагрузку на рендеринг.

Производительность векторных слоёв

Основные факторы оптимизации:

  • ограничение количества объектов на слое
  • использование кластеризации
  • отключение ненужных перерисовок
  • применение простых стилей
  • использование WebGL-рендеринга при больших объёмах данных

VectorLayer может работать в Canvas и WebGL режимах, что влияет на скорость отрисовки.

Обработка больших наборов данных

При работе с тысячами объектов рекомендуется:

  • загружать данные частями (pagination)
  • использовать тайловые источники векторных данных
  • применять фильтрацию на уровне источника

Пример фильтрации:

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 поддерживают события:

  • addfeature
  • removefeature
  • changefeature

Пример:

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-компонентами:

  • таблицы объектов
  • фильтры
  • панели атрибутов
  • редакторы геометрий

Каждое изменение в интерфейсе может приводить к обновлению источника данных и перерисовке слоя.