6

Starting from a layer with point geometry, my goal is to do two calculations in one Geometry Generator expression.

First, for each point, I would like to calculate the centroid for the 5 points nearest to it.

Next, for each calculated centroid I would like to draw the 10 nearest lines connecting to it.

To calculate the centroid I am working with the following expression:

centroid(collect_geometries (
        array_foreach (
            overlay_nearest (
                'TEST',
                $geometry,
                limit:=5
            ),
            make_line (
                $geometry,
                @element
            )
        )
    ))

To draw the line I used this expression:

collect_geometries (
    array_foreach (
        overlay_nearest (
            'CENTRO',
            $geometry,
            limit:=10
        ),
        make_line (
            $geometry,
            @element
        )
    )
)

Result:

enter image description here

My goal is to unify the two expressions in a single expression for the Geometry Generator that works with the original layer.

1 Answer 1

3

There are several things regarding your expression:

  • This is the most critical point, that has to do with the overlay_nearest() function. It will also consider the same feature as a closest taken from the same layer. See this thread for more details: QGIS expression: when using overlay_nearest sometimes a feature considers itself its nearest neighbour. It also refers to a QGIS discussion on the GitHub
  • For each point, you are attempting to calculate the centroid for the 5 points nearest to it. However, in your first expression, you are calculating the centroid for five lines instead, init?
  • Keep in mind, that for a vast data set, one should think of a better approach, even with a spatial index
  • Number of input points: N, number of centroids: N, number of lines N*10

Let's assume there is a point layer called 'points_in_polygon' (N=10), see the image below:

input

After using this expression:

collect_geometries(
    array_foreach(
        array_remove_at(
            overlay_nearest(
                layer:='points_in_polygon', -- change accordingly
                expression:=centroid(
                            collect_geometries(
                                array_remove_at(
                                    overlay_nearest(
                                        layer:='points_in_polygon', -- change accordingly
                                        expression:=$geometry,
                                        limit:=6 -- change correspondingly
                                        ),
                                    0)
                                )
                            ),
                limit:=11 -- change correspondingly
                ),
            0),
        make_line(
            @element,
            centroid(
                collect_geometries(
                    array_remove_at(
                        overlay_nearest(
                            layer:='points_in_polygon', -- change accordingly
                            expression:=$geometry,
                            limit:=6 -- change correspondingly
                            ),
                        0)
                    )
                )
            )
        )
    )

The above expression is sure can be optimized with the with_variable() to avoid double writings.

Afterwards, apply the "Multipart to singleparts" geoalgorithm.

And get the output like this (N=120):

output

Usage of the "Delete duplicate geometries" can also be feasible.

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.