9

I'm trying to find a very simple solution to reproject a vector layer into a temporary layer in PyQGIS, however documentation is really extensive and I'm fairly new to PyQGIS; the only answer I've found here saves the layer, which I totally want to avoid.

The code I've tried:

layer = QgsVectorLayer("/path/file.gpkg", "oko", "ogr")

epsg_crs = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId)

layer.setCoordinateSystem(epsg_crs)

And this error I got:

Traceback (most recent call last):
  File "/usr/lib/python3.6/code.py", line 91, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
TypeError: QgsVectorLayer.setCoordinateSystem(): too many arguments
Taras
  • 32,823
  • 4
  • 66
  • 137
Elio Diaz
  • 3,456
  • 9
  • 22
  • The answer you mentioned writes the input to a new output, because this way coordinates are changed/transformed to the new projection, while using setCoordinateSystem() just change the definition of the CRS and leaves the geometry as it is. So the idea to write a new output layer is correct, you can do that with a memory layer if you want. – Andreas Müller Mar 20 '19 at 10:01
  • how should I write the code to set the temporal layer? – Elio Diaz Mar 20 '19 at 19:34

2 Answers2

16

You can use processing algorithm native:reprojectlayer.

Example:

lyr = iface.activeLayer()
parameter = {
    'INPUT': lyr,
    'TARGET_CRS': 'EPSG:4326',
    'OUTPUT': 'memory:Reprojected'
}
result = processing.run('native:reprojectlayer', parameter)['OUTPUT']
QgsProject.instance().addMapLayer(result)
Taras
  • 32,823
  • 4
  • 66
  • 137
Fran Raga
  • 7,838
  • 3
  • 26
  • 47
5

If you do not want to use Processing Tools you can do it like:

layer = iface.activeLayer()
source_crs = QgsCoordinateReferenceSystem(layer.crs().authid())
target_crs = QgsCoordinateReferenceSystem("EPSG:4326")

with edit(layer): for feat in layer.getFeatures(): # you need to store the geometry in a variable to reproject it; you can not reproject without doing so geom = feat.geometry() # transform the geometry geom.transform(QgsCoordinateTransform(source_crs, target_crs, QgsProject.instance())) # now update the features geometry feat.setGeometry(geom) # dont forget to update the feature, otherwise the changes will have no effect layer.updateFeature(feat) # finally simply set the layers crs to the new one layer.setCrs(target_crs)

Also see: https://qgis.org/pyqgis/3.16/core/QgsGeometry.html#qgis.core.QgsGeometry.transform

Taras
  • 32,823
  • 4
  • 66
  • 137
MrXsquared
  • 34,292
  • 21
  • 67
  • 117