Skip to content
Permalink
Browse files

Prepare for removal of QgsCoordinateTransformCache

  • Loading branch information
nyalldawson committed Nov 6, 2017
1 parent fd77270 commit 9984f39b5d3b16f3ad8f471e53322cf99a2f42f7
@@ -71,6 +71,18 @@ Default constructor, creates an invalid QgsCoordinateTransform.
No reference to ``project`` is stored or utilised outside of the constructor,
and it is used to retrieve the project's transform context only.

.. versionadded:: 3.0
%End

explicit QgsCoordinateTransform( const QgsCoordinateReferenceSystem &source,
const QgsCoordinateReferenceSystem &destination,
int sourceDatumTransform,
int destinationDatumTransform );
%Docstring
Constructs a QgsCoordinateTransform to transform from the ``source``
to ``destination`` coordinate reference system, with the specified
datum transforms.

.. versionadded:: 3.0
%End

@@ -282,6 +294,14 @@ Default constructor, creates an invalid QgsCoordinateTransform.
void initialize();
%Docstring
initialize is used to actually create the Transformer instance
%End

static void invalidateCache();
%Docstring
Clears the internal cache used to initialize QgsCoordinateTransform objects.
This should be called whenever the srs database has
been modified in order to ensure that outdated CRS transforms are not created.
.. versionadded:: 3.0
%End

};
@@ -18,7 +18,7 @@
#include "qgsgeometrycheck.h"
#include "qgsfeaturepool.h"

QgsGeometryCheckerContext::QgsGeometryCheckerContext( int _precision, const QString &_mapCrs, const QMap<QString, QgsFeaturePool *> &_featurePools )
QgsGeometryCheckerContext::QgsGeometryCheckerContext( int _precision, const QgsCoordinateReferenceSystem &_mapCrs, const QMap<QString, QgsFeaturePool *> &_featurePools )
: tolerance( std::pow( 10, -_precision ) )
, reducedTolerance( std::pow( 10, -_precision / 2 ) )
, mapCrs( _mapCrs )
@@ -35,10 +35,10 @@ class QgsFeaturePool;

struct ANALYSIS_EXPORT QgsGeometryCheckerContext
{
QgsGeometryCheckerContext( int _precision, const QString &_mapCrs, const QMap<QString, QgsFeaturePool *> &_featurePools );
QgsGeometryCheckerContext( int _precision, const QgsCoordinateReferenceSystem &_mapCrs, const QMap<QString, QgsFeaturePool *> &_featurePools );
const double tolerance;
const double reducedTolerance;
const QString mapCrs;
const QgsCoordinateReferenceSystem mapCrs;
const QMap<QString, QgsFeaturePool *> featurePools;
};

@@ -18,6 +18,7 @@
#include "qgsgeometrychecker.h"
#include "qgsgeometrycheck.h"
#include "qgsfeaturepool.h"
#include "qgsproject.h"

#include <QtConcurrentMap>
#include <QFutureWatcher>
@@ -144,7 +145,7 @@ bool QgsGeometryChecker::fixError( QgsGeometryCheckError *error, int method, boo
{
const QMap<QgsFeatureId, QList<QgsGeometryCheck::Change>> &layerChanges = changes[layerId];
QgsFeaturePool *featurePool = mContext->featurePools[layerId];
QgsCoordinateTransform t = QgsCoordinateTransformCache::instance()->transform( featurePool->getLayer()->crs().authid(), mContext->mapCrs );
QgsCoordinateTransform t( featurePool->getLayer()->crs(), mContext->mapCrs, QgsProject::instance() );
for ( QgsFeatureId id : layerChanges.keys() )
{
bool removed = false;
@@ -183,7 +184,7 @@ bool QgsGeometryChecker::fixError( QgsGeometryCheckError *error, int method, boo
for ( const QString &layerId : mContext->featurePools.keys() )
{
QgsFeaturePool *featurePool = mContext->featurePools[layerId];
QgsCoordinateTransform t = QgsCoordinateTransformCache::instance()->transform( mContext->mapCrs, featurePool->getLayer()->crs().authid() );
QgsCoordinateTransform t( mContext->mapCrs, featurePool->getLayer()->crs(), QgsProject::instance() );
recheckAreaFeatures[layerId] = featurePool->getIntersects( t.transform( recheckArea ) );
}

@@ -16,6 +16,7 @@
#include "qgscrscache.h"
#include "qgsgeometryfollowboundariescheck.h"
#include "qgsgeometryengine.h"
#include "qgsproject.h"
#include "../qgsgeometrysnapper.h"


@@ -49,7 +50,7 @@ void QgsGeometryFollowBoundariesCheck::collectErrors( QList<QgsGeometryCheckErro
const QgsAbstractGeometry *geom = layerFeature.geometry();

// The geometry to crs of the check layer
QgsCoordinateTransform crst = QgsCoordinateTransformCache::instance()->transform( layerFeature.layer().crs().authid(), mCheckLayer->crs().authid() );
QgsCoordinateTransform crst( layerFeature.layer().crs(), mCheckLayer->crs(), QgsProject::instance() );
QgsGeometry geomt( geom->clone() );
geomt.transform( crst );

@@ -174,7 +174,7 @@ bool QgsCustomProjectionDialog::deleteCrs( const QString &id )
sqlite3_close( myDatabase );

QgsCoordinateReferenceSystem::invalidateCache();
QgsCoordinateTransformCache::instance()->invalidateCrs( QStringLiteral( "USER:%1" ).arg( id ) );
QgsCoordinateTransform::invalidateCache();

return myResult == SQLITE_OK;
}
@@ -300,7 +300,7 @@ bool QgsCustomProjectionDialog::saveCrs( QgsCoordinateReferenceSystem myCRS, con
existingCRSnames[myId] = myName;

QgsCoordinateReferenceSystem::invalidateCache();
QgsCoordinateTransformCache::instance()->invalidateCrs( QStringLiteral( "USER:%1" ).arg( myId ) );
QgsCoordinateTransform::invalidateCache();

// If we have a projection acronym not in the user db previously, add it.
// This is a must, or else we can't select it from the vw_srs table.
@@ -815,7 +815,7 @@ QgsGeometry QgsAtlasComposition::currentGeometry( const QgsCoordinateReferenceSy
}

QgsGeometry transformed = mCurrentFeature.geometry();
transformed.transform( QgsCoordinateTransformCache::instance()->transform( mCoverageLayer->crs().authid(), crs.authid() ) );
transformed.transform( QgsCoordinateTransform( mCoverageLayer->crs(), crs, mComposition->project() ) );
mGeometryCache[crs.srsid()] = transformed;
return transformed;
}
@@ -41,6 +41,9 @@ extern "C"
// if defined shows all information about transform to stdout
// #define COORDINATE_TRANSFORM_VERBOSE

QReadWriteLock QgsCoordinateTransform::sCacheLock;
QMultiHash< QPair< QString, QString >, QgsCoordinateTransform > QgsCoordinateTransform::sTransforms;

QgsCoordinateTransform::QgsCoordinateTransform()
{
d = new QgsCoordinateTransformPrivate();
@@ -67,6 +70,14 @@ QgsCoordinateTransform::QgsCoordinateTransform( const QgsCoordinateReferenceSyst
#endif
}

QgsCoordinateTransform::QgsCoordinateTransform( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination, int sourceDatumTransform, int destinationDatumTransform )
{
d = new QgsCoordinateTransformPrivate( source, destination, sourceDatumTransform, destinationDatumTransform );
#ifdef QGISDEBUG
d->mHasContext = true; // not strictly true, but we don't need to worry if datums have been explicitly set
#endif
}

QgsCoordinateTransform::QgsCoordinateTransform( const QgsCoordinateTransform &o )
{
d = o.d;
@@ -792,3 +803,10 @@ void QgsCoordinateTransform::initialize()
d.detach();
d->initialize();
}

void QgsCoordinateTransform::invalidateCache()
{
sCacheLock.lockForWrite();
sTransforms.clear();
sCacheLock.unlock();
}
@@ -101,6 +101,18 @@ class CORE_EXPORT QgsCoordinateTransform
const QgsCoordinateReferenceSystem &destination,
const QgsProject *project );

/**
* Constructs a QgsCoordinateTransform to transform from the \a source
* to \a destination coordinate reference system, with the specified
* datum transforms.
*
* \since QGIS 3.0
*/
explicit QgsCoordinateTransform( const QgsCoordinateReferenceSystem &source,
const QgsCoordinateReferenceSystem &destination,
int sourceDatumTransform,
int destinationDatumTransform );

/**
* Copy constructor
*/
@@ -364,11 +376,24 @@ class CORE_EXPORT QgsCoordinateTransform
//!initialize is used to actually create the Transformer instance
void initialize();

/**
* Clears the internal cache used to initialize QgsCoordinateTransform objects.
* This should be called whenever the srs database has
* been modified in order to ensure that outdated CRS transforms are not created.
* \since QGIS 3.0
*/
static void invalidateCache();

private:

static void searchDatumTransform( const QString &sql, QList< int > &transforms );

mutable QExplicitlySharedDataPointer<QgsCoordinateTransformPrivate> d;

// cache
static QReadWriteLock sCacheLock;
static QMultiHash< QPair< QString, QString >, QgsCoordinateTransform > sTransforms; //same auth_id pairs might have different datum transformations

};

//! Output stream operator
@@ -58,6 +58,16 @@ QgsCoordinateTransformPrivate::QgsCoordinateTransformPrivate( const QgsCoordinat
initialize();
}

QgsCoordinateTransformPrivate::QgsCoordinateTransformPrivate( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination, int sourceDatumTransform, int destDatumTransform )
: mSourceCRS( source )
, mDestCRS( destination )
, mSourceDatumTransform( sourceDatumTransform )
, mDestinationDatumTransform( destDatumTransform )
{
setFinder();
initialize();
}

QgsCoordinateTransformPrivate::QgsCoordinateTransformPrivate( const QgsCoordinateTransformPrivate &other )
: QSharedData( other )
, mIsValid( other.mIsValid )
@@ -66,6 +66,11 @@ class QgsCoordinateTransformPrivate : public QSharedData
const QgsCoordinateReferenceSystem &destination,
const QgsCoordinateTransformContext &context );

QgsCoordinateTransformPrivate( const QgsCoordinateReferenceSystem &source,
const QgsCoordinateReferenceSystem &destination,
int sourceDatumTransform,
int destDatumTransform );

QgsCoordinateTransformPrivate( const QgsCoordinateTransformPrivate &other );

~QgsCoordinateTransformPrivate();
@@ -115,7 +115,7 @@ void QgsMapHitTest::runHitTestLayer( QgsVectorLayer *vl, SymbolSet &usedSymbols,
{
if ( mSettings.destinationCrs() != vl->crs() )
{
QgsCoordinateTransform ct = QgsCoordinateTransformCache::instance()->transform( mSettings.destinationCrs().authid(), vl->crs().authid() );
QgsCoordinateTransform ct( mSettings.destinationCrs(), vl->crs(), mSettings.transformContext() );
transformedPolygon.transform( ct );
}
}
@@ -754,7 +754,7 @@ QgsRasterBlock *QgsRasterProjector::block( int bandNo, QgsRectangle const &exte
return mInput->block( bandNo, extent, width, height, feedback );
}

QgsCoordinateTransform inverseCt = QgsCoordinateTransformCache::instance()->transform( mDestCRS.authid(), mSrcCRS.authid(), mDestDatumTransform, mSrcDatumTransform );
QgsCoordinateTransform inverseCt( mDestCRS, mSrcCRS, mDestDatumTransform, mSrcDatumTransform );

ProjectorData pd( extent, width, height, mInput, inverseCt, mPrecision );

@@ -852,7 +852,7 @@ bool QgsRasterProjector::destExtentSize( const QgsRectangle &srcExtent, int srcX
{
return false;
}
QgsCoordinateTransform ct = QgsCoordinateTransformCache::instance()->transform( mSrcCRS.authid(), mDestCRS.authid(), mSrcDatumTransform, mDestDatumTransform );
QgsCoordinateTransform ct( mSrcCRS, mDestCRS, mSrcDatumTransform, mDestDatumTransform );

return extentSize( ct, srcExtent, srcXSize, srcYSize, destExtent, destXSize, destYSize );
}
@@ -256,7 +256,7 @@ bool QgsGeometryCheckerResultTab::exportErrorsDo( const QString &file )
{
return false;
}
if ( !createEmptyDataSource( file, QStringLiteral( "ESRI Shapefile" ), "UTF-8", QgsWkbTypes::Point, attributes, mIface->mapCanvas()->mapSettings().destinationCrs() ) )
if ( !createEmptyDataSource( file, QStringLiteral( "ESRI Shapefile" ), "UTF-8", QgsWkbTypes::Point, attributes, QgsProject::instance()->crs() ) )
{
return false;
}
@@ -178,7 +178,7 @@ QList<QgsVectorLayer *> QgsGeometryCheckerSetupTab::getSelectedLayers()

void QgsGeometryCheckerSetupTab::validateInput()
{
QStringList layerCrs = QStringList() << mIface->mapCanvas()->mapSettings().destinationCrs().authid();
QStringList layerCrs = QStringList() << QgsProject::instance()->crs().authid();
QList<QgsVectorLayer *> layers = getSelectedLayers();
int nApplicable = 0;
int nPoint = 0;
@@ -431,7 +431,7 @@ void QgsGeometryCheckerSetupTab::runChecks()
for ( QgsVectorLayer *layer : processLayers )
{
double layerToMapUntis = mIface->mapCanvas()->mapSettings().layerToMapUnits( layer );
QgsCoordinateTransform layerToMapTransform = QgsCoordinateTransformCache::instance()->transform( layer->crs().authid(), mIface->mapCanvas()->mapSettings().destinationCrs().authid() );
QgsCoordinateTransform layerToMapTransform( layer->crs(), QgsProject::instance()->crs(), QgsProject::instance() );
featurePools.insert( layer->id(), new QgsFeaturePool( layer, layerToMapUntis, layerToMapTransform, selectedOnly ) );
}
// LineLayerIntersection check is enabled, make sure there is also a feature pool for that layer
@@ -440,11 +440,11 @@ void QgsGeometryCheckerSetupTab::runChecks()
QgsVectorLayer *layer = dynamic_cast<QgsVectorLayer *>( QgsProject::instance()->mapLayer( ui.comboLineLayerIntersection->currentData().toString() ) );
Q_ASSERT( layer );
double layerToMapUntis = mIface->mapCanvas()->mapSettings().layerToMapUnits( layer );
QgsCoordinateTransform layerToMapTransform = QgsCoordinateTransformCache::instance()->transform( layer->crs().authid(), mIface->mapCanvas()->mapSettings().destinationCrs().authid() );
QgsCoordinateTransform layerToMapTransform( layer->crs(), QgsProject::instance()->crs(), QgsProject::instance() );
featurePools.insert( layer->id(), new QgsFeaturePool( layer, layerToMapUntis, layerToMapTransform, selectedOnly ) );
}

QgsGeometryCheckerContext *context = new QgsGeometryCheckerContext( ui.spinBoxTolerance->value(), mIface->mapCanvas()->mapSettings().destinationCrs().authid(), featurePools );
QgsGeometryCheckerContext *context = new QgsGeometryCheckerContext( ui.spinBoxTolerance->value(), QgsProject::instance()->crs(), featurePools );

QList<QgsGeometryCheck *> checks;
for ( const QgsGeometryCheckFactory *factory : QgsGeometryCheckFactoryRegistry::getCheckFactories() )
@@ -39,6 +39,7 @@
#include "qgsgeometryselfcontactcheck.h"
#include "qgsgeometryselfintersectioncheck.h"
#include "qgsgeometrysliverpolygoncheck.h"
#include "qgsproject.h"

#include "qgsgeometrytypecheck.h"

@@ -55,9 +56,9 @@ class TestQgsGeometryChecks: public QObject
QgsGeometryCheck::ChangeType type;
QgsVertexId vidx;
};
double layerToMapUnits( const QgsMapLayer *layer, const QString &mapCrs ) const;
QgsFeaturePool *createFeaturePool( QgsVectorLayer *layer, const QString &mapCrs, bool selectedOnly = false ) const;
QgsGeometryCheckerContext *createTestContext( QTemporaryDir &tempDir, QMap<QString, QString> &layers, const QString &mapCrs = "EPSG:4326", double prec = 8 ) const;
double layerToMapUnits( const QgsMapLayer *layer, const QgsCoordinateReferenceSystem &mapCrs ) const;
QgsFeaturePool *createFeaturePool( QgsVectorLayer *layer, const QgsCoordinateReferenceSystem &mapCrs, bool selectedOnly = false ) const;
QgsGeometryCheckerContext *createTestContext( QTemporaryDir &tempDir, QMap<QString, QString> &layers, const QgsCoordinateReferenceSystem &mapCrs = QgsCoordinateReferenceSystem( "EPSG:4326" ), double prec = 8 ) const;
void cleanupTestContext( QgsGeometryCheckerContext *ctx ) const;
void listErrors( const QList<QgsGeometryCheckError *> &checkErrors, const QStringList &messages ) const;
QList<QgsGeometryCheckError *> searchCheckErrors( const QList<QgsGeometryCheckError *> &checkErrors, const QString &layerId, const QgsFeatureId &featureId = -1, const QgsPointXY &pos = QgsPointXY(), const QgsVertexId &vid = QgsVertexId(), const QVariant &value = QVariant(), double tol = 1E-4 ) const;
@@ -958,9 +959,9 @@ void TestQgsGeometryChecks::testSliverPolygonCheck()

///////////////////////////////////////////////////////////////////////////////

double TestQgsGeometryChecks::layerToMapUnits( const QgsMapLayer *layer, const QString &mapCrs ) const
double TestQgsGeometryChecks::layerToMapUnits( const QgsMapLayer *layer, const QgsCoordinateReferenceSystem &mapCrs ) const
{
QgsCoordinateTransform crst = QgsCoordinateTransformCache::instance()->transform( layer->crs().authid(), mapCrs );
QgsCoordinateTransform crst = QgsCoordinateTransform( layer->crs(), mapCrs, QgsProject::instance() );
QgsRectangle extent = layer->extent();
QgsPointXY l1( extent.xMinimum(), extent.yMinimum() );
QgsPointXY l2( extent.xMaximum(), extent.yMaximum() );
@@ -971,14 +972,14 @@ double TestQgsGeometryChecks::layerToMapUnits( const QgsMapLayer *layer, const Q
return distMapUnits / distLayerUnits;
}

QgsFeaturePool *TestQgsGeometryChecks::createFeaturePool( QgsVectorLayer *layer, const QString &mapCrs, bool selectedOnly ) const
QgsFeaturePool *TestQgsGeometryChecks::createFeaturePool( QgsVectorLayer *layer, const QgsCoordinateReferenceSystem &mapCrs, bool selectedOnly ) const
{
double layerToMapUntis = layerToMapUnits( layer, mapCrs );
QgsCoordinateTransform layerToMapTransform = QgsCoordinateTransformCache::instance()->transform( layer->crs().authid(), mapCrs );
QgsCoordinateTransform layerToMapTransform = QgsCoordinateTransform( layer->crs(), mapCrs, QgsProject::instance() );
return new QgsFeaturePool( layer, layerToMapUntis, layerToMapTransform, selectedOnly );
}

QgsGeometryCheckerContext *TestQgsGeometryChecks::createTestContext( QTemporaryDir &tempDir, QMap<QString, QString> &layers, const QString &mapCrs, double prec ) const
QgsGeometryCheckerContext *TestQgsGeometryChecks::createTestContext( QTemporaryDir &tempDir, QMap<QString, QString> &layers, const QgsCoordinateReferenceSystem &mapCrs, double prec ) const
{
QDir testDataDir( QDir( TEST_DATA_DIR ).absoluteFilePath( "geometry_checker" ) );
QDir tmpDir( tempDir.path() );

0 comments on commit 9984f39

Please sign in to comment.
You can’t perform that action at this time.