The problem
In QGIS 3.20.0 (Win 10), I have an expression that does not work as expected and I don't understand why. On a point layer, one point is selected. When using Select by expression, the expression should select the N (freely definable number) nearest neighboring points.
Download the QGIS project with layers that show what I tried and for testing my expressions.
What I tried
I created an expression based on two elements (see the expressions below):
Get the geometry of the selected point. Check the layer
points_selectionin the project I linked to see that this works: selected points get a red ring around them. Create this as variable@selected_point.Create a circle around each point with the radius such that it reaches to point furthest away of the
Nnearest neighbors, whereNis the number defined in line 8 (here:3). Thus the circle covers allNneighbors. The radius is multiplied by 1.01 to get a small buffer around the circle to be sure that the furthest points falls within that circle and not on its boundary. Check the layerpoints_circlein the linked project: you see that a circle is created. Create this as variable@circle.
As you can see in the linked project, both elements work as expected. You can also check the layer points_line: if you select a point, lines to the K nearest neighbors are drawn.
What doesn't work
The idea is now to combine these two elements using the expression within (@selected_point, @circle), where @selected_point and @circle are the variables created with the expressions from steps 1 and 2. The within function should return true for those features (points) where the selected point (@selected_point, step 1) is within the circle (@circle) around the current feature's geometry.
The question
What went wrong with the expression: why doesn't it work as expected (see also screenshot at the bottom)?
The expressions
- Selected Point
geometry (
get_feature_by_id (
@layer,
array_first(
aggregate(
@layer,
'array_agg',
$id,
filter:=is_selected( )
)
)
)
)
- Circle around point:
make_circle (
$geometry,
array_max(
array_foreach (
overlay_nearest (
@layer,
$geometry,
limit:=3
),
length (
make_line (
$geometry,
@element
)
)
)
)*1.01,
200
)
- Defining both elements as variables and stick them together with
within- the whole expression looks like this:
with_variable (
'selected_pt',
geometry (
get_feature_by_id (
@layer,
array_first(
aggregate(
@layer,
'array_agg',
$id,
filter:=is_selected( )
)
)
)
),
with_variable (
'circle',
make_circle (
$geometry,
array_max(
array_foreach (
overlay_nearest (
@layer,
$geometry,
limit:=9
),
length (
make_line (
$geometry,
@element
)
)
)
)*1.01,
200
),
within (
@selected_pt,
@circle
)
)
)
Screenshot: setting the limit to 9 nearest neighbors as argument of overlay_nearest, I here still get 12 features selected (the already selected point + 11 neighbors). As you see, there are points selected further away that are selected and others, closer, that are not selected. Both (number of points and which points are selected) does not correspond to what I expect:

