Sometimes when we are working with maps we get symbols that overlap and we need to figure out a way to be able to show both symbols if that is a requirement, in this case I will offset the symbol based on an expression to figure out if it is within a certain distance from the other symbol which in this case are in two different layers, one which is for airports/heliports and the other which is used for the ground based navigation aids used by aircraft.

In QGIS we can apply an offset to symbols but in that case it will apply the offset to all the symbols irrespective if this is actually required or not

In this case we really want to be sure only those symbols which may overlap are to be moved, so what we can do is to use an expression instead, for this particular case I used the following expression, since my data is in WGS84 I need to do a transformation from that to a projected coordinate system in order to apply a distance which I wanted it to be 2.5 Nautical Miles. There needs to be a transformation from 2.5 NM to the projection units which is meters that is why the value is multiplied by 1852

In this expression we are going to use the following functions

``````CASE WHEN
contains(buffer(transform(aggregate(layer:='AirportHeliport_cdb14b2e_594a_4432_be9e_a0f6ba88440e', aggregate:='collect', expression:=\$geometry),@wgs, @project_crs ),2.5*1852),transform(\$geometry,@wgs,@project_crs))
THEN '-1,1'
ELSE '0.0,0.0'
END``````

The case when the expression is true (buffer of the airport contains the navaid) will then cause a displacement of the navaid symbol by -1,1 (x,y), if not there will be no displacement. Notice that in the expression above there are some repetitive values and this could get a bit cumbersome if it needs to provide a more complex transformation, an alternative to that is to use with_variable option.

with_variable(name,value,expression)

Explanation

Same expression but now using the variables which can allow to change the value of that particular variable just once at the start instead of scanning the expression to possible locations

``````with_variable('wgs','EPSG:4326',
CASE WHEN
contains(buffer(transform(aggregate(layer:='AirportHeliport_cdb14b2e_594a_4432_be9e_a0f6ba88440e', aggregate:='collect', expression:=\$geometry),@wgs, @project_crs ),2.5*1852),transform(\$geometry,@wgs,@project_crs))
THEN '-1,1'
ELSE '0.0,0.0'
END
)``````

At the end this is how it looks, hopefully it provides some useful information for this and other cases

Categories: GISQGIS