1

I have a template project that will be used for many future sites and I want to automatically centre all the composer layout maps to the same centre as the main canvas. Ideally this would be done as part of a processing model. I have looked at using an expression for the layout maps extents but I can't see a canvas property to work with. I could use a single feature in an atlas setup but that adds complications I don't really want.

4
  • When should this centering happen? Everytime you move the canvas? Once you open a layout?
    – Erik
    Commented Jun 28, 2021 at 11:17
  • before I export the maps, which I would also like to do using the graphical modeller
    – Sethinacan
    Commented Jun 28, 2021 at 11:31
  • For what I know there is no solution to get the extend of the current view of the QGIS canva. What you could do would be to define a project variable that will be used by your layout and that you could modify. would it suit your needs @Sethinacan ? Commented Jun 28, 2021 at 12:59
  • @CorentinLemaitre That seems like the closest option, it works and stops the scales from changing
    – Sethinacan
    Commented Jun 28, 2021 at 14:11

2 Answers 2

2

Principles

Each map in each layout have in property scale extents and the possibility to set the extent based on atlas.

enter image description here

What you want to do is not atlas but is data driven extent.

Step by step

  1. Copy the extent from your actual canvas : enter image description here
  2. Create the variable to store your extent. Click on the + and name the variable canvas_extent fill it with what you have copied before.

enter image description here

  1. Set the extent X min based on data the expression should be : array_get(string_to_array(replace (@canvas_extent, array(',',' : '), array (',',','))),0).

enter image description here

  1. For Y min it will be array_get(string_to_array(replace (@canvas_extent, array(',',' : '), array (',',','))),1), for X max it will be array_get(string_to_array(replace (@canvas_extent, array(',',' : '), array (',',','))),2) and for Y max it will be array_get(string_to_array(replace (@canvas_extent, array(',',' : '), array (',',','))),3)

Repeat the steps for each layout you have.

When you change your variable canvas_extent value it will update the layout extent.

2
  • What I have done is similar but I added a variable for the centre then used expressions to calculate the extents which allows maps at different scales
    – Sethinacan
    Commented Jun 29, 2021 at 7:05
  • Sadly layouts don't update automatically
    – Sethinacan
    Commented Jun 29, 2021 at 7:24
0

You could drop this into the Python Console and this should just work:

extent = iface.mapCanvas().extent()
project = QgsProject.instance()
projectLayoutManager = project.layoutManager()
layouts = projectLayoutManager.layouts()
for layout in layouts:
    for item in layout.items():
        if isinstance(item, QgsLayoutItemMap):
            scale = item.scale()
            size = item.sizeWithUnits()
            item.setExtent(extent)
            item.setScale(scale)
            item.attemptResize(size)
            item.refresh()
3
  • its a good answer but in my case I have maps at different scales so need to work with a centre
    – Sethinacan
    Commented Jun 29, 2021 at 7:02
  • OK, edited. Almost the same answer as before, but you get the scale before you change the extent and set the scale back afterward.
    – David Galt
    Commented Jun 30, 2021 at 1:16
  • ...and fixed the layout item size change that occurs. I'm sure there has to be a more simple way to do this, but the code above works.
    – David Galt
    Commented Jun 30, 2021 at 2:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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