Picking в Deck.gl представляет собой систему определения объектов сцены, находящихся под курсором или в заданной экранной области. В основе лежит GPU-based выбор объектов, при котором каждый интерактивный элемент получает уникальную идентификацию в offscreen-буфере, позволяя быстро и точно определять попадания без перебора данных на CPU.
Механизм picking интегрирован в рендер-пайплайн и работает на уровне слоёв (layers), поддерживая как простые геометрии, так и сложные агрегированные структуры.
Каждый объект, который может участвовать в выборе, рендерится в специальном режиме в скрытый буфер. Вместо привычного цвета используется закодированный идентификатор объекта.
Ключевые особенности:
readPixelsЭтот подход обеспечивает:
Для того чтобы объект стал доступен для выбора, слой должен
поддерживать и включать параметр pickable.
import {Deck} from '@deck.gl/core';
import {ScatterplotLayer} from '@deck.gl/layers';
const layer = new ScatterplotLayer({
id: 'points',
data: points,
pickable: true,
getPosition: d => d.position,
getRadius: 100,
getFillColor: [255, 0, 0]
});
При отсутствии pickable: true слой полностью исключается
из picking-прохода.
Deck.gl предоставляет высокоуровневые события, через которые возвращается информация о выбранном объекте.
const layer = new ScatterplotLayer({
id: 'points',
data,
pickable: true,
onHover: info => {
const {object, x, y, coordinate, layer} = info;
if (object) {
console.log('Hover object:', object);
console.log('Screen coords:', x, y);
console.log('Geo coords:', coordinate);
}
}
});
Структура info:
object — выбранный объект данныхindex — индекс в массиве datax, y — координаты курсора в пикселяхcoordinate — географические координаты (если
применимо)layer — ссылка на слойcolor — picking color (внутреннее использование)const layer = new ScatterplotLayer({
id: 'points',
data,
pickable: true,
onClick: info => {
if (info.object) {
console.log('Clicked:', info.object);
}
}
});
Click-событие использует тот же механизм picking, но фиксирует событие при нажатии мыши.
Помимо событий слоёв, Deck.gl предоставляет низкоуровневые методы API.
const info = deck.pickObject({x: 100, y: 200});
console.log(info.object);
Возвращает ближайший объект под координатами.
Используется для получения всех объектов в пиксельной области:
const infos = deck.pickMultipleObjects({x: 100, y: 200, radius: 5});
Особенно полезно при плотных данных, где несколько объектов перекрывают друг друга.
const infos = deck.pickObjects({x: 100, y: 200});
Возвращает все объекты, включая из разных слоёв, упорядоченные по глубине.
Результат любого picking-запроса имеет унифицированную структуру:
{
object,
index,
layer,
sourceLayer,
x,
y,
coordinate,
color
}
Особенности:
sourceLayer полезен для composite layerscoordinate зависит от проекции слояlayer может отличаться от sourceLayer в
сложных слояхDeck.gl поддерживает автоматическую подсветку через
autoHighlight.
const layer = new ScatterplotLayer({
id: 'points',
data,
pickable: true,
autoHighlight: true,
highlightColor: [0, 255, 0, 180]
});
Механизм работает через внутренний state слоя и не требует ручного управления.
В реальных сценариях курсор редко попадает точно в центр объекта. Для этого используется радиус выбора.
const layer = new ScatterplotLayer({
id: 'points',
data,
pickable: true,
pickable: true,
radiusMinPixels: 5
});
На уровне API:
deck.pickMultipleObjects({
x: 100,
y: 100,
radius: 10
});
Радиус расширяет область поиска в экранных координатах.
При наличии перекрывающихся объектов используется depth buffer. Deck.gl учитывает z-index сцены и выбирает ближайший объект к камере.
Особенности:
Composite layers (например, GeoJsonLayer) агрегируют множество подслоёв. Picking в этом случае проходит через цепочку:
import {GeoJsonLayer} from '@deck.gl/layers';
const layer = new GeoJsonLayer({
id: 'geojson',
data,
pickable: true,
onClick: info => {
console.log(info.object);
}
});
В info.object может находиться feature GeoJSON.
Слои вроде HexagonLayer или GridLayer
возвращают не исходные объекты, а агрегаты.
import {HexagonLayer} from '@deck.gl/aggregation-layers';
const layer = new HexagonLayer({
id: 'hex',
data,
pickable: true,
getPosition: d => d.position,
getElevationWeight: d => d.value,
onHover: info => {
console.log(info.object.points);
}
});
Особенности:
object содержит агрегированные данныеpoints)В MVTLayer picking работает на уровне тайлов и векторных
фич.
import {MVTLayer} from '@deck.gl/geo-layers';
const layer = new MVTLayer({
id: 'mvt',
data: 'https://tiles/{z}/{x}/{y}.pbf',
pickable: true,
onClick: info => {
console.log(info.object.properties);
}
});
Особенности:
При работе с большими наборами данных важны оптимизации.
Каждый pickable слой увеличивает нагрузку:
Рекомендуется включать picking только там, где он нужен.
Binary attributes позволяют ускорить рендер и picking:
data: {
length: n,
attributes: {
getPosition: {value: new Float32Array(...), size: 3}
}
}
Преимущества:
В некоторых слоях можно переопределить поведение через
getPickingInfo.
const layer = new ScatterplotLayer({
id: 'points',
data,
pickable: true,
getPickingInfo: ({info}) => {
return {
...info,
object: {
...info.object,
custom: true
}
};
}
});
Это позволяет:
Точность picking зависит от нескольких факторов:
Для точечных данных часто используются:
radiusPixelsminPixelSizeНесмотря на высокую эффективность, существуют ограничения:
Типовые сценарии:
Механизм остаётся единым, независимо от типа слоя: GPU-based идентификация с последующим сопоставлением данных на уровне Deck.gl runtime.