1 /*************************************************************************** 2 qgscoordinatetransform_p.h 3 -------------------------- 4 begin : July 2016 5 copyright : (C) 2016 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 #ifndef QGSCOORDINATETRANSFORMPRIVATE_H 18 #define QGSCOORDINATETRANSFORMPRIVATE_H 19 20 #define SIP_NO_FILE 21 #include "qgsconfig.h" 22 23 /// @cond PRIVATE 24 25 // 26 // W A R N I N G 27 // ------------- 28 // 29 // This file is not part of the QGIS API. It exists purely as an 30 // implementation detail. This header file may change from version to 31 // version without notice, or even be removed. 32 // 33 34 #include <QSharedData> 35 36 struct PJconsts; 37 typedef struct PJconsts PJ; 38 typedef PJ *ProjData; 39 40 #include "qgscoordinatereferencesystem.h" 41 #include "qgscoordinatetransformcontext.h" 42 43 class QgsCoordinateTransformPrivate : public QSharedData 44 { 45 46 public: 47 48 explicit QgsCoordinateTransformPrivate(); 49 50 QgsCoordinateTransformPrivate( const QgsCoordinateReferenceSystem &source, 51 const QgsCoordinateReferenceSystem &destination, 52 const QgsCoordinateTransformContext &context ); 53 54 QgsCoordinateTransformPrivate( const QgsCoordinateReferenceSystem &source, 55 const QgsCoordinateReferenceSystem &destination, 56 int sourceDatumTransform, 57 int destDatumTransform ); 58 59 QgsCoordinateTransformPrivate( const QgsCoordinateTransformPrivate &other ); 60 61 ~QgsCoordinateTransformPrivate(); 62 63 bool checkValidity(); 64 65 void invalidate(); 66 67 bool initialize(); 68 69 void calculateTransforms( const QgsCoordinateTransformContext &context ); 70 71 ProjData threadLocalProjData(); 72 73 int mAvailableOpCount = -1; 74 ProjData threadLocalFallbackProjData(); 75 76 // Only meant to be called by QgsCoordinateTransform::removeFromCacheObjectsBelongingToCurrentThread() 77 bool removeObjectsBelongingToCurrentThread( void *pj_context ); 78 79 /** 80 * Flag to indicate whether the transform is valid (ie has a valid 81 * source and destination crs) 82 */ 83 bool mIsValid = false; 84 85 /** 86 * Flag to indicate that the source and destination coordinate systems are 87 * equal and not transformation needs to be done 88 */ 89 bool mShortCircuit = false; 90 91 //! QgsCoordinateReferenceSystem of the source (layer) coordinate system 92 QgsCoordinateReferenceSystem mSourceCRS; 93 94 //! QgsCoordinateReferenceSystem of the destination (map canvas) coordinate system 95 QgsCoordinateReferenceSystem mDestCRS; 96 97 Q_DECL_DEPRECATED QString mSourceProjString; 98 Q_DECL_DEPRECATED QString mDestProjString; 99 100 Q_DECL_DEPRECATED int mSourceDatumTransform = -1; 101 Q_DECL_DEPRECATED int mDestinationDatumTransform = -1; 102 QString mProjCoordinateOperation; 103 bool mShouldReverseCoordinateOperation = false; 104 bool mAllowFallbackTransforms = true; 105 106 bool mSourceIsDynamic = false; 107 bool mDestIsDynamic = false; 108 double mSourceCoordinateEpoch = std::numeric_limits< double >::quiet_NaN(); 109 double mDestCoordinateEpoch = std::numeric_limits< double >::quiet_NaN(); 110 double mDefaultTime = std::numeric_limits< double >::quiet_NaN(); 111 112 //! True if the proj transform corresponds to the reverse direction, and must be flipped when transforming... 113 bool mIsReversed = false; 114 115 QReadWriteLock mProjLock; 116 QMap < uintptr_t, ProjData > mProjProjections; 117 QMap < uintptr_t, ProjData > mProjFallbackProjections; 118 119 /** 120 * Sets a custom handler to use when a coordinate transform is created between \a sourceCrs and 121 * \a destinationCrs, yet the coordinate operation requires a transform \a grid which is not present 122 * on the system. 123 * 124 * \since QGIS 3.8 125 */ 126 static void setCustomMissingRequiredGridHandler( const std::function< void( const QgsCoordinateReferenceSystem &sourceCrs, 127 const QgsCoordinateReferenceSystem &destinationCrs, 128 const QgsDatumTransform::GridDetails &grid )> &handler ); 129 130 /** 131 * Sets a custom handler to use when a coordinate transform is created between \a sourceCrs and 132 * \a destinationCrs, yet a preferred (more accurate?) operation is available which could not 133 * be created on the system (e.g. due to missing transform grids). 134 * 135 * \a preferredOperation gives the details of the preferred coordinate operation, and 136 * \a availableOperation gives the details of the actual operation to be used during the 137 * transform. 138 * 139 * \since QGIS 3.8 140 */ 141 static void setCustomMissingPreferredGridHandler( const std::function< void( const QgsCoordinateReferenceSystem &sourceCrs, 142 const QgsCoordinateReferenceSystem &destinationCrs, 143 const QgsDatumTransform::TransformDetails &preferredOperation, 144 const QgsDatumTransform::TransformDetails &availableOperation )> &handler ); 145 146 /** 147 * Sets a custom handler to use when a coordinate transform was required between \a sourceCrs and 148 * \a destinationCrs, yet the coordinate operation could not be created. The \a error argument 149 * specifies the error message obtained. 150 * 151 * \since QGIS 3.8 152 */ 153 static void setCustomCoordinateOperationCreationErrorHandler( const std::function< void( const QgsCoordinateReferenceSystem &sourceCrs, 154 const QgsCoordinateReferenceSystem &destinationCrs, 155 const QString &error )> &handler ); 156 157 /** 158 * Sets a custom handler to use when a coordinate operation was specified for use between \a sourceCrs and 159 * \a destinationCrs by the transform context, yet the coordinate operation could not be created. The \a desiredOperation argument 160 * specifies the desired transform details as specified by the context. 161 * 162 * \since QGIS 3.8 163 */ 164 static void setCustomMissingGridUsedByContextHandler( const std::function< void( const QgsCoordinateReferenceSystem &sourceCrs, 165 const QgsCoordinateReferenceSystem &destinationCrs, 166 const QgsDatumTransform::TransformDetails &desiredOperation )> &handler ); 167 168 /** 169 * Sets a custom \a handler to use when the desired coordinate operation for use between \a sourceCrs and 170 * \a destinationCrs is a dynamic CRS to dynamic CRS transform, not currently supported by PROJ. 171 * 172 * \since QGIS 3.20 173 */ 174 static void setDynamicCrsToDynamicCrsWarningHandler( const std::function< void( const QgsCoordinateReferenceSystem &sourceCrs, 175 const QgsCoordinateReferenceSystem &destinationCrs )> &handler ); 176 177 private: 178 179 void freeProj(); 180 181 static std::function< void( const QgsCoordinateReferenceSystem &sourceCrs, 182 const QgsCoordinateReferenceSystem &destinationCrs, 183 const QgsDatumTransform::GridDetails &grid )> sMissingRequiredGridHandler; 184 185 static std::function< void( const QgsCoordinateReferenceSystem &sourceCrs, 186 const QgsCoordinateReferenceSystem &destinationCrs, 187 const QgsDatumTransform::TransformDetails &preferredOperation, 188 const QgsDatumTransform::TransformDetails &availableOperation )> sMissingPreferredGridHandler; 189 190 static std::function< void( const QgsCoordinateReferenceSystem &sourceCrs, 191 const QgsCoordinateReferenceSystem &destinationCrs, 192 const QString &error )> sCoordinateOperationCreationErrorHandler; 193 194 static std::function< void( const QgsCoordinateReferenceSystem &sourceCrs, 195 const QgsCoordinateReferenceSystem &destinationCrs, 196 const QgsDatumTransform::TransformDetails &desiredOperation )> sMissingGridUsedByContextHandler; 197 198 static std::function< void( const QgsCoordinateReferenceSystem &sourceCrs, 199 const QgsCoordinateReferenceSystem &destinationCrs )> sDynamicCrsToDynamicCrsWarningHandler; 200 201 QgsCoordinateTransformPrivate &operator= ( const QgsCoordinateTransformPrivate & ) = delete; 202 }; 203 204 /// @endcond 205 206 #endif // QGSCOORDINATETRANSFORMPRIVATE_H 207