В MapLibre GL JS иконки и текстовые метки формируются через слой symbol, который объединяет два независимых, но часто используемых визуальных элемента: графические символы (icon) и подписи (text). Их совместное использование позволяет строить сложные картографические представления — от простых маркеров до насыщенных информационных слоёв с динамической стилизацией.
Symbol layer является центральным механизмом отображения иконок и текста. Он работает поверх векторных данных и использует свойства стиля для управления визуализацией каждого элемента.
Ключевые свойства:
icon-image — ссылка на изображение иконкиtext-field — текстовая подписьicon-size — масштаб иконкиtext-size — размер шрифтаicon-offset, text-offset — смещение
относительно геометрииicon-anchor, text-anchor — точка
привязкиПример базового слоя:
map.addLayer({
id: 'points',
type: 'symbol',
source: 'places',
layout: {
'icon-image': 'marker-15',
'text-field': ['get', 'name'],
'text-offset': [0, 1.2],
'text-anchor': 'top'
}
});
В этом примере иконка и подпись привязываются к координате точки и отображаются совместно.
MapLibre GL JS использует спрайты — наборы изображений, объединённых в один файл PNG или JSON-описание. Спрайты загружаются через стиль карты и становятся доступными как именованные ресурсы.
Структура подключения спрайта задаётся в стиле:
"sprite": "https://example.com/sprite"
После загрузки каждый элемент становится доступным по имени:
'icon-image': 'airport-15'
Спрайты оптимизируют производительность, уменьшая количество HTTP-запросов и ускоряя отрисовку.
Помимо спрайтов можно динамически добавлять изображения в стиль карты
через addImage.
map.loadImage('/icons/custom-marker.png', (error, image) => {
if (error) throw error;
map.addImage('custom-marker', image);
map.addLayer({
id: 'custom-points',
type: 'symbol',
source: 'points',
layout: {
'icon-image': 'custom-marker'
}
});
});
Этот механизм позволяет подгружать пользовательские иконки во время выполнения, что особенно важно для интерактивных приложений.
Signed Distance Field (SDF) иконки — это особый тип изображений, которые позволяют изменять цвет и прозрачность через стиль без необходимости иметь несколько версий одного изображения.
При добавлении изображения задаётся параметр:
map.addImage('pin-sdf', image, { sdf: true });
Далее можно управлять цветом:
'icon-color': '#ff0000',
'icon-halo-color': '#000000',
'icon-halo-width': 2
SDF-подход обеспечивает гибкость стилизации и снижает количество графических ресурсов.
Текстовые метки задаются через text-field. Это выражение
может ссылаться на свойства GeoJSON или использовать константные
значения.
'text-field': ['get', 'title']
Также поддерживаются составные выражения:
'text-field': ['concat', ['get', 'name'], ' — ', ['get', 'type']]
Типографика регулируется через:
text-fonttext-sizetext-letter-spacingtext-line-heightПри плотном расположении объектов возникает конфликт между метками. MapLibre GL JS использует систему приоритетов и правил размещения.
Основные параметры:
text-allow-overlapicon-allow-overlaptext-ignore-placementicon-ignore-placementlayout: {
'text-allow-overlap': false,
'icon-allow-overlap': false
}
Алгоритм размещения пытается минимизировать перекрытия, учитывая важность объектов и их размеры.
Позиционирование иконок и текста управляется системой якорей.
Определяет точку привязки иконки:
centertopbottomleftrighttop-left'icon-anchor': 'bottom'
Позволяет сместить иконку относительно координаты:
'icon-offset': [0, -10]
Это часто используется для размещения маркеров над точкой геометрии.
Иконки и текст могут изменять размер в зависимости от уровня масштаба карты.
'icon-size': [
'interpolate',
['linear'],
['zoom'],
5, 0.5,
10, 1,
15, 1.5
]
Такой подход позволяет адаптировать визуализацию под разные уровни детализации: от регионального обзора до уличного уровня.
MapLibre GL JS поддерживает мощную систему выражений (expressions), позволяющую менять иконки и текст динамически.
Пример выбора иконки по типу объекта:
'icon-image': [
'match',
['get', 'type'],
'restaurant', 'restaurant-15',
'hotel', 'lodging-15',
'default-marker'
]
Это позволяет строить универсальные слои без разделения на множество источников.
Отрисовка иконок и текста требует оптимизации, особенно при большом количестве объектов. Основные факторы влияния:
Рекомендуется ограничивать плотность отображения через:
minzoom / maxzoom'minzoom': 10,
'maxzoom': 18
Текстовые метки используют растровые или SDF-глифы, загружаемые через
glyphs в стиле карты.
"glyphs": "https://example.com/fonts/{fontstack}/{range}.pbf"
Font stack определяет набор шрифтов, используемых для рендеринга текста:
'text-font': ['Open Sans Regular', 'Arial Unicode MS Regular']
Поддержка Unicode позволяет отображать многоязычные подписи без дополнительных настроек.
Часто иконка и текст объединяются в единую композицию:
layout: {
'icon-image': 'poi-15',
'text-field': ['get', 'name'],
'text-offset': [0, 1],
'text-anchor': 'top',
'icon-text-fit': 'none'
}
В таких случаях важно учитывать порядок отрисовки и приоритет слоёв, чтобы текст не перекрывал важные элементы карты.
MapLibre GL JS позволяет изменять стиль слоя во время выполнения:
map.setLayoutProperty('points', 'icon-image', 'new-icon');
map.setPaintProperty('points', 'icon-opacity', 0.8);
Это используется для реактивных интерфейсов, где визуализация зависит от пользовательских действий или данных в реальном времени.
Иконки могут изменять внешний вид при взаимодействии:
map.on('click', 'points', (e) => {
map.setFeatureState(
{ source: 'points', id: e.features[0].id },
{ selected: true }
);
});
И в стиле:
'icon-opacity': [
'case',
['boolean', ['feature-state', 'selected'], false],
1,
0.5
]
Такой механизм позволяет создавать интерактивные карты без перерисовки всего слоя.
Символы в MapLibre GL JS подчиняются ряду ограничений WebGL-рендеринга:
Эти особенности требуют проектирования стиля с учётом масштаба данных и сценариев использования.