Label и текстовые метки

Label в CesiumJS представляет собой один из ключевых механизмов визуализации текстовой информации в 3D-сцене. В отличие от HTML-оверлеев, текстовые метки интегрированы в систему рендеринга WebGL и учитывают глубину сцены, масштабирование, положение камеры и особенности освещения. Label используется как в высокоуровневом API Entities, так и в низкоуровневых коллекциях LabelCollection, обеспечивая гибкость между удобством разработки и производительностью.


Текстовая метка в CesiumJS не является DOM-элементом. Она представляет собой спрайт, который рендерится в экранном пространстве после проекции 3D-координаты на 2D-плоскость.

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

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

Label тесно связан с камерой сцены и пересчитывается при каждом кадре рендеринга.


Label через Entity API

Наиболее распространённый способ работы с текстовыми метками — использование Entity и свойства label.

const entity = viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(37.6173, 55.7558),
  label: {
    text: "Москва",
    font: "16px sans-serif",
    fillColor: Cesium.Color.WHITE,
    outlineColor: Cesium.Color.BLACK,
    outlineWidth: 3,
    style: Cesium.LabelStyle.FILL_AND_OUTLINE
  }
});

Entity API автоматически управляет жизненным циклом метки и её обновлением при изменении позиции или свойств.

Ключевые свойства LabelGraphics

text Основной текст метки. Поддерживает динамические выражения через CallbackProperty.

font CSS-подобное описание шрифта:

font: "bold 14px Arial"

fillColor Цвет заливки текста.

outlineColor и outlineWidth Контур повышает читаемость на сложном фоне.

style Возможные режимы отображения:

  • FILL
  • OUTLINE
  • FILL_AND_OUTLINE

Позиционирование и смещение

pixelOffset

Позволяет смещать текст в экранных пикселях относительно точки привязки.

pixelOffset: new Cesium.Cartesian2(10, -20)

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


eyeOffset

Смещение в координатах камеры:

eyeOffset: new Cesium.Cartesian3(0, 0, -10)

Позволяет визуально “приблизить” или “отдалить” метку относительно точки.


heightReference

Определяет поведение метки относительно поверхности:

  • NONE — абсолютная высота
  • CLAMP_TO_GROUND — привязка к поверхности
  • RELATIVE_TO_GROUND — относительная высота
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND

Управление видимостью

distanceDisplayCondition

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

distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000)

Метки часто скрываются на больших расстояниях для оптимизации сцены.


scaleByDistance

Автоматическое масштабирование:

scaleByDistance: new Cesium.NearFarScalar(1000, 1.0, 5000, 0.2)

Чем дальше объект, тем меньше размер текста.


translucencyByDistance

Контроль прозрачности:

translucencyByDistance: new Cesium.NearFarScalar(2000, 1.0, 6000, 0.0)

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


LabelCollection: низкоуровневый контроль

Для высокопроизводительных сцен применяется LabelCollection.

const labels = viewer.scene.primitives.add(new Cesium.LabelCollection());

labels.add({
  position: Cesium.Cartesian3.fromDegrees(10, 10),
  text: "LabelCollection метка",
  font: "20px sans-serif",
  fillColor: Cesium.Color.YELLOW
});

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

  • минимальные накладные расходы
  • отсутствие Entity-обёртки
  • ручное управление метками
  • высокая производительность при тысячах объектов

Стилизация текста

CesiumJS поддерживает расширенные визуальные параметры.

backgroundColor и backgroundPadding

backgroundColor: Cesium.Color.BLACK.withAlpha(0.7),
backgroundPadding: new Cesium.Cartesian2(6, 4)

Создаёт подложку под текстом для улучшения читаемости.


horizontalOrigin и verticalOrigin

Определяют точку привязки текста:

horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM

Варианты:

  • LEFT, CENTER, RIGHT
  • TOP, CENTER, BOTTOM

Производительность и оптимизация

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

Основные факторы нагрузки:

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

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

Использование LabelCollection вместо Entity при большом количестве объектов:

viewer.entities.removeAll();

и переход к:

new Cesium.LabelCollection()

Минимизация динамических свойств:

text: "Статический текст"

вместо:

text: new Cesium.CallbackProperty(...)

Связь с Billboard и визуальными маркерами

Label часто используется совместно с Billboard:

  • Billboard — графический маркер (иконка)
  • Label — текстовая подпись
viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(30, 50),
  billboard: {
    image: "marker.png"
  },
  label: {
    text: "Объект"
  }
});

Такой подход формирует классическую схему “иконка + подпись”.


Отрисовка и порядок слоёв

Label участвует в системе сортировки прозрачных объектов.

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

  • сортировка по расстоянию до камеры
  • влияние disableDepthTestDistance
  • возможное перекрытие при плотной сцене
disableDepthTestDistance: Number.POSITIVE_INFINITY

Позволяет метке отображаться поверх геометрии.


Динамические метки

Label поддерживает реактивные свойства через CallbackProperty:

label: {
  text: new Cesium.CallbackProperty(function () {
    return "Время: " + new Date().toLocaleTimeString();
  }, false)
}

Такие метки обновляются каждый кадр и подходят для мониторинга данных.


Форматирование текста

Cesium Label поддерживает ограниченное форматирование:

  • перенос строк \n
  • простые текстовые шаблоны
  • отсутствие HTML-разметки
text: "Первая строка\nВторая строка"

Типичные сценарии применения

  • подписи городов и регионов
  • отображение координатных точек
  • визуализация данных датчиков
  • аннотации к объектам 3D Tiles
  • интерфейсные подсказки в сцене