LCOV - code coverage report
Current view: top level - core - qgspointxy.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 63 100 63.0 %
Date: 2021-03-26 12:19:53 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :                           qgspoint.h  -  description
       3                 :            :                              -------------------
       4                 :            :     begin                : Sat Jun 22 2002
       5                 :            :     copyright            : (C) 2002 by Gary E.Sherman
       6                 :            :     email                : sherman at mrcc.com
       7                 :            :  ***************************************************************************/
       8                 :            : 
       9                 :            : /***************************************************************************
      10                 :            :  *                                                                         *
      11                 :            :  *   This program is free software; you can redistribute it and/or modify  *
      12                 :            :  *   it under the terms of the GNU General Public License as published by  *
      13                 :            :  *   the Free Software Foundation; either version 2 of the License, or     *
      14                 :            :  *   (at your option) any later version.                                   *
      15                 :            :  *                                                                         *
      16                 :            :  ***************************************************************************/
      17                 :            : 
      18                 :            : #ifndef QGSPOINTXY_H
      19                 :            : #define QGSPOINTXY_H
      20                 :            : 
      21                 :            : #include "qgis_core.h"
      22                 :            : #include "qgsvector.h"
      23                 :            : 
      24                 :            : #include "qgis.h"
      25                 :            : 
      26                 :            : #include <iostream>
      27                 :            : #include <QString>
      28                 :            : #include <QPoint>
      29                 :            : #include <QObject>
      30                 :            : 
      31                 :            : class QgsPoint;
      32                 :            : 
      33                 :            : /**
      34                 :            :  * \ingroup core
      35                 :            :  * \brief A class to represent a 2D point.
      36                 :            :  *
      37                 :            :  * A QgsPointXY represents a position with X and Y coordinates.
      38                 :            :  * In most scenarios it is preferable to use a QgsPoint instead which also
      39                 :            :  * supports Z and M values.
      40                 :            :  *
      41                 :            :  * \since QGIS 3.0
      42                 :            :  */
      43                 :            : class CORE_EXPORT QgsPointXY
      44                 :            : {
      45                 :            :     Q_GADGET
      46                 :            : 
      47                 :            :     Q_PROPERTY( double x READ x WRITE setX )
      48                 :            :     Q_PROPERTY( double y READ y WRITE setY )
      49                 :            : 
      50                 :            :   public:
      51                 :            :     /// Default constructor
      52                 :        323 :     QgsPointXY() = default;
      53                 :            : 
      54                 :            :     //! Create a point from another point
      55                 :            :     QgsPointXY( const QgsPointXY &p ) SIP_HOLDGIL;
      56                 :            : 
      57                 :            :     /**
      58                 :            :      * Create a point from x,y coordinates
      59                 :            :      * \param x x coordinate
      60                 :            :      * \param y y coordinate
      61                 :            :      */
      62                 :      71662 :     QgsPointXY( double x, double y ) SIP_HOLDGIL
      63                 :      71662 :   : mX( x )
      64                 :      71662 :     , mY( y )
      65                 :      71662 :     , mIsEmpty( false )
      66                 :      71662 :     {}
      67                 :            : 
      68                 :            :     /**
      69                 :            :      * Create a point from a QPointF
      70                 :            :      * \param point QPointF source
      71                 :            :      * \since QGIS 2.7
      72                 :            :      */
      73                 :          4 :     QgsPointXY( QPointF point ) SIP_HOLDGIL
      74                 :          4 :   : mX( point.x() )
      75                 :          4 :     , mY( point.y() )
      76                 :          4 :     , mIsEmpty( false )
      77                 :          4 :     {}
      78                 :            : 
      79                 :            :     /**
      80                 :            :      * Create a point from a QPoint
      81                 :            :      * \param point QPoint source
      82                 :            :      * \since QGIS 2.7
      83                 :            :      */
      84                 :            :     QgsPointXY( QPoint point ) SIP_HOLDGIL
      85                 :            :   : mX( point.x() )
      86                 :            :     , mY( point.y() )
      87                 :            :     , mIsEmpty( false )
      88                 :            :     {}
      89                 :            : 
      90                 :            :     /**
      91                 :            :      * Create a new point.
      92                 :            :      * Z and M values will be dropped.
      93                 :            :      *
      94                 :            :      * \since QGIS 3.0
      95                 :            :      */
      96                 :            :     QgsPointXY( const QgsPoint &point ) SIP_HOLDGIL;
      97                 :            : 
      98                 :            :     // IMPORTANT - while QgsPointXY is inherited by QgsReferencedPointXY, we do NOT want a virtual destructor here
      99                 :            :     // because this class MUST be lightweight and we don't want the cost of the vtable here.
     100                 :            :     // see https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392
     101                 :            :     ~QgsPointXY() = default;
     102                 :            : 
     103                 :            :     /**
     104                 :            :      * Sets the x value of the point
     105                 :            :      * \param x x coordinate
     106                 :            :      */
     107                 :          0 :     void setX( double x ) SIP_HOLDGIL
     108                 :            :     {
     109                 :          0 :       mX = x;
     110                 :          0 :       mIsEmpty = false;
     111                 :          0 :     }
     112                 :            : 
     113                 :            :     /**
     114                 :            :      * Sets the y value of the point
     115                 :            :      * \param y y coordinate
     116                 :            :      */
     117                 :          0 :     void setY( double y ) SIP_HOLDGIL
     118                 :            :     {
     119                 :          0 :       mY = y;
     120                 :          0 :       mIsEmpty = false;
     121                 :          0 :     }
     122                 :            : 
     123                 :            :     //! Sets the x and y value of the point
     124                 :          1 :     void set( double x, double y ) SIP_HOLDGIL
     125                 :            :     {
     126                 :          1 :       mX = x;
     127                 :          1 :       mY = y;
     128                 :          1 :       mIsEmpty = false;
     129                 :          1 :     }
     130                 :            : 
     131                 :            :     /**
     132                 :            :      * Gets the x value of the point
     133                 :            :      * \returns x coordinate
     134                 :            :      */
     135                 :     124016 :     double x() const SIP_HOLDGIL
     136                 :            :     {
     137                 :     124016 :       return mX;
     138                 :            :     }
     139                 :            : 
     140                 :            :     /**
     141                 :            :      * Gets the y value of the point
     142                 :            :      * \returns y coordinate
     143                 :            :      */
     144                 :      63758 :     double y() const SIP_HOLDGIL
     145                 :            :     {
     146                 :      63758 :       return mY;
     147                 :            :     }
     148                 :            : 
     149                 :            :     /**
     150                 :            :      * Converts a point to a QPointF
     151                 :            :      * \returns QPointF with same x and y values
     152                 :            :      * \since QGIS 2.7
     153                 :            :      */
     154                 :          2 :     QPointF toQPointF() const
     155                 :            :     {
     156                 :          2 :       return QPointF( mX, mY );
     157                 :            :     }
     158                 :            : 
     159                 :            :     /**
     160                 :            :      * Returns a string representation of the point (x, y) with a preset \a precision.
     161                 :            :      * If  \a precision is -1, then a default precision will be used.
     162                 :            :      */
     163                 :            :     QString toString( int precision = -1 ) const;
     164                 :            : 
     165                 :            :     /**
     166                 :            :      * Returns the well known text representation for the point (e.g. "POINT(x y)").
     167                 :            :      * The wkt is created without an SRID.
     168                 :            :      */
     169                 :            :     QString asWkt() const;
     170                 :            : 
     171                 :            :     /**
     172                 :            :      * Returns the squared distance between this point a specified x, y coordinate.
     173                 :            :      * \see distance()
     174                 :            :     */
     175                 :        204 :     double sqrDist( double x, double y ) const SIP_HOLDGIL
     176                 :            :     {
     177                 :        204 :       return ( mX - x ) * ( mX - x ) + ( mY - y ) * ( mY - y );
     178                 :            :     }
     179                 :            : 
     180                 :            :     /**
     181                 :            :      * Returns the squared distance between this point another point.
     182                 :            :      * \see distance()
     183                 :            :     */
     184                 :        204 :     double sqrDist( const QgsPointXY &other ) const SIP_HOLDGIL
     185                 :            :     {
     186                 :        204 :       return sqrDist( other.x(), other.y() );
     187                 :            :     }
     188                 :            : 
     189                 :            :     /**
     190                 :            :      * Returns the distance between this point and a specified x, y coordinate.
     191                 :            :      * \param x x-coordniate
     192                 :            :      * \param y y-coordinate
     193                 :            :      * \see sqrDist()
     194                 :            :      * \since QGIS 2.16
     195                 :            :     */
     196                 :          0 :     double distance( double x, double y ) const SIP_HOLDGIL
     197                 :            :     {
     198                 :          0 :       return std::sqrt( sqrDist( x, y ) );
     199                 :            :     }
     200                 :            : 
     201                 :            :     /**
     202                 :            :      * Returns the distance between this point and another point.
     203                 :            :      * \param other other point
     204                 :            :      * \see sqrDist()
     205                 :            :      * \since QGIS 2.16
     206                 :            :     */
     207                 :         26 :     double distance( const QgsPointXY &other ) const SIP_HOLDGIL
     208                 :            :     {
     209                 :         26 :       return std::sqrt( sqrDist( other ) );
     210                 :            :     }
     211                 :            : 
     212                 :            :     //! Returns the minimum distance between this point and a segment
     213                 :            :     double sqrDistToSegment( double x1, double y1, double x2, double y2, QgsPointXY &minDistPoint SIP_OUT, double epsilon = DEFAULT_SEGMENT_EPSILON ) const SIP_HOLDGIL;
     214                 :            : 
     215                 :            :     //! Calculates azimuth between this point and other one (clockwise in degree, starting from north)
     216                 :            :     double azimuth( const QgsPointXY &other ) const SIP_HOLDGIL;
     217                 :            : 
     218                 :            :     /**
     219                 :            :      * Returns a new point which corresponds to this point projected by a specified distance
     220                 :            :      * in a specified bearing.
     221                 :            :      * \param distance distance to project
     222                 :            :      * \param bearing angle to project in, clockwise in degrees starting from north
     223                 :            :      * \since QGIS 2.16
     224                 :            :      */
     225                 :            :     QgsPointXY project( double distance, double bearing ) const SIP_HOLDGIL;
     226                 :            : 
     227                 :            :     /**
     228                 :            :      * Returns TRUE if the geometry is empty.
     229                 :            :      * Unlike QgsPoint, this class is also used to retrieve graphical coordinates like QPointF.
     230                 :            :      * It therefore has the default coordinates (0.0).
     231                 :            :      * A QgsPointXY is considered empty, when the coordinates have not been explicitly filled in.
     232                 :            :      * \since QGIS 3.10
     233                 :            :      */
     234                 :      32205 :     bool isEmpty() const SIP_HOLDGIL { return mIsEmpty; }
     235                 :            : 
     236                 :            :     /**
     237                 :            :      * Compares this point with another point with a fuzzy tolerance
     238                 :            :      * \param other point to compare with
     239                 :            :      * \param epsilon maximum difference for coordinates between the points
     240                 :            :      * \returns TRUE if points are equal within specified tolerance
     241                 :            :      * \since QGIS 2.9
     242                 :            :      */
     243                 :         94 :     bool compare( const QgsPointXY &other, double epsilon = 4 * std::numeric_limits<double>::epsilon() ) const SIP_HOLDGIL
     244                 :            :     {
     245                 :         94 :       return ( qgsDoubleNear( mX, other.x(), epsilon ) && qgsDoubleNear( mY, other.y(), epsilon ) );
     246                 :            :     }
     247                 :            : 
     248                 :            :     //! equality operator
     249                 :          1 :     bool operator==( const QgsPointXY &other ) SIP_HOLDGIL
     250                 :            :     {
     251                 :          1 :       if ( isEmpty() && other.isEmpty() )
     252                 :          0 :         return true;
     253                 :          1 :       if ( isEmpty() && !other.isEmpty() )
     254                 :          0 :         return false;
     255                 :          1 :       if ( ! isEmpty() && other.isEmpty() )
     256                 :          0 :         return false;
     257                 :            : 
     258                 :          1 :       bool equal = true;
     259                 :          1 :       equal &= qgsDoubleNear( other.x(), mX, 1E-8 );
     260                 :          1 :       equal &= qgsDoubleNear( other.y(), mY, 1E-8 );
     261                 :            : 
     262                 :          1 :       return equal;
     263                 :          1 :     }
     264                 :            : 
     265                 :            :     //! Inequality operator
     266                 :          0 :     bool operator!=( const QgsPointXY &other ) const SIP_HOLDGIL
     267                 :            :     {
     268                 :          0 :       if ( isEmpty() && other.isEmpty() )
     269                 :          0 :         return false;
     270                 :          0 :       if ( isEmpty() && !other.isEmpty() )
     271                 :          0 :         return true;
     272                 :          0 :       if ( ! isEmpty() && other.isEmpty() )
     273                 :          0 :         return true;
     274                 :            : 
     275                 :          0 :       bool equal = true;
     276                 :          0 :       equal &= qgsDoubleNear( other.x(), mX, 1E-8 );
     277                 :          0 :       equal &= qgsDoubleNear( other.y(), mY, 1E-8 );
     278                 :            : 
     279                 :          0 :       return !equal;
     280                 :          0 :     }
     281                 :            : 
     282                 :            :     //! Multiply x and y by the given value
     283                 :            :     void multiply( double scalar ) SIP_HOLDGIL
     284                 :            :     {
     285                 :            :       mX *= scalar;
     286                 :            :       mY *= scalar;
     287                 :            :     }
     288                 :            : 
     289                 :            :     //! Assignment
     290                 :        246 :     QgsPointXY &operator=( const QgsPointXY &other ) SIP_HOLDGIL
     291                 :            :     {
     292                 :        246 :       if ( &other != this )
     293                 :            :       {
     294                 :        246 :         mX = other.x();
     295                 :        246 :         mY = other.y();
     296                 :        246 :         mIsEmpty = other.isEmpty();
     297                 :        246 :       }
     298                 :            : 
     299                 :        246 :       return *this;
     300                 :            :     }
     301                 :            : 
     302                 :            :     //! Calculates the vector obtained by subtracting a point from this point
     303                 :          0 :     QgsVector operator-( const QgsPointXY &p ) const { return QgsVector( mX - p.mX, mY - p.mY ); }
     304                 :            : 
     305                 :            :     //! Adds a vector to this point in place
     306                 :          0 :     QgsPointXY &operator+=( QgsVector v ) { *this = *this + v; return *this; }
     307                 :            : 
     308                 :            :     //! Subtracts a vector from this point in place
     309                 :            :     QgsPointXY &operator-=( QgsVector v ) { *this = *this - v; return *this; }
     310                 :            : 
     311                 :            :     //! Adds a vector to this point
     312                 :         24 :     QgsPointXY operator+( QgsVector v ) const { return QgsPointXY( mX + v.x(), mY + v.y() ); }
     313                 :            : 
     314                 :            :     //! Subtracts a vector from this point
     315                 :            :     QgsPointXY operator-( QgsVector v ) const { return QgsPointXY( mX - v.x(), mY - v.y() ); }
     316                 :            : 
     317                 :            :     //! Multiplies the coordinates in this point by a scalar quantity
     318                 :            :     QgsPointXY operator*( double scalar ) const { return QgsPointXY( mX * scalar, mY * scalar ); }
     319                 :            : 
     320                 :            :     //! Divides the coordinates in this point by a scalar quantity
     321                 :            :     QgsPointXY operator/( double scalar ) const { return QgsPointXY( mX / scalar, mY / scalar ); }
     322                 :            : 
     323                 :            :     //! Multiplies the coordinates in this point by a scalar quantity in place
     324                 :            :     QgsPointXY &operator*=( double scalar ) { mX *= scalar; mY *= scalar; return *this; }
     325                 :            : 
     326                 :            :     //! Divides the coordinates in this point by a scalar quantity in place
     327                 :          0 :     QgsPointXY &operator/=( double scalar ) { mX /= scalar; mY /= scalar; return *this; }
     328                 :            : 
     329                 :            :     //! Allows direct construction of QVariants from points.
     330                 :            :     operator QVariant() const
     331                 :            :     {
     332                 :            :       return QVariant::fromValue( *this );
     333                 :            :     }
     334                 :            : 
     335                 :            : #ifdef SIP_RUN
     336                 :            :     SIP_PYOBJECT __repr__();
     337                 :            :     % MethodCode
     338                 :            :     QString str = QStringLiteral( "<QgsPointXY: %1>" ).arg( sipCpp->asWkt() );
     339                 :            :     sipRes = PyUnicode_FromString( str.toUtf8().constData() );
     340                 :            :     % End
     341                 :            : 
     342                 :            :     int __len__();
     343                 :            :     % MethodCode
     344                 :            :     sipRes = 2;
     345                 :            :     % End
     346                 :            : 
     347                 :            : 
     348                 :            :     SIP_PYOBJECT __getitem__( int );
     349                 :            :     % MethodCode
     350                 :            :     if ( a0 == 0 )
     351                 :            :     {
     352                 :            :       sipRes = Py_BuildValue( "d", sipCpp->x() );
     353                 :            :     }
     354                 :            :     else if ( a0 == 1 )
     355                 :            :     {
     356                 :            :       sipRes = Py_BuildValue( "d", sipCpp->y() );
     357                 :            :     }
     358                 :            :     else
     359                 :            :     {
     360                 :            :       QString msg = QString( "Bad index: %1" ).arg( a0 );
     361                 :            :       PyErr_SetString( PyExc_IndexError, msg.toLatin1().constData() );
     362                 :            :     }
     363                 :            :     % End
     364                 :            : 
     365                 :            :     long __hash__() const;
     366                 :            :     % MethodCode
     367                 :            :     sipRes = qHash( *sipCpp );
     368                 :            :     % End
     369                 :            : #endif
     370                 :            : 
     371                 :            :   private:
     372                 :            : 
     373                 :            :     //! x coordinate
     374                 :        323 :     double mX = 0; //std::numeric_limits<double>::quiet_NaN();
     375                 :            : 
     376                 :            :     //! y coordinate
     377                 :        323 :     double mY = 0; //std::numeric_limits<double>::quiet_NaN();
     378                 :            : 
     379                 :            :     //! is point empty?
     380                 :        323 :     bool mIsEmpty = true;
     381                 :            : 
     382                 :            :     friend uint qHash( const QgsPointXY &pnt );
     383                 :            : 
     384                 :            : }; // class QgsPointXY
     385                 :            : 
     386                 :          0 : Q_DECLARE_METATYPE( QgsPointXY )
     387                 :            : 
     388                 :        117 : inline bool operator==( const QgsPointXY &p1, const QgsPointXY &p2 ) SIP_SKIP
     389                 :            : {
     390                 :        117 :   const bool nan1X = std::isnan( p1.x() );
     391                 :        117 :   const bool nan2X = std::isnan( p2.x() );
     392                 :        117 :   if ( nan1X != nan2X )
     393                 :          0 :     return false;
     394                 :        117 :   if ( !nan1X && !qgsDoubleNear( p1.x(), p2.x(), 1E-8 ) )
     395                 :          2 :     return false;
     396                 :            : 
     397                 :        115 :   const bool nan1Y = std::isnan( p1.y() );
     398                 :        115 :   const bool nan2Y = std::isnan( p2.y() );
     399                 :        115 :   if ( nan1Y != nan2Y )
     400                 :          0 :     return false;
     401                 :            : 
     402                 :        115 :   if ( !nan1Y && !qgsDoubleNear( p1.y(), p2.y(), 1E-8 ) )
     403                 :          0 :     return false;
     404                 :            : 
     405                 :        115 :   return true;
     406                 :        117 : }
     407                 :            : 
     408                 :            : inline std::ostream &operator << ( std::ostream &os, const QgsPointXY &p ) SIP_SKIP
     409                 :            : {
     410                 :            :   // Use Local8Bit for printouts
     411                 :            :   os << p.toString().toLocal8Bit().data();
     412                 :            :   return os;
     413                 :            : }
     414                 :            : 
     415                 :          0 : inline uint qHash( const QgsPointXY &p ) SIP_SKIP
     416                 :            : {
     417                 :            :   uint hash;
     418                 :          0 :   uint h1 = qHash( static_cast< quint64 >( p.mX ) );
     419                 :          0 :   uint h2 = qHash( static_cast< quint64 >( p.mY ) );
     420                 :          0 :   hash = h1 ^ ( h2 << 1 );
     421                 :          0 :   return hash;
     422                 :            : }
     423                 :            : 
     424                 :            : 
     425                 :            : #endif //QGSPOINTXY_H

Generated by: LCOV version 1.14