3

With the following expression presented in the question (Creating the minimum convex hull that contains certain percentage of points in QGIS) it is possible to calculate the closest distances between groups of points:

array_sum ( 
    array_foreach (
        overlay_nearest( 
            @layer, 
            $geometry, 
            limit:=2
        ),
        length (
            make_line (
                $geometry, 
                @element
            )
        )
    )
)

In the following screenshot I show the manual selection of the 20 points with the shortest distances from a total of 241 points (field "LONU"):

enter image description here

I would like to reuse this expression to build a Geometry Generator expression that:

1 → Selects the 20 shortest distances

2 → Finds a 4 groups of 3 closest points from this selection

3 → Draws the minimal_circle of each group

My goal is to reuse the above function to build an expression with the Geometry Generator that generates a geometry object like a minimal_circle from a 4 series of groups based on the distances and proximity between points. I show a screenshot with a simulation of the desired target:

enter image description here

My first approach (doesn't work):

with_variable(
    'min',
    array_sort (array_agg (LONU),0)[20],
with_variable(
    'value',
    4,
    make_line(
        $geometry,
        eval (
            'overlay_nearest (
                @layer, 
                $geometry, 
                filter:= LONU =' ||@min||' and || @value || ')[0]
    )
)
)

This expression doesn't work but I think it can give an idea of what I'm working on. Note that, at the moment, I try to draw a line but I would like to draw a minimal_circle or a convex_hull.

1 Answer 1

2

Calculate the sum of the distances to nearest 3 points for each of the first 20 shortest distances from the LONU field.

if(
    array_find(
        array_agg($id, order_by:="LONU"),
        $id
    ) BETWEEN 0 AND 19,
    array_sum( 
        array_foreach(
            overlay_nearest( 
                @layer, 
                $geometry, 
                limit:=3
            ),
            distance(
                $geometry, 
                @element
            )
        )
    ),
    NULL
)

Only the first 20 distances will return a number the other lines will get a NULL value.
And now take the four groups. Use this in the Geometry by expression tool to create the final polygons.

if(
    array_find(
        aggregate(
            'Point layer name / id', -- set here point layer name
            'array_agg',
            $id,
            filter:=not ("distance 20" is NULL) -- replace distance 20 with the name of the field where you stored the past calculation
            order_by:="distance 20" -- set here the name of the field where you stored the past calculation
        ),
        $id
    ) BETWEEN 0 AND 3,
    minimal_circle(
        collect_geometries(
            overlay_nearest(
                'Point layer name / id', -- set here point layer name
                $geometry,
                limit:=4
            )
        )
    ),
    NULL
)

this all the features of the original layer but only the 4 groups will have geometry, so you can remove the remaining records with the remove null geometries tool.

1
  • 1
    A proposed solution that captures exactly the essence of the target I was looking for: a vector visualization model of hotspots, where there is a higher density of activity Oct 5, 2023 at 6:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.