4

Starting from points layer with the fields "DISTANCE" and "CLUSTER_ID".

"DISTANCE" field stores the straight line distance value of each point relative to the 0,0 coordinate.

"CLUSTER_ID" field stores the Cluster id.

As you can see in the screenshot, each point is labeled with its distance "DISTANCE" and I also label each cluster with the mean distance with the following expression array_mean (array_agg ("DISTANCE", group_by:="CLUSTER_ID")):

enter image description here

My goal is to use the Geometry Generator to the points layer and with the computed mean distance value of each cluster id to draw, for each cluster id, an arc from coordinate 0,0 to the mean distance cluster id, as shown in the screenshot.

enter image description here

Babel user's solution applied:

enter image description here

Is it possible to cut the circle in a vertical half left side as shown in this handmade reproduction?

enter image description here

2
  • Should be possible using wedge buffer, what have you tried?
    – Bera
    Commented Jan 17 at 10:59
  • Yes, I think with the wedge_buffer object it might be possible to achieve this goal. I think the solution could be similar to the one proposed in the question [link]gis.stackexchange.com/questions/473510/… Unfortunately, my level of expressions development with wedge_buffer object is still very early and for this reason I haven't tried an own solution Commented Jan 17 at 11:07

1 Answer 1

6

Use make_circle() function with the point (0,0) as center and the mean distance as radius:

make_circle( 
    make_point (0,0),
    array_mean (array_agg ("DISTANCE", group_by:="CLUSTER_ID"))
)

You could also create a convex hull around each point cluster including the center, then intersect this hull with the circle to only get an arc:

Red: convex hull; blue line: intersection with circles: enter image description here

intersection (
    boundary(
        make_circle( 
                make_point (0,0),
                array_mean (array_agg ("DISTANCE", group_by:="CLUSTER_ID")),
        100
        )
    ),
    convex_hull( 
        union (
            geometry(get_feature_by_id ('center',1)),
            collect($geometry,group_by:=CLUSTER_ID)
        )
    )
)

For a half circle, use wedge_buffer():

 wedge_buffer( 
    make_point (0,0),
    90,
    180,
    array_mean (array_agg ("DISTANCE", group_by:="CLUSTER_ID"))
)

enter image description here

And from there, to get rid of the vertical lines on the left, intersect with the boundary of the circle:

with_variable (
    'dist',
    array_mean (array_agg ("DISTANCE", group_by:="CLUSTER_ID")), 
    intersection (
        boundary(
            make_circle( 
                make_point (0,0),
                @dist,
                100
            )
        ),
        wedge_buffer( 
            make_point (0,0),
            90,
            180,
            @dist
        )
    )
)

enter image description here


And to get only the arc for the angle where the points are distributed:

enter image description here

case
when $id = minimum ($id, group_by:="CLUSTER_ID")
then intersection (
    boundary(
        make_circle( 
            geometry(get_feature_by_id ('center',1)),
            array_mean (array_agg ("DISTANCE", group_by:="CLUSTER_ID")),
            100
        )
    ),
    with_variable(
        'azim',
        array_sort(
            array_foreach(
                geometries_to_array (
                    collect($geometry,group_by:=CLUSTER_ID)
                ),
                degrees(
                    azimuth(
                        geometry(get_feature_by_id ('center',1)),
                        @element
                    )
                )
            )
        ),
        wedge_buffer(
            geometry (get_feature_by_id ('center',1)),
            (@azim[-1]+@azim[0])/2,
            @azim[-1]-@azim[0],
            array_mean (array_agg ("DISTANCE", group_by:="CLUSTER_ID"))
        )
    )
)
end

Possible new capability or improvement

See here for a further improvement and an additional question by the initial OP of the question.

13
  • 1
    Excellent. Your convex_hull proposal greatly improves the visualization Commented Jan 17 at 13:44
  • 2
    get_feature_by_id exists since long time before 3.28, see e.g. here documentation for version 3.16: docs.qgis.org/3.16/en/docs/user_manual/working_with_vector/… Maybe typing error? In fact you could also replace this part of the expression with make_point (0,0) in your case is in the first example with the circle.
    – Babel
    Commented Jan 17 at 14:06
  • 2
    get_feature_by_id was introduced in QGIS 3.0 in Feb 2018 - 6 years from now. qgis.org/en/site/forusers/visualchangelog30/…
    – Babel
    Commented Jan 17 at 14:50
  • 1
    I confirm that I was making a typing error and I check that in my QGIS version I have available the function get_feature_by_id. I have managed to implement your solutions Commented Jan 17 at 17:37
  • 1
    @Acperience This is simply the wedge buffer's boundary (including the arc, but hidden in the image). So use the expression in the answer, but delete the intersection function - delete lines 3-10 but keep the then statement and also delete the last closing bracket ) (2nd last line). Like this, you get the wedge buffer. Style it as Outline: Simple line or enclose the wedge_buffer() i a boundary() function.
    – Babel
    Commented Jan 18 at 9:03

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.