Fill-extrusion

Визуальный слой типа extrusion в Mapbox GL JS используется для преобразования плоских полигонов в трёхмерные объекты. Этот подход применяется для отображения зданий, территорий, зон плотности, геологических структур и любых других данных, где важна высота или объём.

Слой реализуется через тип fill-extrusion, который работает только с полигональными геометриями и опирается на числовые атрибуты высоты и базового уровня.


Базовая структура слоя extrusion

Слой добавляется через конфигурацию addLayer, где ключевым параметром является type: "fill-extrusion".

map.addLayer({
  id: "buildings-3d",
  type: "fill-extrusion",
  source: "buildings",
  "source-layer": "building",
  paint: {
    "fill-extrusion-color": "#aaa",
    "fill-extrusion-height": 30,
    "fill-extrusion-base": 0,
    "fill-extrusion-opacity": 0.8
  }
});

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


Источники данных для extrusion

Поддерживаются два основных типа источников:

GeoJSON

map.addSource("zones", {
  type: "geojson",
  data: {
    type: "FeatureCollection",
    features: [
      {
        type: "Feature",
        geometry: {
          type: "Polygon",
          coordinates: [
            [
              [30, 50],
              [30.01, 50],
              [30.01, 50.01],
              [30, 50.01],
              [30, 50]
            ]
          ]
        },
        properties: {
          height: 100
        }
      }
    ]
  }
});

Vector tiles

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

map.addSource("composite", {
  type: "vector",
  url: "mapbox://mapbox.3d-buildings"
});

Управление высотой: fill-extrusion-height

Параметр fill-extrusion-height задаёт итоговую высоту объекта. Значение может быть:

  • числом
  • свойством объекта
  • выражением (data-driven styling)
"fill-extrusion-height": ["get", "height"]

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


Базовый уровень: fill-extrusion-base

Параметр fill-extrusion-base задаёт нижнюю границу экструдированного объекта. Он позволяет создавать многоуровневые структуры и учитывать здания на подиумах или перепадах рельефа.

"fill-extrusion-base": ["get", "min_height"]

При комбинации base и height формируется полноценный объём:

  • нижняя граница: base
  • верхняя граница: height

Цвет и визуальная дифференциация

Параметр fill-extrusion-color поддерживает статические значения и выражения.

"fill-extrusion-color": [
  "interpolate",
  ["linear"],
  ["get", "height"],
  0, "#2c7bb6",
  50, "#abd9e9",
  100, "#fdae61",
  200, "#d7191c"
]

Такой подход позволяет визуально кодировать высоту, плотность или функциональное назначение объектов.


Прозрачность и визуальная глубина

Параметр fill-extrusion-opacity регулирует прозрачность слоя.

"fill-extrusion-opacity": 0.6

Значения ниже 1.0 позволяют:

  • видеть перекрывающиеся объекты
  • сохранять читаемость карты
  • создавать эффекты наложения слоёв

Условное отображение по масштабу

Extrusion-слои часто включаются только при определённом уровне увеличения карты.

"minzoom": 14

Это важно для производительности, поскольку 3D-рендеринг значительно дороже 2D-отображения.


Динамические выражения и data-driven styling

Mapbox GL JS активно использует выражения для управления визуализацией.

Высота на основе атрибутов

"fill-extrusion-height": [
  "*",
  ["get", "levels"],
  3
]

Условные цвета

"fill-extrusion-color": [
  "case",
  [">", ["get", "height"], 100],
  "#ff0000",
  "#00ff00"
]

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

"fill-extrusion-height": [
  "interpolate",
  ["linear"],
  ["zoom"],
  10, 0,
  15, 100,
  20, 300
]

Такой подход позволяет создавать адаптивные 3D-сцены, меняющиеся при масштабировании.


Работа с освещением и восприятием глубины

Mapbox GL JS использует глобальные параметры света, влияющие на extrusion:

map.setLight({
  anchor: "map",
  color: "white",
  intensity: 0.6
});

Освещение влияет на:

  • тени зданий
  • визуальную глубину
  • читаемость плотных районов

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

Работа с fill-extrusion требует учёта ограничений WebGL.

Основные принципы оптимизации:

1. Использование векторных тайлов вместо GeoJSON GeoJSON подходит для малых наборов данных, но не масштабируется.

2. Ограничение zoom-диапазона

minzoom: 14,
maxzoom: 20

3. Упрощение геометрии Сложные полигоны увеличивают нагрузку на GPU.

4. Минимизация выражений Сложные цепочки interpolation и case влияют на производительность.


Комбинирование с другими слоями

Extrusion часто используется вместе с:

  • background для контраста сцены
  • line для границ кварталов
  • symbol для подписей зданий
  • fill для базовых зон

Порядок слоёв критически важен, так как extrusion перекрывает 2D-слои.


Типичные ошибки при работе с extrusion

Отсутствие base при наличии height Приводит к визуальным артефактам при рельефных данных.

Использование слишком больших значений высоты Нарушает масштаб сцены и перспективу.

Применение GeoJSON для больших городов Резко снижает FPS и приводит к лагам.

Отсутствие minzoom 3D-слой перегружает карту на низких масштабах.


Данные о зданиях и стандартные источники

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

  • footprint (контур здания)
  • height (высота)
  • min_height (основание)

Эти данные позволяют строить реалистичные 3D-модели городской среды без дополнительной обработки геометрии на стороне клиента.


Поведение при наклоне карты

Extrusion раскрывается полностью только при использовании pitch и bearing:

map.setPitch(60);
map.setBearing(-20);

Без наклона карта остаётся в псевдо-3D режиме, где эффект высоты минимален.


Использование фильтров

Фильтры позволяют ограничивать отображение объектов:

"filter": ["==", ["get", "type"], "residential"]

или по диапазону высот:

"filter": [">", ["get", "height"], 50]

Это полезно для тематической визуализации городской застройки.


Поведение при зуме и адаптивная детализация

Extrusion-слои могут менять поведение в зависимости от масштаба:

  • на малых zoom: отключение 3D
  • на средних: упрощённые формы
  • на высоких: детализированная геометрия
"fill-extrusion-height": [
  "interpolate",
  ["exponential", 1.5],
  ["zoom"],
  14, 0,
  16, ["get", "height"]
]

Геометрические ограничения и WebGL особенности

В основе rendering лежит WebGL, поэтому:

  • каждая грань здания — отдельные треугольники
  • высота преобразуется в вертикальные стенки
  • верхняя поверхность строится отдельно

Большое количество вершин увеличивает нагрузку на GPU, что особенно заметно при плотной застройке.


Практика работы с городскими сценами

При построении 3D-карты города обычно комбинируются:

  • базовый слой земли
  • дороги
  • вода
  • здания extrusion
  • POI-метки

Такая композиция формирует многослойную сцену, где extrusion отвечает за вертикальную структуру среды.