QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
qgspolyhedralsurface.h
Go to the documentation of this file.
1/***************************************************************************
2 qgspolyhedralsurface.h
3 -------------------
4 begin : August 2024
5 copyright : (C) 2024 by Jean Felder
6 email : jean dot felder at oslandia dot com
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 QGSPOLYHEDRALSURFACE_H
19#define QGSPOLYHEDRALSURFACE_H
20
21#include "qgis_core.h"
22#include "qgis_sip.h"
23#include "qgsmultipolygon.h"
24#include "qgspolygon.h"
25#include "qgssurface.h"
26
36class CORE_EXPORT QgsPolyhedralSurface: public QgsSurface
37{
38 public:
41
42
46 QgsPolyhedralSurface( const QgsMultiPolygon *multiPolygon );
47
49
50#ifndef SIP_RUN
51 private:
52 bool fuzzyHelper( const QgsAbstractGeometry &other, double epsilon, bool useDistance ) const
53 {
55 if ( !otherPolygon )
56 return false;
57
58 //run cheap checks first
59 if ( mWkbType != otherPolygon->mWkbType )
60 return false;
61
62 if ( mPatches.count() != otherPolygon->mPatches.count() )
63 return false;
64
65 for ( int i = 0; i < mPatches.count(); ++i )
66 {
67 if ( ( !mPatches.at( i ) && otherPolygon->mPatches.at( i ) ) ||
68 ( mPatches.at( i ) && !otherPolygon->mPatches.at( i ) ) )
69 return false;
70
71 if ( useDistance )
72 {
73 if ( mPatches.at( i ) && otherPolygon->mPatches.at( i ) &&
74 !( *mPatches.at( i ) ).fuzzyDistanceEqual( *otherPolygon->mPatches.at( i ), epsilon ) )
75 return false;
76 }
77 else
78 {
79 if ( mPatches.at( i ) && otherPolygon->mPatches.at( i ) &&
80 !( *mPatches.at( i ) ).fuzzyEqual( *otherPolygon->mPatches.at( i ), epsilon ) )
81 return false;
82 }
83 }
84
85 return true;
86 }
87#endif
88
89 public:
90 bool fuzzyEqual( const QgsAbstractGeometry &other, double epsilon = 1e-8 ) const override SIP_HOLDGIL
91 {
92 return fuzzyHelper( other, epsilon, false );
93 }
94 bool fuzzyDistanceEqual( const QgsAbstractGeometry &other, double epsilon = 1e-8 ) const override SIP_HOLDGIL
95 {
96 return fuzzyHelper( other, epsilon, true );
97 }
98
99 bool operator==( const QgsAbstractGeometry &other ) const override
100 {
101 return fuzzyEqual( other, 1e-8 );
102 }
103
104 bool operator!=( const QgsAbstractGeometry &other ) const override
105 {
106 return !operator==( other );
107 }
108
109 ~QgsPolyhedralSurface() override;
110
111 QString geometryType() const override SIP_HOLDGIL;
112 int dimension() const final SIP_HOLDGIL;
113 QgsPolyhedralSurface *clone() const override SIP_FACTORY;
114 void clear() override;
115
116 bool fromWkb( QgsConstWkbPtr &wkb ) override;
117 bool fromWkt( const QString &wkt ) override;
118
119 bool isValid( QString &error SIP_OUT, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const override;
120
121 int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
122 QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
123 QString asWkt( int precision = 17 ) const override;
124 QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
125 QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
126 json asJsonObject( int precision = 17 ) const override SIP_SKIP;
127 QString asKml( int precision = 17 ) const override;
128 void normalize() override SIP_HOLDGIL;
129
130 //surface interface
131 double area() const override SIP_HOLDGIL;
132 double perimeter() const override SIP_HOLDGIL;
133 QgsAbstractGeometry *boundary() const override SIP_FACTORY;
134 QgsPolyhedralSurface *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const override SIP_FACTORY;
135 QgsPolyhedralSurface *simplifyByDistance( double tolerance ) const override SIP_FACTORY;
136 bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;
137 bool boundingBoxIntersects( const QgsBox3D &box3d ) const override SIP_HOLDGIL;
138
145 {
146 return mPatches.size();
147 }
148
149#ifndef SIP_RUN
150
156 const QgsPolygon *patchN( int i ) const
157 {
158 if ( i < 0 || i >= mPatches.size() )
159 {
160 return nullptr;
161 }
162 return mPatches.at( i );
163 }
164
171 {
172 if ( i < 0 || i >= mPatches.size() )
173 {
174 return nullptr;
175 }
176 return mPatches.at( i );
177 }
178#else
179
187 SIP_PYOBJECT patchN( int i ) SIP_HOLDGIL SIP_TYPEHINT( QgsPolygon );
188 % MethodCode
189 if ( a0 < 0 || a0 >= sipCpp->numPatches() )
190 {
191 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
192 sipIsErr = 1;
193 }
194 else
195 {
196 return sipConvertFromType( const_cast< QgsPolygon * >( sipCpp->patchN( a0 ) ), sipType_QgsPolygon, NULL );
197 }
198 % End
199#endif
200
204 virtual void setPatches( const QVector<QgsPolygon *> &patches SIP_TRANSFER );
205
209 virtual void addPatch( QgsPolygon *patch SIP_TRANSFER );
210
211#ifndef SIP_RUN
212
219 bool removePatch( int patchIndex );
220#else
221
229 bool removePatch( int ringIndex );
230 % MethodCode
231 if ( a0 < 0 || a0 >= sipCpp->numPatches() )
232 {
233 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
234 sipIsErr = 1;
235 }
236 else
237 {
238 return PyBool_FromLong( sipCpp->removePatch( a0 ) );
239 }
240 % End
241#endif
242
243 QPainterPath asQPainterPath() const override;
244 void draw( QPainter &p ) const override;
245 void transform( const QgsCoordinateTransform &ct, Qgis::TransformDirection d = Qgis::TransformDirection::Forward, bool transformZ = false ) override SIP_THROW( QgsCsException );
246 void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 ) override;
247
248 bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) override;
249 bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) override;
250 bool deleteVertex( QgsVertexId position ) override;
251
252 QgsCoordinateSequence coordinateSequence() const override;
253 int nCoordinates() const override;
254 int vertexNumberFromVertexId( QgsVertexId id ) const override;
255 bool isEmpty() const override SIP_HOLDGIL;
256 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;
257
258 bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const override;
259 void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const override;
260 bool hasCurvedSegments() const final;
261
267 QgsAbstractGeometry *segmentize( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override SIP_FACTORY;
268
274 double vertexAngle( QgsVertexId vertex ) const override;
275
276 int vertexCount( int part = 0, int ring = 0 ) const override;
277 int ringCount( int part = 0 ) const override SIP_HOLDGIL;
278 int partCount() const override SIP_HOLDGIL;
279 QgsPoint vertexAt( QgsVertexId id ) const override;
280 double segmentLength( QgsVertexId startVertex ) const override;
281
282 bool addZValue( double zValue = 0 ) override;
283 bool addMValue( double mValue = 0 ) override;
284 bool dropZValue() override;
285 bool dropMValue() override;
286 void swapXy() override;
287
288 QgsMultiSurface *toCurveType() const override SIP_FACTORY;
289
290 bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) override;
291
296 QgsMultiPolygon *toMultiPolygon() const SIP_FACTORY;
297
298#ifndef SIP_RUN
299 void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
300 void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) override;
301
310 inline static const QgsPolyhedralSurface *cast( const QgsAbstractGeometry *geom ) // cppcheck-suppress duplInheritedMember
311 {
312 if ( !geom )
313 return nullptr;
314
315 const Qgis::WkbType flatType = QgsWkbTypes::flatType( geom->wkbType() );
316 if ( flatType == Qgis::WkbType::PolyhedralSurface
317 || flatType == Qgis::WkbType::TIN )
318 return static_cast<const QgsPolyhedralSurface *>( geom );
319
320 return nullptr;
321 }
322
331 inline static QgsPolyhedralSurface *cast( QgsAbstractGeometry *geom ) // cppcheck-suppress duplInheritedMember
332 {
333 if ( !geom )
334 return nullptr;
335
336 const Qgis::WkbType flatType = QgsWkbTypes::flatType( geom->wkbType() );
337 if ( flatType == Qgis::WkbType::PolyhedralSurface
338 || flatType == Qgis::WkbType::TIN )
339 return static_cast<QgsPolyhedralSurface *>( geom );
340
341 return nullptr;
342 }
343#endif
344
346
347#ifdef SIP_RUN
348 SIP_PYOBJECT __repr__();
349 % MethodCode
350 QString wkt = sipCpp->asWkt();
351 if ( wkt.length() > 1000 )
352 wkt = wkt.left( 1000 ) + QStringLiteral( "..." );
353 QString str = QStringLiteral( "<QgsPolyhedralSurface: %1>" ).arg( wkt );
354 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
355 % End
356
360 int __len__() const;
361 % MethodCode
362 sipRes = sipCpp->numPatches();
363 % End
364
373 SIP_PYOBJECT __getitem__( int index ) SIP_TYPEHINT( QgsPolygon );
374 % MethodCode
375 const int count = sipCpp->numPatches();
376 if ( a0 < -count || a0 >= count )
377 {
378 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
379 sipIsErr = 1;
380 }
381 else if ( a0 >= 0 )
382 {
383 return sipConvertFromType( sipCpp->patchN( a0 ), sipType_QgsPolygon, NULL );
384 }
385 else
386 {
387 return sipConvertFromType( sipCpp->patchN( count + a0 ), sipType_QgsPolygon, NULL );
388 }
389 % End
390#endif
391
392 protected:
393
394 int childCount() const override;
395 QgsAbstractGeometry *childGeometry( int index ) const override;
396 int compareToSameClass( const QgsAbstractGeometry *other ) const override;
397 QgsBox3D calculateBoundingBox3D() const override;
398
399 QVector< QgsPolygon * > mPatches;
400};
401
402// clazy:excludeall=qstring-allocations
403
404#endif // QGSPOLYHEDRALSURFACE_H
Provides global constants and enumerations for use throughout the application.
Definition qgis.h:56
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:277
@ TIN
TIN.
Definition qgis.h:293
@ PolyhedralSurface
PolyhedralSurface.
Definition qgis.h:292
TransformDirection
Indicates the direction (forward or inverse) of a transform.
Definition qgis.h:2671
@ Forward
Forward transform (from source to destination).
Definition qgis.h:2672
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
QgsAbstractGeometry()=default
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:42
A const WKB pointer.
Definition qgswkbptr.h:139
Multi polygon geometry collection.
Polygon geometry type.
Definition qgspolygon.h:33
Polyhedral surface geometry type.
bool operator!=(const QgsAbstractGeometry &other) const override
QVector< QgsPolygon * > mPatches
int numPatches() const
Returns the number of patches contained with the polyhedral surface.
bool fuzzyDistanceEqual(const QgsAbstractGeometry &other, double epsilon=1e-8) const override
Performs fuzzy distance comparison between this geometry and other using an epsilon.
static QgsPolyhedralSurface * cast(QgsAbstractGeometry *geom)
Cast the geom to a QgsPolyhedralSurface.
static const QgsPolyhedralSurface * cast(const QgsAbstractGeometry *geom)
Cast the geom to a QgsPolyhedralSurface.
QgsPolygon * patchN(int i)
Retrieves a patch from the polyhedral surface.
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 QgsPolygon * patchN(int i) const
Retrieves a patch from the polyhedral surface.
Surface geometry type.
Definition qgssurface.h:34
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
#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