Skip to content
Permalink
Browse files

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
  • Loading branch information
nyalldawson committed Jun 28, 2016
1 parent 58dbe56 commit 1729531773e254f35777dd26080f4c86be0a1e15
@@ -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
@@ -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;

@@ -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;
@@ -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 );
@@ -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 );
@@ -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;
@@ -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;

@@ -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
@@ -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 )
@@ -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;
}
@@ -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;

@@ -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();
}
@@ -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;
@@ -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();
}
@@ -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;
@@ -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
}
@@ -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;
@@ -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 )
@@ -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;
}
@@ -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;
@@ -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
@@ -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;

@@ -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;

@@ -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 );
@@ -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 );
}

@@ -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 );

0 comments on commit 1729531

Please sign in to comment.
You can’t perform that action at this time.