mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-17 00:04:02 -04:00
Avoid some crs db lookups on proj 6 builds
This commit is contained in:
parent
0b52a37cad
commit
8a4d306161
@ -383,6 +383,27 @@ bool QgsCoordinateReferenceSystem::createFromOgcWmsCrs( const QString &crs )
|
||||
}
|
||||
}
|
||||
|
||||
#if PROJ_VERSION_MAJOR>=6
|
||||
// first chance for proj 6 - scan through legacy systems and try to use authid directly
|
||||
const QString legacyKey = wmsCrs.toLower();
|
||||
for ( auto it = sAuthIdToQgisSrsIdMap.constBegin(); it != sAuthIdToQgisSrsIdMap.constEnd(); ++it )
|
||||
{
|
||||
if ( it.key().compare( legacyKey, Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
const QStringList parts = it.key().split( ':' );
|
||||
const QString auth = parts.at( 0 );
|
||||
const QString code = parts.at( 1 );
|
||||
if ( loadFromAuthCode( auth, code ) )
|
||||
{
|
||||
sOgcLock.lockForWrite();
|
||||
sOgcCache.insert( crs, *this );
|
||||
sOgcLock.unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( loadFromDatabase( QgsApplication::srsDatabaseFilePath(), QStringLiteral( "lower(auth_name||':'||auth_id)" ), wmsCrs.toLower() ) )
|
||||
{
|
||||
sOgcLock.lockForWrite();
|
||||
@ -463,6 +484,27 @@ bool QgsCoordinateReferenceSystem::createFromSrid( const long id )
|
||||
}
|
||||
sSrIdCacheLock.unlock();
|
||||
|
||||
#if PROJ_VERSION_MAJOR>=6
|
||||
// first chance for proj 6 - scan through legacy systems and try to use authid directly
|
||||
for ( auto it = sAuthIdToQgisSrsIdMap.constBegin(); it != sAuthIdToQgisSrsIdMap.constEnd(); ++it )
|
||||
{
|
||||
if ( it.value().endsWith( QStringLiteral( ",%1" ).arg( id ) ) )
|
||||
{
|
||||
const QStringList parts = it.key().split( ':' );
|
||||
const QString auth = parts.at( 0 );
|
||||
const QString code = parts.at( 1 );
|
||||
if ( loadFromAuthCode( auth, code ) )
|
||||
{
|
||||
sSrIdCacheLock.lockForWrite();
|
||||
sSrIdCache.insert( id, *this );
|
||||
sSrIdCacheLock.unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool result = loadFromDatabase( QgsApplication::srsDatabaseFilePath(), QStringLiteral( "srid" ), QString::number( id ) );
|
||||
|
||||
sSrIdCacheLock.lockForWrite();
|
||||
@ -485,6 +527,27 @@ bool QgsCoordinateReferenceSystem::createFromSrsId( const long id )
|
||||
}
|
||||
sCRSSrsIdLock.unlock();
|
||||
|
||||
#if PROJ_VERSION_MAJOR>=6
|
||||
// first chance for proj 6 - scan through legacy systems and try to use authid directly
|
||||
for ( auto it = sAuthIdToQgisSrsIdMap.constBegin(); it != sAuthIdToQgisSrsIdMap.constEnd(); ++it )
|
||||
{
|
||||
if ( it.value().startsWith( QString::number( id ) + ',' ) )
|
||||
{
|
||||
const QStringList parts = it.key().split( ':' );
|
||||
const QString auth = parts.at( 0 );
|
||||
const QString code = parts.at( 1 );
|
||||
if ( loadFromAuthCode( auth, code ) )
|
||||
{
|
||||
sCRSSrsIdLock.lockForWrite();
|
||||
sSrsIdCache.insert( id, *this );
|
||||
sCRSSrsIdLock.unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool result = loadFromDatabase( id < USER_CRS_START_ID ? QgsApplication::srsDatabaseFilePath() :
|
||||
QgsApplication::qgisUserDatabaseFilePath(),
|
||||
QStringLiteral( "srs_id" ), QString::number( id ) );
|
||||
@ -696,12 +759,13 @@ bool QgsCoordinateReferenceSystem::createFromWkt( const QString &wkt )
|
||||
const QString authCode( proj_get_id_code( d->mPj.get(), 0 ) );
|
||||
if ( !authName.isEmpty() && !authCode.isEmpty() )
|
||||
{
|
||||
const QString authid = QStringLiteral( "%1:%2" ).arg( authName, authCode );
|
||||
bool result = createFromOgcWmsCrs( authid );
|
||||
sCRSWktLock.lockForWrite();
|
||||
sWktCache.insert( wkt, *this );
|
||||
sCRSWktLock.unlock();
|
||||
return result;
|
||||
if ( loadFromAuthCode( authName, authCode ) )
|
||||
{
|
||||
sCRSWktLock.lockForWrite();
|
||||
sWktCache.insert( wkt, *this );
|
||||
sCRSWktLock.unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
@ -874,11 +938,13 @@ bool QgsCoordinateReferenceSystem::createFromProj4( const QString &proj4String )
|
||||
if ( !authName.isEmpty() && !authCode.isEmpty() )
|
||||
{
|
||||
const QString authid = QStringLiteral( "%1:%2" ).arg( authName, authCode );
|
||||
const bool result = createFromOgcWmsCrs( authid );
|
||||
sProj4CacheLock.lockForWrite();
|
||||
sProj4Cache.insert( proj4String, *this );
|
||||
sProj4CacheLock.unlock();
|
||||
return result;
|
||||
if ( createFromOgcWmsCrs( authid ) )
|
||||
{
|
||||
sProj4CacheLock.lockForWrite();
|
||||
sProj4Cache.insert( proj4String, *this );
|
||||
sProj4CacheLock.unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2064,6 +2130,127 @@ long QgsCoordinateReferenceSystem::getRecordCount()
|
||||
return myRecordCount;
|
||||
}
|
||||
|
||||
#if PROJ_VERSION_MAJOR>=6
|
||||
bool testIsGeographic( PJ *crs )
|
||||
{
|
||||
PJ_CONTEXT *pjContext = QgsProjContext::get();
|
||||
bool isGeographic = false;
|
||||
QgsProjUtils::proj_pj_unique_ptr coordinateSystem( proj_crs_get_coordinate_system( pjContext, crs ) );
|
||||
if ( coordinateSystem )
|
||||
{
|
||||
const int axisCount = proj_cs_get_axis_count( pjContext, coordinateSystem.get() );
|
||||
if ( axisCount > 0 )
|
||||
{
|
||||
const char *outUnitAuthName = nullptr;
|
||||
const char *outUnitAuthCode = nullptr;
|
||||
// Read only first axis
|
||||
proj_cs_get_axis_info( pjContext, coordinateSystem.get(), 0,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&outUnitAuthName,
|
||||
&outUnitAuthCode );
|
||||
|
||||
if ( outUnitAuthName && outUnitAuthCode )
|
||||
{
|
||||
const char *unitCategory = nullptr;
|
||||
if ( proj_uom_get_info_from_database( pjContext, outUnitAuthName, outUnitAuthCode, nullptr, nullptr, &unitCategory ) )
|
||||
{
|
||||
isGeographic = QString( unitCategory ).compare( QLatin1String( "angular" ), Qt::CaseInsensitive ) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return isGeographic;
|
||||
}
|
||||
|
||||
void getOperationAndEllipsoidFromProjString( const QString &proj, QString &operation, QString &ellipsoid )
|
||||
{
|
||||
QRegExp projRegExp( "\\+proj=(\\S+)" );
|
||||
if ( projRegExp.indexIn( proj ) < 0 )
|
||||
{
|
||||
QgsDebugMsgLevel( QStringLiteral( "no +proj argument found [%2]" ).arg( proj ), 2 );
|
||||
return;
|
||||
}
|
||||
operation = projRegExp.cap( 1 );
|
||||
|
||||
QRegExp ellipseRegExp( "\\+(?:ellps|datum)=(\\S+)" );
|
||||
QString ellps;
|
||||
if ( ellipseRegExp.indexIn( proj ) >= 0 )
|
||||
{
|
||||
ellipsoid = ellipseRegExp.cap( 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// satisfy not null constraint on ellipsoid_acronym field
|
||||
// possibly we should drop the constraint, yet the crses with missing ellipsoid_acronym are malformed
|
||||
// and will result in oddities within other areas of QGIS (e.g. project ellipsoid won't be correctly
|
||||
// set for these CRSes). Better just hack around and make the constraint happy for now,
|
||||
// and hope that the definitions get corrected in future.
|
||||
ellipsoid = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool QgsCoordinateReferenceSystem::loadFromAuthCode( const QString &auth, const QString &code )
|
||||
{
|
||||
d.detach();
|
||||
d->mIsValid = false;
|
||||
d->mWkt.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 ) );
|
||||
if ( !crs )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ( proj_get_type( crs.get() ) )
|
||||
{
|
||||
case PJ_TYPE_VERTICAL_CRS:
|
||||
return false;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
crs = QgsProjUtils::crsToSingleCrs( crs.get() );
|
||||
|
||||
QString proj4 = getFullProjString( crs.get() );
|
||||
proj4.replace( QStringLiteral( "+type=crs" ), QString() );
|
||||
proj4 = proj4.trimmed();
|
||||
|
||||
d->mIsValid = true;
|
||||
d->mProj4 = proj4;
|
||||
d->mDescription = QString( proj_get_name( crs.get() ) );
|
||||
d->mAuthId = QStringLiteral( "%1:%2" ).arg( auth, code );
|
||||
d->mIsGeographic = testIsGeographic( crs.get() );
|
||||
d->mAxisInvertedDirty = true;
|
||||
QString operation;
|
||||
QString ellipsoid;
|
||||
getOperationAndEllipsoidFromProjString( proj4, operation, ellipsoid );
|
||||
d->mProjectionAcronym = operation;
|
||||
d->mEllipsoidAcronym = ellipsoid;
|
||||
d->mPj = std::move( crs );
|
||||
|
||||
const QString dbVals = sAuthIdToQgisSrsIdMap.value( QStringLiteral( "%1:%2" ).arg( auth, code ).toUpper() );
|
||||
QString srsId;
|
||||
QString srId;
|
||||
if ( !dbVals.isEmpty() )
|
||||
{
|
||||
const QStringList parts = dbVals.split( ',' );
|
||||
d->mSrsId = parts.at( 0 ).toInt();
|
||||
d->mSRID = parts.at( 1 ).toInt();
|
||||
}
|
||||
|
||||
setMapUnits();
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PROJ_VERSION_MAJOR<6
|
||||
// adapted from gdal/ogr/ogr_srs_dict.cpp
|
||||
bool QgsCoordinateReferenceSystem::loadWkts( QHash<int, QString> &wkts, const char *filename )
|
||||
@ -2333,63 +2520,10 @@ int QgsCoordinateReferenceSystem::syncDatabase()
|
||||
}
|
||||
else
|
||||
{
|
||||
// ideally we'd be getting these using the proj api -- but that's not possible
|
||||
|
||||
QRegExp projRegExp( "\\+proj=(\\S+)" );
|
||||
if ( projRegExp.indexIn( proj4 ) < 0 )
|
||||
{
|
||||
QgsDebugMsg( QStringLiteral( "%1:%2: no +proj argument found [%2]" ).arg( authority, code, proj4 ) );
|
||||
continue;
|
||||
}
|
||||
const QString operation = projRegExp.cap( 1 );
|
||||
|
||||
QRegExp ellipseRegExp( "\\+ellps=(\\S+)" );
|
||||
QString operation;
|
||||
QString ellps;
|
||||
if ( ellipseRegExp.indexIn( proj4 ) >= 0 )
|
||||
{
|
||||
ellps = ellipseRegExp.cap( 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// satisfy not null constraint on ellipsoid_acronym field
|
||||
// possibly we should drop the constraint, yet the crses with missing ellipsoid_acronym are malformed
|
||||
// and will result in oddities within other areas of QGIS (e.g. project ellipsoid won't be correctly
|
||||
// set for these CRSes). Better just hack around and make the constraint happy for now,
|
||||
// and hope that the definitions get corrected in future.
|
||||
ellps = "";
|
||||
}
|
||||
|
||||
|
||||
bool isGeographic = false;
|
||||
|
||||
QgsProjUtils::proj_pj_unique_ptr coordinateSystem( proj_crs_get_coordinate_system( pjContext, crs.get() ) );
|
||||
if ( coordinateSystem )
|
||||
{
|
||||
const int axisCount = proj_cs_get_axis_count( pjContext, coordinateSystem.get() );
|
||||
if ( axisCount > 0 )
|
||||
{
|
||||
const char *outUnitAuthName = nullptr;
|
||||
const char *outUnitAuthCode = nullptr;
|
||||
// Read only first axis
|
||||
proj_cs_get_axis_info( pjContext, coordinateSystem.get(), 0,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&outUnitAuthName,
|
||||
&outUnitAuthCode );
|
||||
|
||||
if ( outUnitAuthName && outUnitAuthCode )
|
||||
{
|
||||
const char *unitCategory = nullptr;
|
||||
if ( proj_uom_get_info_from_database( pjContext, outUnitAuthName, outUnitAuthCode, nullptr, nullptr, &unitCategory ) )
|
||||
{
|
||||
isGeographic = QString( unitCategory ).compare( QLatin1String( "angular" ), Qt::CaseInsensitive ) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getOperationAndEllipsoidFromProjString( proj4, operation, ellps );
|
||||
const bool isGeographic = testIsGeographic( crs.get() );
|
||||
|
||||
// work out srid and srsid
|
||||
const QString dbVals = sAuthIdToQgisSrsIdMap.value( QStringLiteral( "%1:%2" ).arg( authority, code ) );
|
||||
|
@ -781,6 +781,10 @@ class CORE_EXPORT QgsCoordinateReferenceSystem
|
||||
//! Helper for getting number of user CRS already in db
|
||||
long getRecordCount();
|
||||
|
||||
#if PROJ_VERSION_MAJOR>=6
|
||||
bool loadFromAuthCode( const QString &auth, const QString &code );
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize the CRS object by looking up CRS database in path given in db argument,
|
||||
* using first CRS entry where expression = 'value'
|
||||
|
@ -701,7 +701,7 @@ void TestQgsCoordinateReferenceSystem::ellipsoidAcronym()
|
||||
myCrs.createFromSrid( GEOSRID );
|
||||
QString myAcronym = myCrs.ellipsoidAcronym();
|
||||
debugPrint( myCrs );
|
||||
QVERIFY( myAcronym == "WGS84" );
|
||||
QCOMPARE( myAcronym, QStringLiteral( "WGS84" ) );
|
||||
}
|
||||
void TestQgsCoordinateReferenceSystem::toWkt()
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user