Skip to content
Permalink
Browse files
[feature] Add a "measure bearing" map tool
This tool behaves similarly to the existing "measure angle" map tool,
but requires the user only to click two points on the map and displays
the bearing between these points.
  • Loading branch information
nyalldawson committed Jun 18, 2021
1 parent 6596d87 commit d83a7698e23c06ab14008dd59dc484fb00e5c389
@@ -920,6 +920,7 @@
<file>themes/default/mIconFolderOpenParams.svg</file>
<file>themes/default/mIconFolderLinkParams.svg</file>
<file>themes/default/mIconFolderHomeParams.svg</file>
<file>themes/default/mActionMeasureBearing.svg</file>
</qresource>
<qresource prefix="/images/tips">
<file alias="symbol_levels.png">qgis_tips/symbol_levels.png</file>
@@ -0,0 +1 @@
<svg height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M 11.764707,14.807559 C 8.4665509,12.921897 8.6275419,12.93651 5.4599056,12.56332 l -0.029936,9.128173 c 1.8820661,-2.316719 4.7029074,-6.243469 6.3347374,-6.883934 z" fill="#c7c7c7"/><path d="M5.4922111 22.006402L5.4762203 3.9992377M5.4922111 22.006402L14.748994 9.069822" stroke="#415a75" fill="none"/><path d="M 12.492216,15.506403 C 9.4922159,13.00641 7.9922159,12.506409 3.9922111,12.506409" stroke="#6d97c4" stroke-linecap="square" fill="none"/><path d="M 5.4366968,1.4048512 8.2272949,7.9944063 H 2.6460998 Z" fill="#415a75" paint-order="stroke fill markers"/><circle cx="19.384918" cy="6.0672107" r="1.9237912" fill="none" stroke="#5b5b5c" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" paint-order="stroke fill markers"/></svg>
@@ -86,6 +86,7 @@ set(QGIS_APP_SRCS
qgsmaptoolhtmlannotation.cpp
qgsmaptoolidentifyaction.cpp
qgsmaptoolmeasureangle.cpp
qgsmaptoolmeasurebearing.cpp
qgsmaptoolmovefeature.cpp
qgsmaptooloffsetcurve.cpp
qgsmaptooloffsetpointsymbol.cpp
@@ -29,6 +29,7 @@
#include "qgsmaptoolcircle3points.h"
#include "qgsmaptoolcircle2tangentspoint.h"
#include "qgsmaptoolmeasureangle.h"
#include "qgsmaptoolmeasurebearing.h"
#include "qgsmaptoolformannotation.h"
#include "qgsmaptoolsvgannotation.h"
#include "qgsmaptoolcircularstringcurvepoint.h"
@@ -120,6 +121,7 @@ QgsAppMapTools::QgsAppMapTools( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockW
mTools.insert( Tool::MeasureDistance, new QgsMeasureTool( canvas, false /* area */ ) );
mTools.insert( Tool::MeasureArea, new QgsMeasureTool( canvas, true /* area */ ) );
mTools.insert( Tool::MeasureAngle, new QgsMapToolMeasureAngle( canvas ) );
mTools.insert( Tool::MeasureBearing, new QgsMapToolMeasureBearing( canvas ) );
mTools.insert( Tool::TextAnnotation, new QgsMapToolTextAnnotation( canvas ) );
mTools.insert( Tool::FormAnnotation, new QgsMapToolFormAnnotation( canvas ) );
mTools.insert( Tool::HtmlAnnotation, new QgsMapToolHtmlAnnotation( canvas ) );
@@ -56,6 +56,7 @@ class QgsAppMapTools
MeasureDistance,
MeasureArea,
MeasureAngle,
MeasureBearing,
AddFeature,
CircularStringCurvePoint,
CircularStringRadius,
@@ -457,6 +457,7 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
#include "qgsmaptoolidentifyaction.h"
#include "qgsmaptoolpinlabels.h"
#include "qgsmaptoolmeasureangle.h"
#include "qgsmaptoolmeasurebearing.h"
#include "qgsmaptoolrotatepointsymbols.h"
#include "qgsmaptooldigitizefeature.h"
#include "qgsmaptooloffsetpointsymbol.h"
@@ -2643,6 +2644,7 @@ void QgisApp::createActions()
connect( mActionMeasure, &QAction::triggered, this, &QgisApp::measure );
connect( mActionMeasureArea, &QAction::triggered, this, &QgisApp::measureArea );
connect( mActionMeasureAngle, &QAction::triggered, this, &QgisApp::measureAngle );
connect( mActionMeasureBearing, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::MeasureBearing ) ); } );
connect( mActionZoomFullExtent, &QAction::triggered, this, &QgisApp::zoomFull );
connect( mActionZoomToLayer, &QAction::triggered, this, &QgisApp::zoomToLayerExtent );
connect( mActionZoomToLayers, &QAction::triggered, this, &QgisApp::zoomToLayerExtent );
@@ -2951,6 +2953,7 @@ void QgisApp::createActionGroups()
mMapToolGroup->addAction( mActionMeasure );
mMapToolGroup->addAction( mActionMeasureArea );
mMapToolGroup->addAction( mActionMeasureAngle );
mMapToolGroup->addAction( mActionMeasureBearing );
mMapToolGroup->addAction( mActionAddFeature );
mMapToolGroup->addAction( mActionCircularStringCurvePoint );
mMapToolGroup->addAction( mActionCircularStringRadius );
@@ -3396,6 +3399,7 @@ void QgisApp::createToolBars()
bt->setPopupMode( QToolButton::MenuButtonPopup );
bt->addAction( mActionMeasure );
bt->addAction( mActionMeasureArea );
bt->addAction( mActionMeasureBearing );
bt->addAction( mActionMeasureAngle );

QAction *defMeasureAction = mActionMeasure;
@@ -3408,6 +3412,9 @@ void QgisApp::createToolBars()
defMeasureAction = mActionMeasureArea;
break;
case 2:
defMeasureAction = mActionMeasureBearing;
break;
case 3:
defMeasureAction = mActionMeasureAngle;
break;
}
@@ -4078,6 +4085,7 @@ void QgisApp::setTheme( const QString &themeName )
mActionMeasure->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionMeasure.svg" ) ) );
mActionMeasureArea->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionMeasureArea.svg" ) ) );
mActionMeasureAngle->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionMeasureAngle.svg" ) ) );
mActionMeasureBearing->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionMeasureBearing.svg" ) ) );
mActionMapTips->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionMapTips.svg" ) ) );
mActionShowBookmarkManager->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionShowBookmarks.svg" ) ) );
mActionShowBookmarks->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionShowBookmarks.svg" ) ) );
@@ -4297,6 +4305,7 @@ void QgisApp::setupCanvasTools()
mMapTools->mapTool( QgsAppMapTools::MeasureDistance )->setAction( mActionMeasure );
mMapTools->mapTool( QgsAppMapTools::MeasureArea )->setAction( mActionMeasureArea );
mMapTools->mapTool( QgsAppMapTools::MeasureAngle )->setAction( mActionMeasureAngle );
mMapTools->mapTool( QgsAppMapTools::MeasureBearing )->setAction( mActionMeasureBearing );
mMapTools->mapTool( QgsAppMapTools::TextAnnotation )->setAction( mActionTextAnnotation );
mMapTools->mapTool( QgsAppMapTools::FormAnnotation )->setAction( mActionFormAnnotation );
mMapTools->mapTool( QgsAppMapTools::HtmlAnnotation )->setAction( mActionHtmlAnnotation );
@@ -12678,6 +12687,7 @@ void QgisApp::showOptionsDialog( QWidget *parent, const QString &currentPage, in
mMapTools->mapTool< QgsMeasureTool >( QgsAppMapTools::MeasureDistance )->updateSettings();
mMapTools->mapTool< QgsMeasureTool >( QgsAppMapTools::MeasureArea )->updateSettings();
mMapTools->mapTool< QgsMapToolMeasureAngle >( QgsAppMapTools::MeasureAngle )->updateSettings();
mMapTools->mapTool< QgsMapToolMeasureBearing >( QgsAppMapTools::MeasureBearing )->updateSettings();

#ifdef HAVE_3D
const QList< Qgs3DMapCanvasDockWidget * > canvases3D = findChildren< Qgs3DMapCanvasDockWidget * >();
@@ -14599,6 +14609,7 @@ void QgisApp::projectProperties( const QString &currentPage )
mMapTools->mapTool< QgsMeasureTool >( QgsAppMapTools::MeasureDistance )->updateSettings();
mMapTools->mapTool< QgsMeasureTool >( QgsAppMapTools::MeasureArea )->updateSettings();
mMapTools->mapTool< QgsMapToolMeasureAngle >( QgsAppMapTools::MeasureAngle )->updateSettings();
mMapTools->mapTool< QgsMapToolMeasureBearing >( QgsAppMapTools::MeasureBearing )->updateSettings();

// Set the window title.
setTitleBarText_( *this );
@@ -19,26 +19,36 @@
#include "qgsunittypes.h"
#include "qgsmaptoolmeasureangle.h"
#include "qgssettings.h"
#include "qgsprojectdisplaysettings.h"
#include "qgsproject.h"
#include "qgsbearingnumericformat.h"

#include <cmath>

QgsDisplayAngle::QgsDisplayAngle( QgsMapToolMeasureAngle *tool, Qt::WindowFlags f )
QgsDisplayAngle::QgsDisplayAngle( QgsMapTool *tool, Qt::WindowFlags f )
: QDialog( tool->canvas()->topLevelWidget(), f )
, mTool( tool )
{
setupUi( this );
}

void QgsDisplayAngle::setValueInRadians( double value )
void QgsDisplayAngle::setAngleInRadians( double value )
{
mValue = value;
updateUi();
}

void QgsDisplayAngle::updateUi()
{
QgsSettings settings;
QgsUnitTypes::AngleUnit unit = QgsUnitTypes::decodeAngleUnit( settings.value( QStringLiteral( "qgis/measure/angleunits" ), QgsUnitTypes::encodeUnit( QgsUnitTypes::AngleDegrees ) ).toString() );
int decimals = settings.value( QStringLiteral( "qgis/measure/decimalplaces" ), 3 ).toInt();
mAngleLineEdit->setText( QgsUnitTypes::formatAngle( mValue * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AngleRadians, unit ), decimals, unit ) );
}

void QgsDisplayAngle::setBearingInRadians( double value )
{
mValue = value;

const double degrees = value * 180.0 / M_PI;

QgsNumericFormatContext context;
const QString valueAsText = QgsProject::instance()->displaySettings()->bearingFormat()->formatDouble( degrees, context );
mAngleLineEdit->setText( valueAsText );
}
@@ -19,31 +19,43 @@
#include "ui_qgsdisplayanglebase.h"
#include "qgis_app.h"

class QgsMapToolMeasureAngle;
class QgsMapTool;

//! A class that displays results of angle measurements with the proper unit
class APP_EXPORT QgsDisplayAngle: public QDialog, private Ui::QgsDisplayAngleBase
{
Q_OBJECT

public:
QgsDisplayAngle( QgsMapToolMeasureAngle *tool = nullptr, Qt::WindowFlags f = Qt::WindowFlags() );
QgsDisplayAngle( QgsMapTool *tool = nullptr, Qt::WindowFlags f = Qt::WindowFlags() );

/**
* Sets the measured angle value (in radians). The value is going to
* be converted to degrees / gon automatically if necessary.
*/
void setValueInRadians( double value );
void setAngleInRadians( double value );

/**
* Sets the measured bearing (in radians).
*/
void setBearingInRadians( double value );

/**
* Returns the current angular value (in radians)
*/
double value() const { return mValue; }

/**
* Returns the current value, as a string.
*/
QString text() const { return mAngleLineEdit->text(); }

private:
//! pointer to tool which owns this dialog
QgsMapToolMeasureAngle *mTool = nullptr;
QgsMapTool *mTool = nullptr;

//! The value we're showing
double mValue = 0.0;

//! Updates UI according to user settings.
void updateUi();
};

#endif // QGSDISPLAYANGLE_H
@@ -80,7 +80,7 @@ void QgsMapToolMeasureAngle::canvasMoveEvent( QgsMapMouseEvent *e )
}
}

mResultDisplay->setValueInRadians( resultAngle );
mResultDisplay->setAngleInRadians( resultAngle );
}
}

@@ -210,7 +210,7 @@ void QgsMapToolMeasureAngle::updateSettings()
}
}

mResultDisplay->setValueInRadians( resultAngle );
mResultDisplay->setAngleInRadians( resultAngle );
}

void QgsMapToolMeasureAngle::configureDistanceArea()
Loading

0 comments on commit d83a769

Please sign in to comment.