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