QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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;
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
QgsCoordinateSequence
QVector< QgsRingSequence > QgsCoordinateSequence
Definition: qgsabstractgeometry.h:57
QgsAbstractGeometry::compareToSameClass
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...
QgsAbstractGeometry::clearCache
virtual void clearCache() const
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
Definition: qgsabstractgeometry.cpp:146
QgsWkbTypes::Point
@ Point
Definition: qgswkbtypes.h:72
qgsrectangle.h
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:48
SIP_OUT
#define SIP_OUT
Definition: qgis_sip.h:58
QgsWkbTypes::flatType
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:732
QgsAbstractGeometry::filterVertices
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...
Definition: qgsabstractgeometry.cpp:292
QgsPoint::z
double z
Definition: qgspoint.h:71
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:69
closestSegment
double closestSegment(const QgsPolylineXY &pl, const QgsPointXY &pt, int &vertexAfter, double epsilon)
Definition: qgstracer.cpp:69
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
SIP_TYPEHINT
#define SIP_TYPEHINT(type)
Definition: qgis_sip.h:227
SIP_FACTORY
#define SIP_FACTORY
Definition: qgis_sip.h:76
QgsAbstractGeometry::isMeasure
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
Definition: qgsabstractgeometry.h:228
MathUtils::leftOf
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
QgsPoint::y
double y
Definition: qgspoint.h:70
precision
int precision
Definition: qgswfsgetfeature.cpp:103
QgsPoint::rx
double & rx()
Returns a reference to the x-coordinate of this point.
Definition: qgspoint.h:263
QgsCsException
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
SIP_SKIP
#define SIP_SKIP
Definition: qgis_sip.h:126
SIP_HOLDGIL
#define SIP_HOLDGIL
Definition: qgis_sip.h:166
SIP_THROW
#define SIP_THROW(name)
Definition: qgis_sip.h:198
QgsAbstractGeometry::wkbType
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
Definition: qgsabstractgeometry.h:206
QgsWkbTypes::Unknown
@ Unknown
Definition: qgswkbtypes.h:71
QgsAbstractGeometry::AxisOrder
AxisOrder
Axis order for GML generation.
Definition: qgsabstractgeometry.h:138
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2265
QgsConstWkbPtr
A const WKB pointer.
Definition: qgswkbptr.h:137
QgsFeedback
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:44
QgsAbstractGeometry::childPoint
virtual QgsPoint childPoint(int index) const
Returns point at index (for geometries without child geometries - i.e.
Definition: qgsabstractgeometry.cpp:372
qgis_sip.h
QgsWkbTypes::hasM
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:1130
QgsPoint::m
double m
Definition: qgspoint.h:72
QgsAbstractGeometry
Abstract base class for all geometries.
Definition: qgsabstractgeometry.h:79
QgsAbstractGeometry::normalize
virtual void normalize()=0
Reorganizes the geometry into a normalized form (or "canonical" form).
QgsAbstractGeometry::is3D
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
Definition: qgsabstractgeometry.h:219
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:58
QgsAbstractGeometry::createEmptyWithSameType
virtual QgsAbstractGeometry * createEmptyWithSameType() const =0
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
QgsAbstractGeometry::operator!=
virtual bool operator!=(const QgsAbstractGeometry &other) const =0
str
#define str(x)
Definition: qgis.cpp:37
operator-
QgsInterval operator-(const QDateTime &dt1, const QDateTime &dt2)
Returns the interval between two datetimes.
Definition: qgsinterval.cpp:299
QgsVector
A class to represent a vector. Currently no Z axis / 2.5D support is implemented.
Definition: qgsvector.h:29
QgsAbstractGeometry::childCount
virtual int childCount() const
Returns number of child geometries (for geometries with child geometries) or child points (for geomet...
Definition: qgsabstractgeometry.h:1102
QgsVertexId
Utility class for identifying a unique vertex within a geometry.
Definition: qgsvertexid.h:30
QgsAbstractGeometryTransformer
An abstract base class for classes which transform geometries by transforming input points to output ...
Definition: qgsgeometrytransformer.h:32
operator+
QDateTime operator+(const QDateTime &start, const QgsInterval &interval)
Adds an interval to a datetime.
Definition: qgsinterval.cpp:305
QgsAbstractGeometry::transformVertices
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.
Definition: qgsabstractgeometry.cpp:297
QgsWkbTypes::hasZ
static bool hasZ(Type type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:1080
Qgis
The Qgis class provides global constants for use throughout the application.
Definition: qgis.h:71
QgsAbstractGeometry::operator==
virtual bool operator==(const QgsAbstractGeometry &other) const =0
QgsWkbTypes
Handles storage of information regarding WKB types and their properties.
Definition: qgswkbtypes.h:41
QgsPoint::ry
double & ry()
Returns a reference to the y-coordinate of this point.
Definition: qgspoint.h:272
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:57
qgsabstractgeometry.h
QgsPoint::x
double x
Definition: qgspoint.h:69