Cache summed up area for curve geometry classes

Avoids recalculation when area is retrieved multiple times
This commit is contained in:
Nyall Dawson 2022-09-28 12:32:17 +10:00
parent 14324b5a4f
commit 1c05421486
6 changed files with 40 additions and 7 deletions

View File

@ -323,6 +323,7 @@ Scrolls the curve vertices so that they start with the vertex at the given index
};
/************************************************************************

View File

@ -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

View File

@ -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()

View File

@ -295,6 +295,7 @@ void QgsCurve::clearCache() const
mBoundingBox = QgsRectangle();
mHasCachedValidity = false;
mValidityFailureReason.clear();
mHasCachedSummedUpArea = false;
QgsAbstractGeometry::clearCache();
}

View File

@ -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;

View File

@ -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 )