Исходный код MapLibre GL JS организован как модульная система, ориентированная на разделение ответственности между уровнями рендеринга, управления стилями, обработки геоданных и взаимодействия с WebGL. Репозиторий построен таким образом, чтобы поддерживать независимую разработку отдельных компонентов без нарушения общей структуры библиотеки.
Ключевые области кода:
Каждый из компонентов выделен в отдельные директории с минимальными пересечениями логики.
Типичная структура исходного дерева включает следующие основные каталоги:
src/ — основной исходный код библиотекиsrc/ui/ — элементы интерфейса картыsrc/style/ — обработка и применение style
specificationsrc/render/ — WebGL рендеринг и управление слоямиsrc/source/ — источники данных (vector, raster,
geojson)src/geo/ — геометрические вычисления и
трансформацииsrc/util/ — вспомогательные функцииsrc/handler/ — обработчики взаимодействийsrc/worker/ — код, выполняющийся в Web Workertest/ — тесты различного уровняОтдельное значение имеет файл точки входа, через который формируется публичный API библиотеки.
Основной класс карты формирует интерфейс, через который происходит вся работа с библиотекой. Он связывает рендерер, источники данных и стиль.
Внутренняя инициализация строится вокруг следующих этапов:
Именно на этом уровне происходит связывание низкоуровневых модулей в единую систему.
Сборка MapLibre GL JS основана на современных JavaScript-инструментах, ориентированных на модульность и оптимизацию итогового бандла.
Используются:
Процесс сборки включает:
Сборочная конфигурация разделяет development и production режимы, что позволяет включать расширенную отладочную информацию в первом случае и агрессивную оптимизацию во втором.
Одна из ключевых особенностей MapLibre GL JS — вынос вычислительно тяжёлых операций в Web Worker. Это позволяет избежать блокировки основного потока UI.
Worker отвечает за:
Связь между основным потоком и worker реализована через message-passing протокол.
Типичный цикл обработки данных:
Такая архитектура позволяет масштабировать производительность при увеличении объёма данных.
Рендеринг в MapLibre GL JS основан на WebGL1/WebGL2 контексте, где каждый слой стиля преобразуется в набор GPU-команд.
Основные компоненты рендерера:
Каждый слой стиля компилируется в отдельный набор WebGL ресурсов.
Процесс рендеринга включает:
Особое внимание уделяется минимизации переключений состояния GPU, так как это напрямую влияет на производительность.
Style Specification представляет собой декларативное описание визуализации карты. Исходный код отвечает за трансляцию этого описания в исполняемые графические инструкции.
Стиль включает:
Внутренний парсер преобразует JSON-структуру в оптимизированные объекты, которые затем используются рендерером.
Каждое свойство стиля компилируется в специализированные структуры, обеспечивающие быстрый доступ во время отрисовки.
Поддерживаются несколько типов источников:
Каждый тип реализует единый интерфейс, что позволяет рендереру работать с абстрактным источником без знания деталей его реализации.
Vector tile pipeline включает:
GeoJSON источник обрабатывается через преобразование в промежуточный формат векторных данных.
Модуль src/geo/ содержит функции, отвечающие за
математические преобразования:
Эти операции являются фундаментом для всех последующих этапов рендеринга.
Особое значение имеет система преобразования между:
Состояние карты включает:
Изменение любого параметра инициирует перерасчёт матрицы трансформации, которая затем используется в WebGL пайплайне.
Матрицы включают:
Их комбинация формирует итоговое преобразование сцены.
Обновление карты строится вокруг событийной модели:
Каждое событие помечает карту как “dirty”, после чего запускается цикл перерисовки.
Рендер-цикл включает:
Исходный код включает развитую систему логирования и debug-инструментов.
Применяются:
Отладочные режимы позволяют анализировать:
Тестовая система включает несколько уровней:
Визуальные тесты сравнивают итоговые изображения сцен, что позволяет выявлять регрессии в рендерере.
В проекте активно используется TypeScript, обеспечивающий:
Типы описывают:
Это позволяет поддерживать сложную архитектуру без потери согласованности между модулями.
Особое внимание уделяется:
Производительность достигается за счёт строгого разделения CPU и GPU задач, а также агрессивного использования worker-архитектуры.
Кодовая база построена так, чтобы новые типы слоёв или источников могли добавляться без изменения ядра рендеринга.
Основные принципы:
Такая структура позволяет развивать библиотеку без нарушения существующей архитектуры.