Типы для стилей

Система стилей в MapLibre GL JS опирается на строго структурированную спецификацию, заимствованную из подхода декларативного описания картографических сцен. Основой служит JSON-описание, которое формально описывается набором типов, определяющих допустимые структуры данных, их взаимосвязи и правила валидации. В TypeScript-обвязке библиотеки эти структуры представлены как набор интерфейсов и объединений (union types), обеспечивающих строгую типизацию при разработке.


Базовый тип стиля: StyleSpecification

Центральным типом является StyleSpecification, описывающий полный стиль карты.

interface StyleSpecification {
  version: number;
  name?: string;
  metadata?: unknown;
  center?: [number, number];
  zoom?: number;
  bearing?: number;
  pitch?: number;
  sources: { [key: string]: SourceSpecification };
  sprite?: string;
  glyphs?: string;
  layers: LayerSpecification[];
  light?: LightSpecification;
}

Ключевые поля

version

  • Версия спецификации стиля
  • Определяет совместимость с рендерером

sources

  • Коллекция источников данных
  • Используется для привязки геоданных к слоям

layers

  • Массив визуальных слоёв
  • Определяет визуализацию данных

sprite и glyphs

  • Ресурсы для иконок и шрифтов

Типы источников данных (Sources)

Источники данных описываются через объединение различных типов SourceSpecification.

type SourceSpecification =
  | VectorSourceSpecification
  | RasterSourceSpecification
  | GeoJSONSourceSpecification
  | ImageSourceSpecification
  | VideoSourceSpecification;

Векторные источники

interface VectorSourceSpecification {
  type: "vector";
  url?: string;
  tiles?: string[];
  minzoom?: number;
  maxzoom?: number;
}

Используются для тайловых наборов векторных данных.

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

  • поддержка MVT (Mapbox Vector Tiles)
  • высокая производительность при масштабировании
  • возможность стилизации на клиенте

GeoJSON источники

interface GeoJSONSourceSpecification {
  type: "geojson";
  dat a: GeoJSON.FeatureCollection | string;
  buffer?: number;
  tolerance?: number;
}

Используются для динамических или локальных данных.


Растровые источники

interface RasterSourceSpecification {
  type: "raster";
  tiles: string[];
  tileSize?: number;
}

Подходят для тайлов изображений (например, спутниковые снимки).


Типы слоёв (Layers)

Слои представляют ключевой механизм визуализации. Каждый слой описывается через LayerSpecification.

type LayerSpecification =
  | BackgroundLayerSpecification
  | FillLayerSpecification
  | LineLayerSpecification
  | SymbolLayerSpecification
  | RasterLayerSpecification
  | CircleLayerSpecification
  | HeatmapLayerSpecification
  | FillExtrusionLayerSpecification;

Базовая структура слоя

interface BaseLayerSpecification {
  id: string;
  type: string;
  source?: string;
  minzoom?: number;
  maxzoom?: number;
  filter?: ExpressionSpecification;
  layout?: unknown;
  paint?: unknown;
}

Fill Layer

interface FillLayerSpecification extends BaseLayerSpecification {
  type: "fill";
  paint?: {
    "fill-color"?: string | ExpressionSpecification;
    "fill-opacity"?: number;
  };
}

Используется для полигонов.


Line Layer

interface LineLayerSpecification extends BaseLayerSpecification {
  type: "line";
  paint?: {
    "line-color"?: string | ExpressionSpecification;
    "line-width"?: number | ExpressionSpecification;
  };
}

Применяется для линейных объектов: дорог, границ, маршрутов.


Symbol Layer

interface SymbolLayerSpecification extends BaseLayerSpecification {
  type: "symbol";
  layout?: {
    "text-field"?: string | ExpressionSpecification;
    "icon-image"?: string | ExpressionSpecification;
  };
}

Отвечает за текст и иконки.


Типы выражений (Expressions)

Одним из наиболее сложных элементов системы стилей является система выражений. Она позволяет задавать динамическое поведение свойств.

type ExpressionSpecification =
  | ["get", string]
  | ["interpolate", ...any[]]
  | ["case", ...any[]]
  | ["match", ...any[]]
  | ["+", any, any]
  | ["-", any, any]
  | ["*", any, any]
  | ["/", any, any];

Пример интерполяции

[
  "interpolate",
  ["linear"],
  ["zoom"],
  5,
  1,
  10,
  2
]

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


Типы layout и paint

Каждый слой делится на две категории свойств:

  • layout — влияет на геометрию и размещение
  • paint — влияет на визуальное отображение

Layout

Определяет структуру отображения:

  • размещение текста
  • порядок слоёв
  • видимость элементов

Paint

Определяет внешний вид:

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

LightSpecification

interface LightSpecification {
  anchor: "map" | "viewport";
  color?: string;
  intensity?: number;
}

Используется для 3D-эффектов и освещения экструзий.


Типизация через union и discriminated unions

Система типов в MapLibre GL JS активно использует discriminated unions. Поле type выступает дискриминатором.

type LayerSpecification =
  | { type: "fill"; ... }
  | { type: "line"; ... }
  | { type: "symbol"; ... };

Такой подход позволяет TypeScript:

  • точно определять доступные поля
  • предотвращать ошибки конфигурации
  • обеспечивать автодополнение в IDE

Валидация стилей через типы

Типы выполняют роль контрактов между JSON-стилем и рендерером.

Основные проверки:

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

Связь типов с Style Specification

Система типов напрямую отражает структуру спецификации стилей, известной как Mapbox Style Specification, на которой базируется MapLibre GL JS.

Каждое поле JSON-стиля соответствует строго определённому TypeScript-типу, что позволяет:

  • описывать стили декларативно
  • проверять корректность на этапе компиляции
  • унифицировать поведение между проектами

Расширяемость типовой системы

Типы не являются статичными. Возможны расширения:

Пользовательские слои

interface CustomLayerSpecification extends BaseLayerSpecification {
  type: "custom";
  render: (context: unknown) => void;
}

Дополнительные источники

Расширение SourceSpecification позволяет подключать новые типы данных без изменения ядра рендера.


Фрагментация типов по слоям ответственности

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

  • Core Style Types — структура стиля
  • Source Types — данные
  • Layer Types — визуализация
  • Expression Types — логика
  • Light Types — 3D освещение

Такое разделение позволяет поддерживать масштабируемость архитектуры и независимость компонентов.