Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add mechanisms to set handlers for coordinate transform creation erro…
…rs and warnings
  • Loading branch information
nyalldawson committed Jun 3, 2019
1 parent d754a09 commit f758bb7
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 0 deletions.
1 change: 1 addition & 0 deletions python/core/auto_generated/qgscoordinatetransform.sip.in
Expand Up @@ -412,6 +412,7 @@ sourceUnits * scaleFactor = destinationUnits
.. versionadded:: 3.4
%End


};


Expand Down
15 changes: 15 additions & 0 deletions src/core/qgscoordinatetransform.cpp
Expand Up @@ -964,3 +964,18 @@ double QgsCoordinateTransform::scaleFactor( const QgsRectangle &ReferenceExtent
double distDestUnits = std::sqrt( dest1.sqrDist( dest2 ) );
return distDestUnits / distSourceUnits;
}

void QgsCoordinateTransform::setCustomMissingRequiredGridHandler( const std::function<void ( const QgsCoordinateReferenceSystem &, const QgsCoordinateReferenceSystem &, const QgsDatumTransform::GridDetails & )> &handler )
{
QgsCoordinateTransformPrivate::setCustomMissingRequiredGridHandler( handler );
}

void QgsCoordinateTransform::setCustomMissingPreferredGridHandler( const std::function<void ( const QgsCoordinateReferenceSystem &, const QgsCoordinateReferenceSystem &, const QgsDatumTransform::TransformDetails &, const QgsDatumTransform::TransformDetails & )> &handler )
{
QgsCoordinateTransformPrivate::setCustomMissingPreferredGridHandler( handler );
}

void QgsCoordinateTransform::setCustomCoordinateOperationCreationErrorHandler( const std::function<void ( const QgsCoordinateReferenceSystem &, const QgsCoordinateReferenceSystem &, const QString & )> &handler )
{
QgsCoordinateTransformPrivate::setCustomCoordinateOperationCreationErrorHandler( handler );
}
54 changes: 54 additions & 0 deletions src/core/qgscoordinatetransform.h
Expand Up @@ -438,6 +438,60 @@ class CORE_EXPORT QgsCoordinateTransform
*/
double scaleFactor( const QgsRectangle &referenceExtent ) const;

#ifndef SIP_RUN

/**
* Sets a custom handler to use when a coordinate transform is created between \a sourceCrs and
* \a destinationCrs, yet the coordinate operation requires a transform \a grid which is not present
* on the system.
*
* \see setCustomMissingPreferredGridHandler()
* \see setCustomCoordinateOperationCreationErrorHandler()
*
* \since QGIS 3.8
* \note Not available in Python bindings
*/
static void setCustomMissingRequiredGridHandler( const std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::GridDetails &grid )> &handler );

/**
* Sets a custom handler to use when a coordinate transform is created between \a sourceCrs and
* \a destinationCrs, yet a preferred (more accurate?) operation is available which could not
* be created on the system (e.g. due to missing transform grids).
*
* \a preferredOperation gives the details of the preferred coordinate operation, and
* \a availableOperation gives the details of the actual operation to be used during the
* transform.
*
* \see setCustomMissingRequiredGridHandler()
* \see setCustomCoordinateOperationCreationErrorHandler()
*
* \since QGIS 3.8
* \note Not available in Python bindings
*/
static void setCustomMissingPreferredGridHandler( const std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::TransformDetails &preferredOperation,
const QgsDatumTransform::TransformDetails &availableOperation )> &handler );

/**
* Sets a custom handler to use when a coordinate transform was required between \a sourceCrs and
* \a destinationCrs, yet the coordinate operation could not be created. The \a error argument
* specifies the error message obtained.
*
* \see setCustomMissingRequiredGridHandler()
* \see setCustomMissingPreferredGridHandler()
*
* \since QGIS 3.8
* \note Not available in Python bindings
*/
static void setCustomCoordinateOperationCreationErrorHandler( const std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QString &error )> &handler );

#endif

private:

mutable QExplicitlySharedDataPointer<QgsCoordinateTransformPrivate> d;
Expand Down
28 changes: 28 additions & 0 deletions src/core/qgscoordinatetransform_p.cpp
Expand Up @@ -33,6 +33,19 @@

/// @cond PRIVATE

std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::GridDetails &grid )> QgsCoordinateTransformPrivate::sMissingRequiredGridHandler = nullptr;

std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::TransformDetails &preferredOperation,
const QgsDatumTransform::TransformDetails &availableOperation )> QgsCoordinateTransformPrivate::sMissingPreferredGridHandler = nullptr;

std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QString &error )> QgsCoordinateTransformPrivate::sCoordinateOperationCreationErrorHandler = nullptr;

#if PROJ_VERSION_MAJOR<6
#ifdef USE_THREAD_LOCAL
thread_local QgsProjContextStore QgsCoordinateTransformPrivate::mProjContext;
Expand Down Expand Up @@ -353,6 +366,21 @@ ProjData QgsCoordinateTransformPrivate::threadLocalProjData()
return res;
}

void QgsCoordinateTransformPrivate::setCustomMissingRequiredGridHandler( const std::function<void ( const QgsCoordinateReferenceSystem &, const QgsCoordinateReferenceSystem &, const QgsDatumTransform::GridDetails & )> &handler )
{
sMissingRequiredGridHandler = handler;
}

void QgsCoordinateTransformPrivate::setCustomMissingPreferredGridHandler( const std::function<void ( const QgsCoordinateReferenceSystem &, const QgsCoordinateReferenceSystem &, const QgsDatumTransform::TransformDetails &, const QgsDatumTransform::TransformDetails & )> &handler )
{
sMissingPreferredGridHandler = handler;
}

void QgsCoordinateTransformPrivate::setCustomCoordinateOperationCreationErrorHandler( const std::function<void ( const QgsCoordinateReferenceSystem &, const QgsCoordinateReferenceSystem &, const QString & )> &handler )
{
sCoordinateOperationCreationErrorHandler = handler;
}

#if PROJ_VERSION_MAJOR<6
QString QgsCoordinateTransformPrivate::stripDatumTransform( const QString &proj4 ) const
{
Expand Down
51 changes: 51 additions & 0 deletions src/core/qgscoordinatetransform_p.h
Expand Up @@ -147,6 +147,44 @@ class QgsCoordinateTransformPrivate : public QSharedData
QReadWriteLock mProjLock;
QMap < uintptr_t, ProjData > mProjProjections;

/**
* Sets a custom handler to use when a coordinate transform is created between \a sourceCrs and
* \a destinationCrs, yet the coordinate operation requires a transform \a grid which is not present
* on the system.
*
* \since QGIS 3.8
*/
static void setCustomMissingRequiredGridHandler( const std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::GridDetails &grid )> &handler );

/**
* Sets a custom handler to use when a coordinate transform is created between \a sourceCrs and
* \a destinationCrs, yet a preferred (more accurate?) operation is available which could not
* be created on the system (e.g. due to missing transform grids).
*
* \a preferredOperation gives the details of the preferred coordinate operation, and
* \a availableOperation gives the details of the actual operation to be used during the
* transform.
*
* \since QGIS 3.8
*/
static void setCustomMissingPreferredGridHandler( const std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::TransformDetails &preferredOperation,
const QgsDatumTransform::TransformDetails &availableOperation )> &handler );

/**
* Sets a custom handler to use when a coordinate transform was required between \a sourceCrs and
* \a destinationCrs, yet the coordinate operation could not be created. The \a error argument
* specifies the error message obtained.
*
* \since QGIS 3.8
*/
static void setCustomCoordinateOperationCreationErrorHandler( const std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QString &error )> &handler );

private:

#if PROJ_VERSION_MAJOR<6
Expand All @@ -158,6 +196,19 @@ class QgsCoordinateTransformPrivate : public QSharedData
#endif

void freeProj();

static std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::GridDetails &grid )> sMissingRequiredGridHandler;

static std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::TransformDetails &preferredOperation,
const QgsDatumTransform::TransformDetails &availableOperation )> sMissingPreferredGridHandler;

static std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QString &error )> sCoordinateOperationCreationErrorHandler;
};

/// @endcond
Expand Down

0 comments on commit f758bb7

Please sign in to comment.