Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgscurve.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 QGSCURVE_H 19 : : #define QGSCURVE_H 20 : : 21 : : #include "qgis_core.h" 22 : : #include "qgis_sip.h" 23 : : #include "qgsabstractgeometry.h" 24 : : #include "qgsrectangle.h" 25 : : #include <QPainterPath> 26 : : 27 : : class QgsLineString; 28 : : 29 : : /** 30 : : * \ingroup core 31 : : * \class QgsCurve 32 : : * \brief Abstract base class for curved geometry type 33 : : * \since QGIS 2.10 34 : : */ 35 : 5667 : class CORE_EXPORT QgsCurve: public QgsAbstractGeometry 36 : : { 37 : : public: 38 : : 39 : : /** 40 : : * Constructor for QgsCurve. 41 : : */ 42 : 6211 : QgsCurve() = default; 43 : : 44 : : /** 45 : : * Checks whether this curve exactly equals another curve. 46 : : * \since QGIS 3.0 47 : : */ 48 : : virtual bool equals( const QgsCurve &other ) const = 0; 49 : : 50 : : bool operator==( const QgsAbstractGeometry &other ) const override; 51 : : bool operator!=( const QgsAbstractGeometry &other ) const override; 52 : : 53 : : QgsCurve *clone() const override = 0 SIP_FACTORY; 54 : : 55 : : /** 56 : : * Returns the starting point of the curve. 57 : : * \see endPoint 58 : : */ 59 : : virtual QgsPoint startPoint() const = 0; 60 : : 61 : : /** 62 : : * Returns the end point of the curve. 63 : : * \see startPoint 64 : : */ 65 : : virtual QgsPoint endPoint() const = 0; 66 : : 67 : : /** 68 : : * Returns TRUE if the curve is closed. 69 : : */ 70 : : virtual bool isClosed() const SIP_HOLDGIL; 71 : : 72 : : /** 73 : : * Returns TRUE if the curve is a ring. 74 : : */ 75 : : virtual bool isRing() const SIP_HOLDGIL; 76 : : 77 : : /** 78 : : * Returns a new line string geometry corresponding to a segmentized approximation 79 : : * of the curve. 80 : : * \param tolerance segmentation tolerance 81 : : * \param toleranceType maximum segmentation angle or maximum difference between approximation and curve 82 : : * 83 : : * Uses a MaximumAngle tolerance of 1 degrees by default (360 84 : : * segments in a full circle) 85 : : */ 86 : : virtual QgsLineString *curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const = 0 SIP_FACTORY; 87 : : 88 : : /** 89 : : * Adds a curve to a painter path. 90 : : */ 91 : : virtual void addToPainterPath( QPainterPath &path ) const = 0; 92 : : QPainterPath asQPainterPath() const override; 93 : : 94 : : /** 95 : : * Draws the curve as a polygon on the specified QPainter. 96 : : * \param p destination QPainter 97 : : */ 98 : : virtual void drawAsPolygon( QPainter &p ) const = 0; 99 : : 100 : : /** 101 : : * Returns a list of points within the curve. 102 : : */ 103 : : virtual void points( QgsPointSequence &pt SIP_OUT ) const = 0; 104 : : 105 : : /** 106 : : * Returns the number of points in the curve. 107 : : */ 108 : : virtual int numPoints() const = 0; 109 : : 110 : : #ifdef SIP_RUN 111 : : int __len__() const; 112 : : % Docstring 113 : : Returns the number of points in the curve. 114 : : % End 115 : : % MethodCode 116 : : sipRes = sipCpp->numPoints(); 117 : : % End 118 : : 119 : : //! Ensures that bool(obj) returns TRUE (otherwise __len__() would be used) 120 : : int __bool__() const; 121 : : % MethodCode 122 : : sipRes = true; 123 : : % End 124 : : #endif 125 : : 126 : : /** 127 : : * Sums up the area of the curve by iterating over the vertices (shoelace formula). 128 : : */ 129 : : virtual void sumUpArea( double &sum SIP_OUT ) const = 0; 130 : : 131 : : QgsCoordinateSequence coordinateSequence() const override; 132 : : bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const override; 133 : : void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const override; 134 : : int vertexNumberFromVertexId( QgsVertexId id ) const override; 135 : : 136 : : /** 137 : : * Returns the point and vertex id of a point within the curve. 138 : : * \param node node number, where the first node is 0 139 : : * \param point will be set to point at corresponding node in the curve 140 : : * \param type will be set to the vertex type of the node 141 : : * \returns TRUE if node exists within the curve 142 : : */ 143 : : virtual bool pointAt( int node, QgsPoint &point SIP_OUT, QgsVertexId::VertexType &type SIP_OUT ) const = 0; 144 : : 145 : : /** 146 : : * Returns a reversed copy of the curve, where the direction of the curve has been flipped. 147 : : * \since QGIS 2.14 148 : : */ 149 : : virtual QgsCurve *reversed() const = 0 SIP_FACTORY; 150 : : 151 : : QgsAbstractGeometry *boundary() const override SIP_FACTORY; 152 : : 153 : : QString asKml( int precision = 17 ) const override; 154 : : 155 : : /** 156 : : * Returns a geometry without curves. Caller takes ownership 157 : : * \param tolerance segmentation tolerance 158 : : * \param toleranceType maximum segmentation angle or maximum difference between approximation and curve 159 : : */ 160 : : QgsCurve *segmentize( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override SIP_FACTORY; 161 : : 162 : : int vertexCount( int part = 0, int ring = 0 ) const override; 163 : : int ringCount( int part = 0 ) const override; 164 : : int partCount() const override; 165 : : QgsPoint vertexAt( QgsVertexId id ) const override; 166 : : QgsCurve *toCurveType() const override SIP_FACTORY; 167 : : 168 : : QgsRectangle boundingBox() const override; 169 : : bool isValid( QString &error SIP_OUT, int flags = 0 ) const override; 170 : : 171 : : /** 172 : : * Returns the x-coordinate of the specified node in the line string. 173 : : * \param index index of node, where the first node in the line is 0 174 : : * \returns x-coordinate of node, or 0.0 if index is out of bounds 175 : : */ 176 : : virtual double xAt( int index ) const = 0; 177 : : 178 : : /** 179 : : * Returns the y-coordinate of the specified node in the line string. 180 : : * \param index index of node, where the first node in the line is 0 181 : : * \returns y-coordinate of node, or 0.0 if index is out of bounds 182 : : */ 183 : : virtual double yAt( int index ) const = 0; 184 : : 185 : : /** 186 : : * Returns a QPolygonF representing the points. 187 : : */ 188 : : virtual QPolygonF asQPolygonF() const; 189 : : 190 : : /** 191 : : * Returns an interpolated point on the curve at the specified \a distance. 192 : : * 193 : : * If z or m values are present, the output z and m will be interpolated using 194 : : * the existing vertices' z or m values. 195 : : * 196 : : * If distance is negative, or is greater than the length of the curve, NULLPTR 197 : : * will be returned. 198 : : * 199 : : * \since QGIS 3.4 200 : : */ 201 : : virtual QgsPoint *interpolatePoint( double distance ) const = 0 SIP_FACTORY; 202 : : 203 : : /** 204 : : * Returns a new curve representing a substring of this curve. 205 : : * 206 : : * The \a startDistance and \a endDistance arguments specify the length along the curve 207 : : * which the substring should start and end at. If the \a endDistance is greater than the 208 : : * total length of the curve then any "extra" length will be ignored. 209 : : * 210 : : * If z or m values are present, the output z and m will be interpolated using 211 : : * the existing vertices' z or m values. 212 : : * 213 : : * \since QGIS 3.4 214 : : */ 215 : : virtual QgsCurve *curveSubstring( double startDistance, double endDistance ) const = 0 SIP_FACTORY; 216 : : 217 : : /** 218 : : * Returns the straight distance of the curve, i.e. the direct/euclidean distance 219 : : * between the first and last vertex of the curve. (Also known as 220 : : * "as the crow flies" distance). 221 : : * 222 : : * \since QGIS 3.2 223 : : */ 224 : : double straightDistance2d() const; 225 : : 226 : : /** 227 : : * Returns the curve sinuosity, which is the ratio of the curve length() to curve 228 : : * straightDistance2d(). Larger numbers indicate a more "sinuous" curve (i.e. more 229 : : * "bendy"). The minimum value returned of 1.0 indicates a perfectly straight curve. 230 : : * 231 : : * If a curve isClosed(), it has infinite sinuosity and will return NaN. 232 : : * 233 : : * \since QGIS 3.2 234 : : */ 235 : : double sinuosity() const; 236 : : 237 : : //! Curve orientation 238 : : enum Orientation 239 : : { 240 : : Clockwise, //!< Clockwise orientation 241 : : CounterClockwise, //!< Counter-clockwise orientation 242 : : }; 243 : : 244 : : /** 245 : : * Returns the curve's orientation, e.g. clockwise or counter-clockwise. 246 : : * 247 : : * \warning The result is not predictable for non-closed curves. 248 : : * 249 : : * \since QGIS 3.6 250 : : */ 251 : : Orientation orientation() const; 252 : : 253 : : #ifndef SIP_RUN 254 : : 255 : : /** 256 : : * Cast the \a geom to a QgsCurve. 257 : : * Should be used by qgsgeometry_cast<QgsCurve *>( geometry ). 258 : : * 259 : : * \note Not available in Python. Objects will be automatically be converted to the appropriate target type. 260 : : * \since QGIS 3.0 261 : : */ 262 : 766 : inline static const QgsCurve *cast( const QgsAbstractGeometry *geom ) 263 : : { 264 : 766 : if ( !geom ) 265 : 1 : return nullptr; 266 : : 267 : 765 : QgsWkbTypes::Type type = geom->wkbType(); 268 : 765 : if ( QgsWkbTypes::geometryType( type ) == QgsWkbTypes::LineGeometry && QgsWkbTypes::isSingleType( type ) ) 269 : : { 270 : 721 : return static_cast<const QgsCurve *>( geom ); 271 : : } 272 : 44 : return nullptr; 273 : 766 : } 274 : : #endif 275 : : 276 : : 277 : : protected: 278 : : 279 : : void clearCache() const override; 280 : : 281 : : int childCount() const override; 282 : : QgsPoint childPoint( int index ) const override; 283 : : 284 : : #ifndef SIP_RUN 285 : : 286 : : /** 287 : : * Helper function for QgsCurve subclasses to snap to grids. 288 : : * \note Not available in Python bindings. 289 : : */ 290 : : bool snapToGridPrivate( double hSpacing, double vSpacing, double dSpacing, double mSpacing, 291 : : const QVector<double> &srcX, const QVector<double> &srcY, const QVector<double> &srcZ, const QVector<double> &srcM, 292 : : QVector<double> &outX, QVector<double> &outY, QVector<double> &outZ, QVector<double> &outM ) const; 293 : : #endif 294 : : 295 : : /** 296 : : * Cached bounding box. 297 : : */ 298 : : mutable QgsRectangle mBoundingBox; 299 : : 300 : : private: 301 : : 302 : 6211 : mutable bool mHasCachedValidity = false; 303 : : mutable QString mValidityFailureReason; 304 : : }; 305 : : 306 : : #endif // QGSCURVE_H