QGIS/tests/src/core/testqgscoordinatetransform.cpp
Nyall Dawson 25c3e135b0 Move datum transform structs out to their own header, to avoid
need to include private header file
2017-12-18 21:19:02 +10:00

261 lines
9.8 KiB
C++

/***************************************************************************
testqgscoordinatetransform.cpp
-----------------------
begin : October 2014
copyright : (C) 2014 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgscoordinatetransform.h"
#include "qgsapplication.h"
#include "qgsrectangle.h"
#include "qgscoordinatetransformcontext.h"
#include "qgsproject.h"
#include <QObject>
#include "qgstest.h"
#include "qgsexception.h"
class TestQgsCoordinateTransform: public QObject
{
Q_OBJECT
private slots:
void initTestCase();
void cleanupTestCase();
void transformBoundingBox();
void copy();
void assignment();
void isValid();
void isShortCircuited();
void contextShared();
private:
};
void TestQgsCoordinateTransform::initTestCase()
{
QgsApplication::init();
QgsApplication::initQgis();
}
void TestQgsCoordinateTransform::cleanupTestCase()
{
QgsApplication::exitQgis();
}
void TestQgsCoordinateTransform::copy()
{
QgsCoordinateTransform uninitialized;
QgsCoordinateTransform uninitializedCopy( uninitialized );
QVERIFY( !uninitializedCopy.isValid() );
QgsCoordinateReferenceSystem source;
source.createFromId( 3111, QgsCoordinateReferenceSystem::EpsgCrsId );
QgsCoordinateReferenceSystem destination;
destination.createFromId( 4326, QgsCoordinateReferenceSystem::EpsgCrsId );
QgsCoordinateTransform original( source, destination, QgsProject::instance() );
QVERIFY( original.isValid() );
QgsCoordinateTransform copy( original );
QVERIFY( copy.isValid() );
QCOMPARE( copy.sourceCrs().authid(), original.sourceCrs().authid() );
QCOMPARE( copy.destinationCrs().authid(), original.destinationCrs().authid() );
// force detachement of copy
QgsCoordinateReferenceSystem newDest;
newDest.createFromId( 3857, QgsCoordinateReferenceSystem::EpsgCrsId );
copy.setDestinationCrs( newDest );
QVERIFY( copy.isValid() );
QCOMPARE( copy.destinationCrs().authid(), QString( "EPSG:3857" ) );
QCOMPARE( original.destinationCrs().authid(), QString( "EPSG:4326" ) );
}
void TestQgsCoordinateTransform::assignment()
{
QgsCoordinateTransform uninitialized;
QgsCoordinateTransform uninitializedCopy;
uninitializedCopy = uninitialized;
QVERIFY( !uninitializedCopy.isValid() );
QgsCoordinateReferenceSystem source;
source.createFromId( 3111, QgsCoordinateReferenceSystem::EpsgCrsId );
QgsCoordinateReferenceSystem destination;
destination.createFromId( 4326, QgsCoordinateReferenceSystem::EpsgCrsId );
QgsCoordinateTransform original( source, destination, QgsProject::instance() );
QVERIFY( original.isValid() );
QgsCoordinateTransform copy;
copy = original;
QVERIFY( copy.isValid() );
QCOMPARE( copy.sourceCrs().authid(), original.sourceCrs().authid() );
QCOMPARE( copy.destinationCrs().authid(), original.destinationCrs().authid() );
// force detachement of copy
QgsCoordinateReferenceSystem newDest;
newDest.createFromId( 3857, QgsCoordinateReferenceSystem::EpsgCrsId );
copy.setDestinationCrs( newDest );
QVERIFY( copy.isValid() );
QCOMPARE( copy.destinationCrs().authid(), QString( "EPSG:3857" ) );
QCOMPARE( original.destinationCrs().authid(), QString( "EPSG:4326" ) );
// test assigning back to invalid
copy = uninitialized;
QVERIFY( !copy.isValid() );
QVERIFY( original.isValid() );
}
void TestQgsCoordinateTransform::isValid()
{
QgsCoordinateTransform tr;
QVERIFY( !tr.isValid() );
QgsCoordinateReferenceSystem srs1;
srs1.createFromSrid( 3994 );
QgsCoordinateReferenceSystem srs2;
srs2.createFromSrid( 4326 );
// valid source, invalid destination
QgsCoordinateTransform tr2( srs1, QgsCoordinateReferenceSystem(), QgsProject::instance() );
QVERIFY( !tr2.isValid() );
// invalid source, valid destination
QgsCoordinateTransform tr3( QgsCoordinateReferenceSystem(), srs2, QgsProject::instance() );
QVERIFY( !tr3.isValid() );
// valid source, valid destination
QgsCoordinateTransform tr4( srs1, srs2, QgsProject::instance() );
QVERIFY( tr4.isValid() );
// try to invalidate by setting source as invalid
tr4.setSourceCrs( QgsCoordinateReferenceSystem() );
QVERIFY( !tr4.isValid() );
QgsCoordinateTransform tr5( srs1, srs2, QgsProject::instance() );
// try to invalidate by setting destination as invalid
tr5.setDestinationCrs( QgsCoordinateReferenceSystem() );
QVERIFY( !tr5.isValid() );
}
void TestQgsCoordinateTransform::isShortCircuited()
{
QgsCoordinateTransform tr;
//invalid transform shortcircuits
QVERIFY( tr.isShortCircuited() );
QgsCoordinateReferenceSystem srs1;
srs1.createFromSrid( 3994 );
QgsCoordinateReferenceSystem srs2;
srs2.createFromSrid( 4326 );
// valid source, invalid destination
QgsCoordinateTransform tr2( srs1, QgsCoordinateReferenceSystem(), QgsProject::instance() );
QVERIFY( tr2.isShortCircuited() );
// invalid source, valid destination
QgsCoordinateTransform tr3( QgsCoordinateReferenceSystem(), srs2, QgsProject::instance() );
QVERIFY( tr3.isShortCircuited() );
// equal, valid source and destination
QgsCoordinateTransform tr4( srs1, srs1, QgsProject::instance() );
QVERIFY( tr4.isShortCircuited() );
// valid but different source and destination
QgsCoordinateTransform tr5( srs1, srs2, QgsProject::instance() );
QVERIFY( !tr5.isShortCircuited() );
// try to short circuit by changing dest
tr5.setDestinationCrs( srs1 );
QVERIFY( tr5.isShortCircuited() );
}
void TestQgsCoordinateTransform::contextShared()
{
//test implicit sharing of QgsCoordinateTransformContext
QgsCoordinateTransformContext original;
original.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem( 3111 ), QgsCoordinateReferenceSystem( 3113 ), 1, 2 );
QgsCoordinateTransformContext copy( original );
QMap< QPair< QString, QString >, QgsDatumTransform::TransformPair > expected;
expected.insert( qMakePair( QStringLiteral( "EPSG:3111" ), QStringLiteral( "EPSG:3113" ) ), QgsDatumTransform::TransformPair( 1, 2 ) );
QCOMPARE( original.sourceDestinationDatumTransforms(), expected );
QCOMPARE( copy.sourceDestinationDatumTransforms(), expected );
// trigger detach
copy.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem( 3111 ), QgsCoordinateReferenceSystem( 3113 ), 3, 4 );
QCOMPARE( original.sourceDestinationDatumTransforms(), expected );
expected.insert( qMakePair( QStringLiteral( "EPSG:3111" ), QStringLiteral( "EPSG:3113" ) ), QgsDatumTransform::TransformPair( 3, 4 ) );
QCOMPARE( copy.sourceDestinationDatumTransforms(), expected );
// copy via assignment
QgsCoordinateTransformContext copy2;
copy2 = original;
expected.insert( qMakePair( QStringLiteral( "EPSG:3111" ), QStringLiteral( "EPSG:3113" ) ), QgsDatumTransform::TransformPair( 1, 2 ) );
QCOMPARE( original.sourceDestinationDatumTransforms(), expected );
QCOMPARE( copy2.sourceDestinationDatumTransforms(), expected );
copy2.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem( 3111 ), QgsCoordinateReferenceSystem( 3113 ), 3, 4 );
QCOMPARE( original.sourceDestinationDatumTransforms(), expected );
expected.insert( qMakePair( QStringLiteral( "EPSG:3111" ), QStringLiteral( "EPSG:3113" ) ), QgsDatumTransform::TransformPair( 3, 4 ) );
QCOMPARE( copy2.sourceDestinationDatumTransforms(), expected );
}
void TestQgsCoordinateTransform::transformBoundingBox()
{
//test transforming a bounding box which crosses the 180 degree longitude line
QgsCoordinateReferenceSystem sourceSrs;
sourceSrs.createFromSrid( 3994 );
QgsCoordinateReferenceSystem destSrs;
destSrs.createFromSrid( 4326 );
QgsCoordinateTransform tr( sourceSrs, destSrs, QgsProject::instance() );
QgsRectangle crossingRect( 6374985, -3626584, 7021195, -3272435 );
QgsRectangle resultRect = tr.transformBoundingBox( crossingRect, QgsCoordinateTransform::ForwardTransform, true );
QgsRectangle expectedRect;
expectedRect.setXMinimum( 175.771 );
expectedRect.setYMinimum( -39.7222 );
expectedRect.setXMaximum( -176.549 );
expectedRect.setYMaximum( -36.3951 );
qDebug( "BBox transform x min: %.17f", resultRect.xMinimum() );
qDebug( "BBox transform x max: %.17f", resultRect.xMaximum() );
qDebug( "BBox transform y min: %.17f", resultRect.yMinimum() );
qDebug( "BBox transform y max: %.17f", resultRect.yMaximum() );
QGSCOMPARENEAR( resultRect.xMinimum(), expectedRect.xMinimum(), 0.001 );
QGSCOMPARENEAR( resultRect.yMinimum(), expectedRect.yMinimum(), 0.001 );
QGSCOMPARENEAR( resultRect.xMaximum(), expectedRect.xMaximum(), 0.001 );
QGSCOMPARENEAR( resultRect.yMaximum(), expectedRect.yMaximum(), 0.001 );
// test transforming a bounding box, resulting in an invalid transform - exception must be thrown
tr = QgsCoordinateTransform( QgsCoordinateReferenceSystem( 4326 ), QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:28356" ) ), QgsProject::instance() );
QgsRectangle rect( -99999999999, 99999999999, -99999999998, 99999999998 );
bool errorObtained = false;
try
{
resultRect = tr.transformBoundingBox( rect );
}
catch ( QgsCsException & )
{
errorObtained = true;
}
QVERIFY( errorObtained );
}
QGSTEST_MAIN( TestQgsCoordinateTransform )
#include "testqgscoordinatetransform.moc"