Overlays в Street View

Overlays в Street View

Street View в Google Maps JavaScript API представляет собой панорамный рендеринг улиц, поверх которого можно размещать интерактивные элементы интерфейса и географические объекты. Архитектурно это расширение базовой модели карты, где вместо плоской проекции используется сферическая панорама с собственной системой координат, углом обзора (POV) и уровнем масштабирования.

Панорама Street View задаётся экземпляром google.maps.StreetViewPanorama, который может существовать как отдельно, так и быть связанным с обычной картой через setStreetView.

В отличие от классической карты, где используется двухмерная проекция Web Mercator, Street View работает с:

  • географическими координатами (LatLng) — для позиционирования камеры в мире;
  • параметрами обзора (Pov) — направление взгляда камеры (heading, pitch);
  • пиксельной проекцией внутри панорамы — для отрисовки оверлеев.

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

Типы оверлеев в Street View

В Street View поддерживаются те же базовые overlay-объекты, что и на карте, но с особенностями поведения:

Маркеры (Marker)

google.maps.Marker может быть добавлен напрямую на панораму:

const panorama = new google.maps.StreetViewPanorama(
  document.getElementById("pano"),
  {
    position: { lat: 48.8584, lng: 2.2945 },
    pov: { heading: 165, pitch: 0 },
    zoom: 1
  }
);

const marker = new google.maps.Marker({
  position: { lat: 48.8584, lng: 2.2945 },
  map: panorama,
  title: "Точка интереса"
});

Маркер автоматически адаптируется к повороту камеры. Если точка выходит за пределы поля зрения, он перестаёт отображаться.

Линии и полигоны

Polyline и Polygon работают как географические оверлеи. Они привязываются к миру, а не к экрану:

const line = new google.maps.Polyline({
  path: [
    { lat: 48.8584, lng: 2.2945 },
    { lat: 48.8590, lng: 2.2950 }
  ],
  strokeColor: "#FF0000",
  strokeOpacity: 1.0,
  strokeWeight: 2,
  map: panorama
});

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

Привязка оверлеев к StreetViewPanorama

Все стандартные overlay-объекты используют метод setMap, принимающий StreetViewPanorama вместо карты.

overlay.setMap(panorama);

Внутренне API интерпретирует это как переключение контекста рендеринга: вместо MapCanvas используется PanoramaCanvas.

Custom Overlays и OverlayView

Для создания произвольных интерфейсных слоёв используется google.maps.OverlayView. Этот механизм позволяет отрисовывать HTML или Canvas поверх панорамы с точной привязкой к географическим координатам.

Базовая структура кастомного overlay

class CustomOverlay extends google.maps.OverlayView {
  constructor(position, content) {
    super();
    this.position = position;
    this.content = content;
    this.div = null;
  }

  onAdd() {
    this.div = document.createElement("div");
    this.div.style.position = "absolute";
    this.div.innerHTML = this.content;

    const panes = this.getPanes();
    panes.floatPane.appendChild(this.div);
  }

  draw() {
    const projection = this.getProjection();
    const point = projection.fromLatLngToDivPixel(this.position);

    if (point && this.div) {
      this.div.style.left = point.x + "px";
      this.div.style.top = point.y + "px";
    }
  }

  onRemove() {
    if (this.div) {
      this.div.parentNode.removeChild(this.div);
      this.div = null;
    }
  }
}

Привязка overlay к Street View

const overlay = new CustomOverlay(
  { lat: 48.8584, lng: 2.2945 },
  "Объект на панораме"
);

overlay.setMap(panorama);

Street View использует тот же механизм OverlayView, что и карта, поэтому координатная трансформация остаётся совместимой.

Проекция координат в Street View

Проекционная модель зависит от текущего состояния камеры:

  • heading — горизонтальный угол поворота
  • pitch — вертикальный наклон
  • zoom — масштаб внутри панорамы

При вычислении позиции overlay используется:

  • мировая позиция (LatLng)
  • текущая ориентация камеры
  • внутренняя панорамная проекция

Метод getProjection() возвращает объект, который позволяет переводить координаты в пиксели относительно текущего viewport.

Динамическое обновление overlay

Street View является событийно-ориентированной системой. Любое изменение камеры требует перерасчёта позиции overlay.

Ключевые события:

  • pov_changed — изменение угла обзора
  • position_changed — перемещение точки обзора
  • zoom_changed — изменение масштаба
  • visible_changed — изменение видимости панорамы

Пример обновления:

panorama.addListener("pov_changed", () => {
  overlay.draw();
});

panorama.addListener("position_changed", () => {
  overlay.draw();
});

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

Street View накладывает специфические ограничения на оверлеи:

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

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

Использование пользовательских HTML-слоёв

HTML-оверлеи часто используются для отображения интерактивных элементов: кнопок, подписей, инфо-блоков.

Особенность заключается в том, что такие элементы должны синхронизироваться с перспективной деформацией панорамы:

  • позиционирование через divPixel
  • динамическое скрытие при выходе из обзора
  • перерасчёт при каждом изменении POV
const el = document.createElement("div");
el.className = "label";
el.textContent = "Объект интереса";

panorama.getDiv().appendChild(el);

Интеграция с сервисом Street View

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

const service = new google.maps.StreetViewService();

service.getPanorama({
  location: { lat: 48.8584, lng: 2.2945 },
  radius: 50
}, (data, status) => {
  if (status === "OK") {
    panorama.setPano(data.location.pano);
  }
});

Оверлеи при смене pano должны пересоздаваться или пересчитываться, поскольку изменяется сама геометрия сцены.

Координация нескольких overlay-слоёв

При использовании нескольких overlay-объектов важно учитывать порядок рендеринга:

  • overlayMouseTarget — интерактивные элементы
  • floatPane — динамические HTML-слои
  • markerLayer — стандартные маркеры
  • overlayLayer — геометрические объекты

Изменение порядка DOM влияет на перекрытие элементов, особенно при высокой плотности объектов в сцене Street View.