Vector источник

Векторный источник в MapLibre GL JS представляет собой механизм подключения и отображения данных в формате векторных тайлов (vector tiles), которые передаются в бинарном формате PBF и интерпретируются на стороне клиента для динамической отрисовки слоёв карты. Такой подход позволяет работать с большими объёмами геоданных, сохраняя высокую производительность и гибкость стилизации.

Архитектура векторных тайлов

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

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

  • данные хранятся в сжатом бинарном формате (обычно .pbf);
  • каждый тайл соответствует координатам {z}/{x}/{y};
  • геометрия представляется в виде точек, линий и полигонов;
  • атрибуты объектов сохраняются для фильтрации и стилизации;
  • отрисовка происходит динамически на клиенте.

Такой подход отличается от растровых тайлов, где сервер возвращает уже готовое изображение.

Определение векторного источника

В MapLibre GL JS векторный источник задаётся через map.addSource с типом vector.

Основная структура:

map.addSource('streets', {
  type: 'vector',
  tiles: [
    'https://example.com/tiles/{z}/{x}/{y}.pbf'
  ],
  minzoom: 0,
  maxzoom: 14
});

Основные параметры vector source

tiles

Параметр tiles определяет шаблон URL для получения векторных тайлов.

tiles: [
  'https://tiles.server.com/roads/{z}/{x}/{y}.pbf'
]

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

  • {z} — уровень масштабирования;
  • {x} — координата по оси X;
  • {y} — координата по оси Y.

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

tiles: [
  'https://a.tiles.com/{z}/{x}/{y}.pbf',
  'https://b.tiles.com/{z}/{x}/{y}.pbf'
]

minzoom и maxzoom

Эти параметры задают диапазон масштабов, на которых источник активен.

minzoom: 0,
maxzoom: 16

Если пользователь выходит за пределы диапазона, MapLibre либо не запрашивает тайлы, либо интерполирует данные.

bounds

Ограничивает географическую область доступности источника.

bounds: [-180, -85.0511, 180, 85.0511]

Формат: [west, south, east, north].

Использование bounds уменьшает количество запросов и повышает производительность.

scheme

Определяет схему нумерации тайлов:

scheme: 'xyz'

или

scheme: 'tms'
  • xyz — стандартная схема (верхний левый угол);
  • tms — инвертированная ось Y.

attribution

Юридическая атрибуция источника данных:

attribution: '© OpenStreetMap contributors'

Отображается в углу карты и обязателен для публичных данных.

Использование vector source в слоях

Векторный источник сам по себе не отображается. Он используется слоями (layer), которые извлекают конкретные данные из тайлов.

Пример подключения слоя линий:

map.addLayer({
  id: 'road-layer',
  type: 'line',
  source: 'streets',
  'source-layer': 'roads',
  paint: {
    'line-color': '#ff0000',
    'line-width': 2
  }
});

source-layer

Векторные тайлы могут содержать несколько логических слоёв внутри одного файла. Например:

  • roads
  • buildings
  • water
  • landuse

Параметр source-layer указывает, какой именно слой использовать.

'source-layer': 'buildings'

Фильтрация данных в vector source

MapLibre GL JS позволяет фильтровать объекты на основе их атрибутов.

filter: ['==', 'class', 'primary']

Пример слоя дорог только для магистралей:

map.addLayer({
  id: 'highways',
  type: 'line',
  source: 'streets',
  'source-layer': 'roads',
  filter: ['==', 'type', 'highway'],
  paint: {
    'line-color': '#000',
    'line-width': 3
  }
});

Фильтры поддерживают логические операции:

  • ==, !=
  • >, <, >=, <=
  • in, !in
  • all, any, none

Динамическое изменение источника

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

map.getSource('streets').setTiles([
  'https://new-tiles.server.com/{z}/{x}/{y}.pbf'
]);

Также возможно обновление параметров через setData только для GeoJSON, но для vector tiles используется замена URL.

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

Vector source активно использует кеширование на нескольких уровнях:

  • браузерный кеш HTTP;
  • внутренний кеш MapLibre;
  • кеш тайлов по координатам {z}/{x}/{y};
  • повторное использование геометрии между слоями.

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

  • уменьшения количества слоёв;
  • ограничения maxzoom;
  • использования генерализованных тайлов на низких zoom уровнях;
  • сокращения атрибутов в данных.

Сравнение vector source с raster source

Vector source отличается от raster следующим образом:

  • передаёт геометрию, а не изображение;
  • позволяет менять стиль без перезагрузки данных;
  • требует больше вычислений на клиенте;
  • обеспечивает лучшую масштабируемость визуализации.

Raster source:

map.addSource('satellite', {
  type: 'raster',
  tiles: [
    'https://tiles.server.com/{z}/{x}/{y}.png'
  ],
  tileSize: 256
});

Vector source:

map.addSource('vector', {
  type: 'vector',
  tiles: [
    'https://tiles.server.com/{z}/{x}/{y}.pbf'
  ]
});

Формат данных внутри vector tiles

Векторный тайл содержит слои, каждый из которых включает:

  • геометрические примитивы (Point, LineString, Polygon);
  • свойства (properties);
  • идентификаторы объектов;
  • метаданные слоя.

Типичная структура:

Tile
 ├── Layer: roads
 │     ├── Feature
 │     ├── Feature
 ├── Layer: buildings
 │     ├── Feature

MapLibre декодирует PBF и преобразует данные в WebGL буферы.

Источники в формате URL template и TileJSON

Помимо прямого массива tiles, часто используется TileJSON:

map.addSource('streets', {
  type: 'vector',
  url: 'https://example.com/tiles.json'
});

TileJSON содержит метаданные:

  • шаблон тайлов;
  • минимальные и максимальные zoom;
  • bounds;
  • атрибуцию;
  • список слоёв.

Пример структуры TileJSON:

{
  "tilejson": "2.2.0",
  "tiles": ["https://example.com/{z}/{x}/{y}.pbf"],
  "minzoom": 0,
  "maxzoom": 14,
  "bounds": [-180, -85, 180, 85],
  "vector_layers": [
    {
      "id": "roads",
      "fields": {
        "type": "String"
      }
    }
  ]
}

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

MapLibre GL JS позволяет комбинировать несколько vector source в одной карте.

map.addSource('roads', {
  type: 'vector',
  tiles: ['https://tiles.com/roads/{z}/{x}/{y}.pbf']
});

map.addSource('buildings', {
  type: 'vector',
  tiles: ['https://tiles.com/buildings/{z}/{x}/{y}.pbf']
});

Далее каждый источник используется в своих слоях, что позволяет разделять ответственность данных.

Использование локальных и кастомных источников

Vector source может обслуживаться:

  • собственным сервером тайлов;
  • генератором на базе PostGIS;
  • инструментами вроде Tippecanoe;
  • облачными сервисами тайлов.

При самостоятельной генерации важно учитывать:

  • оптимизацию геометрии;
  • ограничение количества вершин;
  • генерализацию на низких масштабах;
  • баланс между детализацией и размером тайла.

Протоколы и расширенные схемы доставки

Помимо HTTP URL, возможно использование:

  • CDN с кешированием тайлов;
  • signed URLs для защищённых данных;
  • локальных серверов разработки;
  • кастомных протоколов через MapLibre plugin API.

Некоторые реализации поддерживают форматы типа PMTiles, где весь набор тайлов хранится в одном файле и запрашивается по диапазону байтов, что снижает количество HTTP-запросов.

Ошибки загрузки и отладка

При работе с vector source часто возникают типичные проблемы:

  • неверный source-layer;
  • отсутствие тайлов на указанном zoom;
  • неправильная схема tms/xyz;
  • CORS ограничения;
  • несоответствие структуры PBF ожиданиям стиля.

Для диагностики используются:

map.on('error', (e) => {
  console.log(e.error);
});

Также полезно отслеживать загрузку тайлов:

map.on('data', (e) => {
  if (e.dataType === 'source') {
    console.log('Source updated');
  }
});

Атрибутная модель и стилизация

Векторный источник раскрывает доступ к атрибутам объектов, что позволяет строить сложные правила отображения:

paint: {
  'fill-color': [
    'match',
    ['get', 'landuse'],
    'park', '#00ff00',
    'residential', '#cccccc',
    '#999999'
  ]
}

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

Масштабируемость и серверная генерация тайлов

Vector source особенно эффективен в системах с высокой нагрузкой:

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

При серверной генерации используется pipeline:

  1. извлечение данных (PostGIS, OSM);
  2. генерализация;
  3. упаковка в PBF;
  4. публикация через HTTP/CDN.

Интеграция с MapLibre GL JS API

Ключевые методы взаимодействия:

map.addSource()
map.getSource()
map.removeSource()
map.isSourceLoaded()

Работа с источником обычно сопровождается управлением слоями:

map.addLayer()
map.moveLayer()
map.removeLayer()

Источник и слой связаны только через имя источника, что позволяет переиспользовать один vector source в разных визуальных представлениях одновременно.