Draw — это базовый интерактивный механизм в OpenLayers,
предназначенный для создания геометрий на карте в режиме
пользовательского ввода. Он относится к классу интеракций
(ol/interaction/Interaction) и работает совместно с
векторным источником данных (ol/source/Vector), куда
записываются создаваемые объекты.
Ключевая особенность Draw заключается в том, что он не просто фиксирует координаты, а формирует полноценные геометрические объекты: точки, линии, полигоны, окружности и мультигеометрии. При этом процесс рисования синхронизирован с визуальным представлением на карте.
Для работы Draw необходимы три компонента:
Map)VectorLayer)VectorSource)import Map from 'ol/Map';
import View from 'ol/View';
import Draw from 'ol/interaction/Draw';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
const source = new VectorSource();
const vector = new VectorLayer({
source: source
});
const map = new Map({
target: 'map',
layers: [vector],
view: new View({
center: [0, 0],
zoom: 2
})
});
Минимальная конфигурация Draw требует указания типа геометрии через
параметр type.
import Draw from 'ol/interaction/Draw';
const draw = new Draw({
source: source,
type: 'Point'
});
map.addInteraction(draw);
Доступные типы:
PointLineStringPolygonCircleMultiPointMultiLineStringMultiPolygonGeometryCollectionПроцесс создания геометрии состоит из нескольких фаз:
drawstart — начало рисованияdrawend — завершениеdraw.on('drawstart', function (event) {
const feature = event.feature;
console.log('Начато рисование:', feature);
});
draw.on('drawend', function (event) {
const feature = event.feature;
console.log('Завершено рисование:', feature);
});
События позволяют интегрировать Draw в бизнес-логику: вычисление площади, сохранение в базе, валидация.
const drawLine = new Draw({
source: source,
type: 'LineString'
});
map.addInteraction(drawLine);
const drawPolygon = new Draw({
source: source,
type: 'Polygon'
});
map.addInteraction(drawPolygon);
Polygon автоматически замыкается при завершении.
Для контроля геометрии можно использовать параметры:
minPointsmaxPointsconst draw = new Draw({
source: source,
type: 'LineString',
maxPoints: 5
});
Это полезно для строгих форм (например, треугольники или фиксированные сегменты).
Режим свободного рисования позволяет создавать геометрию непрерывным движением мыши.
const draw = new Draw({
source: source,
type: 'LineString',
freehand: true
});
Дополнительно можно задать условие активации:
import { shiftKeyOnly } from 'ol/events/condition';
const draw = new Draw({
source: source,
type: 'Polygon',
freehandCondition: shiftKeyOnly
});
Circle в OpenLayers — особый тип геометрии, который
хранится как центр и радиус.
const drawCircle = new Draw({
source: source,
type: 'Circle'
});
При завершении создаётся объект ol/geom/Circle, который
может быть преобразован в полигон при экспорте.
geometryFunction позволяет переопределить стандартную
логику построения геометрии.
Пример: создание прямоугольника вместо произвольного полигона.
import { createBox } from 'ol/interaction/Draw';
const drawBox = new Draw({
source: source,
type: 'Circle',
geometryFunction: createBox()
});
map.addInteraction(drawBox);
Также можно реализовать собственную функцию:
const draw = new Draw({
source: source,
type: 'LineString',
geometryFunction: function (coordinates, geometry) {
if (!geometry) {
geometry = new LineString([]);
}
geometry.setCoordinates(coordinates);
return geometry;
}
});
Draw может активироваться только при выполнении определённых условий (например, нажатие клавиш).
import { altKeyOnly } from 'ol/events/condition';
const draw = new Draw({
source: source,
type: 'Polygon',
condition: altKeyOnly
});
Это полезно при совместном использовании с другими интеракциями (панорамирование, выбор объектов).
Во время рисования можно анализировать промежуточную геометрию:
draw.on('drawstart', function (event) {
const feature = event.feature;
const geometry = feature.getGeometry();
geometry.on('change', function () {
const coords = geometry.getCoordinates();
console.log(coords);
});
});
Это позволяет реализовать:
Draw поддерживает два уровня стилей:
style — стиль во время рисованияimport Style from 'ol/style/Style';
import Stroke from 'ol/style/Stroke';
import Fill from 'ol/style/Fill';
const draw = new Draw({
source: source,
type: 'Polygon',
style: new Style({
stroke: new Stroke({
color: 'blue',
width: 2
}),
fill: new Fill({
color: 'rgba(0, 0, 255, 0.1)'
})
})
});
Draw часто используется вместе с Snap, чтобы вершины
“прилипали” к существующим объектам.
import Snap from 'ol/interaction/Snap';
const snap = new Snap({
source: source
});
map.addInteraction(draw);
map.addInteraction(snap);
Комбинация Draw + Snap обеспечивает точное редактирование геометрии без разрывов.
Интеракции можно динамически включать и отключать:
map.removeInteraction(draw);
map.addInteraction(draw);
Это используется при переключении режимов редактора карты.
MultiPolygon и другие мульти-типы позволяют создавать
сложные структуры.
const draw = new Draw({
source: source,
type: 'MultiPolygon'
});
Каждая новая часть добавляется как отдельный полигон внутри общей коллекции.
Все созданные объекты автоматически добавляются в
VectorSource:
const features = source.getFeatures();
features.forEach(f => {
console.log(f.getGeometry().getType());
});
Источник может быть связан с:
source.clear();
или удаление отдельных объектов:
source.removeFeature(feature);
Это часто используется при повторном запуске Draw-сессий.
Draw имеет ряд внутренних особенностей:
Draw применяется в сложных интерфейсах:
В таких системах Draw обычно комбинируется с:
Draw может быть связан с состоянием приложения:
let active = false;
function toggleDraw() {
if (active) {
map.removeInteraction(draw);
} else {
map.addInteraction(draw);
}
active = !active;
}
Это позволяет строить полноценные режимы редактирования карты.
При необходимости координаты можно преобразовывать:
import { transform } fr om 'ol/proj';
const coords = feature.getGeometry().getCoordinates();
const transformed = coords.map(c =>
transform(c, 'EPSG:3857', 'EPSG:4326')
);
Это важно при отправке данных на сервер или сохранении в GeoJSON.
OpenLayers использует внутреннюю интерполяцию для:
Это влияет на ощущение “плавности” рисования и может настраиваться через стили и события, хотя не всегда явно документировано через API Draw.
VectorSource приводит к потере
геометрийDraw обычно выступает как слой пользовательского ввода в архитектуре GIS-интерфейса. Он не хранит данные, не управляет их жизненным циклом и не отвечает за бизнес-логику. Его задача ограничена:
Такая разделённость позволяет масштабировать приложение без усложнения интерактивного слоя.