QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsgeometrycollection.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsgeometrycollection.h
3 -------------------------------------------------------------------
4Date : 28 Oct 2014
5Copyright : (C) 2014 by Marco Hugentobler
6email : marco.hugentobler at sourcepole dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#ifndef QGSGEOMETRYCOLLECTION_H
17#define QGSGEOMETRYCOLLECTION_H
18
19#include <QVector>
20
21
22#include "qgis_core.h"
23#include "qgis_sip.h"
24#include "qgsabstractgeometry.h"
25#include "qgsrectangle.h"
26#include "qgsbox3d.h"
27
28class QgsPoint;
29
30
37{
38 public:
39
40
45
48 ~QgsGeometryCollection() override;
49
50 bool operator==( const QgsAbstractGeometry &other ) const override
51 {
52 return fuzzyEqual( other, 1e-8 );
53 }
54
55 bool operator!=( const QgsAbstractGeometry &other ) const override
56 {
57 return !operator==( other );
58 }
59
60#ifndef SIP_RUN
61 private:
62 bool fuzzyHelper( const QgsAbstractGeometry &other, double epsilon, bool useDistance ) const
63 {
64 const QgsGeometryCollection *otherCollection = qgsgeometry_cast< const QgsGeometryCollection * >( &other );
65 if ( !otherCollection )
66 return false;
67
68 if ( mWkbType != otherCollection->mWkbType )
69 return false;
70
71 if ( mGeometries.count() != otherCollection->mGeometries.count() )
72 return false;
73
74 for ( int i = 0; i < mGeometries.count(); ++i )
75 {
76 QgsAbstractGeometry *g1 = mGeometries.at( i );
77 QgsAbstractGeometry *g2 = otherCollection->mGeometries.at( i );
78
79 // Quick check if the geometries are exactly the same
80 if ( g1 != g2 )
81 {
82 if ( !g1 || !g2 )
83 return false;
84
85 // Slower check, compare the contents of the geometries
86 if ( useDistance )
87 {
88 if ( !( *g1 ).fuzzyDistanceEqual( *g2, epsilon ) )
89 {
90 return false;
91 }
92 }
93 else
94 {
95 if ( !( *g1 ).fuzzyEqual( *g2, epsilon ) )
96 {
97 return false;;
98 }
99 }
100 }
101 }
102 return true;
103 }
104#endif
105 public:
106 bool fuzzyEqual( const QgsAbstractGeometry &other, double epsilon = 1e-8 ) const override SIP_HOLDGIL
107 {
108 return fuzzyHelper( other, epsilon, false );
109 }
110 bool fuzzyDistanceEqual( const QgsAbstractGeometry &other, double epsilon = 1e-8 ) const override SIP_HOLDGIL
111 {
112 return fuzzyHelper( other, epsilon, true );
113 }
114
115 QgsGeometryCollection *clone() const override SIP_FACTORY;
116
120 int numGeometries() const SIP_HOLDGIL
121 {
122 return mGeometries.size();
123 }
124
125#ifdef SIP_RUN
126
130 int __len__() const;
131 % MethodCode
132 sipRes = sipCpp->numGeometries();
133 % End
134
136 int __bool__() const;
137 % MethodCode
138 sipRes = true;
139 % End
140#endif
141
142
149 {
150 return mGeometries.value( n );
151 }
152
153#ifndef SIP_RUN
154
159 QgsAbstractGeometry *geometryN( int n ) SIP_HOLDGIL;
160#else
161
167 SIP_PYOBJECT geometryN( int n ) SIP_TYPEHINT( QgsAbstractGeometry );
168 % MethodCode
169 if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
170 {
171 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
172 sipIsErr = 1;
173 }
174 else
175 {
176 return sipConvertFromType( sipCpp->geometryN( a0 ), sipType_QgsAbstractGeometry, NULL );
177 }
178 % End
179#endif
180
181
182 //methods inherited from QgsAbstractGeometry
183 bool isEmpty() const override SIP_HOLDGIL;
184 int dimension() const override SIP_HOLDGIL;
185 QString geometryType() const override SIP_HOLDGIL;
186 void clear() override;
187 QgsGeometryCollection *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY;
188 bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;
189 QgsAbstractGeometry *boundary() const override SIP_FACTORY;
190 void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const override;
191 int vertexNumberFromVertexId( QgsVertexId id ) const override;
192 bool boundingBoxIntersects( const QgsBox3D &box3d ) const override SIP_HOLDGIL;
193
202 void reserve( int size ) SIP_HOLDGIL;
203
205 virtual bool addGeometry( QgsAbstractGeometry *g SIP_TRANSFER );
206
212 virtual bool insertGeometry( QgsAbstractGeometry *g SIP_TRANSFER, int index );
213
214#ifndef SIP_RUN
215
221 virtual bool removeGeometry( int nr );
222#else
223
230 virtual bool removeGeometry( int nr );
231 % MethodCode
232 const int count = sipCpp->numGeometries();
233 if ( a0 < 0 || a0 >= count )
234 {
235 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
236 sipIsErr = 1;
237 }
238 else
239 {
240 return PyBool_FromLong( sipCpp->removeGeometry( a0 ) );
241 }
242 % End
243#endif
244
245 void normalize() final SIP_HOLDGIL;
246 void transform( const QgsCoordinateTransform &ct, Qgis::TransformDirection d = Qgis::TransformDirection::Forward, bool transformZ = false ) override SIP_THROW( QgsCsException );
247 void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 ) override;
248
249 void draw( QPainter &p ) const override;
250 QPainterPath asQPainterPath() const override;
251
252 bool fromWkb( QgsConstWkbPtr &wkb ) override;
253 bool fromWkt( const QString &wkt ) override;
254
255 int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
256 QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
257 QString asWkt( int precision = 17 ) const override;
258 QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
259 QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
260 json asJsonObject( int precision = 17 ) const override SIP_SKIP;
261 QString asKml( int precision = 17 ) const override;
262
263 QgsBox3D boundingBox3D() const override;
264
265 QgsCoordinateSequence coordinateSequence() const override;
266 int nCoordinates() const override;
267
268 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;
269 bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const override;
270
271 //low-level editing
272 bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) override;
273 bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) override;
274 bool deleteVertex( QgsVertexId position ) override;
275
276 double length() const override SIP_HOLDGIL;
277 double area() const override SIP_HOLDGIL;
278 double perimeter() const override SIP_HOLDGIL;
279
280 bool hasCurvedSegments() const override SIP_HOLDGIL;
281
287 QgsAbstractGeometry *segmentize( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override SIP_FACTORY;
288
289 double vertexAngle( QgsVertexId vertex ) const override;
290 double segmentLength( QgsVertexId startVertex ) const override;
291 int vertexCount( int part = 0, int ring = 0 ) const override;
292 int ringCount( int part = 0 ) const override;
293 int partCount() const override;
294 QgsPoint vertexAt( QgsVertexId id ) const override;
295 bool isValid( QString &error SIP_OUT, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const override;
296
297 bool addZValue( double zValue = 0 ) override;
298 bool addMValue( double mValue = 0 ) override;
299 bool dropZValue() override;
300 bool dropMValue() override;
301 void swapXy() override;
302 QgsGeometryCollection *toCurveType() const override SIP_FACTORY;
303 const QgsAbstractGeometry *simplifiedTypeRef() const override SIP_HOLDGIL;
304
305 bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) override;
306
307#ifndef SIP_RUN
308 void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
309 void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) override;
310
317 inline static const QgsGeometryCollection *cast( const QgsAbstractGeometry *geom )
318 {
319 if ( geom && QgsWkbTypes::isMultiType( geom->wkbType() ) )
320 return static_cast<const QgsGeometryCollection *>( geom );
321 return nullptr;
322 }
323#endif
324
325
326#ifdef SIP_RUN
327
338 SIP_PYOBJECT __getitem__( int index ) SIP_TYPEHINT( QgsAbstractGeometry );
339 % MethodCode
340 const int count = sipCpp->numGeometries();
341 if ( a0 < -count || a0 >= count )
342 {
343 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
344 sipIsErr = 1;
345 }
346 else if ( a0 >= 0 )
347 {
348 return sipConvertFromType( sipCpp->geometryN( a0 ), sipType_QgsAbstractGeometry, NULL );
349 }
350 else
351 {
352 return sipConvertFromType( sipCpp->geometryN( count + a0 ), sipType_QgsAbstractGeometry, NULL );
353 }
354 % End
355
366 void __delitem__( int index );
367 % MethodCode
368 const int count = sipCpp->numGeometries();
369 if ( a0 >= 0 && a0 < count )
370 sipCpp->removeGeometry( a0 );
371 else if ( a0 < 0 && a0 >= -count )
372 sipCpp->removeGeometry( count + a0 );
373 else
374 {
375 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
376 sipIsErr = 1;
377 }
378 % End
379
385 SIP_PYOBJECT __iter__() SIP_TYPEHINT( QgsGeometryPartIterator );
386 % MethodCode
387 sipRes = sipConvertFromNewType( new QgsGeometryPartIterator( sipCpp ), sipType_QgsGeometryPartIterator, Py_None );
388 % End
389#endif
390
404 QgsGeometryCollection *extractPartsByType( Qgis::WkbType type, bool useFlatType = true ) const SIP_FACTORY;
405
406 QgsGeometryCollection *createEmptyWithSameType() const override SIP_FACTORY;
407
408 protected:
409 int childCount() const override;
410 QgsAbstractGeometry *childGeometry( int index ) const override;
411 int compareToSameClass( const QgsAbstractGeometry *other ) const final;
412
413 protected:
414 QVector< QgsAbstractGeometry * > mGeometries;
415
419 virtual bool wktOmitChildType() const;
420
424 bool fromCollectionWkt( const QString &wkt, const QVector<QgsAbstractGeometry *> &subtypes, const QString &defaultChildWkbType = QString() );
425
426 QgsBox3D calculateBoundingBox3D() const override;
427 void clearCache() const override;
428
429 private:
430
431 mutable QgsBox3D mBoundingBox;
432 mutable bool mHasCachedValidity = false;
433 mutable QString mValidityFailureReason;
434};
435
436// clazy:excludeall=qstring-allocations
437
438#endif // QGSGEOMETRYCOLLECTION_H
The Qgis class provides global constants for use throughout the application.
Definition: qgis.h:54
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition: qgis.h:182
An abstract base class for classes which transform geometries by transforming input points to output ...
Abstract base class for all geometries.
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.
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 bool isEmpty() const
Returns true if the geometry is empty.
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...
virtual bool operator==(const QgsAbstractGeometry &other) const =0
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
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.
Definition: qgsexception.h:67
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:44
Geometry collection.
bool fuzzyDistanceEqual(const QgsAbstractGeometry &other, double epsilon=1e-8) const override
Performs fuzzy distance comparison between this geometry and other using an epsilon.
QVector< QgsAbstractGeometry * > mGeometries
static const QgsGeometryCollection * cast(const QgsAbstractGeometry *geom)
Cast the geom to a QgsGeometryCollection.
bool operator==(const QgsAbstractGeometry &other) const override
bool fuzzyEqual(const QgsAbstractGeometry &other, double epsilon=1e-8) const override
Performs fuzzy comparison between this geometry and other using an epsilon.
bool operator!=(const QgsAbstractGeometry &other) const override
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
Java-style iterator for traversal of parts of a geometry.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
static bool isMultiType(Qgis::WkbType type)
Returns true if the WKB type is a multi type.
Definition: qgswkbtypes.h:758
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:222
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
#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