Skip to content

Commit

Permalink
Show warnings on fallback transform
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Feb 17, 2020
1 parent ec78431 commit 1684ff1
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/app/qgsappcoordinateoperationhandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,19 @@ QgsAppMissingGridHandler::QgsAppMissingGridHandler( QObject *parent )
emit missingGridUsedByContextHandler( sourceCrs, destinationCrs, desired );
} );

QgsCoordinateTransform::setFallbackOperationOccurredHandler( [ = ]( const QgsCoordinateReferenceSystem & sourceCrs,
const QgsCoordinateReferenceSystem & destinationCrs,
const QgsDatumTransform::TransformDetails & desired,
const QgsDatumTransform::TransformDetails & used )
{
emit fallbackOperationOccurred( sourceCrs, destinationCrs, desired, used );
} );

connect( this, &QgsAppMissingGridHandler::missingRequiredGrid, this, &QgsAppMissingGridHandler::onMissingRequiredGrid, Qt::QueuedConnection );
connect( this, &QgsAppMissingGridHandler::missingPreferredGrid, this, &QgsAppMissingGridHandler::onMissingPreferredGrid, Qt::QueuedConnection );
connect( this, &QgsAppMissingGridHandler::coordinateOperationCreationError, this, &QgsAppMissingGridHandler::onCoordinateOperationCreationError, Qt::QueuedConnection );
connect( this, &QgsAppMissingGridHandler::missingGridUsedByContextHandler, this, &QgsAppMissingGridHandler::onMissingGridUsedByContextHandler, Qt::QueuedConnection );
connect( this, &QgsAppMissingGridHandler::fallbackOperationOccurred, this, &QgsAppMissingGridHandler::onFallbackOperationOccurred, Qt::QueuedConnection );

connect( QgsProject::instance(), &QgsProject::cleared, this, [ = ] { mAlreadyWarnedPairsForProject.clear(); } );

Expand Down Expand Up @@ -265,6 +274,30 @@ void QgsAppMissingGridHandler::onMissingGridUsedByContextHandler( const QgsCoord
bar->pushWidget( widget, Qgis::Critical, 0 );
}

void QgsAppMissingGridHandler::onFallbackOperationOccurred( const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, const QgsDatumTransform::TransformDetails &desired, const QgsDatumTransform::TransformDetails &used )
{
// if ( !shouldWarnAboutPairForCurrentProject( sourceCrs, destinationCrs ) )
// return;

const QString shortMessage = tr( "Used a fallback transform from %1 to %2" ).arg( sourceCrs.userFriendlyIdentifier( QgsCoordinateReferenceSystem::ShortString ), destinationCrs.userFriendlyIdentifier( QgsCoordinateReferenceSystem::ShortString ) );
const QString longMessage = tr( "<p>An alternative transform was used when transforming coordinates between <i>%1</i> and <i>%2</i>.</p><p style=\"color: red\">I wanted to use %3</p>" ).arg( sourceCrs.userFriendlyIdentifier(), destinationCrs.userFriendlyIdentifier(), desired.proj );

QgsMessageBar *bar = QgisApp::instance()->messageBar();
QgsMessageBarItem *widget = bar->createMessage( QString(), shortMessage );
QPushButton *detailsButton = new QPushButton( tr( "Details" ) );
connect( detailsButton, &QPushButton::clicked, this, [longMessage]
{
// dlg has deleted on close
QgsMessageOutput * dlg( QgsMessageOutput::createMessageOutput() );
dlg->setTitle( tr( "Fallback Transform Occurred" ) );
dlg->setMessage( longMessage, QgsMessageOutput::MessageHtml );
dlg->showMessage();
} );

widget->layout()->addWidget( detailsButton );
bar->pushWidget( widget, Qgis::Critical, 0 );
}

bool QgsAppMissingGridHandler::shouldWarnAboutPair( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &dest )
{
if ( mAlreadyWarnedPairs.contains( qMakePair( source, dest ) ) || mAlreadyWarnedPairs.contains( qMakePair( dest, source ) ) )
Expand Down
11 changes: 11 additions & 0 deletions src/app/qgsappcoordinateoperationhandlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ class QgsAppMissingGridHandler : public QObject
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::TransformDetails &desired );

void fallbackOperationOccurred( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::TransformDetails &desired,
const QgsDatumTransform::TransformDetails &used );

private slots:

void onMissingRequiredGrid( const QgsCoordinateReferenceSystem &sourceCrs,
Expand All @@ -67,6 +72,12 @@ class QgsAppMissingGridHandler : public QObject
void onMissingGridUsedByContextHandler( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::TransformDetails &desired );

void onFallbackOperationOccurred( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::TransformDetails &desired,
const QgsDatumTransform::TransformDetails &used );

private:

bool shouldWarnAboutPair( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &dest );
Expand Down
22 changes: 22 additions & 0 deletions src/core/qgscoordinatetransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ QReadWriteLock QgsCoordinateTransform::sCacheLock;
QMultiHash< QPair< QString, QString >, QgsCoordinateTransform > QgsCoordinateTransform::sTransforms; //same auth_id pairs might have different datum transformations
bool QgsCoordinateTransform::sDisableCache = false;

std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::TransformDetails &desiredOperation,
const QgsDatumTransform::TransformDetails &usedOperation )> QgsCoordinateTransform::sFallbackOperationOccurredHandler = nullptr;

QgsCoordinateTransform::QgsCoordinateTransform()
{
d = new QgsCoordinateTransformPrivate();
Expand Down Expand Up @@ -637,12 +642,14 @@ void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *
return;
}

#if PROJ_VERSION_MAJOR>=6
double *xprev = new double[ numPoints ];
memcpy( xprev, x, sizeof( double ) * numPoints );
double *yprev = new double[ numPoints ];
memcpy( yprev, y, sizeof( double ) * numPoints );
double *zprev = new double[ numPoints ];
memcpy( zprev, z, sizeof( double ) * numPoints );
#endif

#ifdef COORDINATE_TRANSFORM_VERBOSE
double xorg = *x;
Expand Down Expand Up @@ -753,11 +760,21 @@ void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *
memcpy( y, yprev, sizeof( double ) * numPoints );
memcpy( z, zprev, sizeof( double ) * numPoints );
}

if ( sFallbackOperationOccurredHandler )
{
QgsDatumTransform::TransformDetails desired = instantiatedCoordinateOperationDetails();
QgsDatumTransform::TransformDetails used = QgsDatumTransform::transformDetailsFromPj( transform );
sFallbackOperationOccurredHandler( d->mSourceCRS, d->mDestCRS, desired, used );
}
}
}
delete [] xprev;
xprev = nullptr;
delete [] yprev;
yprev = nullptr;
delete [] zprev;
zprev = nullptr;
#endif
if ( projResult != 0 )
{
Expand Down Expand Up @@ -1091,3 +1108,8 @@ void QgsCoordinateTransform::setCustomMissingGridUsedByContextHandler( const std
{
QgsCoordinateTransformPrivate::setCustomMissingGridUsedByContextHandler( handler );
}

void QgsCoordinateTransform::setFallbackOperationOccurredHandler( const std::function<void ( const QgsCoordinateReferenceSystem &, const QgsCoordinateReferenceSystem &, const QgsDatumTransform::TransformDetails &, const QgsDatumTransform::TransformDetails & )> &handler )
{
sFallbackOperationOccurredHandler = handler;
}
19 changes: 19 additions & 0 deletions src/core/qgscoordinatetransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,19 @@ class CORE_EXPORT QgsCoordinateTransform
static void setCustomMissingGridUsedByContextHandler( const std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::TransformDetails &desiredOperation )> &handler );


/**
* Sets a custom \a handler to use when the desired coordinate operation for use between \a sourceCrs and
* \a destinationCrs failed and an alternative fallback \a usedOperation was utilised instead.
*
* \since QGIS 3.10.3
*/
static void setFallbackOperationOccurredHandler( const std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::TransformDetails &desiredOperation,
const QgsDatumTransform::TransformDetails &usedOperation )> &handler );

#endif

#ifndef SIP_RUN
Expand Down Expand Up @@ -596,6 +609,12 @@ class CORE_EXPORT QgsCoordinateTransform
static QMultiHash< QPair< QString, QString >, QgsCoordinateTransform > sTransforms; //same auth_id pairs might have different datum transformations
static bool sDisableCache;


static std::function< void( const QgsCoordinateReferenceSystem &sourceCrs,
const QgsCoordinateReferenceSystem &destinationCrs,
const QgsDatumTransform::TransformDetails &desiredOperation,
const QgsDatumTransform::TransformDetails &usedOperation )> sFallbackOperationOccurredHandler;

};

//! Output stream operator
Expand Down

0 comments on commit 1684ff1

Please sign in to comment.