Skip to content

Commit 37295ec

Browse files
committed
Expose extra arguments to QgsGeometry::transform
Previously these were only available via the raw QgsAbstractGeometry API. Also add more unit tests for QgsGeometry::transform
1 parent 1357a47 commit 37295ec

File tree

4 files changed

+93
-12
lines changed

4 files changed

+93
-12
lines changed

python/core/geometry/qgsgeometry.sip.in

+13-2
Original file line numberDiff line numberDiff line change
@@ -616,9 +616,20 @@ Translates this geometry by dx, dy, dz and dm.
616616
:return: OperationResult a result code: success or reason of failure
617617
%End
618618

619-
OperationResult transform( const QgsCoordinateTransform &ct );
619+
OperationResult transform( const QgsCoordinateTransform &ct,
620+
QgsCoordinateTransform::TransformDirection direction = QgsCoordinateTransform::ForwardTransform,
621+
bool transformZ = false );
620622
%Docstring
621-
Transforms this geometry as described by CoordinateTransform ct
623+
Transforms this geometry as described by the coordinate transform ``ct``.
624+
625+
The transformation defaults to a forward transform, but the direction can be swapped
626+
by setting the ``direction`` argument.
627+
628+
By default, z-coordinates are not transformed, even if the coordinate transform
629+
includes a vertical datum transformation. To transform z-coordinates, set
630+
``transformZ`` to true. This requires that the z coordinates in the geometry represent
631+
height relative to the vertical datum of the source CRS (generally ellipsoidal heights)
632+
and are expressed in its vertical units (generally meters).
622633

623634
:return: OperationResult a result code: success or reason of failure
624635
%End

src/core/geometry/qgsgeometry.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -2337,15 +2337,15 @@ bool QgsGeometry::requiresConversionToStraightSegments() const
23372337
return d->geometry->hasCurvedSegments();
23382338
}
23392339

2340-
QgsGeometry::OperationResult QgsGeometry::transform( const QgsCoordinateTransform &ct )
2340+
QgsGeometry::OperationResult QgsGeometry::transform( const QgsCoordinateTransform &ct, const QgsCoordinateTransform::TransformDirection direction, const bool transformZ )
23412341
{
23422342
if ( !d->geometry )
23432343
{
23442344
return QgsGeometry::InvalidBaseGeometry;
23452345
}
23462346

23472347
detach();
2348-
d->geometry->transform( ct );
2348+
d->geometry->transform( ct, direction, transformZ );
23492349
return QgsGeometry::Success;
23502350
}
23512351

src/core/geometry/qgsgeometry.h

+14-2
Original file line numberDiff line numberDiff line change
@@ -659,10 +659,22 @@ class CORE_EXPORT QgsGeometry
659659
OperationResult translate( double dx, double dy, double dz = 0.0, double dm = 0.0 );
660660

661661
/**
662-
* Transforms this geometry as described by CoordinateTransform ct
662+
* Transforms this geometry as described by the coordinate transform \a ct.
663+
*
664+
* The transformation defaults to a forward transform, but the direction can be swapped
665+
* by setting the \a direction argument.
666+
*
667+
* By default, z-coordinates are not transformed, even if the coordinate transform
668+
* includes a vertical datum transformation. To transform z-coordinates, set
669+
* \a transformZ to true. This requires that the z coordinates in the geometry represent
670+
* height relative to the vertical datum of the source CRS (generally ellipsoidal heights)
671+
* and are expressed in its vertical units (generally meters).
672+
*
663673
* \returns OperationResult a result code: success or reason of failure
664674
*/
665-
OperationResult transform( const QgsCoordinateTransform &ct );
675+
OperationResult transform( const QgsCoordinateTransform &ct,
676+
QgsCoordinateTransform::TransformDirection direction = QgsCoordinateTransform::ForwardTransform,
677+
bool transformZ = false );
666678

667679
/**
668680
* Transforms the x and y components of the geometry using a QTransform object \a t.

tests/src/python/test_qgsgeometry.py

+64-6
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@
3636
QgsCoordinateTransform,
3737
QgsRectangle,
3838
QgsWkbTypes,
39-
QgsRenderChecker
39+
QgsRenderChecker,
40+
QgsCoordinateReferenceSystem,
41+
QgsProject
4042
)
4143
from qgis.PyQt.QtCore import QDir
4244
from qgis.PyQt.QtGui import QImage, QPainter, QPen, QColor, QBrush, QPainterPath
@@ -1196,33 +1198,89 @@ def testTranslate(self):
11961198

11971199
polygon = QgsGeometry.fromWkt("MultiPolygon (((0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0)),((4 0, 5 0, 5 2, 3 2, 3 1, 4 1, 4 0)))")
11981200
self.assertEqual(polygon.translate(1, 2), 0, "Translate failed")
1199-
expwkt = "MultiPolygon (((1 2, 2 2, 2 3, 3 3, 3 4, 1 4, 1 2)),((5 2, 6 2, 6 2, 4 4, 4 3, 5 3, 5 2)))"
1201+
expwkt = "MultiPolygon (((1 2, 2 2, 2 3, 3 3, 3 4, 1 4, 1 2)),((5 2, 6 2, 6 4, 4 4, 4 3, 5 3, 5 2)))"
12001202
wkt = polygon.asWkt()
1203+
assert compareWkt(expwkt, wkt), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)
12011204

1205+
def testTransform(self):
1206+
# null transform
12021207
ct = QgsCoordinateTransform()
12031208

12041209
point = QgsGeometry.fromWkt("Point (1 1)")
1205-
self.assertEqual(point.transform(ct), 0, "Translate failed")
1210+
self.assertEqual(point.transform(ct), 0, "Transform failed")
12061211
expwkt = "Point (1 1)"
12071212
wkt = point.asWkt()
12081213
assert compareWkt(expwkt, wkt), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)
12091214

12101215
point = QgsGeometry.fromWkt("MultiPoint ((1 1),(2 2),(3 3))")
1211-
self.assertEqual(point.transform(ct), 0, "Translate failed")
1216+
self.assertEqual(point.transform(ct), 0, "Transform failed")
12121217
expwkt = "MultiPoint ((1 1),(2 2),(3 3))"
12131218
wkt = point.asWkt()
12141219
assert compareWkt(expwkt, wkt), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)
12151220

12161221
linestring = QgsGeometry.fromWkt("LineString (1 0, 2 0)")
1217-
self.assertEqual(linestring.transform(ct), 0, "Translate failed")
1222+
self.assertEqual(linestring.transform(ct), 0, "Transform failed")
12181223
expwkt = "LineString (1 0, 2 0)"
12191224
wkt = linestring.asWkt()
12201225
assert compareWkt(expwkt, wkt), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)
12211226

12221227
polygon = QgsGeometry.fromWkt("MultiPolygon(((0 0,1 0,1 1,2 1,2 2,0 2,0 0)),((4 0,5 0,5 2,3 2,3 1,4 1,4 0)))")
1223-
self.assertEqual(polygon.transform(ct), 0, "Translate failed")
1228+
self.assertEqual(polygon.transform(ct), 0, "Transform failed")
12241229
expwkt = "MultiPolygon (((0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0)),((4 0, 5 0, 5 2, 3 2, 3 1, 4 1, 4 0)))"
12251230
wkt = polygon.asWkt()
1231+
assert compareWkt(expwkt, wkt), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)
1232+
1233+
# valid transform
1234+
ct = QgsCoordinateTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857), QgsProject.instance())
1235+
1236+
point = QgsGeometry.fromWkt("Point (1 1)")
1237+
self.assertEqual(point.transform(ct), 0, "Transform failed")
1238+
expwkt = "Point (111319 111325)"
1239+
wkt = point.asWkt()
1240+
assert compareWkt(expwkt, wkt, tol=100), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)
1241+
1242+
point = QgsGeometry.fromWkt("MultiPoint ((1 1),(2 2),(3 3))")
1243+
self.assertEqual(point.transform(ct), 0, "Transform failed")
1244+
expwkt = "MultiPoint ((111319 111325),(222638 222684),(333958 334111))"
1245+
wkt = point.asWkt()
1246+
assert compareWkt(expwkt, wkt, tol=100), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)
1247+
1248+
linestring = QgsGeometry.fromWkt("LineString (1 0, 2 0)")
1249+
self.assertEqual(linestring.transform(ct), 0, "Transform failed")
1250+
expwkt = "LineString (111319 0, 222638 0)"
1251+
wkt = linestring.asWkt()
1252+
assert compareWkt(expwkt, wkt, tol=100), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)
1253+
1254+
polygon = QgsGeometry.fromWkt("MultiPolygon(((0 0,1 0,1 1,2 1,2 2,0 2,0 0)),((4 0,5 0,5 2,3 2,3 1,4 1,4 0)))")
1255+
self.assertEqual(polygon.transform(ct), 0, "Transform failed")
1256+
expwkt = "MultiPolygon (((0 0, 111319 0, 111319 111325, 222638 111325, 222638 222684, 0 222684, 0 0)),((445277 0, 556597 0, 556597 222684, 333958 222684, 333958 111325, 445277 111325, 445277 0)))"
1257+
wkt = polygon.asWkt()
1258+
assert compareWkt(expwkt, wkt, tol=100), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)
1259+
1260+
# reverse transform
1261+
point = QgsGeometry.fromWkt("Point (111319 111325)")
1262+
self.assertEqual(point.transform(ct, QgsCoordinateTransform.ReverseTransform), 0, "Transform failed")
1263+
expwkt = "Point (1 1)"
1264+
wkt = point.asWkt()
1265+
assert compareWkt(expwkt, wkt, tol=0.01), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)
1266+
1267+
point = QgsGeometry.fromWkt("MultiPoint ((111319 111325),(222638 222684),(333958 334111))")
1268+
self.assertEqual(point.transform(ct, QgsCoordinateTransform.ReverseTransform), 0, "Transform failed")
1269+
expwkt = "MultiPoint ((1 1),(2 2),(3 3))"
1270+
wkt = point.asWkt()
1271+
assert compareWkt(expwkt, wkt, tol=0.01), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)
1272+
1273+
linestring = QgsGeometry.fromWkt("LineString (111319 0, 222638 0)")
1274+
self.assertEqual(linestring.transform(ct, QgsCoordinateTransform.ReverseTransform), 0, "Transform failed")
1275+
expwkt = "LineString (1 0, 2 0)"
1276+
wkt = linestring.asWkt()
1277+
assert compareWkt(expwkt, wkt, tol=0.01), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)
1278+
1279+
polygon = QgsGeometry.fromWkt("MultiPolygon (((0 0, 111319 0, 111319 111325, 222638 111325, 222638 222684, 0 222684, 0 0)),((445277 0, 556597 0, 556597 222684, 333958 222684, 333958 111325, 445277 111325, 445277 0)))")
1280+
self.assertEqual(polygon.transform(ct, QgsCoordinateTransform.ReverseTransform), 0, "Transform failed")
1281+
expwkt = "MultiPolygon(((0 0,1 0,1 1,2 1,2 2,0 2,0 0)),((4 0,5 0,5 2,3 2,3 1,4 1,4 0)))"
1282+
wkt = polygon.asWkt()
1283+
assert compareWkt(expwkt, wkt, tol=0.01), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)
12261284

12271285
def testExtrude(self):
12281286
# test with empty geometry

0 commit comments

Comments
 (0)