Позиционирование контролов на карте

Контрольные элементы интерфейса в HERE Maps JavaScript API формируют отдельный слой поверх карты и управляются через UI-фреймворк библиотеки. Архитектура разделяет саму карту (H.Map) и интерфейс управления (H.ui.UI), что позволяет независимо настраивать поведение и расположение элементов управления без изменения геометрии карты.

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


В HERE Maps API позиционирование контролов реализовано через абстракцию компоновки (layout system). Каждый элемент интерфейса размещается относительно контейнера карты и может быть закреплён в одной из стандартных позиций.

Основные логические области размещения:

  • верхний левый угол
  • верхний правый угол
  • нижний левый угол
  • нижний правый угол
  • центр (используется ограниченно, чаще для overlay-элементов)

Эти позиции определяются перечислением H.ui.LayoutAlignment, которое используется при настройке UI-компонентов.


Предустановленные области размещения

Встроенные контролы карты по умолчанию распределяются по стандартной схеме:

  • элементы масштабирования располагаются в верхней левой части
  • переключатели слоёв и режимов отображения — в верхней правой части
  • информационные панели — в нижней части интерфейса
  • дополнительные инструменты — в зависимости от конфигурации UI

Такое распределение задаётся при инициализации через H.ui.UI.createDefault, где используется набор стандартных контролов и их дефолтное позиционирование.


Инициализация UI и базовая структура контролов

Создание интерфейса управления картой связано с объектом UI, который привязывается к экземпляру карты:

const platform = new H.service.Platform({
  apikey: 'API_KEY'
});

const defaultLayers = platform.createDefaultLayers();

const map = new H.Map(
  document.getElementById('map'),
  defaultLayers.vector.normal.map,
  {
    center: { lat: 52.52, lng: 13.405 },
    zoom: 10,
    pixelRatio: window.devicePixelRatio || 1
  }
);

const ui = H.ui.UI.createDefault(map, defaultLayers);

После инициализации создаётся набор стандартных контролов, каждый из которых уже закреплён за определённой зоной интерфейса.


Контроль позиционирования через LayoutAlignment

Перераспределение элементов осуществляется через изменение их alignment. Каждый UI-компонент может быть перемещён в одну из доступных зон.

const zoomControl = ui.getControl('zoom');

zoomControl.setAlignment(H.ui.LayoutAlignment.TOP_RIGHT);

Таким образом, элемент масштабирования переносится из стандартной позиции в правый верхний угол.

Используемые значения:

  • TOP_LEFT
  • TOP_RIGHT
  • BOTTOM_LEFT
  • BOTTOM_RIGHT

Эти значения формируют основу всей системы компоновки интерфейса.


Перемещение стандартных контролов

Стандартные элементы UI доступны через идентификаторы, что позволяет изменять их расположение после создания интерфейса.

const mapSettingsControl = ui.getControl('mapsettings');

mapSettingsControl.setAlignment(H.ui.LayoutAlignment.BOTTOM_RIGHT);

Изменение позиции не требует пересоздания UI, поскольку каждый контрол является автономным компонентом, встроенным в систему управления компоновкой.

Некоторые элементы могут содержать внутренние подкомпоненты, которые наследуют позиционирование от родительского контейнера.


Поведение при конфликте позиций

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

Порядок определяется:

  • очередностью инициализации
  • приоритетом UI-компонента
  • внутренними правилами layout-менеджера

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


Кастомные контролы и их размещение

Помимо стандартных элементов, система поддерживает пользовательские контролы, реализуемые через H.ui.Control.

Создание кастомного элемента включает определение DOM-структуры и привязку к UI-слою:

const customControl = new H.ui.Control();

customControl.addEventListener('tap', () => {
  console.log('custom action');
});

customControl.setContent('<div class="custom-button">Action</div>');

ui.addControl('customControl', customControl);

customControl.setAlignment(H.ui.LayoutAlignment.TOP_LEFT);

Пользовательские элементы ведут себя аналогично встроенным: они участвуют в общей системе компоновки и подчиняются правилам распределения зон.


Группировка контролов

Контролы могут быть объединены в контейнеры, формируя составные UI-блоки. Это используется для создания логически связанных панелей инструментов.

Группировка позволяет:

  • объединять несколько элементов в одну область
  • управлять общей позицией группы
  • минимизировать конфликт размещения

Пример группового контейнера:

const container = new H.ui.Container();

container.addChild(ui.getControl('zoom'));
container.addChild(ui.getControl('mapsettings'));

container.setAlignment(H.ui.LayoutAlignment.TOP_LEFT);

ui.addControl('mainGroup', container);

Контейнер становится единым элементом layout-системы и перемещается как цельный блок.


Динамическое изменение расположения

Система UI поддерживает изменение позиции контролов в runtime без пересоздания карты или интерфейса. Это позволяет адаптировать интерфейс под состояние приложения.

Пример переключения позиции:

function toggleZoomPosition() {
  const zoom = ui.getControl('zoom');

  const current = zoom.getAlignment();

  zoom.setAlignment(
    current === H.ui.LayoutAlignment.TOP_LEFT
      ? H.ui.LayoutAlignment.BOTTOM_LEFT
      : H.ui.LayoutAlignment.TOP_LEFT
  );
}

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


Влияние размеров контейнера карты

Позиционирование UI-элементов зависит от размеров DOM-контейнера, в котором размещена карта. При изменении размеров контейнера происходит перерасчёт layout-системы.

Ключевые аспекты:

  • все координаты UI пересчитываются относительно новых границ
  • контролы сохраняют свою привязку к углам
  • адаптация происходит автоматически при событии resize
window.addEventListener('resize', () => {
  map.getViewPort().resize();
});

Без обновления viewport возможны смещения элементов интерфейса относительно карты.


Особенности слоёв интерфейса

UI в HERE Maps работает поверх canvas-слоя карты и не влияет на географические данные. Каждый контрол размещается в отдельном DOM-слое, что обеспечивает независимость от отрисовки тайлов.

Слои разделяются следующим образом:

  • слой карты (WebGL / Canvas)
  • слой UI (HTML элементы)
  • слой взаимодействия (events)

Позиционирование контролов относится исключительно к UI-слою и не влияет на координатную систему карты.


Поведение при масштабировании и панорамировании

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

Это отличие от объектов карты (markers, bubbles), которые следуют за географической системой координат.


Расширенные сценарии размещения

В сложных интерфейсах используется комбинирование нескольких стратегий:

  • фиксированные углы для навигационных элементов
  • динамические панели для аналитических данных
  • скрывающиеся контейнеры для экономии пространства
  • контекстные контролы, появляющиеся при событиях карты

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


Согласование позиционирования с темой оформления

Позиционирование контролов может сочетаться с темами UI. В зависимости от выбранного стиля изменяются:

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

Несмотря на визуальные изменения, логика LayoutAlignment остаётся неизменной, обеспечивая стабильность структуры интерфейса.