API совместимость

MapLibre GL JS изначально проектировалась как форк Mapbox GL JS до версии 1.x, что определило ключевую особенность её API — высокий уровень совместимости с оригинальной спецификацией Mapbox GL JS. Эта совместимость стала фундаментом для миграции существующих проектов и одновременно источником ограничений, связанных с сохранением обратной совместимости и постепенной эволюцией архитектуры.

Архитектурная основа совместимости

Основная идея совместимости заключается в том, что MapLibre GL JS реализует тот же публичный API-интерфейс, что и Mapbox GL JS v1.x:

  • класс Map
  • система sources и layers
  • стиль JSON в формате Mapbox Style Specification
  • события карты (load, click, mousemove и др.)
  • выражения (expressions) в стиле Mapbox

Эта модель позволяет рассматривать MapLibre GL JS как замену «drop-in replacement» в большинстве проектов, где ранее использовался Mapbox GL JS до изменения лицензии.

Ключевая особенность архитектуры — разделение между:

  • движком рендеринга WebGL
  • описанием данных через стиль (style spec)
  • публичным API управления картой

Такое разделение позволило сохранить стабильность интерфейсов при изменениях внутренней реализации.


Совместимость с Mapbox Style Specification

Одним из самых устойчивых элементов совместимости является поддержка спецификации стилей.

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

{
  "version": 8,
  "sources": { ... },
  "layers": [ ... ],
  "glyphs": "...",
  "sprite": "..."
}

Поддерживаемые элементы:

  • источники данных (vector, raster, geojson, image, video)
  • слои (fill, line, symbol, circle, heatmap, fill-extrusion, raster, hillshade)
  • фильтры (==, !=, >, <, in, all, any)
  • выражения (expressions)

Совместимость на уровне стиля означает, что большинство карт, созданных под Mapbox, могут быть загружены без изменений:

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

Однако существуют нюансы:

  • некоторые расширения Mapbox (proprietary sources) не поддерживаются
  • часть новых expression-функций может отличаться по поведению
  • различия в обработке sprite/glyph URL

Совместимость классов API

Класс Map

Основной класс Map является центральной точкой API и сохраняет структуру:

const map = new maplibregl.Map({
  container: 'map',
  style: 'style.json',
  center: [0, 0],
  zoom: 2
});

Поддерживаются ключевые параметры:

  • container
  • style
  • center
  • zoom
  • bearing
  • pitch
  • hash
  • interactive
  • attributionControl

Изменения по сравнению с Mapbox GL JS v1:

  • удалены зависимости от access token
  • упрощена инициализация источников тайлов
  • более строгая работа с CORS при загрузке ресурсов

Совместимость источников данных (Sources)

Система источников данных является одним из наиболее стабильных компонентов API.

Поддерживаемые типы:

vector source

map.addSource('tiles', {
  type: 'vector',
  tiles: ['https://example.com/{z}/{x}/{y}.pbf']
});

geojson source

map.addSource('points', {
  type: 'geojson',
  data: {
    type: 'FeatureCollection',
    features: []
  }
});

raster source

map.addSource('raster', {
  type: 'raster',
  tiles: ['https://example.com/tiles/{z}/{x}/{y}.png'],
  tileSize: 256
});

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

  • API setData() для GeoJSON полностью совместим
  • обновление источников через setData работает без изменений
  • поведение тайлового кеша может отличаться в производительности

Совместимость слоёв (Layers)

Слои остаются ключевой частью API и полностью соответствуют модели Mapbox GL JS v1.

Добавление слоя:

map.addLayer({
  id: 'cities',
  type: 'circle',
  source: 'points',
  paint: {
    'circle-radius': 6,
    'circle-color': '#ff0000'
  }
});

Типы слоёв:

  • fill
  • line
  • circle
  • symbol
  • raster
  • heatmap
  • fill-extrusion
  • hillshade

Совместимость поведения:

  • порядок слоёв сохраняется строго по порядку добавления
  • minzoom и maxzoom работают идентично
  • фильтры поддерживаются полностью

Отличия:

  • некоторые edge-case поведения для blending режимов могут отличаться
  • производительность рендеринга может варьироваться в зависимости от WebGL контекста

Совместимость событийной модели

Событийная система MapLibre GL JS сохраняет структуру событий Mapbox:

map.on('load', () => {
  console.log('map loaded');
});

map.on('click', 'cities', (e) => {
  console.log(e.features);
});

Поддерживаемые события:

  • жизненный цикл карты: load, render, idle
  • взаимодействие: click, mousemove, mouseenter, mouseleave
  • состояние камеры: move, zoom, rotate, pitch

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

  • event propagation остаётся идентичным
  • layer-specific events работают через идентификаторы слоёв
  • порядок обработки событий соответствует z-index слоёв

Совместимость выражений (Expressions)

Expression API — одна из наиболее сложных частей совместимости.

Пример:

'circle-color': [
  'case',
  ['>', ['get', 'population'], 1000000],
  '#ff0000',
  '#0000ff'
]

Поддерживаются:

  • математические операции
  • логические выражения
  • доступ к свойствам (get)
  • интерполяции (interpolate)
  • условия (case)
  • работа с типами (to-number, to-string)

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

  • поведение некоторых edge-case функций может отличаться в деталях
  • расширения Mapbox Pro expressions не поддерживаются
  • производительность выражений может зависеть от реализации WebGL пайплайна

Совместимость управления камерой

API камеры:

map.flyTo({
  center: [10, 10],
  zoom: 5,
  speed: 1.2
});

Поддерживаемые методы:

  • jumpTo
  • easeTo
  • flyTo
  • fitBounds

Совместимость:

  • математическая модель камеры идентична Mapbox GL JS v1
  • параметры анимации полностью совместимы
  • различия могут наблюдаться в плавности анимаций из-за различий в requestAnimationFrame scheduling

Контролы и UI компоненты

Встроенные контролы:

  • NavigationControl
  • ScaleControl
  • AttributionControl
  • FullscreenControl

Пример:

map.addControl(new maplibregl.NavigationControl());

Совместимость:

  • API добавления и удаления контролов идентичен
  • поведение DOM-элементов отличается минимально
  • кастомные контролы полностью поддерживаются через интерфейс IControl

Совместимость расширений и плагинов

Экосистема Mapbox GL JS имела множество плагинов, которые частично перешли в MapLibre.

Основные категории:

визуальные плагины

  • кластеризация
  • heatmap расширения
  • 3D визуализация

функциональные плагины

  • geocoder
  • draw tools
  • routing overlays

Совместимость зависит от:

  • использования публичного API Mapbox GL JS v1
  • отсутствия зависимости от Mapbox token
  • отсутствия внутренних приватных методов

Проблемные зоны:

  • плагины, использующие internal API Mapbox GL JS
  • расширения, завязанные на proprietary tilesets

Отличия в жизненном цикле и инициализации

Инициализация MapLibre GL JS чаще требует более явного контроля над ресурсами:

  • загрузка стиля через CORS
  • доступ к glyphs и sprites
  • управление тайловыми серверами

Пример проблемного кейса:

  • стиль использует Mapbox-hosted tiles → требуется замена источников
  • sprite URL недоступен → визуальные символы не отображаются

Совместимость WebGL слоя

Внутренний рендеринг основан на WebGL, что обеспечивает:

  • идентичную модель батчинга слоёв
  • поддержку GPU-ускоренной отрисовки
  • использование shaders для разных типов слоёв

Отличия:

  • оптимизации производительности могут отличаться между версиями
  • управление памятью текстур может вести себя иначе при больших наборах тайлов
  • поведение при нехватке WebGL ресурсов зависит от браузера

Совместимость миграции проектов

Типичная миграция с Mapbox GL JS:

  1. замена пакета:

    • mapbox-glmaplibre-gl
  2. удаление access token:

// больше не требуется
mapboxgl.accessToken = '...';
  1. проверка источников:
  • tile URLs
  • sprite/glyph endpoints
  1. тестирование expressions и фильтров

Особое внимание:

  • кастомные шрифты (glyphs)
  • локальные тайловые серверы
  • 3D extrusion слои

Ограничения обратной совместимости

Несмотря на высокую степень совместимости, существуют системные ограничения:

  • отсутствие поддержки новых проприетарных функций Mapbox GL JS v2+
  • различия в лицензировании и связанных API
  • несовместимость с некоторыми cloud-only сервисами Mapbox
  • частичные расхождения в реализации новых expression функций

Эти ограничения формируют естественную границу эволюции API, где MapLibre GL JS развивается независимо, сохраняя при этом стабильную базовую модель Mapbox GL JS v1.x.