SVG-изображения в CesiumJS не рендерятся напрямую как в DOM или браузерных интерфейсах. Вся сцена работает через WebGL, поэтому любые векторные данные SVG неизбежно проходят стадию растеризации и превращаются в растровые текстуры перед отображением. Это фундаментальное ограничение определяет архитектуру использования иконок в 3D-карте и влияет на производительность, качество и способы интеграции SVG.
CesiumJS не интерпретирует SVG как векторную графику внутри сцены. Вместо этого SVG используется как источник изображения, которое:
Таким образом, итоговая отрисовка всегда растровая, даже если исходник — вектор.
Ключевая особенность:
SVG не сохраняет векторную природу в сцене CesiumJS — он служит лишь форматом источника изображения.
Это означает, что масштабирование после загрузки не увеличивает детализацию, как в классическом SVG в HTML.
Основной сценарий использования SVG в CesiumJS — иконки маркеров
через BillboardGraphics в системе сущностей.
const viewer = new Cesium.Viewer("cesiumContainer");
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(37.6173, 55.7558),
billboard: {
image: "icons/marker.svg",
width: 32,
height: 32
}
});
SVG передаётся как обычный URL. Cesium передаёт его в загрузчик изображения браузера, после чего результат становится текстурой.
При таком подходе:
SVG может быть встроен прямо в код через Data URI. Это удобно для динамической генерации иконок.
const svg = `
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64">
<circle cx="32" cy="32" r="30" fill="red"/>
</svg>
`;
const dataUri = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg);
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(10, 10),
billboard: {
image: dataUri,
width: 32,
height: 32
}
});
Такой подход часто используется для:
Cesium предоставляет Cesium.Resource, который управляет
загрузкой изображений с учётом кэша и асинхронности.
const resource = Cesium.Resource.fetchImage({
url: "icons/pin.svg"
});
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(20, 20),
billboard: {
image: resource,
width: 40,
height: 40
}
});
Особенность такого подхода — унифицированный pipeline загрузки ресурсов Cesium, включая:
CesiumJS не редактирует SVG как DOM-объект, но предоставляет механизмы постобработки уже растеризованного изображения.
Основной инструмент — color, colorBlendMode
и colorBlendAmount у BillboardGraphics.
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(30, 30),
billboard: {
image: "icons/arrow.svg",
color: Cesium.Color.BLUE,
colorBlendMode: Cesium.ColorBlendMode.REPLACE,
colorBlendAmount: 1.0
}
});
Эти режимы работают на уровне шейдера, а не SVG.
Использование SVG сопровождается рядом технических ограничений:
После загрузки SVG превращается в текстуру фиксированного разрешения.
SVG-фильтры (blur, drop-shadow, feGaussianBlur) могут:
Текст внутри SVG может:
Частая загрузка SVG увеличивает нагрузку из-за:
Cesium не управляет процессом преобразования SVG → bitmap напрямую. Итоговое качество зависит от:
Практическое правило:
SVG должен быть рассчитан на конечный размер отображения, а не на масштабирование в CesiumJS.
Пример:
width: 32,
height: 32
SVG желательно создавать с viewBox, соответствующим плотному разрешению.
Entity API позволяет централизованно управлять иконками, включая SVG как источник изображения.
const entity = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(40, 40),
billboard: {
image: "icons/hospital.svg",
width: 48,
height: 48,
alignedAxis: Cesium.Cartesian3.UNIT_Z
}
});
Дополнительно можно управлять поведением:
showscaledistanceDisplayConditionCesium не анимирует SVG внутри сцены, но поддерживает имитацию анимации через смену изображений.
let frame = 0;
const frames = [
"icons/a1.svg",
"icons/a2.svg",
"icons/a3.svg"
];
viewer.clock.onTick.addEventListener(() => {
frame = (frame + 1) % frames.length;
entity.billboard.image = frames[frame];
});
Этот подход используется для:
SVG часто заменяется альтернативными подходами из-за производительности.
const canvas = document.createElement("canvas");
canvas.width = 64;
canvas.height = 64;
const ctx = canvas.getContext("2d");
ctx.fillStyle = "red";
ctx.beginPath();
ctx.arc(32, 32, 20, 0, Math.PI * 2);
ctx.fill();
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(50, 50),
billboard: {
image: canvas
}
});
Преимущество — полный контроль рендеринга без SVG-парсинга.
При большом количестве иконок используется атлас:
imageSubRegionЭто уменьшает количество WebGL-текстур и повышает FPS.
SVG может использоваться вне сцены CesiumJS как часть UI-слоя:
Такой подход отделяет:
Это снижает нагрузку на рендеринг сцены и упрощает интерактивность.
Типичная архитектура включает промежуточный слой:
Пример утилитарного подхода:
function svgToDataUri(svgString) {
return "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svgString);
}
function createIcon(svg) {
return {
image: svgToDataUri(svg),
width: 32,
height: 32
};
}
В CesiumJS масштабирование сцены не влияет на пиксельную плотность иконок напрямую.
Ключевые параметры:
scale — масштаб billboardpixelOffset — смещениеeyeOffset — смещение в 3D пространствеbillboard: {
image: "icons/point.svg",
scale: 1.5,
pixelOffset: new Cesium.Cartesian2(10, -10)
}
При увеличении масштаба карты SVG не становится «детальнее», так как он уже растеризован.
SVG в CesiumJS функционирует не как векторный элемент сцены, а как промежуточный формат текстурирования, интегрированный в WebGL-пайплайн через стандартные механизмы загрузки изображений и entity-систему билбордов, что определяет его поведение, ограничения и оптимальные сценарии применения.