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