27using namespace Qt::StringLiterals;
32 =
new QgsSettingsEntryString( u
"operation"_s, sTreeCoordinateOperationsDestination, QString(), u
"PROJ coordinate operation string used when transforming between the source and destination CRS pair."_s );
34 =
new QgsSettingsEntryBool( u
"allow-fallback"_s, sTreeCoordinateOperationsDestination,
true, u
"If true, transformations between the source and destination CRS pair are allowed to fall back to a less accurate operation when the preferred coordinate operation fails."_s );
42 : d( new QgsCoordinateTransformContextPrivate() )
52 : d( std::move( rhs.d ) )
70 d = std::move( rhs.d );
79 d->mLock.lockForRead();
80 rhs.d->mLock.lockForRead();
81 const bool equal = d->mSourceDestDatumTransforms == rhs.d->mSourceDestDatumTransforms;
83 rhs.d->mLock.unlock();
89 return !( *
this == rhs );
96 d->mLock.lockForWrite();
97 d->mSourceDestDatumTransforms.clear();
108 d->mLock.lockForRead();
109 auto res = d->mSourceDestDatumTransforms;
112 QMap<QPair<QString, QString>, QString> results;
113 for (
auto it = res.constBegin(); it != res.constEnd(); ++it )
114 results.insert( qMakePair( it.key().first.authid(), it.key().second.authid() ), it.value().operation );
125 Q_UNUSED( sourceTransform )
126 Q_UNUSED( destinationTransform )
137 d->mLock.lockForWrite();
138 QgsCoordinateTransformContextPrivate::OperationDetails details;
139 details.operation = coordinateOperationProjString;
140 details.allowFallback = allowFallback;
141 d->mSourceDestDatumTransforms.insert( qMakePair( sourceCrs, destinationCrs ), details );
153 d->mSourceDestDatumTransforms.remove( qMakePair( sourceCrs, destinationCrs ) );
165 Q_UNUSED( destination )
174 d->mLock.lockForRead();
176 auto it = d->mSourceDestDatumTransforms.constFind( qMakePair( source, destination ) );
177 if ( it == d->mSourceDestDatumTransforms.constEnd() )
180 it = d->mSourceDestDatumTransforms.constFind( qMakePair( destination, source ) );
183 const QString result = it == d->mSourceDestDatumTransforms.constEnd() ? QString() : it.value().operation;
193 d->mLock.lockForRead();
194 QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( source, destination ), QgsCoordinateTransformContextPrivate::OperationDetails() );
195 if ( res.operation.isEmpty() )
198 res = d->mSourceDestDatumTransforms.value( qMakePair( destination, source ), QgsCoordinateTransformContextPrivate::OperationDetails() );
201 return res.allowFallback;
209 d->mLock.lockForRead();
210 QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( source, destination ), QgsCoordinateTransformContextPrivate::OperationDetails() );
211 if ( !res.operation.isEmpty() )
217 res = d->mSourceDestDatumTransforms.value( qMakePair( destination, source ), QgsCoordinateTransformContextPrivate::OperationDetails() );
218 if ( !res.operation.isEmpty() )
231 d->mLock.lockForWrite();
233 d->mSourceDestDatumTransforms.clear();
235 const QDomNodeList contextNodes = element.elementsByTagName( u
"transformContext"_s );
236 if ( contextNodes.count() < 1 )
242 missingTransforms.clear();
245 const QDomElement contextElem = contextNodes.at( 0 ).toElement();
248 const QDomNodeList srcDestNodes = contextElem.elementsByTagName( u
"srcDest"_s );
249 for (
int i = 0; i < srcDestNodes.size(); ++i )
251 const QDomElement transformElem = srcDestNodes.at( i ).toElement();
253 const QDomElement srcElem = transformElem.firstChildElement( u
"src"_s );
254 const QDomElement destElem = transformElem.firstChildElement( u
"dest"_s );
258 if ( !srcElem.isNull() && !destElem.isNull() )
266 const QString key1 = transformElem.attribute( u
"source"_s );
267 const QString key2 = transformElem.attribute( u
"dest"_s );
275 const QString coordinateOp = transformElem.attribute( u
"coordinateOp"_s );
276 const bool allowFallback = transformElem.attribute( u
"allowFallback"_s, u
"1"_s ).toInt();
286 QgsCoordinateTransformContextPrivate::OperationDetails deets;
288 deets.allowFallback = allowFallback;
289 d->mSourceDestDatumTransforms.insert( qMakePair( srcCrs, destCrs ), deets );
298 d->mLock.lockForRead();
300 QDomDocument doc = element.ownerDocument();
302 QDomElement contextElem = doc.createElement( u
"transformContext"_s );
305 for (
auto it = d->mSourceDestDatumTransforms.constBegin(); it != d->mSourceDestDatumTransforms.constEnd(); ++it )
307 QDomElement transformElem = doc.createElement( u
"srcDest"_s );
308 QDomElement srcElem = doc.createElement( u
"src"_s );
309 QDomElement destElem = doc.createElement( u
"dest"_s );
311 it.key().first.writeXml( srcElem, doc );
312 it.key().second.writeXml( destElem, doc );
314 transformElem.appendChild( srcElem );
315 transformElem.appendChild( destElem );
317 transformElem.setAttribute( u
"coordinateOp"_s, it.value().operation );
318 transformElem.setAttribute( u
"allowFallback"_s, it.value().allowFallback ? u
"1"_s : u
"0"_s );
319 contextElem.appendChild( transformElem );
322 element.appendChild( contextElem );
329 d->mLock.lockForWrite();
331 d->mSourceDestDatumTransforms.clear();
333 QMap<QPair<QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem>, QgsCoordinateTransformContextPrivate::OperationDetails> transforms;
335 for (
const QString &srcAuthId : srcAuthIds )
338 for (
const QString &destAuthId : destAuthIds )
340 QgsCoordinateTransformContextPrivate::OperationDetails deets;
348 auto transformIt = transforms.constBegin();
349 for ( ; transformIt != transforms.constEnd(); ++transformIt )
351 d->mSourceDestDatumTransforms.insert( transformIt.key(), transformIt.value() );
361 for (
auto transformIt = d->mSourceDestDatumTransforms.constBegin(); transformIt != d->mSourceDestDatumTransforms.constEnd(); ++transformIt )
363 const QString srcAuthId = transformIt.key().first.authid();
364 const QString destAuthId = transformIt.key().second.authid();
366 if ( srcAuthId.isEmpty() || destAuthId.isEmpty() )
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
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 toWkt(Qgis::CrsWktVariant variant=Qgis::CrsWktVariant::Wkt1Gdal, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
QgsProjOperation operation() const
Returns information about the PROJ operation associated with the coordinate reference system,...
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...
static QgsSettingsTreeNamedListNode * sTreeCoordinateOperationsSource
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...
static const QgsSettingsEntryString * settingsCoordinateOperation
static const QgsSettingsEntryBool * settingsAllowFallback
static QgsSettingsTreeNamedListNode * sTreeCoordinateOperationsDestination
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)
bool operator!=(const QgsCoordinateTransformContext &rhs) const
static bool coordinateOperationIsAvailable(const QString &projDef)
Returns true if a coordinate operation (specified via proj string) is available.
A container for the context for various read/write operations on objects.
A boolean settings entry.
A named list tree node for the settings tree to help organizing and introspecting the tree.
static QgsSettingsTreeNode * sTreeCrs
QString crsToKey(const QgsCoordinateReferenceSystem &crs)