diff --git a/src/core/qgscoordinatetransform.cpp b/src/core/qgscoordinatetransform.cpp index 814e5dfbd316..9cdde766f76e 100644 --- a/src/core/qgscoordinatetransform.cpp +++ b/src/core/qgscoordinatetransform.cpp @@ -42,6 +42,8 @@ QgsCoordinateTransform::QgsCoordinateTransform() , mInitialisedFlag( false ) , mSourceProjection( 0 ) , mDestinationProjection( 0 ) + , mSourceDatumTransform( -1 ) + , mDestinationDatumTransform( -1 ) { setFinder(); } @@ -51,6 +53,8 @@ QgsCoordinateTransform::QgsCoordinateTransform( const QgsCoordinateReferenceSyst , mInitialisedFlag( false ) , mSourceProjection( 0 ) , mDestinationProjection( 0 ) + , mSourceDatumTransform( -1 ) + , mDestinationDatumTransform( -1 ) { setFinder(); mSourceCRS = source; @@ -65,6 +69,8 @@ QgsCoordinateTransform::QgsCoordinateTransform( long theSourceSrsId, long theDes , mDestCRS( theDestSrsId, QgsCoordinateReferenceSystem::InternalCrsId ) , mSourceProjection( 0 ) , mDestinationProjection( 0 ) + , mSourceDatumTransform( -1 ) + , mDestinationDatumTransform( -1 ) { initialise(); } @@ -74,6 +80,8 @@ QgsCoordinateTransform::QgsCoordinateTransform( QString theSourceCRS, QString th , mInitialisedFlag( false ) , mSourceProjection( 0 ) , mDestinationProjection( 0 ) + , mSourceDatumTransform( -1 ) + , mDestinationDatumTransform( -1 ) { setFinder(); mSourceCRS.createFromWkt( theSourceCRS ); @@ -92,6 +100,8 @@ QgsCoordinateTransform::QgsCoordinateTransform( long theSourceSrid, , mInitialisedFlag( false ) , mSourceProjection( 0 ) , mDestinationProjection( 0 ) + , mSourceDatumTransform( -1 ) + , mDestinationDatumTransform( -1 ) { setFinder(); @@ -137,7 +147,7 @@ void QgsCoordinateTransform::setDestCRSID( long theCRSID ) // XXX This whole function is full of multiple return statements!!! // And probably shouldn't be a void -void QgsCoordinateTransform::initialise( int srcDatumTransform, int destDatumTransform ) +void QgsCoordinateTransform::initialise() { // XXX Warning - multiple return paths in this block!! if ( !mSourceCRS.isValid() ) @@ -157,7 +167,7 @@ void QgsCoordinateTransform::initialise( int srcDatumTransform, int destDatumTra mDestCRS = QgsCRSCache::instance()->crsByAuthId( mSourceCRS.authid() ); } - bool useDefaultDatumTransform = ( srcDatumTransform == - 1 && destDatumTransform == -1 ); + bool useDefaultDatumTransform = ( mSourceDatumTransform == - 1 && mDestinationDatumTransform == -1 ); // init the projections (destination and source) pj_free( mDestinationProjection ); @@ -166,9 +176,9 @@ void QgsCoordinateTransform::initialise( int srcDatumTransform, int destDatumTra { destProjString = stripDatumTransform( destProjString ); } - if ( destDatumTransform != -1 ) + if ( mDestinationDatumTransform != -1 ) { - destProjString += ( " " + datumTransformString( destDatumTransform ) ); + destProjString += ( " " + datumTransformString( mDestinationDatumTransform ) ); } mDestinationProjection = pj_init_plus( destProjString.toUtf8() ); @@ -178,9 +188,9 @@ void QgsCoordinateTransform::initialise( int srcDatumTransform, int destDatumTra { sourceProjString = stripDatumTransform( sourceProjString ); } - if ( srcDatumTransform != -1 ) + if ( mSourceDatumTransform != -1 ) { - sourceProjString += ( " " + datumTransformString( srcDatumTransform ) ); + sourceProjString += ( " " + datumTransformString( mSourceDatumTransform ) ); } mSourceProjection = pj_init_plus( sourceProjString.toUtf8() ); @@ -690,6 +700,9 @@ bool QgsCoordinateTransform::readXML( QDomNode & theNode ) QDomNode myDestNode = theNode.namedItem( "destinationsrs" ); mDestCRS.readXML( myDestNode ); + mSourceDatumTransform = theNode.toElement().attribute( "sourceDatumTransform", "-1" ).toInt(); + mDestinationDatumTransform = theNode.toElement().attribute( "destinationDatumTransform", "-1" ).toInt(); + initialise(); return true; @@ -699,6 +712,8 @@ bool QgsCoordinateTransform::writeXML( QDomNode & theNode, QDomDocument & theDoc { QDomElement myNodeElement = theNode.toElement(); QDomElement myTransformElement = theDoc.createElement( "coordinatetransform" ); + myTransformElement.setAttribute( "sourceDatumTransform", QString::number( mSourceDatumTransform ) ); + myTransformElement.setAttribute( "destinationDatumTransform", QString::number( mDestinationDatumTransform ) ); QDomElement mySourceElement = theDoc.createElement( "sourcesrs" ); mSourceCRS.writeXML( mySourceElement, theDoc ); diff --git a/src/core/qgscoordinatetransform.h b/src/core/qgscoordinatetransform.h index df3da1bdfdc0..3dae9be71368 100644 --- a/src/core/qgscoordinatetransform.h +++ b/src/core/qgscoordinatetransform.h @@ -214,9 +214,14 @@ class CORE_EXPORT QgsCoordinateTransform : public QObject /**Returns list of datum transformations for the given src and dest CRS*/ static QList< QList< int > > datumTransformations( const QgsCoordinateReferenceSystem& srcCRS, const QgsCoordinateReferenceSystem& destCRS ); + int sourceDatumTransform() const { return mSourceDatumTransform; } + void setSourceDatumTransform( int dt ) { mSourceDatumTransform = dt; } + int destinationDatumTransform() const { return mDestinationDatumTransform; } + void setDestinationDatumTransform( int dt ) { mDestinationDatumTransform = dt; } + public slots: //!initialise is used to actually create the Transformer instance - void initialise( int srcDatumTransform = -1, int destDatumTransform = -1 ); + void initialise(); /*! Restores state from the given Dom node. * @param theNode The node from which state will be restored @@ -268,6 +273,9 @@ class CORE_EXPORT QgsCoordinateTransform : public QObject */ projPJ mDestinationProjection; + int mSourceDatumTransform; + int mDestinationDatumTransform; + /*! * Finder for PROJ grid files. */ diff --git a/src/core/qgscrscache.cpp b/src/core/qgscrscache.cpp index ef8f7331c646..48ed218e7488 100644 --- a/src/core/qgscrscache.cpp +++ b/src/core/qgscrscache.cpp @@ -39,22 +39,28 @@ QgsCoordinateTransformCache::~QgsCoordinateTransformCache() delete mInstance; } -const QgsCoordinateTransform* QgsCoordinateTransformCache::transform( const QString& srcAuthId, const QString& destAuthId ) +const QgsCoordinateTransform* QgsCoordinateTransformCache::transform( const QString& srcAuthId, const QString& destAuthId, int srcDatumTransform, int destDatumTransform ) { - QHash< QPair< QString, QString >, QgsCoordinateTransform* >::const_iterator ctIt = - mTransforms.find( qMakePair( srcAuthId, destAuthId ) ); - if ( ctIt == mTransforms.constEnd() ) - { - const QgsCoordinateReferenceSystem& srcCrs = QgsCRSCache::instance()->crsByAuthId( srcAuthId ); - const QgsCoordinateReferenceSystem& destCrs = QgsCRSCache::instance()->crsByAuthId( destAuthId ); - QgsCoordinateTransform* ct = new QgsCoordinateTransform( srcCrs, destCrs ); - mTransforms.insert( qMakePair( srcAuthId, destAuthId ), ct ); - return ct; - } - else + QList< QgsCoordinateTransform* > values = + mTransforms.values( qMakePair( srcAuthId, destAuthId ) ); + + QList< QgsCoordinateTransform* >::const_iterator valIt = values.constBegin(); + for ( ; valIt != values.constEnd(); ++valIt ) { - return ctIt.value(); + if ( *valIt && ( *valIt )->sourceDatumTransform() == srcDatumTransform && ( *valIt )->destinationDatumTransform() == destDatumTransform ) + { + return *valIt; + } } + + //not found, insert new value + const QgsCoordinateReferenceSystem& srcCrs = QgsCRSCache::instance()->crsByAuthId( srcAuthId ); + const QgsCoordinateReferenceSystem& destCrs = QgsCRSCache::instance()->crsByAuthId( destAuthId ); + QgsCoordinateTransform* ct = new QgsCoordinateTransform( srcCrs, destCrs ); + ct->setSourceDatumTransform( srcDatumTransform ); + ct->setDestinationDatumTransform( destDatumTransform ); + mTransforms.insertMulti( qMakePair( srcAuthId, destAuthId ), ct ); + return ct; } void QgsCoordinateTransformCache::invalidateCrs( const QString& crsAuthId ) diff --git a/src/core/qgscrscache.h b/src/core/qgscrscache.h index 81da0462a843..b7a10098b353 100644 --- a/src/core/qgscrscache.h +++ b/src/core/qgscrscache.h @@ -33,13 +33,13 @@ class CORE_EXPORT QgsCoordinateTransformCache /**Returns coordinate transformation. Cache keeps ownership @param srcAuthId auth id string of source crs @param destAuthId auth id string of dest crs*/ - const QgsCoordinateTransform* transform( const QString& srcAuthId, const QString& destAuthId ); + const QgsCoordinateTransform* transform( const QString& srcAuthId, const QString& destAuthId, int srcDatumTransform = -1, int destDatumTransform = -1 ); /**Removes transformations where a changed crs is involved from the cache*/ void invalidateCrs( const QString& crsAuthId ); private: static QgsCoordinateTransformCache* mInstance; - QHash< QPair< QString, QString >, QgsCoordinateTransform* > mTransforms; + QMultiHash< QPair< QString, QString >, QgsCoordinateTransform* > mTransforms; //same auth_id pairs might have different datum transformations }; class CORE_EXPORT QgsCRSCache