1

I am trying to publish maps from QGIS Map Composer.

I would like to automatically add the credits of the background layers displayed in the composition (like OSM, Bing, ...)

I am aware of such a feature in main QGIS window using View -> Decorations -> Copyright label but

  • this data is not shown in composer
  • I am looking for an expression to adapt the text depending of the active layer

(Currently using either qgis 2.18 or 3.4)

0

2 Answers 2

5

Please read everything, there are some updates starting from QGIS 3.4 to QGIS 3.18.

In QGIS 3.4, you can build your attribution label automatically, according to layers which are visible.

First, you need to setup metadata for all your layers.

In QGIS 3.4.0 or 3.4.4, you had to use the QGIS Server panel and fill the attribution field: QGIS Server panel

Since QGIS 3.4.5, you can use the Metadata panel: Metadata panel

In my project, I have 3 layers, but 2 layers have the same attribution Provider 2.

Then, in your layout, give an itemID to your map:

itemID for map

Then, in your label, you can create an expression like this:

array_to_string( -- 4 we make the attribution list unique and convert to string
    array_distinct(
        array_foreach( --2 for each layer in the map1
            map_get(item_variables('map1'),'map_layers')  --1 get the list of layers in the map1
            ,array_to_string(
                -- 3 we fetch the attribution for the layer
                layer_property(@element,'attribution')))))

Try to understand the expression by reading comments from 1 to 4.

This will render the correct attribution based on layers which are visible in my map. It will also remove attributions which are the same across layers.

my label with expression

In QGIS 3.6.0, you can add the array_sort expression to sort alphabetically.

In QGIS 3.18, there is now a map_credits( 'Main Map' ) expression function which does all the array_foreach, layer_properties etc ... !

4
  • This works nicely for basemap layers. But as soon as you display a vector layer which has no 'Rights' metadata, the expression breaks.
    – Theo F
    Jun 30, 2021 at 17:23
  • Which expression are you talking about ? Which example because according to the QGIS Version, there is different possibilities
    – etrimaille
    Jun 30, 2021 at 21:06
  • I'm using 3.16. And I used your expression under your section: 'Since QGIS 3.4.5...'. The expression starts with array_to_string( -- 4 we. It works very well if you have layers containing 'Rights' metadata in the Metadata panel. But I added a new layer (with no 'Rights' metadata) to the project which broke things (ie. the text label in my Layout started showing the raw expression string).
    – Theo F
    Jul 1, 2021 at 10:01
  • 1
    I can't try right now. Maybe we need to tweak the expression to add a defulat empty string if now rights, with coalesce ?
    – etrimaille
    Jul 1, 2021 at 11:40
1

One answer to your question can be a union of the great answers (in fact, your question is almost a duplicate) of this one: Automating citation of data source in QGIS print composer?

  • Add a new text label to the layout.

  • In the item properties of the label, main properties, click on Insert an Expression.

  • In the expression builder, switch to the Function Editor tab, and paste this code:

# Be sure to import iface from qgis.utils

from qgis.core import *
from qgis.gui import *
from qgis.utils import iface

@qgsfunction(args='auto', group='Custom')
def get_layer_name(feature, parent):
    return qgis.utils.iface.activeLayer().name()  

Its define a new get_layer_name() function that returns the name of the active layer and can be found under the Custom group of the expressions list.

  • Click on Save and Load Function.

  • Switch to the Expression tab and write this expression:

layer_property( get_layer_name(), 'attribution')

It returns the Attribution metadata of the active layer.

Don't forget to refresh the layout view when the active layer has changed.

1
  • I would rename get_layer_name by get_active_layer_name. It's more explicit that you get the name only for the current selected layer. Note that this is working only for a single layer and if you have the python expression on each computer.
    – etrimaille
    Feb 24, 2019 at 22:41

Not the answer you're looking for? Browse other questions tagged or ask your own question.