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