Спрайты изображений

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

В рамках спецификации стилей MapLibre GL GL поддерживается механизм sprite, который состоит из двух взаимосвязанных ресурсов:

  • растрового изображения (sprite.png или sprite@2x.png)
  • JSON-индекса (sprite.json или sprite@2x.json)

Оба файла работают как единая структура описания набора пиктограмм.


Структура sprite-ресурсов

Графический файл

Файл спрайта представляет собой атлас изображений, в котором все иконки размещены в одной плоскости:

  • формат: PNG (иногда WebP в кастомных пайплайнах)
  • содержит множество иконок разного размера
  • может иметь высокое разрешение @2x для Retina-дисплеев

Преимущество такого подхода заключается в минимизации сетевых запросов и повышении скорости отрисовки.


JSON-описание

JSON-файл спрайта описывает координаты каждой иконки внутри атласа:

{
  "airport-15": {
    "x": 0,
    "y": 0,
    "width": 32,
    "height": 32,
    "pixelRatio": 1
  },
  "rail-11": {
    "x": 32,
    "y": 0,
    "width": 32,
    "height": 32,
    "pixelRatio": 1
  }
}

Каждая запись содержит:

  • x, y — координаты в пикселях внутри атласа
  • width, height — размеры изображения
  • pixelRatio — коэффициент плотности (1 или 2 для HiDPI)

Подключение спрайтов в стиле

В стиле MapLibre GL JS спрайты задаются на уровне объекта sprite:

{
  "version": 8,
  "sprite": "https://example.com/sprites/sprite",
  "glyphs": "https://example.com/fonts/{fontstack}/{range}.pbf",
  "sources": {},
  "layers": []
}

Важно, что расширение .png и .json не указывается — библиотека добавляет их автоматически:

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

Использование иконок из спрайта

Спрайты применяются через свойство icon-image в слоях типа symbol.

Пример слоя

map.addLayer({
  id: "airports",
  type: "symbol",
  source: "places",
  layout: {
    "icon-image": "airport-15",
    "icon-size": 1,
    "icon-allow-overlap": true
  }
});

Имя "airport-15" должно совпадать с ключом в sprite.json.


Механизм выбора изображения

При рендеринге MapLibre GL JS выполняет следующие шаги:

  1. Загружает sprite.json
  2. Загружает sprite.png
  3. Кэширует координаты и текстуры
  4. При необходимости извлекает подизображение из атласа
  5. Использует WebGL-текстуру для отрисовки

Фактическое извлечение происходит на уровне GPU, что обеспечивает высокую производительность при большом количестве объектов.


Поддержка HiDPI (retina)

Для экранов с высокой плотностью пикселей используются отдельные версии:

  • sprite.png — базовое разрешение
  • sprite@2x.png — увеличенное в 2 раза

MapLibre автоматически выбирает нужный вариант на основе devicePixelRatio.

В JSON это отражается полем:

"pixelRatio": 2

Формирование спрайтов

Спрайты обычно генерируются автоматически из набора SVG или PNG-иконок.

Подходы к генерации:

  • сборка из SVG с помощью инструментов bundling
  • использование sprite generator (например, spritezero)
  • интеграция в CI/CD пайплайны

Процесс включает:

  1. оптимизацию исходных SVG
  2. упаковку в атлас
  3. генерацию JSON-индекса
  4. публикацию на CDN

Кэширование и производительность

Спрайты являются критически кэшируемым ресурсом.

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

  • загружаются один раз на стиль
  • кэшируются браузером по URL
  • повторно используются всеми слоями
  • минимизируют количество HTTP-запросов

При использовании CDN достигается стабильная производительность даже при больших наборах иконок.


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

1. Невозможность динамического изменения пикселей

Спрайт является статическим ресурсом. Изменение иконок требует пересборки атласа.


2. Уникальность ключей

Имена иконок должны быть уникальными:

  • допустимы строки вида poi-hospital
  • не допускаются дубликаты ключей

3. Размер атласа

Слишком большие спрайты могут негативно влиять на:

  • время загрузки
  • использование памяти GPU

Рекомендуется логическая сегментация:

  • transport-sprite
  • food-sprite
  • ui-sprite

Использование с фильтрацией и стилями

Спрайты часто применяются совместно с фильтрами слоёв:

map.addLayer({
  id: "poi",
  type: "symbol",
  source: "places",
  layout: {
    "icon-image": ["get", "icon"],
    "icon-size": 1
  },
  filter: ["has", "icon"]
});

В этом случае значение icon в данных источника соответствует ключу в sprite.json.


Взаимодействие с источниками данных

Спрайты тесно связаны с векторными источниками:

  • GeoJSON
  • Vector Tiles
  • кастомные API

Каждый объект может содержать атрибут, указывающий на иконку:

{
  "type": "Feature",
  "properties": {
    "icon": "rail-11"
  },
  "geometry": {
    "type": "Point",
    "coordinates": [66.9237, 48.0196]
  }
}

Динамическая подмена спрайтов

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

map.setStyle("https://example.com/style-with-new-sprite.json");

При этом:

  • старые текстуры освобождаются
  • загружается новый sprite atlas
  • перерисовываются все символы

Типичные проблемы

1. 404 на sprite.json

Причины:

  • неверный URL в стиле
  • отсутствие .json/.png файлов на сервере

2. Несовпадение имён

Если icon-image не совпадает с ключом в JSON:

  • иконка не отображается
  • слой остаётся пустым

3. CORS-ограничения

Sprite должен быть доступен с корректными заголовками:

  • Access-Control-Allow-Origin

Иначе загрузка блокируется браузером.


Оптимизация структуры спрайтов

Практика построения эффективных спрайтов включает:

  • группировку по тематике
  • удаление неиспользуемых иконок
  • минимизацию прозрачных областей
  • использование SVG как исходного формата
  • автоматическую сборку при деплое

Архитектурная роль спрайтов в MapLibre

В системе рендеринга MapLibre GL JS спрайты являются базовым компонентом визуализации символов:

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

Связь с системой стилей MapLibre

Спрайты являются частью Style Specification и взаимодействуют с:

  • layers (символические слои)
  • layout properties
  • paint properties
  • glyphs (шрифтовые атласы)

Полный стек визуализации символов строится на комбинации:

  • glyphs → текст
  • sprite → иконки
  • layers → правила отображения

Роль в экосистеме веб-картографии

MapLibre Official Website

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