Use QgsCRSCache instead of looking up CRS by srs id (refs #15193)

This commit is contained in:
Nyall Dawson 2016-07-05 13:35:01 +10:00
parent 9139872c9e
commit 339d061693
9 changed files with 61 additions and 10 deletions

View File

@ -77,6 +77,7 @@ class QgsCoordinateReferenceSystem
* @note Any members will be overwritten during this process.
* @param theSrsId The QGIS SrsId for the desired spatial reference system.
* @return bool TRUE if success else false
* @note this method is expensive. Consider using QgsCRSCache::crsBySrsId() instead.
*/
bool createFromSrsId( const long theSrsId );

View File

@ -71,6 +71,14 @@ class QgsCRSCache
*/
QgsCoordinateReferenceSystem crsByProj4( const QString& proj4 ) const;
/** Returns the CRS from a specified QGIS SRS ID.
* @param srsId internal QGIS SRS ID
* @returns matching CRS, or an invalid CRS if ID could not be found
* @note added in QGIS 2.16
* @see QgsCoordinateReferenceSystem::createFromSrsId()
*/
QgsCoordinateReferenceSystem crsBySrsId( long srsId ) const;
/** Updates the cached definition of a CRS. Should be called if the definition of a user-created
* CRS has been changed.
* @param authid CRS auth ID, eg "EPSG:4326" or "USER:100009"

View File

@ -124,6 +124,7 @@ class CORE_EXPORT QgsCoordinateReferenceSystem
* @note Any members will be overwritten during this process.
* @param theSrsId The QGIS SrsId for the desired spatial reference system.
* @return bool TRUE if success else false
* @note this method is expensive. Consider using QgsCRSCache::crsBySrsId() instead.
*/
bool createFromSrsId( const long theSrsId );

View File

@ -152,7 +152,7 @@ void QgsCoordinateTransform::setDestCRS( const QgsCoordinateReferenceSystem& the
void QgsCoordinateTransform::setDestCRSID( long theCRSID )
{
//!todo Add some logic here to determine if the srsid is a system or user one
mDestCRS.createFromSrsId( theCRSID );
mDestCRS = QgsCRSCache::instance()->crsBySrsId( theCRSID );
initialise();
}

View File

@ -143,7 +143,7 @@ QgsCoordinateReferenceSystem QgsCRSCache::crsByEpsgId( long epsg ) const
QgsCoordinateReferenceSystem QgsCRSCache::crsByProj4( const QString& proj4 ) const
{
QHash< QString, QgsCoordinateReferenceSystem >::const_iterator crsIt = mCRSProj4.find( proj4 );
QHash< QString, QgsCoordinateReferenceSystem >::const_iterator crsIt = mCRSProj4.constFind( proj4 );
if ( crsIt == mCRSProj4.constEnd() )
{
QgsCoordinateReferenceSystem s;
@ -158,3 +158,21 @@ QgsCoordinateReferenceSystem QgsCRSCache::crsByProj4( const QString& proj4 ) con
return crsIt.value();
}
}
QgsCoordinateReferenceSystem QgsCRSCache::crsBySrsId( long srsId ) const
{
QHash< long, QgsCoordinateReferenceSystem >::const_iterator crsIt = mCRSSrsId.constFind( srsId );
if ( crsIt == mCRSSrsId.constEnd() )
{
QgsCoordinateReferenceSystem s;
if ( ! s.createFromSrsId( srsId ) )
{
return mCRSSrsId.insert( srsId, mInvalidCRS ).value();
}
return mCRSSrsId.insert( srsId, s ).value();
}
else
{
return crsIt.value();
}
}

View File

@ -97,6 +97,14 @@ class CORE_EXPORT QgsCRSCache
*/
QgsCoordinateReferenceSystem crsByProj4( const QString& proj4 ) const;
/** Returns the CRS from a specified QGIS SRS ID.
* @param srsId internal QGIS SRS ID
* @returns matching CRS, or an invalid CRS if ID could not be found
* @note added in QGIS 2.16
* @see QgsCoordinateReferenceSystem::createFromSrsId()
*/
QgsCoordinateReferenceSystem crsBySrsId( long srsId ) const;
/** Updates the cached definition of a CRS. Should be called if the definition of a user-created
* CRS has been changed.
* @param authid CRS auth ID, eg "EPSG:4326" or "USER:100009"
@ -110,6 +118,7 @@ class CORE_EXPORT QgsCRSCache
mutable QHash< QString, QgsCoordinateReferenceSystem > mCRS;
mutable QHash< QString, QgsCoordinateReferenceSystem > mCRSProj4;
mutable QHash< long, QgsCoordinateReferenceSystem > mCRSSrsId;
/** CRS that is not initialized (returned in case of error)*/
QgsCoordinateReferenceSystem mInvalidCRS;

View File

@ -106,8 +106,7 @@ bool QgsDistanceArea::willUseEllipsoid() const
void QgsDistanceArea::setSourceCrs( long srsid )
{
QgsCoordinateReferenceSystem srcCRS;
srcCRS.createFromSrsId( srsid );
QgsCoordinateReferenceSystem srcCRS = QgsCRSCache::instance()->crsBySrsId( srsid );
mCoordTransform->setSourceCrs( srcCRS );
}

View File

@ -87,8 +87,7 @@ QgsCoordinateReferenceSystem QgsProjectionSelectionWidget::crs() const
case QgsProjectionSelectionWidget::RecentCrs:
{
long srsid = mCrsComboBox->itemData( mCrsComboBox->currentIndex(), Qt::UserRole + 1 ).toLongLong();
QgsCoordinateReferenceSystem crs;
crs.createFromSrsId( srsid );
QgsCoordinateReferenceSystem crs = QgsCRSCache::instance()->crsBySrsId( srsid );
return crs;
}
}
@ -174,8 +173,7 @@ void QgsProjectionSelectionWidget::comboIndexChanged( int idx )
case QgsProjectionSelectionWidget::RecentCrs:
{
long srsid = mCrsComboBox->itemData( idx, Qt::UserRole + 1 ).toLongLong();
QgsCoordinateReferenceSystem crs;
crs.createFromSrsId( srsid );
QgsCoordinateReferenceSystem crs = QgsCRSCache::instance()->crsBySrsId( srsid );
emit crsChanged( crs );
return;
}
@ -252,8 +250,7 @@ void QgsProjectionSelectionWidget::addRecentCrs()
}
i++;
QgsCoordinateReferenceSystem crs;
crs.createFromSrsId( srsid );
QgsCoordinateReferenceSystem crs = QgsCRSCache::instance()->crsBySrsId( srsid );
if ( crs.isValid() )
{
mCrsComboBox->addItem( tr( "%1 - %2" ).arg( crs.authid(), crs.description() ), QgsProjectionSelectionWidget::RecentCrs );

View File

@ -89,5 +89,23 @@ class TestQgsCRSCache(unittest.TestCase):
crs = QgsCRSCache.instance().crsByProj4('asdasdasd')
self.assertFalse(crs.isValid())
def testcrsBySrsId(self):
""" test retrieving CRS from cache using srs id """
crs = QgsCRSCache.instance().crsBySrsId(3452)
self.assertTrue(crs.isValid())
self.assertEqual(crs.authid(), 'EPSG:4326')
# a second time, so crs is fetched from cache
crs = QgsCRSCache.instance().crsBySrsId(3452)
self.assertTrue(crs.isValid())
self.assertEqual(crs.authid(), 'EPSG:4326')
# invalid
crs = QgsCRSCache.instance().crsBySrsId(-9999)
self.assertFalse(crs.isValid())
# a second time, so invalid crs is fetched from cache
crs = QgsCRSCache.instance().crsBySrsId(-9999)
self.assertFalse(crs.isValid())
if __name__ == '__main__':
unittest.main()