QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsgeometrycollection.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgeometrycollection.cpp
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 #include "qgsgeometrycollection.h"
17 #include "qgsapplication.h"
18 #include "qgsgeometryfactory.h"
19 #include "qgsgeometryutils.h"
20 #include "qgscircularstring.h"
21 #include "qgscompoundcurve.h"
22 #include "qgslinestring.h"
23 #include "qgsmultilinestring.h"
24 #include "qgspoint.h"
25 #include "qgsmultipoint.h"
26 #include "qgspolygon.h"
27 #include "qgsmultipolygon.h"
28 #include "qgswkbptr.h"
29 #include "qgsgeos.h"
30 
31 #include <nlohmann/json.hpp>
32 #include <memory>
33 
35 {
37 }
38 
41  mBoundingBox( c.mBoundingBox ),
42  mHasCachedValidity( c.mHasCachedValidity ),
43  mValidityFailureReason( c.mValidityFailureReason )
44 {
45  int nGeoms = c.mGeometries.size();
46  mGeometries.resize( nGeoms );
47  for ( int i = 0; i < nGeoms; ++i )
48  {
49  mGeometries[i] = c.mGeometries.at( i )->clone();
50  }
51 }
52 
54 {
55  if ( &c != this )
56  {
57  clearCache();
59  int nGeoms = c.mGeometries.size();
60  mGeometries.resize( nGeoms );
61  for ( int i = 0; i < nGeoms; ++i )
62  {
63  mGeometries[i] = c.mGeometries.at( i )->clone();
64  }
65  }
66  return *this;
67 }
68 
70 {
71  clear();
72 }
73 
75 {
76  const QgsGeometryCollection *otherCollection = qgsgeometry_cast< const QgsGeometryCollection * >( &other );
77  if ( !otherCollection )
78  return false;
79 
80  if ( mWkbType != otherCollection->mWkbType )
81  return false;
82 
83  if ( mGeometries.count() != otherCollection->mGeometries.count() )
84  return false;
85 
86  for ( int i = 0; i < mGeometries.count(); ++i )
87  {
88  QgsAbstractGeometry *g1 = mGeometries.at( i );
89  QgsAbstractGeometry *g2 = otherCollection->mGeometries.at( i );
90 
91  // Quick check if the geometries are exactly the same
92  if ( g1 != g2 )
93  {
94  if ( !g1 || !g2 )
95  return false;
96 
97  // Slower check, compare the contents of the geometries
98  if ( *g1 != *g2 )
99  return false;
100  }
101  }
102 
103  return true;
104 }
105 
107 {
108  return !operator==( other );
109 }
110 
112 {
113  auto result = qgis::make_unique< QgsGeometryCollection >();
114  result->mWkbType = mWkbType;
115  return result.release();
116 }
117 
119 {
120  return new QgsGeometryCollection( *this );
121 }
122 
124 {
125  qDeleteAll( mGeometries );
126  mGeometries.clear();
127  clearCache(); //set bounding box invalid
128 }
129 
130 QgsGeometryCollection *QgsGeometryCollection::snappedToGrid( double hSpacing, double vSpacing, double dSpacing, double mSpacing ) const
131 {
132  std::unique_ptr<QgsGeometryCollection> result;
133 
134  for ( auto geom : mGeometries )
135  {
136  std::unique_ptr<QgsAbstractGeometry> gridified { geom->snappedToGrid( hSpacing, vSpacing, dSpacing, mSpacing ) };
137  if ( gridified )
138  {
139  if ( !result )
140  result = std::unique_ptr<QgsGeometryCollection> { createEmptyWithSameType() };
141 
142  result->mGeometries.append( gridified.release() );
143  }
144  }
145 
146  return result.release();
147 }
148 
149 bool QgsGeometryCollection::removeDuplicateNodes( double epsilon, bool useZValues )
150 {
151  bool result = false;
152  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
153  {
154  if ( geom->removeDuplicateNodes( epsilon, useZValues ) ) result = true;
155  }
156  return result;
157 }
158 
160 {
161  return nullptr;
162 }
163 
164 void QgsGeometryCollection::adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex, QgsVertexId &nextVertex ) const
165 {
166  if ( vertex.part < 0 || vertex.part >= mGeometries.count() )
167  {
168  previousVertex = QgsVertexId();
170  return;
171  }
172 
173  mGeometries.at( vertex.part )->adjacentVertices( vertex, previousVertex, nextVertex );
174 }
175 
177 {
178  if ( id.part < 0 || id.part >= mGeometries.count() )
179  return -1;
180 
181  int number = 0;
182  int part = 0;
183  for ( QgsAbstractGeometry *geometry : mGeometries )
184  {
185  if ( part == id.part )
186  {
187  int partNumber = geometry->vertexNumberFromVertexId( QgsVertexId( 0, id.ring, id.vertex ) );
188  if ( partNumber == -1 )
189  return -1;
190  return number + partNumber;
191  }
192  else
193  {
194  number += geometry->nCoordinates();
195  }
196 
197  part++;
198  }
199  return -1; // should not happen
200 }
201 
203 {
204  mGeometries.reserve( size );
205 }
206 
208 {
209  clearCache();
210  return mGeometries.value( n );
211 }
212 
214 {
215  if ( mGeometries.isEmpty() )
216  return true;
217 
218  for ( QgsAbstractGeometry *geometry : mGeometries )
219  {
220  if ( !geometry->isEmpty() )
221  return false;
222  }
223  return true;
224 }
225 
227 {
228  if ( !g )
229  {
230  return false;
231  }
232 
233  mGeometries.append( g );
234  clearCache(); //set bounding box invalid
235  return true;
236 }
237 
239 {
240  if ( !g )
241  {
242  return false;
243  }
244 
245  index = std::min( mGeometries.count(), index );
246 
247  mGeometries.insert( index, g );
248  clearCache(); //set bounding box invalid
249  return true;
250 }
251 
253 {
254  if ( nr >= mGeometries.size() || nr < 0 )
255  {
256  return false;
257  }
258  delete mGeometries.at( nr );
259  mGeometries.remove( nr );
260  clearCache(); //set bounding box invalid
261  return true;
262 }
263 
265 {
266  int maxDim = 0;
267  QVector< QgsAbstractGeometry * >::const_iterator it = mGeometries.constBegin();
268  for ( ; it != mGeometries.constEnd(); ++it )
269  {
270  int dim = ( *it )->dimension();
271  if ( dim > maxDim )
272  {
273  maxDim = dim;
274  }
275  }
276  return maxDim;
277 }
278 
280 {
281  return QStringLiteral( "GeometryCollection" );
282 }
283 
285 {
286  for ( QgsAbstractGeometry *g : qgis::as_const( mGeometries ) )
287  {
288  g->transform( ct, d, transformZ );
289  }
290  clearCache(); //set bounding box invalid
291 }
292 
293 void QgsGeometryCollection::transform( const QTransform &t, double zTranslate, double zScale, double mTranslate, double mScale )
294 {
295  for ( QgsAbstractGeometry *g : qgis::as_const( mGeometries ) )
296  {
297  g->transform( t, zTranslate, zScale, mTranslate, mScale );
298  }
299  clearCache(); //set bounding box invalid
300 }
301 
302 void QgsGeometryCollection::draw( QPainter &p ) const
303 {
304  QVector< QgsAbstractGeometry * >::const_iterator it = mGeometries.constBegin();
305  for ( ; it != mGeometries.constEnd(); ++it )
306  {
307  ( *it )->draw( p );
308  }
309 }
310 
312 {
313  QPainterPath p;
314  for ( const QgsAbstractGeometry *geom : mGeometries )
315  {
316  QPainterPath partPath = geom->asQPainterPath();
317  if ( !partPath.isEmpty() )
318  p.addPath( partPath );
319  }
320  return p;
321 }
322 
324 {
325  if ( !wkbPtr )
326  {
327  return false;
328  }
329 
332  return false;
333 
334  mWkbType = wkbType;
335 
336  int nGeometries = 0;
337  wkbPtr >> nGeometries;
338 
339  QVector<QgsAbstractGeometry *> geometryListBackup = mGeometries;
340  mGeometries.clear();
341  mGeometries.reserve( nGeometries );
342  for ( int i = 0; i < nGeometries; ++i )
343  {
344  std::unique_ptr< QgsAbstractGeometry > geom( QgsGeometryFactory::geomFromWkb( wkbPtr ) ); // also updates wkbPtr
345  if ( geom )
346  {
347  if ( !addGeometry( geom.release() ) )
348  {
349  qDeleteAll( mGeometries );
350  mGeometries = geometryListBackup;
351  return false;
352  }
353  }
354  }
355  qDeleteAll( geometryListBackup );
356 
357  clearCache(); //set bounding box invalid
358 
359  return true;
360 }
361 
362 bool QgsGeometryCollection::fromWkt( const QString &wkt )
363 {
364  return fromCollectionWkt( wkt, QVector<QgsAbstractGeometry *>() << new QgsPoint << new QgsLineString << new QgsPolygon
365  << new QgsCircularString << new QgsCompoundCurve
366  << new QgsCurvePolygon
367  << new QgsMultiPoint << new QgsMultiLineString
369  << new QgsMultiCurve << new QgsMultiSurface, QStringLiteral( "GeometryCollection" ) );
370 }
371 
372 int QgsGeometryCollection::wkbSize( QgsAbstractGeometry::WkbFlags flags ) const
373 {
374  int binarySize = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 );
375  for ( const QgsAbstractGeometry *geom : mGeometries )
376  {
377  if ( geom )
378  {
379  binarySize += geom->wkbSize( flags );
380  }
381  }
382 
383  return binarySize;
384 }
385 
386 QByteArray QgsGeometryCollection::asWkb( WkbFlags flags ) const
387 {
388  int countNonNull = 0;
389  for ( const QgsAbstractGeometry *geom : mGeometries )
390  {
391  if ( geom )
392  {
393  countNonNull ++;
394  }
395  }
396 
397  QByteArray wkbArray;
398  wkbArray.resize( QgsGeometryCollection::wkbSize( flags ) );
399  QgsWkbPtr wkb( wkbArray );
400  wkb << static_cast<char>( QgsApplication::endian() );
401  wkb << static_cast<quint32>( wkbType() );
402  wkb << static_cast<quint32>( countNonNull );
403  for ( const QgsAbstractGeometry *geom : mGeometries )
404  {
405  if ( geom )
406  {
407  wkb << geom->asWkb( flags );
408  }
409  }
410  return wkbArray;
411 }
412 
414 {
415  QString wkt = wktTypeStr();
416 
417  if ( isEmpty() )
418  wkt += QLatin1String( " EMPTY" );
419  else
420  {
421  wkt += QLatin1String( " (" );
422  for ( const QgsAbstractGeometry *geom : mGeometries )
423  {
424  QString childWkt = geom->asWkt( precision );
425  if ( wktOmitChildType() )
426  {
427  childWkt = childWkt.mid( childWkt.indexOf( '(' ) );
428  }
429  wkt += childWkt + ',';
430  }
431  if ( wkt.endsWith( ',' ) )
432  {
433  wkt.chop( 1 ); // Remove last ','
434  }
435  wkt += ')';
436  }
437  return wkt;
438 }
439 
440 QDomElement QgsGeometryCollection::asGml2( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
441 {
442  QDomElement elemMultiGeometry = doc.createElementNS( ns, QStringLiteral( "MultiGeometry" ) );
443  for ( const QgsAbstractGeometry *geom : mGeometries )
444  {
445  QDomElement elemGeometryMember = doc.createElementNS( ns, QStringLiteral( "geometryMember" ) );
446  elemGeometryMember.appendChild( geom->asGml2( doc, precision, ns, axisOrder ) );
447  elemMultiGeometry.appendChild( elemGeometryMember );
448  }
449  return elemMultiGeometry;
450 }
451 
452 QDomElement QgsGeometryCollection::asGml3( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
453 {
454  QDomElement elemMultiGeometry = doc.createElementNS( ns, QStringLiteral( "MultiGeometry" ) );
455  for ( const QgsAbstractGeometry *geom : mGeometries )
456  {
457  QDomElement elemGeometryMember = doc.createElementNS( ns, QStringLiteral( "geometryMember" ) );
458  elemGeometryMember.appendChild( geom->asGml3( doc, precision, ns, axisOrder ) );
459  elemMultiGeometry.appendChild( elemGeometryMember );
460  }
461  return elemMultiGeometry;
462 }
463 
465 {
466  json coordinates( json::array( ) );
467  for ( const QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
468  {
469  coordinates.push_back( geom->asJsonObject( precision ) );
470  }
471  return
472  {
473  { "type", "GeometryCollection" },
474  { "geometries", coordinates }
475  };
476 }
477 
479 {
480  QString kml;
481  kml.append( QLatin1String( "<MultiGeometry>" ) );
482  const QVector< QgsAbstractGeometry * > &geometries = mGeometries;
483  for ( const QgsAbstractGeometry *geometry : geometries )
484  {
485  kml.append( geometry->asKml( precision ) );
486  }
487  kml.append( QLatin1String( "</MultiGeometry>" ) );
488  return kml;
489 }
490 
492 {
493  if ( mBoundingBox.isNull() )
494  {
495  mBoundingBox = calculateBoundingBox();
496  }
497  return mBoundingBox;
498 }
499 
501 {
502  if ( mGeometries.empty() )
503  {
504  return QgsRectangle();
505  }
506 
507  QgsRectangle bbox = mGeometries.at( 0 )->boundingBox();
508  for ( int i = 1; i < mGeometries.size(); ++i )
509  {
510  if ( mGeometries.at( i )->isEmpty() )
511  continue;
512 
513  QgsRectangle geomBox = mGeometries.at( i )->boundingBox();
514  if ( bbox.isNull() )
515  {
516  // workaround treatment of a QgsRectangle(0,0,0,0) as a "null"/invalid rectangle
517  // if bbox is null, then the first geometry must have returned a bounding box of (0,0,0,0)
518  // so just manually include that as a point... ew.
519  geomBox.combineExtentWith( QPointF( 0, 0 ) );
520  bbox = geomBox;
521  }
522  else if ( geomBox.isNull() )
523  {
524  // ...as above... this part must have a bounding box of (0,0,0,0).
525  // if we try to combine the extent with this "null" box it will just be ignored.
526  bbox.combineExtentWith( QPointF( 0, 0 ) );
527  }
528  else
529  {
530  bbox.combineExtentWith( geomBox );
531  }
532  }
533  return bbox;
534 }
535 
537 {
538  mBoundingBox = QgsRectangle();
539  mHasCachedValidity = false;
540  mValidityFailureReason.clear();
542 }
543 
545 {
546  QgsCoordinateSequence sequence;
547  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
548  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
549  {
550  QgsCoordinateSequence geomCoords = ( *geomIt )->coordinateSequence();
551 
552  QgsCoordinateSequence::const_iterator cIt = geomCoords.constBegin();
553  for ( ; cIt != geomCoords.constEnd(); ++cIt )
554  {
555  sequence.push_back( *cIt );
556  }
557  }
558 
559  return sequence;
560 }
561 
563 {
564  int count = 0;
565 
566  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
567  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
568  {
569  count += ( *geomIt )->nCoordinates();
570  }
571 
572  return count;
573 }
574 
575 double QgsGeometryCollection::closestSegment( const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf, double epsilon ) const
576 {
577  return QgsGeometryUtils::closestSegmentFromComponents( mGeometries, QgsGeometryUtils::Part, pt, segmentPt, vertexAfter, leftOf, epsilon );
578 }
579 
581 {
582  if ( id.part < 0 )
583  {
584  id.part = 0;
585  id.ring = -1;
586  id.vertex = -1;
587  }
588  if ( mGeometries.isEmpty() )
589  {
590  return false;
591  }
592 
593  if ( id.part >= mGeometries.count() )
594  return false;
595 
596  QgsAbstractGeometry *geom = mGeometries.at( id.part );
597  if ( geom->nextVertex( id, vertex ) )
598  {
599  return true;
600  }
601  if ( ( id.part + 1 ) >= numGeometries() )
602  {
603  return false;
604  }
605  ++id.part;
606  id.ring = -1;
607  id.vertex = -1;
608  return mGeometries.at( id.part )->nextVertex( id, vertex );
609 }
610 
612 {
613  if ( position.part >= mGeometries.size() )
614  {
615  return false;
616  }
617 
618  bool success = mGeometries.at( position.part )->insertVertex( position, vertex );
619  if ( success )
620  {
621  clearCache(); //set bounding box invalid
622  }
623  return success;
624 }
625 
627 {
628  if ( position.part < 0 || position.part >= mGeometries.size() )
629  {
630  return false;
631  }
632 
633  bool success = mGeometries.at( position.part )->moveVertex( position, newPos );
634  if ( success )
635  {
636  clearCache(); //set bounding box invalid
637  }
638  return success;
639 }
640 
642 {
643  if ( position.part < 0 || position.part >= mGeometries.size() )
644  {
645  return false;
646  }
647 
648  QgsAbstractGeometry *geom = mGeometries.at( position.part );
649  if ( !geom )
650  {
651  return false;
652  }
653 
654  bool success = geom->deleteVertex( position );
655 
656  //remove geometry if no vertices left
657  if ( geom->isEmpty() )
658  {
659  removeGeometry( position.part );
660  }
661 
662  if ( success )
663  {
664  clearCache(); //set bounding box invalid
665  }
666  return success;
667 }
668 
670 {
671  double length = 0.0;
672  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
673  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
674  {
675  length += ( *geomIt )->length();
676  }
677  return length;
678 }
679 
681 {
682  double area = 0.0;
683  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
684  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
685  {
686  area += ( *geomIt )->area();
687  }
688  return area;
689 }
690 
692 {
693  double perimeter = 0.0;
694  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
695  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
696  {
697  perimeter += ( *geomIt )->perimeter();
698  }
699  return perimeter;
700 }
701 
702 bool QgsGeometryCollection::fromCollectionWkt( const QString &wkt, const QVector<QgsAbstractGeometry *> &subtypes, const QString &defaultChildWkbType )
703 {
704  clear();
705 
706  QPair<QgsWkbTypes::Type, QString> parts = QgsGeometryUtils::wktReadBlock( wkt );
707 
709  {
710  qDeleteAll( subtypes );
711  return false;
712  }
713  mWkbType = parts.first;
714 
715  QString secondWithoutParentheses = parts.second;
716  secondWithoutParentheses = secondWithoutParentheses.remove( '(' ).remove( ')' ).simplified().remove( ' ' );
717  if ( ( parts.second.compare( QLatin1String( "EMPTY" ), Qt::CaseInsensitive ) == 0 ) ||
718  secondWithoutParentheses.isEmpty() )
719  return true;
720 
721  QString defChildWkbType = QStringLiteral( "%1%2%3 " ).arg( defaultChildWkbType, is3D() ? QStringLiteral( "Z" ) : QString(), isMeasure() ? QStringLiteral( "M" ) : QString() );
722 
723  const QStringList blocks = QgsGeometryUtils::wktGetChildBlocks( parts.second, defChildWkbType );
724  for ( const QString &childWkt : blocks )
725  {
726  QPair<QgsWkbTypes::Type, QString> childParts = QgsGeometryUtils::wktReadBlock( childWkt );
727 
728  bool success = false;
729  for ( const QgsAbstractGeometry *geom : subtypes )
730  {
731  if ( QgsWkbTypes::flatType( childParts.first ) == QgsWkbTypes::flatType( geom->wkbType() ) )
732  {
733  mGeometries.append( geom->clone() );
734  if ( mGeometries.back()->fromWkt( childWkt ) )
735  {
736  success = true;
737  break;
738  }
739  }
740  }
741  if ( !success )
742  {
743  clear();
744  qDeleteAll( subtypes );
745  return false;
746  }
747  }
748  qDeleteAll( subtypes );
749 
750  //scan through geometries and check if dimensionality of geometries is different to collection.
751  //if so, update the type dimensionality of the collection to match
752  bool hasZ = false;
753  bool hasM = false;
754  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
755  {
756  hasZ = hasZ || geom->is3D();
757  hasM = hasM || geom->isMeasure();
758  if ( hasZ && hasM )
759  break;
760  }
761  if ( hasZ )
762  addZValue( 0 );
763  if ( hasM )
764  addMValue( 0 );
765 
766  return true;
767 }
768 
770 {
771  QVector< QgsAbstractGeometry * >::const_iterator it = mGeometries.constBegin();
772  for ( ; it != mGeometries.constEnd(); ++it )
773  {
774  if ( ( *it )->hasCurvedSegments() )
775  {
776  return true;
777  }
778  }
779  return false;
780 }
781 
783 {
784  std::unique_ptr< QgsAbstractGeometry > geom( QgsGeometryFactory::geomFromWkbType( QgsWkbTypes::linearType( mWkbType ) ) );
785  QgsGeometryCollection *geomCollection = qgsgeometry_cast<QgsGeometryCollection *>( geom.get() );
786  if ( !geomCollection )
787  {
788  return clone();
789  }
790 
791  geomCollection->reserve( mGeometries.size() );
792  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
793  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
794  {
795  geomCollection->addGeometry( ( *geomIt )->segmentize( tolerance, toleranceType ) );
796  }
797  return geom.release();
798 }
799 
801 {
802  if ( vertex.part < 0 || vertex.part >= mGeometries.size() )
803  {
804  return 0.0;
805  }
806 
807  QgsAbstractGeometry *geom = mGeometries[vertex.part];
808  if ( !geom )
809  {
810  return 0.0;
811  }
812 
813  return geom->vertexAngle( vertex );
814 }
815 
817 {
818  if ( startVertex.part < 0 || startVertex.part >= mGeometries.size() )
819  {
820  return 0.0;
821  }
822 
823  const QgsAbstractGeometry *geom = mGeometries[startVertex.part];
824  if ( !geom )
825  {
826  return 0.0;
827  }
828 
829  return geom->segmentLength( startVertex );
830 }
831 
832 int QgsGeometryCollection::vertexCount( int part, int ring ) const
833 {
834  if ( part < 0 || part >= mGeometries.size() )
835  {
836  return 0;
837  }
838 
839  return mGeometries[part]->vertexCount( 0, ring );
840 }
841 
842 int QgsGeometryCollection::ringCount( int part ) const
843 {
844  if ( part < 0 || part >= mGeometries.size() )
845  {
846  return 0;
847  }
848 
849  return mGeometries[part]->ringCount();
850 }
851 
853 {
854  return mGeometries.size();
855 }
856 
858 {
859  return mGeometries[id.part]->vertexAt( id );
860 }
861 
862 bool QgsGeometryCollection::isValid( QString &error, int flags ) const
863 {
864  if ( flags == 0 && mHasCachedValidity )
865  {
866  // use cached validity results
867  error = mValidityFailureReason;
868  return error.isEmpty();
869  }
870 
871  QgsGeos geos( this );
872  bool res = geos.isValid( &error, flags & QgsGeometry::FlagAllowSelfTouchingHoles, nullptr );
873  if ( flags == 0 )
874  {
875  mValidityFailureReason = !res ? error : QString();
876  mHasCachedValidity = true;
877  }
878  return res;
879 }
880 
881 bool QgsGeometryCollection::addZValue( double zValue )
882 {
883  if ( QgsWkbTypes::hasZ( mWkbType ) )
884  return false;
885 
887 
888  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
889  {
890  geom->addZValue( zValue );
891  }
892  clearCache();
893  return true;
894 }
895 
896 bool QgsGeometryCollection::addMValue( double mValue )
897 {
898  if ( QgsWkbTypes::hasM( mWkbType ) )
899  return false;
900 
902 
903  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
904  {
905  geom->addMValue( mValue );
906  }
907  clearCache();
908  return true;
909 }
910 
911 
913 {
915  return false;
916 
918  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
919  {
920  geom->dropZValue();
921  }
922  clearCache();
923  return true;
924 }
925 
927 {
929  return false;
930 
932  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
933  {
934  geom->dropMValue();
935  }
936  clearCache();
937  return true;
938 }
939 
940 void QgsGeometryCollection::filterVertices( const std::function<bool ( const QgsPoint & )> &filter )
941 {
942  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
943  {
944  if ( geom )
945  geom->filterVertices( filter );
946  }
947  clearCache();
948 }
949 
950 void QgsGeometryCollection::transformVertices( const std::function<QgsPoint( const QgsPoint & )> &transform )
951 {
952  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
953  {
954  if ( geom )
955  geom->transformVertices( transform );
956  }
957  clearCache();
958 }
959 
961 {
962  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
963  {
964  if ( geom )
965  geom->swapXy();
966  }
967  clearCache();
968 }
969 
971 {
972  std::unique_ptr< QgsGeometryCollection > newCollection( new QgsGeometryCollection() );
973  newCollection->reserve( mGeometries.size() );
974  for ( QgsAbstractGeometry *geom : mGeometries )
975  {
976  newCollection->addGeometry( geom->toCurveType() );
977  }
978  return newCollection.release();
979 }
980 
982 {
983  return false;
984 }
985 
987 {
988  return mGeometries.count();
989 }
990 
992 {
993  if ( index < 0 || index > mGeometries.count() )
994  return nullptr;
995  return mGeometries.at( index );
996 }
qgspolygon.h
QgsVertexId::part
int part
Part number.
Definition: qgsabstractgeometry.h:1131
QgsCoordinateSequence
QVector< QgsRingSequence > QgsCoordinateSequence
Definition: qgsabstractgeometry.h:51
QgsGeometryCollection::clearCache
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
Definition: qgsgeometrycollection.cpp:536
QgsGeometryCollection::insertGeometry
virtual bool insertGeometry(QgsAbstractGeometry *g, int index)
Inserts a geometry before a specified index and takes ownership.
Definition: qgsgeometrycollection.cpp:238
QgsGeometryCollection::isEmpty
bool isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
Definition: qgsgeometrycollection.cpp:213
QgsGeometryCollection::childGeometry
QgsAbstractGeometry * childGeometry(int index) const override
Returns pointer to child geometry (for geometries with child geometries - i.e.
Definition: qgsgeometrycollection.cpp:991
QgsGeometryCollection::deleteVertex
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
Definition: qgsgeometrycollection.cpp:641
QgsWkbTypes::dropM
static Type dropM(Type type) SIP_HOLDGIL
Drops the m dimension (if present) for a WKB type and returns the new type.
Definition: qgswkbtypes.h:1213
QgsAbstractGeometry::clearCache
virtual void clearCache() const
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
Definition: qgsabstractgeometry.cpp:112
QgsGeometryCollection::asJsonObject
json asJsonObject(int precision=17) const override
Returns a json object representation of the geometry.
Definition: qgsgeometrycollection.cpp:464
QgsGeometryCollection::fromWkt
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
Definition: qgsgeometrycollection.cpp:362
QgsGeometryCollection::dimension
int dimension() const override SIP_HOLDGIL
Returns the inherent dimension of the geometry.
Definition: qgsgeometrycollection.cpp:264
QgsGeometryCollection::hasCurvedSegments
bool hasCurvedSegments() const override SIP_HOLDGIL
Returns true if the geometry contains curved segments.
Definition: qgsgeometrycollection.cpp:769
QgsRectangle::combineExtentWith
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
Definition: qgsrectangle.h:359
QgsGeometryCollection::geometryType
QString geometryType() const override SIP_HOLDGIL
Returns a unique string representing the geometry type.
Definition: qgsgeometrycollection.cpp:279
QgsPolygon
Polygon geometry type.
Definition: qgspolygon.h:34
qgslinestring.h
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:38
QgsGeometryCollection::nCoordinates
int nCoordinates() const override
Returns the number of nodes contained in the geometry.
Definition: qgsgeometrycollection.cpp:562
qgswkbptr.h
qgsgeometryfactory.h
qgscompoundcurve.h
QgsWkbTypes::flatType
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:702
QgsGeometryFactory::geomFromWkb
static std::unique_ptr< QgsAbstractGeometry > geomFromWkb(QgsConstWkbPtr &wkb)
Construct geometry from a WKB string.
Definition: qgsgeometryfactory.cpp:34
QgsCurvePolygon
Curve polygon geometry type.
Definition: qgscurvepolygon.h:35
QgsAbstractGeometry::parts
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry.
Definition: qgsabstractgeometry.cpp:271
QgsCoordinateTransform::TransformDirection
TransformDirection
Enum used to indicate the direction (forward or inverse) of the transform.
Definition: qgscoordinatetransform.h:59
QgsGeometryCollection::asGml2
QDomElement asGml2(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const override
Returns a GML2 representation of the geometry.
Definition: qgsgeometrycollection.cpp:440
geos
Contains geos related utilities and functions.
Definition: qgsgeos.h:42
QgsGeometryCollection::area
double area() const override SIP_HOLDGIL
Returns the planar, 2-dimensional area of the geometry.
Definition: qgsgeometrycollection.cpp:680
QgsMultiLineString
Multi line string geometry collection.
Definition: qgsmultilinestring.h:32
QgsWkbTypes::addZ
static Type addZ(Type type) SIP_HOLDGIL
Adds the z dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1139
qgsmultipoint.h
QgsGeometryCollection::vertexAt
QgsPoint vertexAt(QgsVertexId id) const override
Returns the point corresponding to a specified vertex id.
Definition: qgsgeometrycollection.cpp:857
QgsAbstractGeometry::wktTypeStr
QString wktTypeStr() const
Returns the WKT type string of the geometry.
Definition: qgsabstractgeometry.cpp:147
QgsGeometryCollection::mGeometries
QVector< QgsAbstractGeometry * > mGeometries
Definition: qgsgeometrycollection.h:327
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
QgsGeometryCollection::asQPainterPath
QPainterPath asQPainterPath() const override
Returns the geometry represented as a QPainterPath.
Definition: qgsgeometrycollection.cpp:311
QgsGeometryCollection::calculateBoundingBox
QgsRectangle calculateBoundingBox() const override
Default calculator for the minimal bounding box for the geometry.
Definition: qgsgeometrycollection.cpp:500
QgsAbstractGeometry::SegmentationToleranceType
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
Definition: qgsabstractgeometry.h:115
qgspoint.h
QgsAbstractGeometry::mWkbType
QgsWkbTypes::Type mWkbType
Definition: qgsabstractgeometry.h:1030
QgsMultiSurface
Multi surface geometry collection.
Definition: qgsmultisurface.h:33
QgsGeometryCollection::length
double length() const override SIP_HOLDGIL
Returns the planar, 2-dimensional length of the geometry.
Definition: qgsgeometrycollection.cpp:669
QgsGeometryCollection::asWkb
QByteArray asWkb(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
Definition: qgsgeometrycollection.cpp:386
QgsGeometryCollection::toCurveType
QgsGeometryCollection * toCurveType() const override
Returns the geometry converted to the more generic curve type.
Definition: qgsgeometrycollection.cpp:970
QgsLineString
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:44
QgsGeometryCollection::vertexCount
int vertexCount(int part=0, int ring=0) const override
Returns the number of vertices of which this geometry is built.
Definition: qgsgeometrycollection.cpp:832
QgsGeometryCollection::addMValue
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
Definition: qgsgeometrycollection.cpp:896
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QgsGeometryCollection::filterVertices
void filterVertices(const std::function< bool(const QgsPoint &) > &filter) override
Filters the vertices from the geometry in place, removing any which do not return true for the filter...
Definition: qgsgeometrycollection.cpp:940
QgsGeometryCollection::vertexNumberFromVertexId
int vertexNumberFromVertexId(QgsVertexId id) const override
Returns the vertex number corresponding to a vertex id.
Definition: qgsgeometrycollection.cpp:176
QgsGeometryCollection::numGeometries
int numGeometries() const SIP_HOLDGIL
Returns the number of geometries within the collection.
Definition: qgsgeometrycollection.h:57
QgsGeometryCollection::boundary
QgsAbstractGeometry * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
Definition: qgsgeometrycollection.cpp:159
QgsGeometryCollection::operator==
bool operator==(const QgsAbstractGeometry &other) const override
Definition: qgsgeometrycollection.cpp:74
QgsGeometryCollection::nextVertex
bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const override
Returns next vertex id and coordinates.
Definition: qgsgeometrycollection.cpp:580
qgsapplication.h
QgsAbstractGeometry::isMeasure
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
Definition: qgsabstractgeometry.h:215
QgsGeometryCollection::closestSegment
double closestSegment(const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf=nullptr, double epsilon=4 *std::numeric_limits< double >::epsilon()) const override
Searches for the closest segment of the geometry to a given point.
Definition: qgsgeometrycollection.cpp:575
MathUtils::leftOf
double ANALYSIS_EXPORT leftOf(const QgsPoint &thepoint, const QgsPoint *p1, const QgsPoint *p2)
Returns whether 'thepoint' is left or right of the line from 'p1' to 'p2'. Negative values mean left ...
Definition: MathUtils.cpp:292
QgsGeometryCollection::createEmptyWithSameType
QgsGeometryCollection * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
Definition: qgsgeometrycollection.cpp:111
QgsAbstractGeometry::vertexAngle
virtual double vertexAngle(QgsVertexId vertex) const =0
Returns approximate angle at a vertex.
QgsGeometryCollection::fromWkb
bool fromWkb(QgsConstWkbPtr &wkb) override
Sets the geometry from a WKB string.
Definition: qgsgeometrycollection.cpp:323
QgsGeometryCollection::clone
QgsGeometryCollection * clone() const override
Clones the geometry by performing a deep copy.
Definition: qgsgeometrycollection.cpp:118
QgsGeometryCollection::QgsGeometryCollection
QgsGeometryCollection() SIP_HOLDGIL
Constructor for an empty geometry collection.
Definition: qgsgeometrycollection.cpp:34
QgsWkbTypes::addM
static Type addM(Type type) SIP_HOLDGIL
Adds the m dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1164
precision
int precision
Definition: qgswfsgetfeature.cpp:49
QgsGeometryCollection
Geometry collection.
Definition: qgsgeometrycollection.h:36
QgsGeometryCollection::partCount
int partCount() const override
Returns count of parts contained in the geometry.
Definition: qgsgeometrycollection.cpp:852
QgsGeometryUtils::closestSegmentFromComponents
static double closestSegmentFromComponents(T &container, ComponentType ctype, const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf, double epsilon)
Definition: qgsgeometryutils.h:739
QgsCircularString
Circular string geometry type.
Definition: qgscircularstring.h:35
QgsAbstractGeometry::wkbType
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
Definition: qgsabstractgeometry.h:193
qgsmultipolygon.h
QgsAbstractGeometry::AxisOrder
AxisOrder
Axis order for GML generation.
Definition: qgsabstractgeometry.h:133
QgsMultiCurve
Multi curve geometry collection.
Definition: qgsmulticurve.h:30
QgsGeometryCollection::~QgsGeometryCollection
~QgsGeometryCollection() override
Definition: qgsgeometrycollection.cpp:69
QgsWkbTypes::linearType
static Type linearType(Type type) SIP_HOLDGIL
Returns the linear type for a WKB type.
Definition: qgswkbtypes.h:592
QgsConstWkbPtr
Definition: qgswkbptr.h:128
QgsGeometry::FlagAllowSelfTouchingHoles
@ FlagAllowSelfTouchingHoles
Indicates that self-touching holes are permitted. OGC validity states that self-touching holes are NO...
Definition: qgsgeometry.h:369
QgsWkbTypes::GeometryCollection
@ GeometryCollection
Definition: qgswkbtypes.h:79
QgsGeometryCollection::moveVertex
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
Definition: qgsgeometrycollection.cpp:626
QgsGeometryCollection::addGeometry
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
Definition: qgsgeometrycollection.cpp:226
QgsGeometryCollection::ringCount
int ringCount(int part=0) const override
Returns the number of rings of which this geometry is built.
Definition: qgsgeometrycollection.cpp:842
QgsGeometryCollection::asKml
QString asKml(int precision=17) const override
Returns a KML representation of the geometry.
Definition: qgsgeometrycollection.cpp:478
QgsGeos
Does vector analysis using the geos library and handles import, export, exception handling*.
Definition: qgsgeos.h:104
QgsGeometryCollection::operator!=
bool operator!=(const QgsAbstractGeometry &other) const override
Definition: qgsgeometrycollection.cpp:106
QgsAbstractGeometry::deleteVertex
virtual bool deleteVertex(QgsVertexId position)=0
Deletes a vertex within the geometry.
QgsGeometryCollection::perimeter
double perimeter() const override SIP_HOLDGIL
Returns the planar, 2-dimensional perimeter of the geometry.
Definition: qgsgeometrycollection.cpp:691
QgsWkbTypes::hasM
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:1093
QgsGeometryCollection::fromCollectionWkt
bool fromCollectionWkt(const QString &wkt, const QVector< QgsAbstractGeometry * > &subtypes, const QString &defaultChildWkbType=QString())
Reads a collection from a WKT string.
Definition: qgsgeometrycollection.cpp:702
QgsGeometryCollection::insertVertex
bool insertVertex(QgsVertexId position, const QgsPoint &vertex) override
Inserts a vertex into the geometry.
Definition: qgsgeometrycollection.cpp:611
QgsGeometryCollection::asWkt
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
Definition: qgsgeometrycollection.cpp:413
QgsApplication::endian
static endian_t endian()
Returns whether this machine uses big or little endian.
Definition: qgsapplication.cpp:1250
QgsGeometryCollection::removeDuplicateNodes
bool removeDuplicateNodes(double epsilon=4 *std::numeric_limits< double >::epsilon(), bool useZValues=false) override
Removes duplicate nodes from the geometry, wherever removing the nodes does not result in a degenerat...
Definition: qgsgeometrycollection.cpp:149
QgsGeometryCollection::wktOmitChildType
virtual bool wktOmitChildType() const
Returns whether child type names are omitted from Wkt representations of the collection.
Definition: qgsgeometrycollection.cpp:981
QgsWkbTypes::dropZ
static Type dropZ(Type type) SIP_HOLDGIL
Drops the z dimension (if present) for a WKB type and returns the new type.
Definition: qgswkbtypes.h:1195
QgsMultiPolygon
Multi polygon geometry collection.
Definition: qgsmultipolygon.h:32
QgsGeometryCollection::wkbSize
int wkbSize(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
Returns the length of the QByteArray returned by asWkb()
Definition: qgsgeometrycollection.cpp:372
QgsGeometryCollection::asGml3
QDomElement asGml3(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const override
Returns a GML3 representation of the geometry.
Definition: qgsgeometrycollection.cpp:452
QgsGeometryCollection::dropMValue
bool dropMValue() override
Drops any measure values which exist in the geometry.
Definition: qgsgeometrycollection.cpp:926
QgsGeometryCollection::segmentize
QgsAbstractGeometry * segmentize(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a geometry without curves.
Definition: qgsgeometrycollection.cpp:782
QgsWkbPtr
Definition: qgswkbptr.h:43
QgsAbstractGeometry::isEmpty
virtual bool isEmpty() const
Returns true if the geometry is empty.
Definition: qgsabstractgeometry.cpp:298
qgscircularstring.h
QgsMultiPoint
Multi point geometry collection.
Definition: qgsmultipoint.h:30
QgsAbstractGeometry
Abstract base class for all geometries.
Definition: qgsabstractgeometry.h:74
qgsgeometryutils.h
QgsAbstractGeometry::is3D
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
Definition: qgsabstractgeometry.h:206
QgsGeometryCollection::isValid
bool isValid(QString &error, int flags=0) const override
Checks validity of the geometry, and returns true if the geometry is valid.
Definition: qgsgeometrycollection.cpp:862
QgsGeometryCollection::transformVertices
void transformVertices(const std::function< QgsPoint(const QgsPoint &) > &transform) override
Transforms the vertices from the geometry in place, applying the transform function to every vertex.
Definition: qgsgeometrycollection.cpp:950
QgsGeometryUtils::wktGetChildBlocks
static QStringList wktGetChildBlocks(const QString &wkt, const QString &defaultType=QString())
Parses a WKT string and returns of list of blocks contained in the WKT.
Definition: qgsgeometryutils.cpp:1340
QgsGeometryCollection::vertexAngle
double vertexAngle(QgsVertexId vertex) const override
Returns approximate angle at a vertex.
Definition: qgsgeometrycollection.cpp:800
QgsGeometryCollection::geometryN
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
Definition: qgsgeometrycollection.h:85
QgsGeometryCollection::swapXy
void swapXy() override
Swaps the x and y coordinates from the geometry.
Definition: qgsgeometrycollection.cpp:960
QgsAbstractGeometry::operator=
QgsAbstractGeometry & operator=(const QgsAbstractGeometry &geom)
Definition: qgsabstractgeometry.cpp:33
c
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
Definition: porting_processing.dox:1
QgsGeometryCollection::dropZValue
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
Definition: qgsgeometrycollection.cpp:912
QgsAbstractGeometry::segmentLength
virtual double segmentLength(QgsVertexId startVertex) const =0
Returns the length of the segment of the geometry which begins at startVertex.
QgsVertexId
Utility class for identifying a unique vertex within a geometry.
Definition: qgsabstractgeometry.h:1059
QgsGeometryCollection::childCount
int childCount() const override
Returns number of child geometries (for geometries with child geometries) or child points (for geomet...
Definition: qgsgeometrycollection.cpp:986
QgsGeometryCollection::addZValue
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
Definition: qgsgeometrycollection.cpp:881
QgsGeometryCollection::clear
void clear() override
Clears the geometry, ie reset it to a null geometry.
Definition: qgsgeometrycollection.cpp:123
QgsGeometryCollection::segmentLength
double segmentLength(QgsVertexId startVertex) const override
Returns the length of the segment of the geometry which begins at startVertex.
Definition: qgsgeometrycollection.cpp:816
QgsGeometryCollection::operator=
QgsGeometryCollection & operator=(const QgsGeometryCollection &c)
Definition: qgsgeometrycollection.cpp:53
QgsWkbTypes::hasZ
static bool hasZ(Type type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:1043
QgsGeometryCollection::snappedToGrid
QgsGeometryCollection * snappedToGrid(double hSpacing, double vSpacing, double dSpacing=0, double mSpacing=0) const override
Makes a new geometry with all the points or vertices snapped to the closest point of the grid.
Definition: qgsgeometrycollection.cpp:130
qgsgeometrycollection.h
QgsConstWkbPtr::readHeader
QgsWkbTypes::Type readHeader() const
readHeader
Definition: qgswkbptr.cpp:54
QgsGeometryUtils::wktReadBlock
static QPair< QgsWkbTypes::Type, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
Definition: qgsgeometryutils.cpp:1306
QgsGeometryCollection::boundingBox
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the geometry.
Definition: qgsgeometrycollection.cpp:491
QgsGeometryCollection::adjacentVertices
void adjacentVertices(QgsVertexId vertex, QgsVertexId &previousVertex, QgsVertexId &nextVertex) const override
Returns the vertices adjacent to a specified vertex within a geometry.
Definition: qgsgeometrycollection.cpp:164
QgsGeometryCollection::coordinateSequence
QgsCoordinateSequence coordinateSequence() const override
Retrieves the sequence of geometries, rings and nodes.
Definition: qgsgeometrycollection.cpp:544
QgsGeometryCollection::reserve
void reserve(int size) SIP_HOLDGIL
Attempts to allocate memory for at least size geometries.
Definition: qgsgeometrycollection.cpp:202
QgsGeometryCollection::draw
void draw(QPainter &p) const override
Draws the geometry using the specified QPainter.
Definition: qgsgeometrycollection.cpp:302
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:53
QgsGeometryFactory::geomFromWkbType
static std::unique_ptr< QgsAbstractGeometry > geomFromWkbType(QgsWkbTypes::Type t)
Returns empty geometry from wkb type.
Definition: qgsgeometryfactory.cpp:228
QgsGeometryCollection::removeGeometry
virtual bool removeGeometry(int nr)
Removes a geometry from the collection.
Definition: qgsgeometrycollection.cpp:252
QgsGeometryUtils::Part
@ Part
Definition: qgsgeometryutils.h:735
QgsAbstractGeometry::nextVertex
virtual bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const =0
Returns next vertex id and coordinates.
QgsRectangle::isNull
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:447
QgsGeometryCollection::transform
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) override SIP_THROW(QgsCsException)
Transforms the geometry using a coordinate transform.
Definition: qgsgeometrycollection.cpp:284
qgsmultilinestring.h
QgsCompoundCurve
Compound curve geometry type.
Definition: qgscompoundcurve.h:32
qgsgeos.h