4

I am having trouble setting the mapCanvas CRS in QGIS 3.0 using Python. I am effectively trying to replicate what happens when you change the CRS by clicking on the bottom-right corner of the Canvas and selecting a CRS.

When I set the CRS using iface.mapCanvas().setDestinationCrs(crs) the CRS changes. However when I import a layer, the CRS changes to the layer's CRS.

For instance, in the code below:

  • Open a new project.
  • Set the CRS to 4326.
  • Import Google Satellite image with the CRS 3857.
  • Set the CRS to 4326 again.
  • QGIS shows a CRS of 3857.

When I run the same code again but add a print statement between adding the layer and setting the CRS the second time, the code works. I am not sure why this works.

from qgis.core import (
    QgsCoordinateReferenceSystem,
    QgsRasterLayer,
    QgsProject
    )
from qgis.utils import iface

def get_google_layer():
    google_uri = "type=xyz&url=https://mt1.google.com/vt/lyrs%3Ds%26x%3D%7Bx%7D%26y%3D%7By%7D%26z%3D%7Bz%7D"
    return QgsRasterLayer(google_uri, 'Google', 'wms')

def change_map_canvas():
    iface.newProject(False)
    crs = QgsCoordinateReferenceSystem(4326)

    iface.mapCanvas().setDestinationCrs(crs)
    iface.mapCanvas().refresh()
    assert iface.mapCanvas().mapSettings().destinationCrs() == crs 

    l = get_google_layer()
    QgsProject.instance().addMapLayer(l)

    #print("Here")

    iface.mapCanvas().setDestinationCrs(crs)
    assert iface.mapCanvas().mapSettings().destinationCrs() == crs
3

By further debugging I was able to find the root of the problem and solve it.

The CRS would not change until after the entire python method change_map_canvas(), but the CRS would change correctly if I added the Print statement halfway through. This led me to think that the ActiveWindow or Application was not refreshing properly. The function would work correctly if the program had already been running, just not from start up.

By adding QApplication.instance().processEvents() after adding the map layer, the script works as expected. The full simplified code is below:

from PyQt5.QtWidgets import (
    QApplication
    )

from qgis.core import (
    QgsCoordinateReferenceSystem,
    QgsRasterLayer,
    QgsProject
    )
from qgis.utils import iface


def get_google_layer():
    iface.newProject(False)
    google_uri = "type=xyz&url=https://mt1.google.com/vt/lyrs%3Ds%26x%3D%7Bx%7D%26y%3D%7By%7D%26z%3D%7Bz%7D"
    return QgsRasterLayer(google_uri, 'Google', 'wms')

def change_map_canvas():
    iface.newProject(False)
    crs = QgsCoordinateReferenceSystem(4326)


    l = get_google_layer()
    QgsProject.instance().addMapLayer(l)
    QApplication.instance().processEvents()

    QgsProject.instance().setCrs(crs)
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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