Skip to content
Permalink
Browse files

[FEATURE]: A tool to measure angles

git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@12663 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent
mhugent committed Jan 2, 2010
1 parent b560e12 commit 82a58ced0205383e42321f318bca117d89df1974
@@ -156,6 +156,7 @@
<file>themes/default/mActionLowerItems.png</file>
<file>themes/default/mActionMapTips.png</file>
<file>themes/default/mActionMeasure.png</file>
<file>themes/default/mActionMeasureAngle.png</file>
<file>themes/default/mActionMeasureArea.png</file>
<file>themes/default/mActionMergeFeatures.png</file>
<file>themes/default/mActionMoveFeature.png</file>
Binary file not shown.
@@ -21,6 +21,7 @@ SET(QGIS_APP_SRCS
qgsspatialitefilterproxymodel.cpp
qgsspatialitetablemodel.cpp
qgsdelattrdialog.cpp
qgsdisplayangle.cpp
qgsfieldcalculator.cpp
qgsnewvectorlayerdialog.cpp
qgsgraduatedsymboldialog.cpp
@@ -37,6 +38,7 @@ SET(QGIS_APP_SRCS
qgsmaptooldeletevertex.cpp
qgsmaptooledit.cpp
qgsmaptoolidentify.cpp
qgsmaptoolmeasureangle.cpp
qgsmaptoolmovefeature.cpp
qgsmaptoolmovevertex.cpp
qgsmaptoolnodetool.cpp
@@ -128,6 +130,7 @@ SET (QGIS_APP_MOC_HDRS
qgscustomprojectiondialog.h
qgsdelattrdialog.h
qgsfieldcalculator.h
qgsmaptoolmeasureangle.h
qgsnewvectorlayerdialog.h
qgsgraduatedsymboldialog.h
qgshelpviewer.h
@@ -169,6 +169,7 @@
#include "qgsmaptooldeletepart.h"
#include "qgsmaptooldeletevertex.h"
#include "qgsmaptoolidentify.h"
#include "qgsmaptoolmeasureangle.h"
#include "qgsmaptoolmovefeature.h"
#include "qgsmaptoolmovevertex.h"
#include "qgsmaptoolnodetool.h"
@@ -811,6 +812,10 @@ void QgisApp::createActions()
mActionMeasureArea->setStatusTip( tr( "Measure an Area" ) );
connect( mActionMeasureArea, SIGNAL( triggered() ), this, SLOT( measureArea() ) );

mActionMeasureAngle = new QAction( getThemeIcon( "mActionMeasureAngle.png" ), tr( "Measure Angle" ), this );
mActionMeasureAngle->setStatusTip( tr( "Measure Angle" ) );
connect( mActionMeasureAngle, SIGNAL( triggered() ), this, SLOT( measureAngle() ) );

mActionZoomFullExtent = new QAction( getThemeIcon( "mActionZoomFullExtent.png" ), tr( "Zoom Full" ), this );
shortcuts->registerAction( mActionZoomFullExtent, tr( "Ctrl+Shift+F", "Zoom to Full Extents" ) );
mActionZoomFullExtent->setStatusTip( tr( "Zoom to Full Extents" ) );
@@ -1110,6 +1115,8 @@ void QgisApp::createActionGroups()
mMapToolGroup->addAction( mActionMeasure );
mActionMeasureArea->setCheckable( true );
mMapToolGroup->addAction( mActionMeasureArea );
mActionMeasureAngle->setCheckable( true );
mMapToolGroup->addAction( mActionMeasureAngle );
mActionCaptureLine->setCheckable( true );
mMapToolGroup->addAction( mActionCaptureLine );
mActionCapturePoint->setCheckable( true );
@@ -1272,6 +1279,7 @@ void QgisApp::createMenus()
mViewMenu->addAction( mActionIdentify );
mViewMenu->addAction( mActionMeasure );
mViewMenu->addAction( mActionMeasureArea );
mViewMenu->addAction( mActionMeasureAngle );
mActionViewSeparator1 = mViewMenu->addSeparator();

mViewMenu->addAction( mActionZoomFullExtent );
@@ -1490,6 +1498,7 @@ void QgisApp::createToolBars()
mAttributesToolBar->addAction( mActionOpenTable );
mAttributesToolBar->addAction( mActionMeasure );
mAttributesToolBar->addAction( mActionMeasureArea );
mAttributesToolBar->addAction( mActionMeasureAngle );
mAttributesToolBar->addAction( mActionMapTips );
mAttributesToolBar->addAction( mActionShowBookmarks );
mAttributesToolBar->addAction( mActionNewBookmark );
@@ -1734,6 +1743,7 @@ void QgisApp::setTheme( QString theThemeName )
mActionOpenTable->setIcon( getThemeIcon( "/mActionOpenTable.png" ) );
mActionMeasure->setIcon( getThemeIcon( "/mActionMeasure.png" ) );
mActionMeasureArea->setIcon( getThemeIcon( "/mActionMeasureArea.png" ) );
mActionMeasureAngle->setIcon( getThemeIcon( "/mActionMeasureAngle.png" ) );
mActionMapTips->setIcon( getThemeIcon( "/mActionMapTips.png" ) );
mActionShowBookmarks->setIcon( getThemeIcon( "/mActionShowBookmarks.png" ) );
mActionNewBookmark->setIcon( getThemeIcon( "/mActionNewBookmark.png" ) );
@@ -1835,6 +1845,8 @@ void QgisApp::createCanvas()
mMapTools.mMeasureDist->setAction( mActionMeasure );
mMapTools.mMeasureArea = new QgsMeasureTool( mMapCanvas, TRUE /* area */ );
mMapTools.mMeasureArea->setAction( mActionMeasureArea );
mMapTools.mMeasureAngle = new QgsMapToolMeasureAngle( mMapCanvas );
mMapTools.mMeasureAngle->setAction( mActionMeasureAngle );
mMapTools.mCapturePoint = new QgsMapToolAddFeature( mMapCanvas, QgsMapToolCapture::CapturePoint );
mMapTools.mCapturePoint->setAction( mActionCapturePoint );
mActionCapturePoint->setVisible( false );
@@ -3508,6 +3520,11 @@ void QgisApp::measureArea()
mMapCanvas->setMapTool( mMapTools.mMeasureArea );
}

void QgisApp::measureAngle()
{
mMapCanvas->setMapTool( mMapTools.mMeasureAngle );
}

void QgisApp::attributeTable()
{
if ( mMapCanvas && mMapCanvas->isDrawing() )
@@ -591,6 +591,8 @@ class QgisApp : public QMainWindow
void measure();
//! Measure area
void measureArea();
//! Measure angle
void measureAngle();

//! show the attribute table for the currently selected layer
void attributeTable();
@@ -798,6 +800,7 @@ class QgisApp : public QMainWindow
QAction *mActionDeselectAll;
QAction *mActionIdentify;
QAction *mActionMeasure;
QAction *mActionMeasureAngle;
QAction *mActionMeasureArea;
QAction *mActionViewSeparator1;
QAction *mActionZoomFullExtent;
@@ -900,6 +903,7 @@ class QgisApp : public QMainWindow
QgsMapTool* mIdentify;
QgsMapTool* mMeasureDist;
QgsMapTool* mMeasureArea;
QgsMapTool* mMeasureAngle;
QgsMapTool* mCapturePoint;
QgsMapTool* mCaptureLine;
QgsMapTool* mCapturePolygon;
@@ -0,0 +1,52 @@
/***************************************************************************
qgsdisplayangle.cpp
------------------------
begin : January 2010
copyright : (C) 2010 by Marco Hugentobler
email : marco at hugis dot net
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsdisplayangle.h"
#include <QSettings>

#ifndef Q_OS_MACX
#include <cmath>
#else
#include <math.h>
#endif

QgsDisplayAngle::QgsDisplayAngle( QWidget * parent, Qt::WindowFlags f ): QDialog( parent, f )
{
setupUi( this );
}

QgsDisplayAngle::~QgsDisplayAngle()
{

}

void QgsDisplayAngle::setValueInRadians( double value )
{
QSettings settings;
QString unitString = settings.value( "/qgis/measure/angleunits", "degrees" ).toString();
if ( unitString == "degrees" )
{
mAngleLineEdit->setText( tr( "%1 degrees" ).arg( value * 180 / M_PI ) );
}
else if ( unitString == "radians" )
{
mAngleLineEdit->setText( tr( "%1 radians" ).arg( value ) );
}
else if ( unitString == "gon" )
{
mAngleLineEdit->setText( tr( "%1 gon" ).arg( value / M_PI * 200 ) );
}
}

@@ -0,0 +1,32 @@
/***************************************************************************
qgsdisplayangle.h
------------------------
begin : January 2010
copyright : (C) 2010 by Marco Hugentobler
email : marco at hugis dot net
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSDISPLAYANGLE_H
#define QGSDISPLAYANGLE_H

#include "ui_qgsdisplayanglebase.h"

/**A class that displays results of angle measurements with the proper unit*/
class QgsDisplayAngle: public QDialog, private Ui::QgsDisplayAngleBase
{
public:
QgsDisplayAngle( QWidget * parent = 0, Qt::WindowFlags f = 0 );
~QgsDisplayAngle();
/**Sets the measured angle value (in radians). The value is going to
be converted to degrees / gon automatically if necessary*/
void setValueInRadians( double value );
};

#endif // QGSDISPLAYANGLE_H
@@ -0,0 +1,154 @@
/***************************************************************************
qgsmaptoolmeasureangle.cpp
--------------------------
begin : December 2009
copyright : (C) 2009 by Marco Hugentobler
email : marco at hugis dot net
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsmaptoolmeasureangle.h"
#include "qgsdisplayangle.h"
#include "qgsdistancearea.h"
#include "qgslogger.h"
#include "qgsmapcanvas.h"
#include "qgsmaptopixel.h"
#include "qgsrubberband.h"
#include <QMouseEvent>
#include <QSettings>

#ifndef Q_OS_MACX
#include <cmath>
#else
#include <math.h>
#endif

QgsMapToolMeasureAngle::QgsMapToolMeasureAngle( QgsMapCanvas* canvas ): QgsMapTool( canvas ), mRubberBand( 0 ), mResultDisplay( 0 )
{
mSnapper.setMapCanvas( canvas );
}

QgsMapToolMeasureAngle::~QgsMapToolMeasureAngle()
{
stopMeasuring();
}

void QgsMapToolMeasureAngle::canvasMoveEvent( QMouseEvent * e )
{
if ( !mRubberBand || mAnglePoints.size() < 1 || mAnglePoints.size() > 2 || !mRubberBand )
{
return;
}

QgsPoint point = snapPoint( e->pos() );
mRubberBand->movePoint( point );
if ( mAnglePoints.size() == 2 )
{
//do angle calculation
QgsDistanceArea* distArea = mCanvas->mapRenderer()->distanceArea();
if ( distArea )
{
double azimutOne = distArea->bearing( mAnglePoints.at( 1 ), mAnglePoints.at( 0 ) );
double azimutTwo = distArea->bearing( mAnglePoints.at( 1 ), point );
double resultAngle = azimutTwo - azimutOne;
QgsDebugMsg( QString::number( fabs( resultAngle ) ) );
QgsDebugMsg( QString::number( M_PI ) );
if ( fabs( resultAngle ) > M_PI )
{
if ( resultAngle < 0 )
{
resultAngle = M_PI + ( resultAngle + M_PI );
}
else
{
resultAngle = -M_PI + ( resultAngle - M_PI );
}
}

//show angle in dialog
if ( !mResultDisplay )
{
mResultDisplay = new QgsDisplayAngle( mCanvas->topLevelWidget() );
QObject::connect( mResultDisplay, SIGNAL( rejected() ), this, SLOT( stopMeasuring() ) );
mResultDisplay->move( e->pos() - QPoint( 100, 100 ) );
}
mResultDisplay->show();
mResultDisplay->setValueInRadians( resultAngle );
}
}
}

void QgsMapToolMeasureAngle::canvasReleaseEvent( QMouseEvent * e )
{
//add points until we have three
if ( mAnglePoints.size() == 3 )
{
mAnglePoints.clear();
}

if ( mAnglePoints.size() < 1 )
{
createRubberBand();
}

if ( mAnglePoints.size() < 3 )
{
QgsPoint newPoint = snapPoint( e->pos() );
mAnglePoints.push_back( newPoint );
mRubberBand->addPoint( newPoint );
}
}

void QgsMapToolMeasureAngle::stopMeasuring()
{
delete mRubberBand;
mRubberBand = 0;
delete mResultDisplay;
mResultDisplay = 0;
mAnglePoints.clear();
}

void QgsMapToolMeasureAngle::activate()
{
QgsMapTool::activate();
}

void QgsMapToolMeasureAngle::deactivate()
{
stopMeasuring();
QgsMapTool::deactivate();
}

void QgsMapToolMeasureAngle::createRubberBand()
{
delete mRubberBand;
mRubberBand = new QgsRubberBand( mCanvas, false );

QSettings settings;
int myRed = settings.value( "/qgis/default_measure_color_red", 180 ).toInt();
int myGreen = settings.value( "/qgis/default_measure_color_green", 180 ).toInt();
int myBlue = settings.value( "/qgis/default_measure_color_blue", 180 ).toInt();
mRubberBand->setColor( QColor( myRed, myGreen, myBlue ) );
}

QgsPoint QgsMapToolMeasureAngle::snapPoint( const QPoint& p )
{
QList<QgsSnappingResult> snappingResults;
if ( mSnapper.snapToBackgroundLayers( p, snappingResults ) != 0 || snappingResults.size() < 1 )
{
return mCanvas->getCoordinateTransform()->toMapCoordinates( p );
}
else
{
return snappingResults.constBegin()->snappedVertex;
}
}



0 comments on commit 82a58ce

Please sign in to comment.
You can’t perform that action at this time.