LCOV - code coverage report
Current view: top level - core/geometry - qgsabstractgeometry.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 245 295 83.1 %
Date: 2021-04-10 08:29:14 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :                         qgsabstractgeometry.cpp
       3                 :            :   -------------------------------------------------------------------
       4                 :            : Date                 : 04 Sept 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 "qgsapplication.h"
      17                 :            : #include "qgsabstractgeometry.h"
      18                 :            : #include "qgswkbptr.h"
      19                 :            : #include "qgsgeos.h"
      20                 :            : #include "qgsmaptopixel.h"
      21                 :            : #include "qgspoint.h"
      22                 :            : #include "qgsgeometrycollection.h"
      23                 :            : 
      24                 :            : #include <nlohmann/json.hpp>
      25                 :            : #include <limits>
      26                 :            : #include <QTransform>
      27                 :            : 
      28                 :      97738 : QgsAbstractGeometry::QgsAbstractGeometry( const QgsAbstractGeometry &geom )
      29                 :      97738 : {
      30                 :      97738 :   mWkbType = geom.mWkbType;
      31                 :      97738 : }
      32                 :            : 
      33                 :      21777 : QgsAbstractGeometry &QgsAbstractGeometry::operator=( const QgsAbstractGeometry &geom )
      34                 :            : {
      35                 :      21777 :   if ( &geom != this )
      36                 :            :   {
      37                 :      21777 :     clear();
      38                 :      21777 :     mWkbType = geom.mWkbType;
      39                 :      21777 :   }
      40                 :      21777 :   return *this;
      41                 :            : }
      42                 :            : 
      43                 :       4198 : void QgsAbstractGeometry::setZMTypeFromSubGeometry( const QgsAbstractGeometry *subgeom, QgsWkbTypes::Type baseGeomType )
      44                 :            : {
      45                 :       4198 :   if ( !subgeom )
      46                 :            :   {
      47                 :          0 :     return;
      48                 :            :   }
      49                 :            : 
      50                 :            :   //special handling for 25d types:
      51                 :       5260 :   if ( baseGeomType == QgsWkbTypes::LineString &&
      52                 :       1077 :        ( subgeom->wkbType() == QgsWkbTypes::Point25D || subgeom->wkbType() == QgsWkbTypes::LineString25D ) )
      53                 :            :   {
      54                 :         16 :     mWkbType = QgsWkbTypes::LineString25D;
      55                 :         16 :     return;
      56                 :            :   }
      57                 :       5383 :   else if ( baseGeomType == QgsWkbTypes::Polygon &&
      58                 :       1201 :             ( subgeom->wkbType() == QgsWkbTypes::Point25D || subgeom->wkbType() == QgsWkbTypes::LineString25D ) )
      59                 :            :   {
      60                 :          4 :     mWkbType = QgsWkbTypes::Polygon25D;
      61                 :          4 :     return;
      62                 :            :   }
      63                 :            : 
      64                 :       4178 :   bool hasZ = subgeom->is3D();
      65                 :       4178 :   bool hasM = subgeom->isMeasure();
      66                 :            : 
      67                 :       4178 :   if ( hasZ && hasM )
      68                 :            :   {
      69                 :        435 :     mWkbType = QgsWkbTypes::addM( QgsWkbTypes::addZ( baseGeomType ) );
      70                 :        435 :   }
      71                 :       3743 :   else if ( hasZ )
      72                 :            :   {
      73                 :        263 :     mWkbType = QgsWkbTypes::addZ( baseGeomType );
      74                 :        263 :   }
      75                 :       3480 :   else if ( hasM )
      76                 :            :   {
      77                 :        157 :     mWkbType = QgsWkbTypes::addM( baseGeomType );
      78                 :        157 :   }
      79                 :            :   else
      80                 :            :   {
      81                 :       3323 :     mWkbType = baseGeomType;
      82                 :            :   }
      83                 :       4198 : }
      84                 :            : 
      85                 :          0 : QgsRectangle QgsAbstractGeometry::calculateBoundingBox() const
      86                 :            : {
      87                 :          0 :   double xmin = std::numeric_limits<double>::max();
      88                 :          0 :   double ymin = std::numeric_limits<double>::max();
      89                 :          0 :   double xmax = -std::numeric_limits<double>::max();
      90                 :          0 :   double ymax = -std::numeric_limits<double>::max();
      91                 :            : 
      92                 :          0 :   QgsVertexId id;
      93                 :          0 :   QgsPoint vertex;
      94                 :            :   double x, y;
      95                 :          0 :   while ( nextVertex( id, vertex ) )
      96                 :            :   {
      97                 :          0 :     x = vertex.x();
      98                 :          0 :     y = vertex.y();
      99                 :          0 :     if ( x < xmin )
     100                 :          0 :       xmin = x;
     101                 :          0 :     if ( x > xmax )
     102                 :          0 :       xmax = x;
     103                 :          0 :     if ( y < ymin )
     104                 :          0 :       ymin = y;
     105                 :          0 :     if ( y > ymax )
     106                 :          0 :       ymax = y;
     107                 :            :   }
     108                 :            : 
     109                 :          0 :   return QgsRectangle( xmin, ymin, xmax, ymax );
     110                 :          0 : }
     111                 :            : 
     112                 :      42531 : void QgsAbstractGeometry::clearCache() const
     113                 :            : {
     114                 :      42531 : }
     115                 :            : 
     116                 :         54 : int QgsAbstractGeometry::nCoordinates() const
     117                 :            : {
     118                 :         54 :   int nCoords = 0;
     119                 :            : 
     120                 :         54 :   const QgsCoordinateSequence seq = coordinateSequence();
     121                 :        108 :   for ( const QgsRingSequence &r : seq )
     122                 :            :   {
     123                 :        108 :     for ( const QgsPointSequence &p : r )
     124                 :            :     {
     125                 :         54 :       nCoords += p.size();
     126                 :            :     }
     127                 :            :   }
     128                 :            : 
     129                 :         54 :   return nCoords;
     130                 :         54 : }
     131                 :            : 
     132                 :          1 : double QgsAbstractGeometry::length() const
     133                 :            : {
     134                 :          1 :   return 0.0;
     135                 :            : }
     136                 :            : 
     137                 :         17 : double QgsAbstractGeometry::perimeter() const
     138                 :            : {
     139                 :         17 :   return 0.0;
     140                 :            : }
     141                 :            : 
     142                 :         17 : double QgsAbstractGeometry::area() const
     143                 :            : {
     144                 :         17 :   return 0.0;
     145                 :            : }
     146                 :            : 
     147                 :       5616 : QString QgsAbstractGeometry::wktTypeStr() const
     148                 :            : {
     149                 :       5616 :   QString wkt = geometryType();
     150                 :       5616 :   if ( is3D() )
     151                 :       2671 :     wkt += 'Z';
     152                 :       5616 :   if ( isMeasure() )
     153                 :       2632 :     wkt += 'M';
     154                 :       5616 :   return wkt;
     155                 :       5616 : }
     156                 :            : 
     157                 :         42 : QString QgsAbstractGeometry::asJson( int precision )
     158                 :            : {
     159                 :         42 :   return QString::fromStdString( asJsonObject( precision ).dump() );
     160                 :          0 : }
     161                 :            : 
     162                 :          0 : json QgsAbstractGeometry::asJsonObject( int precision ) const
     163                 :            : {
     164                 :          0 :   Q_UNUSED( precision ) return nullptr;
     165                 :            : }
     166                 :            : 
     167                 :         95 : QgsPoint QgsAbstractGeometry::centroid() const
     168                 :            : {
     169                 :            :   // http://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon
     170                 :            :   // Pick the first ring of first part for the moment
     171                 :            : 
     172                 :         95 :   int n = vertexCount( 0, 0 );
     173                 :         95 :   if ( n == 1 )
     174                 :            :   {
     175                 :         14 :     return vertexAt( QgsVertexId( 0, 0, 0 ) );
     176                 :            :   }
     177                 :            : 
     178                 :         81 :   double A = 0.;
     179                 :         81 :   double Cx = 0.;
     180                 :         81 :   double Cy = 0.;
     181                 :         81 :   QgsPoint v0 = vertexAt( QgsVertexId( 0, 0, 0 ) );
     182                 :         81 :   int i = 0, j = 1;
     183                 :         81 :   if ( vertexAt( QgsVertexId( 0, 0, 0 ) ) != vertexAt( QgsVertexId( 0, 0, n - 1 ) ) )
     184                 :            :   {
     185                 :         13 :     i = n - 1;
     186                 :         13 :     j = 0;
     187                 :         13 :   }
     188                 :        408 :   for ( ; j < n; i = j++ )
     189                 :            :   {
     190                 :        327 :     QgsPoint vi = vertexAt( QgsVertexId( 0, 0, i ) );
     191                 :        327 :     QgsPoint vj = vertexAt( QgsVertexId( 0, 0, j ) );
     192                 :        327 :     vi.rx() -= v0.x();
     193                 :        327 :     vi.ry() -= v0.y();
     194                 :        327 :     vj.rx() -= v0.x();
     195                 :        327 :     vj.ry() -= v0.y();
     196                 :        327 :     double d = vi.x() * vj.y() - vj.x() * vi.y();
     197                 :        327 :     A += d;
     198                 :        327 :     Cx += ( vi.x() + vj.x() ) * d;
     199                 :        327 :     Cy += ( vi.y() + vj.y() ) * d;
     200                 :        327 :   }
     201                 :            : 
     202                 :         81 :   if ( A < 1E-12 )
     203                 :            :   {
     204                 :         70 :     Cx = Cy = 0.;
     205                 :        346 :     for ( int i = 0; i < n - 1; ++i )
     206                 :            :     {
     207                 :        276 :       QgsPoint vi = vertexAt( QgsVertexId( 0, 0, i ) );
     208                 :        276 :       Cx += vi.x();
     209                 :        276 :       Cy += vi.y();
     210                 :        276 :     }
     211                 :         70 :     return QgsPoint( Cx / ( n - 1 ), Cy / ( n - 1 ) );
     212                 :            :   }
     213                 :            :   else
     214                 :            :   {
     215                 :         11 :     return QgsPoint( v0.x() + Cx / ( 3. * A ), v0.y() + Cy / ( 3. * A ) );
     216                 :            :   }
     217                 :         95 : }
     218                 :            : 
     219                 :         21 : bool QgsAbstractGeometry::convertTo( QgsWkbTypes::Type type )
     220                 :            : {
     221                 :         21 :   if ( type == mWkbType )
     222                 :          2 :     return true;
     223                 :            : 
     224                 :         19 :   if ( QgsWkbTypes::flatType( type ) != QgsWkbTypes::flatType( mWkbType ) )
     225                 :          3 :     return false;
     226                 :            : 
     227                 :         16 :   bool needZ = QgsWkbTypes::hasZ( type );
     228                 :         16 :   bool needM = QgsWkbTypes::hasM( type );
     229                 :         16 :   if ( !needZ )
     230                 :            :   {
     231                 :         10 :     dropZValue();
     232                 :         10 :   }
     233                 :          6 :   else if ( !is3D() )
     234                 :            :   {
     235                 :          3 :     addZValue( std::numeric_limits<double>::quiet_NaN() );
     236                 :          3 :   }
     237                 :            : 
     238                 :         16 :   if ( !needM )
     239                 :            :   {
     240                 :          8 :     dropMValue();
     241                 :          8 :   }
     242                 :          8 :   else if ( !isMeasure() )
     243                 :            :   {
     244                 :          5 :     addMValue( std::numeric_limits<double>::quiet_NaN() );
     245                 :          5 :   }
     246                 :            : 
     247                 :         16 :   return true;
     248                 :         21 : }
     249                 :            : 
     250                 :          0 : void QgsAbstractGeometry::filterVertices( const std::function<bool ( const QgsPoint & )> & )
     251                 :            : {
     252                 :            :   // Ideally this would be pure virtual, but SIP has issues with that
     253                 :          0 : }
     254                 :            : 
     255                 :          0 : void QgsAbstractGeometry::transformVertices( const std::function<QgsPoint( const QgsPoint & )> & )
     256                 :            : {
     257                 :            :   // Ideally this would be pure virtual, but SIP has issues with that
     258                 :          0 : }
     259                 :            : 
     260                 :         43 : QgsAbstractGeometry::part_iterator QgsAbstractGeometry::parts_end()
     261                 :            : {
     262                 :         43 :   const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( this );
     263                 :         43 :   return part_iterator( this, collection ? collection->partCount() : 1 );
     264                 :            : }
     265                 :            : 
     266                 :          5 : QgsGeometryPartIterator QgsAbstractGeometry::parts()
     267                 :            : {
     268                 :          5 :   return QgsGeometryPartIterator( this );
     269                 :            : }
     270                 :            : 
     271                 :          0 : QgsGeometryConstPartIterator QgsAbstractGeometry::parts() const
     272                 :            : {
     273                 :          0 :   return QgsGeometryConstPartIterator( this );
     274                 :            : }
     275                 :            : 
     276                 :          3 : QgsAbstractGeometry::const_part_iterator QgsAbstractGeometry::const_parts_end() const
     277                 :            : {
     278                 :          3 :   const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( this );
     279                 :          3 :   return const_part_iterator( this, collection ? collection->partCount() : 1 );
     280                 :            : }
     281                 :            : 
     282                 :          2 : QgsVertexIterator QgsAbstractGeometry::vertices() const
     283                 :            : {
     284                 :          2 :   return QgsVertexIterator( this );
     285                 :            : }
     286                 :            : 
     287                 :        886 : bool QgsAbstractGeometry::hasChildGeometries() const
     288                 :            : {
     289                 :        886 :   return QgsWkbTypes::isMultiType( wkbType() ) || dimension() == 2;
     290                 :            : }
     291                 :            : 
     292                 :          0 : QgsPoint QgsAbstractGeometry::childPoint( int index ) const
     293                 :            : {
     294                 :            :   Q_UNUSED( index )
     295                 :          0 :   return QgsPoint();
     296                 :            : }
     297                 :            : 
     298                 :          0 : bool QgsAbstractGeometry::isEmpty() const
     299                 :            : {
     300                 :          0 :   QgsVertexId vId;
     301                 :          0 :   QgsPoint vertex;
     302                 :          0 :   return !nextVertex( vId, vertex );
     303                 :          0 : }
     304                 :            : 
     305                 :       1416 : bool QgsAbstractGeometry::hasCurvedSegments() const
     306                 :            : {
     307                 :       1416 :   return false;
     308                 :            : }
     309                 :            : 
     310                 :          6 : bool QgsAbstractGeometry::boundingBoxIntersects( const QgsRectangle &rectangle ) const
     311                 :            : {
     312                 :          6 :   return boundingBox().intersects( rectangle );
     313                 :            : }
     314                 :            : 
     315                 :          1 : QgsAbstractGeometry *QgsAbstractGeometry::segmentize( double tolerance, SegmentationToleranceType toleranceType ) const
     316                 :            : {
     317                 :            :   Q_UNUSED( tolerance )
     318                 :            :   Q_UNUSED( toleranceType )
     319                 :          1 :   return clone();
     320                 :            : }
     321                 :            : 
     322                 :            : 
     323                 :        323 : QgsAbstractGeometry::vertex_iterator::vertex_iterator( const QgsAbstractGeometry *g, int index )
     324                 :        323 :   : depth( 0 )
     325                 :            : {
     326                 :        323 :   levels.fill( Level() );
     327                 :        323 :   levels[0].g = g;
     328                 :        323 :   levels[0].index = index;
     329                 :            : 
     330                 :        323 :   digDown();  // go to the leaf level of the first vertex
     331                 :        323 : }
     332                 :            : 
     333                 :        233 : QgsAbstractGeometry::vertex_iterator &QgsAbstractGeometry::vertex_iterator::operator++()
     334                 :            : {
     335                 :        233 :   if ( depth == 0 && levels[0].index >= levels[0].g->childCount() )
     336                 :          0 :     return *this;  // end of geometry - nowhere else to go
     337                 :            : 
     338                 :            :   Q_ASSERT( !levels[depth].g->hasChildGeometries() );  // we should be at a leaf level
     339                 :            : 
     340                 :        233 :   ++levels[depth].index;
     341                 :            : 
     342                 :            :   // traverse up if we are at the end in the current level
     343                 :        307 :   while ( depth > 0 && levels[depth].index >= levels[depth].g->childCount() )
     344                 :            :   {
     345                 :         74 :     --depth;
     346                 :         74 :     ++levels[depth].index;
     347                 :            :   }
     348                 :            : 
     349                 :        233 :   digDown();  // go to the leaf level again
     350                 :            : 
     351                 :        233 :   return *this;
     352                 :        233 : }
     353                 :            : 
     354                 :        206 : QgsAbstractGeometry::vertex_iterator QgsAbstractGeometry::vertex_iterator::operator++( int )
     355                 :            : {
     356                 :        206 :   vertex_iterator it( *this );
     357                 :        206 :   ++*this;
     358                 :        206 :   return it;
     359                 :            : }
     360                 :            : 
     361                 :        233 : QgsPoint QgsAbstractGeometry::vertex_iterator::operator*() const
     362                 :            : {
     363                 :            :   Q_ASSERT( !levels[depth].g->hasChildGeometries() );
     364                 :        233 :   return levels[depth].g->childPoint( levels[depth].index );
     365                 :            : }
     366                 :            : 
     367                 :         27 : QgsVertexId QgsAbstractGeometry::vertex_iterator::vertexId() const
     368                 :            : {
     369                 :         27 :   int part = 0, ring = 0, vertex = levels[depth].index;
     370                 :         27 :   if ( depth == 0 )
     371                 :            :   {
     372                 :            :     // nothing else to do
     373                 :          3 :   }
     374                 :         24 :   else if ( depth == 1 )
     375                 :            :   {
     376                 :          8 :     if ( QgsWkbTypes::isMultiType( levels[0].g->wkbType() ) )
     377                 :          8 :       part = levels[0].index;
     378                 :            :     else
     379                 :          0 :       ring = levels[0].index;
     380                 :          8 :   }
     381                 :         16 :   else if ( depth == 2 )
     382                 :            :   {
     383                 :         16 :     part = levels[0].index;
     384                 :         16 :     ring = levels[1].index;
     385                 :         16 :   }
     386                 :            :   else
     387                 :            :   {
     388                 :            :     Q_ASSERT( false );
     389                 :          0 :     return QgsVertexId();
     390                 :            :   }
     391                 :            : 
     392                 :            :   // get the vertex type: find out from the leaf geometry
     393                 :         27 :   QgsVertexId::VertexType vertexType = QgsVertexId::SegmentVertex;
     394                 :         27 :   if ( const QgsCurve *curve = dynamic_cast<const QgsCurve *>( levels[depth].g ) )
     395                 :            :   {
     396                 :         24 :     QgsPoint p;
     397                 :         24 :     curve->pointAt( vertex, p, vertexType );
     398                 :         24 :   }
     399                 :            : 
     400                 :         27 :   return QgsVertexId( part, ring, vertex, vertexType );
     401                 :         27 : }
     402                 :            : 
     403                 :        247 : bool QgsAbstractGeometry::vertex_iterator::operator==( const QgsAbstractGeometry::vertex_iterator &other ) const
     404                 :            : {
     405                 :        247 :   if ( depth != other.depth )
     406                 :        201 :     return false;
     407                 :         46 :   return std::equal( std::begin( levels ), std::begin( levels ) + depth + 1, std::begin( other.levels ) );
     408                 :        247 : }
     409                 :            : 
     410                 :        556 : void QgsAbstractGeometry::vertex_iterator::digDown()
     411                 :            : {
     412                 :        556 :   if ( levels[depth].g->hasChildGeometries() && levels[depth].index >= levels[depth].g->childCount() )
     413                 :        300 :     return;  // first check we are not already at the end
     414                 :            : 
     415                 :            :   // while not "final" depth for the geom: go one level down.
     416                 :        330 :   while ( levels[depth].g->hasChildGeometries() )
     417                 :            :   {
     418                 :         74 :     ++depth;
     419                 :            :     Q_ASSERT( depth < 3 );  // that's capacity of the levels array
     420                 :         74 :     levels[depth].index = 0;
     421                 :         74 :     levels[depth].g = levels[depth - 1].g->childGeometry( levels[depth - 1].index );
     422                 :            :   }
     423                 :        556 : }
     424                 :            : 
     425                 :        206 : QgsPoint QgsVertexIterator::next()
     426                 :            : {
     427                 :        206 :   n = i++;
     428                 :        206 :   return *n;
     429                 :            : }
     430                 :            : 
     431                 :         49 : QgsAbstractGeometry::part_iterator::part_iterator( QgsAbstractGeometry *g, int index )
     432                 :         49 :   : mIndex( index )
     433                 :         49 :   , mGeometry( g )
     434                 :            : {
     435                 :         49 : }
     436                 :            : 
     437                 :         31 : QgsAbstractGeometry::part_iterator &QgsAbstractGeometry::part_iterator::operator++()
     438                 :            : {
     439                 :         31 :   const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( mGeometry );
     440                 :         31 :   if ( !collection )
     441                 :            :   {
     442                 :          1 :     mIndex = 1;
     443                 :          1 :     return *this; // end of geometry -- nowhere else to go
     444                 :            :   }
     445                 :            : 
     446                 :         30 :   if ( mIndex >= collection->partCount() )
     447                 :          0 :     return *this; // end of geometry - nowhere else to go
     448                 :            : 
     449                 :         30 :   mIndex++;
     450                 :         30 :   return *this;
     451                 :         31 : }
     452                 :            : 
     453                 :         31 : QgsAbstractGeometry::part_iterator QgsAbstractGeometry::part_iterator::operator++( int )
     454                 :            : {
     455                 :         31 :   part_iterator it( *this );
     456                 :         31 :   ++*this;
     457                 :         31 :   return it;
     458                 :            : }
     459                 :            : 
     460                 :         31 : QgsAbstractGeometry *QgsAbstractGeometry::part_iterator::operator*() const
     461                 :            : {
     462                 :         31 :   QgsGeometryCollection *collection = qgsgeometry_cast< QgsGeometryCollection * >( mGeometry );
     463                 :         31 :   if ( !collection )
     464                 :            :   {
     465                 :          1 :     return mGeometry;
     466                 :            :   }
     467                 :            : 
     468                 :         30 :   return collection->geometryN( mIndex );
     469                 :         31 : }
     470                 :            : 
     471                 :          0 : int QgsAbstractGeometry::part_iterator::partNumber() const
     472                 :            : {
     473                 :          0 :   return mIndex;
     474                 :            : }
     475                 :            : 
     476                 :         37 : bool QgsAbstractGeometry::part_iterator::operator==( QgsAbstractGeometry::part_iterator other ) const
     477                 :            : {
     478                 :         37 :   return mGeometry == other.mGeometry && mIndex == other.mIndex;
     479                 :            : }
     480                 :            : 
     481                 :         31 : QgsAbstractGeometry *QgsGeometryPartIterator::next()
     482                 :            : {
     483                 :         31 :   n = i++;
     484                 :         31 :   return *n;
     485                 :            : }
     486                 :            : 
     487                 :            : 
     488                 :            : 
     489                 :          4 : QgsAbstractGeometry::const_part_iterator::const_part_iterator( const QgsAbstractGeometry *g, int index )
     490                 :          4 :   : mIndex( index )
     491                 :          4 :   , mGeometry( g )
     492                 :            : {
     493                 :          4 : }
     494                 :            : 
     495                 :          1 : QgsAbstractGeometry::const_part_iterator &QgsAbstractGeometry::const_part_iterator::operator++()
     496                 :            : {
     497                 :          1 :   const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( mGeometry );
     498                 :          1 :   if ( !collection )
     499                 :            :   {
     500                 :          1 :     mIndex = 1;
     501                 :          1 :     return *this; // end of geometry -- nowhere else to go
     502                 :            :   }
     503                 :            : 
     504                 :          0 :   if ( mIndex >= collection->partCount() )
     505                 :          0 :     return *this; // end of geometry - nowhere else to go
     506                 :            : 
     507                 :          0 :   mIndex++;
     508                 :          0 :   return *this;
     509                 :          1 : }
     510                 :            : 
     511                 :          1 : QgsAbstractGeometry::const_part_iterator QgsAbstractGeometry::const_part_iterator::operator++( int )
     512                 :            : {
     513                 :          1 :   const_part_iterator it( *this );
     514                 :          1 :   ++*this;
     515                 :          1 :   return it;
     516                 :            : }
     517                 :            : 
     518                 :          1 : const QgsAbstractGeometry *QgsAbstractGeometry::const_part_iterator::operator*() const
     519                 :            : {
     520                 :          1 :   const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( mGeometry );
     521                 :          1 :   if ( !collection )
     522                 :            :   {
     523                 :          1 :     return mGeometry;
     524                 :            :   }
     525                 :            : 
     526                 :          0 :   return collection->geometryN( mIndex );
     527                 :          1 : }
     528                 :            : 
     529                 :          0 : int QgsAbstractGeometry::const_part_iterator::partNumber() const
     530                 :            : {
     531                 :          0 :   return mIndex;
     532                 :            : }
     533                 :            : 
     534                 :          2 : bool QgsAbstractGeometry::const_part_iterator::operator==( QgsAbstractGeometry::const_part_iterator other ) const
     535                 :            : {
     536                 :          2 :   return mGeometry == other.mGeometry && mIndex == other.mIndex;
     537                 :            : }
     538                 :            : 
     539                 :          1 : const QgsAbstractGeometry *QgsGeometryConstPartIterator::next()
     540                 :            : {
     541                 :          1 :   n = i++;
     542                 :          1 :   return *n;
     543                 :            : }
     544                 :            : 
     545                 :         46 : bool QgsAbstractGeometry::vertex_iterator::Level::operator==( const QgsAbstractGeometry::vertex_iterator::Level &other ) const
     546                 :            : {
     547                 :         46 :   return g == other.g && index == other.index;
     548                 :            : }

Generated by: LCOV version 1.14