В Mapbox GL JS данные карты поступают из тайловых источников, которые представляют собой структурированные наборы геоданных, разбитые по координатной сетке и уровням масштабирования. Основной принцип работы заключается в том, что вместо загрузки всей геометрии сразу система запрашивает только те фрагменты данных, которые соответствуют текущему виду карты: области экрана и уровню зума.
Тайлы векторного типа представляют собой бинарные фрагменты (обычно формата MVT — Mapbox Vector Tile), содержащие геометрию и атрибуты объектов. Каждый тайл описывает фиксированную область мира в координатной системе плитки (z/x/y).
Источники данных задаются в стиле карты через
sources:
map.addSource('cities', {
type: 'vector',
tiles: [
'https://example.com/tiles/{z}/{x}/{y}.pbf'
],
minzoom: 0,
maxzoom: 14
});
Ключевые параметры источника:
Система Mapbox GL JS интерпретирует {z}/{x}/{y} как
координаты тайла в глобальной пирамиде.
При изменении состояния карты (панорамирование, масштабирование) происходит пересчет видимой области. Далее выполняется:
Каждый тайл разбивается на слои внутри векторного источника. Эти слои соответствуют логическим наборам данных (например, roads, buildings, water).
Векторные тайлы используют координатную систему с фиксированным экстентом, чаще всего 4096 единиц на сторону:
Эта система позволяет унифицировать геометрию независимо от глобальных координат.
Mapbox GL JS преобразует географические координаты в координаты тайла через проекцию Web Mercator.
Одним из ключевых механизмов работы с тайловыми данными является доступ к уже загруженным и отрендеренным объектам.
Этот метод извлекает данные, которые уже попали в текущий рендеринг WebGL:
map.on('click', (e) => {
const features = map.queryRenderedFeatures(e.point, {
layers: ['cities-layer']
});
console.log(features);
});
Особенности:
Параметр point соответствует пиксельной координате
внутри canvas, а не географической.
Также возможно запросить область:
const features = map.queryRenderedFeatures([
[0, 0],
[300, 300]
]);
Для получения данных до стадии рендеринга используется
querySourceFeatures:
const features = map.querySourceFeatures('cities', {
sourceLayer: 'urban_areas'
});
Отличие от рендеренного запроса:
Важно учитывать, что querySourceFeatures работает только
с уже загруженными тайлами и не инициирует сетевые запросы.
Векторный тайл содержит набор слоёв, определённых на стороне генерации данных. Каждый слой имеет:
roads)Пример обращения к слою:
map.addLayer({
id: 'roads-line',
type: 'line',
source: 'cities',
'source-layer': 'roads',
paint: {
'line-color': '#ff0000',
'line-width': 2
}
});
Фильтрация может происходить на нескольких уровнях:
map.setFilter('roads-line', ['==', ['get', 'type'], 'highway']);
map.queryRenderedFeatures(e.point, {
layers: ['roads-line'],
filter: ['==', ['get', 'class'], 'primary']
});
Фильтры используют expression language Mapbox Style Specification.
Feature State позволяет хранить динамическое состояние объектов, не изменяя исходные тайлы:
map.setFeatureState(
{ source: 'cities', id: 123 },
{ selected: true }
);
Особенности:
Для корректной работы требуется наличие promoteId или
id в данных источника.
Для эффективной работы с тайловыми данными важно наличие стабильных идентификаторов:
map.addSource('cities', {
type: 'vector',
tiles: ['https://example.com/{z}/{x}/{y}.pbf'],
promoteId: 'id'
});
Без идентификаторов невозможно корректно использовать feature-state и оптимизированные обновления.
При запросе данных Mapbox GL JS учитывает пересечение тайлов с viewport. Геометрия может быть разбита между несколькими тайлами, поэтому один и тот же объект может появляться в нескольких запросах.
Для обработки таких случаев:
idХотя основное внимание уделяется векторным данным, растровые тайлы также участвуют в системе:
map.addSource('satellite', {
type: 'raster',
tiles: [
'https://example.com/tiles/{z}/{x}/{y}.png'
],
tileSize: 256
});
В отличие от векторных, растровые тайлы:
Mapbox GL JS использует многоуровневый кэш:
Это позволяет:
При повторном посещении области тайлы часто берутся из памяти без сетевого запроса.
Обработка тайловых данных вынесена в отдельные потоки:
Основной поток отвечает только за управление состоянием карты и пользовательские события.
Взаимодействие с тайлами часто опирается на преобразование координат:
const lngLat = map.unproject([x, y]);
const point = map.project([lng, lat]);
Это позволяет связывать пиксельные координаты интерфейса с географическими данными внутри тайловой системы.
При изменении источника данных:
map.getSource('cities').setTiles([
'https://example.com/new-tiles/{z}/{x}/{y}.pbf'
]);
или при вызове:
map.getSource('cities').setData(geojson);
происходит перерасчет тайлового дерева и перезагрузка затронутых областей.
Каждый уровень zoom определяет плотность и детализацию данных:
Источник может возвращать разные наборы данных в зависимости от
{z} в URL шаблоне.
При отрисовке нескольких источников важен порядок слоёв:
Это позволяет комбинировать несколько наборов тайлов в единую карту.
Система накладывает ряд ограничений: