Миграция стилей

MapLibre GL JS использует стиль-спецификацию, совместимую с Mapbox Style Specification v8, однако при миграции важно учитывать не только формальную совместимость JSON-структуры, но и различия в экосистеме источников данных, лицензирования и поддерживаемых URL-эндпоинтов.

Стиль в MapLibre GL JS представляет собой JSON-документ, описывающий:

  • источники данных (sources)
  • слои (layers)
  • стилизацию (paint, layout)
  • ресурсы (glyphs, sprites)
  • переходы и выражения (expressions)

Ключевой принцип миграции — сохранение структуры стиля при замене инфраструктурных зависимостей, таких как тайловые серверы, шрифты и спрайты.


Проверка совместимости исходного стиля

Большинство стилей, созданных для Mapbox GL JS, формально совместимы с MapLibre GL JS, но требуют проверки следующих аспектов:

Источники данных (sources)

Типы источников:

  • vector
  • raster
  • geojson
  • raster-dem

Типичная проблема миграции — использование Mapbox-specific URL:

"source": {
  "type": "vector",
  "url": "mapbox://mapbox.mapbox-streets-v8"
}

После миграции требуется заменить на:

"source": {
  "type": "vector",
  "tiles": [
    "https://tiles.example.com/streets/{z}/{x}/{y}.pbf"
  ],
  "minzoom": 0,
  "maxzoom": 14
}

Важно: MapLibre не интерпретирует mapbox:// без внешнего резолвера.


Миграция URL источников данных

Наиболее критический этап — замена всех Mapbox-URL схем:

Было (Mapbox-формат)

  • mapbox://tileset.id
  • mapbox://sprites/username/styleid
  • mapbox://fonts/fontstack/range.pbf

Стало (универсальный формат)

  • HTTPS tile endpoints
  • локальные или self-hosted серверы
  • CDN с открытым доступом

Пример замены vector tiles:

"sources": {
  "cities": {
    "type": "vector",
    "tiles": [
      "https://tiles.myserver.org/cities/{z}/{x}/{y}.pbf"
    ]
  }
}

Миграция спрайтов (sprites)

Спрайты содержат иконки и графические элементы стиля.

Исходная конфигурация

"sprite": "mapbox://sprites/user/style"

После миграции

"sprite": "https://cdn.myserver.org/sprites/sprite"

MapLibre ожидает два файла:

  • .json
  • .png

Пример структуры:

sprite.png
sprite.json
sprite@2x.png
sprite@2x.json

Критически важно сохранить согласованность именования, так как механизм ретина-дисплеев зависит от суффикса @2x.


Миграция шрифтов (glyphs)

Шрифты — один из самых частых источников ошибок при переносе.

Mapbox-стиль

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

MapLibre-совместимый вариант

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

Особенности:

  • {fontstack} — список через запятую
  • {range} — диапазон Unicode-глифов
  • сервер должен отдавать .pbf файлы в формате PBF glyphs

При отсутствии корректного glyph endpoint текстовые слои отображаются пустыми.


Переписывание слоёв (layers)

Структура слоёв в MapLibre GL JS полностью соответствует спецификации Mapbox Style, однако важно учитывать нюансы выражений.

Пример слоя до миграции

{
  "id": "population",
  "type": "fill",
  "source": "cities",
  "paint": {
    "fill-color": "#ff0000",
    "fill-opacity": 0.6
  }
}

Этот слой переносится без изменений.


Проверка выражений (expressions)

MapLibre поддерживает выражения:

  • интерполяции
  • условные конструкции
  • арифметические операции
  • match / case

Пример:

"fill-color": [
  "interpolate",
  ["linear"],
  ["get", "population"],
  0, "#2DC4B2",
  1000000, "#FCA107",
  5000000, "#F7555D"
]

При миграции важно:

  • исключить нестандартные Mapbox extensions
  • проверить версии expression spec
  • избегать deprecated функций

Замена Mapbox-specific URL схем

Одним из ключевых этапов является устранение зависимостей от mapbox://.

Полный список замен:

Mapbox URI MapLibre-эквивалент
mapbox://tileset https://…/tiles/{z}/{x}/{y}.pbf
mapbox://sprites https://…/sprite
mapbox://fonts https://…/fonts/{fontstack}/{range}.pbf

Миграция raster и raster-dem источников

Raster tiles

"satellite": {
  "type": "raster",
  "tiles": [
    "https://tiles.server.org/satellite/{z}/{x}/{y}.jpg"
  ],
  "tileSize": 256
}

Terrain (DEM)

"terrain": {
  "source": "dem",
  "exaggeration": 1.5
}

DEM-источники требуют строго корректного формата RGB terrain tiles.


Проверка style JSON на валидность

Перед использованием в MapLibre GL JS рекомендуется проверять:

  • корректность JSON
  • отсутствие неизвестных свойств
  • наличие обязательных полей
  • соответствие Style Specification

Типичные ошибки:

  • отсутствующий sprite
  • некорректный glyphs endpoint
  • битые tile URL
  • несоответствие minzoom/maxzoom

Миграция источников GeoJSON

GeoJSON источники не требуют изменений формата:

"earthquakes": {
  "type": "geojson",
  "data": "https://data.server.org/earthquakes.json"
}

Однако важно учитывать:

  • CORS заголовки
  • размер данных
  • необходимость clustering при больших наборах

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

Некоторые стили используют расширения Mapbox, которые не поддерживаются напрямую:

  • light preset overrides
  • dataset-based styling
  • proprietary tokens

Такие конструкции требуют:

  • ручного удаления
  • замены на expressions
  • или переработки логики слоя

Интеграция стиля в MapLibre GL JS

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

import maplibregl from "maplibre-gl";

const map = new maplibregl.Map({
  container: "map",
  style: "https://styles.myserver.org/basic-style.json",
  center: [37.6173, 55.7558],
  zoom: 10
});

Важно учитывать:

  • задержку загрузки glyphs
  • доступность tile endpoints
  • корректность CORS политик

Типичные ошибки миграции и их причины

Пустая карта

Причины:

  • недоступен style JSON
  • отсутствуют tiles
  • некорректный sprite

Отсутствует текст

Причины:

  • неправильный glyphs URL
  • отсутствие шрифтов на сервере

Слои не отображаются

Причины:

  • неверный source name
  • mismatch vector tile schema
  • неправильный source-layer

Стратегия постепенной миграции

При больших стилях применяется поэтапный подход:

  1. замена tile endpoints
  2. перенос sprite
  3. перенос glyphs
  4. проверка layers
  5. тестирование expressions
  6. оптимизация производительности

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


Оптимизация после миграции

После перехода на MapLibre GL JS обычно требуется:

  • уменьшение количества источников
  • объединение слоёв
  • кэширование tiles
  • оптимизация sprite atlas
  • контроль minzoom/maxzoom

Особенно важна оптимизация vector tiles, так как именно они формируют основную нагрузку на рендерер.