Экспорт изображений

Визуализация данных в kepler.gl строится поверх WebGL-рендеринга, где итоговая сцена формируется библиотекой deck.gl и картографическим движком Mapbox GL. Это означает, что экспорт изображения — не «сохранение HTML», а рендеринг текущего состояния сцены в растровый буфер с последующей сериализацией в PNG или JPEG.

Экспорт всегда опирается на текущее состояние карты: слой данных, фильтры, стили, положение камеры, масштаб, поворот, а также активные визуальные эффекты.


Архитектура рендеринга и влияние на экспорт

Перед тем как рассматривать API экспорта, важно понимать цепочку визуализации:

  • Kepler.gl хранит состояние в Redux (datasets, layers, filters, mapState)
  • Deck.gl отвечает за отрисовку слоёв (ScatterplotLayer, ArcLayer и т.д.)
  • Mapbox GL управляет базовой картой (тайлы, стили, подписи)
  • WebGL контекст объединяет всё в единую сцену

Экспорт изображения происходит на уровне WebGL-контекста, где текущий кадр «снимается» как snapshot.

Ключевой момент: экспорт фиксирует только то, что уже отрисовано. Асинхронные слои (тайлы, подгрузка данных) должны быть полностью загружены до вызова экспорта.


Основной способ экспорта через экземпляр карты

В React-интеграции Kepler.gl доступ к экземпляру карты обычно осуществляется через mapRef.

Типичный сценарий:

  • создаётся компонент KeplerGl
  • сохраняется ref на экземпляр
  • вызывается метод экспорта

Получение инстанса карты

Экземпляр карты доступен через:

  • mapRef.current — React ref
  • getKeplerGlInstance() — доступ к внутреннему API

Логика основана на том, что Kepler.gl хранит несколько карт по ключам, и каждая имеет свой инстанс.


Экспорт изображения через API инстанса

После получения инстанса карты используется метод экспорта:

  • exportToImage()

Он инициирует рендер сцены в canvas и возвращает результат в формате base64 или Blob (в зависимости от реализации).

Общая последовательность вызова

  • получить инстанс Kepler.gl
  • дождаться завершения рендера карты
  • вызвать экспорт изображения
  • обработать результат (скачивание или отправка на сервер)

Особенность: экспорт выполняется асинхронно, так как WebGL должен завершить отрисовку всех слоёв.


Пример логики вызова экспорта

Внутренняя логика обычно выглядит так:

  • доступ к map instance
  • вызов метода рендера кадра
  • захват canvas
  • преобразование в изображение

Псевдологика:

  • map.render()
  • canvas.toDataURL('image/png')

или

  • gl.readPixels(...) (низкоуровневый путь)

Экспорт через UI Kepler.gl

В стандартной сборке интерфейса kepler.gl предусмотрена панель экспорта.

Функциональность включает:

  • экспорт текущего вида карты
  • выбор формата (PNG)
  • сохранение композиции слоёв

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


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

Экспорт изображения напрямую зависит от состояния WebGL-контекста:

1. Потеря контекста

Если GPU-контекст был сброшен (например, из-за нагрузки), экспорт может вернуть пустое изображение.

2. Асинхронные тайлы Mapbox

Базовая карта может быть не полностью загружена, что приводит к «пустым плиткам».

3. Прозрачность фона

По умолчанию фон может быть прозрачным, если не задан стиль Mapbox.


Контроль качества экспортируемого изображения

Для корректного результата важно учитывать:

  • завершённость загрузки данных
  • отсутствие активных анимаций
  • стабильный zoom и rotation
  • фиксированное состояние фильтров

Часто применяется стратегия «заморозки состояния» перед экспортом:

  • отключение интерактивности
  • фиксация камеры
  • ожидание idle-состояния рендера

Экспорт с высоким разрешением

Стандартный экспорт использует размер canvas, соответствующий viewport. Для увеличения качества применяется масштабирование:

  • увеличение devicePixelRatio
  • рендер в offscreen canvas
  • повторный draw с увеличенным viewport

Это позволяет получить изображения для печати или аналитических отчётов.


Работа с несколькими картами

kepler.gl поддерживает несколько экземпляров карт одновременно. При экспорте важно явно указывать, какая карта используется:

  • mapId или instanceKey
  • доступ к нужному reducer-сегменту состояния
  • выбор конкретного map instance через registry

Ошибка выбора инстанса приводит к экспорту «пустого» слоя или дефолтного состояния.


Проблемы синхронизации и их причины

На практике экспорт часто ломается из-за несогласованности состояния:

  • фильтры обновились, но слой ещё не пересчитан
  • данные загружены, но не триггерился rerender
  • Mapbox тайлы находятся в состоянии loading
  • WebGL не завершил frame

Решение обычно сводится к ожиданию idle-цикла рендера и проверке готовности сцены.


Экспорт как часть пайплайна данных

В более сложных системах экспорт изображения используется как этап автоматизации:

  • генерация отчётов
  • snapshot аналитики
  • архивирование карт
  • отправка результатов в BI-системы

В таких сценариях Kepler.gl работает в headless-режиме (например, в Node + headless browser), где важно эмулировать браузерный WebGL-контекст.


Использование headless-рендеринга

В серверных сценариях применяется:

  • Puppeteer или Playwright
  • запуск Kepler.gl в Chromium
  • программное управление состоянием карты
  • вызов экспорта через DOM или window API

Экспорт в этом случае фактически становится screenshot-операцией страницы, но с гарантией полной загрузки сцены.


Ограничения экспорта

Существуют фундаментальные ограничения WebGL-экспорта:

  • невозможность захвата внешних DOM-элементов вне canvas
  • ограничения CORS для тайлов Mapbox
  • зависимость от GPU
  • различия между браузерами

Особенно критичны CORS-ошибки: если тайлы загружены с неправильными заголовками, canvas становится «tainted» и экспорт блокируется.


Оптимизация перед экспортом

Для стабильного результата применяются следующие техники:

  • предзагрузка всех слоёв
  • отключение анимаций и transitions
  • фиксация viewport
  • уменьшение количества одновременно активных слоёв
  • использование упрощённых стилей карты

Форматы результата и преобразование

Хотя базовый экспорт ориентирован на PNG, результат можно преобразовывать:

  • PNG → JPEG для уменьшения веса
  • PNG → WebP для веб-доставки
  • base64 → Blob для скачивания
  • Blob → File для загрузки на сервер

Выбор формата зависит от сценария использования: аналитика, публикация или архивирование.


Роль состояния приложения в итоговом изображении

Экспорт отражает полный snapshot Redux-состояния:

  • datasets определяют геометрию
  • layers — визуализацию
  • filters — выборку данных
  • mapState — камеру и перспективу

Это делает экспорт воспроизводимым: при одинаковом состоянии результат изображения будет идентичен.