Векторное редактирование в OpenLayers требует точного контроля координат при создании и модификации геометрий. Одной из ключевых механик, обеспечивающих аккуратность редактирования, выступает Snap — взаимодействие, позволяющее «прилипать» вершинам и сегментам к существующим объектам слоя.
Snap-интеракция работает поверх источника данных (source) и анализирует близость курсора к геометрическим элементам уже существующих features. При достижении заданного порога расстояния координата автоматически корректируется, обеспечивая топологическую согласованность данных.
Snap реализован как взаимодействие (interaction), которое подключается к карте и слушает события указателя. Основной принцип работы:
Snap не изменяет геометрию напрямую, а влияет на поток координат, поступающих от других интеракций (Draw, Modify).
Snap используется как дополнительная интеракция, чаще всего совместно с Draw и Modify.
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import VectorLayer from 'ol/layer/Vector.js';
import VectorSource from 'ol/source/Vector.js';
import Draw from 'ol/interaction/Draw.js';
import Snap from 'ol/interaction/Snap.js';
const source = new VectorSource();
const vectorLayer = new VectorLayer({
source: source
});
const map = new Map({
target: 'map',
layers: [vectorLayer],
view: new View({
center: [0, 0],
zoom: 2
})
});
const draw = new Draw({
source: source,
type: 'LineString'
});
const snap = new Snap({
source: source
});
map.addInteraction(draw);
map.addInteraction(snap);
В этом сценарии Snap использует тот же источник, что и Draw, что позволяет мгновенно привязываться к уже созданным объектам.
Snap может работать с одним или несколькими источниками:
При использовании нескольких источников Snap объединяет их геометрии в единое пространство поиска.
import Snap from 'ol/interaction/Snap.js';
const snap = new Snap({
sources: [source1, source2]
});
Такой подход применяется в задачах, где объекты распределены по разным слоям: например, дороги, здания и административные границы.
Ключевой параметр Snap — pixelTolerance. Он определяет радиус захвата в пикселях экрана, внутри которого происходит привязка.
const snap = new Snap({
source: source,
pixelTolerance: 12
});
Поведение:
Snap переводит пиксельную дистанцию в координатную систему карты с учётом текущего масштаба.
Наиболее распространённый сценарий — совместное использование Snap и Draw. При рисовании линий или полигонов координаты автоматически корректируются при приближении к существующим вершинам.
const draw = new Draw({
source: source,
type: 'Polygon'
});
const snap = new Snap({
source: source,
pixelTolerance: 10
});
map.addInteraction(draw);
map.addInteraction(snap);
При таком подключении:
Modify отвечает за редактирование уже существующих объектов. Snap здесь играет роль стабилизатора геометрии.
import Modify from 'ol/interaction/Modify.js';
const modify = new Modify({
source: source
});
const snap = new Snap({
source: source
});
map.addInteraction(modify);
map.addInteraction(snap);
В этом режиме:
Snap поддерживает два основных режима привязки:
Внутренне алгоритм анализирует ближайшие элементы и вычисляет оптимальную точку на геометрии.
При работе с сегментами происходит проекция точки курсора на отрезок.
Snap может ограничивать набор объектов, к которым происходит привязка. Это реализуется через функцию фильтрации features.
const snap = new Snap({
source: source,
filter: function (feature) {
return feature.get('type') === 'road';
}
});
Типовые сценарии:
Snap работает с различными типами геометрий:
При этом алгоритм унифицирует обработку через базовую модель координат.
При большом количестве features производительность Snap становится критическим фактором. Основные оптимизации:
Snap использует оптимизированный поиск ближайших геометрий, но сложные сцены всё равно требуют контроля нагрузки.
Snap не зависит от визуального отображения объектов. Он работает напрямую с геометриями источника данных, поэтому:
При использовании нескольких интеракций порядок добавления влияет на обработку событий.
Обычно применяется следующая схема:
Snap перехватывает координаты до их финализации основной интеракцией, корректируя положение точки.
В сложных проектах используется несколько VectorSource, объединённых в Snap:
const snap = new Snap({
sources: [roadsSource, buildingsSource, bordersSource],
pixelTolerance: 8
});
Поведение:
Snap тесно связан с текущим масштабом карты:
Это обеспечивает одинаковое поведение независимо от zoom-level.
Snap применяется в системах, где важна топология:
Основная задача — исключить:
При пересечении нескольких геометрий Snap выбирает ближайший элемент, основываясь на:
В случае равных условий приоритет может зависеть от порядка источников в конфигурации.
Несмотря на универсальность, Snap имеет ограничения:
Snap работает исключительно как механизм корректировки координат в момент ввода.
Snap может использоваться совместно с кастомными интеракциями, перехватывающими pointermove и click события.
В таких сценариях:
Это позволяет реализовывать сложные редакторы геометрий с контролем точности на уровне UX.