Стилизация текста

Текст в MapLibre GL JS отображается с помощью слоя типа symbol. Такой слой способен одновременно выводить иконки и текстовые подписи, либо только текст. Все параметры оформления подписей настраиваются через свойства layout и paint.

Базовый пример текстового слоя:

map.addLayer({
    id: 'cities-labels',
    type: 'symbol',
    source: 'cities',
    layout: {
        'text-field': ['get', 'name'],
        'text-size': 14
    }
});

В данном примере подпись берётся из свойства name каждого объекта источника данных.


Свойство text-field

Параметр text-field определяет содержимое подписи.

Текст может быть:

  • фиксированной строкой;
  • значением атрибута объекта;
  • результатом выражения;
  • комбинацией нескольких значений.

Статический текст

layout: {
    'text-field': 'Город'
}

Значение из GeoJSON

layout: {
    'text-field': ['get', 'name']
}

Для объекта:

{
    "name": "Москва"
}

будет отображена подпись:

Москва

Формирование строки

layout: {
    'text-field': [
        'concat',
        ['get', 'name'],
        ' (',
        ['get', 'population'],
        ')'
    ]
}

Результат:

Москва (13000000)

Размер текста

Размер задаётся через свойство text-size.

layout: {
    'text-size': 16
}

Чем больше значение, тем крупнее надпись.

Динамический размер

Размер можно изменять в зависимости от масштаба карты.

layout: {
    'text-size': [
        'interpolate',
        ['linear'],
        ['zoom'],
        5, 10,
        10, 16,
        15, 28
    ]
}

При увеличении масштаба подписи становятся крупнее.


Выбор шрифта

Свойство text-font задаёт набор шрифтов.

layout: {
    'text-font': ['Open Sans Regular']
}

Несколько вариантов:

layout: {
    'text-font': [
        'Open Sans Regular',
        'Arial Unicode MS Regular'
    ]
}

Если первый шрифт недоступен, используется следующий.


Цвет текста

Основной цвет задаётся через свойство text-color.

paint: {
    'text-color': '#1e88e5'
}

Пример красного текста:

paint: {
    'text-color': '#ff0000'
}

Использование RGBA:

paint: {
    'text-color': 'rgba(255,0,0,0.8)'
}

Прозрачность текста

Для управления прозрачностью применяется свойство text-opacity.

paint: {
    'text-opacity': 0.5
}

Диапазон значений:

0   — полностью прозрачный
1   — полностью непрозрачный

Контур текста

Контур значительно повышает читаемость подписей на сложном фоне.

Цвет контура

paint: {
    'text-halo-color': '#ffffff'
}

Толщина контура

paint: {
    'text-halo-width': 2
}

Размытие контура

paint: {
    'text-halo-blur': 1
}

Полный пример:

paint: {
    'text-color': '#000000',
    'text-halo-color': '#ffffff',
    'text-halo-width': 2,
    'text-halo-blur': 1
}

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


Выравнивание текста

Горизонтальное выравнивание

Свойство text-justify:

layout: {
    'text-justify': 'left'
}

Возможные значения:

left
center
right
auto

Якорная точка

Свойство text-anchor определяет положение текста относительно координаты объекта.

layout: {
    'text-anchor': 'center'
}

Поддерживаемые значения:

center
top
bottom
left
right
top-left
top-right
bottom-left
bottom-right

Пример:

layout: {
    'text-anchor': 'top'
}

Подпись будет расположена над объектом.


Смещение текста

Для более точного позиционирования используется text-offset.

layout: {
    'text-offset': [0, 1.5]
}

Первое значение отвечает за смещение по горизонтали, второе — по вертикали.

Например:

layout: {
    'text-anchor': 'top',
    'text-offset': [0, 0.8]
}

Подпись будет находиться немного выше точки.


Поворот текста

Угол поворота задаётся свойством text-rotate.

layout: {
    'text-rotate': 45
}

Значение указывается в градусах.

Пример вертикальной подписи:

layout: {
    'text-rotate': 90
}

Межбуквенный интервал

Свойство text-letter-spacing регулирует расстояние между символами.

layout: {
    'text-letter-spacing': 0.1
}

Для увеличенного интервала:

layout: {
    'text-letter-spacing': 0.3
}

Это особенно полезно для крупных заголовков на карте.


Высота строки

Для многострочных подписей применяется text-line-height.

layout: {
    'text-line-height': 1.5
}

Пример:

layout: {
    'text-field': 'Первая строка\nВторая строка',
    'text-line-height': 2
}

Максимальная ширина строки

Автоматический перенос текста регулируется через text-max-width.

layout: {
    'text-max-width': 8
}

Если строка длиннее указанного значения, MapLibre перенесёт текст на новую строку.


Преобразование регистра

Свойство text-transform изменяет регистр символов.

Верхний регистр

layout: {
    'text-transform': 'uppercase'
}

Результат:

МОСКВА

Нижний регистр

layout: {
    'text-transform': 'lowercase'
}

Результат:

москва

Ограничение отображения по масштабу

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

map.addLayer({
    id: 'cities-labels',
    type: 'symbol',
    source: 'cities',
    minzoom: 5,
    maxzoom: 15,
    layout: {
        'text-field': ['get', 'name']
    }
});

В этом случае подписи будут видны только между масштабами 5 и 15.


Динамическая стилизация через выражения

MapLibre позволяет изменять оформление текста на основе данных объекта.

Разный цвет

paint: {
    'text-color': [
        'case',
        ['>', ['get', 'population'], 1000000],
        '#d32f2f',
        '#1976d2'
    ]
}

Крупные города будут красными, остальные — синими.


Разный размер

layout: {
    'text-size': [
        'step',
        ['get', 'population'],
        12,
        100000,
        14,
        1000000,
        18
    ]
}

Размер подписи будет зависеть от численности населения.


Форматирование текста через expression format

Функция format позволяет оформлять разные части строки по-разному.

layout: {
    'text-field': [
        'format',
        ['get', 'name'],
        {
            'font-scale': 1.3
        },
        '\n',
        {},
        ['get', 'country'],
        {
            'font-scale': 0.8
        }
    ]
}

В результате:

Москва
Россия

Название города будет отображаться крупнее страны.


Отображение подписей вдоль линий

Для дорог, рек и маршрутов текст может следовать форме линии.

layout: {
    'symbol-placement': 'line',
    'text-field': ['get', 'name']
}

Источник данных должен содержать геометрию типа LineString.

Пример:

map.addLayer({
    id: 'roads-labels',
    type: 'symbol',
    source: 'roads',
    layout: {
        'symbol-placement': 'line',
        'text-field': ['get', 'name'],
        'text-size': 12
    }
});

Подпись будет изгибаться вместе с дорогой.


Предотвращение пересечения подписей

По умолчанию движок старается не отображать пересекающиеся надписи.

Свойство:

layout: {
    'text-allow-overlap': false
}

Это значение используется по умолчанию.

Для принудительного отображения:

layout: {
    'text-allow-overlap': true
}

Следует учитывать, что большое количество пересекающихся подписей ухудшает читаемость карты.


Игнорирование размещённых объектов

Иногда необходимо выводить текст независимо от уже размещённых подписей.

layout: {
    'text-ignore-placement': true
}

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


Приоритет размещения

Для управления порядком отображения используется symbol-sort-key.

layout: {
    'symbol-sort-key': ['get', 'priority']
}

Объекты с более высоким приоритетом получают больше шансов быть отображёнными при нехватке места.


Комплексный пример стилизации текста

map.addLayer({
    id: 'city-labels',
    type: 'symbol',
    source: 'cities',
    layout: {
        'text-field': ['get', 'name'],
        'text-font': [
            'Open Sans Regular',
            'Arial Unicode MS Regular'
        ],
        'text-size': [
            'interpolate',
            ['linear'],
            ['zoom'],
            5, 12,
            10, 18,
            15, 28
        ],
        'text-anchor': 'top',
        'text-offset': [0, 0.8],
        'text-letter-spacing': 0.05
    },
    paint: {
        'text-color': '#263238',
        'text-halo-color': '#ffffff',
        'text-halo-width': 2,
        'text-halo-blur': 1,
        'text-opacity': 0.95
    }
});

Такой набор настроек обеспечивает:

  • масштабируемый размер текста;
  • высокую читаемость на любом фоне;
  • аккуратное позиционирование относительно объекта;
  • поддержку нескольких шрифтов;
  • хорошую визуальную иерархию подписей на карте.