26using namespace Qt::StringLiterals;
34 : d( new QgsCoordinateTransformContextPrivate() )
44 : d( std::move( rhs.d ) )
62 d = std::move( rhs.d );
71 d->mLock.lockForRead();
72 rhs.d->mLock.lockForRead();
73 const bool equal = d->mSourceDestDatumTransforms == rhs.d->mSourceDestDatumTransforms;
75 rhs.d->mLock.unlock();
81 return !( *
this == rhs );
88 d->mLock.lockForWrite();
89 d->mSourceDestDatumTransforms.clear();
100 d->mLock.lockForRead();
101 auto res = d->mSourceDestDatumTransforms;
104 QMap<QPair<QString, QString>, QString> results;
105 for (
auto it = res.constBegin(); it != res.constEnd(); ++it )
106 results.insert( qMakePair( it.key().first.authid(), it.key().second.authid() ), it.value().operation );
115 Q_UNUSED( sourceTransform )
116 Q_UNUSED( destinationTransform )
125 d->mLock.lockForWrite();
126 QgsCoordinateTransformContextPrivate::OperationDetails details;
127 details.operation = coordinateOperationProjString;
128 details.allowFallback = allowFallback;
129 d->mSourceDestDatumTransforms.insert( qMakePair( sourceCrs, destinationCrs ), details );
141 d->mSourceDestDatumTransforms.remove( qMakePair( sourceCrs, destinationCrs ) );
153 Q_UNUSED( destination )
162 d->mLock.lockForRead();
164 auto it = d->mSourceDestDatumTransforms.constFind( qMakePair( source, destination ) );
165 if ( it == d->mSourceDestDatumTransforms.constEnd() )
168 it = d->mSourceDestDatumTransforms.constFind( qMakePair( destination, source ) );
171 const QString result = it == d->mSourceDestDatumTransforms.constEnd() ? QString() : it.value().operation;
181 d->mLock.lockForRead();
182 QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( source, destination ), QgsCoordinateTransformContextPrivate::OperationDetails() );
183 if ( res.operation.isEmpty() )
186 res = d->mSourceDestDatumTransforms.value( qMakePair( destination, source ), QgsCoordinateTransformContextPrivate::OperationDetails() );
189 return res.allowFallback;
197 d->mLock.lockForRead();
198 QgsCoordinateTransformContextPrivate::OperationDetails res = d->mSourceDestDatumTransforms.value( qMakePair( source, destination ), QgsCoordinateTransformContextPrivate::OperationDetails() );
199 if ( !res.operation.isEmpty() )
205 res = d->mSourceDestDatumTransforms.value( qMakePair( destination, source ), QgsCoordinateTransformContextPrivate::OperationDetails() );
206 if ( !res.operation.isEmpty() )
219 d->mLock.lockForWrite();
221 d->mSourceDestDatumTransforms.clear();
223 const QDomNodeList contextNodes = element.elementsByTagName( u
"transformContext"_s );
224 if ( contextNodes.count() < 1 )
230 missingTransforms.clear();
233 const QDomElement contextElem = contextNodes.at( 0 ).toElement();
236 const QDomNodeList srcDestNodes = contextElem.elementsByTagName( u
"srcDest"_s );
237 for (
int i = 0; i < srcDestNodes.size(); ++i )
239 const QDomElement transformElem = srcDestNodes.at( i ).toElement();
241 const QDomElement srcElem = transformElem.firstChildElement( u
"src"_s );
242 const QDomElement destElem = transformElem.firstChildElement( u
"dest"_s );
246 if ( !srcElem.isNull() && !destElem.isNull() )
254 const QString key1 = transformElem.attribute( u
"source"_s );
255 const QString key2 = transformElem.attribute( u
"dest"_s );
263 const QString coordinateOp = transformElem.attribute( u
"coordinateOp"_s );
264 const bool allowFallback = transformElem.attribute( u
"allowFallback"_s, u
"1"_s ).toInt();
274 QgsCoordinateTransformContextPrivate::OperationDetails deets;
276 deets.allowFallback = allowFallback;
277 d->mSourceDestDatumTransforms.insert( qMakePair( srcCrs, destCrs ), deets );
286 d->mLock.lockForRead();
288 QDomDocument doc = element.ownerDocument();
290 QDomElement contextElem = doc.createElement( u
"transformContext"_s );
293 for (
auto it = d->mSourceDestDatumTransforms.constBegin(); it != d->mSourceDestDatumTransforms.constEnd(); ++ it )
295 QDomElement transformElem = doc.createElement( u
"srcDest"_s );
296 QDomElement srcElem = doc.createElement( u
"src"_s );
297 QDomElement destElem = doc.createElement( u
"dest"_s );
299 it.key().first.writeXml( srcElem, doc );
300 it.key().second.writeXml( destElem, doc );
302 transformElem.appendChild( srcElem );
303 transformElem.appendChild( destElem );
305 transformElem.setAttribute( u
"coordinateOp"_s, it.value().operation );
306 transformElem.setAttribute( u
"allowFallback"_s, it.value().allowFallback ? u
"1"_s : u
"0"_s );
307 contextElem.appendChild( transformElem );
310 element.appendChild( contextElem );
317 d->mLock.lockForWrite();
319 d->mSourceDestDatumTransforms.clear();
323 const QStringList projectionKeys = settings.
allKeys();
326 QMap< QPair< QgsCoordinateReferenceSystem, QgsCoordinateReferenceSystem >, QgsCoordinateTransformContextPrivate::OperationDetails > transforms;
327 QStringList::const_iterator pkeyIt = projectionKeys.constBegin();
328 for ( ; pkeyIt != projectionKeys.constEnd(); ++pkeyIt )
330 if ( pkeyIt->contains(
"coordinateOp"_L1 ) )
332 const QStringList split = pkeyIt->split(
'/' );
333 QString srcAuthId, destAuthId;
334 if ( ! split.isEmpty() )
336 srcAuthId = split.at( 0 );
338 if ( split.size() > 1 )
340 destAuthId = split.at( 1 ).split(
'_' ).at( 0 );
343 if ( srcAuthId.isEmpty() || destAuthId.isEmpty() )
346 const QString proj = settings.
value( *pkeyIt ).toString();
347 const bool allowFallback = settings.
value( u
"%1//%2_allowFallback"_s.arg( srcAuthId, destAuthId ) ).toBool();
348 QgsCoordinateTransformContextPrivate::OperationDetails deets;
349 deets.operation = proj;
350 deets.allowFallback = allowFallback;
356 auto transformIt = transforms.constBegin();
357 for ( ; transformIt != transforms.constEnd(); ++transformIt )
359 d->mSourceDestDatumTransforms.insert( transformIt.key(), transformIt.value() );
370 const QStringList groupKeys = settings.
allKeys();
371 QStringList::const_iterator groupKeyIt = groupKeys.constBegin();
372 for ( ; groupKeyIt != groupKeys.constEnd(); ++groupKeyIt )
374 if ( groupKeyIt->contains(
"srcTransform"_L1 ) || groupKeyIt->contains(
"destTransform"_L1 ) || groupKeyIt->contains(
"coordinateOp"_L1 ) )
376 settings.
remove( *groupKeyIt );
380 for (
auto transformIt = d->mSourceDestDatumTransforms.constBegin(); transformIt != d->mSourceDestDatumTransforms.constEnd(); ++transformIt )
382 const QString srcAuthId = transformIt.key().first.authid();
383 const QString destAuthId = transformIt.key().second.authid();
385 if ( srcAuthId.isEmpty() || destAuthId.isEmpty() )
388 const QString proj = transformIt.value().operation;
389 const bool allowFallback = transformIt.value().allowFallback;
390 settings.
setValue( srcAuthId +
"//" + destAuthId +
"_coordinateOp", proj );
391 settings.
setValue( srcAuthId +
"//" + destAuthId +
"_allowFallback", allowFallback );
@ 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...
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)
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.
Stores settings for use within QGIS.
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.
QString crsToKey(const QgsCoordinateReferenceSystem &crs)