Landmarks в контексте веб-картографирования представляют собой объекты, которые пользователь воспринимает как ключевые ориентиры в пространстве: здания, достопримечательности, станции транспорта, природные объекты, точки интереса (POI). В Mapbox GL JS эти элементы реализуются через комбинацию слоёв (layers), источников данных (sources) и правил стилизации, обеспечивающих визуальную иерархию карты.
Основная задача landmarks — формирование когнитивной карты местности, где пользователь быстро считывает структуру окружения за счёт визуально выделенных объектов.
Векторные карты, используемые в Mapbox GL JS, разделяют landmarks на несколько категорий:
Представлены объектами GeoJSON или векторными тайлами:
Реализуются через symbol layer с иконками и текстом.
Используются реже, но важны для навигации:
Обычно визуализируются через line layer с акцентной
стилизацией.
Крупные объекты, задающие структуру города:
Реализуются через fill layer или
fill-extrusion layer.
Ключевой элемент современных карт:
Используется fill-extrusion слой с параметром
height.
Symbol layer объединяет иконки и текст:
map.addLayer({
id: 'landmarks-symbols',
type: 'symbol',
source: 'pois',
layout: {
'icon-image': ['get', 'icon'],
'text-field': ['get', 'name'],
'text-size': 12,
'text-offset': [0, 1.2],
'text-anchor': 'top'
}
});
Здесь ключевую роль играет привязка данных через get,
что позволяет динамически управлять отображением.
3D landmarks создают визуальную глубину карты:
map.addLayer({
id: '3d-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
}
});
Такая визуализация позволяет воспринимать город как объемную структуру, а не плоскую схему.
Часто используется пользовательский набор данных:
map.addSource('custom-landmarks', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [76.8865, 43.2389]
},
properties: {
name: 'Ориентир',
icon: 'star'
}
}
]
}
});
Коммерческая платформа Mapbox предоставляет предсобранные слои:
poi_labelbuildingroadwaterЭти слои оптимизированы для быстрого рендеринга и масштабирования.
Landmarks часто зависят от масштаба:
layout: {
'visibility': 'visible'
},
minzoom: 10,
maxzoom: 18
На низких масштабах отображаются только крупные ориентиры, на высоких — детализированные.
filter: ['==', ['get', 'type'], 'restaurant']
Позволяет отделять коммерческие, культурные и транспортные landmarks.
Одной из сложных задач является предотвращение наложения подписей и иконок.
layout: {
'icon-allow-overlap': false,
'text-allow-overlap': false
}
Mapbox GL JS автоматически перераспределяет элементы, чтобы сохранить читаемость карты.
Порядок добавления слоёв определяет визуальную иерархию:
map.addLayer(layer, 'poi-label');
map.on('click', 'landmarks-symbols', (e) => {
const feature = e.features[0];
console.log(feature.properties.name);
});
map.setPaintProperty('landmarks-symbols', 'icon-opacity', [
'case',
['==', ['get', 'id'], selectedId],
1,
0.5
]);
Landmarks напрямую влияют на нагрузку WebGL.
map.addSource('pois', {
type: 'geojson',
data: geojsonData,
cluster: true,
clusterMaxZoom: 14,
clusterRadius: 50
});
Landmarks должны формировать читаемую структуру:
В Mapbox GL JS это достигается комбинацией:
text-sizezoom interpolationfeature-statestyle layers orderFeature-state позволяет изменять объекты без перерисовки источника:
map.setFeatureState(
{ source: 'pois', id: 123 },
{ highlighted: true }
);
paint: {
'text-color': [
'case',
['boolean', ['feature-state', 'highlighted'], false],
'#ff0000',
'#000000'
]
}
Landmarks часто зависят от контекста:
В темных стилях повышается контраст POI, в светлых — усиливается читаемость текста.
Landmarks используются как опорные точки маршрутизации:
Интеграция с маршрутными слоями позволяет синхронизировать геометрию маршрута и POI.
Стилизация позволяет адаптировать карту под продукт:
Пример настройки цвета иконок:
paint: {
'icon-color': '#2b6cb0',
'text-halo-color': '#ffffff',
'text-halo-width': 1.2
}