Skip to content

Commit

Permalink
Use NaN for missing Z and M coordinates in QgsPoint
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Jun 14, 2017
1 parent 96cf4b7 commit 7f17498
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 29 deletions.
67 changes: 42 additions & 25 deletions src/core/geometry/qgspoint.cpp
Expand Up @@ -60,8 +60,8 @@ QgsPoint::QgsPoint( const QgsPointXY &p )
: QgsAbstractGeometry()
, mX( p.x() )
, mY( p.y() )
, mZ( 0.0 )
, mM( 0.0 )
, mZ( std::numeric_limits<double>::quiet_NaN() )
, mM( std::numeric_limits<double>::quiet_NaN() )
{
mWkbType = QgsWkbTypes::Point;
}
Expand All @@ -70,8 +70,8 @@ QgsPoint::QgsPoint( QPointF p )
: QgsAbstractGeometry()
, mX( p.x() )
, mY( p.y() )
, mZ( 0.0 )
, mM( 0.0 )
, mZ( std::numeric_limits<double>::quiet_NaN() )
, mM( std::numeric_limits<double>::quiet_NaN() )
{
mWkbType = QgsWkbTypes::Point;
}
Expand Down Expand Up @@ -272,7 +272,17 @@ void QgsPoint::draw( QPainter &p ) const

void QgsPoint::clear()
{
mX = mY = mZ = mM = 0.;
mX = mY = 0.;
if ( is3D() )
mZ = 0.;
else
mZ = std::numeric_limits<double>::quiet_NaN();

if ( isMeasure() )
mM = 0.;
else
mM = std::numeric_limits<double>::quiet_NaN();

clearCache();
}

Expand Down Expand Up @@ -404,7 +414,7 @@ bool QgsPoint::dropZValue()
return false;

mWkbType = QgsWkbTypes::dropZ( mWkbType );
mZ = 0.0;
mZ = std::numeric_limits<double>::quiet_NaN();
clearCache();
return true;
}
Expand All @@ -415,7 +425,7 @@ bool QgsPoint::dropMValue()
return false;

mWkbType = QgsWkbTypes::dropM( mWkbType );
mM = 0.0;
mM = std::numeric_limits<double>::quiet_NaN();
clearCache();
return true;
}
Expand All @@ -430,17 +440,17 @@ bool QgsPoint::convertTo( QgsWkbTypes::Type type )
switch ( type )
{
case QgsWkbTypes::Point:
mZ = 0.0;
mM = 0.0;
mZ = std::numeric_limits<double>::quiet_NaN();
mM = std::numeric_limits<double>::quiet_NaN();
mWkbType = type;
return true;
case QgsWkbTypes::PointZ:
case QgsWkbTypes::Point25D:
mM = 0.0;
mM = std::numeric_limits<double>::quiet_NaN();
mWkbType = type;
return true;
case QgsWkbTypes::PointM:
mZ = 0.0;
mZ = std::numeric_limits<double>::quiet_NaN();
mWkbType = type;
return true;
case QgsWkbTypes::PointZM:
Expand Down Expand Up @@ -481,22 +491,38 @@ double QgsPoint::distanceSquared( const QgsPoint &other ) const

double QgsPoint::distance3D( double x, double y, double z ) const
{
return sqrt( ( mX - x ) * ( mX - x ) + ( mY - y ) * ( mY - y ) + ( mZ - z ) * ( mZ - z ) );
double zDistSquared = 0.0;
if ( is3D() || !qIsNaN( z ) )
zDistSquared = ( mZ - z ) * ( mZ - z );

return sqrt( ( mX - x ) * ( mX - x ) + ( mY - y ) * ( mY - y ) + zDistSquared );
}

double QgsPoint::distance3D( const QgsPoint &other ) const
{
return sqrt( ( mX - other.x() ) * ( mX - other.x() ) + ( mY - other.y() ) * ( mY - other.y() ) + ( mZ - other.z() ) * ( mZ - other.z() ) );
double zDistSquared = 0.0;
if ( is3D() || other.is3D() )
zDistSquared = ( mZ - other.z() ) * ( mZ - other.z() );

return sqrt( ( mX - other.x() ) * ( mX - other.x() ) + ( mY - other.y() ) * ( mY - other.y() ) + zDistSquared );
}

double QgsPoint::distanceSquared3D( double x, double y, double z ) const
{
return ( mX - x ) * ( mX - x ) + ( mY - y ) * ( mY - y ) + ( mZ - z ) * ( mZ - z );
double zDistSquared = 0.0;
if ( is3D() || !qIsNaN( z ) )
zDistSquared = ( mZ - z ) * ( mZ - z );

return ( mX - x ) * ( mX - x ) + ( mY - y ) * ( mY - y ) + zDistSquared;
}

double QgsPoint::distanceSquared3D( const QgsPoint &other ) const
{
return ( mX - other.x() ) * ( mX - other.x() ) + ( mY - other.y() ) * ( mY - other.y() ) + ( mZ - other.z() ) * ( mZ - other.z() );
double zDistSquared = 0.0;
if ( is3D() || other.is3D() )
zDistSquared = ( mZ - other.z() ) * ( mZ - other.z() );

return ( mX - other.x() ) * ( mX - other.x() ) + ( mY - other.y() ) * ( mY - other.y() ) + zDistSquared;
}

double QgsPoint::azimuth( const QgsPoint &other ) const
Expand All @@ -520,8 +546,6 @@ double QgsPoint::inclination( const QgsPoint &other ) const

QgsPoint QgsPoint::project( double distance, double azimuth, double inclination ) const
{
QgsWkbTypes::Type pType( QgsWkbTypes::Point );

double radsXy = azimuth * M_PI / 180.0;
double dx = 0.0, dy = 0.0, dz = 0.0;

Expand All @@ -534,18 +558,11 @@ QgsPoint QgsPoint::project( double distance, double azimuth, double inclination
}
else
{
pType = QgsWkbTypes::addZ( pType );
double radsZ = inclination * M_PI / 180.0;
dx = distance * sin( radsZ ) * sin( radsXy );
dy = distance * sin( radsZ ) * cos( radsXy );
dz = distance * cos( radsZ );
}

if ( isMeasure() )
{
pType = QgsWkbTypes::addM( pType );
}

double z = qIsNaN( mZ ) ? 0 : mZ;
return QgsPoint( mX + dx, mY + dy, z + dz, mM, pType );
return QgsPoint( mX + dx, mY + dy, mZ + dz, mM, mWkbType );
}
28 changes: 24 additions & 4 deletions src/core/geometry/qgspoint.h
Expand Up @@ -177,29 +177,49 @@ class CORE_EXPORT QgsPoint: public QgsAbstractGeometry
* \see x()
* \see rx()
*/
void setX( double x ) { clearCache(); mX = x; }
void setX( double x )
{
clearCache();
mX = x;
}

/** Sets the point's y-coordinate.
* \see y()
* \see ry()
*/
void setY( double y ) { clearCache(); mY = y; }
void setY( double y )
{
clearCache();
mY = y;
}

/** Sets the point's z-coordinate.
* \note calling this will have no effect if the point does not contain a z-dimension. Use addZValue() to
* add a z value and force the point to have a z dimension.
* \see z()
* \see rz()
*/
void setZ( double z ) { clearCache(); mZ = z; }
void setZ( double z )
{
if ( !is3D() )
return;
clearCache();
mZ = z;
}

/** Sets the point's m-value.
* \note calling this will have no effect if the point does not contain a m-dimension. Use addMValue() to
* add a m value and force the point to have an m dimension.
* \see m()
* \see rm()
*/
void setM( double m ) { clearCache(); mM = m; }
void setM( double m )
{
if ( !isMeasure() )
return;
clearCache();
mM = m;
}

/** Returns the point as a QPointF.
* \since QGIS 2.14
Expand Down

0 comments on commit 7f17498

Please sign in to comment.