8

I am trying to build an expression that transforms in real-time using the Geometry generator the geometry from points to ellipses.

The expression I am working with is the following:

oriented_bbox(
    collect($geometry,
        group_by:=overlay_nearest(@layer,"CLUSTER_ID"))
    )

As you can see, from a set of points I create the oriented_bbox object grouped by the nearest and filter by a field. The goal is to add the function make_ellipse so that, in real-time, it converts the oriented_bbox objects to ellipses:

enter image description here

I have tried to adapt the following expression that has appeared as a solution posted by the user @MrXsquared to this question Making ellipse based on ellipse-like polygon in QGIS:

make_ellipse(
    centroid($geometry),
    bounds_width($geometry)/2,
    bounds_height($geometry)/2,
    main_angle($geometry),
    45
    )

My attempt was as follows but it didn't work. I'm also not sure that the make_ellipse function can work with the idea of grouping objects by nearest and applying filters.

make_ellipse(
    oriented_bbox(
        collect($geometry,
            group_by:=overlay_nearest(@layer,"CLUSTER_ID")),
        ),
    centroid($geometry),
    bounds_width($geometry)/2,
    bounds_height($geometry)/2,
    main_angle($geometry),
    45)

1 Answer 1

9

You are almost there. But instead of $geometry, which in your case is a point, you need to reference the bounding box you have created with your first expression. The easiest and shortest way to do this is to use a variable.

with_variable(
    'bbox',
    oriented_bbox(
        collect($geometry,
        group_by:=overlay_nearest(@layer, "CLUSTER_ID")
        )
    ),

make_ellipse(
    centroid(@bbox),
    bounds_width(@bbox)/2,
    bounds_height(@bbox)/2,
    main_angle(@bbox),
    45
    )
)

Respectively, if you want to use the other expression from my linked answer:

with_variable(
    'bbox',
    oriented_bbox(
        collect($geometry,
        group_by:=overlay_nearest(@layer, "CLUSTER_ID")
        )
    ),

make_ellipse(
    centroid(@bbox),
    bounds_width(@bbox)/2,
    bounds_height(@bbox)/2,
    main_angle(
        make_line(
            centroid(@bbox),
            closest_point(centroid(@bbox),@bbox)
            )
        )-90,
    45
    )
)

And a hint in case this slows down your rendering: this is because your layer is based on points. So even if you see only 6 bounding boxes / ellipses, you actually have as many bounding boxes / ellipses as you have points. This is because the expression is applied to every feature (point) in your layer.

2
  • 2
    More than a solution. A way to learn how to integrate expressions. Thank's! Commented Sep 6, 2023 at 6:22
  • Regarding the last remark about rendering, see this answer for how to prevent duplicating geometries.
    – Matt
    Commented Nov 14, 2023 at 12:56

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.