Проблемы со стилями

Стили в MapLibre GL JS определяют практически всё визуальное представление карты: источники данных, слои, цвета, подписи, иконки, правила отображения объектов и порядок их отрисовки. Любая ошибка в конфигурации стиля способна привести к частичной или полной неработоспособности карты.

Наиболее распространённые проблемы связаны со следующими факторами:

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

Ошибки загрузки файла стиля

Карта не может отображаться без корректно загруженного Style Specification.

Пример подключения:

const map = new maplibregl.Map({
    container: 'map',
    style: 'style.json'
});

Если путь указан неверно:

style: 'styles/style.json'

а файл фактически отсутствует, в консоли браузера появятся ошибки вида:

404 Not Found
Failed to load style

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

Типичные причины:

  • неправильный относительный путь;
  • ошибка в имени файла;
  • отсутствие доступа к серверу;
  • запрет со стороны CORS.

Некорректный JSON

Стиль представляет собой JSON-документ. Даже одна пропущенная запятая делает файл невалидным.

Ошибочный пример:

{
  "version": 8
  "sources": {}
}

Корректный вариант:

{
  "version": 8,
  "sources": {}
}

Сообщения об ошибках обычно выглядят так:

Unexpected token
JSON Parse Error

Для проверки рекомендуется использовать JSON-валидаторы или встроенные инструменты IDE.


Неверная версия спецификации

MapLibre GL JS ориентируется на стиль версии 8.

Корректный вариант:

{
  "version": 8
}

Некоторые стили, экспортированные из сторонних редакторов, могут содержать другую версию:

{
  "version": 7
}

или

{
  "version": 9
}

Это способно привести к ошибкам интерпретации стиля или игнорированию отдельных параметров.


Отсутствующие источники данных

Каждый слой обязан ссылаться на существующий источник.

Корректная конфигурация:

{
  "sources": {
    "roads": {
      "type": "vector",
      "url": "mbtiles://roads"
    }
  }
}
{
  "id": "road-layer",
  "source": "roads"
}

Ошибка возникает при ссылке на несуществующий источник:

{
  "id": "road-layer",
  "source": "main-roads"
}

При этом слой не будет отображаться.

Часто встречается сообщение:

Source "main-roads" not found

Проблемы с векторными тайлами

Даже при существующем источнике данные могут не отображаться из-за неправильного имени слоя внутри набора тайлов.

Пример:

{
  "source-layer": "roads"
}

Если в наборе тайлов слой называется:

transportation

то объекты не появятся на карте.

Для диагностики используются:

  • TileServer Inspector;
  • MapLibre Inspect;
  • инструменты анализа MBTiles;
  • просмотр метаданных tileset.

Ошибки в порядке слоёв

MapLibre рисует слои сверху вниз.

Пример:

map.addLayer(buildingsLayer);
map.addLayer(roadsLayer);

В этом случае дороги окажутся поверх зданий.

Если требуется обратный результат:

map.addLayer(roadsLayer);
map.addLayer(buildingsLayer);

Неправильный порядок может создавать впечатление, что слой отсутствует, хотя он просто перекрыт другим слоем.


Полностью прозрачные объекты

Иногда слой присутствует, но его прозрачность делает объекты невидимыми.

Пример:

{
  "paint": {
    "fill-opacity": 0
  }
}

Или:

{
  "paint": {
    "line-opacity": 0
  }
}

Для проверки полезно временно установить:

{
  "paint": {
    "fill-opacity": 1
  }
}

Совпадение цветов

Слой может сливаться с фоном.

Пример:

{
  "background-color": "#ffffff"
}

и

{
  "fill-color": "#ffffff"
}

Полигон фактически существует, но визуально незаметен.

Для диагностики рекомендуется использовать контрастные цвета:

{
  "fill-color": "#ff0000"
}

Ошибки выражений (Expressions)

MapLibre активно использует выражения для динамической стилизации.

Корректный пример:

[
  "get",
  "name"
]

Ошибка:

[
  "gett",
  "name"
]

Консоль может вывести:

Unknown expression "gett"

Другой распространённый случай — неверные типы данных:

[
  ">",
  ["get", "population"],
  "1000"
]

Сравнивается число и строка, что приводит к неожиданным результатам.

Правильнее:

[
  ">",
  ["get", "population"],
  1000
]

Ошибки фильтрации

Фильтры определяют, какие объекты отображаются.

Пример:

[
  "==",
  ["get", "class"],
  "motorway"
]

Если атрибут имеет значение:

highway

то слой останется пустым.

Для поиска причины необходимо проверить реальные свойства объектов.


Проблемы со шрифтами

Подписи зависят от настроек glyphs.

Пример:

{
  "glyphs": "https://server/fonts/{fontstack}/{range}.pbf"
}

Если ресурс недоступен:

404 glyphs

или

Failed to load glyphs

то текстовые подписи перестают отображаться.

Особенно часто это происходит после переноса проекта на другой сервер.


Проблемы со спрайтами

Спрайт содержит набор иконок для символов.

Настройка:

{
  "sprite": "https://server/sprites/sprite"
}

MapLibre автоматически пытается загрузить:

sprite.json
sprite.png

Если хотя бы один файл отсутствует:

Failed to load sprite

Символьные слои становятся пустыми.


Неверные имена иконок

Даже при корректной загрузке спрайта возможны ошибки.

Например:

{
  "layout": {
    "icon-image": "bus-stop"
  }
}

Если в спрайте присутствует:

bus_stop

иконка отображаться не будет.

Важно соблюдать точное совпадение имени.


Конфликты после динамического изменения стиля

Во время работы приложения стиль может обновляться:

map.setStyle('dark.json');

После вызова:

map.setStyle(...)

происходит полная перезагрузка стиля.

Слои, добавленные программно:

map.addLayer(...)

будут удалены.

Поэтому после загрузки нового стиля необходимо повторно создавать:

  • пользовательские источники;
  • пользовательские слои;
  • обработчики событий, завязанные на них.

Обычно используется событие:

map.on('style.load', () => {
    // восстановление слоёв
});

Ошибки при работе с собственными слоями

Иногда приложение пытается изменить слой раньше его создания.

Ошибка:

map.setPaintProperty(
    'roads',
    'line-color',
    '#ff0000'
);

если слой ещё отсутствует.

Консоль покажет:

Layer "roads" does not exist

Перед изменением желательно проверять наличие слоя:

if (map.getLayer('roads')) {
    map.setPaintProperty(
        'roads',
        'line-color',
        '#ff0000'
    );
}

Проблемы асинхронной загрузки

Многие ошибки связаны с тем, что карта ещё не успела загрузить стиль.

Неверный вариант:

const map = new maplibregl.Map({...});

map.addLayer(layer);

Правильный подход:

map.on('load', () => {
    map.addLayer(layer);
});

Либо:

map.on('style.load', () => {
    map.addLayer(layer);
});

Использование неподдерживаемых свойств

Некоторые стили создаются для других движков и содержат свойства, отсутствующие в MapLibre GL JS.

Например:

{
  "paint": {
    "unknown-property": true
  }
}

Такие параметры игнорируются либо вызывают предупреждения.

При миграции проектов рекомендуется сверяться со спецификацией MapLibre Style Specification.


Проблемы совместимости со стилями Mapbox

Частая ситуация возникает при использовании стилей, созданных для экосистемы Mapbox.

Возможные сложности:

  • ссылки на закрытые сервисы Mapbox;
  • зависимость от Mapbox Glyphs API;
  • использование проприетарных ресурсов;
  • нестандартные расширения стиля.

Пример:

{
  "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf"
}

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


Диагностика через события ошибок

MapLibre предоставляет механизм отслеживания ошибок.

Общий обработчик:

map.on('error', (event) => {
    console.error(event.error);
});

Отладка загрузки источников:

map.on('sourcedata', (event) => {
    console.log(event);
});

Контроль состояния карты:

map.on('styledata', (event) => {
    console.log(event);
});

Подобные обработчики помогают быстро определить момент возникновения проблемы.


Использование инструментов разработчика браузера

Большая часть ошибок стилей выявляется средствами браузера.

Особое внимание уделяется:

Console

Позволяет увидеть:

  • ошибки JSON;
  • проблемы выражений;
  • отсутствующие слои;
  • ошибки загрузки ресурсов.

Network

Позволяет проверить:

  • статус загрузки стиля;
  • тайлы;
  • шрифты;
  • спрайты;
  • изображения.

Sources

Упрощает анализ загруженных файлов и проверку содержимого стиля.


Методика поиска неисправностей

Практический алгоритм диагностики проблем со стилями обычно выглядит следующим образом:

  1. Проверить отсутствие ошибок в консоли.
  2. Убедиться в успешной загрузке style.json.
  3. Проверить доступность всех источников данных.
  4. Проверить загрузку спрайтов.
  5. Проверить загрузку шрифтов.
  6. Убедиться в существовании source-layer.
  7. Проверить фильтры слоя.
  8. Проверить прозрачность объектов.
  9. Проверить порядок отображения слоёв.
  10. Проверить совместимость используемых свойств.
  11. Проанализировать события error, styledata и sourcedata.
  12. Выполнить тест с упрощённым стилем, постепенно возвращая отключённые элементы.

Такой поэтапный подход позволяет локализовать большинство проблем со стилями в MapLibre GL JS независимо от сложности проекта и количества используемых слоёв.