Работа с пространственными запросами в Mapbox GL JS опирается на взаимодействие с уже отрисованными векторными данными, геометрией на карте и внутренним пространственным индексом рендерера. Основная цель таких запросов — извлечение объектов карты по координатам, области экрана или географическому охвату без обращения к серверу.
Mapbox GL JS хранит отрисованные данные в виде тайлового векторного слоя, где каждый слой разбит на геометрические фрагменты. При рендере создаётся пространственный индекс, позволяющий выполнять быстрые запросы по экранным координатам.
Ключевые особенности:
Пространственные операции в библиотеке реализуются через методы
объекта карты, прежде всего через queryRenderedFeatures и
querySourceFeatures.
Метод позволяет получить объекты, находящиеся в конкретной точке или области экрана.
Сигнатура:
map.queryRenderedFeatures(point, options);
Параметры:
point — координаты в пикселях {x, y};options — фильтрация по слоям и атрибутам.Пример получения объектов под курсором:
map.on('click', (e) => {
const features = map.queryRenderedFeatures(e.point);
console.log(features);
});
Каждый элемент результата содержит:
geometry — геометрия объекта;properties — атрибуты;layer — слой, из которого получен объект;source — источник данных.При работе с большими наборами данных важно ограничивать область поиска:
const features = map.queryRenderedFeatures(point, {
layers: ['roads', 'buildings']
});
Фильтрация снижает нагрузку и ускоряет выполнение запроса за счёт сокращения области поиска в рендер-дереве.
Запрос объектов внутри прямоугольника экрана используется для выделения областей, перетаскивания и анализа сцены.
const bbox = [
[100, 100],
[300, 300]
];
const features = map.queryRenderedFeatures(bbox);
Bounding box интерпретируется как экранный прямоугольник, что делает операцию независимой от географических координат.
Типичные сценарии:
В отличие от queryRenderedFeatures, этот метод работает
с исходными данными слоя до рендеринга.
const features = map.querySourceFeatures('my-source', {
sourceLayer: 'buildings'
});
Особенности:
Mapbox GL JS работает в экранной системе координат, поэтому для географических операций требуется преобразование:
const point = map.project([lng, lat]);
Обратное преобразование:
const lngLat = map.unproject([x, y]);
Эти методы используются для:
При вызове queryRenderedFeatures используется механизм
проверки попадания точки в геометрию.
Для линий применяется буферизация, зависящая от
line-width и line-gap-width, а также текущего
масштаба.
Результаты пространственных запросов возвращаются в порядке визуального наложения слоёв.
Принцип:
style layers order).Это критично для задач выбора объектов, так как первый результат часто интерпретируется как «верхний» объект под курсором.
Mapbox GL JS поддерживает фильтрацию результатов через параметры запроса и постобработку.
const features = map.queryRenderedFeatures(point, {
filter: ['==', ['get', 'type'], 'park']
});
Используется expression syntax Mapbox Style Specification.
const features = map.queryRenderedFeatures(point)
.filter(f => f.properties.population > 10000);
Постфильтрация применяется, когда логика слишком сложна для выражений стиля.
События карты автоматически передают координаты, что позволяет сразу выполнять запросы.
map.on('mousemove', (e) => {
const features = map.queryRenderedFeatures(e.point);
});
map.on('click', (e) => {
const features = map.queryRenderedFeatures(e.point, {
layers: ['cities']
});
});
Типичный сценарий — определение объекта под курсором и изменение интерфейса.
В случае наложения нескольких объектов возвращается массив:
Стратегии обработки:
queryRenderedFeatures в
mousemove требуют оптимизации;map.queryRenderedFeatures(point, {
layers: ['important-layer']
});
let timeout;
map.on('mousemove', (e) => {
clearTimeout(timeout);
timeout = setTimeout(() => {
map.queryRenderedFeatures(e.point);
}, 50);
});
Использование точек вместо больших bounding box снижает нагрузку на spatial index.
Mapbox GL JS позволяет комбинировать пространственные запросы с динамическим состоянием объектов:
map.setFeatureState(
{ source: 'places', id: 1 },
{ hover: true }
);
После этого пространственные запросы могут учитывать состояние через фильтры или стили.
Типичный сценарий сложной логики:
const features = map.queryRenderedFeatures(e.point, {
layers: ['roads', 'buildings']
});
const selected = features.find(f => f.properties.important === true);
Векторные тайлы влияют на точность результатов:
Это особенно важно при работе с полигонами и тонкими линиями.
Mapbox GL JS использует:
Переход между системами происходит автоматически при вызовах
project и unproject, а также внутри
queryRenderedFeatures.
const features = map.queryRenderedFeatures(e.point, {
layers: ['pois']
});
const nearest = features.sort((a, b) => {
return distance(a, e.point) - distance(b, e.point);
})[0];
const grouped = features.reduce((acc, f) => {
const type = f.properties.type;
acc[type] = acc[type] || [];
acc[type].push(f);
return acc;
}, {});
Использование запросов позволяет строить:
Каждый из этих сценариев основан на постоянном выполнении
queryRenderedFeatures в зависимости от положения курсора
или состояния камеры.