QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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 <memory>
30 
32 {
34 }
35 
37 {
38  int nGeoms = c.mGeometries.size();
39  mGeometries.resize( nGeoms );
40  for ( int i = 0; i < nGeoms; ++i )
41  {
42  mGeometries[i] = c.mGeometries.at( i )->clone();
43  }
44 }
45 
47 {
48  if ( &c != this )
49  {
50  clearCache();
52  int nGeoms = c.mGeometries.size();
53  mGeometries.resize( nGeoms );
54  for ( int i = 0; i < nGeoms; ++i )
55  {
56  mGeometries[i] = c.mGeometries.at( i )->clone();
57  }
58  }
59  return *this;
60 }
61 
63 {
64  clear();
65 }
66 
68 {
69  const QgsGeometryCollection *otherCollection = qgsgeometry_cast< const QgsGeometryCollection * >( &other );
70  if ( !otherCollection )
71  return false;
72 
73  if ( mWkbType != otherCollection->mWkbType )
74  return false;
75 
76  if ( mGeometries.count() != otherCollection->mGeometries.count() )
77  return false;
78 
79  for ( int i = 0; i < mGeometries.count(); ++i )
80  {
81  QgsAbstractGeometry *g1 = mGeometries.at( i );
82  QgsAbstractGeometry *g2 = otherCollection->mGeometries.at( i );
83 
84  // Quick check if the geometries are exactly the same
85  if ( g1 != g2 )
86  {
87  if ( !g1 || !g2 )
88  return false;
89 
90  // Slower check, compare the contents of the geometries
91  if ( *g1 != *g2 )
92  return false;
93  }
94  }
95 
96  return true;
97 }
98 
100 {
101  return !operator==( other );
102 }
103 
105 {
106  auto result = qgis::make_unique< QgsGeometryCollection >();
107  result->mWkbType = mWkbType;
108  return result.release();
109 }
110 
112 {
113  return new QgsGeometryCollection( *this );
114 }
115 
117 {
118  qDeleteAll( mGeometries );
119  mGeometries.clear();
120  clearCache(); //set bounding box invalid
121 }
122 
123 QgsGeometryCollection *QgsGeometryCollection::snappedToGrid( double hSpacing, double vSpacing, double dSpacing, double mSpacing ) const
124 {
125  std::unique_ptr<QgsGeometryCollection> result;
126 
127  for ( auto geom : mGeometries )
128  {
129  std::unique_ptr<QgsAbstractGeometry> gridified { geom->snappedToGrid( hSpacing, vSpacing, dSpacing, mSpacing ) };
130  if ( gridified )
131  {
132  if ( !result )
133  result = std::unique_ptr<QgsGeometryCollection> { createEmptyWithSameType() };
134 
135  result->mGeometries.append( gridified.release() );
136  }
137  }
138 
139  return result.release();
140 }
141 
142 bool QgsGeometryCollection::removeDuplicateNodes( double epsilon, bool useZValues )
143 {
144  bool result = false;
145  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
146  {
147  result = result || geom->removeDuplicateNodes( epsilon, useZValues );
148  }
149  return result;
150 }
151 
153 {
154  return nullptr;
155 }
156 
158 {
159  if ( vertex.part < 0 || vertex.part >= mGeometries.count() )
160  {
161  previousVertex = QgsVertexId();
162  nextVertex = QgsVertexId();
163  return;
164  }
165 
166  mGeometries.at( vertex.part )->adjacentVertices( vertex, previousVertex, nextVertex );
167 }
168 
170 {
171  if ( id.part < 0 || id.part >= mGeometries.count() )
172  return -1;
173 
174  int number = 0;
175  int part = 0;
176  for ( QgsAbstractGeometry *geometry : mGeometries )
177  {
178  if ( part == id.part )
179  {
180  int partNumber = geometry->vertexNumberFromVertexId( QgsVertexId( 0, id.ring, id.vertex ) );
181  if ( partNumber == -1 )
182  return -1;
183  return number + partNumber;
184  }
185  else
186  {
187  number += geometry->nCoordinates();
188  }
189 
190  part++;
191  }
192  return -1; // should not happen
193 }
194 
196 {
197  clearCache();
198  return mGeometries.value( n );
199 }
200 
202 {
203  if ( mGeometries.isEmpty() )
204  return true;
205 
206  for ( QgsAbstractGeometry *geometry : mGeometries )
207  {
208  if ( !geometry->isEmpty() )
209  return false;
210  }
211  return true;
212 }
213 
215 {
216  if ( !g )
217  {
218  return false;
219  }
220 
221  mGeometries.append( g );
222  clearCache(); //set bounding box invalid
223  return true;
224 }
225 
227 {
228  if ( !g )
229  {
230  return false;
231  }
232 
233  index = std::min( mGeometries.count(), index );
234 
235  mGeometries.insert( index, g );
236  clearCache(); //set bounding box invalid
237  return true;
238 }
239 
241 {
242  if ( nr >= mGeometries.size() || nr < 0 )
243  {
244  return false;
245  }
246  delete mGeometries.at( nr );
247  mGeometries.remove( nr );
248  clearCache(); //set bounding box invalid
249  return true;
250 }
251 
253 {
254  int maxDim = 0;
255  QVector< QgsAbstractGeometry * >::const_iterator it = mGeometries.constBegin();
256  for ( ; it != mGeometries.constEnd(); ++it )
257  {
258  int dim = ( *it )->dimension();
259  if ( dim > maxDim )
260  {
261  maxDim = dim;
262  }
263  }
264  return maxDim;
265 }
266 
268 {
269  return QStringLiteral( "GeometryCollection" );
270 }
271 
273 {
274  for ( QgsAbstractGeometry *g : qgis::as_const( mGeometries ) )
275  {
276  g->transform( ct, d, transformZ );
277  }
278  clearCache(); //set bounding box invalid
279 }
280 
281 void QgsGeometryCollection::transform( const QTransform &t, double zTranslate, double zScale, double mTranslate, double mScale )
282 {
283  for ( QgsAbstractGeometry *g : qgis::as_const( mGeometries ) )
284  {
285  g->transform( t, zTranslate, zScale, mTranslate, mScale );
286  }
287  clearCache(); //set bounding box invalid
288 }
289 
290 void QgsGeometryCollection::draw( QPainter &p ) const
291 {
292  QVector< QgsAbstractGeometry * >::const_iterator it = mGeometries.constBegin();
293  for ( ; it != mGeometries.constEnd(); ++it )
294  {
295  ( *it )->draw( p );
296  }
297 }
298 
300 {
301  if ( !wkbPtr )
302  {
303  return false;
304  }
305 
308  return false;
309 
310  mWkbType = wkbType;
311 
312  int nGeometries = 0;
313  wkbPtr >> nGeometries;
314 
315  QVector<QgsAbstractGeometry *> geometryListBackup = mGeometries;
316  mGeometries.clear();
317  for ( int i = 0; i < nGeometries; ++i )
318  {
319  std::unique_ptr< QgsAbstractGeometry > geom( QgsGeometryFactory::geomFromWkb( wkbPtr ) ); // also updates wkbPtr
320  if ( geom )
321  {
322  if ( !addGeometry( geom.release() ) )
323  {
324  qDeleteAll( mGeometries );
325  mGeometries = geometryListBackup;
326  return false;
327  }
328  }
329  }
330  qDeleteAll( geometryListBackup );
331 
332  clearCache(); //set bounding box invalid
333 
334  return true;
335 }
336 
337 bool QgsGeometryCollection::fromWkt( const QString &wkt )
338 {
339  return fromCollectionWkt( wkt, QVector<QgsAbstractGeometry *>() << new QgsPoint << new QgsLineString << new QgsPolygon
340  << new QgsCircularString << new QgsCompoundCurve
341  << new QgsCurvePolygon
342  << new QgsMultiPoint << new QgsMultiLineString
344  << new QgsMultiCurve << new QgsMultiSurface, QStringLiteral( "GeometryCollection" ) );
345 }
346 
348 {
349  int binarySize = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 );
350  QVector<QByteArray> wkbForGeometries;
351  for ( const QgsAbstractGeometry *geom : mGeometries )
352  {
353  if ( geom )
354  {
355  QByteArray wkb( geom->asWkb() );
356  binarySize += wkb.length();
357  wkbForGeometries << wkb;
358  }
359  }
360 
361  QByteArray wkbArray;
362  wkbArray.resize( binarySize );
363  QgsWkbPtr wkb( wkbArray );
364  wkb << static_cast<char>( QgsApplication::endian() );
365  wkb << static_cast<quint32>( wkbType() );
366  wkb << static_cast<quint32>( wkbForGeometries.count() );
367  for ( const QByteArray &wkbForGeometry : qgis::as_const( wkbForGeometries ) )
368  {
369  wkb << wkbForGeometry;
370  }
371  return wkbArray;
372 }
373 
375 {
376  QString wkt = wktTypeStr() + " (";
377  for ( const QgsAbstractGeometry *geom : mGeometries )
378  {
379  QString childWkt = geom->asWkt( precision );
380  if ( wktOmitChildType() )
381  {
382  childWkt = childWkt.mid( childWkt.indexOf( '(' ) );
383  }
384  wkt += childWkt + ',';
385  }
386  if ( wkt.endsWith( ',' ) )
387  {
388  wkt.chop( 1 ); // Remove last ','
389  }
390  wkt += ')';
391  return wkt;
392 }
393 
394 QDomElement QgsGeometryCollection::asGml2( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
395 {
396  QDomElement elemMultiGeometry = doc.createElementNS( ns, QStringLiteral( "MultiGeometry" ) );
397  for ( const QgsAbstractGeometry *geom : mGeometries )
398  {
399  QDomElement elemGeometryMember = doc.createElementNS( ns, QStringLiteral( "geometryMember" ) );
400  elemGeometryMember.appendChild( geom->asGml2( doc, precision, ns, axisOrder ) );
401  elemMultiGeometry.appendChild( elemGeometryMember );
402  }
403  return elemMultiGeometry;
404 }
405 
406 QDomElement QgsGeometryCollection::asGml3( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
407 {
408  QDomElement elemMultiGeometry = doc.createElementNS( ns, QStringLiteral( "MultiGeometry" ) );
409  for ( const QgsAbstractGeometry *geom : mGeometries )
410  {
411  QDomElement elemGeometryMember = doc.createElementNS( ns, QStringLiteral( "geometryMember" ) );
412  elemGeometryMember.appendChild( geom->asGml3( doc, precision, ns, axisOrder ) );
413  elemMultiGeometry.appendChild( elemGeometryMember );
414  }
415  return elemMultiGeometry;
416 }
417 
419 {
420  QString json = QStringLiteral( "{\"type\": \"GeometryCollection\", \"geometries\": [" );
421  for ( const QgsAbstractGeometry *geom : mGeometries )
422  {
423  json += geom->asJson( precision ) + ", ";
424  }
425  if ( json.endsWith( QLatin1String( ", " ) ) )
426  {
427  json.chop( 2 ); // Remove last ", "
428  }
429  json += QLatin1String( "] }" );
430  return json;
431 }
432 
434 {
435  if ( mBoundingBox.isNull() )
436  {
437  mBoundingBox = calculateBoundingBox();
438  }
439  return mBoundingBox;
440 }
441 
443 {
444  if ( mGeometries.empty() )
445  {
446  return QgsRectangle();
447  }
448 
449  QgsRectangle bbox = mGeometries.at( 0 )->boundingBox();
450  for ( int i = 1; i < mGeometries.size(); ++i )
451  {
452  QgsRectangle geomBox = mGeometries.at( i )->boundingBox();
453  bbox.combineExtentWith( geomBox );
454  }
455  return bbox;
456 }
457 
459 {
460  mBoundingBox = QgsRectangle();
462 }
463 
465 {
466  QgsCoordinateSequence sequence;
467  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
468  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
469  {
470  QgsCoordinateSequence geomCoords = ( *geomIt )->coordinateSequence();
471 
472  QgsCoordinateSequence::const_iterator cIt = geomCoords.constBegin();
473  for ( ; cIt != geomCoords.constEnd(); ++cIt )
474  {
475  sequence.push_back( *cIt );
476  }
477  }
478 
479  return sequence;
480 }
481 
483 {
484  int count = 0;
485 
486  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
487  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
488  {
489  count += ( *geomIt )->nCoordinates();
490  }
491 
492  return count;
493 }
494 
495 double QgsGeometryCollection::closestSegment( const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf, double epsilon ) const
496 {
497  return QgsGeometryUtils::closestSegmentFromComponents( mGeometries, QgsGeometryUtils::Part, pt, segmentPt, vertexAfter, leftOf, epsilon );
498 }
499 
501 {
502  if ( id.part < 0 )
503  {
504  id.part = 0;
505  id.ring = -1;
506  id.vertex = -1;
507  }
508  if ( mGeometries.isEmpty() )
509  {
510  return false;
511  }
512 
513  if ( id.part >= mGeometries.count() )
514  return false;
515 
516  QgsAbstractGeometry *geom = mGeometries.at( id.part );
517  if ( geom->nextVertex( id, vertex ) )
518  {
519  return true;
520  }
521  if ( ( id.part + 1 ) >= numGeometries() )
522  {
523  return false;
524  }
525  ++id.part;
526  id.ring = -1;
527  id.vertex = -1;
528  return mGeometries.at( id.part )->nextVertex( id, vertex );
529 }
530 
532 {
533  if ( position.part >= mGeometries.size() )
534  {
535  return false;
536  }
537 
538  bool success = mGeometries.at( position.part )->insertVertex( position, vertex );
539  if ( success )
540  {
541  clearCache(); //set bounding box invalid
542  }
543  return success;
544 }
545 
547 {
548  if ( position.part < 0 || position.part >= mGeometries.size() )
549  {
550  return false;
551  }
552 
553  bool success = mGeometries.at( position.part )->moveVertex( position, newPos );
554  if ( success )
555  {
556  clearCache(); //set bounding box invalid
557  }
558  return success;
559 }
560 
562 {
563  if ( position.part < 0 || position.part >= mGeometries.size() )
564  {
565  return false;
566  }
567 
568  QgsAbstractGeometry *geom = mGeometries.at( position.part );
569  if ( !geom )
570  {
571  return false;
572  }
573 
574  bool success = geom->deleteVertex( position );
575 
576  //remove geometry if no vertices left
577  if ( geom->isEmpty() )
578  {
579  removeGeometry( position.part );
580  }
581 
582  if ( success )
583  {
584  clearCache(); //set bounding box invalid
585  }
586  return success;
587 }
588 
590 {
591  double length = 0.0;
592  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
593  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
594  {
595  length += ( *geomIt )->length();
596  }
597  return length;
598 }
599 
601 {
602  double area = 0.0;
603  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
604  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
605  {
606  area += ( *geomIt )->area();
607  }
608  return area;
609 }
610 
612 {
613  double perimeter = 0.0;
614  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
615  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
616  {
617  perimeter += ( *geomIt )->perimeter();
618  }
619  return perimeter;
620 }
621 
622 bool QgsGeometryCollection::fromCollectionWkt( const QString &wkt, const QVector<QgsAbstractGeometry *> &subtypes, const QString &defaultChildWkbType )
623 {
624  clear();
625 
626  QPair<QgsWkbTypes::Type, QString> parts = QgsGeometryUtils::wktReadBlock( wkt );
627 
628  if ( QgsWkbTypes::flatType( parts.first ) != QgsWkbTypes::flatType( wkbType() ) )
629  {
630  qDeleteAll( subtypes );
631  return false;
632  }
633  mWkbType = parts.first;
634 
635  QString defChildWkbType = QStringLiteral( "%1%2%3 " ).arg( defaultChildWkbType, is3D() ? QStringLiteral( "Z" ) : QString(), isMeasure() ? QStringLiteral( "M" ) : QString() );
636 
637  const QStringList blocks = QgsGeometryUtils::wktGetChildBlocks( parts.second, defChildWkbType );
638  for ( const QString &childWkt : blocks )
639  {
640  QPair<QgsWkbTypes::Type, QString> childParts = QgsGeometryUtils::wktReadBlock( childWkt );
641 
642  bool success = false;
643  for ( const QgsAbstractGeometry *geom : subtypes )
644  {
645  if ( QgsWkbTypes::flatType( childParts.first ) == QgsWkbTypes::flatType( geom->wkbType() ) )
646  {
647  mGeometries.append( geom->clone() );
648  if ( mGeometries.back()->fromWkt( childWkt ) )
649  {
650  success = true;
651  break;
652  }
653  }
654  }
655  if ( !success )
656  {
657  clear();
658  qDeleteAll( subtypes );
659  return false;
660  }
661  }
662  qDeleteAll( subtypes );
663 
664  //scan through geometries and check if dimensionality of geometries is different to collection.
665  //if so, update the type dimensionality of the collection to match
666  bool hasZ = false;
667  bool hasM = false;
668  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
669  {
670  hasZ = hasZ || geom->is3D();
671  hasM = hasM || geom->isMeasure();
672  if ( hasZ && hasM )
673  break;
674  }
675  if ( hasZ )
676  addZValue( 0 );
677  if ( hasM )
678  addMValue( 0 );
679 
680  return true;
681 }
682 
684 {
685  QVector< QgsAbstractGeometry * >::const_iterator it = mGeometries.constBegin();
686  for ( ; it != mGeometries.constEnd(); ++it )
687  {
688  if ( ( *it )->hasCurvedSegments() )
689  {
690  return true;
691  }
692  }
693  return false;
694 }
695 
697 {
698  std::unique_ptr< QgsAbstractGeometry > geom( QgsGeometryFactory::geomFromWkbType( mWkbType ) );
699  QgsGeometryCollection *geomCollection = qgsgeometry_cast<QgsGeometryCollection *>( geom.get() );
700  if ( !geomCollection )
701  {
702  return clone();
703  }
704 
705  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
706  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
707  {
708  geomCollection->addGeometry( ( *geomIt )->segmentize( tolerance, toleranceType ) );
709  }
710  return geom.release();
711 }
712 
714 {
715  if ( vertex.part < 0 || vertex.part >= mGeometries.size() )
716  {
717  return 0.0;
718  }
719 
720  QgsAbstractGeometry *geom = mGeometries[vertex.part];
721  if ( !geom )
722  {
723  return 0.0;
724  }
725 
726  return geom->vertexAngle( vertex );
727 }
728 
730 {
731  if ( startVertex.part < 0 || startVertex.part >= mGeometries.size() )
732  {
733  return 0.0;
734  }
735 
736  const QgsAbstractGeometry *geom = mGeometries[startVertex.part];
737  if ( !geom )
738  {
739  return 0.0;
740  }
741 
742  return geom->segmentLength( startVertex );
743 }
744 
745 int QgsGeometryCollection::vertexCount( int part, int ring ) const
746 {
747  if ( part < 0 || part >= mGeometries.size() )
748  {
749  return 0;
750  }
751 
752  return mGeometries[part]->vertexCount( 0, ring );
753 }
754 
755 int QgsGeometryCollection::ringCount( int part ) const
756 {
757  if ( part < 0 || part >= mGeometries.size() )
758  {
759  return 0;
760  }
761 
762  return mGeometries[part]->ringCount();
763 }
764 
766 {
767  return mGeometries.size();
768 }
769 
771 {
772  return mGeometries[id.part]->vertexAt( id );
773 }
774 
775 bool QgsGeometryCollection::addZValue( double zValue )
776 {
777  if ( QgsWkbTypes::hasZ( mWkbType ) )
778  return false;
779 
781 
782  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
783  {
784  geom->addZValue( zValue );
785  }
786  clearCache();
787  return true;
788 }
789 
790 bool QgsGeometryCollection::addMValue( double mValue )
791 {
792  if ( QgsWkbTypes::hasM( mWkbType ) )
793  return false;
794 
796 
797  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
798  {
799  geom->addMValue( mValue );
800  }
801  clearCache();
802  return true;
803 }
804 
805 
807 {
809  return false;
810 
812  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
813  {
814  geom->dropZValue();
815  }
816  clearCache();
817  return true;
818 }
819 
821 {
823  return false;
824 
826  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
827  {
828  geom->dropMValue();
829  }
830  clearCache();
831  return true;
832 }
833 
834 void QgsGeometryCollection::filterVertices( const std::function<bool ( const QgsPoint & )> &filter )
835 {
836  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
837  {
838  if ( geom )
839  geom->filterVertices( filter );
840  }
841  clearCache();
842 }
843 
844 void QgsGeometryCollection::transformVertices( const std::function<QgsPoint( const QgsPoint & )> &transform )
845 {
846  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
847  {
848  if ( geom )
849  geom->transformVertices( transform );
850  }
851  clearCache();
852 }
853 
855 {
856  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
857  {
858  if ( geom )
859  geom->swapXy();
860  }
861  clearCache();
862 }
863 
865 {
866  std::unique_ptr< QgsGeometryCollection > newCollection( new QgsGeometryCollection() );
867  for ( QgsAbstractGeometry *geom : mGeometries )
868  {
869  newCollection->addGeometry( geom->toCurveType() );
870  }
871  return newCollection.release();
872 }
873 
875 {
876  return false;
877 }
878 
880 {
881  return mGeometries.count();
882 }
883 
885 {
886  if ( index < 0 || index > mGeometries.count() )
887  return nullptr;
888  return mGeometries.at( index );
889 }
static std::unique_ptr< QgsAbstractGeometry > geomFromWkb(QgsConstWkbPtr &wkb)
Construct geometry from a WKB string.
virtual bool wktOmitChildType() const
Returns whether child type names are omitted from Wkt representations of the collection.
int precision
virtual bool removeGeometry(int nr)
Removes a geometry from the collection.
bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const override
Returns next vertex id and coordinates.
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
virtual bool isEmpty() const
Returns true if the geometry is empty.
A rectangle specified with double values.
Definition: qgsrectangle.h:40
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...
bool operator!=(const QgsAbstractGeometry &other) const override
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.
static std::unique_ptr< QgsAbstractGeometry > geomFromWkbType(QgsWkbTypes::Type t)
Returns empty geometry from wkb type.
virtual bool deleteVertex(QgsVertexId position)=0
Deletes a vertex within the geometry.
bool fromWkb(QgsConstWkbPtr &wkb) override
Sets the geometry from a WKB string.
bool operator==(const QgsAbstractGeometry &other) const override
void clear() override
Clears the geometry, ie reset it to a null geometry.
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
QgsAbstractGeometry & operator=(const QgsAbstractGeometry &geom)
Multi point geometry collection.
Definition: qgsmultipoint.h:29
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 (...
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...
QVector< QgsRingSequence > QgsCoordinateSequence
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
TransformDirection
Enum used to indicate the direction (forward or inverse) of the transform.
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the geometry.
bool hasCurvedSegments() const override
Returns true if the geometry contains curved segments.
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:435
virtual double vertexAngle(QgsVertexId vertex) const =0
Returns approximate angle at a vertex.
Multi line string geometry collection.
Curve polygon geometry type.
bool insertVertex(QgsVertexId position, const QgsPoint &vertex) override
Inserts a vertex into the geometry.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
QgsAbstractGeometry * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle...
double segmentLength(QgsVertexId startVertex) const override
Returns the length of the segment of the geometry which begins at startVertex.
QgsGeometryCollection & operator=(const QgsGeometryCollection &c)
virtual bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const =0
Returns next vertex id and coordinates.
bool dropMValue() override
Drops any measure values which exist in the geometry.
static endian_t endian()
Returns whether this machine uses big or little endian.
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:906
static QStringList wktGetChildBlocks(const QString &wkt, const QString &defaultType=QString())
Parses a WKT string and returns of list of blocks contained in the WKT.
static Type dropM(Type type)
Drops the m dimension (if present) for a WKB type and returns the new type.
Definition: qgswkbtypes.h:1076
Multi surface geometry collection.
double length() const override
Returns the length of the geometry.
QString asJson(int precision=17) const override
Returns a GeoJSON representation of the geometry.
QgsWkbTypes::Type mWkbType
virtual bool insertGeometry(QgsAbstractGeometry *g, int index)
Inserts a geometry before a specified index and takes ownership.
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...
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
bool isEmpty() const override
Returns true if the geometry is empty.
void adjacentVertices(QgsVertexId vertex, QgsVertexId &previousVertex, QgsVertexId &nextVertex) const override
Returns the vertices adjacent to a specified vertex within a geometry.
int nCoordinates() const override
Returns the number of nodes contained in the geometry.
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
bool isMeasure() const
Returns true if the geometry contains m values.
void swapXy() override
Swaps the x and y coordinates from the geometry.
virtual double segmentLength(QgsVertexId startVertex) const =0
Returns the length of the segment of the geometry which begins at startVertex.
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1027
int dimension() const override
Returns the inherent dimension of the geometry.
QString wktTypeStr() const
Returns the WKT type string of the geometry.
Utility class for identifying a unique vertex within a geometry.
Geometry collection.
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
QgsGeometryCollection * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership...
double area() const override
Returns the area of the geometry.
QgsAbstractGeometry * childGeometry(int index) const override
Returns pointer to child geometry (for geometries with child geometries - i.e.
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1002
T qgsgeometry_cast(const QgsAbstractGeometry *geom)
int childCount() const override
Returns number of child geometries (for geometries with child geometries) or child points (for geomet...
Multi curve geometry collection.
Definition: qgsmulticurve.h:29
QgsAbstractGeometry * segmentize(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a geometry without curves.
QString geometryType() const override
Returns a unique string representing the geometry type.
QByteArray asWkb() const override
Returns a WKB representation of the geometry.
int numGeometries() const
Returns the number of geometries within the collection.
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
Abstract base class for all geometries.
virtual void clearCache() const
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
QgsWkbTypes::Type readHeader() const
readHeader
Definition: qgswkbptr.cpp:53
int vertexNumberFromVertexId(QgsVertexId id) const override
Returns the vertex number corresponding to a vertex id.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
AxisOrder
Axis order for GML generation.
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle...
Definition: qgsrectangle.h:358
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...
int partCount() const override
Returns count of parts contained in the geometry.
QVector< QgsAbstractGeometry * > mGeometries
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.
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.
static Type dropZ(Type type)
Drops the z dimension (if present) for a WKB type and returns the new type.
Definition: qgswkbtypes.h:1058
Multi polygon geometry collection.
QgsPoint vertexAt(QgsVertexId id) const override
Returns the point corresponding to a specified vertex id.
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the geometry.
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:43
QgsGeometryCollection * toCurveType() const override
Returns the geometry converted to the more generic curve type.
QgsCoordinateSequence coordinateSequence() const override
Retrieves the sequence of geometries, rings and nodes.
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
Class for doing transforms between two map coordinate systems.
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry.
double perimeter() const override
Returns the perimeter of the geometry.
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) override SIP_THROW(QgsCsException)
Transforms the geometry using a coordinate transform.
static bool hasM(Type type)
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:956
Compound curve geometry type.
Circular string geometry type.
QgsGeometryCollection * clone() const override
Clones the geometry by performing a deep copy.
Polygon geometry type.
Definition: qgspolygon.h:31
static Type flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:565
double ANALYSIS_EXPORT leftOf(const QgsPoint &thepoint, const QgsPoint *p1, const QgsPoint *p2)
Returns whether &#39;thepoint&#39; is left or right of the line from &#39;p1&#39; to &#39;p2&#39;. Negativ values mean left a...
Definition: MathUtils.cpp:292
static double closestSegmentFromComponents(T &container, ComponentType ctype, const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf, double epsilon)
int vertexCount(int part=0, int ring=0) const override
Returns the number of vertices of which this geometry is built.
void draw(QPainter &p) const override
Draws the geometry using the specified QPainter.
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
double vertexAngle(QgsVertexId vertex) const override
Returns approximate angle at a vertex.
QgsRectangle calculateBoundingBox() const override
Default calculator for the minimal bounding box for the geometry.
bool fromCollectionWkt(const QString &wkt, const QVector< QgsAbstractGeometry * > &subtypes, const QString &defaultChildWkbType=QString())
Reads a collection from a WKT string.
int ringCount(int part=0) const override
Returns the number of rings of which this geometry is built.