QuerySourceFeatures

Метод querySourceFeatures предоставляет доступ к геометрическим и атрибутивным объектам, загруженным в конкретный источник данных MapLibre GL JS, независимо от того, отображаются они на текущем экране или нет. Это ключевой инструмент для работы с векторными тайлами и GeoJSON-источниками на уровне исходных данных, а не рендеринга.

querySourceFeatures используется для извлечения данных напрямую из источника слоя (source), минуя стадию отрисовки. Это позволяет работать с полной выборкой объектов, включая те, которые:

  • находятся за пределами текущего viewport
  • отфильтрованы стилем и не рендерятся
  • принадлежат тайлам, которые загружены, но не видимы

Метод ориентирован на анализ данных, а не визуальное взаимодействие.

Сигнатура

map.querySourceFeatures(sourceId, parameters)

Где:

  • sourceId — строка, идентификатор источника данных
  • parameters — объект параметров фильтрации (необязательный)

Параметры

Объект parameters может содержать следующие поля:

  • sourceLayer — имя слоя внутри векторного тайла (обязательно для vector sources)
  • filter — выражение фильтра MapLibre GL JS для отбора фич

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

{
  sourceLayer: "roads",
  filter: ["==", "class", "primary"]
}

Источники данных

Метод работает только с уже загруженными данными источников:

Vector tiles (vector source) Используются для больших наборов данных, разбитых на тайлы. Требуют указания sourceLayer.

GeoJSON source Работает с локальными или удалёнными GeoJSON-данными, обычно без sourceLayer.

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

Фильтр задаётся в формате выражений MapLibre GL JS, аналогично стилевым фильтрам слоёв.

Примеры операторов:

  • сравнение: ==, !=, >, <
  • логика: all, any, none
  • принадлежность: in

Пример:

map.querySourceFeatures("cities", {
  filter: [">", ["get", "population"], 1000000]
});

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

Различие с queryRenderedFeatures

querySourceFeatures и queryRenderedFeatures часто используются вместе, но работают на разных уровнях.

querySourceFeatures:

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

queryRenderedFeatures:

  • работает с уже отрисованными объектами
  • учитывает стиль, слои, zoom, visibility
  • возвращает только то, что видно пользователю

Ключевое различие заключается в том, что querySourceFeatures игнорирует визуальное представление.

Примеры использования

Получение всех дорог определённого типа:

const roads = map.querySourceFeatures("transport", {
  sourceLayer: "roads",
  filter: ["==", "type", "highway"]
});

Получение всех объектов GeoJSON:

const features = map.querySourceFeatures("points-of-interest");

Фильтрация по числовому атрибуту:

const largeBuildings = map.querySourceFeatures("buildings", {
  sourceLayer: "footprint",
  filter: [">=", ["get", "floors"], 10]
});

Особенности работы с vector tiles

Векторные тайлы загружаются фрагментами, поэтому:

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

Это означает, что результат может быть неполным при быстром зуме или перемещении карты.

Ограничения

Метод имеет ряд архитектурных ограничений:

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

Производительность

querySourceFeatures может быть ресурсоёмким при:

  • большом количестве загруженных тайлов
  • сложных фильтрах
  • частых вызовах в обработчиках событий (например, move или render)

Рекомендуемые практики:

  • кэширование результатов при повторных запросах
  • ограничение частоты вызова через debounce/throttle
  • использование более узких фильтров вместо пост-обработки результата

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

Метод часто используется для задач пространственного анализа:

Агрегация объектов:

const parks = map.querySourceFeatures("landuse", {
  sourceLayer: "parks"
});

const count = parks.length;

Поиск объектов по атрибутам без визуального слоя:

const hospitals = map.querySourceFeatures("amenities", {
  sourceLayer: "poi",
  filter: ["==", ["get", "type"], "hospital"]
});

Подсчёт статистики по данным тайлов:

const buildings = map.querySourceFeatures("cadastre", {
  sourceLayer: "buildings"
});

const total = buildings.reduce((sum, f) => {
  return sum + (f.properties.area || 0);
}, 0);

Поведение при обновлении карты

Результаты querySourceFeatures динамически зависят от состояния карты:

  • после setStyle кэш тайлов сбрасывается
  • при изменении zoom пересчитываются загруженные тайлы
  • при панорамировании меняется набор доступных данных

Это делает метод чувствительным к текущему состоянию рендеринга источников.

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

В случае GeoJSON источников поведение более предсказуемо:

  • данные обычно загружаются целиком
  • фильтрация применяется ко всему набору сразу
  • результаты стабильны при одинаковом состоянии источника
map.querySourceFeatures("geojson-data", {
  filter: ["!=", ["get", "status"], "inactive"]
});

Сложные фильтры и логические выражения

Комбинирование условий позволяет строить сложные выборки:

map.querySourceFeatures("real-estate", {
  sourceLayer: "properties",
  filter: [
    "all",
    [">", ["get", "price"], 100000],
    ["<", ["get", "price"], 500000],
    ["==", ["get", "type"], "apartment"]
  ]
});

Такие конструкции позволяют реализовывать полноценные аналитические запросы без внешней обработки данных.

Взаимодействие с другими API MapLibre GL JS

Метод часто используется совместно с:

  • getSource() — для доступа к объекту источника
  • queryRenderedFeatures() — для визуального анализа
  • on('click') — для обработки пользовательских взаимодействий
  • setFilter() — для синхронизации логики и стиля

Комбинация этих методов позволяет разделять аналитическую и визуальную логику приложения.