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)
Taras
  • 32,823
  • 4
  • 66
  • 137
Ingrid Ingravida
  • 2,193
  • 1
  • 10

1 Answers1

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.

Taras
  • 32,823
  • 4
  • 66
  • 137
MrXsquared
  • 34,292
  • 21
  • 67
  • 117