Skip to content

Commit

Permalink
Expose extra arguments to QgsGeometry::transform
Browse files Browse the repository at this point in the history
Previously these were only available via the raw QgsAbstractGeometry
API.

Also add more unit tests for QgsGeometry::transform
  • Loading branch information
nyalldawson committed Apr 10, 2018
1 parent 1357a47 commit 37295ec
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 12 deletions.
15 changes: 13 additions & 2 deletions python/core/geometry/qgsgeometry.sip.in
Expand Up @@ -616,9 +616,20 @@ Translates this geometry by dx, dy, dz and dm.
:return: OperationResult a result code: success or reason of failure
%End

OperationResult transform( const QgsCoordinateTransform &ct );
OperationResult transform( const QgsCoordinateTransform &ct,
QgsCoordinateTransform::TransformDirection direction = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false );
%Docstring
Transforms this geometry as described by CoordinateTransform ct
Transforms this geometry as described by the coordinate transform ``ct``.

The transformation defaults to a forward transform, but the direction can be swapped
by setting the ``direction`` argument.

By default, z-coordinates are not transformed, even if the coordinate transform
includes a vertical datum transformation. To transform z-coordinates, set
``transformZ`` to true. This requires that the z coordinates in the geometry represent
height relative to the vertical datum of the source CRS (generally ellipsoidal heights)
and are expressed in its vertical units (generally meters).

:return: OperationResult a result code: success or reason of failure
%End
Expand Down
4 changes: 2 additions & 2 deletions src/core/geometry/qgsgeometry.cpp
Expand Up @@ -2337,15 +2337,15 @@ bool QgsGeometry::requiresConversionToStraightSegments() const
return d->geometry->hasCurvedSegments();
}

QgsGeometry::OperationResult QgsGeometry::transform( const QgsCoordinateTransform &ct )
QgsGeometry::OperationResult QgsGeometry::transform( const QgsCoordinateTransform &ct, const QgsCoordinateTransform::TransformDirection direction, const bool transformZ )
{
if ( !d->geometry )
{
return QgsGeometry::InvalidBaseGeometry;
}

detach();
d->geometry->transform( ct );
d->geometry->transform( ct, direction, transformZ );
return QgsGeometry::Success;
}

Expand Down
16 changes: 14 additions & 2 deletions src/core/geometry/qgsgeometry.h
Expand Up @@ -659,10 +659,22 @@ class CORE_EXPORT QgsGeometry
OperationResult translate( double dx, double dy, double dz = 0.0, double dm = 0.0 );

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

/**
* Transforms the x and y components of the geometry using a QTransform object \a t.
Expand Down
70 changes: 64 additions & 6 deletions tests/src/python/test_qgsgeometry.py
Expand Up @@ -36,7 +36,9 @@
QgsCoordinateTransform,
QgsRectangle,
QgsWkbTypes,
QgsRenderChecker
QgsRenderChecker,
QgsCoordinateReferenceSystem,
QgsProject
)
from qgis.PyQt.QtCore import QDir
from qgis.PyQt.QtGui import QImage, QPainter, QPen, QColor, QBrush, QPainterPath
Expand Down Expand Up @@ -1196,33 +1198,89 @@ def testTranslate(self):

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)))")
self.assertEqual(polygon.translate(1, 2), 0, "Translate failed")
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)))"
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)))"
wkt = polygon.asWkt()
assert compareWkt(expwkt, wkt), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)

def testTransform(self):
# null transform
ct = QgsCoordinateTransform()

point = QgsGeometry.fromWkt("Point (1 1)")
self.assertEqual(point.transform(ct), 0, "Translate failed")
self.assertEqual(point.transform(ct), 0, "Transform failed")
expwkt = "Point (1 1)"
wkt = point.asWkt()
assert compareWkt(expwkt, wkt), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)

point = QgsGeometry.fromWkt("MultiPoint ((1 1),(2 2),(3 3))")
self.assertEqual(point.transform(ct), 0, "Translate failed")
self.assertEqual(point.transform(ct), 0, "Transform failed")
expwkt = "MultiPoint ((1 1),(2 2),(3 3))"
wkt = point.asWkt()
assert compareWkt(expwkt, wkt), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)

linestring = QgsGeometry.fromWkt("LineString (1 0, 2 0)")
self.assertEqual(linestring.transform(ct), 0, "Translate failed")
self.assertEqual(linestring.transform(ct), 0, "Transform failed")
expwkt = "LineString (1 0, 2 0)"
wkt = linestring.asWkt()
assert compareWkt(expwkt, wkt), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)

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)))")
self.assertEqual(polygon.transform(ct), 0, "Translate failed")
self.assertEqual(polygon.transform(ct), 0, "Transform failed")
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)))"
wkt = polygon.asWkt()
assert compareWkt(expwkt, wkt), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)

# valid transform
ct = QgsCoordinateTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857), QgsProject.instance())

point = QgsGeometry.fromWkt("Point (1 1)")
self.assertEqual(point.transform(ct), 0, "Transform failed")
expwkt = "Point (111319 111325)"
wkt = point.asWkt()
assert compareWkt(expwkt, wkt, tol=100), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)

point = QgsGeometry.fromWkt("MultiPoint ((1 1),(2 2),(3 3))")
self.assertEqual(point.transform(ct), 0, "Transform failed")
expwkt = "MultiPoint ((111319 111325),(222638 222684),(333958 334111))"
wkt = point.asWkt()
assert compareWkt(expwkt, wkt, tol=100), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)

linestring = QgsGeometry.fromWkt("LineString (1 0, 2 0)")
self.assertEqual(linestring.transform(ct), 0, "Transform failed")
expwkt = "LineString (111319 0, 222638 0)"
wkt = linestring.asWkt()
assert compareWkt(expwkt, wkt, tol=100), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)

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)))")
self.assertEqual(polygon.transform(ct), 0, "Transform failed")
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)))"
wkt = polygon.asWkt()
assert compareWkt(expwkt, wkt, tol=100), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)

# reverse transform
point = QgsGeometry.fromWkt("Point (111319 111325)")
self.assertEqual(point.transform(ct, QgsCoordinateTransform.ReverseTransform), 0, "Transform failed")
expwkt = "Point (1 1)"
wkt = point.asWkt()
assert compareWkt(expwkt, wkt, tol=0.01), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)

point = QgsGeometry.fromWkt("MultiPoint ((111319 111325),(222638 222684),(333958 334111))")
self.assertEqual(point.transform(ct, QgsCoordinateTransform.ReverseTransform), 0, "Transform failed")
expwkt = "MultiPoint ((1 1),(2 2),(3 3))"
wkt = point.asWkt()
assert compareWkt(expwkt, wkt, tol=0.01), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)

linestring = QgsGeometry.fromWkt("LineString (111319 0, 222638 0)")
self.assertEqual(linestring.transform(ct, QgsCoordinateTransform.ReverseTransform), 0, "Transform failed")
expwkt = "LineString (1 0, 2 0)"
wkt = linestring.asWkt()
assert compareWkt(expwkt, wkt, tol=0.01), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)

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)))")
self.assertEqual(polygon.transform(ct, QgsCoordinateTransform.ReverseTransform), 0, "Transform failed")
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)))"
wkt = polygon.asWkt()
assert compareWkt(expwkt, wkt, tol=0.01), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt)

def testExtrude(self):
# test with empty geometry
Expand Down

0 comments on commit 37295ec

Please sign in to comment.