Skip to content

Commit 7f17498

Browse files
committed
Use NaN for missing Z and M coordinates in QgsPoint
1 parent 96cf4b7 commit 7f17498

File tree

2 files changed

+66
-29
lines changed

2 files changed

+66
-29
lines changed

src/core/geometry/qgspoint.cpp

+42-25
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ QgsPoint::QgsPoint( const QgsPointXY &p )
6060
: QgsAbstractGeometry()
6161
, mX( p.x() )
6262
, mY( p.y() )
63-
, mZ( 0.0 )
64-
, mM( 0.0 )
63+
, mZ( std::numeric_limits<double>::quiet_NaN() )
64+
, mM( std::numeric_limits<double>::quiet_NaN() )
6565
{
6666
mWkbType = QgsWkbTypes::Point;
6767
}
@@ -70,8 +70,8 @@ QgsPoint::QgsPoint( QPointF p )
7070
: QgsAbstractGeometry()
7171
, mX( p.x() )
7272
, mY( p.y() )
73-
, mZ( 0.0 )
74-
, mM( 0.0 )
73+
, mZ( std::numeric_limits<double>::quiet_NaN() )
74+
, mM( std::numeric_limits<double>::quiet_NaN() )
7575
{
7676
mWkbType = QgsWkbTypes::Point;
7777
}
@@ -272,7 +272,17 @@ void QgsPoint::draw( QPainter &p ) const
272272

273273
void QgsPoint::clear()
274274
{
275-
mX = mY = mZ = mM = 0.;
275+
mX = mY = 0.;
276+
if ( is3D() )
277+
mZ = 0.;
278+
else
279+
mZ = std::numeric_limits<double>::quiet_NaN();
280+
281+
if ( isMeasure() )
282+
mM = 0.;
283+
else
284+
mM = std::numeric_limits<double>::quiet_NaN();
285+
276286
clearCache();
277287
}
278288

@@ -404,7 +414,7 @@ bool QgsPoint::dropZValue()
404414
return false;
405415

406416
mWkbType = QgsWkbTypes::dropZ( mWkbType );
407-
mZ = 0.0;
417+
mZ = std::numeric_limits<double>::quiet_NaN();
408418
clearCache();
409419
return true;
410420
}
@@ -415,7 +425,7 @@ bool QgsPoint::dropMValue()
415425
return false;
416426

417427
mWkbType = QgsWkbTypes::dropM( mWkbType );
418-
mM = 0.0;
428+
mM = std::numeric_limits<double>::quiet_NaN();
419429
clearCache();
420430
return true;
421431
}
@@ -430,17 +440,17 @@ bool QgsPoint::convertTo( QgsWkbTypes::Type type )
430440
switch ( type )
431441
{
432442
case QgsWkbTypes::Point:
433-
mZ = 0.0;
434-
mM = 0.0;
443+
mZ = std::numeric_limits<double>::quiet_NaN();
444+
mM = std::numeric_limits<double>::quiet_NaN();
435445
mWkbType = type;
436446
return true;
437447
case QgsWkbTypes::PointZ:
438448
case QgsWkbTypes::Point25D:
439-
mM = 0.0;
449+
mM = std::numeric_limits<double>::quiet_NaN();
440450
mWkbType = type;
441451
return true;
442452
case QgsWkbTypes::PointM:
443-
mZ = 0.0;
453+
mZ = std::numeric_limits<double>::quiet_NaN();
444454
mWkbType = type;
445455
return true;
446456
case QgsWkbTypes::PointZM:
@@ -481,22 +491,38 @@ double QgsPoint::distanceSquared( const QgsPoint &other ) const
481491

482492
double QgsPoint::distance3D( double x, double y, double z ) const
483493
{
484-
return sqrt( ( mX - x ) * ( mX - x ) + ( mY - y ) * ( mY - y ) + ( mZ - z ) * ( mZ - z ) );
494+
double zDistSquared = 0.0;
495+
if ( is3D() || !qIsNaN( z ) )
496+
zDistSquared = ( mZ - z ) * ( mZ - z );
497+
498+
return sqrt( ( mX - x ) * ( mX - x ) + ( mY - y ) * ( mY - y ) + zDistSquared );
485499
}
486500

487501
double QgsPoint::distance3D( const QgsPoint &other ) const
488502
{
489-
return sqrt( ( mX - other.x() ) * ( mX - other.x() ) + ( mY - other.y() ) * ( mY - other.y() ) + ( mZ - other.z() ) * ( mZ - other.z() ) );
503+
double zDistSquared = 0.0;
504+
if ( is3D() || other.is3D() )
505+
zDistSquared = ( mZ - other.z() ) * ( mZ - other.z() );
506+
507+
return sqrt( ( mX - other.x() ) * ( mX - other.x() ) + ( mY - other.y() ) * ( mY - other.y() ) + zDistSquared );
490508
}
491509

492510
double QgsPoint::distanceSquared3D( double x, double y, double z ) const
493511
{
494-
return ( mX - x ) * ( mX - x ) + ( mY - y ) * ( mY - y ) + ( mZ - z ) * ( mZ - z );
512+
double zDistSquared = 0.0;
513+
if ( is3D() || !qIsNaN( z ) )
514+
zDistSquared = ( mZ - z ) * ( mZ - z );
515+
516+
return ( mX - x ) * ( mX - x ) + ( mY - y ) * ( mY - y ) + zDistSquared;
495517
}
496518

497519
double QgsPoint::distanceSquared3D( const QgsPoint &other ) const
498520
{
499-
return ( mX - other.x() ) * ( mX - other.x() ) + ( mY - other.y() ) * ( mY - other.y() ) + ( mZ - other.z() ) * ( mZ - other.z() );
521+
double zDistSquared = 0.0;
522+
if ( is3D() || other.is3D() )
523+
zDistSquared = ( mZ - other.z() ) * ( mZ - other.z() );
524+
525+
return ( mX - other.x() ) * ( mX - other.x() ) + ( mY - other.y() ) * ( mY - other.y() ) + zDistSquared;
500526
}
501527

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

521547
QgsPoint QgsPoint::project( double distance, double azimuth, double inclination ) const
522548
{
523-
QgsWkbTypes::Type pType( QgsWkbTypes::Point );
524-
525549
double radsXy = azimuth * M_PI / 180.0;
526550
double dx = 0.0, dy = 0.0, dz = 0.0;
527551

@@ -534,18 +558,11 @@ QgsPoint QgsPoint::project( double distance, double azimuth, double inclination
534558
}
535559
else
536560
{
537-
pType = QgsWkbTypes::addZ( pType );
538561
double radsZ = inclination * M_PI / 180.0;
539562
dx = distance * sin( radsZ ) * sin( radsXy );
540563
dy = distance * sin( radsZ ) * cos( radsXy );
541564
dz = distance * cos( radsZ );
542565
}
543566

544-
if ( isMeasure() )
545-
{
546-
pType = QgsWkbTypes::addM( pType );
547-
}
548-
549-
double z = qIsNaN( mZ ) ? 0 : mZ;
550-
return QgsPoint( mX + dx, mY + dy, z + dz, mM, pType );
567+
return QgsPoint( mX + dx, mY + dy, mZ + dz, mM, mWkbType );
551568
}

src/core/geometry/qgspoint.h

+24-4
Original file line numberDiff line numberDiff line change
@@ -177,29 +177,49 @@ class CORE_EXPORT QgsPoint: public QgsAbstractGeometry
177177
* \see x()
178178
* \see rx()
179179
*/
180-
void setX( double x ) { clearCache(); mX = x; }
180+
void setX( double x )
181+
{
182+
clearCache();
183+
mX = x;
184+
}
181185

182186
/** Sets the point's y-coordinate.
183187
* \see y()
184188
* \see ry()
185189
*/
186-
void setY( double y ) { clearCache(); mY = y; }
190+
void setY( double y )
191+
{
192+
clearCache();
193+
mY = y;
194+
}
187195

188196
/** Sets the point's z-coordinate.
189197
* \note calling this will have no effect if the point does not contain a z-dimension. Use addZValue() to
190198
* add a z value and force the point to have a z dimension.
191199
* \see z()
192200
* \see rz()
193201
*/
194-
void setZ( double z ) { clearCache(); mZ = z; }
202+
void setZ( double z )
203+
{
204+
if ( !is3D() )
205+
return;
206+
clearCache();
207+
mZ = z;
208+
}
195209

196210
/** Sets the point's m-value.
197211
* \note calling this will have no effect if the point does not contain a m-dimension. Use addMValue() to
198212
* add a m value and force the point to have an m dimension.
199213
* \see m()
200214
* \see rm()
201215
*/
202-
void setM( double m ) { clearCache(); mM = m; }
216+
void setM( double m )
217+
{
218+
if ( !isMeasure() )
219+
return;
220+
clearCache();
221+
mM = m;
222+
}
203223

204224
/** Returns the point as a QPointF.
205225
* \since QGIS 2.14

0 commit comments

Comments
 (0)