I am using the following expression to visualize with a buffer, the nearest neighbors at a given distance:
case when
distance(
$geometry,
array_get(
overlay_nearest(
layer:=@layer,
expression:=$geometry,
limit:=2
),
1
)
)<0.9
then
with_variable(
'dista',
distance(
$geometry,
array_get(
overlay_nearest(
layer:=@layer,
expression:=$geometry,
limit:=2
),
1
)
),
collect_geometries (
array_foreach (
overlay_nearest(
@layer,
$geometry,
limit:=1
),
buffer(@element,@dista/1)
)
)
)
end
Screenshot:
I have developed this expression from the solutions presented by user Babel in the questions Clustering vectorpoints and Dissolve buffers if the intersection/overlap is greater than 50%.
My goal is to label count points within dissolved buffers.
Here is a handmade screenshot of the expected idea of counting points within dissolved buffers:
Implementing the solution proposed by user Babel:
For the label, I have adapted the constant buffer radius to a variable buffer radius according to distance:
case when
distance(
$geometry,
array_get(
overlay_nearest(
layer:=@layer,
expression:=$geometry,
limit:=2
),
1
)
)<0.9
then
with_variable(
'radius',
0.45, -- change buffer size here
array_length(
array_agg(
$id,
group_by:= array_foreach (
generate_series (
0,
array_length(
geometries_to_array(
buffer (
collect(
buffer ($geometry, @radius)
),
0
)
)
)-1
),
intersects (
$geometry,
geometries_to_array(
buffer (
collect(
buffer ($geometry, @radius)
),
0
)
)[@element]
)
)
)
)
)
end
For the label placement properties (avoid text repetitions), I do something messy (copy/paste the same expression and injecting the centroid function):
with_variable(
'radius',
0.45, -- change buffer size here
centroid (
collect(
$geometry,
group_by:= array_foreach (
generate_series (
0,
array_length(
geometries_to_array(
buffer (
collect(
buffer ($geometry, @radius)
),
0
)
)
)-1
),
intersects (
$geometry,
geometries_to_array(
buffer (
collect(
buffer ($geometry, @radius)
),
0
)
)[@element]
)
)
)
)
)
At the beginning the objective is achieved, but now the problem is the expression performance. For a layer with 57 points geometry, the labeling and the placement expressions needs 3 minutes to finish with an i7 processor (32GB RAM). I think it is too long for a layer with little information.
I would like, if possible, to ask for optimize a little more the efficiency of the first solution.
make_line()
and thendistance()
when you can just usedistance()
directly on two points? And why usearray_foreach()
- twice - when theoverlay_nearest()
is limited to 1 result? And theif()
test seems unnecessary, of course the distance to the closest feature will be less than that of the second-closest feature (i.e.@dista
variable - index 1 of array). But from your first screenshot it appears your buffers are generated lines, not polygons...if
test for now. You can see the updated code in my question. At the moment I can't remove one of thearray_foreach()
nor themake_line()
. However, the expression that draws the buffers is fast. The efficiency problem is focused more on the labeling expression