Экструзия зданий — это механизм трёхмерного отображения объектов на
карте, при котором полигоны зданий визуально «поднимаются» над
поверхностью земли в соответствии с их высотой. В Mapbox GL JS данный
эффект реализуется через слой типа fill-extrusion, который
преобразует двухмерные геометрии в объёмные формы с управляемой высотой,
цветом и поведением при масштабировании.
Основой для экструзии служат векторные тайлы, содержащие слой зданий. Чаще всего используется набор данных, основанный на OpenStreetMap, преобразованный в формат векторных тайлов.
Типичный слой содержит следующие атрибуты:
height — фактическая высота зданияmin_height — базовый уровень (например, подиум или
подземные этажи)extrude — флаг, указывающий, можно ли визуализировать
здание в 3Dname — идентификатор объекта (опционально)При отсутствии height часто используется приближённое
значение, основанное на количестве этажей или типе здания.
Экструзия реализуется через добавление слоя с типом
fill-extrusion в стиль карты.
map.on('load', () => {
map.addLayer({
id: '3d-buildings',
source: 'composite',
'source-layer': 'building',
filter: ['==', 'extrude', 'true'],
type: 'fill-extrusion',
minzoom: 15,
paint: {
'fill-extrusion-color': '#aaa',
'fill-extrusion-height': ['get', 'height'],
'fill-extrusion-base': ['get', 'min_height'],
'fill-extrusion-opacity': 0.9
}
});
});
Ключевые элементы:
type: fill-extrusion — включает 3D-рендерингfill-extrusion-height — высота объектаfill-extrusion-base — базовая отметкаminzoom — ограничение видимости слояВысота зданий может задаваться напрямую или через выражения интерполяции. Это позволяет создавать более плавное появление 3D-эффекта при увеличении масштаба.
'fill-extrusion-height': [
'interpolate',
['linear'],
['zoom'],
15, 0,
15.05, ['get', 'height']
]
Такая конструкция делает здания «вырастающими» при приближении карты, что улучшает визуальную динамику сцены.
Свойство fill-extrusion-base определяет, с какой высоты
начинается построение объёма. Это особенно важно для зданий с подземной
частью или сложным рельефом.
'fill-extrusion-base': [
'case',
['has', 'min_height'],
['get', 'min_height'],
0
]
При отсутствии значения базовый уровень считается нулевым, и здание начинается от поверхности земли.
Визуальная выразительность экструзии определяется цветом, прозрачностью и иногда градиентами, зависящими от высоты.
'fill-extrusion-color': [
'interpolate',
['linear'],
['get', 'height'],
0, '#d9d9d9',
100, '#b3b3b3',
200, '#8c8c8c',
500, '#666666'
]
Дополнительные параметры:
fill-extrusion-opacity — прозрачность слояfill-extrusion-vertical-gradient — вертикальное
затемнение для объёмаДля корректного отображения трёхмерных зданий используется фильтрация объектов.
filter: [
'all',
['==', 'extrude', 'true'],
['!=', 'height', null]
]
Также применяется ограничение по масштабу:
Mapbox GL JS поддерживает глобальное освещение сцены через свойство
light в стиле карты. Оно влияет на тени и восприятие
объёма.
map.setLight({
anchor: 'viewport',
color: 'white',
intensity: 0.5
});
Параметры освещения:
anchor — привязка источника света (карта или
экран)color — цвет освещенияintensity — интенсивность светаКорректная настройка света критична для различимости высот зданий и создания объёмного эффекта.
Экструзия зданий часто комбинируется с:
line)fill)symbol)Порядок слоёв влияет на восприятие сцены: здания должны находиться выше плоских слоёв, но ниже символических меток.
3D-экструзия требует значительных ресурсов GPU. Оптимизация включает:
minzoompaint при большом
количестве объектовВекторные тайлы уже оптимизированы для WebGL, однако перегрузка стилями может снизить FPS при большом количестве зданий.
Свойства экструзии могут изменяться в реальном времени без перезагрузки карты:
map.setPaintProperty('3d-buildings', 'fill-extrusion-opacity', 0.6);
или
map.setPaintProperty(
'3d-buildings',
'fill-extrusion-color',
'#ffcc00'
);
Это позволяет адаптировать визуализацию под разные сценарии: ночной режим, тепловые карты, тематические слои.
Mapbox GL JS поддерживает выражения, позволяющие создавать зависимость высоты и цвета от зума:
'fill-extrusion-height': [
'interpolate',
['exponential', 1.5],
['zoom'],
14, 0,
16, ['get', 'height']
]
Такая модель позволяет управлять «ростом» городской застройки при приближении камеры.
При использовании данных из различных источников встречаются проблемы:
extrude флагаДля повышения качества визуализации применяется предварительная обработка данных или fallback-логика:
'fill-extrusion-height': [
'coalesce',
['get', 'height'],
10
]
Внутри Mapbox GL JS экструзия преобразует 2D-полигоны в набор треугольников, формирующих боковые грани и крышу. Процесс включает:
Этот процесс выполняется на GPU, что обеспечивает высокую производительность при большом количестве объектов.
Экструзия зданий тесно связана с параметрами камеры:
pitch — наклон карты (необходим для 3D-эффекта)bearing — поворот сценыzoom — масштабированиеТипичная конфигурация для 3D-сцены:
map.setPitch(60);
map.setBearing(-20);
Без наклона (pitch = 0) экструзия теряет объёмное
восприятие и выглядит как плоское смещение.
При переходе между уровнями zoom экструзия проходит несколько стадий:
Этот переход обычно сглаживается интерполяцией, чтобы избежать резких скачков геометрии.
source-layer для зданийminzoomfill-extrusion-base, приводящее к
«плавающим» зданиямpaint, ухудшающая
производительность