25 #ifndef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H 26 #define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H 32 #include <QStringList> 36 #ifdef USE_THREAD_LOCAL 37 thread_local QgsProjContextStore QgsCoordinateTransformPrivate::mProjContext;
39 QThreadStorage< QgsProjContextStore * > QgsCoordinateTransformPrivate::mProjContext;
42 QgsProjContextStore::QgsProjContextStore()
44 context = pj_ctx_alloc();
47 QgsProjContextStore::~QgsProjContextStore()
49 pj_ctx_free( context );
52 QgsCoordinateTransformPrivate::QgsCoordinateTransformPrivate()
60 : mSourceCRS( source )
61 , mDestCRS( destination )
64 calculateTransforms( context );
68 : mSourceCRS( source )
69 , mDestCRS( destination )
70 , mSourceDatumTransform( sourceDatumTransform )
71 , mDestinationDatumTransform( destDatumTransform )
76 QgsCoordinateTransformPrivate::QgsCoordinateTransformPrivate(
const QgsCoordinateTransformPrivate &other )
77 : QSharedData( other )
78 , mIsValid( other.mIsValid )
79 , mShortCircuit( other.mShortCircuit )
80 , mSourceCRS( other.mSourceCRS )
81 , mDestCRS( other.mDestCRS )
82 , mSourceDatumTransform( other.mSourceDatumTransform )
83 , mDestinationDatumTransform( other.mDestinationDatumTransform )
89 QgsCoordinateTransformPrivate::~QgsCoordinateTransformPrivate()
95 bool QgsCoordinateTransformPrivate::checkValidity()
97 if ( !mSourceCRS.isValid() || !mDestCRS.isValid() )
105 void QgsCoordinateTransformPrivate::invalidate()
107 mShortCircuit =
true;
111 bool QgsCoordinateTransformPrivate::initialize()
114 if ( !mSourceCRS.isValid() )
122 if ( !mDestCRS.isValid() )
126 mDestCRS = mSourceCRS;
133 int sourceDatumTransform = mSourceDatumTransform;
134 int destDatumTransform = mDestinationDatumTransform;
135 bool useDefaultDatumTransform = ( sourceDatumTransform == - 1 && destDatumTransform == -1 );
140 mSourceProjString = mSourceCRS.toProj4();
141 if ( !useDefaultDatumTransform )
143 mSourceProjString = stripDatumTransform( mSourceProjString );
145 if ( sourceDatumTransform != -1 )
150 mDestProjString = mDestCRS.toProj4();
151 if ( !useDefaultDatumTransform )
153 mDestProjString = stripDatumTransform( mDestProjString );
155 if ( destDatumTransform != -1 )
160 if ( !useDefaultDatumTransform )
162 addNullGridShifts( mSourceProjString, mDestProjString, sourceDatumTransform, destDatumTransform );
166 QPair<projPJ, projPJ> res = threadLocalProjData();
168 #ifdef COORDINATE_TRANSFORM_VERBOSE 169 QgsDebugMsg(
"From proj : " + mSourceCRS.toProj4() );
173 if ( !res.first || !res.second )
178 #ifdef COORDINATE_TRANSFORM_VERBOSE 181 QgsDebugMsg( QStringLiteral(
"------------------------------------------------------------" ) );
182 QgsDebugMsg( QStringLiteral(
"The OGR Coordinate transformation for this layer was set to" ) );
183 QgsLogger::debug<QgsCoordinateReferenceSystem>(
"Input", mSourceCRS, __FILE__, __FUNCTION__, __LINE__ );
184 QgsLogger::debug<QgsCoordinateReferenceSystem>(
"Output", mDestCRS, __FILE__, __FUNCTION__, __LINE__ );
185 QgsDebugMsg( QStringLiteral(
"------------------------------------------------------------" ) );
189 QgsDebugMsg( QStringLiteral(
"------------------------------------------------------------" ) );
190 QgsDebugMsg( QStringLiteral(
"The OGR Coordinate transformation FAILED TO INITIALIZE!" ) );
191 QgsDebugMsg( QStringLiteral(
"------------------------------------------------------------" ) );
196 QgsDebugMsg( QStringLiteral(
"Coordinate transformation failed to initialize!" ) );
203 if ( mSourceCRS == mDestCRS )
207 mShortCircuit =
true;
208 QgsDebugMsgLevel( QStringLiteral(
"Source/Dest CRS equal, shortcircuit is set." ), 3 );
213 mShortCircuit =
false;
214 QgsDebugMsgLevel( QStringLiteral(
"Source/Dest CRS not equal, shortcircuit is not set." ), 3 );
227 QPair<projPJ, projPJ> QgsCoordinateTransformPrivate::threadLocalProjData()
231 #ifdef USE_THREAD_LOCAL 232 QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constFind( reinterpret_cast< uintptr_t>( mProjContext.get() ) );
234 projCtx pContext =
nullptr;
235 if ( mProjContext.hasLocalData() )
237 pContext = mProjContext.localData()->get();
241 mProjContext.setLocalData(
new QgsProjContextStore() );
242 pContext = mProjContext.localData()->get();
244 QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constFind( reinterpret_cast< uintptr_t>( pContext ) );
247 if ( it != mProjProjections.constEnd() )
249 QPair<projPJ, projPJ> res = it.value();
256 #ifdef USE_THREAD_LOCAL 257 QPair<projPJ, projPJ> res = qMakePair( pj_init_plus_ctx( mProjContext.get(), mSourceProjString.toUtf8() ),
258 pj_init_plus_ctx( mProjContext.get(), mDestProjString.toUtf8() ) );
259 mProjProjections.insert( reinterpret_cast< uintptr_t>( mProjContext.get() ), res );
261 QPair<projPJ, projPJ> res = qMakePair( pj_init_plus_ctx( pContext, mSourceProjString.toUtf8() ),
262 pj_init_plus_ctx( pContext, mDestProjString.toUtf8() ) );
263 mProjProjections.insert( reinterpret_cast< uintptr_t>( pContext ), res );
268 QString QgsCoordinateTransformPrivate::stripDatumTransform(
const QString &proj4 )
const 270 QStringList parameterSplit = proj4.split(
'+', QString::SkipEmptyParts );
271 QString currentParameter;
272 QString newProjString;
274 for (
int i = 0; i < parameterSplit.size(); ++i )
276 currentParameter = parameterSplit.at( i );
277 if ( !currentParameter.startsWith( QLatin1String(
"towgs84" ), Qt::CaseInsensitive )
278 && !currentParameter.startsWith( QLatin1String(
"nadgrids" ), Qt::CaseInsensitive ) )
280 newProjString.append(
'+' );
281 newProjString.append( currentParameter );
282 newProjString.append(
' ' );
285 return newProjString;
288 void QgsCoordinateTransformPrivate::addNullGridShifts( QString &srcProjString, QString &destProjString,
289 int sourceDatumTransform,
int destinationDatumTransform )
const 292 if ( destinationDatumTransform == -1 && srcProjString.contains( QLatin1String(
"+nadgrids" ) ) )
294 destProjString += QLatin1String(
" +nadgrids=@null" );
297 if ( sourceDatumTransform == -1 && destProjString.contains( QLatin1String(
"+nadgrids" ) ) )
299 srcProjString += QLatin1String(
" +nadgrids=@null" );
305 if ( mSourceCRS.authid().compare( QLatin1String(
"EPSG:3857" ), Qt::CaseInsensitive ) == 0 && sourceDatumTransform == -1 )
307 srcProjString += QLatin1String(
" +nadgrids=@null" );
309 if ( mDestCRS.authid().compare( QLatin1String(
"EPSG:3857" ), Qt::CaseInsensitive ) == 0 && destinationDatumTransform == -1 )
311 destProjString += QLatin1String(
" +nadgrids=@null" );
315 void QgsCoordinateTransformPrivate::setFinder()
331 void QgsCoordinateTransformPrivate::freeProj()
334 QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constBegin();
335 for ( ; it != mProjProjections.constEnd(); ++it )
337 pj_free( it.value().first );
338 pj_free( it.value().second );
340 mProjProjections.clear();
The QgsReadWriteLocker class is a convenience class that simplifies locking and unlocking QReadWriteL...
#define QgsDebugMsgLevel(str, level)
Contains information about the context in which a coordinate transform is executed.
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...
This class represents a coordinate reference system (CRS).
void changeMode(Mode mode)
Change the mode of the lock to mode.