QGIS Symbology – Duplicate Line with Offset if Second Field is Filled

geometry-generatoroffsetqgissymbology

I have a line layer with two fields Field A and Field B using the same value representation. Every object has a value in Field A, only some objects have a value in Field B.

I am looking to create a symbology that styles the line according to Field A.
But if a value in Field B is present, the line should offset to one side and a second line with the same offset to the other direction should be created, using the same symbology but referencing Field B.

I am now looking for a way to achieve this, hopefully via geometry generator.

This is my layer only styled by Field A:

enter image description here

This is my current workaround and close to what I want to achieve:

enter image description here

I currently duplicate my layer and use the same styling with offset via geometry generator and referencing Field B. So at the moment, my first layer is always using the line's real placement and the second layer is always set off. When there is a line with both values filled connecting to a line, where only one value is filled, it looks like this:

enter image description here

I would expect the upper line of the left part to be higher so the line on the right is connecting in the middle between the two lines on the left.

Best Answer

You don't need Geometry Generator per se, you can do it by creating a couple of extra symbol layers and using Data Defined Overrides to control their visibility:

enter image description here

Steps
  1. Add 2 more symbol layers
  2. One with a positive offset, one with a negative
  3. Enter the following expressions in the Enable symbol layer Data Defined Override expression editor (one for each symbol layer).

The original symbol layer:

-- render feature only when one field is populated
case 
    when Field_A >= 0 and Field_B is null
    then true
    when Field_B >= 0 and Field_A is null
    then true
    else false
end

The offset symbol layer(s).

-- render feature only when both fields are populated
case 
    when Field_A >= 0 and Field_B >= 0
    then true
    else false
end

enter image description here

Related Question