В MapLibre GL JS отображение домов (зданий) почти всегда опирается на
данные векторных тайлов, где объекты имеют свойства
building, height, min_height,
name и другие атрибуты. Основной способ ограничить
отображение домов — применение фильтров слоя.
Типичная конфигурация слоя зданий:
map.addLayer({
id: 'buildings',
source: 'composite',
'source-layer': 'building',
type: 'fill-extrusion',
minzoom: 14,
paint: {
'fill-extrusion-color': '#aaa',
'fill-extrusion-height': ['get', 'height'],
'fill-extrusion-base': ['get', 'min_height'],
'fill-extrusion-opacity': 0.8
},
filter: ['==', ['get', 'extrude'], 'true']
});
Ключевой механизм ограничения — выражение filter. Оно
определяет, какие здания попадут в визуализацию.
Примеры фильтрации:
// Только здания с заданной высотой
filter: ['>', ['get', 'height'], 10]
// Только жилые здания
filter: ['==', ['get', 'building'], 'residential']
// Исключение небольших построек
filter: ['>=', ['get', 'area'], 200]
Фильтрация выполняется на уровне рендера и не требует изменения источника данных.
Один из наиболее эффективных способов управления «плотностью» домов —
контроль через minzoom и maxzoom.
layout: {
visibility: 'visible'
},
minzoom: 15,
maxzoom: 18
Такой подход используется для снижения нагрузки на GPU и уменьшения визуального шума.
Практика показывает:
Иногда требуется ограничить отображение домов конкретной областью. В
MapLibre GL JS это достигается через фильтр координат с использованием
выражений within или логических условий.
Простейший подход — фильтрация по атрибутам или заранее размеченным полям:
filter: [
'all',
['>=', ['get', 'x_index'], 100],
['<=', ['get', 'x_index'], 200],
['>=', ['get', 'y_index'], 50],
['<=', ['get', 'y_index'], 120]
]
Если данные не содержат индексированных координат, используется геометрическая предобработка тайлов на сервере.
При работе с крупными городами критически важно ограничивать количество одновременно отрисовываемых объектов.
paint: {
'fill-extrusion-opacity': [
'interpolate',
['linear'],
['zoom'],
14, 0.3,
16, 0.8
]
}
Такое ограничение снижает визуальный перегруз при переходных зумах.
filter: [
'all',
['>=', ['get', 'height'], 5],
['!=', ['get', 'type'], 'shed']
]
Удаление малых объектов уменьшает количество геометрии и ускоряет отрисовку.
fill-extrusion позволяет задавать высоту зданий.
Ограничение часто вводится для предотвращения чрезмерных значений высоты
или некорректных данных.
'fill-extrusion-height': [
'min',
['get', 'height'],
120
]
Или более строгая нормализация:
'fill-extrusion-height': [
'case',
['>', ['get', 'height'], 200],
200,
['get', 'height']
]
Дополнительно можно ограничивать базовую высоту:
'fill-extrusion-base': [
'max',
['get', 'min_height'],
0
]
MapLibre GL JS поддерживает автоматическое отсечение геометрии по viewport, но при сложных сценах применяется дополнительное ограничение через маскирующие слои.
Пример использования слоя-маски:
map.addLayer({
id: 'clip-mask',
type: 'fill',
source: {
type: 'geojson',
data: polygon
},
paint: {
'fill-color': '#000',
'fill-opacity': 0
}
});
Далее здания могут фильтроваться через логические выражения, привязанные к геометрии источника.
Векторные тайлы часто содержат смешанные объекты: жилые дома, коммерческие здания, гаражи, склады.
filter: [
'match',
['get', 'building'],
['house', 'apartments', 'residential'],
true,
false
]
Более строгая классификация:
filter: [
'in',
['get', 'type'],
'residential',
'commercial'
]
Такой подход позволяет строить тематические карты плотности застройки.
MapLibre GL JS позволяет менять фильтры во время выполнения:
map.setFilter('buildings', [
'>=',
['get', 'height'],
20
]);
Это используется для интерактивных сценариев:
Смена фильтра мгновенно пересчитывает отрисовку слоя без перезагрузки тайлов.
Векторные тайлы часто содержат разные уровни детализации (LOD).
Ограничение можно реализовать через выбор source-layer.
source-layer: 'building_low'
или
source-layer: 'building_high'
Принцип:
Переключение между слоями позволяет контролировать нагрузку и качество визуализации.
При необходимости ограничить здания конкретным административным контуром применяется spatial clipping на уровне данных или через выражения:
filter: ['within', regionPolygon]
Если within недоступен в конкретной конфигурации,
применяется предобработка GeoJSON и генерация тайлов с обрезкой по
границе региона.
Ошибочные данные о высоте могут искажать карту. Для стабилизации визуализации используется нормализация:
'fill-extrusion-height': [
'step',
['get', 'height'],
0,
2, 2,
10, 10,
50, 50,
150, 150
]
Или ограничение диапазона:
[
'clamp',
['get', 'height'],
0,
100
]
При плотной застройке критически важны механизмы ограничения нагрузки:
Данные заранее редуцируются до минимально допустимого количества вершин.
minzoom: 15
Удаление неиспользуемых свойств уменьшает размер тайлов.
Некоторые источники объединяют мелкие здания в кластеры:
filter: ['>=', ['get', 'cluster_size'], 3]
layout: {
visibility: [
'case',
['>', ['zoom'], 14],
'visible',
'none'
]
}
Такой подход позволяет полностью исключать слой из рендеринга до достижения заданного масштаба, что снижает нагрузку на GPU и CPU.
Реальные сценарии часто требуют комплексных фильтров:
filter: [
'all',
['==', ['get', 'extrude'], 'true'],
['>=', ['get', 'height'], 10],
['<=', ['get', 'height'], 120],
['!=', ['get', 'building'], 'shed']
]
Такие конструкции позволяют точно управлять тем, какие здания попадают в визуализацию, сочетая геометрические, семантические и масштабные ограничения.