SVG-маркеры

SVG-маркеры в HERE Maps API JavaScript позволяют полностью кастомизировать визуальные обозначения объектов на карте, выходя за пределы стандартных пинов. В экосистеме HERE Technologies работа с SVG является одним из наиболее гибких способов создания масштабируемых, стилизуемых и динамически изменяемых маркеров без потери качества при любых уровнях масштабирования карты.

SVG (Scalable Vector Graphics) используется в HERE Maps через объект иконки, который затем применяется в маркере. Главная особенность SVG — независимость от разрешения экрана: изображение остаётся чётким на retina-дисплеях и при масштабировании карты.

В HERE Maps API SVG обычно используется через:

  • строку SVG-разметки
  • data URI
  • внешние SVG-файлы (реже, из-за ограничений загрузки и кэширования)

Ключевой объект для работы:

  • H.map.Icon — определяет визуальное представление маркера
  • H.map.Marker — размещает иконку на карте

Создание SVG-иконки через data URI

Наиболее распространённый способ — инлайновый SVG, закодированный в data URI:

const svgMarkup = `
<svg width="40" height="40" xmlns="http://www.w3.org/2000/svg">
  <circle cx="20" cy="20" r="10" fill="#2b8cff" stroke="#ffffff" stroke-width="3"/>
</svg>
`;

const icon = new H.map.Icon(
  'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svgMarkup)
);

const marker = new H.map.Marker(
  { lat: 52.5, lng: 13.4 },
  { icon }
);

map.addObject(marker);

Важный момент заключается в encodeURIComponent, который обеспечивает корректную передачу SVG в URI-формате без нарушения синтаксиса URL.

Использование H.map.Icon с параметрами

H.map.Icon поддерживает дополнительные настройки, влияющие на позиционирование и поведение маркера:

const icon = new H.map.Icon(svgString, {
  size: { w: 40, h: 40 },
  anchor: { x: 20, y: 20 }
});

Параметры:

  • size — физический размер иконки на карте
  • anchor — точка привязки (например, центр нижней части маркера)

Правильная настройка anchor критична для SVG-маркеров сложной формы, иначе визуальная точка может смещаться относительно координаты объекта.

Центрирование и якорные точки SVG

SVG часто проектируется не в (0,0), а в центре координатной системы, чтобы упростить привязку:

<svg width="40" height="40">
  <g transform="translate(20,20)">
    <circle r="12" fill="red"/>
  </g>
</svg>

Такой подход уменьшает необходимость ручной настройки anchor.

Альтернативный вариант — оставлять SVG в стандартной системе координат и компенсировать смещение через anchor.

Динамическая генерация SVG

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

  • цвет по типу объекта
  • числовые индикаторы
  • статус (активен / неактивен)
  • уровень загрузки

Пример динамического маркера:

function createSvgMarker(color, label) {
  const svg = `
  <svg width="50" height="50" xmlns="http://www.w3.org/2000/svg">
    <circle cx="25" cy="25" r="18" fill="${color}" />
    <text x="25" y="30" font-size="12" text-anchor="middle" fill="#fff">
      ${label}
    </text>
  </svg>
  `;

  return new H.map.Icon('data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg));
}

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

SVG-маркеры и события

Маркеры с SVG сохраняют стандартную систему событий HERE Maps:

marker.addEventListener('tap', function () {
  console.log('Маркер активирован');
});

SVG внутри маркера не влияет на обработку событий, так как события обрабатываются контейнером H.map.Marker.

Масштабирование и поведение при зуме

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

  • фиксированный размер иконки
  • изменение icon при zoom level
  • динамическая пересборка SVG

Пример адаптации под масштаб:

map.addEventListener('mapviewchange', () => {
  const zoom = map.getZoom();

  const size = zoom > 10 ? 60 : 30;
  marker.setIcon(createSvgIcon(size));
});

Производительность SVG-маркеров

SVG-маркеры обладают преимуществами гибкости, но требуют учёта производительности:

  • большое количество сложных SVG увеличивает нагрузку на DOM-подобную структуру карты
  • анимации внутри SVG нежелательны при множестве объектов
  • динамическая пересборка SVG должна быть ограничена

Рекомендуется:

  • использовать простые формы (circle, path)
  • минимизировать фильтры и blur-эффекты
  • избегать встроенных скриптов в SVG

Сложные SVG-маркеры с несколькими слоями

SVG позволяет строить многослойные маркеры:

<svg width="60" height="60">
  <circle cx="30" cy="30" r="25" fill="#e0e0e0"/>
  <circle cx="30" cy="30" r="18" fill="#4caf50"/>
  <circle cx="30" cy="30" r="8" fill="#ffffff"/>
</svg>

Такие конструкции используются для:

  • статусов устройств
  • уровней заполненности
  • визуализации категорий

SVG и кластеризация объектов

При использовании кластеризации SVG часто становится инструментом отображения агрегированных данных. Например, кластер может показывать количество объектов:

function clusterSvg(count) {
  return `
  <svg width="50" height="50">
    <circle cx="25" cy="25" r="20" fill="#1976d2"/>
    <text x="25" y="30" text-anchor="middle" fill="#fff">
      ${count}
    </text>
  </svg>
  `;
}

При увеличении количества объектов SVG может менять цветовую интенсивность или размер внутреннего круга, отражая плотность данных.

Использование внешних SVG-файлов

Хотя чаще применяется inline SVG, возможно использование внешних ресурсов:

const icon = new H.map.Icon('/icons/marker.svg');

Особенности:

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

Привязка SVG к геометрическим точкам

Точность позиционирования критична при работе с геоданными. SVG-маркер всегда привязывается к координате lat/lng, а визуальная часть компенсируется anchor.

При сложных формах (например, стрелках или указателях) важно учитывать:

  • нижнюю точку как опорную
  • центр тяжести формы
  • визуальную симметрию

SVG и кастомные состояния объектов

SVG удобно использовать для отображения состояний без пересоздания маркера:

  • изменение fill через setIcon
  • генерация нового SVG при изменении состояния
  • переключение цветов и текстов

Пример смены состояния:

marker.setIcon(createSvgMarker('#ff9800', 'WARN'));

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

Особенности рендеринга в HERE Maps

SVG внутри H.map.Icon рендерится как изображение, а не как DOM-элемент. Это означает:

  • нельзя напрямую изменять внутренние элементы SVG после добавления на карту
  • любые изменения требуют пересоздания иконки
  • отсутствует доступ к DOM SVG внутри маркера

Это принципиально отличает SVG-маркеры от HTML-overlay подходов и влияет на архитектуру интерактивных решений.

Комбинирование SVG и стандартных иконок

В одной карте можно смешивать:

  • SVG-маркеры для динамических объектов
  • PNG-иконки для статичных элементов
  • CSS-иконки в overlay-слоях

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