Skip to content
Permalink
Browse files
Optimise storage/retrieval of projPJ objects
  • Loading branch information
nyalldawson committed May 16, 2017
1 parent e51737e commit 5201eb251e368fcff71edbb864b70456fecda3d7
Showing with 32 additions and 44 deletions.
  1. +14 −10 src/core/qgscoordinatetransform.cpp
  2. +16 −31 src/core/qgscoordinatetransform_p.cpp
  3. +2 −3 src/core/qgscoordinatetransform_p.h
@@ -474,8 +474,12 @@ void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *

// if the source/destination projection is lat/long, convert the points to radians
// prior to transforming
if ( ( pj_is_latlong( d->destProjection() ) && ( direction == ReverseTransform ) )
|| ( pj_is_latlong( d->sourceProjection() ) && ( direction == ForwardTransform ) ) )
QPair<projPJ, projPJ> projData = d->threadLocalProjData();
projPJ sourceProj = projData.first;
projPJ destProj = projData.second;

if ( ( pj_is_latlong( destProj ) && ( direction == ReverseTransform ) )
|| ( pj_is_latlong( sourceProj ) && ( direction == ForwardTransform ) ) )
{
for ( int i = 0; i < numPoints; ++i )
{
@@ -487,13 +491,13 @@ void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *
int projResult;
if ( direction == ReverseTransform )
{
projResult = pj_transform( d->destProjection(), d->sourceProjection(), numPoints, 0, x, y, z );
projResult = pj_transform( destProj, sourceProj, numPoints, 0, x, y, z );
}
else
{
Q_ASSERT( d->sourceProjection() );
Q_ASSERT( d->destProjection() );
projResult = pj_transform( d->sourceProjection(), d->destProjection(), numPoints, 0, x, y, z );
Q_ASSERT( sourceProj );
Q_ASSERT( destProj );
projResult = pj_transform( sourceProj, destProj, numPoints, 0, x, y, z );
}

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

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

char *srcdef = pj_get_def( d->sourceProjection(), 0 );
char *dstdef = pj_get_def( d->destProjection(), 0 );
char *srcdef = pj_get_def( sourceProj, 0 );
char *dstdef = pj_get_def( destProj, 0 );

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

// if the result is lat/long, convert the results from radians back
// to degrees
if ( ( pj_is_latlong( d->destProjection() ) && ( direction == ForwardTransform ) )
|| ( pj_is_latlong( d->sourceProjection() ) && ( direction == ReverseTransform ) ) )
if ( ( pj_is_latlong( destProj ) && ( direction == ForwardTransform ) )
|| ( pj_is_latlong( sourceProj ) && ( direction == ReverseTransform ) ) )
{
for ( int i = 0; i < numPoints; ++i )
{
@@ -135,14 +135,15 @@ bool QgsCoordinateTransformPrivate::initialize()
addNullGridShifts( mSourceProjString, mDestProjString );
}

initializeCurrentContext();
// create proj projections for current thread
QPair<projPJ, projPJ> res = threadLocalProjData();

#ifdef COORDINATE_TRANSFORM_VERBOSE
QgsDebugMsg( "From proj : " + mSourceCRS.toProj4() );
QgsDebugMsg( "To proj : " + mDestCRS.toProj4() );
#endif

if ( !destProjection() || !sourceProjection() )
if ( !res.first || !res.second )
{
mIsValid = false;
}
@@ -188,42 +189,26 @@ bool QgsCoordinateTransformPrivate::initialize()
return mIsValid;
}

void QgsCoordinateTransformPrivate::initializeCurrentContext()
{
mProjLock.lockForWrite();
mProjProjections.insert( reinterpret_cast< uintptr_t>( mProjContext.get() ), qMakePair( pj_init_plus_ctx( mProjContext.get(), mSourceProjString.toUtf8() ),
pj_init_plus_ctx( mProjContext.get(), mDestProjString.toUtf8() ) ) );
mProjLock.unlock();
}

projPJ QgsCoordinateTransformPrivate::sourceProjection()
QPair<projPJ, projPJ> QgsCoordinateTransformPrivate::threadLocalProjData()
{
mProjLock.lockForRead();
if ( mProjProjections.contains( reinterpret_cast< uintptr_t>( mProjContext.get() ) ) )
{
projPJ src = mProjProjections.value( reinterpret_cast< uintptr_t>( mProjContext.get() ) ).first;
mProjLock.unlock();
return src;
}
mProjLock.unlock();

initializeCurrentContext();
return sourceProjection();
}

projPJ QgsCoordinateTransformPrivate::destProjection()
{
mProjLock.lockForRead();
if ( mProjProjections.contains( reinterpret_cast< uintptr_t>( mProjContext.get() ) ) )
QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constFind( reinterpret_cast< uintptr_t>( mProjContext.get() ) );
if ( it != mProjProjections.constEnd() )
{
projPJ dest = mProjProjections.value( reinterpret_cast< uintptr_t>( mProjContext.get() ) ).second;
QPair<projPJ, projPJ> res = it.value();
mProjLock.unlock();
return dest;
return res;
}
mProjLock.unlock();

initializeCurrentContext();
return destProjection();
// proj projections don't exist yet, so we need to create
mProjLock.unlock();
mProjLock.lockForWrite();
QPair<projPJ, projPJ> res = qMakePair( pj_init_plus_ctx( mProjContext.get(), mSourceProjString.toUtf8() ),
pj_init_plus_ctx( mProjContext.get(), mDestProjString.toUtf8() ) );
mProjProjections.insert( reinterpret_cast< uintptr_t>( mProjContext.get() ), res );
mProjLock.unlock();
return res;
}

QString QgsCoordinateTransformPrivate::stripDatumTransform( const QString &proj4 ) const
@@ -67,7 +67,8 @@ class QgsCoordinateTransformPrivate : public QSharedData
~QgsCoordinateTransformPrivate();

bool initialize();
void initializeCurrentContext();

QPair< projPJ, projPJ > threadLocalProjData();

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

QString mSourceProjString;
QString mDestProjString;
projPJ sourceProjection();
projPJ destProjection();

int mSourceDatumTransform;
int mDestinationDatumTransform;

0 comments on commit 5201eb2

Please sign in to comment.