QGIS API Documentation  3.19.0-Master (f616be29d3)
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 
37 class CORE_EXPORT QgsPoint: public QgsAbstractGeometry
38 {
39  Q_GADGET
40 
41  Q_PROPERTY( double x READ x WRITE setX )
42  Q_PROPERTY( double y READ y WRITE setY )
43  Q_PROPERTY( double z READ z WRITE setZ )
44  Q_PROPERTY( double m READ m WRITE setM )
45 
46  public:
47 
74 #ifndef SIP_RUN
75  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 );
76 #else
77  QgsPoint( SIP_PYOBJECT x = Py_None, SIP_PYOBJECT y = Py_None, SIP_PYOBJECT z = Py_None, SIP_PYOBJECT m = Py_None, SIP_PYOBJECT wkbType = Py_None ) [( double x = 0.0, double y = 0.0, double z = 0.0, double m = 0.0, QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown )];
78  % MethodCode
79  if ( sipCanConvertToType( a0, sipType_QgsPointXY, SIP_NOT_NONE ) && a1 == Py_None && a2 == Py_None && a3 == Py_None && a4 == Py_None )
80  {
81  int state;
82  sipIsErr = 0;
83 
84  QgsPointXY *p = reinterpret_cast<QgsPointXY *>( sipConvertToType( a0, sipType_QgsPointXY, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
85  if ( sipIsErr )
86  {
87  sipReleaseType( p, sipType_QgsPointXY, state );
88  }
89  else
90  {
91  sipCpp = new sipQgsPoint( QgsPoint( *p ) );
92  }
93  }
94  else if ( sipCanConvertToType( a0, sipType_QPointF, SIP_NOT_NONE ) && a1 == Py_None && a2 == Py_None && a3 == Py_None && a4 == Py_None )
95  {
96  int state;
97  sipIsErr = 0;
98 
99  QPointF *p = reinterpret_cast<QPointF *>( sipConvertToType( a0, sipType_QPointF, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
100  if ( sipIsErr )
101  {
102  sipReleaseType( p, sipType_QPointF, state );
103  }
104  else
105  {
106  sipCpp = new sipQgsPoint( QgsPoint( *p ) );
107  }
108  }
109  else if (
110  ( a0 == Py_None || PyFloat_AsDouble( a0 ) != -1.0 || !PyErr_Occurred() ) &&
111  ( a1 == Py_None || PyFloat_AsDouble( a1 ) != -1.0 || !PyErr_Occurred() ) &&
112  ( a2 == Py_None || PyFloat_AsDouble( a2 ) != -1.0 || !PyErr_Occurred() ) &&
113  ( a3 == Py_None || PyFloat_AsDouble( a3 ) != -1.0 || !PyErr_Occurred() ) )
114  {
115  double x = a0 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a0 );
116  double y = a1 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a1 );
117  double z = a2 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a2 );
118  double m = a3 == Py_None ? std::numeric_limits<double>::quiet_NaN() : PyFloat_AsDouble( a3 );
119  QgsWkbTypes::Type wkbType = a4 == Py_None ? QgsWkbTypes::Unknown : static_cast<QgsWkbTypes::Type>( sipConvertToEnum( a4, sipType_QgsWkbTypes_Type ) );
120  sipCpp = new sipQgsPoint( QgsPoint( x, y, z, m, wkbType ) );
121  }
122  else // Invalid ctor arguments
123  {
124  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type in constructor arguments." ).toUtf8().constData() );
125  sipIsErr = 1;
126  }
127  % End
128 #endif
129 
133  explicit QgsPoint( const QgsPointXY &p ) SIP_SKIP;
134 
138  explicit QgsPoint( QPointF p ) SIP_SKIP;
139 
145  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;
146 
147  bool operator==( const QgsAbstractGeometry &other ) const override SIP_HOLDGIL
148  {
149  const QgsPoint *pt = qgsgeometry_cast< const QgsPoint * >( &other );
150  if ( !pt )
151  return false;
152 
153  const QgsWkbTypes::Type type = wkbType();
154 
155  if ( pt->wkbType() != type )
156  return false;
157 
158  const bool nan1X = std::isnan( mX );
159  const bool nan2X = std::isnan( pt->x() );
160  if ( nan1X != nan2X )
161  return false;
162  if ( !nan1X && !qgsDoubleNear( mX, pt->x(), 1E-8 ) )
163  return false;
164 
165  const bool nan1Y = std::isnan( mY );
166  const bool nan2Y = std::isnan( pt->y() );
167  if ( nan1Y != nan2Y )
168  return false;
169  if ( !nan1Y && !qgsDoubleNear( mY, pt->y(), 1E-8 ) )
170  return false;
171 
172  if ( QgsWkbTypes::hasZ( type ) )
173  {
174  const bool nan1Z = std::isnan( mZ );
175  const bool nan2Z = std::isnan( pt->z() );
176  if ( nan1Z != nan2Z )
177  return false;
178  if ( !nan1Z && !qgsDoubleNear( mZ, pt->z(), 1E-8 ) )
179  return false;
180  }
181 
182  if ( QgsWkbTypes::hasM( type ) )
183  {
184  const bool nan1M = std::isnan( mM );
185  const bool nan2M = std::isnan( pt->m() );
186  if ( nan1M != nan2M )
187  return false;
188  if ( !nan1M && !qgsDoubleNear( mM, pt->m(), 1E-8 ) )
189  return false;
190  }
191 
192  return true;
193  }
194 
195  bool operator!=( const QgsAbstractGeometry &other ) const override SIP_HOLDGIL
196  {
197  return !operator==( other );
198  }
199 
205  double x() const SIP_HOLDGIL { return mX; }
206 
212  double y() const SIP_HOLDGIL { return mY; }
213 
219  double z() const SIP_HOLDGIL { return mZ; }
220 
226  double m() const SIP_HOLDGIL { return mM; }
227 
235  double &rx() SIP_SKIP { clearCache(); return mX; }
236 
244  double &ry() SIP_SKIP { clearCache(); return mY; }
245 
253  double &rz() SIP_SKIP { clearCache(); return mZ; }
254 
262  double &rm() SIP_SKIP { clearCache(); return mM; }
263 
269  void setX( double x ) SIP_HOLDGIL
270  {
271  clearCache();
272  mX = x;
273  }
274 
280  void setY( double y ) SIP_HOLDGIL
281  {
282  clearCache();
283  mY = y;
284  }
285 
293  void setZ( double z ) SIP_HOLDGIL
294  {
295  if ( !is3D() )
296  return;
297  clearCache();
298  mZ = z;
299  }
300 
308  void setM( double m ) SIP_HOLDGIL
309  {
310  if ( !isMeasure() )
311  return;
312  clearCache();
313  mM = m;
314  }
315 
320  QPointF toQPointF() const SIP_HOLDGIL
321  {
322  return QPointF( mX, mY );
323  }
324 
332  double distance( double x, double y ) const SIP_HOLDGIL
333  {
334  return std::sqrt( ( mX - x ) * ( mX - x ) + ( mY - y ) * ( mY - y ) );
335  }
336 
343  double distance( const QgsPoint &other ) const SIP_HOLDGIL
344  {
345  return std::sqrt( ( mX - other.x() ) * ( mX - other.x() ) + ( mY - other.y() ) * ( mY - other.y() ) );
346  }
347 
355  double distanceSquared( double x, double y ) const SIP_HOLDGIL
356  {
357  return ( mX - x ) * ( mX - x ) + ( mY - y ) * ( mY - y );
358  }
359 
367  double distanceSquared( const QgsPoint &other ) const SIP_HOLDGIL
368  {
369  return ( mX - other.x() ) * ( mX - other.x() ) + ( mY - other.y() ) * ( mY - other.y() );
370  }
371 
379  double distance3D( double x, double y, double z ) const SIP_HOLDGIL;
380 
387  double distance3D( const QgsPoint &other ) const SIP_HOLDGIL;
388 
396  double distanceSquared3D( double x, double y, double z ) const SIP_HOLDGIL;
397 
405  double distanceSquared3D( const QgsPoint &other ) const SIP_HOLDGIL;
406 
411  double azimuth( const QgsPoint &other ) const SIP_HOLDGIL;
412 
418  double inclination( const QgsPoint &other ) const SIP_HOLDGIL;
419 
450  QgsPoint project( double distance, double azimuth, double inclination = 90.0 ) const SIP_HOLDGIL;
451 
456  QgsVector operator-( const QgsPoint &p ) const SIP_HOLDGIL { return QgsVector( mX - p.mX, mY - p.mY ); }
457 
462  QgsPoint &operator+=( QgsVector v ) SIP_HOLDGIL { mX += v.x(); mY += v.y(); return *this; }
463 
468  QgsPoint &operator-=( QgsVector v ) SIP_HOLDGIL { mX -= v.x(); mY -= v.y(); return *this; }
469 
474  QgsPoint operator+( QgsVector v ) const SIP_HOLDGIL { QgsPoint r = *this; r.rx() += v.x(); r.ry() += v.y(); return r; }
475 
480  QgsPoint operator-( QgsVector v ) const SIP_HOLDGIL { QgsPoint r = *this; r.rx() -= v.x(); r.ry() -= v.y(); return r; }
481 
482  //implementation of inherited methods
483  void normalize() final SIP_HOLDGIL;
484  bool isEmpty() const override SIP_HOLDGIL;
485  QgsRectangle boundingBox() const override SIP_HOLDGIL;
486  QString geometryType() const override SIP_HOLDGIL;
487  int dimension() const override SIP_HOLDGIL;
488  QgsPoint *clone() const override SIP_FACTORY;
489  QgsPoint *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY;
490  bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;
491  void clear() override;
492  bool fromWkb( QgsConstWkbPtr &wkb ) override;
493  bool fromWkt( const QString &wkt ) override;
494  int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
495  QByteArray asWkb( QgsAbstractGeometry::WkbFlags = QgsAbstractGeometry::WkbFlags() ) const override;
496  QString asWkt( int precision = 17 ) const override;
497  QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
498  QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
499  json asJsonObject( int precision = 17 ) const override SIP_SKIP;
500  QString asKml( int precision = 17 ) const override;
501  void draw( QPainter &p ) const override;
502  QPainterPath asQPainterPath() const override;
503  void transform( const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform, bool transformZ = false ) override SIP_THROW( QgsCsException );
504  void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 ) override;
505  QgsCoordinateSequence coordinateSequence() const override;
506  int nCoordinates() const override SIP_HOLDGIL;
507  int vertexNumberFromVertexId( QgsVertexId id ) const override;
508  QgsAbstractGeometry *boundary() const override SIP_FACTORY;
509  bool isValid( QString &error SIP_OUT, int flags = 0 ) const override SIP_HOLDGIL;
510 
511  //low-level editing
512  bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) override;
513  bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) override;
514  bool deleteVertex( QgsVertexId position ) override;
515 
516  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;
517  bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const override;
518  void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const override;
519 
525  double vertexAngle( QgsVertexId vertex ) const override;
526 
527  int vertexCount( int /*part*/ = 0, int /*ring*/ = 0 ) const override;
528  int ringCount( int /*part*/ = 0 ) const override;
529  int partCount() const override;
530  QgsPoint vertexAt( QgsVertexId /*id*/ ) const override;
531  QgsPoint *toCurveType() const override SIP_FACTORY;
532  double segmentLength( QgsVertexId startVertex ) const override;
533  bool boundingBoxIntersects( const QgsRectangle &rectangle ) const override SIP_HOLDGIL;
534 
535  bool addZValue( double zValue = 0 ) override;
536  bool addMValue( double mValue = 0 ) override;
537  bool dropZValue() override;
538  bool dropMValue() override;
539  void swapXy() override;
540  bool convertTo( QgsWkbTypes::Type type ) override;
541 
542  bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) override;
543 
544 #ifndef SIP_RUN
545 
546  void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
547  void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) override;
548 
556  inline static const QgsPoint *cast( const QgsAbstractGeometry *geom )
557  {
558  if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::Point )
559  return static_cast<const QgsPoint *>( geom );
560  return nullptr;
561  }
562 #endif
563 
564  QgsPoint *createEmptyWithSameType() const override SIP_FACTORY;
565 
566 #ifdef SIP_RUN
567  SIP_PYOBJECT __repr__();
568  % MethodCode
569  QString str = QStringLiteral( "<QgsPoint: %1>" ).arg( sipCpp->asWkt() );
570  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
571  % End
572 #endif
573 
574  protected:
575 
576  int compareToSameClass( const QgsAbstractGeometry *other ) const final;
577  int childCount() const override;
578  QgsPoint childPoint( int index ) const override;
579 
580  private:
581  double mX;
582  double mY;
583  double mZ;
584  double mM;
585 };
586 
587 // clazy:excludeall=qstring-allocations
588 
589 #endif // QGSPOINT_H
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:44
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:38
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:332
double m() const SIP_HOLDGIL
Returns the point's m value.
Definition: qgspoint.h:226
double & ry()
Returns a reference to the y-coordinate of this point.
Definition: qgspoint.h:244
QPointF toQPointF() const SIP_HOLDGIL
Returns the point as a QPointF.
Definition: qgspoint.h:320
static const QgsPoint * cast(const QgsAbstractGeometry *geom)
Cast the geom to a QgsPoint.
Definition: qgspoint.h:556
void setX(double x) SIP_HOLDGIL
Sets the point's x-coordinate.
Definition: qgspoint.h:269
double distance(const QgsPoint &other) const SIP_HOLDGIL
Returns the Cartesian 2D distance between this point and another point.
Definition: qgspoint.h:343
Q_GADGET double x
Definition: qgspoint.h:41
void setY(double y) SIP_HOLDGIL
Sets the point's y-coordinate.
Definition: qgspoint.h:280
double & rz()
Returns a reference to the z-coordinate of this point.
Definition: qgspoint.h:253
double & rm()
Returns a reference to the m value of this point.
Definition: qgspoint.h:262
void setZ(double z) SIP_HOLDGIL
Sets the point's z-coordinate.
Definition: qgspoint.h:293
QgsPoint operator-(QgsVector v) const SIP_HOLDGIL
Subtracts a vector from this point.
Definition: qgspoint.h:480
double y() const SIP_HOLDGIL
Returns the point's y-coordinate.
Definition: qgspoint.h:212
double distanceSquared(const QgsPoint &other) const SIP_HOLDGIL
Returns the Cartesian 2D squared distance between this point another point.
Definition: qgspoint.h:367
double z
Definition: qgspoint.h:43
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:355
QgsPoint operator+(QgsVector v) const SIP_HOLDGIL
Adds a vector to this point.
Definition: qgspoint.h:474
double x() const SIP_HOLDGIL
Returns the point's x-coordinate.
Definition: qgspoint.h:205
double & rx()
Returns a reference to the x-coordinate of this point.
Definition: qgspoint.h:235
double z() const SIP_HOLDGIL
Returns the point's z-coordinate.
Definition: qgspoint.h:219
QgsPoint & operator-=(QgsVector v) SIP_HOLDGIL
Subtracts a vector from this point in place.
Definition: qgspoint.h:468
double m
Definition: qgspoint.h:44
bool operator!=(const QgsAbstractGeometry &other) const override SIP_HOLDGIL
Definition: qgspoint.h:195
double y
Definition: qgspoint.h:42
void setM(double m) SIP_HOLDGIL
Sets the point's m-value.
Definition: qgspoint.h:308
QgsPoint & operator+=(QgsVector v) SIP_HOLDGIL
Adds a vector to this point in place.
Definition: qgspoint.h:462
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:350
#define SIP_THROW(name)
Definition: qgis_sip.h:189
#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:68
int precision
Utility class for identifying a unique vertex within a geometry.