Skip to content

Commit

Permalink
Don't transform z coordinates by default
Browse files Browse the repository at this point in the history
Since z coordinates can represent potentially any height
unit and reference point, it's not safe to assume that they
always represent height in metres relative to the ellipsoid.

Instead, leave z values untouched by default with geometry
transforms, and make transforming z an optional parameter

Refs #14702
  • Loading branch information
nyalldawson committed Jun 29, 2016
1 parent 58dbe56 commit 1729531
Show file tree
Hide file tree
Showing 23 changed files with 73 additions and 74 deletions.
12 changes: 9 additions & 3 deletions python/core/geometry/qgsabstractgeometryv2.sip
Expand Up @@ -203,9 +203,15 @@ class QgsAbstractGeometryV2

/** Transforms the geometry using a coordinate transform
* @param ct coordinate transform
@param d transformation direction
*/
virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) = 0;
* @param d transformation direction
* @param transformZ set to true to also transform z coordinates. 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 metres). If false, then z coordinates will not be changed by the
* transform.
*/
virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false ) = 0;

/** Transforms the geometry using a QTransform object
* @param t QTransform transformation
Expand Down
8 changes: 2 additions & 6 deletions python/core/geometry/qgscircularstringv2.sip
Expand Up @@ -61,12 +61,8 @@ class QgsCircularStringV2: public QgsCurveV2
virtual QgsLineStringV2* curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const;

void draw( QPainter& p ) const;

/** Transforms the geometry using a coordinate transform
* @param ct coordinate transform
* @param d transformation direction
*/
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false );
void transform( const QTransform& t );
void addToPainterPath( QPainterPath& path ) const;

Expand Down
7 changes: 2 additions & 5 deletions python/core/geometry/qgscompoundcurvev2.sip
Expand Up @@ -62,11 +62,8 @@ class QgsCompoundCurveV2: public QgsCurveV2
void addVertex( const QgsPointV2& pt );

void draw( QPainter& p ) const;
/** Transforms the geometry using a coordinate transform
* @param ct coordinate transform
@param d transformation direction
*/
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false );
void transform( const QTransform& t );
void addToPainterPath( QPainterPath& path ) const;
void drawAsPolygon( QPainter& p ) const;
Expand Down
7 changes: 2 additions & 5 deletions python/core/geometry/qgscurvepolygonv2.sip
Expand Up @@ -57,11 +57,8 @@ class QgsCurvePolygonV2: public QgsSurfaceV2
bool removeInteriorRing( int nr );

virtual void draw( QPainter& p ) const;
/** Transforms the geometry using a coordinate transform
* @param ct coordinate transform
* @param d transformation direction
*/
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false );
void transform( const QTransform& t );

virtual bool insertVertex( QgsVertexId position, const QgsPointV2& vertex );
Expand Down
7 changes: 2 additions & 5 deletions python/core/geometry/qgsgeometrycollectionv2.sip
Expand Up @@ -46,11 +46,8 @@ class QgsGeometryCollectionV2: public QgsAbstractGeometryV2
*/
virtual bool removeGeometry( int nr );

/** Transforms the geometry using a coordinate transform
* @param ct coordinate transform
* @param d transformation direction
*/
virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false );
void transform( const QTransform& t );

//virtual void clip( const QgsRectangle& rect );
Expand Down
4 changes: 2 additions & 2 deletions python/core/geometry/qgslinestringv2.sip
Expand Up @@ -141,8 +141,8 @@ class QgsLineStringV2: public QgsCurveV2
void points( QList<QgsPointV2>& pt ) const;

void draw( QPainter& p ) const;

void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false );
void transform( const QTransform& t );

void addToPainterPath( QPainterPath& path ) const;
Expand Down
3 changes: 2 additions & 1 deletion python/core/geometry/qgspointv2.sip
Expand Up @@ -153,7 +153,8 @@ class QgsPointV2: public QgsAbstractGeometryV2
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const;
QString asJSON( int precision = 17 ) const;
void draw( QPainter& p ) const;
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false );
void transform( const QTransform& t );
virtual QList< QList< QList< QgsPointV2 > > > coordinateSequence() const;

Expand Down
12 changes: 9 additions & 3 deletions src/core/geometry/qgsabstractgeometryv2.h
Expand Up @@ -187,9 +187,15 @@ class CORE_EXPORT QgsAbstractGeometryV2

/** Transforms the geometry using a coordinate transform
* @param ct coordinate transform
@param d transformation direction
*/
virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) = 0;
* @param d transformation direction
* @param transformZ set to true to also transform z coordinates. 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 metres). If false, then z coordinates will not be changed by the
* transform.
*/
virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false ) = 0;

/** Transforms the geometry using a QTransform object
* @param t QTransform transformation
Expand Down
7 changes: 4 additions & 3 deletions src/core/geometry/qgscircularstringv2.cpp
Expand Up @@ -629,15 +629,16 @@ void QgsCircularStringV2::draw( QPainter& p ) const
p.drawPath( path );
}

void QgsCircularStringV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d )
void QgsCircularStringV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d, bool transformZ )
{
clearCache();

double* zArray = mZ.data();

bool hasZ = is3D();
int nPoints = numPoints();
if ( !hasZ )
bool useDummyZ = !hasZ || !transformZ;
if ( useDummyZ )
{
zArray = new double[nPoints];
for ( int i = 0; i < nPoints; ++i )
Expand All @@ -646,7 +647,7 @@ void QgsCircularStringV2::transform( const QgsCoordinateTransform& ct, QgsCoordi
}
}
ct.transformCoords( nPoints, mX.data(), mY.data(), zArray, d );
if ( !hasZ )
if ( useDummyZ )
{
delete[] zArray;
}
Expand Down
8 changes: 2 additions & 6 deletions src/core/geometry/qgscircularstringv2.h
Expand Up @@ -86,12 +86,8 @@ class CORE_EXPORT QgsCircularStringV2: public QgsCurveV2
virtual QgsLineStringV2* curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override;

void draw( QPainter& p ) const override;

/** Transforms the geometry using a coordinate transform
* @param ct coordinate transform
* @param d transformation direction
*/
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false ) override;
void transform( const QTransform& t ) override;
void addToPainterPath( QPainterPath& path ) const override;

Expand Down
4 changes: 2 additions & 2 deletions src/core/geometry/qgscompoundcurvev2.cpp
Expand Up @@ -458,11 +458,11 @@ void QgsCompoundCurveV2::draw( QPainter& p ) const
}
}

void QgsCompoundCurveV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d )
void QgsCompoundCurveV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d, bool transformZ )
{
Q_FOREACH ( QgsCurveV2* curve, mCurves )
{
curve->transform( ct, d );
curve->transform( ct, d, transformZ );
}
clearCache();
}
Expand Down
7 changes: 2 additions & 5 deletions src/core/geometry/qgscompoundcurvev2.h
Expand Up @@ -86,11 +86,8 @@ class CORE_EXPORT QgsCompoundCurveV2: public QgsCurveV2
void addVertex( const QgsPointV2& pt );

void draw( QPainter& p ) const override;
/** Transforms the geometry using a coordinate transform
* @param ct coordinate transform
@param d transformation direction
*/
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false ) override;
void transform( const QTransform& t ) override;
void addToPainterPath( QPainterPath& path ) const override;
void drawAsPolygon( QPainter& p ) const override;
Expand Down
6 changes: 3 additions & 3 deletions src/core/geometry/qgscurvepolygonv2.cpp
Expand Up @@ -561,16 +561,16 @@ void QgsCurvePolygonV2::draw( QPainter& p ) const
}
}

void QgsCurvePolygonV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d )
void QgsCurvePolygonV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d, bool transformZ )
{
if ( mExteriorRing )
{
mExteriorRing->transform( ct, d );
mExteriorRing->transform( ct, d, transformZ );
}

Q_FOREACH ( QgsCurveV2* curve, mInteriorRings )
{
curve->transform( ct, d );
curve->transform( ct, d, transformZ );
}
clearCache();
}
Expand Down
7 changes: 2 additions & 5 deletions src/core/geometry/qgscurvepolygonv2.h
Expand Up @@ -83,11 +83,8 @@ class CORE_EXPORT QgsCurvePolygonV2: public QgsSurfaceV2
bool removeInteriorRing( int nr );

virtual void draw( QPainter& p ) const override;
/** Transforms the geometry using a coordinate transform
* @param ct coordinate transform
* @param d transformation direction
*/
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false ) override;
void transform( const QTransform& t ) override;

virtual bool insertVertex( QgsVertexId position, const QgsPointV2& vertex ) override;
Expand Down
4 changes: 2 additions & 2 deletions src/core/geometry/qgsgeometrycollectionv2.cpp
Expand Up @@ -142,11 +142,11 @@ int QgsGeometryCollectionV2::dimension() const
return maxDim;
}

void QgsGeometryCollectionV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d )
void QgsGeometryCollectionV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d, bool transformZ )
{
Q_FOREACH ( QgsAbstractGeometryV2* g, mGeometries )
{
g->transform( ct, d );
g->transform( ct, d, transformZ );
}
clearCache(); //set bounding box invalid
}
Expand Down
7 changes: 2 additions & 5 deletions src/core/geometry/qgsgeometrycollectionv2.h
Expand Up @@ -70,11 +70,8 @@ class CORE_EXPORT QgsGeometryCollectionV2: public QgsAbstractGeometryV2
*/
virtual bool removeGeometry( int nr );

/** Transforms the geometry using a coordinate transform
* @param ct coordinate transform
* @param d transformation direction
*/
virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false ) override;
void transform( const QTransform& t ) override;
#if 0
virtual void clip( const QgsRectangle& rect ) override;
Expand Down
7 changes: 4 additions & 3 deletions src/core/geometry/qgslinestringv2.cpp
Expand Up @@ -599,13 +599,14 @@ QgsAbstractGeometryV2* QgsLineStringV2::toCurveType() const
* See details in QEP #17
****************************************************************************/

void QgsLineStringV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d )
void QgsLineStringV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d, bool transformZ )
{
double* zArray = mZ.data();

bool hasZ = is3D();
int nPoints = numPoints();
if ( !hasZ )
bool useDummyZ = !hasZ || !transformZ;
if ( useDummyZ )
{
zArray = new double[nPoints];
for ( int i = 0; i < nPoints; ++i )
Expand All @@ -614,7 +615,7 @@ void QgsLineStringV2::transform( const QgsCoordinateTransform& ct, QgsCoordinate
}
}
ct.transformCoords( nPoints, mX.data(), mY.data(), zArray, d );
if ( !hasZ )
if ( useDummyZ )
{
delete[] zArray;
}
Expand Down
3 changes: 2 additions & 1 deletion src/core/geometry/qgslinestringv2.h
Expand Up @@ -168,7 +168,8 @@ class CORE_EXPORT QgsLineStringV2: public QgsCurveV2

void draw( QPainter& p ) const override;

void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false ) override;
void transform( const QTransform& t ) override;

void addToPainterPath( QPainterPath& path ) const override;
Expand Down
12 changes: 10 additions & 2 deletions src/core/geometry/qgspointv2.cpp
Expand Up @@ -257,10 +257,18 @@ void QgsPointV2::clear()
clearCache();
}

void QgsPointV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d )
void QgsPointV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d, bool transformZ )
{
clearCache();
ct.transformInPlace( mX, mY, mZ, d );
if ( transformZ )
{
ct.transformInPlace( mX, mY, mZ, d );
}
else
{
double z = 0.0;
ct.transformInPlace( mX, mY, z, d );
}
}

QgsCoordinateSequenceV2 QgsPointV2::coordinateSequence() const
Expand Down
3 changes: 2 additions & 1 deletion src/core/geometry/qgspointv2.h
Expand Up @@ -165,7 +165,8 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometryV2
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const override;
QString asJSON( int precision = 17 ) const override;
void draw( QPainter& p ) const override;
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false ) override;
void transform( const QTransform& t ) override;
virtual QgsCoordinateSequenceV2 coordinateSequence() const override;

Expand Down
6 changes: 3 additions & 3 deletions src/core/qgscoordinatetransform.h
Expand Up @@ -159,11 +159,11 @@ class CORE_EXPORT QgsCoordinateTransform : public QObject
// C style arrays.
void transformInPlace( double& x, double& y, double &z, TransformDirection direction = ForwardTransform ) const;

// @note not available in python bindings
//! @note not available in python bindings
void transformInPlace( float& x, float& y, double &z, TransformDirection direction = ForwardTransform ) const;
// @note not available in python bindings
//! @note not available in python bindings
void transformInPlace( float& x, float& y, float& z, TransformDirection direction = ForwardTransform ) const;
// @note not available in python bindings
//! @note not available in python bindings
void transformInPlace( QVector<float>& x, QVector<float>& y, QVector<float>& z,
TransformDirection direction = ForwardTransform ) const;

Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgslinesymbollayerv2.cpp
Expand Up @@ -1063,7 +1063,7 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
{
//transform
x = vPoint.x(), y = vPoint.y();
z = vPoint.z();
z = 0.0;
if ( ct )
{
ct->transformInPlace( x, y, z );
Expand Down
4 changes: 2 additions & 2 deletions src/core/symbology-ng/qgssymbolv2.cpp
Expand Up @@ -115,7 +115,7 @@ QgsConstWkbPtr QgsSymbolV2::_getPoint( QPointF& pt, QgsRenderContext& context, Q

if ( context.coordinateTransform() )
{
double z = 0; // dummy variable for coordiante transform
double z = 0; // dummy variable for coordinate transform
context.coordinateTransform()->transformInPlace( pt.rx(), pt.ry(), z );
}

Expand Down Expand Up @@ -993,7 +993,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
//transform
x = vertexPoint.x();
y = vertexPoint.y();
z = vertexPoint.z();
z = 0.0;
if ( ct )
{
ct->transformInPlace( x, y, z );
Expand Down

0 comments on commit 1729531

Please sign in to comment.