21 #include "qgssettings.h" 
   29 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 
   31 bool qMapLessThanKey<QPair<QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem>>( 
const QPair<QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem> &key1,
 
   32     const QPair<QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem> &key2 )
 
   34   const QPair< QString, QString > key1String = qMakePair( 
crsToKey( key1.first ), 
crsToKey( key1.second ) );
 
   35   const QPair< QString, QString > key2String = qMakePair( 
crsToKey( key2.first ), 
crsToKey( key2.second ) );
 
   36   return key1String < key2String;
 
   41   : d( new QgsCoordinateTransformContextPrivate() )
 
   61   d->mLock.lockForRead();
 
   62   rhs.d->mLock.lockForRead();
 
   63   bool equal = d->mSourceDestDatumTransforms == rhs.d->mSourceDestDatumTransforms;
 
   65   rhs.d->mLock.unlock();
 
   73   d->mLock.lockForWrite();
 
   74   d->mSourceDestDatumTransforms.clear();
 
   85   d->mLock.lockForRead();
 
   86   auto res = d->mSourceDestDatumTransforms;
 
   89   QMap<QPair<QString, QString>, QString> results;
 
   90   for ( 
auto it = res.constBegin(); it != res.constEnd(); ++it )
 
   91     results.insert( qMakePair( it.key().first.authid(), it.key().second.authid() ), it.value().operation );
 
  100   Q_UNUSED( sourceTransform )
 
  101   Q_UNUSED( destinationTransform )
 
  110   d->mLock.lockForWrite();
 
  111   QgsCoordinateTransformContextPrivate::OperationDetails details;
 
  112   details.operation = coordinateOperationProjString;
 
  113   details.allowFallback = allowFallback;
 
  114   d->mSourceDestDatumTransforms.insert( qMakePair( sourceCrs, destinationCrs ), details );
 
  126   d->mSourceDestDatumTransforms.remove( qMakePair( sourceCrs, destinationCrs ) );
 
  138   Q_UNUSED( destination )
 
  147   d->mLock.lockForRead();
 
  148   QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( source, destination ), QgsCoordinateTransformContextPrivate::OperationDetails() );
 
  149   if ( res.operation.isEmpty() )
 
  152     res = d->mSourceDestDatumTransforms.value( qMakePair( destination, source ), QgsCoordinateTransformContextPrivate::OperationDetails() );
 
  155   return res.operation;
 
  163   d->mLock.lockForRead();
 
  164   QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( source, destination ), QgsCoordinateTransformContextPrivate::OperationDetails() );
 
  165   if ( res.operation.isEmpty() )
 
  168     res = d->mSourceDestDatumTransforms.value( qMakePair( destination, source ), QgsCoordinateTransformContextPrivate::OperationDetails() );
 
  171   return res.allowFallback;
 
  179   d->mLock.lockForRead();
 
  180   QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( source, destination ), QgsCoordinateTransformContextPrivate::OperationDetails() );
 
  181   if ( !res.operation.isEmpty() )
 
  187   res = d->mSourceDestDatumTransforms.value( qMakePair( destination, source ), QgsCoordinateTransformContextPrivate::OperationDetails() );
 
  188   if ( !res.operation.isEmpty() )
 
  201   d->mLock.lockForWrite();
 
  203   d->mSourceDestDatumTransforms.clear();
 
  205   const QDomNodeList contextNodes = element.elementsByTagName( QStringLiteral( 
"transformContext" ) );
 
  206   if ( contextNodes.count() < 1 )
 
  212   missingTransforms.clear();
 
  215   const QDomElement contextElem = contextNodes.at( 0 ).toElement();
 
  218   const QDomNodeList srcDestNodes = contextElem.elementsByTagName( QStringLiteral( 
"srcDest" ) );
 
  219   for ( 
int i = 0; i < srcDestNodes.size(); ++i )
 
  221     const QDomElement transformElem = srcDestNodes.at( i ).toElement();
 
  223     const QDomElement srcElem = transformElem.firstChildElement( QStringLiteral( 
"src" ) );
 
  224     const QDomElement destElem = transformElem.firstChildElement( QStringLiteral( 
"dest" ) );
 
  228     if ( !srcElem.isNull() && !destElem.isNull() )
 
  236       const QString key1 = transformElem.attribute( QStringLiteral( 
"source" ) );
 
  237       const QString key2 = transformElem.attribute( QStringLiteral( 
"dest" ) );
 
  245     const QString coordinateOp = transformElem.attribute( QStringLiteral( 
"coordinateOp" ) );
 
  246     const bool allowFallback = transformElem.attribute( QStringLiteral( 
"allowFallback" ), QStringLiteral( 
"1" ) ).toInt();
 
  256     QgsCoordinateTransformContextPrivate::OperationDetails deets;
 
  257     deets.operation = coordinateOp;
 
  258     deets.allowFallback = allowFallback;
 
  259     d->mSourceDestDatumTransforms.insert( qMakePair( srcCrs, destCrs ), deets );
 
  268   d->mLock.lockForRead();
 
  270   QDomDocument doc = element.ownerDocument();
 
  272   QDomElement contextElem = doc.createElement( QStringLiteral( 
"transformContext" ) );
 
  275   for ( 
auto it = d->mSourceDestDatumTransforms.constBegin(); it != d->mSourceDestDatumTransforms.constEnd(); ++ it )
 
  277     QDomElement transformElem = doc.createElement( QStringLiteral( 
"srcDest" ) );
 
  278     QDomElement srcElem = doc.createElement( QStringLiteral( 
"src" ) );
 
  279     QDomElement destElem = doc.createElement( QStringLiteral( 
"dest" ) );
 
  281     it.key().first.writeXml( srcElem, doc );
 
  282     it.key().second.writeXml( destElem, doc );
 
  284     transformElem.appendChild( srcElem );
 
  285     transformElem.appendChild( destElem );
 
  287     transformElem.setAttribute( QStringLiteral( 
"coordinateOp" ), it.value().operation );
 
  288     transformElem.setAttribute( QStringLiteral( 
"allowFallback" ), it.value().allowFallback ? QStringLiteral( 
"1" ) : QStringLiteral( 
"0" ) );
 
  289     contextElem.appendChild( transformElem );
 
  292   element.appendChild( contextElem );
 
  299   d->mLock.lockForWrite();
 
  301   d->mSourceDestDatumTransforms.clear();
 
  303   QgsSettings settings;
 
  304   settings.beginGroup( QStringLiteral( 
"/Projections" ) );
 
  305   QStringList projectionKeys = settings.allKeys();
 
  308   QMap< QPair< QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem >, QgsCoordinateTransformContextPrivate::OperationDetails > transforms;
 
  309   QStringList::const_iterator pkeyIt = projectionKeys.constBegin();
 
  310   for ( ; pkeyIt != projectionKeys.constEnd(); ++pkeyIt )
 
  312     if ( pkeyIt->contains( QLatin1String( 
"coordinateOp" ) ) )
 
  314       QStringList split = pkeyIt->split( 
'/' );
 
  315       QString srcAuthId, destAuthId;
 
  316       if ( ! split.isEmpty() )
 
  318         srcAuthId = split.at( 0 );
 
  320       if ( split.size() > 1 )
 
  322         destAuthId = split.at( 1 ).split( 
'_' ).at( 0 );
 
  325       if ( srcAuthId.isEmpty() || destAuthId.isEmpty() )
 
  328       const QString proj = settings.value( *pkeyIt ).toString();
 
  329       const bool allowFallback = settings.value( QStringLiteral( 
"%1//%2_allowFallback" ).arg( srcAuthId, destAuthId ) ).toBool();
 
  330       QgsCoordinateTransformContextPrivate::OperationDetails deets;
 
  331       deets.operation = proj;
 
  332       deets.allowFallback = allowFallback;
 
  338   auto transformIt = transforms.constBegin();
 
  339   for ( ; transformIt != transforms.constEnd(); ++transformIt )
 
  341     d->mSourceDestDatumTransforms.insert( transformIt.key(), transformIt.value() );
 
  350   QgsSettings settings;
 
  351   settings.beginGroup( QStringLiteral( 
"/Projections" ) );
 
  352   QStringList groupKeys = settings.allKeys();
 
  353   QStringList::const_iterator groupKeyIt = groupKeys.constBegin();
 
  354   for ( ; groupKeyIt != groupKeys.constEnd(); ++groupKeyIt )
 
  356     if ( groupKeyIt->contains( QLatin1String( 
"srcTransform" ) ) || groupKeyIt->contains( QLatin1String( 
"destTransform" ) ) || groupKeyIt->contains( QLatin1String( 
"coordinateOp" ) ) )
 
  358       settings.remove( *groupKeyIt );
 
  362   for ( 
auto transformIt = d->mSourceDestDatumTransforms.constBegin(); transformIt != d->mSourceDestDatumTransforms.constEnd(); ++transformIt )
 
  364     const QString srcAuthId = transformIt.key().first.authid();
 
  365     const QString destAuthId = transformIt.key().second.authid();
 
  367     if ( srcAuthId.isEmpty() || destAuthId.isEmpty() )
 
  370     const QString proj = transformIt.value().operation;
 
  371     const bool allowFallback = transformIt.value().allowFallback;
 
  372     settings.setValue( srcAuthId + 
"//" + destAuthId + 
"_coordinateOp", proj );
 
  373     settings.setValue( srcAuthId + 
"//" + destAuthId + 
"_allowFallback", allowFallback );
 
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.
static bool coordinateOperationIsAvailable(const QString &projDef)
Returns true if a coordinate operation (specified via proj string) is available.
The class is used as a container of context for various read/write operations on other objects.
QString crsToKey(const QgsCoordinateReferenceSystem &crs)
const QgsCoordinateReferenceSystem & crs