QGIS API Documentation 3.36.0-Maidenhead (09951dc0acf)
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 <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.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition qgsfeedback.h:44
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.
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