Стиль в MapLibre GL JS представляет собой JSON-документ, который полностью описывает внешний вид карты: используемые источники данных, набор слоёв, правила визуализации объектов, порядок отрисовки и параметры отображения.
Минимальная структура стиля выглядит следующим образом:
{
"version": 8,
"sources": {},
"layers": []
}
Основные компоненты:
Создание собственного стиля с нуля означает ручное описание всех элементов карты без использования готовых стилей вроде Streets, Bright или Positron.
Первым этапом формируется минимальный JSON-файл.
{
"version": 8,
"name": "Custom Style",
"sources": {},
"layers": []
}
Подключение такого стиля выполняется следующим образом:
const map = new maplibregl.Map({
container: 'map',
style: 'style.json',
center: [37.6176, 55.7558],
zoom: 10
});
После загрузки карта окажется пустой, поскольку отсутствуют источники данных и слои.
Практически любой стиль начинается со слоя фона.
{
"id": "background",
"type": "background",
"paint": {
"background-color": "#eef3f8"
}
}
Полный стиль:
{
"version": 8,
"sources": {},
"layers": [
{
"id": "background",
"type": "background",
"paint": {
"background-color": "#eef3f8"
}
}
]
}
Тип слоя background не требует источника данных и служит
для задания базового цвета всей карты.
Большинство современных карт строится на основе векторных тайлов.
Добавление источника:
{
"sources": {
"osm": {
"type": "vector",
"tiles": [
"https://example.com/tiles/{z}/{x}/{y}.pbf"
],
"minzoom": 0,
"maxzoom": 14
}
}
}
Параметры:
| Свойство | Назначение |
|---|---|
| type | Тип источника |
| tiles | URL-шаблон тайлов |
| minzoom | Минимальный масштаб |
| maxzoom | Максимальный масштаб |
После подключения источника данные всё ещё не отображаются. Для визуализации необходимы слои.
Предположим, что в тайлах присутствует слой water.
Слой отображения:
{
"id": "water",
"type": "fill",
"source": "osm",
"source-layer": "water",
"paint": {
"fill-color": "#a8d8ff"
}
}
Здесь:
fill используется для полигонов;source указывает источник данных;source-layer задаёт имя слоя внутри векторного
тайла.Если в данных присутствует слой landuse, можно создать
отдельную заливку.
{
"id": "land",
"type": "fill",
"source": "osm",
"source-layer": "landuse",
"paint": {
"fill-color": "#edf4e8"
}
}
Порядок слоёв крайне важен.
Например:
[
{
"id": "background"
},
{
"id": "land"
},
{
"id": "water"
}
]
Каждый следующий слой рисуется поверх предыдущего.
Для отображения дорог применяется тип line.
{
"id": "roads",
"type": "line",
"source": "osm",
"source-layer": "transportation",
"paint": {
"line-color": "#ffffff",
"line-width": 2
}
}
Более реалистичный вариант:
{
"id": "roads",
"type": "line",
"source": "osm",
"source-layer": "transportation",
"paint": {
"line-color": "#fefefe",
"line-width": [
"interpolate",
["linear"],
["zoom"],
5, 0.5,
10, 2,
15, 6
]
}
}
Толщина линии становится зависимой от масштаба.
Выражения являются фундаментом современных стилей MapLibre.
Пример изменения цвета дороги в зависимости от класса:
{
"line-color": [
"match",
["get", "class"],
"motorway", "#ff9f43",
"primary", "#feca57",
"secondary", "#ffdd59",
"#dcdde1"
]
}
Логика:
class.Нередко вместо одного слоя создаётся несколько.
Автомагистрали:
{
"id": "motorways",
"type": "line",
"source": "osm",
"source-layer": "transportation",
"filter": [
"==",
["get", "class"],
"motorway"
],
"paint": {
"line-color": "#ff8c42",
"line-width": 4
}
}
Второстепенные дороги:
{
"id": "secondary",
"type": "line",
"source": "osm",
"source-layer": "transportation",
"filter": [
"==",
["get", "class"],
"secondary"
],
"paint": {
"line-color": "#ffffff",
"line-width": 2
}
}
Такой подход обеспечивает максимальный контроль над оформлением.
Для отображения текста необходимо подключить шрифты.
В корне стиля:
{
"glyphs": "https://example.com/fonts/{fontstack}/{range}.pbf"
}
Затем создаётся слой подписей.
{
"id": "city-labels",
"type": "symbol",
"source": "osm",
"source-layer": "place",
"layout": {
"text-field": ["get", "name"],
"text-font": [
"Noto Sans Regular"
],
"text-size": 14
},
"paint": {
"text-color": "#333333"
}
}
Подпись автоматически берётся из атрибута name.
Размер текста обычно изменяется вместе с масштабом.
{
"text-size": [
"interpolate",
["linear"],
["zoom"],
5, 10,
10, 14,
15, 20
]
}
Результат:
| Zoom | Размер |
|---|---|
| 5 | 10 |
| 10 | 14 |
| 15 | 20 |
Между указанными значениями выполняется плавная интерполяция.
Для повышения читаемости используется ореол вокруг текста.
{
"paint": {
"text-color": "#2d3436",
"text-halo-color": "#ffffff",
"text-halo-width": 2
}
}
Подобный приём применяется практически во всех профессиональных картографических стилях.
Для использования пиктограмм необходим спрайт.
В корневой части стиля:
{
"sprite": "https://example.com/sprites/sprite"
}
Затем создаётся слой.
{
"id": "poi",
"type": "symbol",
"source": "osm",
"source-layer": "poi",
"layout": {
"icon-image": "restaurant"
}
}
Имя restaurant должно существовать внутри спрайта.
Фильтры позволяют выбирать только нужные объекты.
Например, отображение парков:
{
"filter": [
"==",
["get", "class"],
"park"
]
}
Несколько условий:
{
"filter": [
"all",
[
"==",
["get", "class"],
"park"
],
[
">",
["zoom"],
10
]
]
}
Слой будет виден только начиная с десятого масштаба.
Классическая техника заключается в рисовании дороги двумя слоями.
Подложка:
{
"id": "road-casing",
"type": "line",
"paint": {
"line-color": "#b2bec3",
"line-width": 8
}
}
Основная линия:
{
"id": "road-fill",
"type": "line",
"paint": {
"line-color": "#ffffff",
"line-width": 5
}
}
Получается эффект дорожного контура, характерный для большинства навигационных карт.
Для зданий применяется тип fill.
{
"id": "buildings",
"type": "fill",
"source": "osm",
"source-layer": "building",
"paint": {
"fill-color": "#dfe6e9",
"fill-outline-color": "#b2bec3"
}
}
Такое оформление хорошо подходит для светлых картографических тем.
MapLibre поддерживает экструзию полигонов.
{
"id": "3d-buildings",
"type": "fill-extrusion",
"source": "osm",
"source-layer": "building",
"paint": {
"fill-extrusion-color": "#c8d6e5",
"fill-extrusion-height": [
"get",
"height"
],
"fill-extrusion-base": 0,
"fill-extrusion-opacity": 0.9
}
}
Дополнительно задаётся наклон карты:
map.setPitch(60);
Для поддержания единого визуального стиля удобно заранее определить палитру.
Пример светлой темы:
| Элемент | Цвет |
|---|---|
| Фон | #eef3f8 |
| Вода | #a8d8ff |
| Парки | #c8e6c9 |
| Здания | #dfe6e9 |
| Дороги | #ffffff |
| Текст | #2d3436 |
Пример тёмной темы:
| Элемент | Цвет |
|---|---|
| Фон | #101418 |
| Вода | #243447 |
| Парки | #1e3d2f |
| Здания | #2f3640 |
| Дороги | #5f6770 |
| Текст | #ecf0f1 |
Наличие единой палитры значительно упрощает дальнейшее развитие стиля.
Каждый слой требует отдельной обработки при рендеринге.
Распространённые способы оптимизации:
Пример ограничения масштаба:
{
"minzoom": 12,
"maxzoom": 18
}
Слой будет отрисовываться только в указанном диапазоне.
При разработке крупных карт стиль часто разбивается на логические группы:
Подобная последовательность отражает фактический порядок визуального наложения объектов.
Пример структуры массива слоёв:
{
"layers": [
{ "id": "background" },
{ "id": "land" },
{ "id": "water" },
{ "id": "parks" },
{ "id": "railways" },
{ "id": "roads" },
{ "id": "buildings" },
{ "id": "boundaries" },
{ "id": "poi-icons" },
{ "id": "labels" }
]
}
{
"version": 8,
"name": "Custom Basic Style",
"glyphs": "https://example.com/fonts/{fontstack}/{range}.pbf",
"sources": {
"osm": {
"type": "vector",
"tiles": [
"https://example.com/tiles/{z}/{x}/{y}.pbf"
]
}
},
"layers": [
{
"id": "background",
"type": "background",
"paint": {
"background-color": "#eef3f8"
}
},
{
"id": "water",
"type": "fill",
"source": "osm",
"source-layer": "water",
"paint": {
"fill-color": "#a8d8ff"
}
},
{
"id": "roads",
"type": "line",
"source": "osm",
"source-layer": "transportation",
"paint": {
"line-color": "#ffffff",
"line-width": 2
}
},
{
"id": "buildings",
"type": "fill",
"source": "osm",
"source-layer": "building",
"paint": {
"fill-color": "#dfe6e9"
}
},
{
"id": "labels",
"type": "symbol",
"source": "osm",
"source-layer": "place",
"layout": {
"text-field": [
"get",
"name"
],
"text-font": [
"Noto Sans Regular"
],
"text-size": 14
},
"paint": {
"text-color": "#333333",
"text-halo-color": "#ffffff",
"text-halo-width": 2
}
}
]
}
Такой стиль формирует полноценную базовую карту и служит отправной точкой для дальнейшей разработки собственных картографических тем, специализированных визуализаций, навигационных схем, корпоративных карт и отраслевых геоинформационных приложений.