QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
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
27#include <QString>
28
29using namespace Qt::StringLiterals;
30
40class CORE_EXPORT QgsPolyhedralSurface : public QgsSurface
41{
42 public:
45
46
50 QgsPolyhedralSurface( const QgsMultiPolygon *multiPolygon );
51
53
54#ifndef SIP_RUN
55 private:
56 bool fuzzyHelper( const QgsAbstractGeometry &other, double epsilon, bool useDistance ) const
57 {
59 if ( !otherPolygon )
60 return false;
61
62 //run cheap checks first
63 if ( mWkbType != otherPolygon->mWkbType )
64 return false;
65
66 if ( mPatches.count() != otherPolygon->mPatches.count() )
67 return false;
68
69 for ( int i = 0; i < mPatches.count(); ++i )
70 {
71 if ( ( !mPatches.at( i ) && otherPolygon->mPatches.at( i ) ) || ( mPatches.at( i ) && !otherPolygon->mPatches.at( i ) ) )
72 return false;
73
74 if ( useDistance )
75 {
76 if ( mPatches.at( i ) && otherPolygon->mPatches.at( i ) && !( *mPatches.at( i ) ).fuzzyDistanceEqual( *otherPolygon->mPatches.at( i ), epsilon ) )
77 return false;
78 }
79 else
80 {
81 if ( mPatches.at( i ) && otherPolygon->mPatches.at( i ) && !( *mPatches.at( i ) ).fuzzyEqual( *otherPolygon->mPatches.at( i ), epsilon ) )
82 return false;
83 }
84 }
85
86 return true;
87 }
88#endif
89
90 public:
91 // clang-format off
92 bool fuzzyEqual( const QgsAbstractGeometry &other, double epsilon = 1e-8 ) const override SIP_HOLDGIL
93 // clang-format on
94 {
95 return fuzzyHelper( other, epsilon, false );
96 }
97 bool fuzzyDistanceEqual( const QgsAbstractGeometry &other, double epsilon = 1e-8 ) const override SIP_HOLDGIL
98 {
99 return fuzzyHelper( other, epsilon, true );
100 }
101
102 bool operator==( const QgsAbstractGeometry &other ) const override
103 {
104 return fuzzyEqual( other, 1e-8 );
105 }
106
107 bool operator!=( const QgsAbstractGeometry &other ) const override
108 {
109 return !operator==( other );
110 }
111
112 ~QgsPolyhedralSurface() override;
113
114 QString geometryType() const override SIP_HOLDGIL;
115 int dimension() const final SIP_HOLDGIL;
116 QgsPolyhedralSurface *clone() const override SIP_FACTORY;
117 void clear() override;
118
119 bool fromWkb( QgsConstWkbPtr &wkb ) override;
120 bool fromWkt( const QString &wkt ) override;
121
122 bool isValid( QString &error SIP_OUT, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const override;
123
124 int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
125 QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
126 QString asWkt( int precision = 17 ) const override;
127 QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
128 QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
129 json asJsonObject( int precision = 17 ) const override SIP_SKIP;
130 QString asKml( int precision = 17 ) const override;
131 void normalize() override SIP_HOLDGIL;
132
133 //surface interface
134 double area() const override SIP_HOLDGIL;
135 double area3D() const override SIP_HOLDGIL;
136 double perimeter() const override SIP_HOLDGIL;
137 QgsAbstractGeometry *boundary() const override SIP_FACTORY;
138 QgsPolyhedralSurface *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0, bool removeRedundantPoints = false ) const override SIP_FACTORY;
139 QgsPolyhedralSurface *simplifyByDistance( double tolerance ) const override SIP_FACTORY;
140 bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;
141
142 using QgsSurface::boundingBoxIntersects;
143 bool boundingBoxIntersects( const QgsBox3D &box3d ) const override SIP_HOLDGIL;
144
151 {
152 return mPatches.size();
153 }
154
155#ifndef SIP_RUN
156
162 const QgsPolygon *patchN( int i ) const
163 {
164 if ( i < 0 || i >= mPatches.size() )
165 {
166 return nullptr;
167 }
168 return mPatches.at( i );
169 }
170
177 {
178 if ( i < 0 || i >= mPatches.size() )
179 {
180 return nullptr;
181 }
182 return mPatches.at( i );
183 }
184#else
185// clang-format off
186
194 SIP_PYOBJECT patchN( int i ) SIP_HOLDGIL SIP_TYPEHINT( QgsPolygon );
195 % MethodCode
196 if ( a0 < 0 || a0 >= sipCpp->numPatches() )
197 {
198 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
199 sipIsErr = 1;
200 }
201 else
202 {
203 return sipConvertFromType( const_cast< QgsPolygon * >( sipCpp->patchN( a0 ) ), sipType_QgsPolygon, NULL );
204 }
205 % End
206// clang-format on
207#endif
208
212 virtual void setPatches( const QVector<QgsPolygon *> &patches SIP_TRANSFER );
213
217 virtual void addPatch( QgsPolygon *patch SIP_TRANSFER );
218
219#ifndef SIP_RUN
220
227 bool removePatch( int patchIndex );
228#else
229// clang-format off
230
238 bool removePatch( int ringIndex );
239 % MethodCode
240 if ( a0 < 0 || a0 >= sipCpp->numPatches() )
241 {
242 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
243 sipIsErr = 1;
244 }
245 else
246 {
247 return PyBool_FromLong( sipCpp->removePatch( a0 ) );
248 }
249 % End
250// clang-format on
251#endif
252
253 QPainterPath asQPainterPath() const override;
254 void draw( QPainter &p ) const override;
255 void transform( const QgsCoordinateTransform &ct, Qgis::TransformDirection d = Qgis::TransformDirection::Forward, bool transformZ = false ) override SIP_THROW( QgsCsException );
256 void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 ) override;
257
258 bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) override;
259 bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) override;
260 bool deleteVertex( QgsVertexId position ) override;
261
262 QgsCoordinateSequence coordinateSequence() const override;
263 int nCoordinates() const override;
264 int vertexNumberFromVertexId( QgsVertexId id ) const override;
265 bool isEmpty() const override SIP_HOLDGIL;
266 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;
267
268 bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const override;
269 void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const override;
270 bool hasCurvedSegments() const final;
271
277 QgsAbstractGeometry *segmentize( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override SIP_FACTORY;
278
284 double vertexAngle( QgsVertexId vertex ) const override;
285
286 int vertexCount( int part = 0, int ring = 0 ) const override;
287 int ringCount( int part = 0 ) const override SIP_HOLDGIL;
288 int partCount() const override SIP_HOLDGIL;
289 QgsPoint vertexAt( QgsVertexId id ) const override;
290 double segmentLength( QgsVertexId startVertex ) const override;
291
292 bool addZValue( double zValue = 0 ) override;
293 bool addMValue( double mValue = 0 ) override;
294 bool dropZValue() override;
295 bool dropMValue() override;
296 void swapXy() override;
297
298 QgsMultiSurface *toCurveType() const override SIP_FACTORY;
299
300 bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) override;
301
306 QgsMultiPolygon *toMultiPolygon() const SIP_FACTORY;
307
308#ifndef SIP_RUN
309 void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
310 void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) override;
311
320 inline static const QgsPolyhedralSurface *cast( const QgsAbstractGeometry *geom ) // cppcheck-suppress duplInheritedMember
321 {
322 if ( !geom )
323 return nullptr;
324
325 const Qgis::WkbType flatType = QgsWkbTypes::flatType( geom->wkbType() );
326 if ( flatType == Qgis::WkbType::PolyhedralSurface
327 || flatType == Qgis::WkbType::TIN )
328 return static_cast<const QgsPolyhedralSurface *>( geom );
329
330 return nullptr;
331 }
332
341 inline static QgsPolyhedralSurface *cast( QgsAbstractGeometry *geom ) // cppcheck-suppress duplInheritedMember
342 {
343 if ( !geom )
344 return nullptr;
345
346 const Qgis::WkbType flatType = QgsWkbTypes::flatType( geom->wkbType() );
347 if ( flatType == Qgis::WkbType::PolyhedralSurface
348 || flatType == Qgis::WkbType::TIN )
349 return static_cast<QgsPolyhedralSurface *>( geom );
350
351 return nullptr;
352 }
353#endif
354
356
357#ifdef SIP_RUN
358// clang-format off
359 SIP_PYOBJECT __repr__();
360 % MethodCode
361 QString wkt = sipCpp->asWkt();
362 if ( wkt.length() > 1000 )
363 wkt = wkt.left( 1000 ) + u"..."_s;
364 QString str = u"<QgsPolyhedralSurface: %1>"_s.arg( wkt );
365 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
366 % End
367
371 int __len__() const;
372 % MethodCode
373 sipRes = sipCpp->numPatches();
374 % End
375
384 SIP_PYOBJECT __getitem__( int index ) SIP_TYPEHINT( QgsPolygon );
385 % MethodCode
386 const int count = sipCpp->numPatches();
387 if ( a0 < -count || a0 >= count )
388 {
389 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
390 sipIsErr = 1;
391 }
392 else if ( a0 >= 0 )
393 {
394 return sipConvertFromType( sipCpp->patchN( a0 ), sipType_QgsPolygon, NULL );
395 }
396 else
397 {
398 return sipConvertFromType( sipCpp->patchN( count + a0 ), sipType_QgsPolygon, NULL );
399 }
400 % End
401// clang-format on
402#endif
403
404 protected:
405
406 int childCount() const override;
407 QgsAbstractGeometry *childGeometry( int index ) const override;
408 int compareToSameClass( const QgsAbstractGeometry *other ) const override;
409 QgsBox3D calculateBoundingBox3D() const override;
410
411 QVector< QgsPolygon * > mPatches;
412};
413
414// clazy:excludeall=qstring-allocations
415
416#endif // QGSPOLYHEDRALSURFACE_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:294
@ TIN
TIN.
Definition qgis.h:310
@ PolyhedralSurface
PolyhedralSurface.
Definition qgis.h:309
TransformDirection
Indicates the direction (forward or inverse) of a transform.
Definition qgis.h:2764
@ Forward
Forward transform (from source to destination).
Definition qgis.h:2765
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:45
A const WKB pointer.
Definition qgswkbptr.h:211
Multi polygon geometry collection.
Polygon geometry type.
Definition qgspolygon.h:37
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:239
#define SIP_SKIP
Definition qgis_sip.h:133
#define SIP_TRANSFER
Definition qgis_sip.h:35
#define SIP_OUT
Definition qgis_sip.h:57
#define SIP_HOLDGIL
Definition qgis_sip.h:178
#define SIP_FACTORY
Definition qgis_sip.h:83
#define SIP_THROW(name,...)
Definition qgis_sip.h:210
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsRingSequence > QgsCoordinateSequence
double closestSegment(const QgsPolylineXY &pl, const QgsPointXY &pt, int &vertexAfter, double epsilon)
Definition qgstracer.cpp:72