Image источник

Роль изображений в стилях карт

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

Внутри графического конвейера WebGL изображения становятся текстурами, которые привязываются к геометрии или используются как самостоятельные источники данных. Работа с ними требует понимания нескольких уровней абстракции: загрузка, регистрация в стиле, использование в слоях и управление кешированием.


Добавление изображений в стиль

Метод addImage

Базовый механизм подключения изображения к стилю реализуется через метод:

  • map.addImage(name, image, options)

Где:

  • name — уникальный идентификатор изображения в стиле
  • image — объект HTMLImageElement, ImageData, Canvas или ArrayBufferView
  • options — параметры поведения изображения

Изображение после регистрации становится доступным для использования в слоях типа symbol.

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

  • загрузка изображения
  • ожидание завершения декодирования
  • добавление в стиль
  • использование в слое

Ключевым моментом является тот факт, что изображение хранится в GPU-кеше, а не просто в DOM-структуре.


Использование изображений в слоях

Символьные слои (symbol layer)

Изображения применяются преимущественно в слоях типа symbol. Поле icon-image указывает на имя зарегистрированного изображения.

Основная схема:

  • изображение добавлено через addImage
  • слой ссылается на него через icon-image
  • рендеринг происходит на основе координат геометрии
map.addLayer({
  id: "points",
  type: "symbol",
  source: "points-source",
  layout: {
    "icon-image": "marker-icon"
  }
});

Изображение интерполируется и масштабируется в зависимости от уровня зума и параметров слоя.


Атлас изображений (Sprite)

Концепция sprite

В стилях MapLibre используется механизм спрайтов — единый атлас изображений, содержащий множество иконок.

Спрайт состоит из двух файлов:

  • JSON-описание координат
  • PNG-изображение атласа

JSON содержит:

  • координаты каждой иконки
  • размеры
  • пиксельные смещения

Преимущества sprite-подхода

  • минимизация HTTP-запросов
  • ускорение рендеринга
  • эффективное использование памяти GPU
  • единый кеш для всех иконок

Sprite загружается автоматически при применении стиля через sprite-параметр.


Параметры addImage и управление качеством

Фильтрация и масштабирование

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

  • pixelRatio — плотность пикселей для HiDPI экранов
  • sdf — использование signed distance field
  • sdfScale — масштабирование SDF-иконок

SDF-режим позволяет:

  • изменять цвет иконки через стиль
  • применять тени и обводки
  • сохранять чёткость при масштабировании

Динамическая загрузка изображений

Асинхронные источники

Изображения могут подгружаться динамически:

  • через map.loadImage(url, callback)
  • через fetch и последующую конвертацию в ImageBitmap
  • через Canvas API

Типичный поток:

  1. загрузка ресурса по URL
  2. декодирование изображения
  3. регистрация через addImage
  4. обновление слоя

Критическим аспектом является синхронизация загрузки с рендер-циклом WebGL.


Удаление и обновление изображений

Метод removeImage

Изображение может быть удалено из стиля:

  • map.removeImage(name)

Удаление приводит к:

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

Обновление изображения обычно реализуется через:

  • удаление старого
  • добавление нового с тем же именем

Использование canvas как источника изображения

Генерация текстур на лету

В качестве источника можно использовать <canvas>, что позволяет:

  • рисовать динамические иконки
  • визуализировать числовые данные
  • создавать адаптивные маркеры

Canvas передается в addImage как готовый bitmap.

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

  • изображение фиксируется на момент добавления
  • дальнейшие изменения canvas не влияют на уже добавленную текстуру

Image Source как тип источника данных

Отличие от raster и vector sources

Помимо регистрации отдельных изображений существует тип источника image source, который представляет собой одиночное изображение, геопривязанное к координатам.

Он задаётся через:

  • URL изображения
  • bounding box координат

Такой источник используется для:

  • оверлеев (карты, схемы, планы)
  • исторических карт
  • спутниковых снимков без тайлинга

Привязка изображения к географии

Image source описывается четырьмя угловыми координатами:

  • верхний левый
  • верхний правый
  • нижний правый
  • нижний левый

Изображение растягивается между этими точками, преобразуясь в геопространственную текстуру.

Ключевые особенности:

  • поддержка искажений проекции
  • привязка к системе координат карты
  • масштабирование вместе с картой

Производительность и GPU-кеширование

Поведение текстур

После добавления изображения:

  • оно загружается в GPU
  • преобразуется в WebGL texture
  • кешируется до удаления слоя или стиля

Ограничения:

  • количество текстур ограничено видеопамятью
  • большие изображения увеличивают нагрузку на рендер
  • повторяющиеся изображения лучше объединять в sprite

Форматы изображений и декодирование

Поддерживаются основные форматы:

  • PNG
  • JPEG
  • WebP (в зависимости от браузера)

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

  • PNG используется для прозрачных иконок
  • JPEG — для фоновых растров
  • WebP — для оптимизации размера

Декодирование выполняется браузером, MapLibre лишь управляет загрузкой и регистрацией.


Масштабирование и поведение на зумах

Изображения в symbol слоях:

  • масштабируются в зависимости от zoom
  • могут фиксироваться по размеру через icon-size
  • могут вращаться и наклоняться

При использовании SDF:

  • цвет иконки изменяется динамически
  • масштабирование сохраняет резкость

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

Механизм повторного использования

Если изображение зарегистрировано:

  • оно доступно всем слоям стиля
  • повторная регистрация с тем же именем запрещена без удаления
  • кэш сохраняется до смены стиля карты

Оптимизация достигается за счёт:

  • единой таблицы изображений
  • ссылочной модели в слоях
  • WebGL texture atlas внутри движка

Типичные архитектурные паттерны

Централизованное хранилище иконок

В сложных приложениях изображения:

  • загружаются при инициализации карты
  • регистрируются централизованно
  • используются через конфигурацию слоёв

Ленивое добавление

Другой подход:

  • изображения добавляются по мере появления данных
  • используется событие styleimagemissing
  • загрузка происходит по требованию

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


Обработка отсутствующих изображений

Событие styleimagemissing позволяет:

  • перехватить запрос на несуществующую иконку
  • динамически загрузить ресурс
  • зарегистрировать его до следующего рендера

Это важно для:

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

Связь с символическими слоями и текстом

Изображения в symbol слоях могут комбинироваться с текстом:

  • иконка + подпись
  • только иконка
  • только текст

Параметры layout позволяют управлять:

  • порядком отображения
  • смещением
  • выравниванием

Особенности работы в WebGL контексте

Все изображения проходят этап:

  1. декодирование браузером
  2. загрузка в GPU
  3. привязка к shader pipeline
  4. использование в фрагментных шейдерах

Это означает, что любые операции с изображениями напрямую влияют на:

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