Branch data Line data Source code
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 : :
32 : : /**
33 : : * \ingroup core
34 : : * \brief Point geometry type, with support for z-dimension and m-values.
35 : : * \since QGIS 3.0, (previously QgsPointV2 since QGIS 2.10)
36 : : */
37 : 562504 : 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 : :
48 : : /**
49 : : * Construct a point with the provided initial coordinate values.
50 : : *
51 : : * If \a wkbType is set to `QgsWkbTypes::Point`, `QgsWkbTypes::PointZ`, `QgsWkbTypes::PointM` or `QgsWkbTypes::PointZM`
52 : : * the type will be set accordingly. If it is left to the default `QgsWkbTypes::Unknown`, the type will be set
53 : : * based on the following rules:
54 : : *
55 : : * - If only x and y are specified, the type will be a 2D point.
56 : : * - If any or both of the Z and M are specified, the appropriate type will be created.
57 : : *
58 : : * \code{.py}
59 : : * pt = QgsPoint(43.4, 5.3)
60 : : * pt.asWkt() # Point(43.4 5.3)
61 : : *
62 : : * pt_z = QgsPoint(120, 343, 77)
63 : : * pt.asWkt() # PointZ(120 343 77)
64 : : *
65 : : * pt_m = QgsPoint(33, 88, m=5)
66 : : * pt_m.m() # 5
67 : : * pt_m.wkbType() # QgsWkbTypes.PointM
68 : : *
69 : : * pt = QgsPoint(30, 40, wkbType=QgsWkbTypes.PointZ)
70 : : * pt.z() # nan
71 : : * pt.wkbType() # QgsWkbTypes.PointZ
72 : : * \endcode
73 : : */
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 : :
130 : : /**
131 : : * Construct a QgsPoint from a QgsPointXY object
132 : : */
133 : : explicit QgsPoint( const QgsPointXY &p ) SIP_SKIP;
134 : :
135 : : /**
136 : : * Construct a QgsPoint from a QPointF
137 : : */
138 : : explicit QgsPoint( QPointF p ) SIP_SKIP;
139 : :
140 : : /**
141 : : * Create a new point with the given wkbtype and values.
142 : : *
143 : : * \note Not available in Python bindings
144 : : */
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 : 104387 : bool operator==( const QgsAbstractGeometry &other ) const override SIP_HOLDGIL
148 : : {
149 : 104387 : const QgsPoint *pt = qgsgeometry_cast< const QgsPoint * >( &other );
150 : 104387 : if ( !pt )
151 : 2 : return false;
152 : :
153 : 104385 : const QgsWkbTypes::Type type = wkbType();
154 : :
155 : 104385 : if ( pt->wkbType() != type )
156 : 9 : return false;
157 : :
158 : 104376 : const bool nan1X = std::isnan( mX );
159 : 104376 : const bool nan2X = std::isnan( pt->x() );
160 : 104376 : if ( nan1X != nan2X )
161 : 7 : return false;
162 : 104369 : if ( !nan1X && !qgsDoubleNear( mX, pt->x(), 1E-8 ) )
163 : 1270 : return false;
164 : :
165 : 103099 : const bool nan1Y = std::isnan( mY );
166 : 103099 : const bool nan2Y = std::isnan( pt->y() );
167 : 103099 : if ( nan1Y != nan2Y )
168 : 0 : return false;
169 : 103099 : if ( !nan1Y && !qgsDoubleNear( mY, pt->y(), 1E-8 ) )
170 : 458 : return false;
171 : :
172 : 102641 : if ( QgsWkbTypes::hasZ( type ) )
173 : : {
174 : 492 : const bool nan1Z = std::isnan( mZ );
175 : 492 : const bool nan2Z = std::isnan( pt->z() );
176 : 492 : if ( nan1Z != nan2Z )
177 : 0 : return false;
178 : 492 : if ( !nan1Z && !qgsDoubleNear( mZ, pt->z(), 1E-8 ) )
179 : 1 : return false;
180 : 491 : }
181 : :
182 : 102640 : if ( QgsWkbTypes::hasM( type ) )
183 : : {
184 : 450 : const bool nan1M = std::isnan( mM );
185 : 450 : const bool nan2M = std::isnan( pt->m() );
186 : 450 : if ( nan1M != nan2M )
187 : 0 : return false;
188 : 450 : if ( !nan1M && !qgsDoubleNear( mM, pt->m(), 1E-8 ) )
189 : 1 : return false;
190 : 449 : }
191 : :
192 : 102639 : return true;
193 : 104387 : }
194 : :
195 : 101099 : bool operator!=( const QgsAbstractGeometry &other ) const override SIP_HOLDGIL
196 : : {
197 : 101099 : return !operator==( other );
198 : : }
199 : :
200 : : /**
201 : : * Returns the point's x-coordinate.
202 : : * \see setX()
203 : : * \see rx()
204 : : */
205 : 376305 : double x() const SIP_HOLDGIL { return mX; }
206 : :
207 : : /**
208 : : * Returns the point's y-coordinate.
209 : : * \see setY()
210 : : * \see ry()
211 : : */
212 : 372893 : double y() const SIP_HOLDGIL { return mY; }
213 : :
214 : : /**
215 : : * Returns the point's z-coordinate.
216 : : * \see setZ()
217 : : * \see rz()
218 : : */
219 : 46708 : double z() const SIP_HOLDGIL { return mZ; }
220 : :
221 : : /**
222 : : * Returns the point's m value.
223 : : * \see setM()
224 : : * \see rm()
225 : : */
226 : 44741 : double m() const SIP_HOLDGIL { return mM; }
227 : :
228 : : /**
229 : : * Returns a reference to the x-coordinate of this point.
230 : : * Using a reference makes it possible to directly manipulate x in place.
231 : : * \see x()
232 : : * \see setX()
233 : : * \note not available in Python bindings
234 : : */
235 : 659 : double &rx() SIP_SKIP { clearCache(); return mX; }
236 : :
237 : : /**
238 : : * Returns a reference to the y-coordinate of this point.
239 : : * Using a reference makes it possible to directly manipulate y in place.
240 : : * \see y()
241 : : * \see setY()
242 : : * \note not available in Python bindings
243 : : */
244 : 659 : double &ry() SIP_SKIP { clearCache(); return mY; }
245 : :
246 : : /**
247 : : * Returns a reference to the z-coordinate of this point.
248 : : * Using a reference makes it possible to directly manipulate z in place.
249 : : * \see z()
250 : : * \see setZ()
251 : : * \note not available in Python bindings
252 : : */
253 : 2 : double &rz() SIP_SKIP { clearCache(); return mZ; }
254 : :
255 : : /**
256 : : * Returns a reference to the m value of this point.
257 : : * Using a reference makes it possible to directly manipulate m in place.
258 : : * \see m()
259 : : * \see setM()
260 : : * \note not available in Python bindings
261 : : */
262 : 2 : double &rm() SIP_SKIP { clearCache(); return mM; }
263 : :
264 : : /**
265 : : * Sets the point's x-coordinate.
266 : : * \see x()
267 : : * \see rx()
268 : : */
269 : 406 : void setX( double x ) SIP_HOLDGIL
270 : : {
271 : 406 : clearCache();
272 : 406 : mX = x;
273 : 406 : }
274 : :
275 : : /**
276 : : * Sets the point's y-coordinate.
277 : : * \see y()
278 : : * \see ry()
279 : : */
280 : 405 : void setY( double y ) SIP_HOLDGIL
281 : : {
282 : 405 : clearCache();
283 : 405 : mY = y;
284 : 405 : }
285 : :
286 : : /**
287 : : * Sets the point's z-coordinate.
288 : : * \note calling this will have no effect if the point does not contain a z-dimension. Use addZValue() to
289 : : * add a z value and force the point to have a z dimension.
290 : : * \see z()
291 : : * \see rz()
292 : : */
293 : 23 : void setZ( double z ) SIP_HOLDGIL
294 : : {
295 : 23 : if ( !is3D() )
296 : 0 : return;
297 : 23 : clearCache();
298 : 23 : mZ = z;
299 : 23 : }
300 : :
301 : : /**
302 : : * Sets the point's m-value.
303 : : * \note calling this will have no effect if the point does not contain a m-dimension. Use addMValue() to
304 : : * add a m value and force the point to have an m dimension.
305 : : * \see m()
306 : : * \see rm()
307 : : */
308 : 20 : void setM( double m ) SIP_HOLDGIL
309 : : {
310 : 20 : if ( !isMeasure() )
311 : 0 : return;
312 : 20 : clearCache();
313 : 20 : mM = m;
314 : 20 : }
315 : :
316 : : /**
317 : : * Returns the point as a QPointF.
318 : : * \since QGIS 2.14
319 : : */
320 : 1 : QPointF toQPointF() const SIP_HOLDGIL
321 : : {
322 : 1 : return QPointF( mX, mY );
323 : : }
324 : :
325 : : /**
326 : : * Returns the Cartesian 2D distance between this point and a specified x, y coordinate. In certain
327 : : * cases it may be more appropriate to call the faster distanceSquared() method, e.g.,
328 : : * when comparing distances.
329 : : * \see distanceSquared()
330 : : * \since QGIS 3.0
331 : : */
332 : 5 : double distance( double x, double y ) const SIP_HOLDGIL
333 : : {
334 : 5 : return std::sqrt( ( mX - x ) * ( mX - x ) + ( mY - y ) * ( mY - y ) );
335 : : }
336 : :
337 : : /**
338 : : * Returns the Cartesian 2D distance between this point and another point. In certain
339 : : * cases it may be more appropriate to call the faster distanceSquared() method, e.g.,
340 : : * when comparing distances.
341 : : * \since QGIS 3.0
342 : : */
343 : 565 : double distance( const QgsPoint &other ) const SIP_HOLDGIL
344 : : {
345 : 565 : return std::sqrt( ( mX - other.x() ) * ( mX - other.x() ) + ( mY - other.y() ) * ( mY - other.y() ) );
346 : : }
347 : :
348 : : /**
349 : : * Returns the Cartesian 2D squared distance between this point a specified x, y coordinate. Calling
350 : : * this is faster than calling distance(), and may be useful in use cases such as comparing
351 : : * distances where the extra expense of calling distance() is not required.
352 : : * \see distance()
353 : : * \since QGIS 3.0
354 : : */
355 : 5 : double distanceSquared( double x, double y ) const SIP_HOLDGIL
356 : : {
357 : 5 : return ( mX - x ) * ( mX - x ) + ( mY - y ) * ( mY - y );
358 : : }
359 : :
360 : : /**
361 : : * Returns the Cartesian 2D squared distance between this point another point. Calling
362 : : * this is faster than calling distance(), and may be useful in use cases such as comparing
363 : : * distances where the extra expense of calling distance() is not required.
364 : : * \see distance()
365 : : * \since QGIS 3.0
366 : : */
367 : 13 : double distanceSquared( const QgsPoint &other ) const SIP_HOLDGIL
368 : : {
369 : 13 : return ( mX - other.x() ) * ( mX - other.x() ) + ( mY - other.y() ) * ( mY - other.y() );
370 : : }
371 : :
372 : : /**
373 : : * Returns the Cartesian 3D distance between this point and a specified x, y, z coordinate. In certain
374 : : * cases it may be more appropriate to call the faster distanceSquared() method, e.g.,
375 : : * when comparing distances.
376 : : * \see distanceSquared()
377 : : * \since QGIS 3.0
378 : : */
379 : : double distance3D( double x, double y, double z ) const SIP_HOLDGIL;
380 : :
381 : : /**
382 : : * Returns the Cartesian 3D distance between this point and another point. In certain
383 : : * cases it may be more appropriate to call the faster distanceSquared() method, e.g.,
384 : : * when comparing distances.
385 : : * \since QGIS 3.0
386 : : */
387 : : double distance3D( const QgsPoint &other ) const SIP_HOLDGIL;
388 : :
389 : : /**
390 : : * Returns the Cartesian 3D squared distance between this point and a specified x, y, z coordinate. Calling
391 : : * this is faster than calling distance(), and may be useful in use cases such as comparing
392 : : * distances where the extra expense of calling distance() is not required.
393 : : * \see distance()
394 : : * \since QGIS 3.0
395 : : */
396 : : double distanceSquared3D( double x, double y, double z ) const SIP_HOLDGIL;
397 : :
398 : : /**
399 : : * Returns the Cartesian 3D squared distance between this point and another point. Calling
400 : : * this is faster than calling distance(), and may be useful in use cases such as comparing
401 : : * distances where the extra expense of calling distance() is not required.
402 : : * \see distance()
403 : : * \since QGIS 3.0
404 : : */
405 : : double distanceSquared3D( const QgsPoint &other ) const SIP_HOLDGIL;
406 : :
407 : : /**
408 : : * Calculates Cartesian azimuth between this point and other one (clockwise in degree, starting from north)
409 : : * \since QGIS 3.0
410 : : */
411 : : double azimuth( const QgsPoint &other ) const SIP_HOLDGIL;
412 : :
413 : : /**
414 : : * Calculates Cartesian inclination between this point and other one (starting from zenith = 0 to nadir = 180. Horizon = 90)
415 : : * Returns 90.0 if the distance between this point and other one is equal to 0 (same point).
416 : : * \since QGIS 3.0
417 : : */
418 : : double inclination( const QgsPoint &other ) const SIP_HOLDGIL;
419 : :
420 : : /**
421 : : * Returns a new point which corresponds to this point projected by a specified distance
422 : : * with specified angles (azimuth and inclination), using Cartesian mathematics.
423 : : * M value is preserved.
424 : : * \param distance distance to project
425 : : * \param azimuth angle to project in X Y, clockwise in degrees starting from north
426 : : * \param inclination angle to project in Z (3D). If the point is 2D, the Z value is assumed to be 0.
427 : : * \returns The point projected. If a 2D point is projected a 3D point will be returned except if
428 : : * inclination is 90. A 3D point is always returned if a 3D point is projected.
429 : : *
430 : : * ### Example
431 : : *
432 : : * \code{.py}
433 : : * p = QgsPoint( 1, 2 ) # 2D point
434 : : * pr = p.project ( 1, 0 )
435 : : * # pr is a 2D point: 'Point (1 3)'
436 : : * pr = p.project ( 1, 0, 90 )
437 : : * # pr is a 2D point: 'Point (1 3)'
438 : : * pr = p.project (1, 0, 0 )
439 : : * # pr is a 3D point: 'PointZ (1 2 1)'
440 : : * p = QgsPoint( QgsWkbTypes.PointZ, 1, 2, 2 ) # 3D point
441 : : * pr = p.project ( 1, 0 )
442 : : * # pr is a 3D point: 'PointZ (1 3 2)'
443 : : * pr = p.project ( 1, 0, 90 )
444 : : * # pr is a 3D point: 'PointZ (1 3 2)'
445 : : * pr = p.project (1, 0, 0 )
446 : : * # pr is a 3D point: 'PointZ (1 2 3)'
447 : : * \endcode
448 : : * \since QGIS 3.0
449 : : */
450 : : QgsPoint project( double distance, double azimuth, double inclination = 90.0 ) const SIP_HOLDGIL;
451 : :
452 : : /**
453 : : * Calculates the vector obtained by subtracting a point from this point.
454 : : * \since QGIS 3.0
455 : : */
456 : 2 : QgsVector operator-( const QgsPoint &p ) const SIP_HOLDGIL { return QgsVector( mX - p.mX, mY - p.mY ); }
457 : :
458 : : /**
459 : : * Adds a vector to this point in place.
460 : : * \since QGIS 3.0
461 : : */
462 : 1 : QgsPoint &operator+=( QgsVector v ) SIP_HOLDGIL { mX += v.x(); mY += v.y(); return *this; }
463 : :
464 : : /**
465 : : * Subtracts a vector from this point in place.
466 : : * \since QGIS 3.0
467 : : */
468 : 1 : QgsPoint &operator-=( QgsVector v ) SIP_HOLDGIL { mX -= v.x(); mY -= v.y(); return *this; }
469 : :
470 : : /**
471 : : * Adds a vector to this point.
472 : : * \since QGIS 3.0
473 : : */
474 : 1 : QgsPoint operator+( QgsVector v ) const SIP_HOLDGIL { QgsPoint r = *this; r.rx() += v.x(); r.ry() += v.y(); return r; }
475 : :
476 : : /**
477 : : * Subtracts a vector from this point.
478 : : * \since QGIS 3.0
479 : : */
480 : 1 : 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 : :
519 : : /**
520 : : * Angle undefined. Always returns 0.0
521 : : * \param vertex the vertex id
522 : : * \returns 0.0
523 : : */
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 : : bool boundingBoxIntersects( const QgsRectangle &rectangle ) const override SIP_HOLDGIL;
533 : :
534 : : bool addZValue( double zValue = 0 ) override;
535 : : bool addMValue( double mValue = 0 ) override;
536 : : bool dropZValue() override;
537 : : bool dropMValue() override;
538 : : void swapXy() override;
539 : : bool convertTo( QgsWkbTypes::Type type ) override;
540 : :
541 : : bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) override;
542 : :
543 : : #ifndef SIP_RUN
544 : :
545 : : void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
546 : : void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) override;
547 : :
548 : : /**
549 : : * Cast the \a geom to a QgsPoint.
550 : : * Should be used by qgsgeometry_cast<QgsPoint *>( geometry ).
551 : : *
552 : : * \note Not available in Python. Objects will be automatically be converted to the appropriate target type.
553 : : * \since QGIS 3.0
554 : : */
555 : 135067 : inline static const QgsPoint *cast( const QgsAbstractGeometry *geom )
556 : : {
557 : 135067 : if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::Point )
558 : 134955 : return static_cast<const QgsPoint *>( geom );
559 : 112 : return nullptr;
560 : 135067 : }
561 : : #endif
562 : :
563 : : QgsPoint *createEmptyWithSameType() const override SIP_FACTORY;
564 : :
565 : : #ifdef SIP_RUN
566 : : SIP_PYOBJECT __repr__();
567 : : % MethodCode
568 : : QString str = QStringLiteral( "<QgsPoint: %1>" ).arg( sipCpp->asWkt() );
569 : : sipRes = PyUnicode_FromString( str.toUtf8().constData() );
570 : : % End
571 : : #endif
572 : :
573 : : protected:
574 : :
575 : : int childCount() const override;
576 : : QgsPoint childPoint( int index ) const override;
577 : :
578 : : private:
579 : : double mX;
580 : : double mY;
581 : : double mZ;
582 : : double mM;
583 : : };
584 : :
585 : : // clazy:excludeall=qstring-allocations
586 : :
587 : : #endif // QGSPOINT_H
|