Параметр exaggeration в MapLibre GL JS используется для вертикального масштабирования рельефа, отображаемого на основе цифровой модели высот (DEM — Digital Elevation Model). Он позволяет визуально усиливать или ослаблять перепады высот без изменения исходных данных.
При использовании трёхмерного рельефа карта может выглядеть слишком плоской, особенно на территориях с небольшими перепадами высот. Увеличение значения exaggeration делает горы выше, долины глубже и общий рельеф более выразительным.
Настройка выполняется через источник типа raster-dem и
объект terrain.
Базовая конфигурация выглядит следующим образом:
map.addSource('dem', {
type: 'raster-dem',
url: 'https://example.com/dem.json',
tileSize: 512
});
map.setTerrain({
source: 'dem',
exaggeration: 1
});
Значение 1 означает отображение рельефа без
изменений.
MapLibre GL JS получает данные высот из DEM-тайлов. Для каждой точки известна абсолютная высота над уровнем моря. Перед визуализацией движок умножает каждое значение высоты на коэффициент exaggeration.
Условно процесс выглядит следующим образом:
Итоговая высота = Исходная высота × exaggeration
Если исходная вершина имеет высоту 1500 метров:
| Exaggeration | Отображаемая высота |
|---|---|
| 0.5 | 750 м |
| 1 | 1500 м |
| 2 | 3000 м |
| 3 | 4500 м |
Физические координаты объектов не изменяются. Изменяется только визуальное представление поверхности.
Наиболее распространённым считается значение:
exaggeration: 1
Такой режим обеспечивает максимально реалистичное отображение рельефа.
Пример:
map.setTerrain({
source: 'dem',
exaggeration: 1
});
Подходит для:
Коэффициент может быть меньше единицы.
Пример:
map.setTerrain({
source: 'dem',
exaggeration: 0.5
});
Результат:
Такой подход полезен, если:
Иногда используются ещё меньшие значения:
exaggeration: 0.25
или
exaggeration: 0.1
Карта приобретает почти плоский вид.
Значение 0 фактически обнуляет все высоты.
map.setTerrain({
source: 'dem',
exaggeration: 0
});
В этом режиме:
Для полного отключения terrain обычно используется:
map.setTerrain(null);
Однако значение 0 удобно применять для плавной анимации
включения рельефа.
Наиболее интересным является увеличение коэффициента выше единицы.
Пример:
map.setTerrain({
source: 'dem',
exaggeration: 2
});
Высоты визуально удваиваются.
Эффект особенно заметен:
Например, Альпы или Гималаи становятся значительно более выразительными при обзоре под углом.
Допускаются и большие значения.
map.setTerrain({
source: 'dem',
exaggeration: 5
});
или
map.setTerrain({
source: 'dem',
exaggeration: 10
});
Подобные коэффициенты используются преимущественно для:
При больших значениях карта становится менее реалистичной.
Например:
exaggeration: 20
может превратить умеренные холмы в практически вертикальные стены.
Exaggeration воздействует на все элементы, зависящие от поверхности terrain.
При увеличении коэффициента изменяются:
Пример:
map.setTerrain({
source: 'dem',
exaggeration: 3
});
Высотные здания могут визуально казаться ниже окружающих гор, поскольку поверхность земли становится значительно выше.
Эффект exaggeration особенно заметен при наклоне карты.
Небольшой наклон:
map.easeTo({
pitch: 20
});
Средний наклон:
map.easeTo({
pitch: 45
});
Максимально выраженный эффект:
map.easeTo({
pitch: 70
});
Чем больше угол обзора, тем сильнее воспринимается увеличение рельефа.
Комбинация:
pitch: 70
exaggeration: 2
обычно выглядит значительно эффектнее, чем:
pitch: 0
exaggeration: 2
Коэффициент может изменяться во время работы приложения.
Пример:
map.setTerrain({
source: 'dem',
exaggeration: 1
});
button.addEventListener('click', () => {
map.setTerrain({
source: 'dem',
exaggeration: 2
});
});
После вызова setTerrain() карта автоматически перестроит
поверхность.
Часто пользователю предоставляется выбор между несколькими режимами.
const levels = {
flat: 0,
normal: 1,
enhanced: 2,
dramatic: 4
};
function setRelief(level) {
map.setTerrain({
source: 'dem',
exaggeration: levels[level]
});
}
Использование:
setRelief('normal');
setRelief('enhanced');
setRelief('dramatic');
Такой подход распространён в туристических и геоинформационных системах.
MapLibre GL JS позволяет создавать плавные визуальные эффекты путём последовательного изменения коэффициента.
Простейший пример:
let exaggeration = 0;
const interval = setInterval(() => {
exaggeration += 0.1;
map.setTerrain({
source: 'dem',
exaggeration
});
if (exaggeration >= 2) {
clearInterval(interval);
}
}, 50);
Результат:
Подобный эффект часто используется в презентациях геоданных.
Интерактивное управление обычно реализуется через элемент range.
HTML:
<input
id="terrain-slider"
type="range"
min="0"
max="5"
step="0.1"
value="1">
Jav * aScript:
const slider = document.getElementById('terrain-slider');
slider.addEventListener('input', (event) => {
map.setTerrain({
source: 'dem',
exaggeration: Number(event.target.value)
});
});
Пользователь получает возможность мгновенно оценивать влияние различных коэффициентов.
Иногда требуется усиливать рельеф только при определённом приближении.
Пример:
map.on('zoom', () => {
const zoom = map.getZoom();
let exaggeration = 1;
if (zoom > 10) {
exaggeration = 2;
}
map.setTerrain({
source: 'dem',
exaggeration
});
});
Логика может быть более сложной:
if (zoom < 6) {
exaggeration = 0.5;
}
else if (zoom < 10) {
exaggeration = 1;
}
else if (zoom < 14) {
exaggeration = 2;
}
else {
exaggeration = 3;
}
Такой подход помогает улучшить восприятие местности на разных уровнях масштабирования.
Практика показывает следующие диапазоны:
| Значение | Назначение |
|---|---|
| 0 | Полностью плоская поверхность |
| 0.25–0.75 | Слабый рельеф |
| 1 | Реалистичное отображение |
| 1.5–2 | Умеренное усиление |
| 2–4 | Ярко выраженный рельеф |
| 5+ | Демонстрационный режим |
Для большинства приложений подходят значения:
exaggeration: 1.2
или
exaggeration: 1.5
Они делают карту более выразительной без существенной потери реалистичности.
Сам по себе параметр exaggeration практически не влияет на производительность.
Основная нагрузка связана с:
Следующие варианты имеют близкую стоимость:
exaggeration: 1
exaggeration: 2
exaggeration: 5
Поэтому выбор коэффициента обычно определяется исключительно визуальными требованиями.
exaggeration: 15
или
exaggeration: 20
Часто приводит к неестественному отображению поверхности.
Некорректный код:
map.setTerrain({
source: 'dem',
exaggeration: 2
});
если источник ещё не зарегистрирован.
Правильный порядок:
map.addSource('dem', {
type: 'raster-dem',
url: 'https://example.com/dem.json'
});
map.setTerrain({
source: 'dem',
exaggeration: 2
});
Некорректный пример:
exaggeration: -1
Отрицательные коэффициенты не имеют практического смысла и могут привести к непредсказуемому поведению визуализации.
Неэффективный подход:
map.on('mousemove', () => {
map.setTerrain({
source: 'dem',
exaggeration: Math.random()
});
});
Постоянная перестройка рельефа способна создавать лишнюю нагрузку на систему.
Предпочтительно использовать:
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json',
center: [7.5, 46.5],
zoom: 10,
pitch: 60
});
map.on('load', () => {
map.addSource('dem', {
type: 'raster-dem',
url: 'https://example.com/dem.json',
tileSize: 512
});
map.setTerrain({
source: 'dem',
exaggeration: 1.8
});
map.easeTo({
pitch: 70,
duration: 3000
});
});
В результате формируется выразительная трёхмерная сцена с усиленным рельефом, хорошо демонстрирующая возможности цифровой модели высот и механизма terrain в MapLibre GL JS.