Select для выбора объектов

Sel ect — механизм взаимодействия в OpenLayers, предназначенный для выделения пространственных объектов на карте и управления состоянием их выбора. Реализуется через класс Select, входящий в модуль ol/interaction/Select. В основе лежит система интеракций (interactions), которая перехватывает события указателя и преобразует их в операции над векторными объектами.

Sel ect является специализированной интеракцией, работающей поверх слоя отображения векторных данных. Внутри используется механизм пересечения геометрий (hit detection), основанный на координатах пикселя события и геометриях фич.

Основные компоненты:

  • interaction.Select — класс взаимодействия
  • Feature — выбираемые объекты
  • Collection — коллекция выбранных элементов
  • Condition — функция условия срабатывания
  • Style — визуальное оформление выбранных объектов

Взаимодействие интегрируется в карту через метод map.addInteraction() и начинает перехватывать события указателя сразу после добавления.

Базовая модель выбора объектов

Sel ect работает по следующему принципу:

  1. Обрабатывается событие указателя (click, pointermove и т.д.)
  2. Определяется пиксель на карте
  3. Выполняется поиск пересечения с объектами слоя
  4. При совпадении объект добавляется в коллекцию выбора
  5. Генерируется событие select

Коллекция выбранных объектов хранится внутри экземпляра Select и доступна через метод getFeatures().

import Select fr om 'ol/interaction/Sel ect.js';

const select = new Select();

map.addInteraction(select);

Настройка условия выбора (condition)

Поведение выбора определяется функцией condition. Она контролирует, при каком событии происходит выделение.

Наиболее распространённые условия:

  • одиночный клик
  • удержание Shift + клик
  • наведение курсора
  • двойной клик
import Select fr om 'ol/interaction/Sel ect.js';
import { click } fr om 'ol/events/condition.js';

const sel ect = new Select({
  condition: click
});

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

Множественный выбор

Select поддерживает режим накопления выбранных объектов. При включении multi или использовании модификаторов клавиатуры возможно формирование множественного набора.

Типовой сценарий:

import Select fr om 'ol/interaction/Sel ect.js';
import { shiftKeyOnly, click } fr om 'ol/events/condition.js';

const sel ect = new Select({
  condition: function (event) {
    return click(event) && shiftKeyOnly(event);
  }
});

В этом режиме новые объекты добавляются в коллекцию без очистки предыдущих.

Доступ к выбранным объектам

Выбранные элементы хранятся в Collection. Для доступа используется:

const features = select.getFeatures();

Коллекция поддерживает стандартные методы:

  • push()
  • remove()
  • clear()
  • getLength()

Пример обхода выбранных объектов:

features.forEach(function (feature) {
  console.log(feature.getId());
});

Событие select

При изменении выбора генерируется событие select. Оно содержит информацию о новых и снятых выделениях.

Структура события:

  • selected — массив добавленных объектов
  • deselected — массив снятых объектов
select.on('select', function (event) {
  const added = event.selected;
  const removed = event.deselected;
});

Это позволяет синхронизировать выбор с внешними системами, таблицами атрибутов или интерфейсом управления данными.

Ограничение выбора по слоям

Select может быть настроен на работу только с определёнными слоями. Это реализуется через параметр layers.

const select = new Select({
  layers: function (layer) {
    return layer.get('selectable') === true;
  }
});

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

Стиль выделения объектов

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

import Style fr om 'ol/style/Style.js';
import Stroke fr om 'ol/style/Stroke.js';
import Fill fr om 'ol/style/Fill.js';

const sel ect = new Sel ect({
  style: function () {
    return new Style({
      stroke: new Stroke({
        color: 'blue',
        width: 3
      }),
      fill: new Fill({
        color: 'rgba(0, 0, 255, 0.1)'
      })
    });
  }
});

Стиль применяется поверх исходного оформления слоя, не заменяя его полностью, а накладывая визуальное выделение.

Режимы поведения Select

Select поддерживает несколько режимов работы:

Replace (замещение)

Каждое новое выделение очищает предыдущий набор.

const select = new Select({
  multi: false
});

Additive (добавление)

Новые объекты добавляются в коллекцию без очистки.

const select = new Select({
  multi: true
});

Toggle (переключение)

Повторный выбор объекта снимает выделение.

Реализуется через кастомную обработку события:

select.on('select', function (event) {
  event.deselected.forEach(function (feature) {
    select.getFeatures().remove(feature);
  });
});

Работа с pointermove (hover-выделение)

Select может работать в режиме выделения при наведении курсора. Для этого используется pointermove как условие.

import { pointerMove } fr om 'ol/events/condition.js';

const sel ect = new Select({
  condition: pointerMove
});

Такой режим применяется для подсветки объектов без фиксации выбора.

Фильтрация объектов (filter)

Дополнительная логика отбора объектов реализуется через filter. Функция проверяет каждый объект перед добавлением в коллекцию выбора.

const select = new Select({
  filter: function (feature, layer) {
    return feature.get('type') === 'road';
  }
});

Фильтрация позволяет ограничивать выбор по атрибутам, типам геометрии или состоянию слоя.

Интеграция с DragBox

Select может комбинироваться с интеракцией прямоугольного выделения области.

import DragBox fr om 'ol/interaction/DragBox.js';
import { shiftKeyOnly } fr om 'ol/events/condition.js';

const dragBox = new DragBox({
  condition: shiftKeyOnly
});

dragBox.on('boxend', function () {
  const extent = dragBox.getGeometry().getExtent();
});

После получения экстента выполняется выбор всех объектов внутри области и добавление их в коллекцию Select.

Очистка выбора

Сброс состояния выполняется через метод clear():

select.getFeatures().clear();

Очистка сопровождается генерацией события select с пустым набором выбранных элементов.

Взаимодействие с атрибутами объектов

Выбранные объекты часто используются для редактирования или отображения атрибутов. Доступ к данным осуществляется через getProperties():

select.on('select', function (event) {
  event.selected.forEach(function (feature) {
    const properties = feature.getProperties();
  });
});

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

Поведение при работе с несколькими слоями

При наличии нескольких векторных слоёв выбор может происходить одновременно на всех слоях, удовлетворяющих условиям layers и filter. Приоритет определяется порядком рендеринга и настройками прозрачности hit detection.

Особенности hit detection

Механизм выбора основан на пиксельной проверке:

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

Это обеспечивает высокую производительность даже при большом количестве объектов.

Кастомные сценарии выбора

Select допускает расширение логики через комбинирование условий и событий:

  • выбор по двойному клику
  • выбор с задержкой
  • выбор с учетом масштаба карты
  • фильтрация по текущему экстенту

Такие сценарии реализуются через композицию condition, filter и событий карты.

Связь Select с состоянием приложения

Коллекция выбранных объектов часто используется как реактивное состояние:

  • синхронизация с UI таблицами
  • отображение информации в боковых панелях
  • управление стилями других слоёв
  • связывание с редакторами геометрии

Изменение состояния выбора является центральным событием для интерфейсов, построенных вокруг интерактивной карты.