Pass geometry to forEachFeatureAtPixel callback

This commit is contained in:
Andreas Hocevar
2020-11-27 13:43:28 +01:00
parent 7b5f53753b
commit 28aaa2e0d3
12 changed files with 108 additions and 28 deletions

View File

@@ -355,19 +355,18 @@ class CanvasBuilder extends VectorContext {
* @param {import("../../Feature.js").FeatureLike} feature Feature.
*/
beginGeometry(geometry, feature) {
const extent = geometry.getExtent();
this.beginGeometryInstruction1_ = [
CanvasInstruction.BEGIN_GEOMETRY,
feature,
0,
extent,
geometry,
];
this.instructions.push(this.beginGeometryInstruction1_);
this.beginGeometryInstruction2_ = [
CanvasInstruction.BEGIN_GEOMETRY,
feature,
0,
extent,
geometry,
];
this.hitDetectionInstructions.push(this.beginGeometryInstruction2_);
}

View File

@@ -53,6 +53,11 @@ import {transform2D} from '../../geom/flat/transform.js';
* @typedef {{0: CanvasRenderingContext2D, 1: number, 2: import("../canvas.js").Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement, 3: ImageOrLabelDimensions, 4: number, 5: Array<*>, 6: Array<*>}} ReplayImageOrLabelArgs
*/
/**
* @template T
* @typedef {function(import("../../Feature.js").FeatureLike, import("../../geom/SimpleGeometry.js").default): T=} FeatureCallback
*/
/**
* @type {import("../../extent.js").Extent}
*/
@@ -597,7 +602,7 @@ class Executor {
* @param {import("../../transform.js").Transform} transform Transform.
* @param {Array<*>} instructions Instructions array.
* @param {boolean} snapToPixel Snap point symbols and text to integer pixels.
* @param {function(import("../../Feature.js").FeatureLike): T|undefined} featureCallback Feature callback.
* @param {FeatureCallback<T>|undefined} featureCallback Feature callback.
* @param {import("../../extent.js").Extent=} opt_hitExtent Only check features that intersect this
* extent.
* @param {import("rbush").default=} opt_declutterTree Declutter tree.
@@ -668,18 +673,19 @@ class Executor {
const batchSize =
this.instructions != instructions || this.overlaps ? 0 : 200;
let /** @type {import("../../Feature.js").FeatureLike} */ feature;
let x, y;
let x, y, currentGeometry;
while (i < ii) {
const instruction = instructions[i];
const type = /** @type {import("./Instruction.js").default} */ (instruction[0]);
switch (type) {
case CanvasInstruction.BEGIN_GEOMETRY:
feature = /** @type {import("../../Feature.js").FeatureLike} */ (instruction[1]);
currentGeometry = instruction[3];
if (!feature.getGeometry()) {
i = /** @type {number} */ (instruction[2]);
} else if (
opt_hitExtent !== undefined &&
!intersects(opt_hitExtent, instruction[3])
!intersects(opt_hitExtent, currentGeometry.getExtent())
) {
i = /** @type {number} */ (instruction[2]) + 1;
} else {
@@ -1048,7 +1054,7 @@ class Executor {
case CanvasInstruction.END_GEOMETRY:
if (featureCallback !== undefined) {
feature = /** @type {import("../../Feature.js").FeatureLike} */ (instruction[1]);
const result = featureCallback(feature);
const result = featureCallback(feature, currentGeometry);
if (result) {
return result;
}
@@ -1168,7 +1174,7 @@ class Executor {
* @param {CanvasRenderingContext2D} context Context.
* @param {import("../../transform.js").Transform} transform Transform.
* @param {number} viewRotation View rotation.
* @param {function(import("../../Feature.js").FeatureLike): T=} opt_featureCallback
* @param {FeatureCallback<T>} opt_featureCallback
* Feature callback.
* @param {import("../../extent.js").Extent=} opt_hitExtent Only check features that intersect this
* extent.

View File

@@ -161,7 +161,7 @@ class ExecutorGroup {
* @param {number} resolution Resolution.
* @param {number} rotation Rotation.
* @param {number} hitTolerance Hit tolerance in pixels.
* @param {function(import("../../Feature.js").FeatureLike): T} callback Feature callback.
* @param {import("./Executor.js").FeatureCallback<T>} callback Feature callback.
* @param {Array<import("../../Feature.js").FeatureLike>} declutteredFeatures Decluttered features.
* @return {T|undefined} Callback result.
* @template T
@@ -225,9 +225,10 @@ class ExecutorGroup {
/**
* @param {import("../../Feature.js").FeatureLike} feature Feature.
* @param {import("../../geom/SimpleGeometry.js").default} geometry Geometry.
* @return {?} Callback result.
*/
function featureCallback(feature) {
function featureCallback(feature, geometry) {
const imageData = context.getImageData(0, 0, contextSize, contextSize)
.data;
for (let i = 0; i < contextSize; i++) {
@@ -243,7 +244,7 @@ class ExecutorGroup {
) ||
declutteredFeatures.indexOf(feature) !== -1
) {
result = callback(feature);
result = callback(feature, geometry);
}
if (result) {
return result;