QGIS API Documentation 3.39.0-Master (d85f3c2a281)
Loading...
Searching...
No Matches
qgscurvepolygon.h
Go to the documentation of this file.
1/***************************************************************************
2 qgscurvepolygon.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 QGSCURVEPOLYGON_H
19#define QGSCURVEPOLYGON_H
20
21#include "qgis_core.h"
22#include "qgis_sip.h"
23#include "qgssurface.h"
24#include "qgscurve.h"
25#include <memory>
26
27class QgsPolygon;
28
34class CORE_EXPORT QgsCurvePolygon: public QgsSurface
35{
36 public:
40
41#ifndef SIP_RUN
42 private:
43 bool fuzzyHelper( const QgsAbstractGeometry &other, double epsilon, bool useDistance ) const
44 {
45 const QgsCurvePolygon *otherPolygon = qgsgeometry_cast< const QgsCurvePolygon * >( &other );
46 if ( !otherPolygon )
47 return false;
48
49 //run cheap checks first
50 if ( mWkbType != otherPolygon->mWkbType )
51 return false;
52
53 if ( ( !mExteriorRing && otherPolygon->mExteriorRing ) || ( mExteriorRing && !otherPolygon->mExteriorRing ) )
54 return false;
55
56 if ( mInteriorRings.count() != otherPolygon->mInteriorRings.count() )
57 return false;
58
59 // compare rings
60 if ( mExteriorRing && otherPolygon->mExteriorRing )
61 {
62 if ( useDistance )
63 {
64 if ( !( *mExteriorRing ).fuzzyDistanceEqual( *otherPolygon->mExteriorRing, epsilon ) )
65 return false;
66 }
67 else
68 {
69 if ( !( *mExteriorRing ).fuzzyEqual( *otherPolygon->mExteriorRing, epsilon ) )
70 return false;
71 }
72 }
73
74 for ( int i = 0; i < mInteriorRings.count(); ++i )
75 {
76 if ( ( !mInteriorRings.at( i ) && otherPolygon->mInteriorRings.at( i ) ) ||
77 ( mInteriorRings.at( i ) && !otherPolygon->mInteriorRings.at( i ) ) )
78 return false;
79
80 if ( useDistance )
81 {
82 if ( mInteriorRings.at( i ) && otherPolygon->mInteriorRings.at( i ) &&
83 !( *mInteriorRings.at( i ) ).fuzzyDistanceEqual( *otherPolygon->mInteriorRings.at( i ), epsilon ) )
84 return false;
85 }
86 else
87 {
88 if ( mInteriorRings.at( i ) && otherPolygon->mInteriorRings.at( i ) &&
89 !( *mInteriorRings.at( i ) ).fuzzyEqual( *otherPolygon->mInteriorRings.at( i ), epsilon ) )
90 return false;
91 }
92 }
93
94 return true;
95 }
96#endif
97 public:
98 bool fuzzyEqual( const QgsAbstractGeometry &other, double epsilon = 1e-8 ) const override SIP_HOLDGIL
99 {
100 return fuzzyHelper( other, epsilon, false );
101 }
102 bool fuzzyDistanceEqual( const QgsAbstractGeometry &other, double epsilon = 1e-8 ) const override SIP_HOLDGIL
103 {
104 return fuzzyHelper( other, epsilon, true );
105 }
106 bool operator==( const QgsAbstractGeometry &other ) const override
107 {
108 return fuzzyEqual( other, 1e-8 );
109 }
110
111 bool operator!=( const QgsAbstractGeometry &other ) const override
112 {
113 return !operator==( other );
114 }
115
116 ~QgsCurvePolygon() override;
117
118 QString geometryType() const override SIP_HOLDGIL;
119 int dimension() const override SIP_HOLDGIL;
120 QgsCurvePolygon *clone() const override SIP_FACTORY;
121 void clear() override;
122
123 bool fromWkb( QgsConstWkbPtr &wkb ) override;
124 bool fromWkt( const QString &wkt ) override;
125
126 int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
127 QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
128 QString asWkt( int precision = 17 ) const override;
129 QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
130 QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
131 json asJsonObject( int precision = 17 ) const override SIP_SKIP;
132 QString asKml( int precision = 17 ) const override;
133 void normalize() final SIP_HOLDGIL;
134
139 virtual QgsPolygon *surfaceToPolygon() const SIP_FACTORY;
140
141 //surface interface
142 double area() const override SIP_HOLDGIL;
143 double perimeter() const override SIP_HOLDGIL;
144 QgsAbstractGeometry *boundary() const override SIP_FACTORY;
145 QgsCurvePolygon *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const override SIP_FACTORY;
146 QgsCurvePolygon *simplifyByDistance( double tolerance ) const override SIP_FACTORY;
147 bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;
148 bool boundingBoxIntersects( const QgsBox3D &box3d ) const override SIP_HOLDGIL;
149
155 double roundness() const;
156
157 //curve polygon interface
158
164 int numInteriorRings() const SIP_HOLDGIL
165 {
166 return mInteriorRings.size();
167 }
168
175 {
176 return mExteriorRing.get();
177 }
178
188 {
189 return mExteriorRing.get();
190 }
191
192#ifndef SIP_RUN
193
200 const QgsCurve *interiorRing( int i ) const SIP_HOLDGIL
201 {
202 if ( i < 0 || i >= mInteriorRings.size() )
203 {
204 return nullptr;
205 }
206 return mInteriorRings.at( i );
207 }
208
218 {
219 if ( i < 0 || i >= mInteriorRings.size() )
220 {
221 return nullptr;
222 }
223 return mInteriorRings.at( i );
224 }
225#else
226
235 SIP_PYOBJECT interiorRing( int i ) SIP_HOLDGIL SIP_TYPEHINT( QgsCurve );
236 % MethodCode
237 if ( a0 < 0 || a0 >= sipCpp->numInteriorRings() )
238 {
239 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
240 sipIsErr = 1;
241 }
242 else
243 {
244 return sipConvertFromType( const_cast< QgsCurve * >( sipCpp->interiorRing( a0 ) ), sipType_QgsCurve, NULL );
245 }
246 % End
247#endif
248
255 virtual QgsPolygon *toPolygon( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const SIP_FACTORY;
256
265 virtual void setExteriorRing( QgsCurve *ring SIP_TRANSFER );
266
268 void setInteriorRings( const QVector<QgsCurve *> &rings SIP_TRANSFER );
270 virtual void addInteriorRing( QgsCurve *ring SIP_TRANSFER );
271
272#ifndef SIP_RUN
273
280 bool removeInteriorRing( int ringIndex );
281#else
282
292 bool removeInteriorRing( int i );
293 % MethodCode
294 if ( a0 < 0 || a0 >= sipCpp->numInteriorRings() )
295 {
296 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
297 sipIsErr = 1;
298 }
299 else
300 {
301 return PyBool_FromLong( sipCpp->removeInteriorRing( a0 ) );
302 }
303 % End
304#endif
305
312 void removeInteriorRings( double minimumAllowedArea = -1 );
313
320 void removeInvalidRings();
321
335 void forceRHR();
336
345 void forceClockwise();
346
355 void forceCounterClockwise();
356
357 QPainterPath asQPainterPath() const override;
358 void draw( QPainter &p ) const override;
360 void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 ) override;
361
362 bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) override;
363 bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) override;
364 bool deleteVertex( QgsVertexId position ) override;
365
366 QgsCoordinateSequence coordinateSequence() const override;
367 int nCoordinates() const override;
368 int vertexNumberFromVertexId( QgsVertexId id ) const override;
369 bool isEmpty() const override SIP_HOLDGIL;
370 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;
371
372 bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const override;
373 void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const override;
374 bool hasCurvedSegments() const override;
375
381 QgsAbstractGeometry *segmentize( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override SIP_FACTORY;
382
388 double vertexAngle( QgsVertexId vertex ) const override;
389
390 int vertexCount( int part = 0, int ring = 0 ) const override;
391 int ringCount( int part = 0 ) const override SIP_HOLDGIL;
392 int partCount() const override SIP_HOLDGIL;
393 QgsPoint vertexAt( QgsVertexId id ) const override;
394 double segmentLength( QgsVertexId startVertex ) const override;
395
396 bool addZValue( double zValue = 0 ) override;
397 bool addMValue( double mValue = 0 ) override;
398 bool dropZValue() override;
399 bool dropMValue() override;
400 void swapXy() override;
401
402 QgsCurvePolygon *toCurveType() const override SIP_FACTORY;
403
404 bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) override;
405
406#ifndef SIP_RUN
407 void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
408 void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) override;
409
416 inline static const QgsCurvePolygon *cast( const QgsAbstractGeometry *geom )
417 {
418 if ( !geom )
419 return nullptr;
420
421 const Qgis::WkbType flatType = QgsWkbTypes::flatType( geom->wkbType() );
422 if ( flatType == Qgis::WkbType::CurvePolygon
423 || flatType == Qgis::WkbType::Polygon
424 || flatType == Qgis::WkbType::Triangle )
425 return static_cast<const QgsCurvePolygon *>( geom );
426 return nullptr;
427 }
428#endif
429
431
432#ifdef SIP_RUN
433 SIP_PYOBJECT __repr__();
434 % MethodCode
435 QString wkt = sipCpp->asWkt();
436 if ( wkt.length() > 1000 )
437 wkt = wkt.left( 1000 ) + QStringLiteral( "..." );
438 QString str = QStringLiteral( "<QgsCurvePolygon: %1>" ).arg( wkt );
439 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
440 % End
441#endif
442
443 protected:
444
445 int childCount() const override;
446 QgsAbstractGeometry *childGeometry( int index ) const override;
447 int compareToSameClass( const QgsAbstractGeometry *other ) const final;
448
449 protected:
450
451 std::unique_ptr< QgsCurve > mExteriorRing;
452 QVector<QgsCurve *> mInteriorRings;
453
454 QgsBox3D calculateBoundingBox3D() const override;
455};
456
457// clazy:excludeall=qstring-allocations
458
459#endif // QGSCURVEPOLYGON_H
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:256
@ Polygon
Polygon.
@ Triangle
Triangle.
@ CurvePolygon
CurvePolygon.
TransformDirection
Indicates the direction (forward or inverse) of a transform.
Definition qgis.h:2502
@ Forward
Forward transform (from source to destination)
An abstract base class for classes which transform geometries by transforming input points to output ...
Abstract base class for all geometries.
virtual QgsBox3D calculateBoundingBox3D() const
Calculates the minimal 3D bounding box for the geometry.
virtual void draw(QPainter &p) const =0
Draws the geometry using the specified QPainter.
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 QString geometryType() const =0
Returns a unique string representing the geometry type.
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=(const QgsAbstractGeometry &geom)
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
virtual bool fuzzyEqual(const QgsAbstractGeometry &other, double epsilon=1e-8) const =0
Performs fuzzy comparison between this geometry and other using an epsilon.
virtual QPainterPath asQPainterPath() const =0
Returns the geometry represented as a QPainterPath.
virtual void transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection d=Qgis::TransformDirection::Forward, bool transformZ=false)=0
Transforms the geometry using a coordinate transform.
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...
virtual QgsAbstractGeometry * childGeometry(int index) const
Returns pointer to child geometry (for geometries with child geometries - i.e.
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...
A 3-dimensional box composed of x, y, z coordinates.
Definition qgsbox3d.h:43
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.
Curve polygon geometry type.
const QgsCurve * exteriorRing() const
Returns the curve polygon's exterior ring.
QVector< QgsCurve * > mInteriorRings
bool operator!=(const QgsAbstractGeometry &other) const override
const QgsCurve * interiorRing(int i) const
Retrieves an interior ring from the curve polygon.
QgsCurve * interiorRing(int i)
Retrieves an interior ring from the curve polygon.
static const QgsCurvePolygon * cast(const QgsAbstractGeometry *geom)
Cast the geom to a QgsCurvePolygon.
bool fuzzyEqual(const QgsAbstractGeometry &other, double epsilon=1e-8) const override
Performs fuzzy comparison between this geometry and other using an epsilon.
bool fuzzyDistanceEqual(const QgsAbstractGeometry &other, double epsilon=1e-8) const override
Performs fuzzy distance comparison between this geometry and other using an epsilon.
QgsCurve * exteriorRing()
Returns a non-const pointer to the curve polygon's exterior ring.
bool operator==(const QgsAbstractGeometry &other) const override
std::unique_ptr< QgsCurve > mExteriorRing
Abstract base class for curved geometry type.
Definition qgscurve.h:35
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition qgsfeedback.h:44
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:49
Polygon geometry type.
Definition qgspolygon.h:33
Surface geometry type.
Definition qgssurface.h:34
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
#define str(x)
Definition qgis.cpp:38
#define SIP_TYPEHINT(type)
Definition qgis_sip.h:232
#define SIP_SKIP
Definition qgis_sip.h:126
#define SIP_TRANSFER
Definition qgis_sip.h:36
#define SIP_OUT
Definition qgis_sip.h:58
#define SIP_HOLDGIL
Definition qgis_sip.h:171
#define SIP_FACTORY
Definition qgis_sip.h:76
#define SIP_THROW(name,...)
Definition qgis_sip.h:203
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.
Definition qgsvertexid.h:30