Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgscoordinatetransformcontext.h 3 : : ------------------------------- 4 : : begin : November 2017 5 : : copyright : (C) 2017 by Nyall Dawson 6 : : email : nyall dot dawson at gmail dot com 7 : : ***************************************************************************/ 8 : : 9 : : /*************************************************************************** 10 : : * * 11 : : * This program is free software; you can redistribute it and/or modify * 12 : : * it under the terms of the GNU General Public License as published by * 13 : : * the Free Software Foundation; either version 2 of the License, or * 14 : : * (at your option) any later version. * 15 : : * * 16 : : ***************************************************************************/ 17 : : 18 : : #ifndef QGSCOORDINATETRANSFORMCONTEXT_H 19 : : #define QGSCOORDINATETRANSFORMCONTEXT_H 20 : : 21 : : #include "qgis_core.h" 22 : : #include "qgis_sip.h" 23 : : #include "qgsdatumtransform.h" 24 : : 25 : : #include <QMetaType> 26 : : #include <QExplicitlySharedDataPointer> 27 : : class QgsCoordinateReferenceSystem; 28 : : class QgsReadWriteContext; 29 : : class QgsCoordinateTransformContextPrivate; 30 : : class QDomElement; 31 : : 32 : : /*************************************************************************** 33 : : * This class is considered CRITICAL and any change MUST be accompanied with 34 : : * full unit tests in testqgsfeature.cpp. 35 : : * See details in QEP #17 36 : : ****************************************************************************/ 37 : : 38 : : /** 39 : : * \class QgsCoordinateTransformContext 40 : : * \ingroup core 41 : : * \brief Contains information about the context in which a coordinate transform is executed. 42 : : * 43 : : * The context stores various information regarding which coordinate operations should 44 : : * be used when transforming points from a source to destination coordinate reference 45 : : * system. 46 : : * 47 : : * \note QgsCoordinateTransformContext objects are thread safe for read and write. 48 : : * 49 : : * \note QgsCoordinateTransformContext objects are implicitly shared. 50 : : * 51 : : * \see QgsDatumTransform 52 : : * \see QgsCoordinateTransform 53 : : * 54 : : * \since QGIS 3.0 55 : : */ 56 : : 57 : : class CORE_EXPORT QgsCoordinateTransformContext 58 : : { 59 : : public: 60 : : 61 : : /** 62 : : * Constructor for QgsCoordinateTransformContext. 63 : : */ 64 : : QgsCoordinateTransformContext(); 65 : : 66 : : ~QgsCoordinateTransformContext() ; 67 : : 68 : : /** 69 : : * Copy constructor 70 : : */ 71 : : QgsCoordinateTransformContext( const QgsCoordinateTransformContext &rhs ); 72 : : 73 : : /** 74 : : * Assignment operator 75 : : */ 76 : : QgsCoordinateTransformContext &operator=( const QgsCoordinateTransformContext &rhs ) SIP_SKIP; 77 : : 78 : : bool operator==( const QgsCoordinateTransformContext &rhs ) const ; 79 : : 80 : : /** 81 : : * Clears all stored transform information from the context. 82 : : */ 83 : : void clear(); 84 : : 85 : : /** 86 : : * Returns the stored mapping for source to destination CRS pairs to associated datum transforms to use. 87 : : * The map keys will be QgsCoordinateReferenceSystems::authid()s. 88 : : * 89 : : * If either the source transform ID or destination transform ID is -1, then no datum transform is 90 : : * required for transformations for that source or destination. 91 : : * 92 : : * \warning This method should not be used to calculate the corresponding datum transforms 93 : : * to use for a coordinate transform. Instead, always use calculateDatumTransforms() 94 : : * to determine this. 95 : : * 96 : : * \see addSourceDestinationDatumTransform() 97 : : * 98 : : * \deprecated Has no effect on builds based on Proj 6.0 or later, use coordinateOperations() instead. 99 : : */ 100 : : Q_DECL_DEPRECATED QMap< QPair< QString, QString>, QgsDatumTransform::TransformPair > sourceDestinationDatumTransforms() const SIP_DEPRECATED; 101 : : 102 : : /** 103 : : * Returns the stored mapping for source to destination CRS pairs to associated coordinate operation to use 104 : : * (as a proj string). The map keys will be QgsCoordinateReferenceSystems::authid()s. 105 : : * 106 : : * \warning This method should not be used to calculate the corresponding coordinate operation 107 : : * to use for a coordinate transform. Instead, always use calculateCoordinateOperation() 108 : : * to determine this. 109 : : * 110 : : * \see addCoordinateOperation() 111 : : * 112 : : * \note Requires Proj 6.0 or later. Builds based on earlier Proj versions will always return an empty list, 113 : : * and the deprecated sourceDestinationDatumTransforms() method must be used instead. 114 : : * 115 : : * \since QGIS 3.8 116 : : */ 117 : : QMap< QPair< QString, QString>, QString > coordinateOperations() const; 118 : : 119 : : /** 120 : : * Adds a new \a sourceTransform and \a destinationTransform to use when projecting coordinates 121 : : * from the specified \a sourceCrs to the specified \a destinationCrs. 122 : : * 123 : : * If either \a sourceTransformId or \a destinationTransformId is -1, then no datum transform is 124 : : * required for transformations for that source or destination. 125 : : * 126 : : * Returns TRUE if the new transform pair was added successfully. 127 : : * 128 : : * \see sourceDestinationDatumTransforms() 129 : : * \see removeSourceDestinationDatumTransform() 130 : : * 131 : : * \deprecated Has no effect on builds based on Proj 6.0 or later, use addCoordinateOperation() instead. 132 : : */ 133 : : Q_DECL_DEPRECATED bool addSourceDestinationDatumTransform( const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, int sourceTransformId, int destinationTransformId ) SIP_DEPRECATED; 134 : : 135 : : /** 136 : : * Adds a new \a coordinateOperationProjString to use when projecting coordinates 137 : : * from the specified \a sourceCrs to the specified \a destinationCrs. 138 : : * 139 : : * \a coordinateOperationProjString should be set to a valid Proj coordinate operation 140 : : * string. If \a coordinateOperationProjString is empty, then the default Proj operation 141 : : * will be used when transforming between the coordinate reference systems. 142 : : * 143 : : * If \a allowFallback is TRUE (since QGIS 3.12), then "ballpark" fallback transformations 144 : : * will be used in the case that the specified coordinate operation fails (such as when 145 : : * coordinates from outside a required grid shift file are transformed). See 146 : : * QgsCoordinateTransform::fallbackOperationOccurred() for further details. Note that if an 147 : : * existing \a sourceCrs and \a destinationCrs pair are added with a different \a allowFallback 148 : : * value, that value will replace the existing one (i.e. each combination of \a sourceCrs and 149 : : * \a destinationCrs must be unique). 150 : : * 151 : : * \warning coordinateOperationProjString MUST be a proj string which has been normalized for 152 : : * visualization, and must be constructed so that coordinates are always input and output 153 : : * with x/y coordinate ordering. (Proj strings output by utilities such as projinfo will NOT 154 : : * automatically normalize the axis order!). 155 : : * 156 : : * Returns TRUE if the new coordinate operation was added successfully. 157 : : * 158 : : * \see coordinateOperations() 159 : : * \see removeCoordinateOperation() 160 : : * 161 : : * \note Requires Proj 6.0 or later. Builds based on earlier Proj versions will ignore this setting, 162 : : * and the deprecated addSourceDestinationDatumTransform() method must be used instead. 163 : : * 164 : : * \since QGIS 3.8 165 : : */ 166 : : bool addCoordinateOperation( const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, const QString &coordinateOperationProjString, bool allowFallback = true ); 167 : : 168 : : /** 169 : : * Removes the source to destination datum transform pair for the specified \a sourceCrs and 170 : : * \a destinationCrs. 171 : : * \see addSourceDestinationDatumTransform() 172 : : * 173 : : * \deprecated Use removeCoordinateOperation() instead 174 : : */ 175 : : Q_DECL_DEPRECATED void removeSourceDestinationDatumTransform( const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs ) SIP_DEPRECATED ; 176 : : 177 : : /** 178 : : * Removes the coordinate operation for the specified \a sourceCrs and \a destinationCrs. 179 : : * 180 : : * \since QGIS 3.8 181 : : */ 182 : : void removeCoordinateOperation( const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs ); 183 : : 184 : : /** 185 : : * Returns TRUE if the context has a valid coordinate operation to use 186 : : * when transforming from the specified \a source CRS to \a destination CRS. 187 : : * \note source and destination are reversible. 188 : : */ 189 : : bool hasTransform( const QgsCoordinateReferenceSystem &source, 190 : : const QgsCoordinateReferenceSystem &destination ) const; 191 : : 192 : : /** 193 : : * Returns the pair of source and destination datum transforms to use 194 : : * for a transform from the specified \a source CRS to \a destination CRS. 195 : : * 196 : : * Returns an ID of -1 if a datum transform should not be used for the source or 197 : : * destination. 198 : : * 199 : : * \note source and destination are reversible. 200 : : * \deprecated Has no effect on builds based on Proj 6.0 or later. Use calculateCoordinateOperation() instead. 201 : : */ 202 : : Q_DECL_DEPRECATED QgsDatumTransform::TransformPair calculateDatumTransforms( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination ) const SIP_DEPRECATED; 203 : : 204 : : /** 205 : : * Returns the Proj coordinate operation string to use when transforming 206 : : * from the specified \a source CRS to \a destination CRS. 207 : : * 208 : : * Returns an empty string if no specific coordinate operation is set for the source to 209 : : * destination pair, in which case the default Proj coordinate operation should 210 : : * be used. 211 : : * 212 : : * \note source and destination are reversible. 213 : : * 214 : : * \note Requires Proj 6.0 or later. Builds based on earlier Proj versions will always return 215 : : * an empty string, and the deprecated calculateDatumTransforms() method should be used instead. 216 : : * 217 : : * \warning Always check the result of mustReverseCoordinateOperation() in order to determine if the 218 : : * proj coordinate operation string returned by this method corresponds to the reverse operation, and 219 : : * must be manually flipped when calculating coordinate transforms. 220 : : * 221 : : * \since QGIS 3.8 222 : : */ 223 : : QString calculateCoordinateOperation( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination ) const; 224 : : 225 : : /** 226 : : * Returns TRUE if approximate "ballpark" transforms may be used when transforming 227 : : * between a \a source and \a destination CRS pair, in the case that the preferred 228 : : * coordinate operation fails (such as when 229 : : * coordinates from outside a required grid shift file are transformed). See 230 : : * QgsCoordinateTransform::fallbackOperationOccurred() for further details. 231 : : * 232 : : * \since QGIS 3.12 233 : : */ 234 : : bool allowFallbackTransform( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination ) const; 235 : : 236 : : /** 237 : : * Returns TRUE if the coordinate operation returned by calculateCoordinateOperation() for the \a source to \a destination pair 238 : : * must be inverted. 239 : : * 240 : : * \since QGIS 3.10.2 241 : : */ 242 : : bool mustReverseCoordinateOperation( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination ) const; 243 : : 244 : : // TODO QGIS 4.0 - remove missingTransforms, not used for Proj >= 6.0 builds 245 : : 246 : : /** 247 : : * Reads the context's state from a DOM \a element. 248 : : * 249 : : * Returns FALSE if transforms stored in the XML are not available. In this case \a missingTransforms will be 250 : : * filled with missing datum transform strings. 251 : : * 252 : : * \see writeXml() 253 : : */ 254 : : bool readXml( const QDomElement &element, const QgsReadWriteContext &context, QStringList &missingTransforms SIP_OUT ); 255 : : 256 : : /** 257 : : * Writes the context's state to a DOM \a element. 258 : : * \see readXml() 259 : : */ 260 : : void writeXml( QDomElement &element, const QgsReadWriteContext &context ) const; 261 : : 262 : : 263 : : /** 264 : : * Reads the context's state from application settings. 265 : : * \see readSettings() 266 : : */ 267 : : void readSettings(); 268 : : 269 : : /** 270 : : * Write the context's state to application settings. 271 : : * \see writeSettings() 272 : : */ 273 : : void writeSettings(); 274 : : 275 : : 276 : : private: 277 : : 278 : : QExplicitlySharedDataPointer<QgsCoordinateTransformContextPrivate> d; 279 : : 280 : : }; 281 : : 282 : 1 : Q_DECLARE_METATYPE( QgsCoordinateTransformContext ) 283 : : 284 : : #endif // QGSCOORDINATETRANSFORMCONTEXT_H 285 : : 286 : : 287 : : 288 : :