QGIS API Documentation  3.2.0-Bonn (bc43194)
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  if ( mGeometries.at( i ) != otherCollection->mGeometries.at( i ) )
82  return false;
83  }
84 
85  return true;
86 }
87 
89 {
90  return !operator==( other );
91 }
92 
94 {
95  auto result = qgis::make_unique< QgsGeometryCollection >();
96  result->mWkbType = mWkbType;
97  return result.release();
98 }
99 
101 {
102  return new QgsGeometryCollection( *this );
103 }
104 
106 {
107  qDeleteAll( mGeometries );
108  mGeometries.clear();
109  clearCache(); //set bounding box invalid
110 }
111 
112 QgsGeometryCollection *QgsGeometryCollection::snappedToGrid( double hSpacing, double vSpacing, double dSpacing, double mSpacing ) const
113 {
114  std::unique_ptr<QgsGeometryCollection> result;
115 
116  for ( auto geom : mGeometries )
117  {
118  std::unique_ptr<QgsAbstractGeometry> gridified { geom->snappedToGrid( hSpacing, vSpacing, dSpacing, mSpacing ) };
119  if ( gridified )
120  {
121  if ( !result )
122  result = std::unique_ptr<QgsGeometryCollection> { createEmptyWithSameType() };
123 
124  result->mGeometries.append( gridified.release() );
125  }
126  }
127 
128  return result.release();
129 }
130 
131 bool QgsGeometryCollection::removeDuplicateNodes( double epsilon, bool useZValues )
132 {
133  bool result = false;
134  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
135  {
136  result = result || geom->removeDuplicateNodes( epsilon, useZValues );
137  }
138  return result;
139 }
140 
142 {
143  return nullptr;
144 }
145 
147 {
148  if ( vertex.part < 0 || vertex.part >= mGeometries.count() )
149  {
150  previousVertex = QgsVertexId();
151  nextVertex = QgsVertexId();
152  return;
153  }
154 
155  mGeometries.at( vertex.part )->adjacentVertices( vertex, previousVertex, nextVertex );
156 }
157 
159 {
160  if ( id.part < 0 || id.part >= mGeometries.count() )
161  return -1;
162 
163  int number = 0;
164  int part = 0;
165  for ( QgsAbstractGeometry *geometry : mGeometries )
166  {
167  if ( part == id.part )
168  {
169  int partNumber = geometry->vertexNumberFromVertexId( QgsVertexId( 0, id.ring, id.vertex ) );
170  if ( partNumber == -1 )
171  return -1;
172  return number + partNumber;
173  }
174  else
175  {
176  number += geometry->nCoordinates();
177  }
178 
179  part++;
180  }
181  return -1; // should not happen
182 }
183 
185 {
186  clearCache();
187  return mGeometries.value( n );
188 }
189 
191 {
192  if ( mGeometries.isEmpty() )
193  return true;
194 
195  for ( QgsAbstractGeometry *geometry : mGeometries )
196  {
197  if ( !geometry->isEmpty() )
198  return false;
199  }
200  return true;
201 }
202 
204 {
205  if ( !g )
206  {
207  return false;
208  }
209 
210  mGeometries.append( g );
211  clearCache(); //set bounding box invalid
212  return true;
213 }
214 
216 {
217  if ( !g )
218  {
219  return false;
220  }
221 
222  index = std::min( mGeometries.count(), index );
223 
224  mGeometries.insert( index, g );
225  clearCache(); //set bounding box invalid
226  return true;
227 }
228 
230 {
231  if ( nr >= mGeometries.size() || nr < 0 )
232  {
233  return false;
234  }
235  delete mGeometries.at( nr );
236  mGeometries.remove( nr );
237  clearCache(); //set bounding box invalid
238  return true;
239 }
240 
242 {
243  int maxDim = 0;
244  QVector< QgsAbstractGeometry * >::const_iterator it = mGeometries.constBegin();
245  for ( ; it != mGeometries.constEnd(); ++it )
246  {
247  int dim = ( *it )->dimension();
248  if ( dim > maxDim )
249  {
250  maxDim = dim;
251  }
252  }
253  return maxDim;
254 }
255 
257 {
258  return QStringLiteral( "GeometryCollection" );
259 }
260 
262 {
263  for ( QgsAbstractGeometry *g : qgis::as_const( mGeometries ) )
264  {
265  g->transform( ct, d, transformZ );
266  }
267  clearCache(); //set bounding box invalid
268 }
269 
270 void QgsGeometryCollection::transform( const QTransform &t, double zTranslate, double zScale, double mTranslate, double mScale )
271 {
272  for ( QgsAbstractGeometry *g : qgis::as_const( mGeometries ) )
273  {
274  g->transform( t, zTranslate, zScale, mTranslate, mScale );
275  }
276  clearCache(); //set bounding box invalid
277 }
278 
279 void QgsGeometryCollection::draw( QPainter &p ) const
280 {
281  QVector< QgsAbstractGeometry * >::const_iterator it = mGeometries.constBegin();
282  for ( ; it != mGeometries.constEnd(); ++it )
283  {
284  ( *it )->draw( p );
285  }
286 }
287 
289 {
290  if ( !wkbPtr )
291  {
292  return false;
293  }
294 
297  return false;
298 
299  mWkbType = wkbType;
300 
301  int nGeometries = 0;
302  wkbPtr >> nGeometries;
303 
304  QVector<QgsAbstractGeometry *> geometryListBackup = mGeometries;
305  mGeometries.clear();
306  for ( int i = 0; i < nGeometries; ++i )
307  {
308  std::unique_ptr< QgsAbstractGeometry > geom( QgsGeometryFactory::geomFromWkb( wkbPtr ) ); // also updates wkbPtr
309  if ( geom )
310  {
311  if ( !addGeometry( geom.release() ) )
312  {
313  qDeleteAll( mGeometries );
314  mGeometries = geometryListBackup;
315  return false;
316  }
317  }
318  }
319  qDeleteAll( geometryListBackup );
320 
321  clearCache(); //set bounding box invalid
322 
323  return true;
324 }
325 
326 bool QgsGeometryCollection::fromWkt( const QString &wkt )
327 {
328  return fromCollectionWkt( wkt, QVector<QgsAbstractGeometry *>() << new QgsPoint << new QgsLineString << new QgsPolygon
329  << new QgsCircularString << new QgsCompoundCurve
330  << new QgsCurvePolygon
331  << new QgsMultiPoint << new QgsMultiLineString
333  << new QgsMultiCurve << new QgsMultiSurface, QStringLiteral( "GeometryCollection" ) );
334 }
335 
337 {
338  int binarySize = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 );
339  QVector<QByteArray> wkbForGeometries;
340  for ( const QgsAbstractGeometry *geom : mGeometries )
341  {
342  if ( geom )
343  {
344  QByteArray wkb( geom->asWkb() );
345  binarySize += wkb.length();
346  wkbForGeometries << wkb;
347  }
348  }
349 
350  QByteArray wkbArray;
351  wkbArray.resize( binarySize );
352  QgsWkbPtr wkb( wkbArray );
353  wkb << static_cast<char>( QgsApplication::endian() );
354  wkb << static_cast<quint32>( wkbType() );
355  wkb << static_cast<quint32>( wkbForGeometries.count() );
356  for ( const QByteArray &wkbForGeometry : qgis::as_const( wkbForGeometries ) )
357  {
358  wkb << wkbForGeometry;
359  }
360  return wkbArray;
361 }
362 
363 QString QgsGeometryCollection::asWkt( int precision ) const
364 {
365  QString wkt = wktTypeStr() + " (";
366  for ( const QgsAbstractGeometry *geom : mGeometries )
367  {
368  QString childWkt = geom->asWkt( precision );
369  if ( wktOmitChildType() )
370  {
371  childWkt = childWkt.mid( childWkt.indexOf( '(' ) );
372  }
373  wkt += childWkt + ',';
374  }
375  if ( wkt.endsWith( ',' ) )
376  {
377  wkt.chop( 1 ); // Remove last ','
378  }
379  wkt += ')';
380  return wkt;
381 }
382 
383 QDomElement QgsGeometryCollection::asGml2( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
384 {
385  QDomElement elemMultiGeometry = doc.createElementNS( ns, QStringLiteral( "MultiGeometry" ) );
386  for ( const QgsAbstractGeometry *geom : mGeometries )
387  {
388  QDomElement elemGeometryMember = doc.createElementNS( ns, QStringLiteral( "geometryMember" ) );
389  elemGeometryMember.appendChild( geom->asGml2( doc, precision, ns, axisOrder ) );
390  elemMultiGeometry.appendChild( elemGeometryMember );
391  }
392  return elemMultiGeometry;
393 }
394 
395 QDomElement QgsGeometryCollection::asGml3( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
396 {
397  QDomElement elemMultiGeometry = doc.createElementNS( ns, QStringLiteral( "MultiGeometry" ) );
398  for ( const QgsAbstractGeometry *geom : mGeometries )
399  {
400  QDomElement elemGeometryMember = doc.createElementNS( ns, QStringLiteral( "geometryMember" ) );
401  elemGeometryMember.appendChild( geom->asGml3( doc, precision, ns, axisOrder ) );
402  elemMultiGeometry.appendChild( elemGeometryMember );
403  }
404  return elemMultiGeometry;
405 }
406 
407 QString QgsGeometryCollection::asJson( int precision ) const
408 {
409  QString json = QStringLiteral( "{\"type\": \"GeometryCollection\", \"geometries\": [" );
410  for ( const QgsAbstractGeometry *geom : mGeometries )
411  {
412  json += geom->asJson( precision ) + ", ";
413  }
414  if ( json.endsWith( QLatin1String( ", " ) ) )
415  {
416  json.chop( 2 ); // Remove last ", "
417  }
418  json += QLatin1String( "] }" );
419  return json;
420 }
421 
423 {
424  if ( mBoundingBox.isNull() )
425  {
426  mBoundingBox = calculateBoundingBox();
427  }
428  return mBoundingBox;
429 }
430 
432 {
433  if ( mGeometries.empty() )
434  {
435  return QgsRectangle();
436  }
437 
438  QgsRectangle bbox = mGeometries.at( 0 )->boundingBox();
439  for ( int i = 1; i < mGeometries.size(); ++i )
440  {
441  QgsRectangle geomBox = mGeometries.at( i )->boundingBox();
442  bbox.combineExtentWith( geomBox );
443  }
444  return bbox;
445 }
446 
448 {
449  mBoundingBox = QgsRectangle();
451 }
452 
454 {
455  QgsCoordinateSequence sequence;
456  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
457  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
458  {
459  QgsCoordinateSequence geomCoords = ( *geomIt )->coordinateSequence();
460 
461  QgsCoordinateSequence::const_iterator cIt = geomCoords.constBegin();
462  for ( ; cIt != geomCoords.constEnd(); ++cIt )
463  {
464  sequence.push_back( *cIt );
465  }
466  }
467 
468  return sequence;
469 }
470 
472 {
473  int count = 0;
474 
475  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
476  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
477  {
478  count += ( *geomIt )->nCoordinates();
479  }
480 
481  return count;
482 }
483 
484 double QgsGeometryCollection::closestSegment( const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf, double epsilon ) const
485 {
486  return QgsGeometryUtils::closestSegmentFromComponents( mGeometries, QgsGeometryUtils::Part, pt, segmentPt, vertexAfter, leftOf, epsilon );
487 }
488 
490 {
491  if ( id.part < 0 )
492  {
493  id.part = 0;
494  id.ring = -1;
495  id.vertex = -1;
496  }
497  if ( mGeometries.isEmpty() )
498  {
499  return false;
500  }
501 
502  if ( id.part >= mGeometries.count() )
503  return false;
504 
505  QgsAbstractGeometry *geom = mGeometries.at( id.part );
506  if ( geom->nextVertex( id, vertex ) )
507  {
508  return true;
509  }
510  if ( ( id.part + 1 ) >= numGeometries() )
511  {
512  return false;
513  }
514  ++id.part;
515  id.ring = -1;
516  id.vertex = -1;
517  return mGeometries.at( id.part )->nextVertex( id, vertex );
518 }
519 
521 {
522  if ( position.part >= mGeometries.size() )
523  {
524  return false;
525  }
526 
527  bool success = mGeometries.at( position.part )->insertVertex( position, vertex );
528  if ( success )
529  {
530  clearCache(); //set bounding box invalid
531  }
532  return success;
533 }
534 
536 {
537  if ( position.part < 0 || position.part >= mGeometries.size() )
538  {
539  return false;
540  }
541 
542  bool success = mGeometries.at( position.part )->moveVertex( position, newPos );
543  if ( success )
544  {
545  clearCache(); //set bounding box invalid
546  }
547  return success;
548 }
549 
551 {
552  if ( position.part < 0 || position.part >= mGeometries.size() )
553  {
554  return false;
555  }
556 
557  QgsAbstractGeometry *geom = mGeometries.at( position.part );
558  if ( !geom )
559  {
560  return false;
561  }
562 
563  bool success = geom->deleteVertex( position );
564 
565  //remove geometry if no vertices left
566  if ( geom->isEmpty() )
567  {
568  removeGeometry( position.part );
569  }
570 
571  if ( success )
572  {
573  clearCache(); //set bounding box invalid
574  }
575  return success;
576 }
577 
579 {
580  double length = 0.0;
581  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
582  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
583  {
584  length += ( *geomIt )->length();
585  }
586  return length;
587 }
588 
590 {
591  double area = 0.0;
592  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
593  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
594  {
595  area += ( *geomIt )->area();
596  }
597  return area;
598 }
599 
601 {
602  double perimeter = 0.0;
603  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
604  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
605  {
606  perimeter += ( *geomIt )->perimeter();
607  }
608  return perimeter;
609 }
610 
611 bool QgsGeometryCollection::fromCollectionWkt( const QString &wkt, const QVector<QgsAbstractGeometry *> &subtypes, const QString &defaultChildWkbType )
612 {
613  clear();
614 
615  QPair<QgsWkbTypes::Type, QString> parts = QgsGeometryUtils::wktReadBlock( wkt );
616 
617  if ( QgsWkbTypes::flatType( parts.first ) != QgsWkbTypes::flatType( wkbType() ) )
618  {
619  qDeleteAll( subtypes );
620  return false;
621  }
622  mWkbType = parts.first;
623 
624  QString defChildWkbType = QStringLiteral( "%1%2%3 " ).arg( defaultChildWkbType, is3D() ? "Z" : "", isMeasure() ? "M" : "" );
625 
626  const QStringList blocks = QgsGeometryUtils::wktGetChildBlocks( parts.second, defChildWkbType );
627  for ( const QString &childWkt : blocks )
628  {
629  QPair<QgsWkbTypes::Type, QString> childParts = QgsGeometryUtils::wktReadBlock( childWkt );
630 
631  bool success = false;
632  for ( const QgsAbstractGeometry *geom : subtypes )
633  {
634  if ( QgsWkbTypes::flatType( childParts.first ) == QgsWkbTypes::flatType( geom->wkbType() ) )
635  {
636  mGeometries.append( geom->clone() );
637  if ( mGeometries.back()->fromWkt( childWkt ) )
638  {
639  success = true;
640  break;
641  }
642  }
643  }
644  if ( !success )
645  {
646  clear();
647  qDeleteAll( subtypes );
648  return false;
649  }
650  }
651  qDeleteAll( subtypes );
652 
653  //scan through geometries and check if dimensionality of geometries is different to collection.
654  //if so, update the type dimensionality of the collection to match
655  bool hasZ = false;
656  bool hasM = false;
657  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
658  {
659  hasZ = hasZ || geom->is3D();
660  hasM = hasM || geom->isMeasure();
661  if ( hasZ && hasM )
662  break;
663  }
664  if ( hasZ )
665  addZValue( 0 );
666  if ( hasM )
667  addMValue( 0 );
668 
669  return true;
670 }
671 
673 {
674  QVector< QgsAbstractGeometry * >::const_iterator it = mGeometries.constBegin();
675  for ( ; it != mGeometries.constEnd(); ++it )
676  {
677  if ( ( *it )->hasCurvedSegments() )
678  {
679  return true;
680  }
681  }
682  return false;
683 }
684 
686 {
687  std::unique_ptr< QgsAbstractGeometry > geom( QgsGeometryFactory::geomFromWkbType( mWkbType ) );
688  QgsGeometryCollection *geomCollection = qgsgeometry_cast<QgsGeometryCollection *>( geom.get() );
689  if ( !geomCollection )
690  {
691  return clone();
692  }
693 
694  QVector< QgsAbstractGeometry * >::const_iterator geomIt = mGeometries.constBegin();
695  for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
696  {
697  geomCollection->addGeometry( ( *geomIt )->segmentize( tolerance, toleranceType ) );
698  }
699  return geom.release();
700 }
701 
703 {
704  if ( vertex.part < 0 || vertex.part >= mGeometries.size() )
705  {
706  return 0.0;
707  }
708 
709  QgsAbstractGeometry *geom = mGeometries[vertex.part];
710  if ( !geom )
711  {
712  return 0.0;
713  }
714 
715  return geom->vertexAngle( vertex );
716 }
717 
719 {
720  if ( startVertex.part < 0 || startVertex.part >= mGeometries.size() )
721  {
722  return 0.0;
723  }
724 
725  const QgsAbstractGeometry *geom = mGeometries[startVertex.part];
726  if ( !geom )
727  {
728  return 0.0;
729  }
730 
731  return geom->segmentLength( startVertex );
732 }
733 
734 int QgsGeometryCollection::vertexCount( int part, int ring ) const
735 {
736  if ( part < 0 || part >= mGeometries.size() )
737  {
738  return 0;
739  }
740 
741  return mGeometries[part]->vertexCount( 0, ring );
742 }
743 
744 int QgsGeometryCollection::ringCount( int part ) const
745 {
746  if ( part < 0 || part >= mGeometries.size() )
747  {
748  return 0;
749  }
750 
751  return mGeometries[part]->ringCount();
752 }
753 
755 {
756  return mGeometries.size();
757 }
758 
760 {
761  return mGeometries[id.part]->vertexAt( id );
762 }
763 
764 bool QgsGeometryCollection::addZValue( double zValue )
765 {
766  if ( QgsWkbTypes::hasZ( mWkbType ) )
767  return false;
768 
770 
771  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
772  {
773  geom->addZValue( zValue );
774  }
775  clearCache();
776  return true;
777 }
778 
779 bool QgsGeometryCollection::addMValue( double mValue )
780 {
781  if ( QgsWkbTypes::hasM( mWkbType ) )
782  return false;
783 
785 
786  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
787  {
788  geom->addMValue( mValue );
789  }
790  clearCache();
791  return true;
792 }
793 
794 
796 {
798  return false;
799 
801  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
802  {
803  geom->dropZValue();
804  }
805  clearCache();
806  return true;
807 }
808 
810 {
812  return false;
813 
815  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
816  {
817  geom->dropMValue();
818  }
819  clearCache();
820  return true;
821 }
822 
823 void QgsGeometryCollection::filterVertices( const std::function<bool ( const QgsPoint & )> &filter )
824 {
825  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
826  {
827  if ( geom )
828  geom->filterVertices( filter );
829  }
830  clearCache();
831 }
832 
834 {
835  for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) )
836  {
837  if ( geom )
838  geom->swapXy();
839  }
840  clearCache();
841 }
842 
844 {
845  std::unique_ptr< QgsGeometryCollection > newCollection( new QgsGeometryCollection() );
846  for ( QgsAbstractGeometry *geom : mGeometries )
847  {
848  newCollection->addGeometry( geom->toCurveType() );
849  }
850  return newCollection.release();
851 }
852 
854 {
855  return false;
856 }
857 
859 {
860  return mGeometries.count();
861 }
862 
864 {
865  if ( index < 0 || index > mGeometries.count() )
866  return nullptr;
867  return mGeometries.at( index );
868 }
bool isMeasure() const
Returns true if the geometry contains m values.
static std::unique_ptr< QgsAbstractGeometry > geomFromWkb(QgsConstWkbPtr &wkb)
Construct geometry from a WKB string.
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.
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
virtual bool isEmpty() const
Returns true if the geometry is empty.
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.
bool hasCurvedSegments() const override
Returns true if the geometry contains curved segments.
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.
QgsAbstractGeometry * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
virtual bool wktOmitChildType() const
Returns whether child type names are omitted from Wkt representations of the collection.
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:768
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:938
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.
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
QString wktTypeStr() const
Returns the WKT type string of the geometry.
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:67
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
void swapXy() override
Swaps the x and y coordinates from the geometry.
virtual void clearCache() const
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
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:889
int dimension() const override
Returns the inherent dimension 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:864
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.
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
Abstract base class for all geometries.
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the geometry.
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
bool fromCollectionWkt(const QString &wkt, const QVector< QgsAbstractGeometry *> &subtypes, const QString &defaultChildWkbType=QString())
Reads a collection from a WKT string.
AxisOrder
Axis order for GML generation.
int numGeometries() const
Returns the number of geometries within the collection.
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle...
Definition: qgsrectangle.h:352
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:920
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.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:429
Class for doing transforms between two map coordinate systems.
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:818
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:427
QgsWkbTypes::Type readHeader() const
readHeader
Definition: qgswkbptr.cpp:53
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
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.
int ringCount(int part=0) const override
Returns the number of rings of which this geometry is built.