QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
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  bool isEmpty() const override SIP_HOLDGIL;
484  QgsRectangle boundingBox() const override SIP_HOLDGIL;
485  QString geometryType() const override SIP_HOLDGIL;
486  int dimension() const override SIP_HOLDGIL;
487  QgsPoint *clone() const override SIP_FACTORY;
488  QgsPoint *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY;
489  bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;
490  void clear() override;
491  bool fromWkb( QgsConstWkbPtr &wkb ) override;
492  bool fromWkt( const QString &wkt ) override;
493  int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
494  QByteArray asWkb( QgsAbstractGeometry::WkbFlags = QgsAbstractGeometry::WkbFlags() ) const override;
495  QString asWkt( int precision = 17 ) const override;
496  QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
497  QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
498  json asJsonObject( int precision = 17 ) const override SIP_SKIP;
499  QString asKml( int precision = 17 ) const override;
500  void draw( QPainter &p ) const override;
501  QPainterPath asQPainterPath() const override;
502  void transform( const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform, bool transformZ = false ) override SIP_THROW( QgsCsException );
503  void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 ) override;
504  QgsCoordinateSequence coordinateSequence() const override;
505  int nCoordinates() const override SIP_HOLDGIL;
506  int vertexNumberFromVertexId( QgsVertexId id ) const override;
507  QgsAbstractGeometry *boundary() const override SIP_FACTORY;
508  bool isValid( QString &error SIP_OUT, int flags = 0 ) const override SIP_HOLDGIL;
509 
510  //low-level editing
511  bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) override;
512  bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) override;
513  bool deleteVertex( QgsVertexId position ) override;
514 
515  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;
516  bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const override;
517  void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const override;
518 
524  double vertexAngle( QgsVertexId vertex ) const override;
525 
526  int vertexCount( int /*part*/ = 0, int /*ring*/ = 0 ) const override;
527  int ringCount( int /*part*/ = 0 ) const override;
528  int partCount() const override;
529  QgsPoint vertexAt( QgsVertexId /*id*/ ) const override;
530  QgsPoint *toCurveType() const override SIP_FACTORY;
531  double segmentLength( QgsVertexId startVertex ) const override;
532 
533  bool addZValue( double zValue = 0 ) override;
534  bool addMValue( double mValue = 0 ) override;
535  bool dropZValue() override;
536  bool dropMValue() override;
537  void swapXy() override;
538  bool convertTo( QgsWkbTypes::Type type ) override;
539 
540  bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) override;
541 
542 #ifndef SIP_RUN
543 
544  void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
545  void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) override;
546 
554  inline static const QgsPoint *cast( const QgsAbstractGeometry *geom )
555  {
556  if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::Point )
557  return static_cast<const QgsPoint *>( geom );
558  return nullptr;
559  }
560 #endif
561 
562  QgsPoint *createEmptyWithSameType() const override SIP_FACTORY;
563 
564 #ifdef SIP_RUN
565  SIP_PYOBJECT __repr__();
566  % MethodCode
567  QString str = QStringLiteral( "<QgsPoint: %1>" ).arg( sipCpp->asWkt() );
568  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
569  % End
570 #endif
571 
572  protected:
573 
574  int childCount() const override;
575  QgsPoint childPoint( int index ) const override;
576 
577  private:
578  double mX;
579  double mY;
580  double mZ;
581  double mM;
582 };
583 
584 // clazy:excludeall=qstring-allocations
585 
586 #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 bool isEmpty() const
Returns true if the geometry is empty.
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
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
A const WKB pointer.
Definition: qgswkbptr.h:130
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:554
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
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:316
#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.