Data Layer концепция

Роль Data Layer в архитектуре карты

Data Layer представляет собой специализированный слой в Google Maps JavaScript API, предназначенный для работы с геопространственными данными в формате GeoJSON и внутренними объектами Feature. Он отделяет визуализацию геометрии от бизнес-логики, позволяя управлять наборами объектов как единым целым.

Ключевая идея заключается в том, что карта перестаёт быть набором разрозненных маркеров и фигур. Вместо этого формируется структурированная модель данных, где каждая сущность имеет:

  • геометрию (точка, линия, полигон),
  • свойства (properties),
  • идентификатор,
  • набор событий и стилизацию.

Data Layer становится промежуточным уровнем между источником данных (GeoJSON, API, база данных) и визуальным представлением на карте.


Структура Feature и GeoJSON-интеграция

Основной единицей Data Layer является Feature. Она соответствует объекту GeoJSON и может содержать:

  • Point
  • LineString
  • Polygon
  • MultiGeometry

Каждая Feature включает:

  • geometry — координаты и тип геометрии
  • properties — произвольные данные
  • id — уникальный идентификатор (опционально)

Пример GeoJSON-объекта:

const geoJsonObject = {
  type: "FeatureCollection",
  features: [
    {
      type: "Feature",
      geometry: {
        type: "Polygon",
        coordinates: [
          [
            [37.62, 55.75],
            [37.65, 55.75],
            [37.65, 55.77],
            [37.62, 55.77],
            [37.62, 55.75]
          ]
        ]
      },
      properties: {
        name: "Зона интереса",
        category: "restricted"
      }
    }
  ]
};

Загрузка данных в Data Layer выполняется через метод addGeoJson:

map.data.addGeoJson(geoJsonObject);

Этот вызов автоматически преобразует GeoJSON в внутренние объекты API.


Инициализация Data Layer на карте

Data Layer доступен через свойство map.data после создания карты.

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

Даже без добавления данных слой существует и готов к работе:

console.log(map.data);

Добавление данных в Data Layer

Добавление GeoJSON

map.data.addGeoJson(geoJsonObject);

Метод возвращает массив созданных Feature-объектов, что позволяет сразу работать с ними программно.

Добавление одной Feature вручную

map.data.add({
  geometry: new google.maps.Data.Point({ lat: 55.75, lng: 37.62 }),
  properties: {
    name: "Точка интереса"
  }
});

Такой способ используется, когда данные формируются динамически и не представлены в GeoJSON.


Управление стилями объектов

Одной из ключевых возможностей Data Layer является централизованная стилизация.

Метод setStyle позволяет задавать функцию или объект стиля:

map.data.setStyle((feature) => {
  const category = feature.getProperty("category");

  return {
    fillColor: category === "restricted" ? "red" : "green",
    strokeWeight: 2,
    strokeColor: "#333",
    fillOpacity: 0.4
  };
});

Особенность подхода заключается в том, что стиль вычисляется на основе свойств Feature, а не задаётся отдельно для каждого объекта.

Поддерживаемые параметры стиля:

  • fillColor
  • strokeColor
  • strokeWeight
  • icon (для точек)
  • visible
  • zIndex

Работа с событиями Data Layer

Каждая Feature может генерировать события, что делает Data Layer интерактивным уровнем.

Обработка клика по объекту

map.data.addListener("click", (event) => {
  const feature = event.feature;

  const name = feature.getProperty("name");
  console.log("Выбран объект:", name);
});

Наведение курсора

map.data.addListener("mouseover", (event) => {
  map.data.overrideStyle(event.feature, {
    fillColor: "blue"
  });
});

Сброс стиля при уходе курсора

map.data.addListener("mouseout", (event) => {
  map.data.revertStyle();
});

Механизм overrideStyle позволяет временно изменять отображение объекта без изменения глобального стиля.


Управление свойствами Feature

Data Layer предоставляет API для работы с атрибутами объектов.

Установка свойства

feature.setProperty("status", "active");

Получение свойства

const status = feature.getProperty("status");

Удаление свойства

feature.setProperty("status", null);

Свойства используются как основной механизм хранения бизнес-логики внутри геометрических объектов.


Фильтрация отображения объектов

Data Layer позволяет скрывать или показывать объекты без удаления данных.

map.data.setStyle((feature) => {
  return {
    visible: feature.getProperty("visible") !== false
  };
});

Альтернативный подход — использование forEach и ручного контроля:

map.data.forEach((feature) => {
  if (feature.getProperty("type") === "temporary") {
    map.data.remove(feature);
  }
});

Удаление данных из Data Layer

Удаление конкретного объекта

map.data.remove(feature);

Очистка всех данных

map.data.forEach((feature) => {
  map.data.remove(feature);
});

Или более короткий вариант:

map.data.setMap(null);
map.data.setMap(map);

Последний способ полностью пересоздаёт слой.


Поиск и идентификация Feature

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

const feature = map.data.getFeatureById("zone-1");

ID задаётся при создании GeoJSON:

{
  type: "Feature",
  id: "zone-1",
  geometry: { ... },
  properties: { ... }
}

Использование ID критично при работе с динамическими наборами данных.


Импорт и экспорт GeoJSON

Экспорт

const exported = map.data.toGeoJson((json) => {
  console.log(json);
});

Метод формирует полный GeoJSON из текущего состояния слоя.

Импорт

map.data.addGeoJson(jsonData);

Таким образом Data Layer может выступать в роли двустороннего адаптера между API и внешними источниками данных.


Геометрические операции в рамках Data Layer

Хотя Data Layer не является GIS-движком, он поддерживает базовые операции над геометрией:

  • отображение сложных полигонов
  • работа с мульти-геометрией
  • автоматическое упрощение отображения при масштабировании

Пример MultiPolygon:

geometry: {
  type: "MultiPolygon",
  coordinates: [
    [
      [
        [37.6, 55.7],
        [37.7, 55.7],
        [37.7, 55.8],
        [37.6, 55.8],
        [37.6, 55.7]
      ]
    ],
    [
      [
        [37.8, 55.7],
        [37.9, 55.7],
        [37.9, 55.8],
        [37.8, 55.8],
        [37.8, 55.7]
      ]
    ]
  ]
}

Производительность и поведение при больших данных

Data Layer оптимизирован для работы с большими наборами GeoJSON, но имеет ряд особенностей:

  • рендеринг происходит через внутреннюю оптимизацию Google Maps
  • стили применяются через функцию, вызываемую для каждого Feature
  • частое изменение стиля может влиять на производительность
  • массовое добавление объектов лучше выполнять через addGeoJson, а не по одному

Оптимизационные практики:

  • минимизация количества вызовов setStyle
  • группировка изменений
  • использование свойств вместо внешних структур состояния
  • избегание частых remove/add операций в цикле

Событийная модель и реактивное поведение

Data Layer строится вокруг событийной модели:

  • addfeature
  • removefeature
  • setgeometry
  • setproperty

Пример обработки добавления:

map.data.addListener("addfeature", (event) => {
  console.log("Добавлен объект:", event.feature);
});

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


Взаимодействие Data Layer с другими слоями карты

Data Layer работает независимо от:

  • Marker
  • Polyline
  • Polygon
  • Circle

Однако при необходимости можно синхронизировать данные:

map.data.addListener("click", (event) => {
  new google.maps.Marker({
    position: event.latLng,
    map: map
  });
});

Такая комбинация используется для создания гибридных визуализаций: статические данные через Data Layer и интерактивные элементы через стандартные overlay-объекты.


Роль Data Layer в архитектуре гео-приложений

Data Layer часто становится центральным компонентом в приложениях, где требуется:

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

В таких системах Data Layer выступает как слой представления данных, отделённый от источника и бизнес-логики, что упрощает масштабирование и поддержку архитектуры.