# Making a buffer cover a specific area (need to calculate overlap)

I work in precision agriculture and use QGIS. Today's technology makes it possible to adjust the spreading width of, for example, sprayers and manure spreaders according to where you have driven before, to reduce overlap. Such implements can have a spreading width of over 30 m. The overlap, when driving towards the headland at an angle <> 90 degrees, will be significant when considering investing in such equipment.

So, to the point. I want to make a tool in QGIS Graphic Modeler with the field boundary and the width of the implement and direction of travel as input. QGIS would then calculate the overlap. I have reached a point where I have made a headland (buffer on the inside of the border with the width corresponding to the tool). After specifying a direction of travel, I have made parallel lines indicating the center point of the track. These are then "clipped" to the headland.

A buffer on each side of the track (with a flat end cap) marks the area worked. The result is then an overlap on one side of the track and a "negative" overlap on the other side of the track (see figure) when I enter the headland on an angel <> 90 degrees.

As I want to automate the process, I need help to figure out how to extend the worked area a little longer on each end to just cover the headland as the figure shows.

Will it be possible to calculate the maximum extent of the worked area by figuring out point A and B, then extend the rectangle to that pint and then repeat this process for all the worked rectangles?

https://i.stack.imgur.com/IwcaY.png

• Please define "headline", and edit your screeshot to show its location. Jan 7, 2021 at 16:03
• Stupid auto-correct. "headland" or "hedland" Jan 7, 2021 at 16:04
• “Headland” As the screenshot shows the headland is the pink area. This will be the area first area covered with with for example a planter driving along the field border. Then the tractor willl start driving in parallel lanes. My goal is to calculate the overlap between the parallel lines and the headland. Jan 7, 2021 at 19:12

In principle, the solution is easy: extend the buffer of the worked area for so long until both lateral sides (boundaies) touch the inline of the headland. That is the distance until which the track should go to cover the whole area.

The realisation needs some steps as it includes some auxiliary lines and points to be constructed. At a first glance, it might seem a bit more complicated than it is in fact. If you need that repeatedly, you could create a processing model.

First is a "algorithmic" description, in the second part a guide how to actually implement that in QGIS.

The setting

Consider the screenshot below: red line (layer `track`): original track (with an interval of 44 m from line to line), blue polygon (layer `worked_area`): worked area (here: buffer of 22 m around red line), pink polygon (layer `headland`): headland (buffer around the farmland plot), line in dark pink (layer `inner_boundary`): inner boundary of the headland - this line encloses the area that should be fully covered by the blue buffers.

(By the way/side note, maybe to consider for other questions: providing sample data would ease the process of experimenting and looking for a solution that fits your data).

The basic idea

1. Extend the red line for a distance long enough that it clearly projects beyond the headland: black dotted line (layer `track_extended`).

2. Create a buffer of (again) 22 m around the line from step 1: light green outline (retangles, layer `worked_area_extended`)

3. Find the intersection of the boundaray of the rectangles from 2 (light green line) with the inner boundary of the headland (dark pink line): you get the white dots (layer `crossing_points`).

4. Create a line starting at the white dots, perpendicular to the direction (angle, azimuth) of the track (red line) and running on both sides for a distance slightly longer than the covered area width (22 m) to be sure it crosses the neighboring extended track - to the right as well as to the left. This line is not visible on the screenshot as it is an auxiliary line only, used to create the points in the next step (in fact, 4 & 5 will be implemented/processed in one step).

5. Create points where the line of step 4 intersects the extended track (black dotted line): you get the red points, layer `stop_point`.

6. These red points are the end point of the track you are looking for. All red points that lie on the same black dotted line should now be connected by a line. This is the final track. When implementing it in QGIS below, what is here described as one step is extended to several smaller steps (6 to 8) for auxiliary purposes.

Apply again a buffer of 22 m around it to get the final worked area (layer `worked_area_final`) you're looking for:

The implementation in QGIS

To create new geometries, use `Menu Processing / Toolbox / Geometry by expression` and set the appropriate geometry output type.

1. `extend (\$geometry, 200,200)`, input: `track`

2. `Menu Vector / Geoprocessing Tools / Buffer`

3. Use this expression on the output from 2 to create the white dots `crossing_points` (and create singlepart geoemtries if you got multipoints).

``````intersection (
boundary (\$geometry),
geometry (
get_feature_by_id (
'inner_boundary',
1
)
)
)
``````
1. Create the perpendicular line. This step here only describes how to get the right angle for the line. We crete the actual auxiliary line starting at the `crossing_points` at once in step 5, where it is only used to create the final output as points `stop_point`, so the line itself is not needed and only an auxiliary tool. Importan is to get the correct angle (azimuth): 90 degrees from the direction of the track. To calculate it, use this expression. You might do this in the field calculator of the track layer with the expression: `main_angle (\$geometry)`. You don't need to execute it. The preview at the bottom in the expression editor shows you the value calculated: copy it. As all track lines are parallel, so this value is the same for all lines. In my case, the value is 74.84 degrees. So perpendicular means: 74.84° + 90°.

2. Now that we have the angle, we create a new point layer on the basis of the points layer from step 3 with this expression that uses the auxiliary line to create the points: see the angle of 74.84 (change it according to your value), added 90 degrees to be perpendicular and converted to radians as the `project` expression expects radians, not degrees. As well, change the length of the auxiliary line (in my case: `22.1`) according to your data: It should be slightly longer than the size of the buffer (22 in my case). If it has exactly the size of the buffer, the line should touch the track, but sometimes it does not create an intersection (see. QGIS snapping issue). If the line is too long, it intersects neighboring tracks as well.

``````intersection (
extend (
make_line (
\$geometry,
project (
\$geometry,
22.1,
)
),
22.1,
22.1
),
aggregate(
'track_extended',
'collect',
\$geometry
)
)

``````
1. As the output is a multipoint geometry, convert to to single points using `Menu Vector / Geometry Tools / Multipart to singleparts`. You get the layer `stop_point` as output.

2. Now, assign to each feature (point) of the layer `stop_point` from 6 the no. of the track ("row" ) it belongs to so that we can group together those points that should be connected by a line in the next, final step. For this, create a new field `track_no` with field calculator using this expression. You should have a unique identifier in your layer `track_extended`, in my case it's the field named `fid`:

``````array_to_string (
overlay_nearest(
'track_extended',
fid
)
)
``````
1. Connect all points from `stop_point` that belong to the same track using `Menu Processing / Toolbox / Points to path` with `stop_point` as `Input point layer`. Select `track_no` for both `Order field` and `Group field`. The output is the final track you're looking for, named layer `track_final` in my case. Apply the 22 m buffer to it to get the `worked_area_final` polygon layer.

If you look closely to the last screenshot, you see that there is a small corner left uncovered in the easternmost edge of the field. The same problem, but an even smaller area, can be found in the westernmost edge (barely visible on the screenshot above). You might neglect this very small area. However, to give a complete solution to your problem, you could do this:

`Menu Vector / Geoprocessing tools / Difference` and select `inner_boundary` as `input layer` and `worked_area_final` as `Overlay layer` to get those parts of the inline boundary of the headland that is not yet covered (outline of the "uncovered" corner). In the screenshot, it's layer `difference` in turquois.

Form these line(s), extract the vertices: my layer `vertices` (white crosses).

Create a line that connects the white crosses with the neares point on the `worked_area_final` with this expression:

``````make_line (
\$geometry,
closest_point (
array_first (
overlay_nearest(
'worked_area_final',
\$geometry,
limit:=1
)
),
\$geometry
)
)
``````

The black dotted line is for visualization purposes only, you don't have to create it, only measure the distance. For this, create a new attribute `distance_corner` on the layer `vertices` with the field calculator and the expression `length(geometry)`, where you replace `geometry` by the expression from above.

Now inspect the results and decide which of the corners should be corrected, depending on the values of the `distance_corner` fields. In my case, the longest of the dotted black lines on the screenshot below is 12.8 m long. So the farthes point of the uncovered corner is 12.8 m away from the end of the covered area. That means: the track here has to be extended for 12.8 m.

Thus extend the line using the expression `extend(geometry,start_distance,end_distance)` and set the appropriate values, than re-create the buffer. See final result:

• Thanks! I This is awesome! I’m working through it step by step. I have managed to reproduce to step 4 :-). In step 5 the expression runs without any errors, but the point layer has no geometry. The attribute table has an id, instance, offset and an angel field, but the id is NULL. I have tried to add a geometry column to verify that there is coordinates, bur it returns a NULL. I have also tried to simply fie the expression to locate the error. It seems that the make_line part does not create any line (empty layer without geometry. Anny suggestions? Jan 19, 2021 at 21:20
• Could it be that the lines are too short to create intersections? I used a value of 22.1 [m] - try increasing it. It should be slightly longer than the size of the buffer. If it has exactly the size of the buffer, the line should touch the track, but sometimes it does not create an intersection. If the line is too long, it intersects neighboring tracks as well. Jan 19, 2021 at 21:25
• Changing the points i 3 to single part solved the problem. Thanks. I'l grind on :-) Jan 19, 2021 at 21:43
• Will this expressions run in the graphical modeler? Jan 19, 2021 at 21:45
• OK, thanks for the hint to create single part geometries in step 3 - don't remember if I had this or converted it. I did not test it in graphic modeler, maybe a few tiny changes could be necessary, but hard to say without testing. Of course, the workflow itself for sure is possible to automatize. Jan 19, 2021 at 21:51