Skip to content

Commit

Permalink
Cache summed up area for curve geometry classes
Browse files Browse the repository at this point in the history
Avoids recalculation when area is retrieved multiple times
  • Loading branch information
nyalldawson committed Sep 28, 2022
1 parent 14324b5 commit 1c05421
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 7 deletions.
1 change: 1 addition & 0 deletions python/core/auto_generated/geometry/qgscurve.sip.in
Expand Up @@ -323,6 +323,7 @@ Scrolls the curve vertices so that they start with the vertex at the given index




};

/************************************************************************
Expand Down
19 changes: 14 additions & 5 deletions src/core/geometry/qgscircularstring.cpp
Expand Up @@ -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] );
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down
11 changes: 10 additions & 1 deletion src/core/geometry/qgscompoundcurve.cpp
Expand Up @@ -1148,10 +1148,19 @@ std::tuple<std::unique_ptr<QgsCurve>, std::unique_ptr<QgsCurve> > 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()
Expand Down
1 change: 1 addition & 0 deletions src/core/geometry/qgscurve.cpp
Expand Up @@ -295,6 +295,7 @@ void QgsCurve::clearCache() const
mBoundingBox = QgsRectangle();
mHasCachedValidity = false;
mValidityFailureReason.clear();
mHasCachedSummedUpArea = false;
QgsAbstractGeometry::clearCache();
}

Expand Down
3 changes: 3 additions & 0 deletions src/core/geometry/qgscurve.h
Expand Up @@ -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;
Expand Down
12 changes: 11 additions & 1 deletion src/core/geometry/qgslinestring.cpp
Expand Up @@ -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;
Expand All @@ -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 )
Expand Down

0 comments on commit 1c05421

Please sign in to comment.