5

I have a polyline layer with roads in WGS84 that covers several UTM zones. For every road I need to place a set of points at different distances (in metres). To do so I want to reproject each road to respective UTM zone, create points in this UTM zone, reproject points to WGS84 and add them to respectful layer. There is aQgsCoordinateTransform() class that allows to perform transformation for individual points, but it doesn't accept polylines. I guess I could manually disassemble polylines into the set of points, transform each of them and recreate a polyline, but I hope that there is a build-in method or class that I overlooked, that allows to transform individual polylines.

  • One option would be to convert your polyline to a polygon, then transformPolygon() that, then just take the outer ring again. Its pretty much just QVector operations all the way down... – BradHards Sep 21 '15 at 10:11
13

use QgsGeometry.transform( QgsCoordinateTransform tr ). for example after created your instance of QgsCoordinateTransform with source and dest crs, for each geometry instance do:

sourceCrs = QgsCoordinateReferenceSystem(4326)
destCrs = QgsCoordinateReferenceSystem(2154)
tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance())
myGeometryInstance.transform(tr)

https://qgis.org/api/classQgsCoordinateTransform.html#aa5ad428819ac020f8f5716e835ab754f

beware that the transformation (applying QgsCoordinateTransform) will change the QgsGeometry instance.

  • Thank you for this answer. The operation gives me back a 0 number and my geometry doesn't seems to be reprojected. – SIGIS Sep 14 '17 at 8:42
  • can you give more details abut what you did? e.g. wkt of the geom, origin and dest epsg code and all that can be usefl to replicate. Obviously also qgis version and platform. tnx – Luigi Pirelli Sep 14 '17 at 10:54
  • Ok I missed a step to get a QgsCoordinateSystemReference class in the choosen coordinate eg 2154. It still gave back a 0 but the vertex has changed their coordinate. – SIGIS Sep 14 '17 at 12:23
  • This codesnippet does not work anymore in QGIS 3.4.4 : TypeError: QgsCoordinateTransform(): arguments did not match any overloaded call: overload 1: too many arguments overload 2: not enough arguments overload 3: not enough arguments overload 4: not enough arguments overload 5: argument 1 has unexpected type 'QgsCoordinateReferenceSystem' – Riccardo Jan 25 at 15:11
  • 1
    @Riccardo The API has changed and you need to add a third parameter QgsCoordinateTransformContext. You can get it from QgsProject.instance(). So the call should be like QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) – spatialthoughts Apr 4 at 11:19
3

Old Question, but duckduckgo brings you here for "pyqgis transform single geometry"

Just like Riccardo Pointed out, the accepted answer does not work for scripts in QGIS 3, the situation is explained in the api reference:

Python scripts should utilize the QgsProject.instance() project instance when creating QgsCoordinateTransform. This will ensure that any datum transforms defined in the project will be correctly respected during coordinate transforms. E.g.

transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem("EPSG:3111"),
                                   QgsCoordinateReferenceSystem("EPSG:4326"), QgsProject.instance())

Using QgsCoordinateTransform in QGIS 3 will transform the geometry instance inplace, and return 0:

geom = QgsGeometry(QgsPoint(5,20))
sourceCrs = QgsCoordinateReferenceSystem(4326)
destCrs = QgsCoordinateReferenceSystem(2154)
tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance())
geom.transform(tr)
#[out]: 0

geom
#[out]: <QgsGeometry: Point (930236.95432910311501473 3567516.9810206750407815)>

back_tr = QgsCoordinateTransform(destCrs, sourceCrs, QgsProject.instance())
geom.transform(back_tr)
#[out]: 0

geom
#[out]: <QgsGeometry: Point (5 19.99999999999911182)>

If you want to copy an already existing QgsGeometry Instance, the QgsGeometry class constructor will make the trick. From the docs:

Class: QgsGeometry class qgis.core.QgsGeometry Bases: sip.wrapper

Constructor

QgsGeometry(QgsGeometry) Copy constructor will prompt a deep copy of the object

example:

geom2 = QgsGeometry(geom)
geom2
#[out]: <QgsGeometry: Point (5 19.99999999999911182)>
geom
#[out]: <QgsGeometry: Point (5 19.99999999999911182)>
geom2.transform(tr)
#[out]: 0
geom2
#[out]: <QgsGeometry: Point (930236.95432910579256713 3567516.98102056747302413)>
geom
#[out]: <QgsGeometry: Point (5 19.99999999999911182)>
  • OMG, using project as an argument for transformation looks like a terrible design to me... – SS_Rebelious Mar 8 at 20:50
  • 1
    I was just copying the docs there. – Javier JC Mar 8 at 21:23

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.