Обработка событий слоя данных

Data Layer (слой данных) в Google Maps JavaScript API представляет собой специализированный слой для хранения и визуализации геопространственных объектов поверх карты. Он основан на классе google.maps.Data и позволяет работать с геометрией и атрибутами объектов как с единым набором структурированных данных.

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

const map = new google.maps.Map(document.getElementById("map"), {
  center: { lat: 55.751244, lng: 37.618423 },
  zoom: 10
});

const dataLayer = new google.maps.Data();
dataLayer.setMap(map);

Архитектура событий Data Layer

Событийная модель слоя данных построена вокруг регистрации обработчиков на уровне объекта google.maps.Data. События генерируются при взаимодействии пользователя с объектами слоя или при изменении структуры данных.

Общий механизм:

  • события привязываются к экземпляру Data
  • каждый Feature может инициировать события взаимодействия
  • обработчики получают объект события с контекстом геометрии и свойств
dataLayer.addListener("click", (event) => {
  console.log(event.feature.getId());
});

Регистрация событий слоя данных

Основной метод подписки на события — addListener. Он применяется к экземпляру google.maps.Data и позволяет отслеживать изменения и пользовательские действия.

const listener = dataLayer.addListener("mouseover", (event) => {
  console.log("Наведение на объект");
});

Удаление обработчика осуществляется через removeListener:

google.maps.event.removeListener(listener);

Подписка возможна на любые события, поддерживаемые Data Layer, включая события изменений и интерактивные события.


Основные события Data Layer

События взаимодействия пользователя

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

  • click — клик по feature
  • dblclick — двойной клик
  • mouseover — наведение курсора
  • mouseout — уход курсора
  • rightclick — контекстное меню
dataLayer.addListener("click", (event) => {
  const feature = event.feature;
  const name = feature.getProperty("name");
  console.log("Клик по объекту:", name);
});

События изменения данных

Слой данных генерирует события при изменении структуры или содержимого:

  • addfeature — добавление объекта
  • removefeature — удаление объекта
  • setgeometry — изменение геометрии
  • setproperty — изменение свойства
  • removeproperty — удаление свойства
dataLayer.addListener("setproperty", (event) => {
  console.log("Изменено свойство:", event.feature.getProperty("status"));
});

События загрузки и синхронизации

При работе с внешними источниками данных (GeoJSON) могут возникать события:

  • load — завершение загрузки данных
dataLayer.loadGeoJson("data.geojson", null, (features) => {
  console.log("Загружено объектов:", features.length);
});

Объект события Data Layer

Каждое событие содержит объект event, структура которого зависит от типа события, но базовые поля включают:

  • feature — объект google.maps.Data.Feature
  • latLng — координаты точки события (для пользовательских событий)
  • featureId — идентификатор объекта (если задан)
dataLayer.addListener("click", (event) => {
  const feature = event.feature;
  const geometry = feature.getGeometry();

  console.log("Тип геометрии:", geometry.getType());
});

Работа со свойствами Feature

Feature предоставляет API для доступа к атрибутам:

const id = feature.getId();
const value = feature.getProperty("population");

feature.setProperty("population", value + 1);
feature.setGeometry(new google.maps.Data.Point({
  lat: 55.75,
  lng: 37.61
}));

Делегирование и управление событиями

События Data Layer не требуют привязки к каждому отдельному объекту. Обработчики устанавливаются на уровне слоя, а контекст определяется через event.feature.

Это позволяет реализовать централизованную обработку:

dataLayer.addListener("mouseover", (event) => {
  dataLayer.revertStyle();
  dataLayer.overrideStyle(event.feature, {
    fillColor: "blue",
    strokeWeight: 2
  });
});

Такой подход снижает сложность кода при работе с большим количеством объектов.


Фильтрация и реакция на события

События часто используются совместно с фильтрацией объектов:

dataLayer.setStyle((feature) => {
  return {
    visible: feature.getProperty("active") === true,
    fillColor: feature.getProperty("type") === "park" ? "green" : "gray"
  };
});

В обработчиках событий можно динамически изменять стиль:

dataLayer.addListener("click", (event) => {
  const isSelected = event.feature.getProperty("selected");

  event.feature.setProperty("selected", !isSelected);
});

Геометрические события

Изменение геометрии объекта также вызывает события, что позволяет отслеживать редактирование:

dataLayer.addListener("setgeometry", (event) => {
  const geometry = event.feature.getGeometry();
  console.log("Геометрия изменена:", geometry.getType());
});

Типичные сценарии:

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

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

При загрузке GeoJSON данные автоматически превращаются в Features, после чего события становятся доступны:

dataLayer.loadGeoJson("regions.geojson");

dataLayer.addListener("click", (event) => {
  fetch("/api/update", {
    method: "POST",
    body: JSON.stringify({
      id: event.feature.getId(),
      name: event.feature.getProperty("name")
    })
  });
});

Управление жизненным циклом слушателей

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

const listeners = [];

listeners.push(
  dataLayer.addListener("click", handlerClick),
  dataLayer.addListener("mouseover", handlerHover)
);

// очистка
listeners.forEach((l) => google.maps.event.removeListener(l));

Это предотвращает утечки памяти при динамическом изменении слоев или перерисовке карты.


Взаимодействие событий с визуальным состоянием

События Data Layer часто используются для изменения визуального состояния объектов:

dataLayer.addListener("mouseout", (event) => {
  dataLayer.revertStyle(event.feature);
});

или комбинированно:

dataLayer.addListener("click", (event) => {
  dataLayer.overrideStyle(event.feature, {
    strokeColor: "red",
    fillOpacity: 0.5
  });
});

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