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

Стандартный маркер в API представляет собой классический красный «пин», который подходит для базовых сценариев, но быстро становится ограничением при построении интерфейсов с высокой плотностью данных, кастомной визуализацией или брендингом. Пользовательские иконки позволяют полностью контролировать внешний вид маркеров: от простого изображения до сложных SVG-символов и динамически изменяемых компонентов.


Базовая настройка свойства icon

Основной способ задать пользовательскую иконку — использование свойства icon при создании маркера.

const marker = new google.maps.Marker({
  position: { lat: 48.8566, lng: 2.3522 },
  map,
  icon: "https://example.com/icons/marker.png"
});

В этом варианте используется внешнее изображение. API загружает его и отображает вместо стандартного маркера.

Дополнительно icon может быть объектом:

const marker = new google.maps.Marker({
  position: { lat: 48.8566, lng: 2.3522 },
  map,
  icon: {
    url: "https://example.com/icons/marker.png",
    scaledSize: new google.maps.Size(40, 40)
  }
});

Управление размером через scaledSize

Изображения редко подходят под реальные требования интерфейса без масштабирования. Параметр scaledSize задаёт финальный размер иконки на карте.

icon: {
  url: "icon.png",
  scaledSize: new google.maps.Size(32, 32)
}

Ключевой момент: оригинальный размер изображения не влияет на отображение — используется именно scaledSize.


Смещение точки привязки (anchor)

Иконка маркера «прикрепляется» к координате карты через точку якоря. По умолчанию это нижний центр изображения, но при кастомных иконках часто требуется корректировка.

icon: {
  url: "icon.png",
  scaledSize: new google.maps.Size(40, 40),
  anchor: new google.maps.Point(20, 40)
}

Логика:

  • anchor.x — горизонтальное смещение
  • anchor.y — вертикальное смещение
  • координата маркера соответствует этой точке изображения

Использование SVG-иконок

SVG обеспечивает масштабируемость без потери качества и возможность динамической стилизации.

Вариант через URL

icon: {
  url: "icon.svg",
  scaledSize: new google.maps.Size(30, 30)
}

Встроенный SVG как data URI

icon: {
  url: "data:image/svg+xml;charset=UTF-8," + encodeURIComponent(`
    <svg width="40" height="40" viewBox="0 0 40 40">
      <circle cx="20" cy="20" r="10" fill="blue"/>
    </svg>
  `),
  scaledSize: new google.maps.Size(40, 40)
}

SVG особенно полезен при необходимости менять цвет маркера в зависимости от состояния объекта (например, статус, категория, приоритет).


Символьные маркеры (Symbol)

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

const marker = new google.maps.Marker({
  position: { lat: 48.8566, lng: 2.3522 },
  map,
  icon: {
    path: google.maps.SymbolPath.CIRCLE,
    scale: 8,
    fillColor: "#4285F4",
    fillOpacity: 1,
    strokeWeight: 2
  }
});

Основные параметры:

  • path — форма символа
  • scale — размер
  • fillColor — цвет заливки
  • strokeColor — цвет обводки
  • strokeWeight — толщина линии

Доступны предопределённые формы:

  • CIRCLE
  • FORWARD_CLOSED_ARROW
  • BACKWARD_CLOSED_ARROW

Динамическая смена иконки

Иконку можно изменять после создания маркера без пересоздания объекта.

marker.setIcon("new-icon.png");

Или с объектной конфигурацией:

marker.setIcon({
  url: "active-icon.png",
  scaledSize: new google.maps.Size(50, 50)
});

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

  • изменение состояния (активен / неактивен)
  • фильтрация данных
  • отображение событий в реальном времени

Использование разных иконок по условиям

Часто иконка определяется динамически:

function getIcon(type) {
  if (type === "restaurant") {
    return "icons/restaurant.png";
  }
  if (type === "hotel") {
    return "icons/hotel.png";
  }
  return "icons/default.png";
}

const marker = new google.maps.Marker({
  position,
  map,
  icon: getIcon(place.type)
});

Оптимизация загрузки иконок

При большом количестве маркеров критично учитывать производительность:

  • повторное использование одинаковых URL снижает нагрузку
  • предпочтение SVG или Symbol уменьшает количество HTTP-запросов
  • кеширование изображений браузером ускоряет рендеринг
  • уменьшение размера файлов снижает задержки отрисовки

Центровка сложных иконок

При нестандартной геометрии изображения важно точно настроить anchor, иначе маркер будет «прыгать» относительно координаты.

icon: {
  url: "pin.png",
  scaledSize: new google.maps.Size(60, 60),
  anchor: new google.maps.Point(30, 60)
}

Для сложных UI-иконок (например, с тенью или подписью) часто требуется ручная калибровка координат.


Совместимость с label

Иконка может комбинироваться с текстовой подписью:

const marker = new google.maps.Marker({
  position,
  map,
  icon: "icon.png",
  label: {
    text: "A",
    color: "white"
  }
});

При кастомных иконках важно учитывать контраст и читаемость текста поверх изображения.


Современный подход: AdvancedMarkerElement

В новых версиях API рекомендуется использовать AdvancedMarkerElement, который заменяет классические маркеры и предоставляет расширенные возможности кастомизации.

const pin = new google.maps.marker.PinElement({
  background: "#4285F4",
  borderColor: "#1a73e8",
  glyphColor: "white"
});

const marker = new google.maps.marker.AdvancedMarkerElement({
  map,
  position: { lat: 48.8566, lng: 2.3522 },
  content: pin.element
});

Преимущества:

  • полноценная HTML/CSS кастомизация
  • отсутствие ограничений raster-иконок
  • более гибкая интеграция с интерфейсом

Анимация и визуальные состояния

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

setInterval(() => {
  marker.setIcon(toggle ? "icon1.png" : "icon2.png");
  toggle = !toggle;
}, 1000);

Для AdvancedMarkerElement возможна полноценная CSS-анимация через content.


Практические паттерны использования

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

Ограничения и особенности рендеринга

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