Saturday 3 August 2019

pyqgis - QGIS changing canvas CRS defaults to imported layer


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

Answer



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)

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...