События Drawing Manager

Google Maps JavaScript API предоставляет компонент Drawing Manager как надстройку над базовой картой для интерактивного создания геометрических объектов. Его событийная модель строится вокруг жизненного цикла создаваемых оверлеев и изменений режима рисования, обеспечивая контроль над пользовательскими действиями и редактированием геометрии в реальном времени.


Архитектура событий Drawing Manager

События Drawing Manager делятся на две основные категории:

  • события уровня менеджера рисования (режимы, завершение создания объектов)
  • события уровня оверлеев (изменение геометрии после создания)

Менеджер рисования не управляет геометрией напрямую после её создания — он лишь инициирует процесс и возвращает ссылку на созданный объект. Дальнейшая динамика полностью делегируется API объектов google.maps.Polygon, google.maps.Polyline, google.maps.Circle, google.maps.Rectangle, google.maps.Marker.


Событие overlaycomplete

Ключевое событие жизненного цикла Drawing Manager.

Срабатывает в момент завершения рисования любого оверлея пользователем.

drawingManager.addListener('overlaycomplete', function(event) {
  const overlay = event.overlay;
  const type = event.type;
});

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

  • event.overlay — созданный объект (Marker, Polygon, Polyline, Circle, Rectangle)
  • event.type — строка типа объекта: "marker" | "polygon" | "polyline" | "circle" | "rectangle"

Поведение после события

После генерации:

  • объект добавляется на карту автоматически
  • Drawing Manager продолжает работу в текущем режиме (или сбрасывается при конфигурации)
  • управление объектом переходит в API оверлея

Типичные сценарии использования

  • сохранение геометрии в базу данных
  • назначение обработчиков редактирования
  • применение бизнес-логики (например, проверка пересечения зон)

Событие drawingmode_changed

Отслеживает переключение режима рисования.

drawingManager.addListener('drawingmode_changed', function() {
  const mode = drawingManager.getDrawingMode();
});

Возможные состояния

  • null — режим рисования выключен
  • "marker"
  • "polygon"
  • "polyline"
  • "circle"
  • "rectangle"

Поведенческая модель

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


Управление состоянием Drawing Manager через события

Drawing Manager часто используется как конечный автомат, где события служат триггерами переходов:

  • включение режима → пользователь начинает рисование
  • overlaycomplete → фиксация результата
  • выключение режима → возврат к стандартному взаимодействию с картой
drawingManager.setDrawingMode(null);

Такой подход позволяет синхронизировать UI (панели инструментов) с состоянием карты.


События оверлеев после создания

После получения overlay из overlaycomplete, управление переходит к событиям конкретных геометрических объектов.


Полигон: события редактирования

При включённой опции editable: true доступны события массива вершин.

polygon.getPath().addListener('set_at', function(index) {});
polygon.getPath().addListener('insert_at', function(index) {});
polygon.getPath().addListener('remove_at', function(index) {});

Семантика событий

  • set_at — изменение существующей вершины
  • insert_at — добавление вершины
  • remove_at — удаление вершины

Каждое событие изменяет структуру MVCArray, которая хранит координаты полигона.


Ломаная линия: аналогичная модель

Polyline использует ту же модель событий, что и Polygon:

polyline.getPath().addListener('set_at', handler);
polyline.getPath().addListener('insert_at', handler);
polyline.getPath().addListener('remove_at', handler);

Отличие заключается в семантике:

  • полигон замкнутый
  • ломаная линия открытая

Круг: события центра и радиуса

Circle имеет две ключевые изменяемые сущности:

  • центр (center_changed)
  • радиус (radius_changed)
circle.addListener('center_changed', function() {});
circle.addListener('radius_changed', function() {});

Оба события срабатывают при интерактивном редактировании или программном изменении параметров.


Прямоугольник: изменение границ

Rectangle генерирует события при изменении bounds:

rectangle.addListener('bounds_changed', function() {});

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


Маркер: базовые события взаимодействия

Marker поддерживает стандартные события карты:

marker.addListener('click', function() {});
marker.addListener('dragend', function() {});

При использовании Drawing Manager маркер обычно создаётся без drag по умолчанию, но может быть модифицирован:

marker.setDraggable(true);

События взаимодействия с режимом редактирования

Для всех редактируемых объектов применим общий принцип:

  • включение editable: true активирует MVC-события
  • отключение редактирования блокирует генерацию событий изменения геометрии
  • события продолжают работать при программных изменениях

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

Типичная модель обработки событий Drawing Manager:

  1. overlaycomplete

    • регистрация объекта
    • сохранение ссылки
  2. назначение событий оверлея

    • отслеживание изменений
  3. синхронизация с внешним состоянием

    • API сервера
    • локальное хранилище

Множественные подписки и управление памятью

Каждое событие создаёт подписку, которую необходимо учитывать:

const listener = polygon.addListener('click', handler);
google.maps.event.removeListener(listener);

Особенно критично при динамическом создании большого числа объектов через Drawing Manager.


Взаимодействие событий Drawing Manager с картой

Drawing Manager не изолирован от карты:

  • клики по карте могут конфликтовать с режимом рисования
  • события карты (click, mousedown, mousemove) подавляются в активном режиме рисования
  • после завершения рисования карта возвращается к стандартному потоку событий

Приоритет событий

При одновременной активности нескольких слоёв:

  1. Drawing Manager (интерактивное рисование)
  2. Overlay события (редактирование)
  3. Map события (навигация и взаимодействие)

Практическая модель обработки overlaycomplete как центра событийной системы

drawingManager.addListener('overlaycomplete', function(event) {
  const overlay = event.overlay;

  if (event.type === 'polygon') {
    overlay.getPath().addListener('set_at', sync);
    overlay.getPath().addListener('insert_at', sync);
  }

  overlay.addListener('click', selectOverlay);
});

Такая структура превращает Drawing Manager в фабрику интерактивных объектов с динамической привязкой поведения.


Особенности поведения при множественном рисовании

При повторном использовании Drawing Manager:

  • каждый новый объект генерирует отдельный overlaycomplete
  • старые объекты сохраняют подписки
  • режим рисования не влияет на уже созданные слои

Это позволяет строить системы аннотаций, где каждый элемент карты живёт независимо.


Синхронизация событий с внешними хранилищами

Любое изменение геометрии может транслироваться в сериализуемую структуру:

  • координаты полигона → массив lat/lng
  • круг → центр + радиус
  • прямоугольник → bounds

Обновление обычно инициируется через MVCArray-события или *_changed.


Поведение событий при программной модификации

События генерируются не только пользователем:

  • setPath у полигона вызывает цепочку MVC событий
  • setCenter у круга инициирует center_changed
  • setBounds у прямоугольника вызывает bounds_changed

Это создаёт единый механизм отслеживания изменений независимо от источника.