7

Refreshing the map extent on QGIS's composer requires to click on Set map extent to match main canvas extent enter image description here

I was wondering if there was a possibility to have a map extent (in the composer) that constantly refreshes itself depending on the main canvas location. That means, that no manual action has to be done.

In comparison to ArcGIS and if I'm not mistaken, the solution is symbolised by a locker located right bottom corner (at least for ArcMap 10).

2
  • I don't think there is the option, however someone might know more than me
    – JonasV
    Commented Oct 14, 2020 at 13:12
  • Based on this answer you should be able to use data defined override on the extent of your map element. Please let us know, if you were able to achieve your desired result.
    – Erik
    Commented Oct 14, 2020 at 13:31

2 Answers 2

4

I think the main issue here is, that there is no option to set the auto-refresh rate of print-layout-maps (at least none that I know of). So you can use data defined override for your extents as below, but the print-layout-canvas will only refresh if you manually click on the refresh button, minimize and remaximize the print layout window, or something like that. Which makes it a little bit pointless... But in my eyes this would be a nice feature though.

However, you could create a custom function like the following:

@qgsfunction(args='auto', group='Custom')
def my_canvas(feature, parent):    
    e = QgsGeometry.fromWkt(qgis.utils.iface.mapCanvas().extent().asWktPolygon())
    return e

It returns the geometry of your current main-window-map-canvas. You can then use x_max(my_canvas()), x_min(my_canvas()), y_min(my_canvas()), y_max(my_canvas()) as expressions for data defined override for your print-layout-map properties:

enter image description here

PS: I am not an expert in PyQGIS, so I dont know why I had to use .asWktPolygon() as step inbetween. It just failed returning QgsGeometry() directly when using .asPolygon().

1

Thank you for those first answers. As I have poor knowledge of coding, it'll take time before I meet a result.

My research led me to a plugin (Layout loader), which is able when opening the composer to zoom directly to the canvas location. However, for certain reasons, I am not likely to use that plugin, and so I'll carry on with your solutions.

Here is the link to the plugin : link to Github

And here, an extract of the code:

# Get current canvas extend and apply that to all maps (items) in layout
# Replace any text "{{title}}" in any layout label with the dialog Title text
canvas = iface.mapCanvas()
for item in l.items():
    if item.type()==65639: # Map
        item.zoomToExtent(canvas.extent())
    if item.type()==65641: # Label
        item.setText(item.text().replace('{{title}}', title_text))

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.