Skip to content

Commit

Permalink
Cache generated WKT if it's in the preferred format
Browse files Browse the repository at this point in the history
Some frequently called code paths call this, and it's rather costly
to calculate on the proj side.

(cherry picked from commit 65296e9)
  • Loading branch information
nyalldawson committed May 15, 2020
1 parent e37310d commit 8b245c0
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
28 changes: 27 additions & 1 deletion src/core/qgscoordinatereferencesystem.cpp
Expand Up @@ -597,6 +597,7 @@ bool QgsCoordinateReferenceSystem::loadFromDatabase( const QString &db, const QS

QgsDebugMsgLevel( "load CRS from " + db + " where " + expression + " is " + value, 3 );
d->mIsValid = false;
d->mWktPreferred.clear();

QFileInfo myInfo( db );
if ( !myInfo.exists() )
Expand Down Expand Up @@ -644,6 +645,7 @@ bool QgsCoordinateReferenceSystem::loadFromDatabase( const QString &db, const QS
d->mEllipsoidAcronym = statement.columnAsText( 3 );
#endif
d->mProj4 = statement.columnAsText( 4 );
d->mWktPreferred.clear();
d->mSRID = statement.columnAsText( 5 ).toLong();
d->mAuthId = statement.columnAsText( 6 );
d->mIsGeographic = statement.columnAsText( 7 ).toInt() != 0;
Expand Down Expand Up @@ -841,6 +843,7 @@ bool QgsCoordinateReferenceSystem::createFromWkt( const QString &wkt )

d->mIsValid = false;
d->mProj4.clear();
d->mWktPreferred.clear();
if ( wkt.isEmpty() )
{
QgsDebugMsgLevel( QStringLiteral( "theWkt is uninitialized, operation failed" ), 4 );
Expand Down Expand Up @@ -899,6 +902,7 @@ bool QgsCoordinateReferenceSystem::createFromProj( const QString &projString )
{
d->mIsValid = false;
d->mProj4.clear();
d->mWktPreferred.clear();
return false;
}

Expand Down Expand Up @@ -928,6 +932,7 @@ bool QgsCoordinateReferenceSystem::createFromProj( const QString &projString )
myProj4String = myProj4String.trimmed();

d->mIsValid = false;
d->mWktPreferred.clear();
#if PROJ_VERSION_MAJOR>=6
// first, try to use proj to do this for us...
const QString projCrsString = myProj4String + ( myProj4String.contains( QStringLiteral( "+type=crs" ) ) ? QString() : QStringLiteral( " +type=crs" ) );
Expand Down Expand Up @@ -1466,6 +1471,7 @@ void QgsCoordinateReferenceSystem::setProjString( const QString &proj4String )
{
d.detach();
d->mProj4 = proj4String;
d->mWktPreferred.clear();

QgsLocaleNumC l;
QString trimmed = proj4String.trimmed();
Expand Down Expand Up @@ -1521,6 +1527,7 @@ bool QgsCoordinateReferenceSystem::setWktString( const QString &wkt, bool allowP
{
bool res = false;
d->mIsValid = false;
d->mWktPreferred.clear();

#if PROJ_VERSION_MAJOR>=6
// TODO - remove allowProjFallback when we require proj 6+ to build
Expand Down Expand Up @@ -1896,6 +1903,13 @@ QString QgsCoordinateReferenceSystem::toWkt( WktVariant variant, bool multiline,
#if PROJ_VERSION_MAJOR>=6
if ( PJ *obj = d->threadLocalProjObject() )
{
const bool isDefaultPreferredFormat = variant == WKT_PREFERRED && !multiline;
if ( isDefaultPreferredFormat && !d->mWktPreferred.isEmpty() )
{
// can use cached value
return d->mWktPreferred;
}

PJ_WKT_TYPE type = PJ_WKT1_GDAL;
switch ( variant )
{
Expand All @@ -1922,7 +1936,15 @@ QString QgsCoordinateReferenceSystem::toWkt( WktVariant variant, bool multiline,
const QByteArray multiLineOption = QStringLiteral( "MULTILINE=%1" ).arg( multiline ? QStringLiteral( "YES" ) : QStringLiteral( "NO" ) ).toLocal8Bit();
const QByteArray indentatationWidthOption = QStringLiteral( "INDENTATION_WIDTH=%1" ).arg( multiline ? QString::number( indentationWidth ) : QStringLiteral( "0" ) ).toLocal8Bit();
const char *const options[] = {multiLineOption.constData(), indentatationWidthOption.constData(), nullptr};
return QString( proj_as_wkt( QgsProjContext::get(), obj, type, options ) );
QString res = proj_as_wkt( QgsProjContext::get(), obj, type, options );

if ( isDefaultPreferredFormat )
{
// cache result for later use
d->mWktPreferred = res;
}

return res;
}
return QString();
#else
Expand Down Expand Up @@ -2024,6 +2046,8 @@ bool QgsCoordinateReferenceSystem::readXml( const QDomNode &node )
node = srsNode.namedItem( QStringLiteral( "geographicflag" ) );
d->mIsGeographic = node.toElement().text().compare( QLatin1String( "true" ) );

d->mWktPreferred.clear();

//make sure the map units have been set
setMapUnits();
}
Expand Down Expand Up @@ -2384,6 +2408,7 @@ bool QgsCoordinateReferenceSystem::loadFromAuthCode( const QString &auth, const
{
d.detach();
d->mIsValid = false;
d->mWktPreferred.clear();

PJ_CONTEXT *pjContext = QgsProjContext::get();
QgsProjUtils::proj_pj_unique_ptr crs( proj_create_from_database( pjContext, auth.toUtf8().constData(), code.toUtf8().constData(), PJ_CATEGORY_CRS, false, nullptr ) );
Expand All @@ -2409,6 +2434,7 @@ bool QgsCoordinateReferenceSystem::loadFromAuthCode( const QString &auth, const

d->mIsValid = true;
d->mProj4 = proj4;
d->mWktPreferred.clear();
d->mDescription = QString( proj_get_name( crs.get() ) );
d->mAuthId = QStringLiteral( "%1:%2" ).arg( auth, code );
d->mIsGeographic = testIsGeographic( crs.get() );
Expand Down
3 changes: 2 additions & 1 deletion src/core/qgscoordinatereferencesystem_p.h
Expand Up @@ -71,6 +71,7 @@ class QgsCoordinateReferenceSystemPrivate : public QSharedData
, mCRS( nullptr )
#endif
, mProj4( other.mProj4 )
, mWktPreferred( other.mWktPreferred )
, mAxisInvertedDirty( other.mAxisInvertedDirty )
, mAxisInverted( other.mAxisInverted )
{
Expand Down Expand Up @@ -178,7 +179,7 @@ class QgsCoordinateReferenceSystemPrivate : public QSharedData

mutable QString mProj4;

mutable QString mWkt
mutable QString mWktPreferred;

//! True if presence of an inverted axis needs to be recalculated
mutable bool mAxisInvertedDirty = false;
Expand Down

0 comments on commit 8b245c0

Please sign in to comment.