The CollisionFilterExtension
allows layers to hide features which overlap with other features. An example is a dense ScatterplotLayer
with many points which overlap: by using this extension points that collide with others are hidden such that only one of the colliding points is shown. The collisions are computed on the GPU in realtime, allowing the collisions to be updated smoothly on every frame.
To use this extension on a layer, add the CollisionFilterExtension
to the layer's extensions
prop.
import {ScatterplotLayer} from '@deck.gl/layers';
import {CollisionFilterExtension} from '@deck.gl/extensions';
const layer = new ScatterplotLayer({
id: 'points',
data: points,
extensions: [new CollisionFilterExtension()],
getPosition: d => d.COORDINATES,
getRadius: 10,
radiusUnits: 'pixels'
})
To install the dependencies from NPM:
npm install deck.gl
# or
npm install @deck.gl/core @deck.gl/extensions
import {CollisionFilterExtension} from '@deck.gl/extensions';
new CollisionFilterExtension();
To use pre-bundled scripts:
<script src="https://unpkg.com/deck.gl@^9.0.0/dist.min.js"></script>
<!-- or -->
<script src="https://unpkg.com/@deck.gl/core@^9.0.0/dist.min.js"></script>
<script src="https://unpkg.com/@deck.gl/extensions@^9.0.0/dist.min.js"></script>
new deck.CollisionFilterExtension();
new CollisionFilterExtension();
When added to a layer via the extensions
prop, the CollisionFilterExtension
adds the following properties to the layer:
Enable/disable collisions. If collisions are disabled, all objects are rendered. Defaults to true
.
Collision group this layer belongs to. If it is not set, the 'default' collision group is used. Two (or more) layers that share the same collisionGroup
will be considered together when calculating collisions.
For example, here the icon and text features will avoid colliding with each other, but permits collisions with the scatterplot features.
const layers = [
new ScatterplotLayer({
...,
extensions: [new CollisionFilterExtension()],
collisionGroup: 'visualization'
}),
new IconLayer({
...,
extensions: [new CollisionFilterExtension()],
collisionGroup: 'legend'
}),
new TextLayer({
...,
extensions: [new CollisionFilterExtension()],
collisionGroup: 'legend'
})
];
Props to override when computing collisions. A common use case is to increase the size of the features when computing collisions to provide greater spacing between visible features. For the ScatterplotLayer
this would be done by:
collisionTestProps: {radiusScale: 2}
getCollisionPriority
(Accessor<number>, optional) {#getcollisionpriority}
The collision priority of each object. Features with higher values are shown preferentially. The priority is a number in the range -1000 -> 1000, values outside will be clamped.
- If a number is provided, it is used for all objects in the layer.
- If a function is provided, it is called on each object to retrieve its priority.
The CollisionFilterExtension
samples at the anchor point of a feature when calculating collisions. Layers must ensure that a pixel is rendered at this location when the picking pass is drawn.
A common issue is with the IconLayer
, which discards transparent pixels. To avoid this, use alphaCutoff: -1
. A similar issue occurs when the anchor point of the IconLayer
is too close to the edge of the image, to be safe include a few pixels of padding, e.g.
iconMapping: {
marker: {x: 0, y: 0, width: 128, height: 128, anchorY: 124}
}
- Accessors are not supported in
collisionTestProps
- Given that collisions is performed on the GPU, the layers of
@deck.gl/aggregation-layers
module that does aggregation on the CPU, for exampleCPUGridLayer
andHexagonLayer
, are not supported. - The collision is point-in-polygon, specifically is computed by comparing the anchor point of a feature with the rasterized screen-space areas of other features. While good for realtime applications, generally this will not give the same results as a full collision test would.