What you want to do is a cartographic generalization operation called displace. You might have a look at GRASS v.generalize, it has an option for displacement.
Principal idea of the solution
What I propose, however, is using geometry generator with the function offset_curve( ) and for the distance use the variable @map_scale
, divided by a constant.
The line in the middle should not be offset at all and the lines at the right and left should be offset in the respective direction. For this, create a new attribute offset
and add for each line a value of 0
(no offset), 1
(offset to the left) or -1
(offset to the right). You could also set other numbers to get different offset distances for different roads: the higher the number, the higher the offset.
Combine these elements with geometry generator and this expression (change 500
to a value that fits your data):
How to implement it
offset_curve ($geometry, "offset" * @map_scale/500)
The line in the middle should not be offset at all and the lines at the right and left should be offset in the respective direction. For this, create a new attribute
offset
and add for each line a value of0
(no offset),1
(offset to the left) or-1
(offset to the right). You could also set other numbers to get different offset distances for different roads: the higher the number, the higher the offset.Combine these elements with geometry generator and this expression (change
500
to a value that fits your data):offset_curve ($geometry, "offset" * @map_scale/500)
When you now zoom out, the lines to the right and left move away from the line in the center:
Screenshot 1: black solid line: mid-line (no offset), black dotted line: original line that must be offset, red-lines: offsetted lines: