Цвета и изображения

Визуальное оформление сцены играет важную роль при разработке геоинформационных приложений. Цвета позволяют выделять объекты, группировать данные по категориям, отображать состояние элементов и формировать тематические карты. Изображения используются для текстурирования поверхностей, создания иконок, нанесения графических материалов на геометрию и отображения картографических слоёв.

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


Класс Cesium.Color

Основным инструментом работы с цветами является класс Cesium.Color.

Цвет хранится в формате RGBA:

  • R (Red) — красный канал;
  • G (Green) — зелёный канал;
  • B (Blue) — синий канал;
  • A (Alpha) — прозрачность.

Значения компонентов задаются числами от 0.0 до 1.0.

Создание красного цвета:

const color = new Cesium.Color(1.0, 0.0, 0.0, 1.0);

Создание полупрозрачного синего цвета:

const color = new Cesium.Color(0.0, 0.0, 1.0, 0.5);

Готовые цветовые константы

Для большинства стандартных цветов не требуется создавать объекты вручную.

Cesium содержит большой набор встроенных констант:

Cesium.Color.RED
Cesium.Color.GREEN
Cesium.Color.BLUE
Cesium.Color.YELLOW
Cesium.Color.ORANGE
Cesium.Color.WHITE
Cesium.Color.BLACK
Cesium.Color.GRAY
Cesium.Color.CYAN
Cesium.Color.MAGENTA

Пример использования:

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(37.62, 55.75),
    point: {
        pixelSize: 15,
        color: Cesium.Color.RED
    }
});

Прозрачность цвета

Прозрачность регулируется альфа-каналом.

Значения:

Alpha Результат
1.0 Полностью непрозрачный
0.5 Полупрозрачный
0.0 Полностью прозрачный

Пример:

viewer.entities.add({
    polygon: {
        hierarchy: Cesium.Cartesian3.fromDegreesArray([
            30, 60,
            35, 60,
            35, 65,
            30, 65
        ]),
        material: Cesium.Color.BLUE.withAlpha(0.3)
    }
});

Метод withAlpha() позволяет создавать новую версию цвета с изменённой прозрачностью.


Создание цвета из компонентов RGB

Часто цвета задаются привычными значениями от 0 до 255.

Для этого используется метод:

Cesium.Color.fromBytes()

Пример:

const color = Cesium.Color.fromBytes(
    255,
    128,
    0,
    255
);

Полученный цвет соответствует оранжевому оттенку.


Создание цвета из CSS-строки

Cesium умеет интерпретировать CSS-цвета.

Используется метод:

Cesium.Color.fromCssColorString()

Пример:

const color = Cesium.Color.fromCssColorString("#ff0000");

RGB-запись:

const color = Cesium.Color.fromCssColorString(
    "rgb(0,255,0)"
);

RGBA-запись:

const color = Cesium.Color.fromCssColorString(
    "rgba(0,0,255,0.5)"
);

Именованный цвет:

const color = Cesium.Color.fromCssColorString(
    "gold"
);

Клонирование цветов

Для копирования используется метод:

const color2 = Cesium.Color.clone(color1);

Пример:

const baseColor = Cesium.Color.RED;
const copyColor = Cesium.Color.clone(baseColor);

Это полезно при последующей модификации цвета без изменения исходного объекта.


Интерполяция цветов

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

Для вычисления промежуточного цвета применяется метод:

Cesium.Color.lerp()

Пример:

const result = new Cesium.Color();

Cesium.Color.lerp(
    Cesium.Color.RED,
    Cesium.Color.BLUE,
    0.5,
    result
);

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


Цвета точек

Графический объект PointGraphics поддерживает цветовую настройку.

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(37, 55),
    point: {
        pixelSize: 20,
        color: Cesium.Color.YELLOW
    }
});

Дополнительно можно настроить контур:

point: {
    pixelSize: 20,
    color: Cesium.Color.YELLOW,
    outlineColor: Cesium.Color.BLACK,
    outlineWidth: 2
}

Цвета линий

Для полилиний цвет задаётся через материал.

viewer.entities.add({
    polyline: {
        positions: Cesium.Cartesian3.fromDegreesArray([
            30, 50,
            40, 60
        ]),
        width: 5,
        material: Cesium.Color.RED
    }
});

Полупрозрачная линия:

material: Cesium.Color.RED.withAlpha(0.5)

Цвета полигонов

Полигоны используют свойство material.

viewer.entities.add({
    polygon: {
        hierarchy: Cesium.Cartesian3.fromDegreesArray([
            20, 50,
            25, 50,
            25, 55,
            20, 55
        ]),
        material: Cesium.Color.GREEN
    }
});

Прозрачный полигон:

material: Cesium.Color.GREEN.withAlpha(0.4)

Цвета эллипсов

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(30, 60),
    ellipse: {
        semiMajorAxis: 50000,
        semiMinorAxis: 30000,
        material: Cesium.Color.CYAN
    }
});

Полупрозрачный вариант:

material: Cesium.Color.CYAN.withAlpha(0.5)

Цвета объёмных фигур

Материал доступен для большинства трёхмерных объектов:

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(30, 60),
    box: {
        dimensions: new Cesium.Cartesian3(
            50000,
            50000,
            50000
        ),
        material: Cesium.Color.ORANGE
    }
});

Цилиндр:

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(35, 60),
    cylinder: {
        length: 100000,
        topRadius: 20000,
        bottomRadius: 20000,
        material: Cesium.Color.BLUE
    }
});

Цветовые материалы

В простейшем случае объект получает материал цвета:

material: Cesium.Color.RED

Однако фактически используется объект:

new Cesium.ColorMaterialProperty(
    Cesium.Color.RED
)

Эквивалентная запись:

material: new Cesium.ColorMaterialProperty(
    Cesium.Color.RED
)

Использование изображений

Во многих случаях вместо однотонного цвета требуется использовать графическое изображение.

Материал может содержать текстуру.

Пример:

viewer.entities.add({
    polygon: {
        hierarchy: Cesium.Cartesian3.fromDegreesArray([
            20, 50,
            25, 50,
            25, 55,
            20, 55
        ]),
        material: "./textures/grass.jpg"
    }
});

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


ImageMaterialProperty

Для расширенного управления текстурами используется класс:

Cesium.ImageMaterialProperty

Пример:

material: new Cesium.ImageMaterialProperty({
    image: "./textures/brick.jpg"
})

Прозрачность изображения

Изображение может быть дополнительно смешано с цветом.

material: new Cesium.ImageMaterialProperty({
    image: "./textures/stone.jpg",
    color: Cesium.Color.WHITE.withAlpha(0.5)
})

В результате текстура станет полупрозрачной.


Повторение текстуры

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

material: new Cesium.ImageMaterialProperty({
    image: "./textures/tile.png",
    repeat: new Cesium.Cartesian2(5, 5)
})

Здесь текстура повторится пять раз по каждой координатной оси.


Использование изображений в билбордах

Billboard представляет собой плоское изображение, всегда ориентированное к камере.

Пример:

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(37.62, 55.75),
    billboard: {
        image: "./icons/marker.png"
    }
});

Масштабирование билбордов

Размер изображения изменяется через свойство scale.

billboard: {
    image: "./icons/marker.png",
    scale: 2.0
}

Уменьшение:

scale: 0.5

Изменение размеров изображения

Фиксированные размеры задаются явно:

billboard: {
    image: "./icons/marker.png",
    width: 64,
    height: 64
}

Цветовая модификация билбордов

Изображение может быть окрашено поверх исходной текстуры.

billboard: {
    image: "./icons/marker.png",
    color: Cesium.Color.RED
}

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


Прозрачность билбордов

billboard: {
    image: "./icons/marker.png",
    color: Cesium.Color.WHITE.withAlpha(0.5)
}

Изображение становится полупрозрачным.


Использование Canvas как изображения

Вместо готового файла можно использовать HTML Canvas.

Создание холста:

const canvas =
    document.createElement("canvas");

canvas.width = 128;
canvas.height = 128;

const ctx = canvas.getContext("2d");

ctx.fillStyle = "red";
ctx.fillRect(0, 0, 128, 128);

Использование:

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(30, 60),
    billboard: {
        image: canvas
    }
});

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


Использование SVG

Cesium поддерживает SVG-файлы.

billboard: {
    image: "./icons/location.svg"
}

Преимущества SVG:

  • масштабирование без потери качества;
  • небольшой размер файлов;
  • удобное изменение стилей;
  • высокая чёткость на дисплеях высокого разрешения.

Использование Data URI

Изображение может храниться непосредственно в строке.

billboard: {
    image:
        "data:image/png;base64,iVBOR..."
}

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


Изображения в прямоугольниках

Геометрия RectangleGraphics также поддерживает текстуры.

viewer.entities.add({
    rectangle: {
        coordinates:
            Cesium.Rectangle.fromDegrees(
                20,
                50,
                30,
                60
            ),
        material: "./images/map.png"
    }
});

Комбинирование цвета и изображения

Материал изображения может одновременно использовать текстуру и цветовой фильтр.

material: new Cesium.ImageMaterialProperty({
    image: "./textures/grid.png",
    color: Cesium.Color.YELLOW
})

Фильтр применяется поверх изображения.


Динамическое изменение цвета

Цвет можно изменять во время выполнения программы.

const entity = viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(30, 60),
    point: {
        pixelSize: 20,
        color: Cesium.Color.RED
    }
});

Позже:

entity.point.color = Cesium.Color.BLUE;

Изменение будет мгновенно отображено на сцене.


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

Для билбордов возможно изменение источника изображения.

entity.billboard.image =
    "./icons/new-icon.png";

После обновления объект автоматически перерисуется.


Практические сценарии применения

Тематические карты

Разные категории объектов выделяются цветом:

city.point.color = Cesium.Color.GREEN;
airport.point.color = Cesium.Color.BLUE;
port.point.color = Cesium.Color.ORANGE;

Тепловые зоны

Интенсивность отображается прозрачностью:

material:
    Cesium.Color.RED.withAlpha(value);

Иконки объектов

billboard: {
    image: "./icons/airport.png"
}

Фотореалистичные поверхности

material: new Cesium.ImageMaterialProperty({
    image: "./textures/asphalt.jpg"
})

Выделение выбранных объектов

entity.polygon.material =
    Cesium.Color.YELLOW;

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