Skip to content

Commit

Permalink
Show bounds of operations in transform selection dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 8, 2019
1 parent 337f1d9 commit d03c9d5
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 58 deletions.
2 changes: 2 additions & 0 deletions python/core/auto_generated/qgsdatumtransform.sip.in
Expand Up @@ -113,6 +113,8 @@ and ``destinationTransformId`` transforms.

QString areaOfUse;

QgsRectangle bounds;

QList< QgsDatumTransform::GridDetails > grids;

QList< QgsDatumTransform::SingleOperationDetails > operationDetails;
Expand Down
4 changes: 2 additions & 2 deletions src/app/qgisapp.cpp
Expand Up @@ -7859,7 +7859,7 @@ QString QgisApp::saveAsVectorFileGeneral( QgsVectorLayer *vlayer, bool symbology

if ( destCRS.isValid() )
{
QgsDatumTransformDialog::run( vlayer->crs(), destCRS, this );
QgsDatumTransformDialog::run( vlayer->crs(), destCRS, this, mMapCanvas );
ct = QgsCoordinateTransform( vlayer->crs(), destCRS, QgsProject::instance() );
}

Expand Down Expand Up @@ -13733,7 +13733,7 @@ bool QgisApp::askUserForDatumTransform( const QgsCoordinateReferenceSystem &sour
{
Q_ASSERT( qApp->thread() == QThread::currentThread() );

return QgsDatumTransformDialog::run( sourceCrs, destinationCrs, this );
return QgsDatumTransformDialog::run( sourceCrs, destinationCrs, this, mMapCanvas );
}

void QgisApp::readDockWidgetSettings( QDockWidget *dockWidget, const QDomElement &elem )
Expand Down
5 changes: 3 additions & 2 deletions src/app/qgsdatumtransformtablewidget.cpp
Expand Up @@ -17,6 +17,7 @@

#include "qgscoordinatetransform.h"
#include "qgsdatumtransformdialog.h"
#include "qgisapp.h"


QgsDatumTransformTableModel::QgsDatumTransformTableModel( QObject *parent )
Expand Down Expand Up @@ -228,7 +229,7 @@ QgsDatumTransformTableWidget::QgsDatumTransformTableWidget( QWidget *parent )

void QgsDatumTransformTableWidget::addDatumTransform()
{
QgsDatumTransformDialog dlg( QgsCoordinateReferenceSystem(), QgsCoordinateReferenceSystem(), true, false, false );
QgsDatumTransformDialog dlg( QgsCoordinateReferenceSystem(), QgsCoordinateReferenceSystem(), true, false, false, QPair< int, int >(), nullptr, nullptr, QString(), QgisApp::instance()->mapCanvas() );
if ( dlg.exec() )
{
const QgsDatumTransformDialog::TransformInfo dt = dlg.selectedDatumTransform();
Expand Down Expand Up @@ -296,7 +297,7 @@ void QgsDatumTransformTableWidget::editDatumTransform()
( sourceTransform != -1 || destinationTransform != -1 ) )
#endif
{
QgsDatumTransformDialog dlg( sourceCrs, destinationCrs, true, false, false, qMakePair( sourceTransform, destinationTransform ), nullptr, nullptr, proj );
QgsDatumTransformDialog dlg( sourceCrs, destinationCrs, true, false, false, qMakePair( sourceTransform, destinationTransform ), nullptr, nullptr, proj, QgisApp::instance()->mapCanvas() );
if ( dlg.exec() )
{
const QgsDatumTransformDialog::TransformInfo dt = dlg.selectedDatumTransform();
Expand Down
11 changes: 10 additions & 1 deletion src/core/qgsdatumtransform.cpp
Expand Up @@ -327,9 +327,18 @@ QgsDatumTransform::TransformDetails QgsDatumTransform::transformDetailsFromPj( P
details.code = QString( proj_get_id_code( op, 0 ) );

const char *areaOfUseName = nullptr;
if ( proj_get_area_of_use( pjContext, op, nullptr, nullptr, nullptr, nullptr, &areaOfUseName ) )
double westLon = 0;
double southLat = 0;
double eastLon = 0;
double northLat = 0;
if ( proj_get_area_of_use( pjContext, op, &westLon, &southLat, &eastLon, &northLat, &areaOfUseName ) )
{
details.areaOfUse = QString( areaOfUseName );
// don't use the constructor which normalizes!
details.bounds.setXMinimum( westLon );
details.bounds.setYMinimum( southLat );
details.bounds.setXMaximum( eastLon );
details.bounds.setYMaximum( northLat );
}

#if PROJ_VERSION_MAJOR > 6 or PROJ_VERSION_MINOR >= 2
Expand Down
9 changes: 9 additions & 0 deletions src/core/qgsdatumtransform.h
Expand Up @@ -19,6 +19,7 @@

#include "qgis_core.h"
#include "qgis_sip.h"
#include "qgsrectangle.h"
#include <QString>
#include <QList>

Expand Down Expand Up @@ -231,9 +232,17 @@ class CORE_EXPORT QgsDatumTransform
*
* This is only available for single step coordinate operations. For multi-step operations, check
* \a operationDetails instead.
*
* \see bounds
*/
QString areaOfUse;

/**
* Valid bounds for the coordinate operation.
* \see areaOfUse
*/
QgsRectangle bounds;

/**
* Contains a list of transform grids used by the operation.
*/
Expand Down
51 changes: 46 additions & 5 deletions src/gui/qgsdatumtransformdialog.cpp
Expand Up @@ -33,7 +33,7 @@
#include <proj.h>
#endif

bool QgsDatumTransformDialog::run( const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, QWidget *parent )
bool QgsDatumTransformDialog::run( const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, QWidget *parent, QgsMapCanvas *mapCanvas )
{
if ( sourceCrs == destinationCrs )
return true;
Expand All @@ -44,7 +44,7 @@ bool QgsDatumTransformDialog::run( const QgsCoordinateReferenceSystem &sourceCrs
return true;
}

QgsDatumTransformDialog dlg( sourceCrs, destinationCrs, false, true, true, qMakePair( -1, -1 ), parent );
QgsDatumTransformDialog dlg( sourceCrs, destinationCrs, false, true, true, qMakePair( -1, -1 ), parent, nullptr, QString(), mapCanvas );
if ( dlg.shouldAskUserForSelection() )
{
if ( dlg.exec() )
Expand Down Expand Up @@ -74,7 +74,7 @@ QgsDatumTransformDialog::QgsDatumTransformDialog( const QgsCoordinateReferenceSy
const QgsCoordinateReferenceSystem &destinationCrs, const bool allowCrsChanges, const bool showMakeDefault, const bool forceChoice,
QPair<int, int> selectedDatumTransforms,
QWidget *parent,
Qt::WindowFlags f, const QString &selectedProj )
Qt::WindowFlags f, const QString &selectedProj, QgsMapCanvas *mapCanvas )
: QDialog( parent, f )
, mPreviousCursorOverride( qgis::make_unique< QgsTemporaryCursorRestoreOverride >() ) // this dialog is often shown while cursor overrides are in place, so temporarily remove them
{
Expand Down Expand Up @@ -120,6 +120,37 @@ QgsDatumTransformDialog::QgsDatumTransformDialog( const QgsCoordinateReferenceSy
mDestCrsLabel->setText( QgsProjectionSelectionWidget::crsOptionText( destinationCrs ) );
}

#if PROJ_VERSION_MAJOR<6
mAreaCanvas->hide();
( void )mapCanvas;
#else
if ( mapCanvas )
{
// show canvas extent in preview widget
QPolygonF mainCanvasPoly = mapCanvas->mapSettings().visiblePolygon();
QgsGeometry g = QgsGeometry::fromQPolygonF( mainCanvasPoly );
// close polygon
mainCanvasPoly << mainCanvasPoly.at( 0 );
if ( QgsProject::instance()->crs() !=
QgsCoordinateReferenceSystem::fromEpsgId( 4326 ) )
{
// reproject extent
QgsCoordinateTransform ct( QgsProject::instance()->crs(),
QgsCoordinateReferenceSystem::fromEpsgId( 4326 ), QgsProject::instance() );

g = g.densifyByCount( 5 );
try
{
g.transform( ct );
}
catch ( QgsCsException & )
{
}
}
mAreaCanvas->setCanvasRect( g.boundingBox() );
}
#endif

#if PROJ_VERSION_MAJOR>=6
// proj 6 doesn't provide deprecated operations
mHideDeprecatedCheckBox->setVisible( false );
Expand Down Expand Up @@ -294,9 +325,10 @@ void QgsDatumTransformDialog::load( QPair<int, int> selectedDatumTransforms, con

if ( !transform.areaOfUse.isEmpty() && !areasOfUse.contains( transform.areaOfUse ) )
areasOfUse << transform.areaOfUse;
item->setData( BoundsRole, transform.bounds );

const QString id = QStringLiteral( "%1:%2" ).arg( transform.authority, transform.code );
if ( !transform.authority.isEmpty() && !transform.code.isEmpty() && !authorityCodes.contains( id ) )
const QString id = !transform.authority.isEmpty() && !transform.code.isEmpty() ? QStringLiteral( "%1:%2" ).arg( transform.authority, transform.code ) : QString();
if ( !id.isEmpty() && !authorityCodes.contains( id ) )
authorityCodes << id;

#if PROJ_VERSION_MAJOR > 6 or PROJ_VERSION_MINOR >= 2
Expand Down Expand Up @@ -723,6 +755,15 @@ void QgsDatumTransformDialog::tableCurrentItemChanged( QTableWidgetItem *, QTabl

QTableWidgetItem *srcItem = mDatumTransformTableWidget->item( row, 0 );
mLabelSrcDescription->setText( srcItem ? srcItem->toolTip() : QString() );
if ( srcItem )
{
QgsRectangle rect = srcItem->data( BoundsRole ).value< QgsRectangle >();
mAreaCanvas->setPreviewRect( rect );
}
else
{
mAreaCanvas->setPreviewRect( QgsRectangle() );
}
QTableWidgetItem *destItem = mDatumTransformTableWidget->item( row, 1 );
mLabelDstDescription->setText( destItem ? destItem->toolTip() : QString() );
}
Expand Down
10 changes: 8 additions & 2 deletions src/gui/qgsdatumtransformdialog.h
Expand Up @@ -65,11 +65,15 @@ class GUI_EXPORT QgsDatumTransformDialog : public QDialog, private Ui::QgsDatumT
* and the user has asked to be prompted, not re-adding transforms already in the current project
* context, etc.
*
* The optional \a mapCanvas argument can be used to refine the dialog's display based on the current
* map canvas extent.
*
* \since QGIS 3.8
*/
static bool run( const QgsCoordinateReferenceSystem &sourceCrs = QgsCoordinateReferenceSystem(),
const QgsCoordinateReferenceSystem &destinationCrs = QgsCoordinateReferenceSystem(),
QWidget *parent = nullptr );
QWidget *parent = nullptr,
QgsMapCanvas *mapCanvas = nullptr );

// TODO QGIS 4.0 - remove selectedDatumTransform

Expand All @@ -84,7 +88,8 @@ class GUI_EXPORT QgsDatumTransformDialog : public QDialog, private Ui::QgsDatumT
QPair<int, int> selectedDatumTransforms = qMakePair( -1, -1 ),
QWidget *parent = nullptr,
Qt::WindowFlags f = nullptr,
const QString &selectedProj = QString() );
const QString &selectedProj = QString(),
QgsMapCanvas *mapCanvas = nullptr );
~QgsDatumTransformDialog() override;

void accept() override;
Expand All @@ -109,6 +114,7 @@ class GUI_EXPORT QgsDatumTransformDialog : public QDialog, private Ui::QgsDatumT
TransformIdRole = Qt::UserRole + 1,
ProjRole,
AvailableRole,
BoundsRole
};

bool gridShiftTransformation( const QString &itemText ) const;
Expand Down
120 changes: 74 additions & 46 deletions src/ui/qgsdatumtransformdialogbase.ui
Expand Up @@ -13,41 +13,7 @@
<property name="windowTitle">
<string>Select Datum Transformations</string>
</property>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,1,0,0,0,0">
<item row="5" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="mHideDeprecatedCheckBox">
<property name="text">
<string>Hide deprecated transformations</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="mMakeDefaultCheckBox">
<property name="toolTip">
<string>If checked, the selected transformation will become the default choice in all new projects</string>
</property>
<property name="text">
<string>Make default</string>
</property>
</widget>
</item>
</layout>
</item>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,2,1,0,0,0">
<item row="1" column="0" colspan="2">
<widget class="QStackedWidget" name="mCrsStackedWidget">
<property name="currentIndex">
Expand Down Expand Up @@ -143,6 +109,50 @@
</widget>
</widget>
</item>
<item row="5" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="mHideDeprecatedCheckBox">
<property name="text">
<string>Hide deprecated transformations</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="mMakeDefaultCheckBox">
<property name="toolTip">
<string>If checked, the selected transformation will become the default choice in all new projects</string>
</property>
<property name="text">
<string>Make default</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<widget class="QTableWidget" name="mDatumTransformTableWidget">
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QDialogButtonBox" name="mButtonBox">
<property name="orientation">
Expand All @@ -154,7 +164,7 @@
</widget>
</item>
<item row="3" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,1,0">
<item>
<widget class="QLabel" name="mLabelSrcDescription">
<property name="cursor">
Expand Down Expand Up @@ -193,18 +203,30 @@
</property>
</widget>
</item>
<item>
<widget class="QgsCoordinateBoundsPreviewMapWidget" name="mAreaCanvas" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>117</width>
<height>117</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777214</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<widget class="QTableWidget" name="mDatumTransformTableWidget">
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_5">
<property name="text">
Expand All @@ -224,6 +246,12 @@
<header>qgsprojectionselectionwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsCoordinateBoundsPreviewMapWidget</class>
<extends>QWidget</extends>
<header>qgscoordinateboundspreviewmapwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>mDatumTransformTableWidget</tabstop>
Expand Down

0 comments on commit d03c9d5

Please sign in to comment.