QGIS API Documentation 3.99.0-Master (a8882ad4560)
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
39
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
129 int __len__() const;
130 % MethodCode
131 sipRes = sipCpp->numGeometries();
132 % End
133
135 int __bool__() const;
136 % MethodCode
137 sipRes = true;
138 % End
139#endif
140
141
148 {
149 return mGeometries.value( n );
150 }
151
152#ifndef SIP_RUN
153
158 QgsAbstractGeometry *geometryN( int n ) SIP_HOLDGIL;
159#else
160
166 SIP_PYOBJECT geometryN( int n ) SIP_TYPEHINT( QgsAbstractGeometry );
167 % MethodCode
168 if ( a0 < 0 || a0 >= sipCpp->numGeometries() )
169 {
170 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
171 sipIsErr = 1;
172 }
173 else
174 {
175 return sipConvertFromType( sipCpp->geometryN( a0 ), sipType_QgsAbstractGeometry, NULL );
176 }
177 % End
178#endif
179
180
181 //methods inherited from QgsAbstractGeometry
182 bool isEmpty() const override SIP_HOLDGIL;
183 int dimension() const override SIP_HOLDGIL;
184 QString geometryType() const override SIP_HOLDGIL;
185 void clear() override;
186 QgsGeometryCollection *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const override SIP_FACTORY;
187 bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;
188 QgsAbstractGeometry *boundary() const override SIP_FACTORY;
189 void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const override;
190 int vertexNumberFromVertexId( QgsVertexId id ) const override;
191
192 using QgsAbstractGeometry::boundingBoxIntersects;
193 bool boundingBoxIntersects( const QgsBox3D &box3d ) const override SIP_HOLDGIL;
194
203 void reserve( int size ) SIP_HOLDGIL;
204
206 virtual bool addGeometry( QgsAbstractGeometry *g SIP_TRANSFER );
207
215 virtual bool addGeometries( const QVector< QgsAbstractGeometry * > &geometries SIP_TRANSFER );
216
222 virtual bool insertGeometry( QgsAbstractGeometry *g SIP_TRANSFER, int index );
223
224#ifndef SIP_RUN
225
231 virtual bool removeGeometry( int nr );
232#else
233
240 virtual bool removeGeometry( int nr );
241 % MethodCode
242 const int count = sipCpp->numGeometries();
243 if ( a0 < 0 || a0 >= count )
244 {
245 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
246 sipIsErr = 1;
247 }
248 else
249 {
250 return PyBool_FromLong( sipCpp->removeGeometry( a0 ) );
251 }
252 % End
253#endif
254
261 QVector< QgsAbstractGeometry * > takeGeometries() SIP_TRANSFER;
262
263 void normalize() final SIP_HOLDGIL;
264 void transform( const QgsCoordinateTransform &ct, Qgis::TransformDirection d = Qgis::TransformDirection::Forward, bool transformZ = false ) override SIP_THROW( QgsCsException );
265 void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 ) override;
266
267 void draw( QPainter &p ) const override;
268 QPainterPath asQPainterPath() const override;
269
270 bool fromWkb( QgsConstWkbPtr &wkb ) override;
271 bool fromWkt( const QString &wkt ) override;
272
273 int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
274 QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
275 QString asWkt( int precision = 17 ) const override;
276 QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
277 QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
278 json asJsonObject( int precision = 17 ) const override SIP_SKIP;
279 QString asKml( int precision = 17 ) const override;
280
281 QgsBox3D boundingBox3D() const override;
282
283 QgsCoordinateSequence coordinateSequence() const override;
284 int nCoordinates() const override;
285
286 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;
287 bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const override;
288
289 //low-level editing
290 bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) override;
291 bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) override;
292 bool deleteVertex( QgsVertexId position ) override;
293
294 double length() const override SIP_HOLDGIL;
295 double area() const override SIP_HOLDGIL;
296 double area3D() const override SIP_HOLDGIL;
297 double perimeter() const override SIP_HOLDGIL;
298
299 bool hasCurvedSegments() const override SIP_HOLDGIL;
300
306 QgsAbstractGeometry *segmentize( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override SIP_FACTORY;
307
308 double vertexAngle( QgsVertexId vertex ) const override;
309 double segmentLength( QgsVertexId startVertex ) const override;
310 int vertexCount( int part = 0, int ring = 0 ) const override;
311 int ringCount( int part = 0 ) const override;
312 int partCount() const override;
313 QgsPoint vertexAt( QgsVertexId id ) const override;
314 bool isValid( QString &error SIP_OUT, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const override;
315
316 bool addZValue( double zValue = 0 ) override;
317 bool addMValue( double mValue = 0 ) override;
318 bool dropZValue() override;
319 bool dropMValue() override;
320 void swapXy() override;
321 QgsGeometryCollection *toCurveType() const override SIP_FACTORY;
322 const QgsAbstractGeometry *simplifiedTypeRef() const override SIP_HOLDGIL;
323 QgsGeometryCollection *simplifyByDistance( double tolerance ) const override SIP_FACTORY;
324
325 bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) override;
326
327#ifndef SIP_RUN
328 void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
329 void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) override;
330
339 inline static const QgsGeometryCollection *cast( const QgsAbstractGeometry *geom )
340 {
341 if ( geom && QgsWkbTypes::isMultiType( geom->wkbType() ) )
342 return static_cast<const QgsGeometryCollection *>( geom );
343 return nullptr;
344 }
345
355 {
356 if ( geom && QgsWkbTypes::isMultiType( geom->wkbType() ) )
357 return static_cast<QgsGeometryCollection *>( geom );
358 return nullptr;
359 }
360#endif
361
362
363#ifdef SIP_RUN
364
375 SIP_PYOBJECT __getitem__( int index ) SIP_TYPEHINT( QgsAbstractGeometry );
376 % MethodCode
377 const int count = sipCpp->numGeometries();
378 if ( a0 < -count || a0 >= count )
379 {
380 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
381 sipIsErr = 1;
382 }
383 else if ( a0 >= 0 )
384 {
385 return sipConvertFromType( sipCpp->geometryN( a0 ), sipType_QgsAbstractGeometry, NULL );
386 }
387 else
388 {
389 return sipConvertFromType( sipCpp->geometryN( count + a0 ), sipType_QgsAbstractGeometry, NULL );
390 }
391 % End
392
403 void __delitem__( int index );
404 % MethodCode
405 const int count = sipCpp->numGeometries();
406 if ( a0 >= 0 && a0 < count )
407 sipCpp->removeGeometry( a0 );
408 else if ( a0 < 0 && a0 >= -count )
409 sipCpp->removeGeometry( count + a0 );
410 else
411 {
412 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
413 sipIsErr = 1;
414 }
415 % End
416
422 SIP_PYOBJECT __iter__() SIP_TYPEHINT( QgsGeometryPartIterator );
423 % MethodCode
424 sipRes = sipConvertFromNewType( new QgsGeometryPartIterator( sipCpp ), sipType_QgsGeometryPartIterator, Py_None );
425 % End
426#endif
427
441 QgsGeometryCollection *extractPartsByType( Qgis::WkbType type, bool useFlatType = true ) const SIP_FACTORY;
442
443 QgsGeometryCollection *createEmptyWithSameType() const override SIP_FACTORY;
444
445 protected:
446 int childCount() const override;
447 QgsAbstractGeometry *childGeometry( int index ) const override;
448 int compareToSameClass( const QgsAbstractGeometry *other ) const final;
449
450 protected:
452
456 virtual bool wktOmitChildType() const;
457
461 SIP_SKIP bool fromCollectionWkt( const QString &wkt, const QVector<Qgis::WkbType> &subtypes, const QString &defaultChildWkbType = QString() );
462
463 QgsBox3D calculateBoundingBox3D() const override;
464 void clearCache() const override;
465
466 private:
467
468 mutable QgsBox3D mBoundingBox;
469 mutable bool mHasCachedValidity = false;
470 mutable QString mValidityFailureReason;
471};
472
473// clazy:excludeall=qstring-allocations
474
475#endif // QGSGEOMETRYCOLLECTION_H
Provides global constants and enumerations for use throughout the application.
Definition qgis.h:59
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:280
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:42
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:49
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:240
#define SIP_SKIP
Definition qgis_sip.h:134
#define SIP_TRANSFER
Definition qgis_sip.h:36
#define SIP_OUT
Definition qgis_sip.h:58
#define SIP_HOLDGIL
Definition qgis_sip.h:179
#define SIP_FACTORY
Definition qgis_sip.h:84
#define SIP_THROW(name,...)
Definition qgis_sip.h:211
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsRingSequence > QgsCoordinateSequence
double closestSegment(const QgsPolylineXY &pl, const QgsPointXY &pt, int &vertexAfter, double epsilon)
Definition qgstracer.cpp:72