/
qgscurvepolygon.h
230 lines (189 loc) · 9.22 KB
/
qgscurvepolygon.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
/***************************************************************************
qgscurvepolygon.h
-------------------
begin : September 2014
copyright : (C) 2014 by Marco Hugentobler
email : marco at sourcepole dot ch
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSCURVEPOLYGONV2_H
#define QGSCURVEPOLYGONV2_H
#include "qgis_core.h"
#include "qgis.h"
#include "qgssurface.h"
#include <memory>
class QgsPolygon;
/**
* \ingroup core
* \class QgsCurvePolygon
* \brief Curve polygon geometry type
* \since QGIS 2.10
*/
class CORE_EXPORT QgsCurvePolygon: public QgsSurface
{
public:
QgsCurvePolygon();
QgsCurvePolygon( const QgsCurvePolygon &p );
QgsCurvePolygon &operator=( const QgsCurvePolygon &p );
bool operator==( const QgsAbstractGeometry &other ) const override;
bool operator!=( const QgsAbstractGeometry &other ) const override;
~QgsCurvePolygon() override;
QString geometryType() const override;
int dimension() const override;
QgsCurvePolygon *clone() const override SIP_FACTORY;
void clear() override;
bool fromWkb( QgsConstWkbPtr &wkb ) override;
bool fromWkt( const QString &wkt ) override;
QByteArray asWkb() const override;
QString asWkt( int precision = 17 ) const override;
QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
QString asJson( int precision = 17 ) const override;
//surface interface
double area() const override;
double perimeter() const override;
QgsPolygon *surfaceToPolygon() const override SIP_FACTORY;
QgsAbstractGeometry *boundary() const override SIP_FACTORY;
QgsCurvePolygon *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY;
bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;
//curve polygon interface
int numInteriorRings() const
{
return mInteriorRings.size();
}
const QgsCurve *exteriorRing() const
{
return mExteriorRing.get();
}
const QgsCurve *interiorRing( int i ) const
{
if ( i < 0 || i >= mInteriorRings.size() )
{
return nullptr;
}
return mInteriorRings.at( i );
}
/**
* Returns a new polygon geometry corresponding to a segmentized approximation
* of the curve.
* \param tolerance segmentation tolerance
* \param toleranceType maximum segmentation angle or maximum difference between approximation and curve*/
virtual QgsPolygon *toPolygon( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const SIP_FACTORY;
/**
* Sets the exterior ring of the polygon. The CurvePolygon type will be updated to match the dimensionality
* of the exterior ring. For instance, setting a 2D exterior ring on a 3D CurvePolygon will drop the z dimension
* from the CurvePolygon and all interior rings.
* \param ring new exterior ring. Ownership is transferred to the CurvePolygon.
* \see setInteriorRings()
* \see exteriorRing()
*/
virtual void setExteriorRing( QgsCurve *ring SIP_TRANSFER );
//! Sets all interior rings (takes ownership)
void setInteriorRings( const QVector<QgsCurve *> &rings SIP_TRANSFER );
//! Adds an interior ring to the geometry (takes ownership)
virtual void addInteriorRing( QgsCurve *ring SIP_TRANSFER );
/**
* Removes an interior ring from the polygon. The first interior ring has index 0.
* The corresponding ring is removed from the polygon and deleted. If a ring was successfully removed
* the function will return true. It is not possible to remove the exterior ring using this method.
* \see removeInteriorRings()
*/
bool removeInteriorRing( int ringIndex );
/**
* Removes the interior rings from the polygon. If the minimumAllowedArea
* parameter is specified then only rings smaller than this minimum
* area will be removed.
* \see removeInteriorRing()
* \since QGIS 3.0
*/
void removeInteriorRings( double minimumAllowedArea = -1 );
/**
* Removes any interior rings which are not valid from the polygon.
*
* For example, this removes unclosed rings and rings with less than 4 vertices.
*
* \since QGIS 3.0
*/
void removeInvalidRings();
void draw( QPainter &p ) const override;
void transform( const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform, bool transformZ = false ) override SIP_THROW( QgsCsException );
void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 ) override;
bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) override;
bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) override;
bool deleteVertex( QgsVertexId position ) override;
QgsCoordinateSequence coordinateSequence() const override;
int nCoordinates() const override;
int vertexNumberFromVertexId( QgsVertexId id ) const override;
bool isEmpty() const override;
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;
bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const override;
void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const override;
bool hasCurvedSegments() const override;
/**
* Returns a geometry without curves. Caller takes ownership
* \param tolerance segmentation tolerance
* \param toleranceType maximum segmentation angle or maximum difference between approximation and curve*/
QgsAbstractGeometry *segmentize( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override SIP_FACTORY;
/**
* Returns approximate rotation angle for a vertex. Usually average angle between adjacent segments.
* \param vertex the vertex id
* \returns rotation in radians, clockwise from north
*/
double vertexAngle( QgsVertexId vertex ) const override;
int vertexCount( int part = 0, int ring = 0 ) const override;
int ringCount( int part = 0 ) const override;
int partCount() const override;
QgsPoint vertexAt( QgsVertexId id ) const override;
double segmentLength( QgsVertexId startVertex ) const override;
bool addZValue( double zValue = 0 ) override;
bool addMValue( double mValue = 0 ) override;
bool dropZValue() override;
bool dropMValue() override;
void swapXy() override;
QgsCurvePolygon *toCurveType() const override SIP_FACTORY;
#ifndef SIP_RUN
void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
/**
* Cast the \a geom to a QgsCurvePolygon.
* Should be used by qgsgeometry_cast<QgsCurvePolygon *>( geometry ).
*
* \note Not available in Python. Objects will be automatically be converted to the appropriate target type.
* \since QGIS 3.0
*/
inline const QgsCurvePolygon *cast( const QgsAbstractGeometry *geom ) const
{
if ( !geom )
return nullptr;
QgsWkbTypes::Type flatType = QgsWkbTypes::flatType( geom->wkbType() );
if ( flatType == QgsWkbTypes::CurvePolygon
|| flatType == QgsWkbTypes::Polygon
|| flatType == QgsWkbTypes::Triangle )
return static_cast<const QgsCurvePolygon *>( geom );
return nullptr;
}
#endif
QgsCurvePolygon *createEmptyWithSameType() const override SIP_FACTORY;
#ifdef SIP_RUN
SIP_PYOBJECT __repr__();
% MethodCode
QString str = QStringLiteral( "<QgsCurvePolygon: %1>" ).arg( sipCpp->asWkt() );
sipRes = PyUnicode_FromString( str.toUtf8().data() );
% End
#endif
protected:
int childCount() const override;
QgsAbstractGeometry *childGeometry( int index ) const override;
protected:
std::unique_ptr< QgsCurve > mExteriorRing;
QVector<QgsCurve *> mInteriorRings;
QgsRectangle calculateBoundingBox() const override;
};
// clazy:excludeall=qstring-allocations
#endif // QGSCURVEPOLYGONV2_H