30 bool qMapLessThanKey<QPair<QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem>>( 
const QPair<QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem> &key1,
 
   31     const QPair<QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem> &key2 )
 
   33   const QPair< QString, QString > key1String = qMakePair( 
crsToKey( key1.first ), 
crsToKey( key1.second ) );
 
   34   const QPair< QString, QString > key2String = qMakePair( 
crsToKey( key2.first ), 
crsToKey( key2.second ) );
 
   35   return key1String < key2String;
 
   39   : d( new QgsCoordinateTransformContextPrivate() )
 
   59   d->mLock.lockForRead();
 
   60   rhs.d->mLock.lockForRead();
 
   61   bool equal = d->mSourceDestDatumTransforms == rhs.d->mSourceDestDatumTransforms;
 
   63   rhs.d->mLock.unlock();
 
   71   d->mLock.lockForWrite();
 
   72   d->mSourceDestDatumTransforms.clear();
 
   78 #if PROJ_VERSION_MAJOR>=6 
   81   d->mLock.lockForRead();
 
   82   auto res = d->mSourceDestDatumTransforms;
 
   91 #if PROJ_VERSION_MAJOR>=6 
   92   d->mLock.lockForRead();
 
   93   auto res = d->mSourceDestDatumTransforms;
 
   96   QMap<QPair<QString, QString>, QString> results;
 
   97   for ( 
auto it = res.constBegin(); it != res.constEnd(); ++it )
 
   98     results.insert( qMakePair( it.key().first.authid(), it.key().second.authid() ), it.value().operation );
 
  102   return QMap<QPair<QString, QString>, QString>();
 
  110 #if PROJ_VERSION_MAJOR>=6 
  111   Q_UNUSED( sourceTransform )
 
  112   Q_UNUSED( destinationTransform )
 
  116   d->mLock.lockForWrite();
 
  127 #if PROJ_VERSION_MAJOR>=6 
  129   d->mLock.lockForWrite();
 
  130   QgsCoordinateTransformContextPrivate::OperationDetails details;
 
  131   details.operation = coordinateOperationProjString;
 
  132   details.allowFallback = allowFallback;
 
  133   d->mSourceDestDatumTransforms.insert( qMakePair( sourceCrs, destinationCrs ), details );
 
  137   Q_UNUSED( coordinateOperationProjString )
 
  138   Q_UNUSED( allowFallback )
 
  150 #if PROJ_VERSION_MAJOR>=6 
  151   d->mSourceDestDatumTransforms.remove( qMakePair( sourceCrs, destinationCrs ) );
 
  153   d->mSourceDestDatumTransforms.remove( qMakePair( sourceCrs.
authid(), destinationCrs.
authid() ) );
 
  159 #if PROJ_VERSION_MAJOR>=6 
  167   return t.sourceTransformId != -1 || t.destinationTransformId != -1;
 
  173 #if PROJ_VERSION_MAJOR>=6 
  175   Q_UNUSED( destination )
 
  178   QString srcKey = source.
authid();
 
  179   QString destKey = destination.
authid();
 
  181   d->mLock.lockForRead();
 
  197 #if PROJ_VERSION_MAJOR>=6 
  201   d->mLock.lockForRead();
 
  202   QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( source, destination ), QgsCoordinateTransformContextPrivate::OperationDetails() );
 
  203   if ( res.operation.isEmpty() )
 
  206     res = d->mSourceDestDatumTransforms.value( qMakePair( destination, source ), QgsCoordinateTransformContextPrivate::OperationDetails() );
 
  209   return res.operation;
 
  212   Q_UNUSED( destination )
 
  219 #if PROJ_VERSION_MAJOR>=6 
  223   d->mLock.lockForRead();
 
  224   QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( source, destination ), QgsCoordinateTransformContextPrivate::OperationDetails() );
 
  225   if ( res.operation.isEmpty() )
 
  228     res = d->mSourceDestDatumTransforms.value( qMakePair( destination, source ), QgsCoordinateTransformContextPrivate::OperationDetails() );
 
  231   return res.allowFallback;
 
  234   Q_UNUSED( destination )
 
  241 #if PROJ_VERSION_MAJOR>=6 
  245   d->mLock.lockForRead();
 
  246   QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( source, destination ), QgsCoordinateTransformContextPrivate::OperationDetails() );
 
  247   if ( !res.operation.isEmpty() )
 
  253   res = d->mSourceDestDatumTransforms.value( qMakePair( destination, source ), QgsCoordinateTransformContextPrivate::OperationDetails() );
 
  254   if ( !res.operation.isEmpty() )
 
  264   Q_UNUSED( destination )
 
  272   d->mLock.lockForWrite();
 
  274   d->mSourceDestDatumTransforms.clear();
 
  276   const QDomNodeList contextNodes = element.elementsByTagName( QStringLiteral( 
"transformContext" ) );
 
  277   if ( contextNodes.count() < 1 )
 
  283   missingTransforms.clear();
 
  286   const QDomElement contextElem = contextNodes.at( 0 ).toElement();
 
  289   const QDomNodeList srcDestNodes = contextElem.elementsByTagName( QStringLiteral( 
"srcDest" ) );
 
  290   for ( 
int i = 0; i < srcDestNodes.size(); ++i )
 
  292     const QDomElement transformElem = srcDestNodes.at( i ).toElement();
 
  294 #if PROJ_VERSION_MAJOR>=6 
  295     const QDomElement srcElem = transformElem.firstChildElement( QStringLiteral( 
"src" ) );
 
  296     const QDomElement destElem = transformElem.firstChildElement( QStringLiteral( 
"dest" ) );
 
  300     if ( !srcElem.isNull() && !destElem.isNull() )
 
  308       const QString key1 = transformElem.attribute( QStringLiteral( 
"source" ) );
 
  309       const QString key2 = transformElem.attribute( QStringLiteral( 
"dest" ) );
 
  317     const QString coordinateOp = transformElem.attribute( QStringLiteral( 
"coordinateOp" ) );
 
  318     const bool allowFallback = transformElem.attribute( QStringLiteral( 
"allowFallback" ), QStringLiteral( 
"1" ) ).toInt();
 
  321     if ( !QgsProjUtils::coordinateOperationIsAvailable( coordinateOp ) )
 
  328     QgsCoordinateTransformContextPrivate::OperationDetails deets;
 
  329     deets.operation = coordinateOp;
 
  330     deets.allowFallback = allowFallback;
 
  331     d->mSourceDestDatumTransforms.insert( qMakePair( srcCrs, destCrs ), deets );
 
  333     const QString key1 = transformElem.attribute( QStringLiteral( 
"source" ) );
 
  334     const QString key2 = transformElem.attribute( QStringLiteral( 
"dest" ) );
 
  336     QString value1 = transformElem.attribute( QStringLiteral( 
"sourceTransform" ) );
 
  337     QString value2 = transformElem.attribute( QStringLiteral( 
"destTransform" ) );
 
  343     if ( !value1.isEmpty() )
 
  349         missingTransforms << value1;
 
  352     if ( !value2.isEmpty() )
 
  358         missingTransforms << value2;
 
  373   d->mLock.lockForRead();
 
  375   QDomDocument doc = element.ownerDocument();
 
  377   QDomElement contextElem = doc.createElement( QStringLiteral( 
"transformContext" ) );
 
  380   for ( 
auto it = d->mSourceDestDatumTransforms.constBegin(); it != d->mSourceDestDatumTransforms.constEnd(); ++ it )
 
  382     QDomElement transformElem = doc.createElement( QStringLiteral( 
"srcDest" ) );
 
  383 #if PROJ_VERSION_MAJOR>=6 
  384     QDomElement srcElem = doc.createElement( QStringLiteral( 
"src" ) );
 
  385     QDomElement destElem = doc.createElement( QStringLiteral( 
"dest" ) );
 
  387     it.key().first.writeXml( srcElem, doc );
 
  388     it.key().second.writeXml( destElem, doc );
 
  390     transformElem.appendChild( srcElem );
 
  391     transformElem.appendChild( destElem );
 
  393     transformElem.setAttribute( QStringLiteral( 
"coordinateOp" ), it.value().operation );
 
  394     transformElem.setAttribute( QStringLiteral( 
"allowFallback" ), it.value().allowFallback ? QStringLiteral( 
"1" ) : QStringLiteral( 
"0" ) );
 
  396     transformElem.setAttribute( QStringLiteral( 
"source" ), it.key().first );
 
  397     transformElem.setAttribute( QStringLiteral( 
"dest" ), it.key().second );
 
  401     transformElem.setAttribute( QStringLiteral( 
"destTransform" ), it.value().destinationTransformId < 0 ? QString() : 
QgsDatumTransform::datumTransformToProj( it.value().destinationTransformId ) );
 
  404     contextElem.appendChild( transformElem );
 
  407   element.appendChild( contextElem );
 
  414   d->mLock.lockForWrite();
 
  416   d->mSourceDestDatumTransforms.clear();
 
  419   settings.
beginGroup( QStringLiteral( 
"/Projections" ) );
 
  420   QStringList projectionKeys = settings.
allKeys();
 
  423 #if PROJ_VERSION_MAJOR>=6 
  424   QMap< QPair< QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem >, QgsCoordinateTransformContextPrivate::OperationDetails > transforms;
 
  426   QMap< QPair< QString, QString >, QPair< int, int > > transforms;
 
  428   QStringList::const_iterator pkeyIt = projectionKeys.constBegin();
 
  429   for ( ; pkeyIt != projectionKeys.constEnd(); ++pkeyIt )
 
  431 #if PROJ_VERSION_MAJOR>=6 
  432     if ( pkeyIt->contains( QLatin1String( 
"coordinateOp" ) ) )
 
  434       QStringList split = pkeyIt->split( 
'/' );
 
  435       QString srcAuthId, destAuthId;
 
  436       if ( ! split.isEmpty() )
 
  438         srcAuthId = split.at( 0 );
 
  440       if ( split.size() > 1 )
 
  442         destAuthId = split.at( 1 ).split( 
'_' ).at( 0 );
 
  445       if ( srcAuthId.isEmpty() || destAuthId.isEmpty() )
 
  448       const QString proj = settings.
value( *pkeyIt ).toString();
 
  449       const bool allowFallback = settings.
value( QStringLiteral( 
"%1//%2_allowFallback" ).arg( srcAuthId, destAuthId ) ).toBool();
 
  450       QgsCoordinateTransformContextPrivate::OperationDetails deets;
 
  451       deets.operation = proj;
 
  452       deets.allowFallback = allowFallback;
 
  456     if ( pkeyIt->contains( QLatin1String( 
"srcTransform" ) ) || pkeyIt->contains( QLatin1String( 
"destTransform" ) ) )
 
  458       QStringList split = pkeyIt->split( 
'/' );
 
  459       QString srcAuthId, destAuthId;
 
  460       if ( ! split.isEmpty() )
 
  462         srcAuthId = split.at( 0 );
 
  464       if ( split.size() > 1 )
 
  466         destAuthId = split.at( 1 ).split( 
'_' ).at( 0 );
 
  469       QString proj = settings.
value( *pkeyIt ).toString();
 
  473       if ( pkeyIt->contains( QLatin1String( 
"srcTransform" ) ) )
 
  475         transforms[ qMakePair( srcAuthId, destAuthId )].first = datumId;
 
  477       else if ( pkeyIt->contains( QLatin1String( 
"destTransform" ) ) )
 
  479         transforms[ qMakePair( srcAuthId, destAuthId )].second = datumId;
 
  486   auto transformIt = transforms.constBegin();
 
  487   for ( ; transformIt != transforms.constEnd(); ++transformIt )
 
  489 #if PROJ_VERSION_MAJOR>=6 
  490     d->mSourceDestDatumTransforms.insert( transformIt.key(), transformIt.value() );
 
  503   settings.
beginGroup( QStringLiteral( 
"/Projections" ) );
 
  504   QStringList groupKeys = settings.
allKeys();
 
  505   QStringList::const_iterator groupKeyIt = groupKeys.constBegin();
 
  506   for ( ; groupKeyIt != groupKeys.constEnd(); ++groupKeyIt )
 
  508     if ( groupKeyIt->contains( QLatin1String( 
"srcTransform" ) ) || groupKeyIt->contains( QLatin1String( 
"destTransform" ) ) || groupKeyIt->contains( QLatin1String( 
"coordinateOp" ) ) )
 
  510       settings.
remove( *groupKeyIt );
 
  514   for ( 
auto transformIt = d->mSourceDestDatumTransforms.constBegin(); transformIt != d->mSourceDestDatumTransforms.constEnd(); ++transformIt )
 
  516 #if PROJ_VERSION_MAJOR>=6 
  517     const QString srcAuthId = transformIt.key().first.authid();
 
  518     const QString destAuthId = transformIt.key().second.authid();
 
  520     const QString srcAuthId = transformIt.key().first;
 
  521     const QString destAuthId = transformIt.key().second;
 
  524     if ( srcAuthId.isEmpty() || destAuthId.isEmpty() )
 
  527 #if PROJ_VERSION_MAJOR>=6 
  528     const QString proj = transformIt.value().operation;
 
  529     const bool allowFallback = transformIt.value().allowFallback;
 
  530     settings.
setValue( srcAuthId + 
"//" + destAuthId + 
"_coordinateOp", proj );
 
  531     settings.
setValue( srcAuthId + 
"//" + destAuthId + 
"_allowFallback", allowFallback );
 
  533     int sourceDatumTransform = transformIt.value().sourceTransformId;
 
  534     QString sourceDatumProj;
 
  536     if ( sourceDatumTransform >= 0 )
 
  538     int destinationDatumTransform = transformIt.value().destinationTransformId;
 
  539     QString destinationDatumProj;
 
  540     if ( destinationDatumTransform >= 0 )
 
  544     settings.
setValue( srcAuthId + 
"//" + destAuthId + 
"_srcTransform", sourceDatumProj );
 
  545     settings.
setValue( srcAuthId + 
"//" + destAuthId + 
"_destTransform", destinationDatumProj );
 
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
QString authid() const
Returns the authority identifier for the CRS.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
Contains information about the context in which a coordinate transform is executed.
void clear()
Clears all stored transform information from the context.
bool allowFallbackTransform(const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination) const
Returns true if approximate "ballpark" transforms may be used when transforming between a source and ...
QString calculateCoordinateOperation(const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination) const
Returns the Proj coordinate operation string to use when transforming from the specified source CRS t...
void readSettings()
Reads the context's state from application settings.
void writeSettings()
Write the context's state to application settings.
Q_DECL_DEPRECATED bool addSourceDestinationDatumTransform(const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, int sourceTransformId, int destinationTransformId)
Adds a new sourceTransform and destinationTransform to use when projecting coordinates from the speci...
QMap< QPair< QString, QString >, QString > coordinateOperations() const
Returns the stored mapping for source to destination CRS pairs to associated coordinate operation to ...
void writeXml(QDomElement &element, const QgsReadWriteContext &context) const
Writes the context's state to a DOM element.
Q_DECL_DEPRECATED QgsDatumTransform::TransformPair calculateDatumTransforms(const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination) const
Returns the pair of source and destination datum transforms to use for a transform from the specified...
Q_DECL_DEPRECATED QMap< QPair< QString, QString >, QgsDatumTransform::TransformPair > sourceDestinationDatumTransforms() const
Returns the stored mapping for source to destination CRS pairs to associated datum transforms to use.
~QgsCoordinateTransformContext()
bool readXml(const QDomElement &element, const QgsReadWriteContext &context, QStringList &missingTransforms)
Reads the context's state from a DOM element.
bool addCoordinateOperation(const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, const QString &coordinateOperationProjString, bool allowFallback=true)
Adds a new coordinateOperationProjString to use when projecting coordinates from the specified source...
void removeCoordinateOperation(const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs)
Removes the coordinate operation for the specified sourceCrs and destinationCrs.
QgsCoordinateTransformContext()
Constructor for QgsCoordinateTransformContext.
bool hasTransform(const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination) const
Returns true if the context has a valid coordinate operation to use when transforming from the specif...
bool mustReverseCoordinateOperation(const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination) const
Returns true if the coordinate operation returned by calculateCoordinateOperation() for the source to...
bool operator==(const QgsCoordinateTransformContext &rhs) const
Q_DECL_DEPRECATED void removeSourceDestinationDatumTransform(const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs)
Removes the source to destination datum transform pair for the specified sourceCrs and destinationCrs...
QgsCoordinateTransformContext & operator=(const QgsCoordinateTransformContext &rhs)
Assignment operator.
The class is used as a container of context for various read/write operations on other objects.
This class is a composition of two QSettings instances:
void endGroup()
Resets the group to what it was before the corresponding beginGroup() call.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void beginGroup(const QString &prefix, QgsSettings::Section section=QgsSettings::NoSection)
Appends prefix to the current group.
void remove(const QString &key, QgsSettings::Section section=QgsSettings::NoSection)
Removes the setting key and any sub-settings of key in a section.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
QStringList allKeys() const
Returns a list of all keys, including subkeys, that can be read using the QSettings object.
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
QString crsToKey(const QgsCoordinateReferenceSystem &crs)
const QgsCoordinateReferenceSystem & crs