Работа в офлайн-среде для картографических приложений на базе Mapbox GL JS требует разделения системы на несколько независимых уровней: загрузка стилей, получение тайлов, управление источниками данных и контроль сетевого состояния. Библиотека изначально ориентирована на онлайн-режим, поэтому офлайн-поддержка строится как надстройка над механизмами перехвата запросов и локального кэширования.
Ключевая проблема заключается в том, что рендеринг карты зависит от внешних ресурсов:
Каждый из этих компонентов требует отдельной стратегии офлайн-доступа.
Основной механизм управления загрузками в Mapbox GL JS — функция
transformRequest, передаваемая в конфигурации карты.
Она позволяет перехватывать каждый HTTP-запрос:
Типовая логика офлайн-режима строится вокруг подмены URL:
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/example/style.json',
transformRequest: (url, resourceType) => {
if (!navigator.onLine) {
return {
url: `/offline-cache${new URL(url).pathname}`
};
}
return { url };
}
});
Браузер предоставляет базовые механизмы определения состояния сети:
window.addEventListener('online', () => {
// восстановление синхронизации
});
window.addEventListener('offline', () => {
// переключение в режим локального кэша
});
Однако этого недостаточно, так как:
Поэтому используется комбинированный подход:
Наиболее устойчивый способ офлайн-поддержки — Service Worker, который перехватывает сетевые запросы на уровне браузера.
Базовая стратегия:
self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
if (url.pathname.includes('/tiles/')) {
event.respondWith(
caches.match(event.request).then((cached) => {
return cached || fetch(event.request).then((response) => {
const copy = response.clone();
caches.open('tiles-cache').then((cache) => {
cache.put(event.request, copy);
});
return response;
});
})
);
}
});
Для стабильного офлайн-режима используется многоуровневая система хранения:
Используется для:
Используется Service Worker’ом:
Применяется только для:
Style JSON — центральный элемент конфигурации карты. В офлайн-режиме он должен быть полностью локализован.
Типичная проблема — абсолютные URL:
"glyphs": "https://api.mapbox.com/fonts/..."
"sprites": "https://api.mapbox.com/sprites/..."
Решение заключается в подмене на локальные ресурсы:
"glyphs": "/offline/glyphs/{fontstack}/{range}.pbf",
"sprites": "/offline/sprites/sprite"
При этом важно соблюдать:
Vector tiles (MVT) обеспечивают гибкость рендеринга, но требуют сложной офлайн-подготовки:
Raster tiles проще в офлайн-режиме:
Выбор зависит от сценария:
Mapbox GL JS в онлайн-режиме использует access token для доступа к API. В офлайн-среде возникают ограничения:
Типовая архитектура решения:
Mapbox GL JS использует внутренний pipeline загрузки ресурсов. Ошибки офлайн-режима проявляются в событиях:
errordatastyledatasourcedataОбработка ошибок позволяет переключать режимы:
map.on('error', (e) => {
if (!navigator.onLine) {
// переключение на offline fallback
}
});
Важно учитывать, что ошибки могут возникать не только из-за отсутствия сети, но и из-за:
Наиболее стабильный подход — развёртывание локального сервера:
Пример структуры:
/tiles/{z}/{x}/{y}.pbf
/styles/basic/style.json
/sprites/sprite.png
/fonts/{fontstack}/{range}.pbf
В этом случае Mapbox GL JS работает без сетевых зависимостей, а transformRequest выполняет только маршрутизацию на локальный origin.
Офлайн-режим невозможен без предварительной загрузки данных.
Используются подходы:
Пример логики:
В офлайн-режиме часть функций становится недоступной:
Архитектура должна учитывать деградацию:
При офлайн-хранении критично проверять:
Типовой подход:
Офлайн-режим в Mapbox GL JS строится как совокупность:
Такая архитектура превращает изначально онлайн-ориентированную систему рендеринга карт в автономную визуализационную среду, способную функционировать без постоянного доступа к сети при условии заранее подготовленного набора геоданных и ресурсов.