Порядок отображения и z-index

В OpenLayers визуальное перекрытие объектов на карте определяется несколькими независимыми механизмами: порядком слоёв в карте, параметрами z-index у слоёв, внутренним порядком отрисовки объектов внутри слоя и отдельными правилами для DOM-оверлеев.

Система рендеринга строится по принципу слоёного стека, где каждый уровень может иметь собственный контекст отрисовки (Canvas, WebGL или DOM). Итоговое изображение формируется путём последовательного наложения этих слоёв.


Порядок слоёв в карте

Базовый механизм определения глубины — порядок добавления слоёв в объект карты:

  • слой, добавленный раньше, отображается ниже
  • слой, добавленный позже, перекрывает предыдущие
map.addLayer(rasterLayer);
map.addLayer(vectorLayer);
map.addLayer(labelLayer);

В этом случае labelLayer будет находиться выше остальных, независимо от их типа.

При использовании коллекции слоёв (ol/Collection) порядок определяется индексами внутри массива. Изменение порядка элементов коллекции немедленно влияет на визуальное перекрытие.


Свойство zIndex у слоёв

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

layer.setZIndex(10);

Слои с большим zIndex отображаются выше слоёв с меньшим значением, независимо от порядка добавления.

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

  • zIndex работает только внутри группы слоёв одного контейнера карты
  • при равных значениях учитывается порядок добавления
  • отсутствие zIndex интерпретируется как 0

Типичная схема использования:

  • базовая подложка: zIndex = 0
  • тематические слои: zIndex = 5–10
  • подписи и маркеры: zIndex = 20+

Группы слоёв и вложенная сортировка

LayerGroup позволяет объединять слои в логические блоки. Внутри группы сохраняются те же правила:

  • порядок внутри группы определяется массивом слоёв
  • zIndex применяется как дополнительный уровень сортировки
  • группы сами участвуют в глобальной сортировке как единый слой

При конфликте значений:

  1. сравнивается zIndex группы
  2. затем учитывается порядок внутри группы

Векторные объекты и порядок внутри слоя

Векторный слой (VectorLayer) имеет собственный порядок отрисовки фич.

По умолчанию:

  • объекты рисуются в порядке добавления в источник (source)
  • последние добавленные объекты оказываются поверх

Управление порядком через zIndex у стилей

Для точечного и линейного рендера используется стиль с zIndex:

style: new Style({
  zIndex: 5
})

Более высокие значения поднимают объект выше других в пределах одного слоя.


Геометрия и приоритет рисования

При отрисовке внутри одного слоя учитываются дополнительные факторы:

  • тип геометрии (полигон под линией, линия под точкой)
  • порядок в массиве фич
  • стиль с заданным zIndex

При конфликте перекрытия:

  1. полигоны рисуются первыми
  2. линии поверх полигонов
  3. точки поверх линий

Это поведение можно частично переопределять стилями и кастомной сортировкой.


Canvas и WebGL: различия в порядке наложения

Canvas-рендерер

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

  • каждый слой отрисовывается последовательно
  • перерисовка полностью пересобирает изображение
  • z-index применяется до начала рендеринга

WebGL-рендерер

В WebGL:

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

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


Overlay и DOM-слои

DOM-оверлеи (Overlay) находятся вне canvas-контекста карты и управляются через CSS.

Основной механизм:

overlay.getElement().style.zIndex = '1000';

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

  • DOM-элементы всегда выше canvas-слоёв
  • порядок определяется исключительно CSS z-index
  • разные overlay сравниваются как обычные DOM-элементы

Контейнер карты обычно имеет базовый стек, внутри которого overlay располагаются поверх всех визуальных слоёв карты.


Маркеры и HTML-элементы

HTML-маркеры, созданные через Overlay, ведут себя как обычные DOM-узлы:

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

Конфликты z-index часто возникают между:

  • контролами карты (zoom, attribution)
  • overlay-элементами
  • пользовательскими HTML-маркерами

Стили и приоритеты отображения объектов

Векторные стили позволяют управлять визуальной иерархией внутри одного слоя:

  • zIndex в Style
  • условия на основе свойств фич (feature.get(...))
  • динамическая сортировка через функцию стиля

Пример приоритизации:

  • критические объекты (аварии) → высокий zIndex
  • обычные объекты → средний
  • фоновые элементы → низкий

Сортировка через renderOrder

Для более тонкого контроля используется renderOrder:

layer.setRenderOrder((a, b) => {
  return a.get('priority') - b.get('priority');
});

Механизм позволяет:

  • переопределять стандартный порядок фич
  • учитывать атрибуты объектов
  • строить сложные правила визуальной иерархии

Конфликты и типичные особенности поведения

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

  • zIndex слоя перекрывает порядок добавления
  • renderOrder влияет только внутри слоя
  • DOM-оверлеи игнорируют Canvas-логику
  • WebGL может группировать элементы независимо от порядка источника

При отладке визуального перекрытия учитываются сразу три уровня:

  1. стек слоёв карты
  2. внутренняя сортировка слоя
  3. DOM/CSS-иерархия оверлеев