Раскрашивание объектов
Вы можете выделять на карте с помощью клика различные объекты: здания, дороги, иконки и т. д. Для обычного и выделенного состояния объекта вы можете задавать разные настройки отображения. Например, здание в обычном состоянии может иметь серый цвет, а в выделенном (при клике на здание) перекрашиваться в красный цвет.
Вы можете настроить цвета объекта в разных состояниях двумя способами:
- С помощью Редактора стилей. Вы можете задавать общие настройки цвета для группы объектов, отображение которых настраивается в соответствующем слое в Редакторе стилей. Например, с помощью отдельных слоёв можно задать настройки цветов административных зданий, магистральных дорог и так далее: см. список готовых слоёв. При клике на объекты они будут раскрашиваться согласно настройкам слоя.
- С помощью глобальных переменных стиля карты. Вы можете изменять цвета любых объектов при клике на них независимо от слоя, которому они принадлежат.
С помощью глобальных стилевых переменных вы также можете раскрашивать объекты не при клике, а автоматически при выполнении определённых условий (например, раскрашивать здания с определённым количеством этажей).
Настройка при клике с помощью Редактора стилей
В этом примере при клике на объекты они будут раскрашиваться согласно настройкам цвета для выделенного состояния, которые указаны в стилевых слоях в Редакторе стилей. Для настроек разных объектов используются соответствующие стилевые слои, например, цвета административных зданий и жилых зданий задаются в разных слоях. Все объекты, принадлежащие одному слою, раскрашиваются одинаково.
В готовых слоях цвета объектов в разных состояниях настроены заранее, и при необходимости вы можете изменить их в Редакторе стилей. В этом примере новые настройки цвета задаются только для слоя с промышленными зданиями, а для остальных слоёв используются готовые настройки из базового стиля.
Для некоторых слоёв настройка цвета в разных состояниях недоступна, например, для водоёмов (слой Water).
Пример использования:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>2GIS Map API</title>
<meta name="description" content="An object selection example" />
<style>
html,
body,
#container {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="https://mapgl.2gis.com/api/js/v1"></script>
<script>
const map = new mapgl.Map('container', {
center: [37.629589, 55.746067],
zoom: 17,
key: 'Your API access key'
});
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);
});
</script>
</body>
</html>
Чтобы настроить раскрашивание объектов при клике с помощью Редактора стилей:
-
Задайте настройки стилевого слоя в Редакторе стилей:
-
Откройте Редактор стилей.
-
Откройте нужный стиль.
-
Откройте нужный слой. Укажите настройки цвета для обычного и выделенного состояния.
Пример для промышленных зданий (слой Industrial buildings):
-
-
Чтобы настроить выделение объектов, добавьте обработчик кликов для карты и передайте 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); });
Подробнее о выделении объектов см. в инструкции Выделение объектов.
Настройка при клике с помощью глобальных переменных
В этом примере при клике на объекты они будут раскрашиваться согласно настройкам цвета, которые передаются в глобальных переменных стиля карты.
Вы можете выбирать три цвета для раскраски зданий с помощью цветовых палитр: цвет стен, крыши и обводки (рёбер здания). При клике на здания на карте они будут автоматически раскрашиваться в выбранные цвета. Административные здания, жилые здания и другие типы зданий будут иметь одинаковые настройки независимо от слоя, которому они принадлежат.
Пример использования:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>2GIS Map API</title>
<style>
html,
body,
#container {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="https://mapgl.2gis.com/api/js/v1"></script>
<div id="colors" style="position: absolute; top: 0; left: 0; display: flex; gap:15px; flex-direction: column; height: 100%; padding-top: 15px; padding-left: 15px;">
<rgba-color-picker id='wallDown' style="width: 150px; height: 150px;" color='{
"r": 143,
"g": 219,
"b": 126,
"a": 1
}'></rgba-color-picker>
<rgba-color-picker id='wallTop' style="width: 150px; height: 150px;" color='{
"r": 237,
"g": 255,
"b": 155,
"a": 1
}'></rgba-color-picker>
<rgba-color-picker id='strokeColor' style="width: 150px; height: 150px;" color='{
"r": 205,
"g": 250,
"b": 152,
"a": 0.9
}'></rgba-color-picker>
</div>
<script src="https://mapgl.2gis.com/api/js/v1"></script>
<script type="module">
import 'https://esm.sh/vanilla-colorful/rgba-color-picker';
const colorPicker = document.querySelector('rgba-color-picker');
colorPicker.color = { r: 143, g: 219, b: 126, a: 1 };
</script>
<script>
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"],
]
};
// ID здания, которое будет раскрашено по умолчанию
let selectedIds = ["4504235283020869"];
const map = new mapgl.Map('container', {
center: [37.629589, 55.746067],
zoom: 17.2,
rotation: -40,
pitch: 45,
key: 'Your API access key',
});
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);
});
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 });
});
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");
</script>
</body>
</html>
Чтобы настроить раскрашивание объектов при клике с помощью глобальных стилевых переменных:
-
Создайте слой с 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
— для настройки цвета только для выделенных зданий на карте.
-
Передайте в метод 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); });
-
Чтобы настроить выделение зданий по клику, добавьте обработчик кликов для карты и передайте 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 }); });
-
Создайте функцию для обновления цветов зданий, которые будут меняться в зависимости от выбранных цветов в палитрах, и передайте новые значения цвета в метод
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');
Настройка по условиям с помощью глобальных переменных
Вы можете раскрашивать объекты не только при клике, а по определённым условиям с помощью глобальных переменных стиля карты. Например, автоматически раскрашивать все здания выше пяти этажей в области видимости карты.
В этом примере здания раскрашиваются в зависимости от количества этажей: сначала выделяются и раскрашиваются здания с наибольшим количеством этажей в области видимости карты, затем раскрашиваются здания с количеством этажей меньше на один и так далее. После того как все здания в области видимости карты раскрашены, автоматически снимается выделение, начиная со зданий с наименьшим количеством этажей. Вы можете выбирать три цвета для раскраски зданий с помощью цветовых палитр: цвет стен, крыши и обводки (рёбер здания).
Пример использования:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>2GIS Map API</title>
<style>
html,
body,
#container {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="https://mapgl.2gis.com/api/js/v1"></script>
<div id="colors" style="position: absolute; top: 0; left: 0; display: flex; gap:15px; flex-direction: column; height: 100%; padding-top: 15px; padding-left: 15px;">
<rgba-color-picker id='wallDown' style="width: 150px; height: 150px;" color='{
"r": 143,
"g": 219,
"b": 126,
"a": 1
}'></rgba-color-picker>
<rgba-color-picker id='wallTop' style="width: 150px; height: 150px;" color='{
"r": 237,
"g": 255,
"b": 155,
"a": 1
}'></rgba-color-picker>
<rgba-color-picker id='strokeColor' style="width: 150px; height: 150px;" color='{
"r": 205,
"g": 250,
"b": 152,
"a": 0.9
}'></rgba-color-picker>
</div>
<script src="https://mapgl.2gis.com/api/js/v1"></script>
<script type="module">
import 'https://esm.sh/vanilla-colorful/rgba-color-picker';
</script>
<script>
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"]]]
};
// ID здания, которое будет раскрашено по умолчанию
let selectedIds = ["70030076552334291"];
const map = new mapgl.Map('container', {
center: [37.629589, 55.746067],
zoom: 17.2,
rotation: -40,
pitch: 45,
key: 'Your API access key',
});
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);
});
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);
});
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");
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);
</script>
</body>
</html>
Чтобы настроить раскрашивание объектов по условиям с помощью глобальных стилевых переменных:
-
Создайте слой с 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
— для настройки цвета зданий с определённым количеством этажей.
-
Передайте в метод 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); });
-
Чтобы настроить выделение зданий по клику, добавьте обработчик кликов для карты и передайте 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); });
-
Создайте функцию для обновления цветов зданий, которые будут меняться в зависимости от выбранных цветов в палитрах, и передайте новые значения цвета в метод
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');
-
Задайте условия для раскрашивания зданий в зависимости от количества этажей и передайте количество этажей в метод
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);