QGIS API Documentation  3.21.0-Master (5b68dc587e)
qgspoint.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgspointv2.h
3  --------------
4  begin : September 2014
5  copyright : (C) 2014 by Marco Hugentobler
6  email : marco at sourcepole dot ch
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 QGSPOINT_H
19 #define QGSPOINT_H
20 
21 #include "qgis_core.h"
22 #include "qgis_sip.h"
23 #include "qgsabstractgeometry.h"
24 #include "qgsrectangle.h"
25 
26 /***************************************************************************
27  * This class is considered CRITICAL and any change MUST be accompanied with
28  * full unit tests in testqgsgeometry.cpp.
29  * See details in QEP #17
30  ****************************************************************************/
31 
48 class CORE_EXPORT QgsPoint: public QgsAbstractGeometry
49 {
50  Q_GADGET
51 
52  Q_PROPERTY( double x READ x WRITE setX )
53  Q_PROPERTY( double y READ y WRITE setY )
54  Q_PROPERTY( double z READ z WRITE setZ )
55  Q_PROPERTY( double m READ m WRITE setM )
56 
57  public:
58 
85 #ifndef SIP_RUN
86  QgsPoint( double x = std::numeric_limits<double>::quiet_NaN(), double y = std::numeric_limits<double>::quiet_NaN(), double z = std::numeric_limits<double>::quiet_NaN(), double m = std::numeric_limits<double>::quiet_NaN(), QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown );
87 #else
88  QgsPoint( SIP_PYOBJECT x SIP_TYPEHINT( Optional[Union[QgsPoint, QPointF, float]] ) = Py_None, SIP_PYOBJECT y SIP_TYPEHINT( Optional[float] ) = Py_None, SIP_PYOBJECT z SIP_TYPEHINT( Optional[float] ) = Py_None, SIP_PYOBJECT m SIP_TYPEHINT( Optional[float] ) = Py_None, SIP_PYOBJECT wkbType SIP_TYPEHINT( Optional[int] ) = Py_None ) [( double x = 0.0, double y = 0.0, double z = 0.0, double m = 0.0, QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown )];
89  % MethodCode
90  if ( sipCanConvertToType( a0, sipType_QgsPointXY, SIP_NOT_NONE ) && a1 == Py_None && a2 == Py_None && a3 == Py_None && a4 == Py_None )
91  {
92  int state;
93  sipIsErr = 0;
94 
95  QgsPointXY *p = reinterpret_cast<QgsPointXY *>( sipConvertToType( a0, sipType_QgsPointXY, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
96  if ( sipIsErr )
97  {
98  sipReleaseType( p, sipType_QgsPointXY, state );
99  }
100  else
101  {
102  sipCpp = new sipQgsPoint( QgsPoint( *p ) );
103  }
104  }
105  else if ( sipCanConvertToType( a0, sipType_QPointF, SIP_NOT_NONE ) && a1 == Py_None && a2 == Py_None && a3 == Py_None && a4 == Py_None )
106  {
107  int state;
108  sipIsErr = 0;
109 
110  QPointF *p = reinterpret_cast<QPointF *>( sipConvertToType( a0, sipType_QPointF, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
111  if ( sipIsErr )
112  {
113  sipReleaseType( p, sipType_QPointF, state );
114  }
115  else
116  {
117  sipCpp = new sipQgsPoint( QgsPoint( *p ) );
118  }
119  }
120  else if (
121  ( a0 == Py_None || PyFloat_AsDouble( a0 ) != -1.0 || !PyErr_Occurred() ) &&
122  ( a1 == Py_None || PyFloat_AsDouble( a1 ) != -1.0 || !PyErr_Occurred() ) &&
123  ( a2 == Py_None || PyFloat_AsDouble( a2 ) != -1.0 || !PyErr_Occurred() ) &&
124  ( a3 == Py_None || PyFloat_AsDouble( a3 ) != -1.0 || !PyErr_Occurred() ) )
125  {
126  double x = a0 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a0 );
127  double y = a1 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a1 );
128  double z = a2 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a2 );
129  double m = a3 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a3 );
130  QgsWkbTypes::Type wkbType = a4 == Py_None ? QgsWkbTypes::Unknown : static_cast<QgsWkbTypes::Type>( sipConvertToEnum( a4, sipType_QgsWkbTypes_Type ) );
131  sipCpp = new sipQgsPoint( QgsPoint( x, y, z, m, wkbType ) );
132  }
133  else // Invalid ctor arguments
134  {
135  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type in constructor arguments." ).toUtf8().constData() );
136  sipIsErr = 1;
137  }
138  % End
139 #endif
140 
144  explicit QgsPoint( const QgsPointXY &p ) SIP_SKIP;
145 
149  explicit QgsPoint( QPointF p ) SIP_SKIP;
150 
156  explicit QgsPoint( QgsWkbTypes::Type wkbType, double x = std::numeric_limits<double>::quiet_NaN(), double y = std::numeric_limits<double>::quiet_NaN(), double z = std::numeric_limits<double>::quiet_NaN(), double m = std::numeric_limits<double>::quiet_NaN() ) SIP_SKIP;
157 
158  bool operator==( const QgsAbstractGeometry &other ) const override SIP_HOLDGIL
159  {
160  const QgsPoint *pt = qgsgeometry_cast< const QgsPoint * >( &other );
161  if ( !pt )
162  return false;
163 
164  const QgsWkbTypes::Type type = wkbType();
165 
166  if ( pt->wkbType() != type )
167  return false;
168 
169  const bool nan1X = std::isnan( mX );
170  const bool nan2X = std::isnan( pt->x() );
171  if ( nan1X != nan2X )
172  return false;
173  if ( !nan1X && !qgsDoubleNear( mX, pt->x(), 1E-8 ) )
174  return false;
175 
176  const bool nan1Y = std::isnan( mY );
177  const bool nan2Y = std::isnan( pt->y() );
178  if ( nan1Y != nan2Y )
179  return false;
180  if ( !nan1Y && !qgsDoubleNear( mY, pt->y(), 1E-8 ) )
181  return false;
182 
183  if ( QgsWkbTypes::hasZ( type ) )
184  {
185  const bool nan1Z = std::isnan( mZ );
186  const bool nan2Z = std::isnan( pt->z() );
187  if ( nan1Z != nan2Z )
188  return false;
189  if ( !nan1Z && !qgsDoubleNear( mZ, pt->z(), 1E-8 ) )
190  return false;
191  }
192 
193  if ( QgsWkbTypes::hasM( type ) )
194  {
195  const bool nan1M = std::isnan( mM );
196  const bool nan2M = std::isnan( pt->m() );
197  if ( nan1M != nan2M )
198  return false;
199  if ( !nan1M && !qgsDoubleNear( mM, pt->m(), 1E-8 ) )
200  return false;
201  }
202 
203  return true;
204  }
205 
206  bool operator!=( const QgsAbstractGeometry &other ) const override SIP_HOLDGIL
207  {
208  return !operator==( other );
209  }
210 
216  double x() const SIP_HOLDGIL { return mX; }
217 
223  double y() const SIP_HOLDGIL { return mY; }
224 
230  double z() const SIP_HOLDGIL { return mZ; }
231 
237  double m() const SIP_HOLDGIL { return mM; }
238 
246  double &rx() SIP_SKIP { clearCache(); return mX; }
247 
255  double &ry() SIP_SKIP { clearCache(); return mY; }
256 
264  double &rz() SIP_SKIP { clearCache(); return mZ; }
265 
273  double &rm() SIP_SKIP { clearCache(); return mM; }
274 
280  void setX( double x ) SIP_HOLDGIL
281  {
282  clearCache();
283  mX = x;
284  }
285 
291  void setY( double y ) SIP_HOLDGIL
292  {
293  clearCache();
294  mY = y;
295  }
296 
304  void setZ( double z ) SIP_HOLDGIL
305  {
306  if ( !is3D() )
307  return;
308  clearCache();
309  mZ = z;
310  }
311 
319  void setM( double m ) SIP_HOLDGIL
320  {
321  if ( !isMeasure() )
322  return;
323  clearCache();
324  mM = m;
325  }
326 
331  QPointF toQPointF() const SIP_HOLDGIL
332  {
333  return QPointF( mX, mY );
334  }
335 
343  double distance( double x, double y ) const SIP_HOLDGIL
344  {
345  return std::sqrt( ( mX - x ) * ( mX - x ) + ( mY - y ) * ( mY - y ) );
346  }
347 
355  double distance( const QgsPoint &other ) const SIP_HOLDGIL
356  {
357  return std::sqrt( ( mX - other.x() ) * ( mX - other.x() ) + ( mY - other.y() ) * ( mY - other.y() ) );
358  }
359 
367  double distanceSquared( double x, double y ) const SIP_HOLDGIL
368  {
369  return ( mX - x ) * ( mX - x ) + ( mY - y ) * ( mY - y );
370  }
371 
379  double distanceSquared( const QgsPoint &other ) const SIP_HOLDGIL
380  {
381  return ( mX - other.x() ) * ( mX - other.x() ) + ( mY - other.y() ) * ( mY - other.y() );
382  }
383 
391  double distance3D( double x, double y, double z ) const SIP_HOLDGIL;
392 
400  double distance3D( const QgsPoint &other ) const SIP_HOLDGIL;
401 
409  double distanceSquared3D( double x, double y, double z ) const SIP_HOLDGIL;
410 
418  double distanceSquared3D( const QgsPoint &other ) const SIP_HOLDGIL;
419 
424  double azimuth( const QgsPoint &other ) const SIP_HOLDGIL;
425 
431  double inclination( const QgsPoint &other ) const SIP_HOLDGIL;
432 
463  QgsPoint project( double distance, double azimuth, double inclination = 90.0 ) const SIP_HOLDGIL;
464 
469  QgsVector operator-( const QgsPoint &p ) const SIP_HOLDGIL { return QgsVector( mX - p.mX, mY - p.mY ); }
470 
475  QgsPoint &operator+=( QgsVector v ) SIP_HOLDGIL { mX += v.x(); mY += v.y(); return *this; }
476 
481  QgsPoint &operator-=( QgsVector v ) SIP_HOLDGIL { mX -= v.x(); mY -= v.y(); return *this; }
482 
487  QgsPoint operator+( QgsVector v ) const SIP_HOLDGIL { QgsPoint r = *this; r.rx() += v.x(); r.ry() += v.y(); return r; }
488 
493  QgsPoint operator-( QgsVector v ) const SIP_HOLDGIL { QgsPoint r = *this; r.rx() -= v.x(); r.ry() -= v.y(); return r; }
494 
495  //implementation of inherited methods
496  void normalize() final SIP_HOLDGIL;
497  bool isEmpty() const override SIP_HOLDGIL;
498  QgsRectangle boundingBox() const override SIP_HOLDGIL;
499  QString geometryType() const override SIP_HOLDGIL;
500  int dimension() const override SIP_HOLDGIL;
501  QgsPoint *clone() const override SIP_FACTORY;
502  QgsPoint *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY;
503  bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;
504  void clear() override;
505  bool fromWkb( QgsConstWkbPtr &wkb ) override;
506  bool fromWkt( const QString &wkt ) override;
507  int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
508  QByteArray asWkb( QgsAbstractGeometry::WkbFlags = QgsAbstractGeometry::WkbFlags() ) const override;
509  QString asWkt( int precision = 17 ) const override;
510  QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
511  QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
512  json asJsonObject( int precision = 17 ) const override SIP_SKIP;
513  QString asKml( int precision = 17 ) const override;
514  void draw( QPainter &p ) const override;
515  QPainterPath asQPainterPath() const override;
516  void transform( const QgsCoordinateTransform &ct, Qgis::TransformDirection d = Qgis::TransformDirection::Forward, bool transformZ = false ) override SIP_THROW( QgsCsException );
517  void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 ) override;
518  QgsCoordinateSequence coordinateSequence() const override;
519  int nCoordinates() const override SIP_HOLDGIL;
520  int vertexNumberFromVertexId( QgsVertexId id ) const override;
521  QgsAbstractGeometry *boundary() const override SIP_FACTORY;
522  bool isValid( QString &error SIP_OUT, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const override SIP_HOLDGIL;
523 
524  //low-level editing
525  bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) override;
526  bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) override;
527  bool deleteVertex( QgsVertexId position ) override;
528 
529  double closestSegment( const QgsPoint &pt, QgsPoint &segmentPt SIP_OUT, QgsVertexId &vertexAfter SIP_OUT, int *leftOf SIP_OUT = nullptr, double epsilon = 4 * std::numeric_limits<double>::epsilon() ) const override;
530  bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const override;
531  void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const override;
532 
538  double vertexAngle( QgsVertexId vertex ) const override;
539 
540  int vertexCount( int /*part*/ = 0, int /*ring*/ = 0 ) const override;
541  int ringCount( int /*part*/ = 0 ) const override;
542  int partCount() const override;
543  QgsPoint vertexAt( QgsVertexId /*id*/ ) const override;
544  QgsPoint *toCurveType() const override SIP_FACTORY;
545  double segmentLength( QgsVertexId startVertex ) const override;
546  bool boundingBoxIntersects( const QgsRectangle &rectangle ) const override SIP_HOLDGIL;
547 
548  bool addZValue( double zValue = 0 ) override;
549  bool addMValue( double mValue = 0 ) override;
550  bool dropZValue() override;
551  bool dropMValue() override;
552  void swapXy() override;
553  bool convertTo( QgsWkbTypes::Type type ) override;
554 
555  bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) override;
556 
557 #ifndef SIP_RUN
558 
559  void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
560  void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) override;
561 
569  inline static const QgsPoint *cast( const QgsAbstractGeometry *geom )
570  {
571  if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::Point )
572  return static_cast<const QgsPoint *>( geom );
573  return nullptr;
574  }
575 #endif
576 
577  QgsPoint *createEmptyWithSameType() const override SIP_FACTORY;
578 
579 #ifdef SIP_RUN
580  SIP_PYOBJECT __repr__();
581  % MethodCode
582  QString str = QStringLiteral( "<QgsPoint: %1>" ).arg( sipCpp->asWkt() );
583  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
584  % End
585 #endif
586 
587  protected:
588 
589  int compareToSameClass( const QgsAbstractGeometry *other ) const final;
590  int childCount() const override;
591  QgsPoint childPoint( int index ) const override;
592 
593  private:
594  double mX;
595  double mY;
596  double mZ;
597  double mM;
598 };
599 
600 // clazy:excludeall=qstring-allocations
601 
602 #endif // QGSPOINT_H
The Qgis class provides global constants for use throughout the application.
Definition: qgis.h:63
An abstract base class for classes which transform geometries by transforming input points to output ...
Abstract base class for all geometries.
virtual QgsPoint childPoint(int index) const
Returns point at index (for geometries without child geometries - i.e.
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
virtual int childCount() const
Returns number of child geometries (for geometries with child geometries) or child points (for geomet...
virtual void transformVertices(const std::function< QgsPoint(const QgsPoint &) > &transform)
Transforms the vertices from the geometry in place, applying the transform function to every vertex.
virtual QgsAbstractGeometry * createEmptyWithSameType() const =0
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
virtual void clearCache() const
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
virtual void normalize()=0
Reorganizes the geometry into a normalized form (or "canonical" form).
virtual void filterVertices(const std::function< bool(const QgsPoint &) > &filter)
Filters the vertices from the geometry in place, removing any which do not return true for the filter...
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
virtual bool operator==(const QgsAbstractGeometry &other) const =0
virtual int compareToSameClass(const QgsAbstractGeometry *other) const =0
Compares to an other geometry of the same class, and returns a integer for sorting of the two geometr...
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
A const WKB pointer.
Definition: qgswkbptr.h:138
Class for doing transforms between two map coordinate systems.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
A class to represent a 2D point.
Definition: qgspointxy.h:59
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
double distance(double x, double y) const SIP_HOLDGIL
Returns the Cartesian 2D distance between this point and a specified x, y coordinate.
Definition: qgspoint.h:343
double m() const SIP_HOLDGIL
Returns the point's m value.
Definition: qgspoint.h:237
double & ry()
Returns a reference to the y-coordinate of this point.
Definition: qgspoint.h:255
QPointF toQPointF() const SIP_HOLDGIL
Returns the point as a QPointF.
Definition: qgspoint.h:331
static const QgsPoint * cast(const QgsAbstractGeometry *geom)
Cast the geom to a QgsPoint.
Definition: qgspoint.h:569
void setX(double x) SIP_HOLDGIL
Sets the point's x-coordinate.
Definition: qgspoint.h:280
double distance(const QgsPoint &other) const SIP_HOLDGIL
Returns the Cartesian 2D distance between this point and another point.
Definition: qgspoint.h:355
Q_GADGET double x
Definition: qgspoint.h:52
void setY(double y) SIP_HOLDGIL
Sets the point's y-coordinate.
Definition: qgspoint.h:291
double & rz()
Returns a reference to the z-coordinate of this point.
Definition: qgspoint.h:264
double & rm()
Returns a reference to the m value of this point.
Definition: qgspoint.h:273
void setZ(double z) SIP_HOLDGIL
Sets the point's z-coordinate.
Definition: qgspoint.h:304
QgsPoint operator-(QgsVector v) const SIP_HOLDGIL
Subtracts a vector from this point.
Definition: qgspoint.h:493
double y() const SIP_HOLDGIL
Returns the point's y-coordinate.
Definition: qgspoint.h:223
double distanceSquared(const QgsPoint &other) const SIP_HOLDGIL
Returns the Cartesian 2D squared distance between this point another point.
Definition: qgspoint.h:379
double z
Definition: qgspoint.h:54
double distanceSquared(double x, double y) const SIP_HOLDGIL
Returns the Cartesian 2D squared distance between this point a specified x, y coordinate.
Definition: qgspoint.h:367
QgsPoint operator+(QgsVector v) const SIP_HOLDGIL
Adds a vector to this point.
Definition: qgspoint.h:487
double x() const SIP_HOLDGIL
Returns the point's x-coordinate.
Definition: qgspoint.h:216
double & rx()
Returns a reference to the x-coordinate of this point.
Definition: qgspoint.h:246
double z() const SIP_HOLDGIL
Returns the point's z-coordinate.
Definition: qgspoint.h:230
QgsPoint & operator-=(QgsVector v) SIP_HOLDGIL
Subtracts a vector from this point in place.
Definition: qgspoint.h:481
double m
Definition: qgspoint.h:55
bool operator!=(const QgsAbstractGeometry &other) const override SIP_HOLDGIL
Definition: qgspoint.h:206
double y
Definition: qgspoint.h:53
void setM(double m) SIP_HOLDGIL
Sets the point's m-value.
Definition: qgspoint.h:319
QgsPoint & operator+=(QgsVector v) SIP_HOLDGIL
Adds a vector to this point in place.
Definition: qgspoint.h:475
A rectangle specified with double values.
Definition: qgsrectangle.h:42
A class to represent a vector.
Definition: qgsvector.h:30
Handles storage of information regarding WKB types and their properties.
Definition: qgswkbtypes.h:42
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:1100
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:702
static bool hasZ(Type type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:1050
double ANALYSIS_EXPORT leftOf(const QgsPoint &thepoint, const QgsPoint *p1, const QgsPoint *p2)
Returns whether 'thepoint' is left or right of the line from 'p1' to 'p2'. Negative values mean left ...
Definition: MathUtils.cpp:292
#define str(x)
Definition: qgis.cpp:37
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:1234
#define SIP_THROW(name)
Definition: qgis_sip.h:189
#define SIP_TYPEHINT(type)
Definition: qgis_sip.h:218
#define SIP_SKIP
Definition: qgis_sip.h:126
#define SIP_OUT
Definition: qgis_sip.h:58
#define SIP_HOLDGIL
Definition: qgis_sip.h:157
#define SIP_FACTORY
Definition: qgis_sip.h:76
QVector< QgsRingSequence > QgsCoordinateSequence
double closestSegment(const QgsPolylineXY &pl, const QgsPointXY &pt, int &vertexAfter, double epsilon)
Definition: qgstracer.cpp:69
int precision
Utility class for identifying a unique vertex within a geometry.