Don't transform z coordinates by default

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
This commit is contained in:
Nyall Dawson 2016-06-29 09:22:23 +10:00
parent 58dbe56213
commit 1729531773
23 changed files with 71 additions and 72 deletions

View File

@ -203,9 +203,15 @@ class QgsAbstractGeometryV2
/** Transforms the geometry using a coordinate transform /** Transforms the geometry using a coordinate transform
* @param ct coordinate transform * @param ct coordinate transform
@param d transformation direction * @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 ) = 0; virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false ) = 0;
/** Transforms the geometry using a QTransform object /** Transforms the geometry using a QTransform object
* @param t QTransform transformation * @param t QTransform transformation

View File

@ -61,12 +61,8 @@ class QgsCircularStringV2: public QgsCurveV2
virtual QgsLineStringV2* curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const; virtual QgsLineStringV2* curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const;
void draw( QPainter& p ) const; void draw( QPainter& p ) const;
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
/** Transforms the geometry using a coordinate transform bool transformZ = false );
* @param ct coordinate transform
* @param d transformation direction
*/
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QTransform& t ); void transform( const QTransform& t );
void addToPainterPath( QPainterPath& path ) const; void addToPainterPath( QPainterPath& path ) const;

View File

@ -62,11 +62,8 @@ class QgsCompoundCurveV2: public QgsCurveV2
void addVertex( const QgsPointV2& pt ); void addVertex( const QgsPointV2& pt );
void draw( QPainter& p ) const; void draw( QPainter& p ) const;
/** Transforms the geometry using a coordinate transform void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
* @param ct coordinate transform bool transformZ = false );
@param d transformation direction
*/
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QTransform& t ); void transform( const QTransform& t );
void addToPainterPath( QPainterPath& path ) const; void addToPainterPath( QPainterPath& path ) const;
void drawAsPolygon( QPainter& p ) const; void drawAsPolygon( QPainter& p ) const;

View File

@ -57,11 +57,8 @@ class QgsCurvePolygonV2: public QgsSurfaceV2
bool removeInteriorRing( int nr ); bool removeInteriorRing( int nr );
virtual void draw( QPainter& p ) const; virtual void draw( QPainter& p ) const;
/** Transforms the geometry using a coordinate transform void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
* @param ct coordinate transform bool transformZ = false );
* @param d transformation direction
*/
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QTransform& t ); void transform( const QTransform& t );
virtual bool insertVertex( QgsVertexId position, const QgsPointV2& vertex ); virtual bool insertVertex( QgsVertexId position, const QgsPointV2& vertex );

View File

@ -46,11 +46,8 @@ class QgsGeometryCollectionV2: public QgsAbstractGeometryV2
*/ */
virtual bool removeGeometry( int nr ); virtual bool removeGeometry( int nr );
/** Transforms the geometry using a coordinate transform void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
* @param ct coordinate transform bool transformZ = false );
* @param d transformation direction
*/
virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
void transform( const QTransform& t ); void transform( const QTransform& t );
//virtual void clip( const QgsRectangle& rect ); //virtual void clip( const QgsRectangle& rect );

View File

@ -141,8 +141,8 @@ class QgsLineStringV2: public QgsCurveV2
void points( QList<QgsPointV2>& pt ) const; void points( QList<QgsPointV2>& pt ) const;
void draw( QPainter& p ) 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 transform( const QTransform& t );
void addToPainterPath( QPainterPath& path ) const; void addToPainterPath( QPainterPath& path ) const;

View File

@ -153,7 +153,8 @@ class QgsPointV2: public QgsAbstractGeometryV2
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const; QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const;
QString asJSON( int precision = 17 ) const; QString asJSON( int precision = 17 ) const;
void draw( QPainter& p ) 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 transform( const QTransform& t );
virtual QList< QList< QList< QgsPointV2 > > > coordinateSequence() const; virtual QList< QList< QList< QgsPointV2 > > > coordinateSequence() const;

View File

@ -187,9 +187,15 @@ class CORE_EXPORT QgsAbstractGeometryV2
/** Transforms the geometry using a coordinate transform /** Transforms the geometry using a coordinate transform
* @param ct coordinate transform * @param ct coordinate transform
@param d transformation direction * @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 ) = 0; virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
bool transformZ = false ) = 0;
/** Transforms the geometry using a QTransform object /** Transforms the geometry using a QTransform object
* @param t QTransform transformation * @param t QTransform transformation

View File

@ -629,7 +629,7 @@ void QgsCircularStringV2::draw( QPainter& p ) const
p.drawPath( path ); p.drawPath( path );
} }
void QgsCircularStringV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d ) void QgsCircularStringV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d, bool transformZ )
{ {
clearCache(); clearCache();
@ -637,7 +637,8 @@ void QgsCircularStringV2::transform( const QgsCoordinateTransform& ct, QgsCoordi
bool hasZ = is3D(); bool hasZ = is3D();
int nPoints = numPoints(); int nPoints = numPoints();
if ( !hasZ ) bool useDummyZ = !hasZ || !transformZ;
if ( useDummyZ )
{ {
zArray = new double[nPoints]; zArray = new double[nPoints];
for ( int i = 0; i < nPoints; ++i ) for ( int i = 0; i < nPoints; ++i )
@ -646,7 +647,7 @@ void QgsCircularStringV2::transform( const QgsCoordinateTransform& ct, QgsCoordi
} }
} }
ct.transformCoords( nPoints, mX.data(), mY.data(), zArray, d ); ct.transformCoords( nPoints, mX.data(), mY.data(), zArray, d );
if ( !hasZ ) if ( useDummyZ )
{ {
delete[] zArray; delete[] zArray;
} }

View File

@ -86,12 +86,8 @@ class CORE_EXPORT QgsCircularStringV2: public QgsCurveV2
virtual QgsLineStringV2* curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override; virtual QgsLineStringV2* curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override;
void draw( QPainter& p ) const override; void draw( QPainter& p ) const override;
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
/** Transforms the geometry using a coordinate transform bool transformZ = false ) override;
* @param ct coordinate transform
* @param d transformation direction
*/
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
void transform( const QTransform& t ) override; void transform( const QTransform& t ) override;
void addToPainterPath( QPainterPath& path ) const override; void addToPainterPath( QPainterPath& path ) const override;

View File

@ -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 ) Q_FOREACH ( QgsCurveV2* curve, mCurves )
{ {
curve->transform( ct, d ); curve->transform( ct, d, transformZ );
} }
clearCache(); clearCache();
} }

View File

@ -86,11 +86,8 @@ class CORE_EXPORT QgsCompoundCurveV2: public QgsCurveV2
void addVertex( const QgsPointV2& pt ); void addVertex( const QgsPointV2& pt );
void draw( QPainter& p ) const override; void draw( QPainter& p ) const override;
/** Transforms the geometry using a coordinate transform void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
* @param ct coordinate transform bool transformZ = false ) override;
@param d transformation direction
*/
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
void transform( const QTransform& t ) override; void transform( const QTransform& t ) override;
void addToPainterPath( QPainterPath& path ) const override; void addToPainterPath( QPainterPath& path ) const override;
void drawAsPolygon( QPainter& p ) const override; void drawAsPolygon( QPainter& p ) const override;

View File

@ -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 ) if ( mExteriorRing )
{ {
mExteriorRing->transform( ct, d ); mExteriorRing->transform( ct, d, transformZ );
} }
Q_FOREACH ( QgsCurveV2* curve, mInteriorRings ) Q_FOREACH ( QgsCurveV2* curve, mInteriorRings )
{ {
curve->transform( ct, d ); curve->transform( ct, d, transformZ );
} }
clearCache(); clearCache();
} }

View File

@ -83,11 +83,8 @@ class CORE_EXPORT QgsCurvePolygonV2: public QgsSurfaceV2
bool removeInteriorRing( int nr ); bool removeInteriorRing( int nr );
virtual void draw( QPainter& p ) const override; virtual void draw( QPainter& p ) const override;
/** Transforms the geometry using a coordinate transform void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
* @param ct coordinate transform bool transformZ = false ) override;
* @param d transformation direction
*/
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
void transform( const QTransform& t ) override; void transform( const QTransform& t ) override;
virtual bool insertVertex( QgsVertexId position, const QgsPointV2& vertex ) override; virtual bool insertVertex( QgsVertexId position, const QgsPointV2& vertex ) override;

View File

@ -142,11 +142,11 @@ int QgsGeometryCollectionV2::dimension() const
return maxDim; 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 ) Q_FOREACH ( QgsAbstractGeometryV2* g, mGeometries )
{ {
g->transform( ct, d ); g->transform( ct, d, transformZ );
} }
clearCache(); //set bounding box invalid clearCache(); //set bounding box invalid
} }

View File

@ -70,11 +70,8 @@ class CORE_EXPORT QgsGeometryCollectionV2: public QgsAbstractGeometryV2
*/ */
virtual bool removeGeometry( int nr ); virtual bool removeGeometry( int nr );
/** Transforms the geometry using a coordinate transform virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
* @param ct coordinate transform bool transformZ = false ) override;
* @param d transformation direction
*/
virtual void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
void transform( const QTransform& t ) override; void transform( const QTransform& t ) override;
#if 0 #if 0
virtual void clip( const QgsRectangle& rect ) override; virtual void clip( const QgsRectangle& rect ) override;

View File

@ -599,13 +599,14 @@ QgsAbstractGeometryV2* QgsLineStringV2::toCurveType() const
* See details in QEP #17 * 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(); double* zArray = mZ.data();
bool hasZ = is3D(); bool hasZ = is3D();
int nPoints = numPoints(); int nPoints = numPoints();
if ( !hasZ ) bool useDummyZ = !hasZ || !transformZ;
if ( useDummyZ )
{ {
zArray = new double[nPoints]; zArray = new double[nPoints];
for ( int i = 0; i < nPoints; ++i ) for ( int i = 0; i < nPoints; ++i )
@ -614,7 +615,7 @@ void QgsLineStringV2::transform( const QgsCoordinateTransform& ct, QgsCoordinate
} }
} }
ct.transformCoords( nPoints, mX.data(), mY.data(), zArray, d ); ct.transformCoords( nPoints, mX.data(), mY.data(), zArray, d );
if ( !hasZ ) if ( useDummyZ )
{ {
delete[] zArray; delete[] zArray;
} }

View File

@ -168,7 +168,8 @@ class CORE_EXPORT QgsLineStringV2: public QgsCurveV2
void draw( QPainter& p ) 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; void transform( const QTransform& t ) override;
void addToPainterPath( QPainterPath& path ) const override; void addToPainterPath( QPainterPath& path ) const override;

View File

@ -257,10 +257,18 @@ void QgsPointV2::clear()
clearCache(); clearCache();
} }
void QgsPointV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d ) void QgsPointV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d, bool transformZ )
{ {
clearCache(); 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 QgsCoordinateSequenceV2 QgsPointV2::coordinateSequence() const

View File

@ -165,7 +165,8 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometryV2
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const override; QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const override;
QString asJSON( int precision = 17 ) const override; QString asJSON( int precision = 17 ) const override;
void draw( QPainter& p ) 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; void transform( const QTransform& t ) override;
virtual QgsCoordinateSequenceV2 coordinateSequence() const override; virtual QgsCoordinateSequenceV2 coordinateSequence() const override;

View File

@ -159,11 +159,11 @@ class CORE_EXPORT QgsCoordinateTransform : public QObject
// C style arrays. // C style arrays.
void transformInPlace( double& x, double& y, double &z, TransformDirection direction = ForwardTransform ) const; 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; 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; 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, void transformInPlace( QVector<float>& x, QVector<float>& y, QVector<float>& z,
TransformDirection direction = ForwardTransform ) const; TransformDirection direction = ForwardTransform ) const;

View File

@ -1063,7 +1063,7 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
{ {
//transform //transform
x = vPoint.x(), y = vPoint.y(); x = vPoint.x(), y = vPoint.y();
z = vPoint.z(); z = 0.0;
if ( ct ) if ( ct )
{ {
ct->transformInPlace( x, y, z ); ct->transformInPlace( x, y, z );

View File

@ -115,7 +115,7 @@ QgsConstWkbPtr QgsSymbolV2::_getPoint( QPointF& pt, QgsRenderContext& context, Q
if ( context.coordinateTransform() ) 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 ); context.coordinateTransform()->transformInPlace( pt.rx(), pt.ry(), z );
} }
@ -993,7 +993,7 @@ void QgsSymbolV2::renderFeature( const QgsFeature& feature, QgsRenderContext& co
//transform //transform
x = vertexPoint.x(); x = vertexPoint.x();
y = vertexPoint.y(); y = vertexPoint.y();
z = vertexPoint.z(); z = 0.0;
if ( ct ) if ( ct )
{ {
ct->transformInPlace( x, y, z ); ct->transformInPlace( x, y, z );