24 #ifndef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H 25 #define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H 31 #include <QStringList> 35 #ifdef USE_THREAD_LOCAL 36 thread_local QgsProjContextStore QgsCoordinateTransformPrivate::mProjContext;
38 QThreadStorage< QgsProjContextStore * > QgsCoordinateTransformPrivate::mProjContext;
41 QgsProjContextStore::QgsProjContextStore()
43 context = pj_ctx_alloc();
46 QgsProjContextStore::~QgsProjContextStore()
48 pj_ctx_free( context );
51 QgsCoordinateTransformPrivate::QgsCoordinateTransformPrivate()
59 : mSourceCRS( source )
60 , mDestCRS( destination )
63 calculateTransforms( context );
67 : mSourceCRS( source )
68 , mDestCRS( destination )
69 , mSourceDatumTransform( sourceDatumTransform )
70 , mDestinationDatumTransform( destDatumTransform )
75 QgsCoordinateTransformPrivate::QgsCoordinateTransformPrivate(
const QgsCoordinateTransformPrivate &other )
76 : QSharedData( other )
77 , mIsValid( other.mIsValid )
78 , mShortCircuit( other.mShortCircuit )
79 , mSourceCRS( other.mSourceCRS )
80 , mDestCRS( other.mDestCRS )
81 , mSourceDatumTransform( other.mSourceDatumTransform )
82 , mDestinationDatumTransform( other.mDestinationDatumTransform )
88 QgsCoordinateTransformPrivate::~QgsCoordinateTransformPrivate()
94 bool QgsCoordinateTransformPrivate::checkValidity()
96 if ( !mSourceCRS.isValid() || !mDestCRS.isValid() )
104 void QgsCoordinateTransformPrivate::invalidate()
106 mShortCircuit =
true;
110 bool QgsCoordinateTransformPrivate::initialize()
113 if ( !mSourceCRS.isValid() )
121 if ( !mDestCRS.isValid() )
125 mDestCRS = mSourceCRS;
132 int sourceDatumTransform = mSourceDatumTransform;
133 int destDatumTransform = mDestinationDatumTransform;
134 bool useDefaultDatumTransform = ( sourceDatumTransform == - 1 && destDatumTransform == -1 );
139 mSourceProjString = mSourceCRS.toProj4();
140 if ( !useDefaultDatumTransform )
142 mSourceProjString = stripDatumTransform( mSourceProjString );
144 if ( sourceDatumTransform != -1 )
149 mDestProjString = mDestCRS.toProj4();
150 if ( !useDefaultDatumTransform )
152 mDestProjString = stripDatumTransform( mDestProjString );
154 if ( destDatumTransform != -1 )
159 if ( !useDefaultDatumTransform )
161 addNullGridShifts( mSourceProjString, mDestProjString, sourceDatumTransform, destDatumTransform );
165 QPair<projPJ, projPJ> res = threadLocalProjData();
167 #ifdef COORDINATE_TRANSFORM_VERBOSE 168 QgsDebugMsg(
"From proj : " + mSourceCRS.toProj4() );
172 if ( !res.first || !res.second )
177 #ifdef COORDINATE_TRANSFORM_VERBOSE 180 QgsDebugMsg( QStringLiteral(
"------------------------------------------------------------" ) );
181 QgsDebugMsg( QStringLiteral(
"The OGR Coordinate transformation for this layer was set to" ) );
182 QgsLogger::debug<QgsCoordinateReferenceSystem>(
"Input", mSourceCRS, __FILE__, __FUNCTION__, __LINE__ );
183 QgsLogger::debug<QgsCoordinateReferenceSystem>(
"Output", mDestCRS, __FILE__, __FUNCTION__, __LINE__ );
184 QgsDebugMsg( QStringLiteral(
"------------------------------------------------------------" ) );
188 QgsDebugMsg( QStringLiteral(
"------------------------------------------------------------" ) );
189 QgsDebugMsg( QStringLiteral(
"The OGR Coordinate transformation FAILED TO INITIALIZE!" ) );
190 QgsDebugMsg( QStringLiteral(
"------------------------------------------------------------" ) );
195 QgsDebugMsg( QStringLiteral(
"Coordinate transformation failed to initialize!" ) );
202 if ( mSourceCRS == mDestCRS )
206 mShortCircuit =
true;
207 QgsDebugMsgLevel( QStringLiteral(
"Source/Dest CRS equal, shortcircuit is set." ), 3 );
212 mShortCircuit =
false;
213 QgsDebugMsgLevel( QStringLiteral(
"Source/Dest CRS not equal, shortcircuit is not set." ), 3 );
226 QPair<projPJ, projPJ> QgsCoordinateTransformPrivate::threadLocalProjData()
228 mProjLock.lockForRead();
230 #ifdef USE_THREAD_LOCAL 231 QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constFind( reinterpret_cast< uintptr_t>( mProjContext.get() ) );
233 projCtx pContext =
nullptr;
234 if ( mProjContext.hasLocalData() )
236 pContext = mProjContext.localData()->get();
240 mProjContext.setLocalData(
new QgsProjContextStore() );
241 pContext = mProjContext.localData()->get();
243 QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constFind( reinterpret_cast< uintptr_t>( pContext ) );
246 if ( it != mProjProjections.constEnd() )
248 QPair<projPJ, projPJ> res = it.value();
255 mProjLock.lockForWrite();
257 #ifdef USE_THREAD_LOCAL 258 QPair<projPJ, projPJ> res = qMakePair( pj_init_plus_ctx( mProjContext.get(), mSourceProjString.toUtf8() ),
259 pj_init_plus_ctx( mProjContext.get(), mDestProjString.toUtf8() ) );
260 mProjProjections.insert( reinterpret_cast< uintptr_t>( mProjContext.get() ), res );
262 QPair<projPJ, projPJ> res = qMakePair( pj_init_plus_ctx( pContext, mSourceProjString.toUtf8() ),
263 pj_init_plus_ctx( pContext, mDestProjString.toUtf8() ) );
264 mProjProjections.insert( reinterpret_cast< uintptr_t>( pContext ), res );
270 QString QgsCoordinateTransformPrivate::stripDatumTransform(
const QString &proj4 )
const 272 QStringList parameterSplit = proj4.split(
'+', QString::SkipEmptyParts );
273 QString currentParameter;
274 QString newProjString;
276 for (
int i = 0; i < parameterSplit.size(); ++i )
278 currentParameter = parameterSplit.at( i );
279 if ( !currentParameter.startsWith( QLatin1String(
"towgs84" ), Qt::CaseInsensitive )
280 && !currentParameter.startsWith( QLatin1String(
"nadgrids" ), Qt::CaseInsensitive ) )
282 newProjString.append(
'+' );
283 newProjString.append( currentParameter );
284 newProjString.append(
' ' );
287 return newProjString;
290 void QgsCoordinateTransformPrivate::addNullGridShifts( QString &srcProjString, QString &destProjString,
291 int sourceDatumTransform,
int destinationDatumTransform )
const 294 if ( destinationDatumTransform == -1 && srcProjString.contains( QLatin1String(
"+nadgrids" ) ) )
296 destProjString += QLatin1String(
" +nadgrids=@null" );
299 if ( sourceDatumTransform == -1 && destProjString.contains( QLatin1String(
"+nadgrids" ) ) )
301 srcProjString += QLatin1String(
" +nadgrids=@null" );
307 if ( mSourceCRS.authid().compare( QLatin1String(
"EPSG:3857" ), Qt::CaseInsensitive ) == 0 && sourceDatumTransform == -1 )
309 srcProjString += QLatin1String(
" +nadgrids=@null" );
311 if ( mDestCRS.authid().compare( QLatin1String(
"EPSG:3857" ), Qt::CaseInsensitive ) == 0 && destinationDatumTransform == -1 )
313 destProjString += QLatin1String(
" +nadgrids=@null" );
317 void QgsCoordinateTransformPrivate::setFinder()
333 void QgsCoordinateTransformPrivate::freeProj()
335 mProjLock.lockForWrite();
336 if ( !mProjProjections.isEmpty() )
338 projCtx tmpContext = pj_ctx_alloc();
339 QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constBegin();
340 for ( ; it != mProjProjections.constEnd(); ++it )
342 pj_set_ctx( it.value().first, tmpContext );
343 pj_free( it.value().first );
344 pj_set_ctx( it.value().second, tmpContext );
345 pj_free( it.value().second );
347 pj_ctx_free( tmpContext );
348 mProjProjections.clear();
#define QgsDebugMsgLevel(str, level)
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...
Contains information about the context in which a coordinate transform is executed.
This class represents a coordinate reference system (CRS).