Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsgeometrycollection.h 3 : : ------------------------------------------------------------------- 4 : : Date : 28 Oct 2014 5 : : Copyright : (C) 2014 by Marco Hugentobler 6 : : email : marco.hugentobler at sourcepole dot com 7 : : *************************************************************************** 8 : : * * 9 : : * This program is free software; you can redistribute it and/or modify * 10 : : * it under the terms of the GNU General Public License as published by * 11 : : * the Free Software Foundation; either version 2 of the License, or * 12 : : * (at your option) any later version. * 13 : : * * 14 : : ***************************************************************************/ 15 : : 16 : : #ifndef QGSGEOMETRYCOLLECTION_H 17 : : #define QGSGEOMETRYCOLLECTION_H 18 : : 19 : : #include <QVector> 20 : : 21 : : 22 : : #include "qgis_core.h" 23 : : #include "qgis_sip.h" 24 : : #include "qgsabstractgeometry.h" 25 : : 26 : : class QgsPoint; 27 : : 28 : : 29 : : /** 30 : : * \ingroup core 31 : : * \class QgsGeometryCollection 32 : : * \brief Geometry collection 33 : : * \since QGIS 2.10 34 : : */ 35 : : class CORE_EXPORT QgsGeometryCollection: public QgsAbstractGeometry 36 : : { 37 : : public: 38 : : 39 : : 40 : : /** 41 : : * Constructor for an empty geometry collection. 42 : : */ 43 : : QgsGeometryCollection() SIP_HOLDGIL; 44 : : 45 : : QgsGeometryCollection( const QgsGeometryCollection &c ); 46 : : QgsGeometryCollection &operator=( const QgsGeometryCollection &c ); 47 : : ~QgsGeometryCollection() override; 48 : : 49 : : bool operator==( const QgsAbstractGeometry &other ) const override; 50 : : bool operator!=( const QgsAbstractGeometry &other ) const override; 51 : : 52 : : QgsGeometryCollection *clone() const override SIP_FACTORY; 53 : : 54 : : /** 55 : : * Returns the number of geometries within the collection. 56 : : */ 57 : 82223 : int numGeometries() const SIP_HOLDGIL 58 : : { 59 : 82223 : return mGeometries.size(); 60 : : } 61 : : 62 : : #ifdef SIP_RUN 63 : : 64 : : /** 65 : : * Returns the number of geometries within the collection. 66 : : */ 67 : : int __len__() const; 68 : : % MethodCode 69 : : sipRes = sipCpp->numGeometries(); 70 : : % End 71 : : 72 : : //! Ensures that bool(obj) returns TRUE (otherwise __len__() would be used) 73 : : int __bool__() const; 74 : : % MethodCode 75 : : sipRes = true; 76 : : % End 77 : : #endif 78 : : 79 : : 80 : : /** 81 : : * Returns a const reference to a geometry from within the collection. 82 : : * \param n index of geometry to return 83 : : * \note not available in Python bindings 84 : : */ 85 : 41015 : const QgsAbstractGeometry *geometryN( int n ) const SIP_SKIP 86 : : { 87 : 41015 : return mGeometries.value( n ); 88 : : } 89 : : 90 : : #ifndef SIP_RUN 91 : : 92 : : /** 93 : : * Returns a geometry from within the collection. 94 : : * \param n index of geometry to return 95 : : */ 96 : : QgsAbstractGeometry *geometryN( int n ) SIP_HOLDGIL; 97 : : #else 98 : : 99 : : /** 100 : : * Returns a geometry from within the collection. 101 : : * \param n index of geometry to return. An IndexError will be raised if no geometry with the specified index exists. 102 : : */ 103 : : SIP_PYOBJECT geometryN( int n ) SIP_TYPEHINT( QgsAbstractGeometry ); 104 : : % MethodCode 105 : : if ( a0 < 0 || a0 >= sipCpp->numGeometries() ) 106 : : { 107 : : PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) ); 108 : : sipIsErr = 1; 109 : : } 110 : : else 111 : : { 112 : : return sipConvertFromType( sipCpp->geometryN( a0 ), sipType_QgsAbstractGeometry, NULL ); 113 : : } 114 : : % End 115 : : #endif 116 : : 117 : : 118 : : //methods inherited from QgsAbstractGeometry 119 : : bool isEmpty() const override SIP_HOLDGIL; 120 : : int dimension() const override SIP_HOLDGIL; 121 : : QString geometryType() const override SIP_HOLDGIL; 122 : : void clear() override; 123 : : QgsGeometryCollection *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY; 124 : : bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override; 125 : : QgsAbstractGeometry *boundary() const override SIP_FACTORY; 126 : : void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) const override; 127 : : int vertexNumberFromVertexId( QgsVertexId id ) const override; 128 : : bool boundingBoxIntersects( const QgsRectangle &rectangle ) const override SIP_HOLDGIL; 129 : : 130 : : /** 131 : : * Attempts to allocate memory for at least \a size geometries. 132 : : * 133 : : * If the number of geometries is known in advance, calling this function prior to adding geometries will prevent 134 : : * reallocations and memory fragmentation. 135 : : * 136 : : * \since QGIS 3.10 137 : : */ 138 : : void reserve( int size ) SIP_HOLDGIL; 139 : : 140 : : //! Adds a geometry and takes ownership. Returns TRUE in case of success. 141 : : virtual bool addGeometry( QgsAbstractGeometry *g SIP_TRANSFER ); 142 : : 143 : : /** 144 : : * Inserts a geometry before a specified index and takes ownership. Returns TRUE in case of success. 145 : : * \param g geometry to insert. Ownership is transferred to the collection. 146 : : * \param index position to insert geometry before 147 : : */ 148 : : virtual bool insertGeometry( QgsAbstractGeometry *g SIP_TRANSFER, int index ); 149 : : 150 : : #ifndef SIP_RUN 151 : : 152 : : /** 153 : : * Removes a geometry from the collection. 154 : : * \param nr index of geometry to remove 155 : : * \returns TRUE if removal was successful. 156 : : */ 157 : : virtual bool removeGeometry( int nr ); 158 : : #else 159 : : 160 : : /** 161 : : * Removes a geometry from the collection by index. 162 : : * 163 : : * An IndexError will be raised if no geometry with the specified index exists. 164 : : * 165 : : * \returns TRUE if removal was successful. 166 : : */ 167 : : virtual bool removeGeometry( int nr ); 168 : : % MethodCode 169 : : const int count = sipCpp->numGeometries(); 170 : : if ( a0 < 0 || a0 >= count ) 171 : : { 172 : : PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) ); 173 : : sipIsErr = 1; 174 : : } 175 : : else 176 : : { 177 : : return PyBool_FromLong( sipCpp->removeGeometry( a0 ) ); 178 : : } 179 : : % End 180 : : #endif 181 : : 182 : : void transform( const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform, bool transformZ = false ) override SIP_THROW( QgsCsException ); 183 : : void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 ) override; 184 : : 185 : : void draw( QPainter &p ) const override; 186 : : QPainterPath asQPainterPath() const override; 187 : : 188 : : bool fromWkb( QgsConstWkbPtr &wkb ) override; 189 : : bool fromWkt( const QString &wkt ) override; 190 : : 191 : : int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override; 192 : : QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override; 193 : : QString asWkt( int precision = 17 ) const override; 194 : : QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override; 195 : : QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override; 196 : : json asJsonObject( int precision = 17 ) const override SIP_SKIP; 197 : : QString asKml( int precision = 17 ) const override; 198 : : 199 : : QgsRectangle boundingBox() const override; 200 : : 201 : : QgsCoordinateSequence coordinateSequence() const override; 202 : : int nCoordinates() const override; 203 : : 204 : : 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; 205 : : bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const override; 206 : : 207 : : //low-level editing 208 : : bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) override; 209 : : bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) override; 210 : : bool deleteVertex( QgsVertexId position ) override; 211 : : 212 : : double length() const override SIP_HOLDGIL; 213 : : double area() const override SIP_HOLDGIL; 214 : : double perimeter() const override SIP_HOLDGIL; 215 : : 216 : : bool hasCurvedSegments() const override SIP_HOLDGIL; 217 : : 218 : : /** 219 : : * Returns a geometry without curves. Caller takes ownership 220 : : * \param tolerance segmentation tolerance 221 : : * \param toleranceType maximum segmentation angle or maximum difference between approximation and curve 222 : : */ 223 : : QgsAbstractGeometry *segmentize( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override SIP_FACTORY; 224 : : 225 : : double vertexAngle( QgsVertexId vertex ) const override; 226 : : double segmentLength( QgsVertexId startVertex ) const override; 227 : : int vertexCount( int part = 0, int ring = 0 ) const override; 228 : : int ringCount( int part = 0 ) const override; 229 : : int partCount() const override; 230 : : QgsPoint vertexAt( QgsVertexId id ) const override; 231 : : bool isValid( QString &error SIP_OUT, int flags = 0 ) const override; 232 : : 233 : : bool addZValue( double zValue = 0 ) override; 234 : : bool addMValue( double mValue = 0 ) override; 235 : : bool dropZValue() override; 236 : : bool dropMValue() override; 237 : : void swapXy() override; 238 : : QgsGeometryCollection *toCurveType() const override SIP_FACTORY; 239 : : 240 : : bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) override; 241 : : 242 : : #ifndef SIP_RUN 243 : : void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override; 244 : : void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) override; 245 : : 246 : : /** 247 : : * Cast the \a geom to a QgsGeometryCollection. 248 : : * Should be used by qgsgeometry_cast<QgsGeometryCollection *>( geometry ). 249 : : * 250 : : * \note Not available in Python. Objects will be automatically be converted to the appropriate target type. 251 : : * \since QGIS 3.0 252 : : */ 253 : 21736 : inline static const QgsGeometryCollection *cast( const QgsAbstractGeometry *geom ) 254 : : { 255 : 21736 : if ( geom && QgsWkbTypes::isMultiType( geom->wkbType() ) ) 256 : 21681 : return static_cast<const QgsGeometryCollection *>( geom ); 257 : 55 : return nullptr; 258 : 21736 : } 259 : : #endif 260 : : 261 : : 262 : : #ifdef SIP_RUN 263 : : 264 : : /** 265 : : * Returns the geometry at the specified ``index``. An IndexError will be raised if no geometry with the specified ``index`` exists. 266 : : * 267 : : * Indexes can be less than 0, in which case they correspond to geometries from the end of the collect. E.g. an index of -1 268 : : * corresponds to the last geometry in the collection. 269 : : * 270 : : * \since QGIS 3.6 271 : : */ 272 : : SIP_PYOBJECT __getitem__( int index ) SIP_TYPEHINT( QgsAbstractGeometry ); 273 : : % MethodCode 274 : : const int count = sipCpp->numGeometries(); 275 : : if ( a0 < -count || a0 >= count ) 276 : : { 277 : : PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) ); 278 : : sipIsErr = 1; 279 : : } 280 : : else if ( a0 >= 0 ) 281 : : { 282 : : return sipConvertFromType( sipCpp->geometryN( a0 ), sipType_QgsAbstractGeometry, NULL ); 283 : : } 284 : : else 285 : : { 286 : : return sipConvertFromType( sipCpp->geometryN( count + a0 ), sipType_QgsAbstractGeometry, NULL ); 287 : : } 288 : : % End 289 : : 290 : : /** 291 : : * Deletes the geometry at the specified ``index``. A geometry at the ``index`` must already exist or an IndexError will be raised. 292 : : * 293 : : * Indexes can be less than 0, in which case they correspond to geometries from the end of the collection. E.g. an index of -1 294 : : * corresponds to the last geometry in the collection. 295 : : * 296 : : * \since QGIS 3.6 297 : : */ 298 : : void __delitem__( int index ); 299 : : % MethodCode 300 : : const int count = sipCpp->numGeometries(); 301 : : if ( a0 >= 0 && a0 < count ) 302 : : sipCpp->removeGeometry( a0 ); 303 : : else if ( a0 < 0 && a0 >= -count ) 304 : : sipCpp->removeGeometry( count + a0 ); 305 : : else 306 : : { 307 : : PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) ); 308 : : sipIsErr = 1; 309 : : } 310 : : % End 311 : : 312 : : /** 313 : : * Iterates through all geometries in the collection. 314 : : * 315 : : * \since QGIS 3.6 316 : : */ 317 : : SIP_PYOBJECT __iter__() SIP_TYPEHINT( QgsGeometryPartIterator ); 318 : : % MethodCode 319 : : sipRes = sipConvertFromNewType( new QgsGeometryPartIterator( sipCpp ), sipType_QgsGeometryPartIterator, Py_None ); 320 : : % End 321 : : #endif 322 : : 323 : : QgsGeometryCollection *createEmptyWithSameType() const override SIP_FACTORY; 324 : : 325 : : protected: 326 : : int childCount() const override; 327 : : QgsAbstractGeometry *childGeometry( int index ) const override; 328 : : 329 : : protected: 330 : : QVector< QgsAbstractGeometry * > mGeometries; 331 : : 332 : : /** 333 : : * Returns whether child type names are omitted from Wkt representations of the collection 334 : : * \since QGIS 2.12 335 : : */ 336 : : virtual bool wktOmitChildType() const; 337 : : 338 : : /** 339 : : * Reads a collection from a WKT string. 340 : : */ 341 : : bool fromCollectionWkt( const QString &wkt, const QVector<QgsAbstractGeometry *> &subtypes, const QString &defaultChildWkbType = QString() ); 342 : : 343 : : QgsRectangle calculateBoundingBox() const override; 344 : : void clearCache() const override; 345 : : 346 : : private: 347 : : 348 : : mutable QgsRectangle mBoundingBox; 349 : : mutable bool mHasCachedValidity = false; 350 : : mutable QString mValidityFailureReason; 351 : : }; 352 : : 353 : : // clazy:excludeall=qstring-allocations 354 : : 355 : : #endif // QGSGEOMETRYCOLLECTION_H