Информационные окна (InfoBox) в CesiumJS предназначены для отображения сведений о выбранном объекте сцены. Они позволяют выводить текст, HTML-разметку, ссылки, таблицы, изображения и другие данные, связанные с сущностью (Entity). Информационные окна являются важным элементом интерфейса геоинформационных приложений, поскольку обеспечивают удобное взаимодействие пользователя с объектами на глобусе.
В стандартной конфигурации CesiumJS информационное окно автоматически
появляется при выборе сущности мышью и отображает содержимое свойства
description.
При создании объекта Viewer компонент информационного
окна включён по умолчанию:
const viewer = new Cesium.Viewer("cesiumContainer");
В этом случае интерфейс содержит:
Если пользователь выбирает сущность, имеющую описание, оно автоматически отображается в информационном окне.
Пример создания объекта:
viewer.entities.add({
name: "Город Алматы",
position: Cesium.Cartesian3.fromDegrees(76.8897, 43.2389),
point: {
pixelSize: 12,
color: Cesium.Color.RED
},
description: "Крупнейший город Казахстана."
});
После щелчка по точке появится окно с указанным текстом.
Основным источником данных для информационного окна является свойство
description.
Простейший вариант:
viewer.entities.add({
name: "Объект",
description: "Описание объекта"
});
Описание может быть:
Property;Например:
viewer.entities.add({
name: "Башня",
description: new Cesium.ConstantProperty(
"Высота сооружения: 120 метров"
)
});
InfoBox поддерживает HTML-контент.
Пример:
viewer.entities.add({
name: "Метеостанция",
description: `
<h2>Метеостанция №1</h2>
<p>Температура: <b>18°C</b></p>
<p>Влажность: <b>72%</b></p>
`
});
Результат включает форматированный текст с заголовками и выделениями.
Допустимо использовать:
<h1>
<h2>
<h3>
<p>
<div>
<span>
<ul>
<li>
<table>
<img>
<a>
Часто информация представляется в виде таблиц.
Пример:
viewer.entities.add({
name: "Спутник",
description: `
<table border="1">
<tr>
<th>Параметр</th>
<th>Значение</th>
</tr>
<tr>
<td>Высота</td>
<td>550 км</td>
</tr>
<tr>
<td>Скорость</td>
<td>7.8 км/с</td>
</tr>
</table>
`
});
Подобный подход широко применяется в системах мониторинга, диспетчерских приложениях и цифровых картах.
В описании можно размещать изображения.
Пример:
viewer.entities.add({
name: "Озеро",
description: `
<h2>Озеро Балхаш</h2>
<img
src="images/balkhash.jpg"
width="300"
>
`
});
Изображения могут загружаться:
Пример:
<img src="https://example.com/photo.jpg">
Информационные окна поддерживают гиперссылки.
viewer.entities.add({
name: "Документация",
description: `
<a href="https://cesium.com/learn/"
target="_blank">
Открыть документацию
</a>
`
});
Ссылки часто используются для перехода:
Информация может формироваться в момент отображения.
Для этого используется CallbackProperty.
const aircraft = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(70, 50),
point: {
pixelSize: 10
}
});
aircraft.description =
new Cesium.CallbackProperty(function() {
const altitude =
Math.floor(Math.random() * 10000);
return `
<h3>Самолёт</h3>
<p>Высота: ${altitude} м</p>
`;
}, false);
При каждом обновлении интерфейса содержимое пересчитывается.
Такой механизм полезен для:
Описание может содержать данные самой сущности.
const entity = viewer.entities.add({
name: "Датчик",
position: Cesium.Cartesian3.fromDegrees(75, 42)
});
entity.description =
new Cesium.CallbackProperty(function() {
const cartographic =
Cesium.Cartographic.fromCartesian(
entity.position.getValue(
Cesium.JulianDate.now()
)
);
return `
<p>Широта:
${Cesium.Math.toDegrees(
cartographic.latitude
).toFixed(4)}
</p>
`;
}, false);
В результате данные внутри окна всегда соответствуют текущему состоянию объекта.
Информационное окно может открываться без участия пользователя.
Для этого используется свойство:
viewer.selectedEntity = entity;
Пример:
const city = viewer.entities.add({
name: "Астана",
description: "Столица Казахстана"
});
viewer.selectedEntity = city;
После выполнения кода окно автоматически откроется.
Для скрытия окна необходимо сбросить выбранную сущность.
viewer.selectedEntity = undefined;
Или:
viewer.selectedEntity = null;
После этого окно исчезнет.
Текущий выбранный объект хранится в свойстве:
viewer.selectedEntity
Пример:
if (viewer.selectedEntity) {
console.log(
viewer.selectedEntity.name
);
}
Это позволяет организовать дополнительную бизнес-логику после выбора объекта.
Для отслеживания выбора используется событие:
viewer.selectedEntityChanged
Пример:
viewer.selectedEntityChanged.addEventListener(
function(entity) {
if (entity) {
console.log(
"Выбран объект:",
entity.name
);
}
}
);
Событие срабатывает:
Компонент можно отключить при создании Viewer.
const viewer = new Cesium.Viewer(
"cesiumContainer",
{
infoBox: false
}
);
После этого стандартное окно отсутствует.
Такой подход применяется при разработке собственного пользовательского интерфейса.
Компонент информационного окна существует как самостоятельный виджет.
Создание:
const infoBox = new Cesium.InfoBox(
document.getElementById("infoBox")
);
После создания появляется независимое окно, не связанное напрямую с Viewer.
Это позволяет:
Внутри InfoBox используется объект InfoBoxViewModel.
Пример:
infoBox.viewModel.titleText =
"Информация";
infoBox.viewModel.description =
"<p>Содержимое окна</p>";
Изменение свойств приводит к автоматическому обновлению интерфейса.
Основные свойства:
| Свойство | Назначение |
|---|---|
| titleText | Заголовок |
| description | HTML-содержимое |
| showInfo | Видимость |
| enableCamera | Кнопка перехода |
| isCameraTracking | Режим слежения |
Стандартное информационное окно содержит кнопку камеры.
Она позволяет быстро перейти к выбранному объекту.
При выборе сущности:
viewer.selectedEntity = entity;
нажатие на кнопку вызывает перемещение камеры к объекту.
Этот механизм особенно полезен при работе с большим количеством сущностей.
После выбора объекта возможно включение режима слежения.
viewer.trackedEntity = entity;
Теперь камера будет автоматически сопровождать объект.
Информационное окно продолжит отображать данные выбранной сущности.
Отключение:
viewer.trackedEntity = undefined;
Внешний вид содержимого можно полностью контролировать через CSS.
HTML:
description: `
<div class="station-info">
<h2>Станция</h2>
<p>Статус: активна</p>
</div>
`
CSS:
.station-info {
font-family: Arial;
padding: 10px;
}
.station-info h2 {
color: #2c6cb0;
}
Это позволяет привести окно к стилю всего приложения.
Содержимое description вставляется как HTML.
При работе с внешними источниками данных необходимо учитывать риск внедрения вредоносного кода.
Опасный пример:
description =
serverResponse;
Безопаснее выполнять предварительную очистку данных:
description =
sanitize(serverResponse);
Особенно это важно для:
Распространённым приёмом является автоматическое формирование HTML.
Исходные данные:
const station = {
id: 10,
name: "Станция А",
temperature: 21,
humidity: 65
};
Генерация:
const html = `
<h2>${station.name}</h2>
<p>ID: ${station.id}</p>
<p>Температура: ${station.temperature}</p>
<p>Влажность: ${station.humidity}%</p>
`;
Использование:
viewer.entities.add({
description: html
});
Подобная техника позволяет быстро строить интерфейсы мониторинга и аналитические панели.
const airport = viewer.entities.add({
name: "Аэропорт",
position: Cesium.Cartesian3.fromDegrees(
71.466,
51.022
),
point: {
pixelSize: 12,
color: Cesium.Color.ORANGE
},
description: `
<h2>Международный аэропорт</h2>
<table border="1">
<tr>
<td>Статус</td>
<td>Открыт</td>
</tr>
<tr>
<td>Рейсов сегодня</td>
<td>128</td>
</tr>
</table>
<br>
<img
src="images/airport.jpg"
width="280"
>
`
});
viewer.selectedEntity = airport;
Данный пример объединяет большинство возможностей информационных окон: программное открытие, форматированный HTML, таблицу данных и встроенное изображение.