# Cropping Voronoi polygons to specific distance from input points using QGIS

The Voronoi polygon algorithm propagates the polygons to the extent of the input layer (the points), which means some massive polygons. The majority of those massive polygons are nonsense data - we can't have any confidence that the values there are reasonable just because the value at a point a long way away is X (and that happens to be the nearest point sampled).

Potential solutions:

1. set a single universal maximum distance from node point, so the polygons would be rounded out instead of continue.
2. set a dynamic maximum distance based on nearby points... but I suspect that'd get complicated quick.

I'm not sure how to do this though. The Voronois are created by an algorithm in QGis, using the points as input. But the resulting voronoi polygons layer doesn't know where the points are. There doesn't look to be an option for this in the algorithm (Python function), sadly.

Possibly I could attach the input points to the output Voronoi somehow, to act as centroids for step 2. Step 2: apply some kind of buffering algorithm to each polygon, i.e. "set extent to be the current bounds or a circle of Y radius, whichever's smallest.

Has anyone ever done this?

Voronois being untrustable at a certain projection distance seems like something others would have had to deal with.

This picture shows points around Florida, USA. Easy to remove the centre by masking land, but I need ocean points to append to a grid and lots of them are going to be unreasonable/wrong. Another solution using concave hull: first "cluster" nearby points into different groups, then create Voronoi polygons for each clustered group separately:

1. Create a concave hull (alpha shapes) around your points: use a small Threshold value to get a small hull:

Create concave hull (blue) around the points with Threshold = 0.1: 1. On the resulting layer, run multipart to single parts.

2. Attach the id of the features of the output of step 2 (the individual polygons of the concave hull) to the points: so each point gets an attribute as to whicht "cluster" it belongs. Create a new field called `cluster_group` on the point layer with field calculator and this expression: `array_first (overlay_within ('clusters',\$id))` 1. Now select each group individually using select by expression with an expression like `cluster_group = 1` etc. and create Voronoi polygons separately for each group: 2. Clip the resulting voronoi polygon layer (yellow) with the clusters layer from step 2 (blue): And this is how the result for the wholy layer looks like: • This is great, thank you, and sorry for the slow reply. I presume it should be decently possible to buffer the concave hulls (after step 1) right? Otherwise there'll be edge & corner points with no extrapolation area outside of the concave hull. I'll have a look tomorrow regardless. Cheers! Oct 26, 2021 at 5:17
• Yes, you're right. Of course, a reasonable buffering would probably be a good idea if you want to include some area outside. Oct 26, 2021 at 11:42

Quick solution / principles

See below for variation with dynamic distance buffer

2. Create a buffer around your points and be sure to check the dissolve option.
3. Intersect buffer with polygon layer.

Voronoi polygons (blue) of the white points; red: dissolved buffer around the points: Green: voronoi polygons intersected with the buffers - everything outside of the buffer layer is clipped from the voronoi layer: Variations

1. Make buffer with a dynamic distance, based on the density of the points (based on the nearest neighboring point). In the buffer tool, for `Distance` use data driven override and insert this expression (you can modify it to vary the buffer size even further):
``````length (
make_line (
\$geometry,
array_first (
overlay_nearest (
'points',
\$geometry
))))
`````` 1. On the buffer layer, run Multipart to single parts before intersection.

2. After intersection, on the output layer check if there are any polygons that do not contain points (this is the case where the buffer of a points partially falls inside the voronoi polygon of another point - see screenshot). To select these "empty" poylgons, use Select by expression with this expression, where `points` is the name of the layer containing the points: `overlay_contains( 'points') = false`. Delete the selected polygons.

"Empty" polygons, highlighted in yellow; red: buffer with dynamic size, black lines: boundary of the voronoi polygons: Green: resulting voronoi polygons, clipped with a buffer with dynamic distance: Result, showing the whole result: voronoi-polygons clipped to a dynamic distance around the points, based on the density of the points (the closer points are, the smaller the voronoi polygons). Of course, there are no overlaps between polygons, but sometimes gaps between them: • Fabulous stuff, thanks again! I suspect static distance is most defensible. I'll have to think of a way to decide that value. I wonder if I could do some kind of nearest neighbour analysis... see if there's a falling trend in autocorrelation to the same value as distance to NN increases? Oct 26, 2021 at 5:23
• What do you mean by nearest neigbour analysis? The distance based on the N nearest neighbours? That is possible modifying the `overlay_nearest` function with a `limit:=N` argument to get the N nearest neighbours and then calculate let's say the mean distance. Oct 26, 2021 at 11:40
• I'm not using the right terms I suspect. I'm thinking: Find each point's single nearest neighbour, extract the value of that point, compare it to the value of the 'source node', and do that for every node. Resulting columns would be 'dist to nearest neighbour' and 'modulus of value difference'. Plot that, x=dist, y=mod, draw trendline. Sounds like `overlay_nearest` `limit:=1` would be a start. Cheers! Oct 26, 2021 at 16:40
• Sorted. Went for an eyeballed static rate. Thank you so much for your wonderful walkthrough! Nov 3, 2021 at 21:14