mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-17 00:09:36 -04:00
Fix invalid transforms occur if project file contains corrupt/incomplete
coordinate operation details Also make storage of transform operations more resilent by correctly handling crses without authids. Fixes #34926
This commit is contained in:
parent
02a94f030c
commit
b91bccc64c
@ -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<QPair<QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem>>( const QPair<QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem> &key1,
|
||||
const QPair<QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem> &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<QPair<QString, QString>, QString> QgsCoordinateTransformContext::coordinate
|
||||
d->mLock.unlock();
|
||||
QMap<QPair<QString, QString>, 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;
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
Loading…
x
Reference in New Issue
Block a user