diff --git a/python/core/auto_generated/geometry/qgscurve.sip.in b/python/core/auto_generated/geometry/qgscurve.sip.in index acb8d292752..6a88668a466 100644 --- a/python/core/auto_generated/geometry/qgscurve.sip.in +++ b/python/core/auto_generated/geometry/qgscurve.sip.in @@ -323,6 +323,7 @@ Scrolls the curve vertices so that they start with the vertex at the given index + }; /************************************************************************ diff --git a/src/core/geometry/qgscircularstring.cpp b/src/core/geometry/qgscircularstring.cpp index 9d95e4608d9..c3b1c31f828 100644 --- a/src/core/geometry/qgscircularstring.cpp +++ b/src/core/geometry/qgscircularstring.cpp @@ -1347,8 +1347,14 @@ bool QgsCircularString::pointAt( int node, QgsPoint &point, Qgis::VertexType &ty void QgsCircularString::sumUpArea( double &sum ) const { - int maxIndex = numPoints() - 2; + if ( mHasCachedSummedUpArea ) + { + sum += mSummedUpArea; + return; + } + int maxIndex = numPoints() - 2; + mSummedUpArea = 0; for ( int i = 0; i < maxIndex; i += 2 ) { QgsPoint p1( mX[i], mY[i] ); @@ -1359,11 +1365,11 @@ void QgsCircularString::sumUpArea( double &sum ) const if ( p1 == p3 ) { double r2 = QgsGeometryUtils::sqrDistance2D( p1, p2 ) / 4.0; - sum += M_PI * r2; + mSummedUpArea += M_PI * r2; continue; } - sum += 0.5 * ( mX[i] * mY[i + 2] - mY[i] * mX[i + 2] ); + mSummedUpArea += 0.5 * ( mX[i] * mY[i + 2] - mY[i] * mX[i + 2] ); //calculate area between circle and chord, then sum / subtract from total area double midPointX = ( p1.x() + p3.x() ) / 2.0; @@ -1397,13 +1403,16 @@ void QgsCircularString::sumUpArea( double &sum ) const if ( !circlePointLeftOfLine ) { - sum += circleChordArea; + mSummedUpArea += circleChordArea; } else { - sum -= circleChordArea; + mSummedUpArea -= circleChordArea; } } + + mHasCachedSummedUpArea = true; + sum += mSummedUpArea; } bool QgsCircularString::hasCurvedSegments() const diff --git a/src/core/geometry/qgscompoundcurve.cpp b/src/core/geometry/qgscompoundcurve.cpp index e02bc75b07a..965464341ce 100644 --- a/src/core/geometry/qgscompoundcurve.cpp +++ b/src/core/geometry/qgscompoundcurve.cpp @@ -1148,10 +1148,19 @@ std::tuple, std::unique_ptr > QgsCompoundCur void QgsCompoundCurve::sumUpArea( double &sum ) const { + if ( mHasCachedSummedUpArea ) + { + sum += mSummedUpArea; + return; + } + + mSummedUpArea = 0; for ( const QgsCurve *curve : mCurves ) { - curve->sumUpArea( sum ); + curve->sumUpArea( mSummedUpArea ); } + mHasCachedSummedUpArea = true; + sum += mSummedUpArea; } void QgsCompoundCurve::close() diff --git a/src/core/geometry/qgscurve.cpp b/src/core/geometry/qgscurve.cpp index ec8e5caed8c..bef68b8cc1e 100644 --- a/src/core/geometry/qgscurve.cpp +++ b/src/core/geometry/qgscurve.cpp @@ -295,6 +295,7 @@ void QgsCurve::clearCache() const mBoundingBox = QgsRectangle(); mHasCachedValidity = false; mValidityFailureReason.clear(); + mHasCachedSummedUpArea = false; QgsAbstractGeometry::clearCache(); } diff --git a/src/core/geometry/qgscurve.h b/src/core/geometry/qgscurve.h index f3e71deea4f..5852a5f0b7d 100644 --- a/src/core/geometry/qgscurve.h +++ b/src/core/geometry/qgscurve.h @@ -341,6 +341,9 @@ class CORE_EXPORT QgsCurve: public QgsAbstractGeometry SIP_ABSTRACT */ mutable QgsRectangle mBoundingBox; + mutable bool mHasCachedSummedUpArea = false; + mutable double mSummedUpArea = 0; + private: mutable bool mHasCachedValidity = false; diff --git a/src/core/geometry/qgslinestring.cpp b/src/core/geometry/qgslinestring.cpp index 4b9a04d357c..328f0548629 100644 --- a/src/core/geometry/qgslinestring.cpp +++ b/src/core/geometry/qgslinestring.cpp @@ -1936,6 +1936,13 @@ QgsPoint QgsLineString::centroid() const void QgsLineString::sumUpArea( double &sum ) const { + if ( mHasCachedSummedUpArea ) + { + sum += mSummedUpArea; + return; + } + + mSummedUpArea = 0; const int maxIndex = mX.size(); if ( maxIndex == 0 ) return; @@ -1946,10 +1953,13 @@ void QgsLineString::sumUpArea( double &sum ) const double prevY = *y++; for ( int i = 1; i < maxIndex; ++i ) { - sum += 0.5 * ( prevX * ( *y ) - prevY * ( *x ) ); + mSummedUpArea += 0.5 * ( prevX * ( *y ) - prevY * ( *x ) ); prevX = *x++; prevY = *y++; } + + mHasCachedSummedUpArea = true; + sum += mSummedUpArea; } void QgsLineString::importVerticesFromWkb( const QgsConstWkbPtr &wkb )