Перейти к основному содержимому

Раскрашивание объектов

Вы можете выделять на карте с помощью клика различные объекты: здания, дороги, иконки и т. д. Для обычного и выделенного состояния объекта вы можете задавать разные настройки отображения. Например, здание в обычном состоянии может иметь серый цвет, а в выделенном (при клике на здание) перекрашиваться в красный цвет.

Вы можете настроить цвета объекта в разных состояниях двумя способами:

  • С помощью Редактора стилей. Вы можете задавать общие настройки цвета для группы объектов, отображение которых настраивается в соответствующем слое в Редакторе стилей. Например, с помощью отдельных слоёв можно задать настройки цветов административных зданий, магистральных дорог и так далее: см. список готовых слоёв. При клике на объекты они будут раскрашиваться согласно настройкам слоя.
  • С помощью глобальных переменных стиля карты. Вы можете изменять цвета любых объектов при клике на них независимо от слоя, которому они принадлежат.

С помощью глобальных стилевых переменных вы также можете раскрашивать объекты не при клике, а автоматически при выполнении определённых условий (например, раскрашивать здания с определённым количеством этажей).

Настройка при клике с помощью Редактора стилей

В этом примере при клике на объекты они будут раскрашиваться согласно настройкам цвета для выделенного состояния, которые указаны в стилевых слоях в Редакторе стилей. Для настроек разных объектов используются соответствующие стилевые слои, например, цвета административных зданий и жилых зданий задаются в разных слоях. Все объекты, принадлежащие одному слою, раскрашиваются одинаково.

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

Для некоторых слоёв настройка цвета в разных состояниях недоступна, например, для водоёмов (слой Water).

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


Чтобы настроить раскрашивание объектов при клике с помощью Редактора стилей:

  1. Задайте настройки стилевого слоя в Редакторе стилей:

    1. Откройте Редактор стилей.

    2. Откройте нужный стиль.

    3. Откройте нужный слой. Укажите настройки цвета для обычного и выделенного состояния.

      Пример для промышленных зданий (слой Industrial buildings):

      Состояния объекта
  2. Чтобы настроить выделение объектов, добавьте обработчик кликов для карты и передайте ID выделенных объектов в метод setSelectedObjects():

    let selectedIds = [];

    map.on('click', (e) => {
    if (!e.target) {
    return;
    }

    const { id } = e.target;

    if (selectedIds.includes(id)) {
    selectedIds = selectedIds.filter((i) => i !== id);
    } else {
    selectedIds.push(id);
    }

    map.setSelectedObjects(selectedIds);
    });

    Подробнее о выделении объектов см. в инструкции Выделение объектов.

Настройка при клике с помощью глобальных переменных

В этом примере при клике на объекты они будут раскрашиваться согласно настройкам цвета, которые передаются в глобальных переменных стиля карты.

Вы можете выбирать три цвета для раскраски зданий с помощью цветовых палитр: цвет стен, крыши и обводки (рёбер здания). При клике на здания на карте они будут автоматически раскрашиваться в выбранные цвета. Административные здания, жилые здания и другие типы зданий будут иметь одинаковые настройки независимо от слоя, которому они принадлежат.

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


Чтобы настроить раскрашивание объектов при клике с помощью глобальных стилевых переменных:

  1. Создайте слой с 3D-зданиями:

    const building = {
    id: 'wallsSelectLayer',
    type: 'polygonExtrusion',
    style: {
    topColor: [
    'match',
    ['to-boolean', ['global', 'wallColorTop']],
    [true],
    ['to-color', ['global', 'wallColorTop']],
    'rgba(1,1,1,1)',
    ],
    sideColor: [
    'match',
    ['to-boolean', ['global', 'wallColorDown']],
    [true],
    ['to-color', ['global', 'wallColorDown']],
    'rgba(1,1,1,1)',
    ],
    visibility: 'visible',
    strokeColor: [
    'match',
    ['to-boolean', ['global', 'strokeColor']],
    [true],
    ['to-color', ['global', 'strokeColor']],
    'rgba(1,1,1,1)',
    ],
    strokeWidth: 0.1,
    },
    filter: ['in', ['get', 'db_id'], ['global', 'hoverId']],
    };

    Инициализируйте следующие глобальные переменные стиля карты:

    • wallColorTop — для настройки цвета крыши;
    • wallColorDown — для настройки цвета стен;
    • strokeColor — для настройки цвета обводки зданий;
    • hoverId — для настройки цвета только для выделенных зданий на карте.
  2. Передайте в метод map.patchStyleState() созданные глобальные переменные. Укажите начальные цвета для wallColorDown, wallColorTop и strokeColor, а также передайте выделенные объекты (массив selectedIds) в hoverId:

    window.map = map;

    map.on('styleload', () => {
    map.patchStyleState({
    wallColorDown: 'rgba(143,219,126,1)',
    wallColorTop: 'rgba(237,255,155,1)',
    strokeColor: 'rgba(237,255,155,1)',
    hoverId: selectedIds,
    });

    // Выделение объектов
    map.setSelectedObjects(selectedIds);

    // Добавление слоя со зданиями
    map.addLayer(building);
    });
  3. Чтобы настроить выделение зданий по клику, добавьте обработчик кликов для карты и передайте ID выделенных объектов в метод map.patchStyleState():

    map.on('click', (ev) => {
    const id = ev.target?.id;
    if (!id) return;
    selectedIds = selectedIds.includes(id)
    ? selectedIds.filter((selectId) => selectId !== id)
    : [...selectedIds, id];
    map.patchStyleState({ hoverId: selectedIds });
    });
  4. Создайте функцию для обновления цветов зданий, которые будут меняться в зависимости от выбранных цветов в палитрах, и передайте новые значения цвета в метод map.patchStyleState():

    function updateColor(pickerId, stateKey) {
    const picker = document.getElementById(pickerId);
    picker?.addEventListener('color-changed', (event) => {
    const v = event.detail?.value;
    if (!v) return;
    map.patchStyleState({
    [stateKey]: `rgba(${v.r},${v.g},${v.b},${v.a})`,
    });
    });
    }
    updateColor('wallDown', 'wallColorDown');
    updateColor('wallTop', 'wallColorTop');
    updateColor('strokeColor', 'strokeColor');

Настройка по условиям с помощью глобальных переменных

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

В этом примере здания раскрашиваются в зависимости от количества этажей: сначала выделяются и раскрашиваются здания с наибольшим количеством этажей в области видимости карты, затем раскрашиваются здания с количеством этажей меньше на один и так далее. После того как все здания в области видимости карты раскрашены, автоматически снимается выделение, начиная со зданий с наименьшим количеством этажей. Вы можете выбирать три цвета для раскраски зданий с помощью цветовых палитр: цвет стен, крыши и обводки (рёбер здания).

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


Чтобы настроить раскрашивание объектов по условиям с помощью глобальных стилевых переменных:

  1. Создайте слой с 3D-зданиями:

    const building = {
    id: 'wallsSelectLayer',
    type: 'polygonExtrusion',
    style: {
    topColor: [
    'match',
    ['to-boolean', ['global', 'wallColorTop']],
    [true],
    ['to-color', ['global', 'wallColorTop']],
    'rgba(1,1,1,1)',
    ],
    sideColor: [
    'match',
    ['to-boolean', ['global', 'wallColorDown']],
    [true],
    ['to-color', ['global', 'wallColorDown']],
    'rgba(1,1,1,1)',
    ],
    visibility: 'visible',
    strokeColor: [
    'match',
    ['to-boolean', ['global', 'strokeColor']],
    [true],
    ['to-color', ['global', 'strokeColor']],
    'rgba(1,1,1,1)',
    ],
    strokeWidth: 0.1,
    },
    filter: ['all', ['>', ['get', 'db_height'], ['global', 'floorsCurrentHeight']]],
    };

    Инициализируйте следующие глобальные переменные стиля карты:

    • wallColorTop — для настройки цвета крыши;
    • wallColorDown — для настройки цвета стен;
    • strokeColor — для настройки цвета обводки зданий;
    • floorsCurrentHeight — для настройки цвета зданий с определённым количеством этажей.
  2. Передайте в метод map.patchStyleState() созданные глобальные переменные. Укажите начальные цвета для wallColorDown, wallColorTop и strokeColor, а также передайте выделенные объекты (массив selectedIds) в hoverId:

    window.map = map;

    map.on('styleload', () => {
    map.patchStyleState({
    wallColorDown: 'rgba(143,219,126,1)',
    wallColorTop: 'rgba(237,255,155,1)',
    strokeColor: 'rgba(237,255,155,1)',
    hoverId: selectedIds,
    });

    // Выделение объектов
    map.setSelectedObjects(selectedIds);

    // Добавление слоя со зданиями
    map.addLayer(building);
    });
  3. Чтобы настроить выделение зданий по клику, добавьте обработчик кликов для карты и передайте ID выделенных объектов в метод map.patchStyleState():

    map.on('click', async (ev) => {
    const id = ev.target && ev.target.id;
    if (selectedIds.includes(id)) {
    selectedIds = selectedIds.filter((selectId) => selectId !== id);
    } else {
    selectedIds.push(id);
    }
    map.patchStyleState({
    hoverId: selectedIds,
    });
    map.setSelectedObjects(selectedIds);
    });
  4. Создайте функцию для обновления цветов зданий, которые будут меняться в зависимости от выбранных цветов в палитрах, и передайте новые значения цвета в метод map.patchStyleState():

    function updateColor(pickerId, stateKey) {
    const picker = document.getElementById(pickerId);
    picker?.addEventListener('color-changed', (event) => {
    const v = event.detail?.value;
    if (!v) return;
    map.patchStyleState({
    [stateKey]: `rgba(${v.r},${v.g},${v.b},${v.a})`,
    });
    });
    }
    updateColor('wallDown', 'wallColorDown');
    updateColor('wallTop', 'wallColorTop');
    updateColor('strokeColor', 'strokeColor');
  5. Задайте условия для раскрашивания зданий в зависимости от количества этажей и передайте количество этажей в метод map.patchStyleState():

    const MAX_FLOOR_HEIGHT = 8000;
    let STEP = 500;
    let currentFloorHeight = MAX_FLOOR_HEIGHT;
    let isDecreasing = false;

    setInterval(() => {
    if (isDecreasing) {
    STEP = -500;
    } else {
    STEP = 500;
    }

    if (currentFloorHeight <= 0) {
    isDecreasing = true;
    } else if (currentFloorHeight > MAX_FLOOR_HEIGHT) {
    isDecreasing = false;
    }

    currentFloorHeight = currentFloorHeight - STEP;
    map.patchStyleState({ floorsCurrentHeight: currentFloorHeight });
    }, 1000);