QGIS – How to Offset Lines in QGIS That Share the Same Origin and Destination

cartographyflow-mapqgissymbology

I have a set of lines in QGIS that represent travel between destinations.

Some of these lines of travel overlap – for example, traveling from Rome to Paris, and then back to Rome, and then on to Prague.

My goal is to represent the travel in a non-overlapping way that gives me curved arrows that will start at the origin, flare out, and end at the destination point. The return trip will do the same thing with an opposite offset.

I followed some basics in this post to prepare my data: How to graphically offset the boundary line of a polygon in QGIS?

But this post is talking about a constant offset of polygon data, and does not really address what I am trying to do. However I have created a field in my line layer called offset that gives a value of 1 for any lines that need to be offset. I can offset these, but they offset in a linear way, giving me parallel lines that do not touch the origin/destination.

I have also reviewed the post by @underdark here that talks about flow maps, however, I feel like I am trying to do something much more simple here; and anyway the formula does not work for my shapefile. I feel like this should get me close but I am not an expert and need something that is a bit more generic for non-weighted data. I am just trying to symbolize overlapping travel in a non-confusing way.

What I am looking for here is a geometry generator formula that can show me how to generically create offset curved lines (with arrows if possible) between an origin/destination pair.

UPDATE: Here is a graphic representing what I'm trying to do:
arrows

Best Answer

Hopefully you are using QGIS 3.0, as it has new offset_curve() function.

offset_curve($geometry, "offset")

In the above example "offset" is the field name you have mentioned.

enter image description here


[EDIT] In response to the update by @auslander.

Revised geometry generator syntax: (should work for QGIS 2.18 & QGIS 3.0)

make_line(
  start_point($geometry), 
  translate(
            centroid($geometry),
            "offset"*cos(azimuth(start_point($geometry), end_point($geometry))+0.5), 
            "offset"*sin(azimuth(start_point($geometry), end_point($geometry))+0.5)
            ), 
  end_point($geometry)
)

enter image description here

Related Question