From 43d5b0c8b3e000bd7b09d132fceba431779ce2dd Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 10 Mar 2021 14:20:21 +1000 Subject: [PATCH] Optimise two heavily used methods in QgsLineString --- src/core/geometry/qgslinestring.cpp | 36 ++++++++++++++++------------- src/core/geometry/qgslinestring.h | 1 + 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/core/geometry/qgslinestring.cpp b/src/core/geometry/qgslinestring.cpp index f3581eab7cc6..e5a2af5d2fb6 100644 --- a/src/core/geometry/qgslinestring.cpp +++ b/src/core/geometry/qgslinestring.cpp @@ -375,6 +375,18 @@ bool QgsLineString::removeDuplicateNodes( double epsilon, bool useZValues ) return result; } +bool QgsLineString::isClosed() const +{ + if ( mX.empty() ) + return false; + + bool closed = qgsDoubleNear( mX.first(), mX.last() ) && + qgsDoubleNear( mY.first(), mY.last() ); + if ( is3D() && closed ) + closed &= qgsDoubleNear( mZ.first(), mZ.last() ) || ( std::isnan( mZ.first() ) && std::isnan( mZ.last() ) ); + return closed; +} + QVector< QgsVertexId > QgsLineString::collectDuplicateNodes( double epsilon, bool useZValues ) const { QVector< QgsVertexId > res; @@ -448,23 +460,15 @@ bool QgsLineString::fromWkb( QgsConstWkbPtr &wkbPtr ) QgsRectangle QgsLineString::calculateBoundingBox() const { - double xmin = std::numeric_limits::max(); - double ymin = std::numeric_limits::max(); - double xmax = -std::numeric_limits::max(); - double ymax = -std::numeric_limits::max(); + if ( mX.empty() ) + return QgsRectangle(); - const int nb = mX.size(); - const double *x = mX.constData(); - const double *y = mY.constData(); - for ( int i = 0; i < nb; ++i ) - { - const double px = *x++; - xmin = std::min( xmin, px ); - xmax = std::max( xmax, px ); - const double py = *y++; - ymin = std::min( ymin, py ); - ymax = std::max( ymax, py ); - } + auto result = std::minmax_element( mX.begin(), mX.end() ); + const double xmin = *result.first; + const double xmax = *result.second; + result = std::minmax_element( mY.begin(), mY.end() ); + const double ymin = *result.first; + const double ymax = *result.second; return QgsRectangle( xmin, ymin, xmax, ymax, false ); } diff --git a/src/core/geometry/qgslinestring.h b/src/core/geometry/qgslinestring.h index 7975b8e1b9de..d04bd3767700 100644 --- a/src/core/geometry/qgslinestring.h +++ b/src/core/geometry/qgslinestring.h @@ -590,6 +590,7 @@ class CORE_EXPORT QgsLineString: public QgsCurve bool isValid( QString &error SIP_OUT, int flags = 0 ) const override; QgsLineString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY; bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits::epsilon(), bool useZValues = false ) override; + bool isClosed() const override SIP_HOLDGIL; /** * Returns a list of any duplicate nodes contained in the geometry, within the specified tolerance.