diff --git a/src/core/qgscoordinatetransformcontext.cpp b/src/core/qgscoordinatetransformcontext.cpp index f8afa9977fd..833df86b284 100644 --- a/src/core/qgscoordinatetransformcontext.cpp +++ b/src/core/qgscoordinatetransformcontext.cpp @@ -21,6 +21,19 @@ #include "qgssettings.h" #include "qgsprojutils.h" +QString crsToKey( const QgsCoordinateReferenceSystem &crs ) +{ + return crs.authid().isEmpty() ? crs.toWkt( QgsCoordinateReferenceSystem::WKT2_2018 ) : crs.authid(); +} + +template<> +bool qMapLessThanKey>( const QPair &key1, + const QPair &key2 ) +{ + const QPair< QString, QString > key1String = qMakePair( crsToKey( key1.first ), crsToKey( key1.second ) ); + const QPair< QString, QString > key2String = qMakePair( crsToKey( key2.first ), crsToKey( key2.second ) ); + return key1String < key2String; +} QgsCoordinateTransformContext::QgsCoordinateTransformContext() : d( new QgsCoordinateTransformContextPrivate() ) @@ -28,11 +41,11 @@ QgsCoordinateTransformContext::QgsCoordinateTransformContext() QgsCoordinateTransformContext::~QgsCoordinateTransformContext() = default; -QgsCoordinateTransformContext::QgsCoordinateTransformContext( const QgsCoordinateTransformContext &rhs ) //NOLINT +QgsCoordinateTransformContext::QgsCoordinateTransformContext( const QgsCoordinateTransformContext &rhs ) //NOLINT : d( rhs.d ) {} -QgsCoordinateTransformContext &QgsCoordinateTransformContext::operator=( const QgsCoordinateTransformContext &rhs ) //NOLINT +QgsCoordinateTransformContext &QgsCoordinateTransformContext::operator=( const QgsCoordinateTransformContext &rhs ) //NOLINT { d = rhs.d; return *this; @@ -82,7 +95,7 @@ QMap, QString> QgsCoordinateTransformContext::coordinate d->mLock.unlock(); QMap, QString> results; for ( auto it = res.constBegin(); it != res.constEnd(); ++it ) - results.insert( it.key(), it.value().operation ); + results.insert( qMakePair( it.key().first.authid(), it.key().second.authid() ), it.value().operation ); return results; #else @@ -117,7 +130,7 @@ bool QgsCoordinateTransformContext::addCoordinateOperation( const QgsCoordinateR QgsCoordinateTransformContextPrivate::OperationDetails details; details.operation = coordinateOperationProjString; details.allowFallback = allowFallback; - d->mSourceDestDatumTransforms.insert( qMakePair( sourceCrs.authid(), destinationCrs.authid() ), details ); + d->mSourceDestDatumTransforms.insert( qMakePair( sourceCrs, destinationCrs ), details ); d->mLock.unlock(); return true; #else @@ -134,7 +147,7 @@ void QgsCoordinateTransformContext::removeSourceDestinationDatumTransform( const void QgsCoordinateTransformContext::removeCoordinateOperation( const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs ) { - d->mSourceDestDatumTransforms.remove( qMakePair( sourceCrs.authid(), destinationCrs.authid() ) ); + d->mSourceDestDatumTransforms.remove( qMakePair( sourceCrs, destinationCrs ) ); } bool QgsCoordinateTransformContext::hasTransform( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination ) const @@ -178,15 +191,12 @@ QgsDatumTransform::TransformPair QgsCoordinateTransformContext::calculateDatumTr QString QgsCoordinateTransformContext::calculateCoordinateOperation( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination ) const { #if PROJ_VERSION_MAJOR>=6 - const QString srcKey = source.authid(); - const QString destKey = destination.authid(); - d->mLock.lockForRead(); - QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( srcKey, destKey ), QgsCoordinateTransformContextPrivate::OperationDetails() ); + QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( source, destination ), QgsCoordinateTransformContextPrivate::OperationDetails() ); if ( res.operation.isEmpty() ) { // try to reverse - res = d->mSourceDestDatumTransforms.value( qMakePair( destKey, srcKey ), QgsCoordinateTransformContextPrivate::OperationDetails() ); + res = d->mSourceDestDatumTransforms.value( qMakePair( destination, source ), QgsCoordinateTransformContextPrivate::OperationDetails() ); } d->mLock.unlock(); return res.operation; @@ -200,15 +210,12 @@ QString QgsCoordinateTransformContext::calculateCoordinateOperation( const QgsCo bool QgsCoordinateTransformContext::allowFallbackTransform( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination ) const { #if PROJ_VERSION_MAJOR>=6 - const QString srcKey = source.authid(); - const QString destKey = destination.authid(); - d->mLock.lockForRead(); - QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( srcKey, destKey ), QgsCoordinateTransformContextPrivate::OperationDetails() ); + QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( source, destination ), QgsCoordinateTransformContextPrivate::OperationDetails() ); if ( res.operation.isEmpty() ) { // try to reverse - res = d->mSourceDestDatumTransforms.value( qMakePair( destKey, srcKey ), QgsCoordinateTransformContextPrivate::OperationDetails() ); + res = d->mSourceDestDatumTransforms.value( qMakePair( destination, source ), QgsCoordinateTransformContextPrivate::OperationDetails() ); } d->mLock.unlock(); return res.allowFallback; @@ -222,18 +229,15 @@ bool QgsCoordinateTransformContext::allowFallbackTransform( const QgsCoordinateR bool QgsCoordinateTransformContext::mustReverseCoordinateOperation( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination ) const { #if PROJ_VERSION_MAJOR>=6 - const QString srcKey = source.authid(); - const QString destKey = destination.authid(); - d->mLock.lockForRead(); - QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( srcKey, destKey ), QgsCoordinateTransformContextPrivate::OperationDetails() ); + QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( source, destination ), QgsCoordinateTransformContextPrivate::OperationDetails() ); if ( !res.operation.isEmpty() ) { d->mLock.unlock(); return false; } // see if the reverse operation is present - res = d->mSourceDestDatumTransforms.value( qMakePair( destKey, srcKey ), QgsCoordinateTransformContextPrivate::OperationDetails() ); + res = d->mSourceDestDatumTransforms.value( qMakePair( destination, source ), QgsCoordinateTransformContextPrivate::OperationDetails() ); if ( !res.operation.isEmpty() ) { d->mLock.unlock(); @@ -273,10 +277,30 @@ bool QgsCoordinateTransformContext::readXml( const QDomElement &element, const Q for ( int i = 0; i < srcDestNodes.size(); ++i ) { const QDomElement transformElem = srcDestNodes.at( i ).toElement(); - const QString key1 = transformElem.attribute( QStringLiteral( "source" ) ); - const QString key2 = transformElem.attribute( QStringLiteral( "dest" ) ); #if PROJ_VERSION_MAJOR>=6 + const QDomElement srcElem = transformElem.firstChildElement( QStringLiteral( "src" ) ); + const QDomElement destElem = transformElem.firstChildElement( QStringLiteral( "dest" ) ); + + QgsCoordinateReferenceSystem srcCrs; + QgsCoordinateReferenceSystem destCrs; + if ( !srcElem.isNull() && !destElem.isNull() ) + { + srcCrs.readXml( srcElem ); + destCrs.readXml( destElem ); + } + else + { + // for older project compatibility + const QString key1 = transformElem.attribute( QStringLiteral( "source" ) ); + const QString key2 = transformElem.attribute( QStringLiteral( "dest" ) ); + srcCrs = QgsCoordinateReferenceSystem( key1 ); + destCrs = QgsCoordinateReferenceSystem( key2 ); + } + + if ( !srcCrs.isValid() || !destCrs.isValid() ) + continue; + const QString coordinateOp = transformElem.attribute( QStringLiteral( "coordinateOp" ) ); const bool allowFallback = transformElem.attribute( QStringLiteral( "allowFallback" ), QStringLiteral( "1" ) ).toInt(); @@ -291,8 +315,11 @@ bool QgsCoordinateTransformContext::readXml( const QDomElement &element, const Q QgsCoordinateTransformContextPrivate::OperationDetails deets; deets.operation = coordinateOp; deets.allowFallback = allowFallback; - d->mSourceDestDatumTransforms.insert( qMakePair( key1, key2 ), deets ); + d->mSourceDestDatumTransforms.insert( qMakePair( srcCrs, destCrs ), deets ); #else + const QString key1 = transformElem.attribute( QStringLiteral( "source" ) ); + const QString key2 = transformElem.attribute( QStringLiteral( "dest" ) ); + QString value1 = transformElem.attribute( QStringLiteral( "sourceTransform" ) ); QString value2 = transformElem.attribute( QStringLiteral( "destTransform" ) ); @@ -332,14 +359,24 @@ void QgsCoordinateTransformContext::writeXml( QDomElement &element, const QgsRea { d->mLock.lockForRead(); - QDomElement contextElem = element.ownerDocument().createElement( QStringLiteral( "transformContext" ) ); + QDomDocument doc = element.ownerDocument(); + + QDomElement contextElem = doc.createElement( QStringLiteral( "transformContext" ) ); //src/dest transforms for ( auto it = d->mSourceDestDatumTransforms.constBegin(); it != d->mSourceDestDatumTransforms.constEnd(); ++ it ) { - QDomElement transformElem = element.ownerDocument().createElement( QStringLiteral( "srcDest" ) ); - transformElem.setAttribute( QStringLiteral( "source" ), it.key().first ); - transformElem.setAttribute( QStringLiteral( "dest" ), it.key().second ); + QDomElement transformElem = doc.createElement( QStringLiteral( "srcDest" ) ); + + QDomElement srcElem = doc.createElement( QStringLiteral( "src" ) ); + QDomElement destElem = doc.createElement( QStringLiteral( "dest" ) ); + + it.key().first.writeXml( srcElem, doc ); + it.key().second.writeXml( destElem, doc ); + + transformElem.appendChild( srcElem ); + transformElem.appendChild( destElem ); + #if PROJ_VERSION_MAJOR>=6 transformElem.setAttribute( QStringLiteral( "coordinateOp" ), it.value().operation ); transformElem.setAttribute( QStringLiteral( "allowFallback" ), it.value().allowFallback ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ); @@ -369,7 +406,7 @@ void QgsCoordinateTransformContext::readSettings() //collect src and dest entries that belong together #if PROJ_VERSION_MAJOR>=6 - QMap< QPair< QString, QString >, QgsCoordinateTransformContextPrivate::OperationDetails > transforms; + QMap< QPair< QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem >, QgsCoordinateTransformContextPrivate::OperationDetails > transforms; #else QMap< QPair< QString, QString >, QPair< int, int > > transforms; #endif @@ -390,12 +427,15 @@ void QgsCoordinateTransformContext::readSettings() destAuthId = split.at( 1 ).split( '_' ).at( 0 ); } + if ( srcAuthId.isEmpty() || destAuthId.isEmpty() ) + continue; + const QString proj = settings.value( *pkeyIt ).toString(); const bool allowFallback = settings.value( QStringLiteral( "%1//%2_allowFallback" ).arg( srcAuthId, destAuthId ) ).toBool(); QgsCoordinateTransformContextPrivate::OperationDetails deets; deets.operation = proj; deets.allowFallback = allowFallback; - transforms[ qMakePair( srcAuthId, destAuthId )] = deets; + transforms[ qMakePair( QgsCoordinateReferenceSystem( srcAuthId ), QgsCoordinateReferenceSystem( destAuthId ) )] = deets; } #else if ( pkeyIt->contains( QLatin1String( "srcTransform" ) ) || pkeyIt->contains( QLatin1String( "destTransform" ) ) ) @@ -458,8 +498,11 @@ void QgsCoordinateTransformContext::writeSettings() for ( auto transformIt = d->mSourceDestDatumTransforms.constBegin(); transformIt != d->mSourceDestDatumTransforms.constEnd(); ++transformIt ) { - const QString srcAuthId = transformIt.key().first; - const QString destAuthId = transformIt.key().second; + const QString srcAuthId = transformIt.key().first.authid(); + const QString destAuthId = transformIt.key().second.authid(); + + if ( srcAuthId.isEmpty() || destAuthId.isEmpty() ) + continue; // not so nice, but alternative would be to shove whole CRS wkt into the settings values... #if PROJ_VERSION_MAJOR>=6 const QString proj = transformIt.value().operation; diff --git a/src/core/qgscoordinatetransformcontext_p.h b/src/core/qgscoordinatetransformcontext_p.h index 5274fa55eba..0a543117704 100644 --- a/src/core/qgscoordinatetransformcontext_p.h +++ b/src/core/qgscoordinatetransformcontext_p.h @@ -70,7 +70,7 @@ class QgsCoordinateTransformContextPrivate : public QSharedData return operation == other.operation && allowFallback == other.allowFallback; } }; - QMap< QPair< QString, QString >, OperationDetails > mSourceDestDatumTransforms; + QMap< QPair< QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem >, OperationDetails > mSourceDestDatumTransforms; #else QMap< QPair< QString, QString >, QgsDatumTransform::TransformPair > mSourceDestDatumTransforms; #endif diff --git a/tests/src/python/test_qgscoordinatetransformcontext.py b/tests/src/python/test_qgscoordinatetransformcontext.py index 90c9783d532..0d7b3a0a5e0 100644 --- a/tests/src/python/test_qgscoordinatetransformcontext.py +++ b/tests/src/python/test_qgscoordinatetransformcontext.py @@ -54,12 +54,12 @@ class TestQgsCoordinateTransformContext(unittest.TestCase): self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2)}) self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'), - QgsCoordinateReferenceSystem(4283), 3, 4)) + QgsCoordinateReferenceSystem('EPSG:4283'), 3, 4)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4)}) self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'), - QgsCoordinateReferenceSystem(28357), 7, 8)) + QgsCoordinateReferenceSystem('EPSG:28357'), 7, 8)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), @@ -86,23 +86,23 @@ class TestQgsCoordinateTransformContext(unittest.TestCase): ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11)}) # indicate no transform required - self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(28357), - QgsCoordinateReferenceSystem(28356), -1, -1)) + self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28357'), + QgsCoordinateReferenceSystem('EPSG:28356'), -1, -1)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), ('EPSG:28357', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, -1)}) - self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(3111), - QgsCoordinateReferenceSystem(28356), 17, -1)) + self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:3111'), + QgsCoordinateReferenceSystem('EPSG:28356'), 17, -1)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), ('EPSG:28357', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, -1), ('EPSG:3111', 'EPSG:28356'): QgsDatumTransform.TransformPair(17, -1)}) - self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(3113), - QgsCoordinateReferenceSystem(28356), -1, 18)) + self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:3113'), + QgsCoordinateReferenceSystem('EPSG:28356'), -1, 18)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), @@ -111,7 +111,7 @@ class TestQgsCoordinateTransformContext(unittest.TestCase): ('EPSG:3111', 'EPSG:28356'): QgsDatumTransform.TransformPair(17, -1), ('EPSG:3113', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, 18)}) # remove non-existing - context.removeCoordinateOperation(QgsCoordinateReferenceSystem(3113), QgsCoordinateReferenceSystem(3111)) + context.removeCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3113'), QgsCoordinateReferenceSystem('EPSG:3111')) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), @@ -121,16 +121,16 @@ class TestQgsCoordinateTransformContext(unittest.TestCase): ('EPSG:3113', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, 18)}) # remove existing - context.removeCoordinateOperation(QgsCoordinateReferenceSystem(3111), - QgsCoordinateReferenceSystem(4283)) + context.removeCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3111'), + QgsCoordinateReferenceSystem('EPSG:4283')) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), ('EPSG:28357', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, -1), ('EPSG:3111', 'EPSG:28356'): QgsDatumTransform.TransformPair(17, -1), ('EPSG:3113', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, 18)}) - context.removeCoordinateOperation(QgsCoordinateReferenceSystem(3111), - QgsCoordinateReferenceSystem(28356)) + context.removeCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3111'), + QgsCoordinateReferenceSystem('EPSG:28356')) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), @@ -143,7 +143,7 @@ class TestQgsCoordinateTransformContext(unittest.TestCase): @unittest.skipIf(QgsProjUtils.projVersionMajor() < 6, 'Skipped on non proj6 builds') def testSourceDestinationDatumTransformsProj6(self): context = QgsCoordinateTransformContext() - self.assertEqual(context.sourceDestinationDatumTransforms(), {}) + self.assertEqual(context.coordinateOperations(), {}) proj_string = '+proj=pipeline +step +inv +proj=lcc +lat_0=-37 +lon_0=145 +lat_1=-36 +lat_2=-38 +x_0=2500000 +y_0=2500000 +ellps=GRS80 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' self.assertFalse( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'))) @@ -203,12 +203,12 @@ class TestQgsCoordinateTransformContext(unittest.TestCase): proj_string_2 = '+proj=pipeline +step +inv +proj=utm +zone=56 +south +ellps=GRS80 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28356'), - QgsCoordinateReferenceSystem(4283), proj_string_2)) + QgsCoordinateReferenceSystem('EPSG:4283'), proj_string_2)) self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2}) proj_string_3 = '+proj=pipeline +step +inv +proj=utm +zone=56 +south +ellps=GRS80 +step +proj=utm +zone=57 +south +ellps=GRS80' self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28356'), - QgsCoordinateReferenceSystem(28357), proj_string_3)) + QgsCoordinateReferenceSystem('EPSG:28357'), proj_string_3)) self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): proj_string_3}) @@ -232,28 +232,28 @@ class TestQgsCoordinateTransformContext(unittest.TestCase): ('EPSG:28356', 'EPSG:28357'): 'some other proj string'}) # indicate no transform required - self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem(28357), - QgsCoordinateReferenceSystem(28356), '')) + self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28357'), + QgsCoordinateReferenceSystem('EPSG:28356'), '')) self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): 'some other proj string', ('EPSG:28357', 'EPSG:28356'): ''}) # remove non-existing - context.removeCoordinateOperation(QgsCoordinateReferenceSystem(3113), QgsCoordinateReferenceSystem(3111)) + context.removeCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3113'), QgsCoordinateReferenceSystem('EPSG:3111')) self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): 'some other proj string', ('EPSG:28357', 'EPSG:28356'): ''}) # remove existing - context.removeCoordinateOperation(QgsCoordinateReferenceSystem(3111), - QgsCoordinateReferenceSystem(4283)) + context.removeCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3111'), + QgsCoordinateReferenceSystem('EPSG:4283')) self.assertEqual(context.coordinateOperations(), {('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): 'some other proj string', ('EPSG:28357', 'EPSG:28356'): ''}) - context.removeCoordinateOperation(QgsCoordinateReferenceSystem(28356), - QgsCoordinateReferenceSystem(28357)) + context.removeCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28356'), + QgsCoordinateReferenceSystem('EPSG:28357')) self.assertEqual(context.coordinateOperations(), {('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28357', 'EPSG:28356'): ''}) @@ -319,21 +319,21 @@ class TestQgsCoordinateTransformContext(unittest.TestCase): # setup a context context = QgsCoordinateTransformContext() - source_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204), - QgsCoordinateReferenceSystem(4326))[0].sourceTransformId - dest_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204), - QgsCoordinateReferenceSystem(4326))[0].destinationTransformId + source_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem('EPSG:4204'), + QgsCoordinateReferenceSystem('EPSG:4326'))[0].sourceTransformId + dest_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem('EPSG:4204'), + QgsCoordinateReferenceSystem('EPSG:4326'))[0].destinationTransformId - source_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205), - QgsCoordinateReferenceSystem(4326))[0].sourceTransformId - dest_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205), - QgsCoordinateReferenceSystem(4326))[0].destinationTransformId + source_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem('EPSG:4205'), + QgsCoordinateReferenceSystem('EPSG:4326'))[0].sourceTransformId + dest_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem('EPSG:4205'), + QgsCoordinateReferenceSystem('EPSG:4326'))[0].destinationTransformId - self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(4204), - QgsCoordinateReferenceSystem(4326), source_id_1, + self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:4204'), + QgsCoordinateReferenceSystem('EPSG:4326'), source_id_1, dest_id_1)) - self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(4205), - QgsCoordinateReferenceSystem(4326), source_id_2, + self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:4205'), + QgsCoordinateReferenceSystem('EPSG:4326'), source_id_2, dest_id_2)) self.assertEqual(context.sourceDestinationDatumTransforms(), @@ -361,15 +361,21 @@ class TestQgsCoordinateTransformContext(unittest.TestCase): proj_1 = '+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 +step +proj=cart +ellps=intl +step +proj=helmert +x=-18.944 +y=-379.364 +z=-24.063 +rx=-0.04 +ry=0.764 +rz=-6.431 +s=3.657 +convention=coordinate_frame +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' proj_2 = '+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 +step +proj=cart +ellps=intl +step +proj=helmert +x=-150 +y=-250 +z=-1 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' + proj_3 = '+proj=pipeline +step +proj=axisswap +order=2,1' - self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem(4204), - QgsCoordinateReferenceSystem(4326), proj_1, True)) - self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem(4205), - QgsCoordinateReferenceSystem(4326), proj_2, False)) + self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:4204'), + QgsCoordinateReferenceSystem('EPSG:4326'), proj_1, True)) + self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:4205'), + QgsCoordinateReferenceSystem('EPSG:4326'), proj_2, False)) + + # also insert a crs with no authid available + self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem.fromProj("+proj=longlat +a=6378137 +rf=298.25722356300003 +no_defs"), + QgsCoordinateReferenceSystem('EPSG:4326'), proj_3, False)) self.assertEqual(context.coordinateOperations(), {('EPSG:4204', 'EPSG:4326'): proj_1, - ('EPSG:4205', 'EPSG:4326'): proj_2}) + ('EPSG:4205', 'EPSG:4326'): proj_2, + ('', 'EPSG:4326'): proj_3}) # save to xml doc = QDomDocument("testdoc") @@ -383,11 +389,21 @@ class TestQgsCoordinateTransformContext(unittest.TestCase): # check result self.assertEqual(context2.coordinateOperations(), {('EPSG:4204', 'EPSG:4326'): proj_1, - ('EPSG:4205', 'EPSG:4326'): proj_2}) - self.assertTrue(context2.allowFallbackTransform(QgsCoordinateReferenceSystem(4204), - QgsCoordinateReferenceSystem(4326))) - self.assertFalse(context2.allowFallbackTransform(QgsCoordinateReferenceSystem(4205), - QgsCoordinateReferenceSystem(4326))) + ('EPSG:4205', 'EPSG:4326'): proj_2, + ('', 'EPSG:4326'): proj_3}) + self.assertEqual(context2.calculateCoordinateOperation(QgsCoordinateReferenceSystem.fromProj("+proj=longlat +a=6378137 +rf=298.25722356300003 +no_defs"), + QgsCoordinateReferenceSystem('EPSG:4326')), '+proj=pipeline +step +proj=axisswap +order=2,1') + self.assertFalse(context2.mustReverseCoordinateOperation(QgsCoordinateReferenceSystem.fromProj("+proj=longlat +a=6378137 +rf=298.25722356300003 +no_defs"), + QgsCoordinateReferenceSystem('EPSG:4326'))) + self.assertEqual(context2.calculateCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:4326'), + QgsCoordinateReferenceSystem.fromProj("+proj=longlat +a=6378137 +rf=298.25722356300003 +no_defs")), + '+proj=pipeline +step +proj=axisswap +order=2,1') + self.assertTrue(context2.mustReverseCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:4326'), + QgsCoordinateReferenceSystem.fromProj("+proj=longlat +a=6378137 +rf=298.25722356300003 +no_defs"))) + self.assertTrue(context2.allowFallbackTransform(QgsCoordinateReferenceSystem('EPSG:4204'), + QgsCoordinateReferenceSystem('EPSG:4326'))) + self.assertFalse(context2.allowFallbackTransform(QgsCoordinateReferenceSystem('EPSG:4205'), + QgsCoordinateReferenceSystem('EPSG:4326'))) @unittest.skipIf(QgsProjUtils.projVersionMajor() >= 6, 'Skipped on proj6 builds') def testMissingTransforms(self): @@ -482,15 +498,15 @@ class TestQgsCoordinateTransformContext(unittest.TestCase): context = QgsCoordinateTransformContext() context.readSettings() - source_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204), - QgsCoordinateReferenceSystem(4326))[0].sourceTransformId - dest_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204), - QgsCoordinateReferenceSystem(4326))[0].destinationTransformId + source_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem('EPSG:4204'), + QgsCoordinateReferenceSystem('EPSG:4326'))[0].sourceTransformId + dest_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem('EPSG:4204'), + QgsCoordinateReferenceSystem('EPSG:4326'))[0].destinationTransformId - source_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205), - QgsCoordinateReferenceSystem(4326))[0].sourceTransformId - dest_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205), - QgsCoordinateReferenceSystem(4326))[0].destinationTransformId + source_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem('EPSG:4205'), + QgsCoordinateReferenceSystem('EPSG:4326'))[0].sourceTransformId + dest_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem('EPSG:4205'), + QgsCoordinateReferenceSystem('EPSG:4326'))[0].destinationTransformId # should be empty self.assertEqual(context.sourceDestinationDatumTransforms(), {}) @@ -499,7 +515,7 @@ class TestQgsCoordinateTransformContext(unittest.TestCase): QgsCoordinateReferenceSystem('EPSG:4326'), source_id_1, dest_id_1)) self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:4205'), - QgsCoordinateReferenceSystem(4326), source_id_2, + QgsCoordinateReferenceSystem('EPSG:4326'), source_id_2, dest_id_2)) self.assertEqual(context.sourceDestinationDatumTransforms(), @@ -530,18 +546,18 @@ class TestQgsCoordinateTransformContext(unittest.TestCase): # should be empty self.assertEqual(context.coordinateOperations(), {}) - self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem(4204), - QgsCoordinateReferenceSystem(4326), proj_1, True)) - self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem(4205), - QgsCoordinateReferenceSystem(4326), proj_2, False)) + self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:4204'), + QgsCoordinateReferenceSystem('EPSG:4326'), proj_1, True)) + self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:4205'), + QgsCoordinateReferenceSystem('EPSG:4326'), proj_2, False)) self.assertEqual(context.coordinateOperations(), {('EPSG:4204', 'EPSG:4326'): proj_1, ('EPSG:4205', 'EPSG:4326'): proj_2}) - self.assertTrue(context.allowFallbackTransform(QgsCoordinateReferenceSystem(4204), - QgsCoordinateReferenceSystem(4326))) - self.assertFalse(context.allowFallbackTransform(QgsCoordinateReferenceSystem(4205), - QgsCoordinateReferenceSystem(4326))) + self.assertTrue(context.allowFallbackTransform(QgsCoordinateReferenceSystem('EPSG:4204'), + QgsCoordinateReferenceSystem('EPSG:4326'))) + self.assertFalse(context.allowFallbackTransform(QgsCoordinateReferenceSystem('EPSG:4205'), + QgsCoordinateReferenceSystem('EPSG:4326'))) # save to settings context.writeSettings() @@ -556,10 +572,10 @@ class TestQgsCoordinateTransformContext(unittest.TestCase): {('EPSG:4204', 'EPSG:4326'): proj_1, ('EPSG:4205', 'EPSG:4326'): proj_2}) - self.assertTrue(context2.allowFallbackTransform(QgsCoordinateReferenceSystem(4204), - QgsCoordinateReferenceSystem(4326))) - self.assertFalse(context2.allowFallbackTransform(QgsCoordinateReferenceSystem(4205), - QgsCoordinateReferenceSystem(4326))) + self.assertTrue(context2.allowFallbackTransform(QgsCoordinateReferenceSystem('EPSG:4204'), + QgsCoordinateReferenceSystem('EPSG:4326'))) + self.assertFalse(context2.allowFallbackTransform(QgsCoordinateReferenceSystem('EPSG:4205'), + QgsCoordinateReferenceSystem('EPSG:4326'))) @unittest.skipIf(QgsProjUtils.projVersionMajor() >= 6, 'Skipped on proj6 builds') def testEqualOperator(self):