Leaflet.draw для редактирования

Leaflet.draw расширяет функциональность библиотеки Leaflet, добавляя инструменты интерактивного рисования и редактирования геометрии на карте. Плагин ориентирован на работу с векторными слоями и предоставляет готовый набор контролов для создания точек, линий, полигонов, прямоугольников и окружностей, а также их последующего изменения.

Leaflet.draw построен как надстройка над системой слоёв Leaflet. Вся логика рисования опирается на стандартные GeoJSON-совместимые геометрии и события карты. Основная идея заключается в том, что пользователь взаимодействует не с абстрактными инструментами, а с временными слоями, которые затем преобразуются в полноценные объекты карты.

Плагин использует:

  • набор контролов (Draw Control)
  • обработчики событий карты
  • временные слои редактирования
  • механизм стилизации через опции

Каждый создаваемый объект сразу становится частью слоя, что позволяет интегрировать его с любыми источниками данных, включая GeoJSON, API и локальные хранилища.

Подключение и инициализация

Leaflet.draw подключается как дополнительный модуль к Leaflet.

Базовая установка через npm:

npm install leaflet-draw

Подключение в проекте:

import L from 'leaflet';
import 'leaflet-draw';
import 'leaflet/dist/leaflet.css';
import 'leaflet-draw/dist/leaflet.draw.css';

Инициализация карты и включение инструмента рисования:

const map = L.map('map').setView([51.505, -0.09], 13);

Добавление панели инструментов:

const drawControl = new L.Control.Draw({
  position: 'topright',
  draw: {
    polyline: true,
    polygon: true,
    rectangle: true,
    circle: true,
    marker: true,
    circlemarker: false
  },
  edit: {
    featureGroup: editableLayers
  }
});

map.addControl(drawControl);

FeatureGroup как основа редактирования

Все создаваемые объекты должны храниться в FeatureGroup. Это обязательный слой, который объединяет геометрии для последующего редактирования.

const editableLayers = new L.FeatureGroup();
map.addLayer(editableLayers);

Каждый новый объект добавляется именно в эту группу:

map.on('draw:created', function (e) {
  const layer = e.layer;
  editableLayers.addLayer(layer);
});

FeatureGroup выступает центральной точкой управления состоянием геометрий.

Инструменты рисования

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

Маркеры

Маркер — базовый тип точки. Используется для одиночных координат.

draw: {
  marker: {
    icon: customIcon
  }
}

Событие создания:

map.on('draw:created', function (e) {
  if (e.layerType === 'marker') {
    editableLayers.addLayer(e.layer);
  }
});

Полилинии

Полилиния создаётся последовательностью кликов по карте.

draw: {
  polyline: {
    shapeOptions: {
      color: 'blue',
      weight: 4
    }
  }
}

Полилинии часто используются для маршрутов и трасс.

Полигональные области

Полигоны замыкают контур автоматически при завершении рисования.

draw: {
  polygon: {
    allowIntersection: false,
    showArea: true,
    shapeOptions: {
      color: '#ff0000'
    }
  }
}

Опция allowIntersection контролирует геометрическую корректность фигуры.

Прямоугольники

Прямоугольник создаётся по диагонали.

draw: {
  rectangle: {
    shapeOptions: {
      color: '#3388ff'
    }
  }
}

Окружности

Круг определяется центром и радиусом в метрах.

draw: {
  circle: {
    shapeOptions: {
      color: 'green'
    }
  }
}

Радиус пересчитывается в зависимости от проекции карты.

События рисования

Leaflet.draw активно использует событийную модель Leaflet.

Основные события:

  • draw:created
  • draw:edited
  • draw:deleted
  • draw:drawstart
  • draw:drawstop

Пример обработки создания объекта:

map.on('draw:created', function (e) {
  const type = e.layerType;
  const layer = e.layer;

  editableLayers.addLayer(layer);
});

Обработка редактирования:

map.on('draw:edited', function (e) {
  const layers = e.layers;
  layers.eachLayer(function (layer) {
    console.log('Изменён слой', layer);
  });
});

Удаление объектов:

map.on('draw:deleted', function (e) {
  console.log('Удалённые объекты', e.layers);
});

Режим редактирования

Редактирование включается через edit в конфигурации контролов.

edit: {
  featureGroup: editableLayers,
  remove: true
}

При активации режима пользователь может:

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

Каждое изменение вызывает событие draw:edited.

Работа с GeoJSON

Векторные данные легко сериализуются в GeoJSON:

const geojson = editableLayers.toGeoJSON();
console.log(JSON.stringify(geojson));

Загрузка GeoJSON обратно:

L.geoJSON(data, {
  onEachFeature: function (feature, layer) {
    editableLayers.addLayer(layer);
  }
}).addTo(map);

GeoJSON является основным форматом интеграции с внешними сервисами.

Настройка стилей

Стилизация применяется через shapeOptions:

polygon: {
  shapeOptions: {
    color: '#purple',
    fillOpacity: 0.3,
    weight: 2
  }
}

Дополнительно можно использовать динамическое изменение стиля:

layer.setStyle({
  color: 'orange'
});

Ограничения и валидация геометрии

Плагин позволяет контролировать корректность данных:

  • запрет самопересечений
  • ограничение количества точек
  • контроль минимальной площади
  • проверка радиуса окружности

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

polygon: {
  allowIntersection: false,
  maxPoints: 10
}

Кастомизация панели инструментов

Панель можно полностью перестроить:

const drawControl = new L.Control.Draw({
  draw: {
    polygon: false,
    circle: false,
    rectangle: true,
    polyline: true,
    marker: true
  }
});

Позиция панели:

position: 'bottomleft'

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

Программное управление

Создание объектов без интерфейса:

const polygon = L.polygon([
  [51.51, -0.1],
  [51.52, -0.12],
  [51.53, -0.11]
]);

editableLayers.addLayer(polygon);

Редактирование через API:

polygon.editing.enable();
polygon.editing.disable();

Производительность при большом количестве объектов

При работе с тысячами геометрий важно учитывать:

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

Рекомендуется хранить геометрию вне DOM и синхронизировать состояние только при изменениях.

Интеграционные сценарии

Leaflet.draw часто используется в системах:

  • GIS-редакторы
  • системы логистики
  • картографические сервисы
  • интерфейсы аннотирования данных
  • планирование маршрутов

Интеграция с backend обычно строится через GeoJSON API:

fetch('/api/save', {
  method: 'POST',
  body: JSON.stringify(geojson)
});

Расширение функциональности

Плагин допускает расширение:

  • кастомные инструменты рисования
  • собственные контролы
  • обработка нестандартных событий
  • интеграция с внешними редакторами геометрии

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

L.Control.MyDraw = L.Control.extend({
  onAdd: function(map) {
    const btn = L.DomUtil.create('button');
    btn.innerHTML = 'Инструмент';
    return btn;
  }
});

Взаимодействие с другими плагинами

Leaflet.draw совместим с:

  • системами кластеризации
  • библиотеками визуализации маршрутов
  • тайловыми слоями
  • библиотеками анализа геоданных

Особенно часто он используется вместе с GeoJSON-слоями и динамическими источниками данных, что усиливает его роль как инструмента редактирования в экосистеме Leaflet