[FEATURE] Show the total pan distance and bearing in the status bar during

canvas pan operations

Allows users to know exactly how far (and in what direction) they've dragged
the map.
This commit is contained in:
Nyall Dawson 2019-12-05 15:51:10 +10:00
parent 0b1c0fdbf2
commit 99c8afe4e9
8 changed files with 108 additions and 4 deletions

View File

@ -526,6 +526,7 @@ sets map tile rendering flag
Ends pan action and redraws the canvas.
%End
void panAction( QMouseEvent *event );
%Docstring
Called when mouse is moving and pan is activated
@ -989,6 +990,18 @@ Emitted whenever an error is encountered during a map render operation.
The ``layer`` argument indicates the associated map layer, if available.
.. versionadded:: 3.10.0
%End
void panDistanceBearingChanged( double distance, QgsUnitTypes::DistanceUnit unit, double bearing );
%Docstring
Emitted whenever the distance or bearing of an in-progress panning
operation is changed.
This signal will be emitted during a pan operation as the user moves the map,
giving the total distance and bearing between the map position at the
start of the pan and the current pan position.
.. versionadded:: 3.12
%End
protected:

View File

@ -9,6 +9,7 @@
class QgsMapToolPan : QgsMapTool
{
%Docstring
@ -44,6 +45,20 @@ constructor
virtual bool gestureEvent( QGestureEvent *e );
signals:
void panDistanceBearingChanged( double distance, QgsUnitTypes::DistanceUnit unit, double bearing );
%Docstring
Emitted whenever the distance or bearing of an in-progress panning
operation is changed.
This signal will be emitted during a pan operation as the user moves the map,
giving the total distance and bearing between the map position at the
start of the pan and the current pan position.
.. versionadded:: 3.12
%End
};
/************************************************************************

View File

@ -349,6 +349,7 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
#include "qgsvaliditycheckregistry.h"
#include "qgsappcoordinateoperationhandlers.h"
#include "qgsprojectviewsettings.h"
#include "qgscoordinateformatter.h"
#include "qgsuserprofilemanager.h"
#include "qgsuserprofile.h"
@ -1567,6 +1568,8 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
connect( QgsProject::instance(), &QgsProject::isDirtyChanged, mActionRevertProject, toggleRevert );
connect( QgsProject::instance(), &QgsProject::fileNameChanged, mActionRevertProject, toggleRevert );
connect( mMapCanvas, &QgsMapCanvas::panDistanceBearingChanged, this, &QgisApp::showPanMessage );
// the most important part of the initialization: make sure that people can play puzzle if they need
QgsPuzzleWidget *puzzleWidget = new QgsPuzzleWidget( mMapCanvas );
mCentralContainer->insertWidget( 2, puzzleWidget );
@ -3939,6 +3942,7 @@ void QgisApp::createCanvasTools()
mMapTools.mZoomOut = new QgsMapToolZoom( mMapCanvas, true /* zoomOut */ );
mMapTools.mZoomOut->setAction( mActionZoomOut );
mMapTools.mPan = new QgsMapToolPan( mMapCanvas );
connect( static_cast< QgsMapToolPan * >( mMapTools.mPan ), &QgsMapToolPan::panDistanceBearingChanged, this, &QgisApp::showPanMessage );
mMapTools.mPan->setAction( mActionPan );
mMapTools.mIdentify = new QgsMapToolIdentifyAction( mMapCanvas );
mMapTools.mIdentify->setAction( mActionIdentify );
@ -12797,7 +12801,13 @@ void QgisApp::showRotation()
// update the statusbar with the current rotation.
double myrotation = mMapCanvas->rotation();
mRotationEdit->setValue( myrotation );
} // QgisApp::showRotation
}
void QgisApp::showPanMessage( double distance, QgsUnitTypes::DistanceUnit unit, double bearing )
{
mStatusBar->showMessage( tr( "Pan distance %1 (%2)" ).arg( QgsDistanceArea::formatDistance( distance, 1, unit ),
QgsCoordinateFormatter::formatX( bearing, QgsCoordinateFormatter::FormatDecimalDegrees, 1, QgsCoordinateFormatter::FlagDegreesUseStringSuffix ) ), 2000 );
}
void QgisApp::updateMouseCoordinatePrecision()

View File

@ -1528,6 +1528,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
void extentChanged();
void showRotation();
void showPanMessage( double distance, QgsUnitTypes::DistanceUnit unit, double bearing );
void displayMapToolMessage( const QString &message, Qgis::MessageLevel level = Qgis::Info );
void displayMessage( const QString &title, const QString &message, Qgis::MessageLevel level );
void removeMapToolMessage();

View File

@ -1340,7 +1340,7 @@ void QgsMapCanvas::keyPressEvent( QKeyEvent *e )
{
QApplication::setOverrideCursor( Qt::ClosedHandCursor );
mCanvasProperties->panSelectorDown = true;
mCanvasProperties->rubberStartPoint = mCanvasProperties->mouseLastXY;
panActionStart( mCanvasProperties->mouseLastXY );
}
break;
@ -1475,7 +1475,7 @@ void QgsMapCanvas::mousePressEvent( QMouseEvent *e )
if ( e->button() == Qt::MidButton )
{
mCanvasProperties->panSelectorDown = true;
mCanvasProperties->rubberStartPoint = mCanvasProperties->mouseLastXY;
panActionStart( mCanvasProperties->mouseLastXY );
}
else
{
@ -2029,10 +2029,23 @@ void QgsMapCanvas::panActionEnd( QPoint releasePoint )
refresh();
}
void QgsMapCanvas::panActionStart( QPoint releasePoint )
{
mCanvasProperties->rubberStartPoint = releasePoint;
mDa = QgsDistanceArea();
mDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
mDa.setSourceCrs( mapSettings().destinationCrs(), QgsProject::instance()->transformContext() );
}
void QgsMapCanvas::panAction( QMouseEvent *e )
{
Q_UNUSED( e )
QgsPointXY currentMapPoint = getCoordinateTransform()->toMapCoordinates( e->pos() );
QgsPointXY startMapPoint = getCoordinateTransform()->toMapCoordinates( mCanvasProperties->rubberStartPoint );
emit panDistanceBearingChanged( mDa.measureLine( currentMapPoint, startMapPoint ), mDa.lengthUnits(), mDa.bearing( currentMapPoint, startMapPoint ) * 180 / M_PI );
// move all map canvas items
moveCanvasContents();
}

View File

@ -490,6 +490,16 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
//! Ends pan action and redraws the canvas.
void panActionEnd( QPoint releasePoint );
#ifndef SIP_RUN
/**
* Starts a pan action.
* \note Not available in Python bindings
* \since QGIS 3.12
*/
void panActionStart( QPoint releasePoint );
#endif
//! Called when mouse is moving and pan is activated
void panAction( QMouseEvent *event );
@ -880,6 +890,18 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
*/
void renderErrorOccurred( const QString &error, QgsMapLayer *layer );
/**
* Emitted whenever the distance or bearing of an in-progress panning
* operation is changed.
*
* This signal will be emitted during a pan operation as the user moves the map,
* giving the total distance and bearing between the map position at the
* start of the pan and the current pan position.
*
* \since QGIS 3.12
*/
void panDistanceBearingChanged( double distance, QgsUnitTypes::DistanceUnit unit, double bearing );
protected:
bool event( QEvent *e ) override;
@ -1032,6 +1054,8 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
QVector<QPointer<QgsCustomDropHandler >> mDropHandlers;
QgsDistanceArea mDa;
/**
* Returns the last cursor position on the canvas in geographical coordinates
* \since QGIS 3.4

View File

@ -20,7 +20,8 @@
#include "qgsmapcanvas.h"
#include "qgsmaptopixel.h"
#include "qgsmapmouseevent.h"
#include "qgsproject.h"
#include "qgslogger.h"
QgsMapToolPan::QgsMapToolPan( QgsMapCanvas *canvas )
@ -52,7 +53,10 @@ void QgsMapToolPan::deactivate()
void QgsMapToolPan::canvasPressEvent( QgsMapMouseEvent *e )
{
if ( e->button() == Qt::LeftButton )
{
mCanvas->setCursor( QCursor( Qt::ClosedHandCursor ) );
mCanvas->panActionStart( e->pos() );
}
}
@ -83,9 +87,15 @@ void QgsMapToolPan::canvasReleaseEvent( QgsMapMouseEvent *e )
else // add pan to mouse cursor
{
// transform the mouse pos to map coordinates
const QgsPointXY prevCenter = mCanvas->center();
QgsPointXY center = mCanvas->getCoordinateTransform()->toMapCoordinates( e->x(), e->y() );
mCanvas->setCenter( center );
mCanvas->refresh();
QgsDistanceArea da;
da.setEllipsoid( QgsProject::instance()->ellipsoid() );
da.setSourceCrs( mCanvas->mapSettings().destinationCrs(), QgsProject::instance()->transformContext() );
emit panDistanceBearingChanged( da.measureLine( center, prevCenter ), da.lengthUnits(), da.bearing( center, prevCenter ) * 180 / M_PI );
}
}
}

View File

@ -18,6 +18,9 @@
#include "qgsmaptool.h"
#include "qgis_gui.h"
#include "qgspointxy.h"
#include "qgsdistancearea.h"
class QgsMapCanvas;
@ -45,6 +48,20 @@ class GUI_EXPORT QgsMapToolPan : public QgsMapTool
void canvasDoubleClickEvent( QgsMapMouseEvent *e ) override;
bool gestureEvent( QGestureEvent *e ) override;
signals:
/**
* Emitted whenever the distance or bearing of an in-progress panning
* operation is changed.
*
* This signal will be emitted during a pan operation as the user moves the map,
* giving the total distance and bearing between the map position at the
* start of the pan and the current pan position.
*
* \since QGIS 3.12
*/
void panDistanceBearingChanged( double distance, QgsUnitTypes::DistanceUnit unit, double bearing );
private:
//! Flag to indicate a map canvas drag operation is taking place