# How to create a convex hull set polygons conditioned by a minimum number of points and a maximum distance

With the following expression I am trying to create a set of convex hulls from a layer with a point geometry that complies two variable conditions: a minimum number of points can be declared and a maximum distance can be declared.

My first approximation to get these goal is the following expression. In this work example case, the minimum number of points is 6 and the maximum distance is 200 meters:

``````convex_hull(
collect_geometries(
array_foreach(
array_filter(
overlay_nearest('punts', \$geometry, limit:=6, max_distance:=200),
distance(\$geometry, @element) > (
array_sort(
array_agg(
distance(\$geometry, @element)
)
)[1] * 3
)
),
@element
)
)
)
``````

Expression description:

My idea to create a convex hull with a variable number of nearest points and a maximum distance I use `overlay_nearest` function in combinaction with `convex_hull` function and a expression to calculate the minimum distance. Here are the steps:

1- `limit:=6` → variable to number of nearest points I want to consider

2- `max_distance:=200` → variable to the maximum distance I want to consider

3- `[1] * 3` → variable to minimum distance factor I want to use

I write this expression with the idea to works by first using the `overlay_nearest` function to finds specified number of nearest points to each feature in the layer within the specified maximum distance. I then filters out any points that are closer than specified minimum distance factor using `array_filter` function and the distance function. Finally, it collects all the filtered points into single multipoint geometry and creates a convex hull polygon.

Result of the previous expression in which I have made a correction in adding the `max_distance` parameter:

Then I add the conditions like this but with this expression the result is NULL:

``````CASE
WHEN count(overlay_nearest('punts', \$geometry, limit:=6, max_distance:=200)) >= 6 THEN
convex_hull(collect_geometries(array_foreach(generate_series(1,6),
convex_hull(
collect_geometries(
array_foreach(
array_filter(
overlay_nearest('punts',\$geometry,limit:=6, max_distance:=200),
distance(\$geometry, @element) > (
array_sort(
array_agg(
distance(\$geometry, @element)
)
)[0] * 3
)
),
@element
)
)
))))
ELSE
NULL
END
``````

Result of this expression after adding the correction proposed by user Tom Brennan:

So far the result is not as expected. I don't know if this approach is good, or if the problem I want to solve is not so trivial and requires a more sophisticated expression that takes into consideration a different approach. Any help is welcome.

The expected result would be something like this:

I don't know if I am approaching the problem well with this expression I am building, or there is some other more simplified approach.

• Can you explain your first expression? It looks like you are saying that the distance to any feature in the group should be no more than 3 times the distance to the closest feature in that group, but you haven't mentioned this anywhere else. How does this relate to the 200m? Oct 9, 2023 at 21:00
• Yes, of course. I try to make the description of the expression in the text above Oct 10, 2023 at 6:02
• Start by replacing "count" with "array_length". I don't think it will fully solve your problem(!), but it will fix the reason that you're getting NULL for everything. "overlay_nearest" returns an array, so you need to test the length of the array. Oct 10, 2023 at 7:36
• The core issue you have is that each point feature will have its own convex hull (or NULL if it fails the test) because the initial logic is looking for the nearest 6 points to that point within 200m. Your final diagram assumes that you will only end up with say 4 convex hulls, but you can see from the previous diagram that it's potentially quite a few more than that. Your problem statement has similarities with: gis.stackexchange.com/questions/468119/… Oct 10, 2023 at 11:44
• You probably need to refine your conditions more precisely, and also accept that it may be too hard to do with just the Geometry Generator ie may need to create a helper layer. For example, if you were to just restrict to a maximum distance between points, and a minimum number of points, you could use a buffer layer similar to the solution above. Oct 10, 2023 at 22:59

2. Use the minimum bounding geometry tool, asking it to return convex hulls, and taking into account the `CLUSTER_ID` the DB-Scan gave us: