Webgl / use feature index for hit detection in points layer

For each feature its opacity value index is encoded on 4 bytes
in the color values, and the uid is stored in the opacity
value, allowing for a much higher range of uids to be read.
This commit is contained in:
jahow
2019-06-19 15:06:24 +02:00
committed by Olivier Guyot
parent 28b99767f8
commit 3bca9b5297
+11 -3
View File
@@ -493,6 +493,8 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
color color
); );
// for hit detection, the feature uid is saved in the opacity value
// and the index of the opacity value is encoded in the color values
elementIndex = writePointFeatureInstructions( elementIndex = writePointFeatureInstructions(
this.hitRenderInstructions_, this.hitRenderInstructions_,
elementIndex, elementIndex,
@@ -503,9 +505,9 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
u1, u1,
v1, v1,
size, size,
opacity, opacity > 0 ? Number(getUid(feature)) : 0,
rotateWithView, rotateWithView,
colorEncodeId(parseInt(getUid(feature)), tmpColor) colorEncodeId(elementIndex + 7, tmpColor)
); );
} }
@@ -534,6 +536,10 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
* @inheritDoc * @inheritDoc
*/ */
forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback, declutteredFeatures) { forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback, declutteredFeatures) {
if (!this.hitRenderInstructions_) {
return;
}
const pixel = applyTransform(frameState.coordinateToPixelTransform, coordinate.slice()); const pixel = applyTransform(frameState.coordinateToPixelTransform, coordinate.slice());
const data = this.hitRenderTarget_.readPixel(pixel[0], pixel[1]); const data = this.hitRenderTarget_.readPixel(pixel[0], pixel[1]);
@@ -543,7 +549,9 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
data[2] / 255, data[2] / 255,
data[3] / 255 data[3] / 255
]; ];
const uid = colorDecodeId(color).toString(); const index = colorDecodeId(color);
const opacity = this.hitRenderInstructions_[index];
const uid = Math.floor(opacity).toString();
const source = this.getLayer().getSource(); const source = this.getLayer().getSource();
const feature = source.getFeatureByUid(uid); const feature = source.getFeatureByUid(uid);