QGIS API Documentation 4.3.0-Master (ca159e4aeaf)
Loading...
Searching...
No Matches
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 "qgis_core.h"
20#include "qgis_sip.h"
21#include "qgsabstractgeometry.h"
22#include "qgsbox3d.h"
23#include "qgsrectangle.h"
24
25#include <QVector>
26
27class QgsPoint;
28
29
36{
37 public:
38 // clang-format off
43 // clang-format on
44
47 ~QgsGeometryCollection() override;
48
49 bool operator==( const QgsAbstractGeometry &other ) const override
50 {
51 return fuzzyEqual( other, 1e-8 );
52 }
53
54 bool operator!=( const QgsAbstractGeometry &other ) const override
55 {
56 return !operator==( other );
57 }
58
59#ifndef SIP_RUN
60 private:
61 bool fuzzyHelper( const QgsAbstractGeometry &other, double epsilon, bool useDistance ) const
62 {
64 if ( !otherCollection )
65 return false;
66
67 if ( mWkbType != otherCollection->mWkbType )
68 return false;
69
70 if ( mGeometries.count() != otherCollection->mGeometries.count() )
71 return false;
72
73 for ( int i = 0; i < mGeometries.count(); ++i )
74 {
75 QgsAbstractGeometry *g1 = mGeometries.at( i );
76 QgsAbstractGeometry *g2 = otherCollection->mGeometries.at( i );
77
78 // Quick check if the geometries are exactly the same
79 if ( g1 != g2 )
80 {
81 if ( !g1 || !g2 )
82 return false;
83
84 // Slower check, compare the contents of the geometries
85 if ( useDistance )
86 {
87 if ( !( *g1 ).fuzzyDistanceEqual( *g2, epsilon ) )
88 {
89 return false;
90 }
91 }
92 else
93 {
94 if ( !( *g1 ).fuzzyEqual( *g2, epsilon ) )
95 {
96 return false;;
97 }
98 }
99 }
100 }
101 return true;
102 }
103#endif
104 public:
105 bool fuzzyEqual( const QgsAbstractGeometry &other, double epsilon = 1e-8 ) const override SIP_HOLDGIL
106 {
107 return fuzzyHelper( other, epsilon, false );
108 }
109 bool fuzzyDistanceEqual( const QgsAbstractGeometry &other, double epsilon = 1e-8 ) const override SIP_HOLDGIL
110 {
111 return fuzzyHelper( other, epsilon, true );
112 }
113
114 QgsGeometryCollection *clone() const override SIP_FACTORY;
115
120 {
121 return mGeometries.size();
122 }
123
124#ifdef SIP_RUN
125// clang-format off
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// clang-format on
141#endif
142
143
150 {
151 return mGeometries.value( n );
152 }
153
154#ifndef SIP_RUN
155
160 QgsAbstractGeometry *geometryN( int n ) SIP_HOLDGIL;
161#else
162// clang-format off
163
169 SIP_PYOBJECT geometryN( int n ) SIP_TYPEHINT( QgsAbstractGeometry );
170 % MethodCode
171 if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
172 {
173 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
174 sipIsErr = 1;
175 }
176 else
177 {
178 return sipConvertFromType( sipCpp->geometryN( a0 ), sipType_QgsAbstractGeometry, NULL );
179 }
180 % End
181// clang-format on
182#endif
183
184
185 //methods inherited from QgsAbstractGeometry
186 bool isEmpty() const override SIP_HOLDGIL;
187 int dimension() const override SIP_HOLDGIL;
188 QString geometryType() const override SIP_HOLDGIL;
189 void clear() override;
190 QgsGeometryCollection *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const override SIP_FACTORY;
191 bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;
192 QgsAbstractGeometry *boundary() const override SIP_FACTORY;
193 void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const override;
194 int vertexNumberFromVertexId( QgsVertexId id ) const override;
195
196 using QgsAbstractGeometry::boundingBoxIntersects;
197 bool boundingBoxIntersects( const QgsBox3D &box3d ) const override SIP_HOLDGIL;
198
207 void reserve( int size ) SIP_HOLDGIL;
208
210 virtual bool addGeometry( QgsAbstractGeometry *g SIP_TRANSFER );
211
219 virtual bool addGeometries( const QVector< QgsAbstractGeometry * > &geometries SIP_TRANSFER );
220
226 virtual bool insertGeometry( QgsAbstractGeometry *g SIP_TRANSFER, int index );
227
228#ifndef SIP_RUN
229
235 virtual bool removeGeometry( int nr );
236#else
237// clang-format off
238
245 virtual bool removeGeometry( int nr );
246 % MethodCode
247 const int count = sipCpp->numGeometries();
248 if ( a0 < 0 || a0 >= count )
249 {
250 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
251 sipIsErr = 1;
252 }
253 else
254 {
255 return PyBool_FromLong( sipCpp->removeGeometry( a0 ) );
256 }
257 % End
258// clang-format on
259#endif
260
267 QVector< QgsAbstractGeometry * > takeGeometries() SIP_TRANSFER;
268
269 void normalize() final SIP_HOLDGIL;
270 void transform( const QgsCoordinateTransform &ct, Qgis::TransformDirection d = Qgis::TransformDirection::Forward, bool transformZ = false ) override SIP_THROW( QgsCsException );
271 void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 ) override;
272
273 void draw( QPainter &p ) const override;
274 QPainterPath asQPainterPath() const override;
275
276 bool fromWkb( QgsConstWkbPtr &wkb ) override;
277 bool fromWkt( const QString &wkt ) override;
278
279 int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
280 QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
281 QString asWkt( int precision = 17 ) const override;
282 QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
283 QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
284 json asJsonObject( int precision = 17, Qgis::GeoJsonProfile profile = Qgis::GeoJsonProfile::Legacy ) const override SIP_SKIP;
285 QString asKml( int precision = 17 ) const override;
286
287 QgsBox3D boundingBox3D() const override;
288
289 QgsCoordinateSequence coordinateSequence() const override;
290 int nCoordinates() const override;
291
292 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;
293 bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const override;
294
295 //low-level editing
296 bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) override;
297 bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) override;
298 bool deleteVertices( const QSet<QgsVertexId> &positions ) override;
299 bool hasVertex( QgsVertexId position ) const override;
300
301 double length() const override SIP_HOLDGIL;
302 double area() const override SIP_HOLDGIL;
303 double area3D() const override SIP_HOLDGIL;
304 double perimeter() const override SIP_HOLDGIL;
305
306 bool hasCurvedSegments() const override SIP_HOLDGIL;
307
313 QgsAbstractGeometry *segmentize( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override SIP_FACTORY;
314
315 double vertexAngle( QgsVertexId vertex ) const override;
316 double segmentLength( QgsVertexId startVertex ) const override;
317 int vertexCount( int part = 0, int ring = 0 ) const override;
318 int ringCount( int part = 0 ) const override;
319 int partCount() const override;
320 QgsPoint vertexAt( QgsVertexId id ) const override;
321 bool isValid( QString &error SIP_OUT, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const override;
322
323 bool addZValue( double zValue = 0 ) override;
324 bool addMValue( double mValue = 0 ) override;
325 bool dropZValue() override;
326 bool dropMValue() override;
327 void swapXy() override;
328 QgsGeometryCollection *toCurveType() const override SIP_FACTORY;
329 const QgsAbstractGeometry *simplifiedTypeRef() const override SIP_HOLDGIL;
330 QgsGeometryCollection *simplifyByDistance( double tolerance ) const override SIP_FACTORY;
331
332 bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) override;
333
334#ifndef SIP_RUN
335 void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
336 void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) override;
337
346 inline static const QgsGeometryCollection *cast( const QgsAbstractGeometry *geom )
347 {
348 if ( geom && QgsWkbTypes::isMultiType( geom->wkbType() ) )
349 return static_cast<const QgsGeometryCollection *>( geom );
350 return nullptr;
351 }
352
362 {
363 if ( geom && QgsWkbTypes::isMultiType( geom->wkbType() ) )
364 return static_cast<QgsGeometryCollection *>( geom );
365 return nullptr;
366 }
367#endif
368
369
370#ifdef SIP_RUN
371// clang-format off
372
383 SIP_PYOBJECT __getitem__( int index ) SIP_TYPEHINT( QgsAbstractGeometry );
384 % MethodCode
385 const int count = sipCpp->numGeometries();
386 if ( a0 < -count || a0 >= count )
387 {
388 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
389 sipIsErr = 1;
390 }
391 else if ( a0 >= 0 )
392 {
393 return sipConvertFromType( sipCpp->geometryN( a0 ), sipType_QgsAbstractGeometry, NULL );
394 }
395 else
396 {
397 return sipConvertFromType( sipCpp->geometryN( count + a0 ), sipType_QgsAbstractGeometry, NULL );
398 }
399 % End
400
411 void __delitem__( int index );
412 % MethodCode
413 const int count = sipCpp->numGeometries();
414 if ( a0 >= 0 && a0 < count )
415 sipCpp->removeGeometry( a0 );
416 else if ( a0 < 0 && a0 >= -count )
417 sipCpp->removeGeometry( count + a0 );
418 else
419 {
420 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
421 sipIsErr = 1;
422 }
423 % End
424
430 SIP_PYOBJECT __iter__() SIP_TYPEHINT( QgsGeometryPartIterator );
431 % MethodCode
432 sipRes = sipConvertFromNewType( new QgsGeometryPartIterator( sipCpp ), sipType_QgsGeometryPartIterator, Py_None );
433 % End
434// clang-format on
435#endif
436
450 QgsGeometryCollection *extractPartsByType( Qgis::WkbType type, bool useFlatType = true ) const SIP_FACTORY;
451
452 QgsGeometryCollection *createEmptyWithSameType() const override SIP_FACTORY;
453
454 protected:
455 int childCount() const override;
456 QgsAbstractGeometry *childGeometry( int index ) const override;
457 int compareToSameClass( const QgsAbstractGeometry *other ) const final;
458
459 protected:
461
465 virtual bool wktOmitChildType() const;
466
470 SIP_SKIP bool fromCollectionWkt( const QString &wkt, const QVector<Qgis::WkbType> &subtypes, const QString &defaultChildWkbType = QString() );
471
472 QgsBox3D calculateBoundingBox3D() const override;
473 void clearCache() const override;
474
475 private:
476
477 mutable QgsBox3D mBoundingBox;
478 mutable bool mHasCachedValidity = false;
479 mutable QString mValidityFailureReason;
480};
481
482// clazy:excludeall=qstring-allocations
483
484#endif // QGSGEOMETRYCOLLECTION_H
Provides global constants and enumerations for use throughout the application.
Definition qgis.h:62
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:314
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 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
QgsAbstractGeometry()=default
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:45
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
bool fromCollectionWkt(const QString &wkt, const QVector< Qgis::WkbType > &subtypes, const QString &defaultChildWkbType=QString())
Reads a collection from a WKT string.
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
QgsGeometryCollection()
Constructor for an empty geometry collection.
static QgsGeometryCollection * cast(QgsAbstractGeometry *geom)
Cast the geom to a QgsGeometryCollection.
static const QgsGeometryCollection * cast(const QgsAbstractGeometry *geom)
Cast the geom to a QgsGeometryCollection.
bool operator==(const QgsAbstractGeometry &other) const override
QgsBox3D calculateBoundingBox3D() const override
Calculates the minimal 3D bounding box for the geometry.
virtual bool wktOmitChildType() const
Returns whether child type names are omitted from Wkt representations of the collection.
bool fuzzyEqual(const QgsAbstractGeometry &other, double epsilon=1e-8) const override
Performs fuzzy comparison between this geometry and other using an epsilon.
int numGeometries() const
Returns the number of geometries within the collection.
bool operator!=(const QgsAbstractGeometry &other) const override
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:53
static Q_INVOKABLE bool isMultiType(Qgis::WkbType type)
Returns true if the WKB type is a multi type.
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:242
#define SIP_SKIP
Definition qgis_sip.h:138
#define SIP_TRANSFER
Definition qgis_sip.h:35
#define SIP_OUT
Definition qgis_sip.h:57
#define SIP_HOLDGIL
Definition qgis_sip.h:183
#define SIP_FACTORY
Definition qgis_sip.h:83
#define SIP_THROW(name,...)
Definition qgis_sip.h:215
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsRingSequence > QgsCoordinateSequence
double closestSegment(const QgsPolylineXY &pl, const QgsPointXY &pt, int &vertexAfter, double epsilon)
Definition qgstracer.cpp:72