1 /***************************************************************************
2                          qgscompoundcurve.h
3                          ---------------------
4     begin                : September 2014
5     copyright            : (C) 2014 by Marco Hugentobler
6     email                : marco at sourcepole dot ch
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 QGSCOMPOUNDCURVE_H
19 #define QGSCOMPOUNDCURVE_H
20 
21 #include "qgis_core.h"
22 #include "qgis_sip.h"
23 #include "qgscurve.h"
24 
25 /**
26  * \ingroup core
27  * \class QgsCompoundCurve
28  * \brief Compound curve geometry type
29  * \since QGIS 2.10
30  */
31 class CORE_EXPORT QgsCompoundCurve: public QgsCurve
32 {
33   public:
34     QgsCompoundCurve();
35     QgsCompoundCurve( const QgsCompoundCurve &curve );
36     QgsCompoundCurve &operator=( const QgsCompoundCurve &curve );
37     ~QgsCompoundCurve() override;
38 
39     bool equals( const QgsCurve &other ) const override;
40 
41     QString geometryType() const override SIP_HOLDGIL;
42     int dimension() const override SIP_HOLDGIL;
43     QgsCompoundCurve *clone() const override SIP_FACTORY;
44     void clear() override;
45 
46     bool fromWkb( QgsConstWkbPtr &wkb ) override;
47     bool fromWkt( const QString &wkt ) override;
48 
49     int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
50     QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
51     QString asWkt( int precision = 17 ) const override;
52     QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
53     QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
54     json asJsonObject( int precision = 17 ) const override SIP_SKIP;
55 
56     //curve interface
57     double length() const override SIP_HOLDGIL;
58     QgsPoint startPoint() const override SIP_HOLDGIL;
59     QgsPoint endPoint() const override SIP_HOLDGIL;
60     void points( QgsPointSequence &pts SIP_OUT ) const override;
61     int numPoints() const override SIP_HOLDGIL;
62     bool isEmpty() const override SIP_HOLDGIL;
63 
64     /**
65      * Returns a new line string geometry corresponding to a segmentized approximation
66      * of the curve.
67      * \param tolerance segmentation tolerance
68      * \param toleranceType maximum segmentation angle or maximum difference between approximation and curve
69     */
70     QgsLineString *curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override SIP_FACTORY;
71 
72     QgsCompoundCurve *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY;
73     bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;
74 
75     /**
76      * Returns the number of curves in the geometry.
77      */
nCurves()78     int nCurves() const SIP_HOLDGIL { return mCurves.size(); }
79 
80     /**
81      * Returns the curve at the specified index.
82      */
83     const QgsCurve *curveAt( int i ) const SIP_HOLDGIL;
84 
85     /**
86      * Adds a curve to the geometry (takes ownership)
87      */
88     void addCurve( QgsCurve *c SIP_TRANSFER );
89 
90     /**
91      * Removes a curve from the geometry.
92      * \param i index of curve to remove
93      */
94     void removeCurve( int i );
95 
96     /**
97      * Adds a vertex to the end of the geometry.
98      */
99     void addVertex( const QgsPoint &pt );
100 
101     void draw( QPainter &p ) const override;
102     void transform( const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform, bool transformZ = false ) override  SIP_THROW( QgsCsException );
103     void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 ) override;
104     void addToPainterPath( QPainterPath &path ) const override;
105     void drawAsPolygon( QPainter &p ) const override;
106     bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) override;
107     bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) override;
108     bool deleteVertex( QgsVertexId position ) override;
109     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;
110     bool pointAt( int node, QgsPoint &point, QgsVertexId::VertexType &type ) const override;
111     void sumUpArea( double &sum SIP_OUT ) const override;
112 
113     //! Appends first point if not already closed.
114     void close();
115 
116     bool hasCurvedSegments() const override;
117     double vertexAngle( QgsVertexId vertex ) const override;
118     double segmentLength( QgsVertexId startVertex ) const override;
119     QgsCompoundCurve *reversed() const override SIP_FACTORY;
120     QgsPoint *interpolatePoint( double distance ) const override SIP_FACTORY;
121     QgsCompoundCurve *curveSubstring( double startDistance, double endDistance ) const override SIP_FACTORY;
122 
123     bool addZValue( double zValue = 0 ) override;
124     bool addMValue( double mValue = 0 ) override;
125 
126     bool dropZValue() override;
127     bool dropMValue() override;
128     void swapXy() override;
129 
130     double xAt( int index ) const override SIP_HOLDGIL;
131     double yAt( int index ) const override SIP_HOLDGIL;
132 
133 #ifndef SIP_RUN
134     void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
135     void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) override;
136 
137     /**
138      * Cast the \a geom to a QgsCompoundCurve.
139      * Should be used by qgsgeometry_cast<QgsCompoundCurve *>( geometry ).
140      *
141      * \note Not available in Python. Objects will be automatically be converted to the appropriate target type.
142      * \since QGIS 3.0
143      */
cast(const QgsAbstractGeometry * geom)144     inline const QgsCompoundCurve *cast( const QgsAbstractGeometry *geom ) const
145     {
146       if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::CompoundCurve )
147         return static_cast<const QgsCompoundCurve *>( geom );
148       return nullptr;
149     }
150 #endif
151 
152     QgsCompoundCurve *createEmptyWithSameType() const override SIP_FACTORY;
153 
154 #ifdef SIP_RUN
155     SIP_PYOBJECT __repr__();
156     % MethodCode
157     QString wkt = sipCpp->asWkt();
158     if ( wkt.length() > 1000 )
159       wkt = wkt.left( 1000 ) + QStringLiteral( "..." );
160     QString str = QStringLiteral( "<QgsCompoundCurve: %1>" ).arg( wkt );
161     sipRes = PyUnicode_FromString( str.toUtf8().constData() );
162     % End
163 #endif
164 
165   protected:
166 
167     QgsRectangle calculateBoundingBox() const override;
168 
169   private:
170     QVector< QgsCurve * > mCurves;
171 
172     /**
173      * Turns a vertex id for the compound curve into one or more ids for the subcurves
174      * \returns the index of the subcurve or -1 in case of error
175     */
176     QVector< QPair<int, QgsVertexId> > curveVertexId( QgsVertexId id ) const;
177 
178 };
179 
180 // clazy:excludeall=qstring-allocations
181 
182 #endif // QGSCOMPOUNDCURVE_H
183