Skip to content

Commit 5201eb2

Browse files
committed
Optimise storage/retrieval of projPJ objects
1 parent e51737e commit 5201eb2

File tree

3 files changed

+32
-44
lines changed

3 files changed

+32
-44
lines changed

src/core/qgscoordinatetransform.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -474,8 +474,12 @@ void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *
474474

475475
// if the source/destination projection is lat/long, convert the points to radians
476476
// prior to transforming
477-
if ( ( pj_is_latlong( d->destProjection() ) && ( direction == ReverseTransform ) )
478-
|| ( pj_is_latlong( d->sourceProjection() ) && ( direction == ForwardTransform ) ) )
477+
QPair<projPJ, projPJ> projData = d->threadLocalProjData();
478+
projPJ sourceProj = projData.first;
479+
projPJ destProj = projData.second;
480+
481+
if ( ( pj_is_latlong( destProj ) && ( direction == ReverseTransform ) )
482+
|| ( pj_is_latlong( sourceProj ) && ( direction == ForwardTransform ) ) )
479483
{
480484
for ( int i = 0; i < numPoints; ++i )
481485
{
@@ -487,13 +491,13 @@ void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *
487491
int projResult;
488492
if ( direction == ReverseTransform )
489493
{
490-
projResult = pj_transform( d->destProjection(), d->sourceProjection(), numPoints, 0, x, y, z );
494+
projResult = pj_transform( destProj, sourceProj, numPoints, 0, x, y, z );
491495
}
492496
else
493497
{
494-
Q_ASSERT( d->sourceProjection() );
495-
Q_ASSERT( d->destProjection() );
496-
projResult = pj_transform( d->sourceProjection(), d->destProjection(), numPoints, 0, x, y, z );
498+
Q_ASSERT( sourceProj );
499+
Q_ASSERT( destProj );
500+
projResult = pj_transform( sourceProj, destProj, numPoints, 0, x, y, z );
497501
}
498502

499503
if ( projResult != 0 )
@@ -515,8 +519,8 @@ void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *
515519

516520
QString dir = ( direction == ForwardTransform ) ? QObject::tr( "forward transform" ) : QObject::tr( "inverse transform" );
517521

518-
char *srcdef = pj_get_def( d->sourceProjection(), 0 );
519-
char *dstdef = pj_get_def( d->destProjection(), 0 );
522+
char *srcdef = pj_get_def( sourceProj, 0 );
523+
char *dstdef = pj_get_def( destProj, 0 );
520524

521525
QString msg = QObject::tr( "%1 of\n"
522526
"%2"
@@ -538,8 +542,8 @@ void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *
538542

539543
// if the result is lat/long, convert the results from radians back
540544
// to degrees
541-
if ( ( pj_is_latlong( d->destProjection() ) && ( direction == ForwardTransform ) )
542-
|| ( pj_is_latlong( d->sourceProjection() ) && ( direction == ReverseTransform ) ) )
545+
if ( ( pj_is_latlong( destProj ) && ( direction == ForwardTransform ) )
546+
|| ( pj_is_latlong( sourceProj ) && ( direction == ReverseTransform ) ) )
543547
{
544548
for ( int i = 0; i < numPoints; ++i )
545549
{

src/core/qgscoordinatetransform_p.cpp

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,15 @@ bool QgsCoordinateTransformPrivate::initialize()
135135
addNullGridShifts( mSourceProjString, mDestProjString );
136136
}
137137

138-
initializeCurrentContext();
138+
// create proj projections for current thread
139+
QPair<projPJ, projPJ> res = threadLocalProjData();
139140

140141
#ifdef COORDINATE_TRANSFORM_VERBOSE
141142
QgsDebugMsg( "From proj : " + mSourceCRS.toProj4() );
142143
QgsDebugMsg( "To proj : " + mDestCRS.toProj4() );
143144
#endif
144145

145-
if ( !destProjection() || !sourceProjection() )
146+
if ( !res.first || !res.second )
146147
{
147148
mIsValid = false;
148149
}
@@ -188,42 +189,26 @@ bool QgsCoordinateTransformPrivate::initialize()
188189
return mIsValid;
189190
}
190191

191-
void QgsCoordinateTransformPrivate::initializeCurrentContext()
192-
{
193-
mProjLock.lockForWrite();
194-
mProjProjections.insert( reinterpret_cast< uintptr_t>( mProjContext.get() ), qMakePair( pj_init_plus_ctx( mProjContext.get(), mSourceProjString.toUtf8() ),
195-
pj_init_plus_ctx( mProjContext.get(), mDestProjString.toUtf8() ) ) );
196-
mProjLock.unlock();
197-
}
198-
199-
projPJ QgsCoordinateTransformPrivate::sourceProjection()
192+
QPair<projPJ, projPJ> QgsCoordinateTransformPrivate::threadLocalProjData()
200193
{
201194
mProjLock.lockForRead();
202-
if ( mProjProjections.contains( reinterpret_cast< uintptr_t>( mProjContext.get() ) ) )
203-
{
204-
projPJ src = mProjProjections.value( reinterpret_cast< uintptr_t>( mProjContext.get() ) ).first;
205-
mProjLock.unlock();
206-
return src;
207-
}
208-
mProjLock.unlock();
209195

210-
initializeCurrentContext();
211-
return sourceProjection();
212-
}
213-
214-
projPJ QgsCoordinateTransformPrivate::destProjection()
215-
{
216-
mProjLock.lockForRead();
217-
if ( mProjProjections.contains( reinterpret_cast< uintptr_t>( mProjContext.get() ) ) )
196+
QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constFind( reinterpret_cast< uintptr_t>( mProjContext.get() ) );
197+
if ( it != mProjProjections.constEnd() )
218198
{
219-
projPJ dest = mProjProjections.value( reinterpret_cast< uintptr_t>( mProjContext.get() ) ).second;
199+
QPair<projPJ, projPJ> res = it.value();
220200
mProjLock.unlock();
221-
return dest;
201+
return res;
222202
}
223-
mProjLock.unlock();
224203

225-
initializeCurrentContext();
226-
return destProjection();
204+
// proj projections don't exist yet, so we need to create
205+
mProjLock.unlock();
206+
mProjLock.lockForWrite();
207+
QPair<projPJ, projPJ> res = qMakePair( pj_init_plus_ctx( mProjContext.get(), mSourceProjString.toUtf8() ),
208+
pj_init_plus_ctx( mProjContext.get(), mDestProjString.toUtf8() ) );
209+
mProjProjections.insert( reinterpret_cast< uintptr_t>( mProjContext.get() ), res );
210+
mProjLock.unlock();
211+
return res;
227212
}
228213

229214
QString QgsCoordinateTransformPrivate::stripDatumTransform( const QString &proj4 ) const

src/core/qgscoordinatetransform_p.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ class QgsCoordinateTransformPrivate : public QSharedData
6767
~QgsCoordinateTransformPrivate();
6868

6969
bool initialize();
70-
void initializeCurrentContext();
70+
71+
QPair< projPJ, projPJ > threadLocalProjData();
7172

7273
//! Flag to indicate whether the transform is valid (ie has a valid
7374
//! source and destination crs)
@@ -87,8 +88,6 @@ class QgsCoordinateTransformPrivate : public QSharedData
8788

8889
QString mSourceProjString;
8990
QString mDestProjString;
90-
projPJ sourceProjection();
91-
projPJ destProjection();
9291

9392
int mSourceDatumTransform;
9493
int mDestinationDatumTransform;

0 commit comments

Comments
 (0)