Skip to content

Commit cd2a18c

Browse files
author
timlinux
committed
Applied patch from ticket #3240 with some tweaks. Allows unprojected measurement of distances
git-svn-id: http://svn.osgeo.org/qgis/trunk@14956 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 0226eea commit cd2a18c

8 files changed

+206
-29
lines changed

src/app/qgsdisplayangle.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,29 @@
2020
QgsDisplayAngle::QgsDisplayAngle( QWidget * parent, Qt::WindowFlags f ): QDialog( parent, f )
2121
{
2222
setupUi( this );
23+
QSettings settings;
24+
int s = settings.value( "/qgis/measure/projectionEnabled", "2" ).toInt();
25+
if ( s == 2 )
26+
mcbProjectionEnabled->setCheckState( Qt::Checked );
27+
else
28+
mcbProjectionEnabled->setCheckState( Qt::Unchecked );
29+
30+
connect( mcbProjectionEnabled, SIGNAL( stateChanged(int) ),
31+
this, SLOT( changeState() ) );
32+
connect( mcbProjectionEnabled, SIGNAL( stateChanged(int) ),
33+
this, SIGNAL( changeProjectionEnabledState() ) );
2334
}
2435

2536
QgsDisplayAngle::~QgsDisplayAngle()
2637
{
2738

2839
}
2940

41+
bool QgsDisplayAngle::projectionEnabled()
42+
{
43+
return mcbProjectionEnabled->isChecked();
44+
}
45+
3046
void QgsDisplayAngle::setValueInRadians( double value )
3147
{
3248
QSettings settings;
@@ -45,3 +61,11 @@ void QgsDisplayAngle::setValueInRadians( double value )
4561
}
4662
}
4763

64+
void QgsDisplayAngle::changeState()
65+
{
66+
QSettings settings;
67+
if ( mcbProjectionEnabled->isChecked() )
68+
settings.setValue( "/qgis/measure/projectionEnabled", 2);
69+
else
70+
settings.setValue( "/qgis/measure/projectionEnabled", 0);
71+
}

src/app/qgsdisplayangle.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ class QgsDisplayAngle: public QDialog, private Ui::QgsDisplayAngleBase
2929
/**Sets the measured angle value (in radians). The value is going to
3030
be converted to degrees / gon automatically if necessary*/
3131
void setValueInRadians( double value );
32+
33+
bool projectionEnabled();
34+
35+
signals:
36+
void changeProjectionEnabledState();
37+
38+
private slots:
39+
void changeState();
40+
3241
};
3342

3443
#endif // QGSDISPLAYANGLE_H

src/app/qgsmaptoolmeasureangle.cpp

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,26 @@ void QgsMapToolMeasureAngle::canvasMoveEvent( QMouseEvent * e )
4949
QgsDistanceArea* distArea = mCanvas->mapRenderer()->distanceArea();
5050
if ( distArea )
5151
{
52-
double azimutOne = distArea->bearing( mAnglePoints.at( 1 ), mAnglePoints.at( 0 ) );
53-
double azimutTwo = distArea->bearing( mAnglePoints.at( 1 ), point );
54-
double resultAngle = azimutTwo - azimutOne;
52+
//show angle in dialog
53+
if ( !mResultDisplay )
54+
{
55+
mResultDisplay = new QgsDisplayAngle( mCanvas->topLevelWidget() );
56+
QObject::connect( mResultDisplay, SIGNAL( rejected() ), this, SLOT( stopMeasuring() ) );
57+
QObject::connect( mResultDisplay, SIGNAL( changeProjectionEnabledState() ),
58+
this, SLOT( changeProjectionEnabledState() ) );
59+
mResultDisplay->move( e->pos() - QPoint( 100, 100 ) );
60+
}
61+
mResultDisplay->show();
62+
63+
QgsDistanceArea myDa;
64+
myDa.setSourceCrs( mCanvas->mapRenderer()->destinationSrs().srsid() );
65+
myDa.setEllipsoid( distArea->ellipsoid() );
66+
myDa.setProjectionsEnabled( mResultDisplay->projectionEnabled() );
67+
68+
//angle calculation
69+
double azimuthOne = myDa.bearing( mAnglePoints.at( 1 ), mAnglePoints.at( 0 ) );
70+
double azimuthTwo = myDa.bearing( mAnglePoints.at( 1 ), point );
71+
double resultAngle = azimuthTwo - azimuthOne;
5572
QgsDebugMsg( QString::number( qAbs( resultAngle ) ) );
5673
QgsDebugMsg( QString::number( M_PI ) );
5774
if ( qAbs( resultAngle ) > M_PI )
@@ -66,14 +83,6 @@ void QgsMapToolMeasureAngle::canvasMoveEvent( QMouseEvent * e )
6683
}
6784
}
6885

69-
//show angle in dialog
70-
if ( !mResultDisplay )
71-
{
72-
mResultDisplay = new QgsDisplayAngle( mCanvas->topLevelWidget() );
73-
QObject::connect( mResultDisplay, SIGNAL( rejected() ), this, SLOT( stopMeasuring() ) );
74-
mResultDisplay->move( e->pos() - QPoint( 100, 100 ) );
75-
}
76-
mResultDisplay->show();
7786
mResultDisplay->setValueInRadians( resultAngle );
7887
}
7988
}
@@ -145,5 +154,36 @@ QgsPoint QgsMapToolMeasureAngle::snapPoint( const QPoint& p )
145154
}
146155
}
147156

157+
void QgsMapToolMeasureAngle::changeProjectionEnabledState()
158+
{
159+
if ( mAnglePoints.size() != 3 )
160+
return;
161+
if ( !mResultDisplay )
162+
return;
163+
164+
QgsDistanceArea myDa;
165+
myDa.setSourceCrs( mCanvas->mapRenderer()->destinationSrs().srsid() );
166+
myDa.setEllipsoid( mCanvas->mapRenderer()->distanceArea()->ellipsoid() );
167+
myDa.setProjectionsEnabled( mResultDisplay->projectionEnabled() );
168+
169+
//angle calculation
170+
double azimuthOne = myDa.bearing( mAnglePoints.at( 1 ), mAnglePoints.at( 0 ) );
171+
double azimuthTwo = myDa.bearing( mAnglePoints.at( 1 ), mAnglePoints.at( 2 ) );
172+
double resultAngle = azimuthTwo - azimuthOne;
173+
QgsDebugMsg( QString::number( fabs( resultAngle ) ) );
174+
QgsDebugMsg( QString::number( M_PI ) );
175+
if ( fabs( resultAngle ) > M_PI )
176+
{
177+
if ( resultAngle < 0 )
178+
{
179+
resultAngle = M_PI + ( resultAngle + M_PI );
180+
}
181+
else
182+
{
183+
resultAngle = -M_PI + ( resultAngle - M_PI );
184+
}
185+
}
186+
mResultDisplay->setValueInRadians( resultAngle );
148187

188+
}
149189

src/app/qgsmaptoolmeasureangle.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ class QgsMapToolMeasureAngle: public QgsMapTool
5959
/**Deletes the rubber band and the dialog*/
6060
void stopMeasuring();
6161

62+
/** recalculate angle if projection state changed*/
63+
void changeProjectionEnabledState();
64+
6265
};
6366

6467
#endif // QGSMAPTOOLMEASUREANGLE_H

src/app/qgsmeasuredialog.cpp

Lines changed: 92 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,14 @@ QgsMeasureDialog::QgsMeasureDialog( QgsMeasureTool* tool, Qt::WFlags f )
5252
//mTable->setHeaderLabels(QStringList() << tr("Segments (in meters)") << tr("Total") << tr("Azimuth") );
5353

5454
QSettings settings;
55+
int s = settings.value( "/qgis/measure/projectionEnabled", "2" ).toInt();
56+
if ( s == 2 )
57+
mcbProjectionEnabled->setCheckState( Qt::Checked );
58+
else
59+
mcbProjectionEnabled->setCheckState( Qt::Unchecked );
5560

61+
connect( mcbProjectionEnabled, SIGNAL( stateChanged(int) ),
62+
this, SLOT( changeProjectionEnabledState() ));
5663

5764
updateUi();
5865
}
@@ -91,21 +98,27 @@ void QgsMeasureDialog::mouseMove( QgsPoint &point )
9198
QSettings settings;
9299
int decimalPlaces = settings.value( "/qgis/measure/decimalplaces", "3" ).toInt();
93100

101+
// Create QgsDistance Area for customization ProjectionEnabled setting
102+
QgsDistanceArea myDa;
103+
myDa.setSourceCrs( mTool->canvas()->mapRenderer()->destinationSrs().srsid() );
104+
myDa.setEllipsoid( mTool->canvas()->mapRenderer()->distanceArea()->ellipsoid() );
105+
myDa.setProjectionsEnabled( mcbProjectionEnabled->isChecked() );
106+
94107
// show current distance/area while moving the point
95108
// by creating a temporary copy of point array
96-
// and adding moving point at the end
109+
// and adding moving point at the end
97110
if ( mMeasureArea && mTool->points().size() > 1 )
98111
{
99112
QList<QgsPoint> tmpPoints = mTool->points();
100113
tmpPoints.append( point );
101-
double area = mTool->canvas()->mapRenderer()->distanceArea()->measurePolygon( tmpPoints );
114+
double area = myDa.measurePolygon( tmpPoints );
102115
editTotal->setText( formatArea( area, decimalPlaces ) );
103116
}
104117
else if ( !mMeasureArea && mTool->points().size() > 0 )
105118
{
106119
QgsPoint p1( mTool->points().last() ), p2( point );
107120

108-
double d = mTool->canvas()->mapRenderer()->distanceArea()->measureLine( p1, p2 );
121+
double d = myDa.measureLine( p1, p2 );
109122
editTotal->setText( formatDistance( mTotal + d, decimalPlaces ) );
110123
QGis::UnitType myDisplayUnits;
111124
// Ignore units
@@ -120,10 +133,16 @@ void QgsMeasureDialog::addPoint( QgsPoint &point )
120133
QSettings settings;
121134
int decimalPlaces = settings.value( "/qgis/measure/decimalplaces", "3" ).toInt();
122135

136+
// Create QgsDistance Area for customization ProjectionEnabled setting
137+
QgsDistanceArea myDa;
138+
myDa.setSourceCrs( mTool->canvas()->mapRenderer()->destinationSrs().srsid() );
139+
myDa.setEllipsoid( mTool->canvas()->mapRenderer()->distanceArea()->ellipsoid() );
140+
myDa.setProjectionsEnabled( mcbProjectionEnabled->isChecked() );
141+
123142
int numPoints = mTool->points().size();
124143
if ( mMeasureArea && numPoints > 2 )
125144
{
126-
double area = mTool->canvas()->mapRenderer()->distanceArea()->measurePolygon( mTool->points() );
145+
double area = myDa.measurePolygon( mTool->points() );
127146
editTotal->setText( formatArea( area, decimalPlaces ) );
128147
}
129148
else if ( !mMeasureArea && numPoints > 1 )
@@ -132,7 +151,7 @@ void QgsMeasureDialog::addPoint( QgsPoint &point )
132151

133152
QgsPoint p1 = mTool->points()[last], p2 = mTool->points()[last+1];
134153

135-
double d = mTool->canvas()->mapRenderer()->distanceArea()->measureLine( p1, p2 );
154+
double d = myDa.measureLine( p1, p2 );
136155

137156
mTotal += d;
138157
editTotal->setText( formatDistance( mTotal, decimalPlaces ) );
@@ -252,17 +271,17 @@ void QgsMeasureDialog::convertMeasurement( double &measure, QGis::UnitType &u, b
252271
QGis::UnitType myUnits = mTool->canvas()->mapUnits();
253272
if (( myUnits == QGis::Degrees || myUnits == QGis::Feet ) &&
254273
mTool->canvas()->mapRenderer()->distanceArea()->ellipsoid() != "NONE" &&
255-
mTool->canvas()->mapRenderer()->distanceArea()->hasCrsTransformEnabled() )
274+
mcbProjectionEnabled->isChecked() )
256275
{
257276
// Measuring on an ellipsoid returns meters, and so does using projections???
258277
myUnits = QGis::Meters;
259278
QgsDebugMsg( "We're measuring on an ellipsoid or using projections, the system is returning meters" );
260279
}
261-
280+
262281
// Get the units for display
263282
QSettings settings;
264283
QString myDisplayUnitsTxt = settings.value( "/qgis/measure/displayunits", "meters" ).toString();
265-
284+
266285
// Only convert between meters and feet
267286
if ( myUnits == QGis::Meters && myDisplayUnitsTxt == "feet" )
268287
{
@@ -289,3 +308,68 @@ void QgsMeasureDialog::convertMeasurement( double &measure, QGis::UnitType &u, b
289308

290309
u = myUnits;
291310
}
311+
312+
void QgsMeasureDialog::changeProjectionEnabledState()
313+
{
314+
// store value
315+
QSettings settings;
316+
if ( mcbProjectionEnabled->isChecked() )
317+
settings.setValue( "/qgis/measure/projectionEnabled", 2);
318+
else
319+
settings.setValue( "/qgis/measure/projectionEnabled", 0);
320+
321+
// clear interface
322+
mTable->clear();
323+
QTreeWidgetItem* item = new QTreeWidgetItem( QStringList( QString::number( 0, 'f', 1 ) ) );
324+
item->setTextAlignment( 0, Qt::AlignRight );
325+
mTable->addTopLevelItem( item );
326+
mTotal = 0;
327+
updateUi();
328+
329+
int decimalPlaces = settings.value( "/qgis/measure/decimalplaces", "3" ).toInt();
330+
331+
// create DistanceArea
332+
QgsDistanceArea myDa;
333+
myDa.setSourceCrs( mTool->canvas()->mapRenderer()->destinationSrs().srsid() );
334+
myDa.setEllipsoid( mTool->canvas()->mapRenderer()->distanceArea()->ellipsoid() );
335+
myDa.setProjectionsEnabled( mcbProjectionEnabled->isChecked() );
336+
337+
if ( mMeasureArea )
338+
{
339+
double area = 0.0;
340+
if ( mTool->points().size() > 1 )
341+
{
342+
area = myDa.measurePolygon( mTool->points() );
343+
}
344+
editTotal->setText( formatArea( area, decimalPlaces ) );
345+
}else
346+
{
347+
QList<QgsPoint>::const_iterator it;
348+
bool b = true; // first point
349+
350+
QgsPoint p1,p2;
351+
352+
for (it=mTool->points().constBegin(); it != mTool->points().constEnd(); ++it)
353+
{
354+
p2 = *it;
355+
if ( !b )
356+
{
357+
double d = myDa.measureLine( p1, p2 );
358+
mTotal += d;
359+
editTotal->setText( formatDistance( mTotal, decimalPlaces ) );
360+
QGis::UnitType myDisplayUnits;
361+
362+
convertMeasurement( d, myDisplayUnits, false );
363+
364+
QTreeWidgetItem *item = mTable->topLevelItem( mTable->topLevelItemCount() - 1 );
365+
item->setText( 0, QLocale::system().toString( d, 'f', decimalPlaces ) );
366+
item = new QTreeWidgetItem( QStringList( QLocale::system().toString( 0.0, 'f', decimalPlaces ) ) );
367+
item->setTextAlignment( 0, Qt::AlignRight );
368+
mTable->addTopLevelItem( item );
369+
mTable->scrollToItem( item );
370+
}
371+
p1 = p2;
372+
b = false;
373+
}
374+
}
375+
}

src/app/qgsmeasuredialog.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ class QgsMeasureDialog : public QDialog, private Ui::QgsMeasureBase
6262

6363
//! Show the help for the dialog
6464
void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
65+
private slots:
66+
//! on change state projection enable
67+
void changeProjectionEnabledState();
6568

6669
private:
6770

src/ui/qgsdisplayanglebase.ui

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,22 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>276</width>
10-
<height>78</height>
9+
<width>293</width>
10+
<height>105</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
1414
<string>Angle</string>
1515
</property>
1616
<layout class="QGridLayout" name="gridLayout">
17-
<item row="0" column="0" colspan="2">
17+
<item row="1" column="0" colspan="2">
1818
<widget class="QLineEdit" name="mAngleLineEdit">
1919
<property name="readOnly">
2020
<bool>true</bool>
2121
</property>
2222
</widget>
2323
</item>
24-
<item row="1" column="0">
24+
<item row="2" column="0">
2525
<spacer name="horizontalSpacer">
2626
<property name="orientation">
2727
<enum>Qt::Horizontal</enum>
@@ -34,7 +34,7 @@
3434
</property>
3535
</spacer>
3636
</item>
37-
<item row="1" column="1">
37+
<item row="2" column="1">
3838
<widget class="QDialogButtonBox" name="buttonBox">
3939
<property name="orientation">
4040
<enum>Qt::Horizontal</enum>
@@ -44,6 +44,13 @@
4444
</property>
4545
</widget>
4646
</item>
47+
<item row="0" column="0">
48+
<widget class="QCheckBox" name="mcbProjectionEnabled">
49+
<property name="text">
50+
<string>Ellipsoidal (WGS84)</string>
51+
</property>
52+
</widget>
53+
</item>
4754
</layout>
4855
</widget>
4956
<resources/>

0 commit comments

Comments
 (0)