Skip to content

Commit fbc22e2

Browse files
lbartolettinyalldawson
authored andcommitted
[feature] Add an option to cartesian measurement
Adds an option force Cartesian measurements to the measure distance/area dialogue Fixes #19902
1 parent db1a192 commit fbc22e2

File tree

4 files changed

+221
-59
lines changed

4 files changed

+221
-59
lines changed

src/app/qgsmeasuredialog.cpp

+58-45
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,27 @@ QgsMeasureDialog::QgsMeasureDialog( QgsMeasureTool *tool, Qt::WindowFlags f )
7979
connect( mUnitsCombo, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsMeasureDialog::unitsChanged );
8080
connect( buttonBox, &QDialogButtonBox::rejected, this, &QgsMeasureDialog::reject );
8181
connect( mCanvas, &QgsMapCanvas::destinationCrsChanged, this, &QgsMeasureDialog::crsChanged );
82+
connect( mCartesian, &QRadioButton::toggled, this, &QgsMeasureDialog::projChanged );
8283

8384
groupBox->setCollapsed( true );
8485
}
8586

87+
void QgsMeasureDialog::projChanged()
88+
{
89+
if ( mCartesian->isChecked() )
90+
{
91+
mDa.setEllipsoid( GEO_NONE );
92+
}
93+
else
94+
{
95+
mDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
96+
}
97+
98+
mTable->clear();
99+
mTotal = 0.;
100+
updateUi();
101+
}
102+
86103
void QgsMeasureDialog::openConfigTab()
87104
{
88105
QgisApp::instance()->showOptionsDialog( this, QStringLiteral( "mOptionsPageMapTools" ) );
@@ -102,6 +119,9 @@ void QgsMeasureDialog::crsChanged()
102119
{
103120
mUnitsCombo->setEnabled( true );
104121
}
122+
123+
mTable->clear();
124+
mTotal = 0.;
105125
updateUi();
106126
}
107127

@@ -116,23 +136,18 @@ void QgsMeasureDialog::updateSettings()
116136
mMapDistanceUnits = QgsProject::instance()->crs().mapUnits();
117137
mAreaUnits = QgsProject::instance()->areaUnits();
118138
mDa.setSourceCrs( mCanvas->mapSettings().destinationCrs(), QgsProject::instance()->transformContext() );
119-
mDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
139+
projChanged();
120140

121-
mTable->clear();
122-
mTotal = 0;
123-
updateUi();
124141

125-
if ( !mCanvas->mapSettings().destinationCrs().isValid() ||
142+
if ( mCartesian->isChecked() || !mCanvas->mapSettings().destinationCrs().isValid() ||
126143
( mCanvas->mapSettings().destinationCrs().mapUnits() == QgsUnitTypes::DistanceDegrees
127144
&& mDistanceUnits == QgsUnitTypes::DistanceDegrees ) )
128145
{
129146
mDa.setEllipsoid( GEO_NONE );
130-
mForceCartesian = true;
131147
}
132148
else
133149
{
134150
mDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
135-
mForceCartesian = false;
136151
}
137152
}
138153

@@ -164,6 +179,7 @@ void QgsMeasureDialog::unitsChanged( int index )
164179
mUseMapUnits = false;
165180
}
166181
}
182+
167183
mTable->clear();
168184
mTotal = 0.;
169185
updateUi();
@@ -188,19 +204,6 @@ void QgsMeasureDialog::restart()
188204

189205
void QgsMeasureDialog::mouseMove( const QgsPointXY &point )
190206
{
191-
if ( !mCanvas->mapSettings().destinationCrs().isValid() ||
192-
( mCanvas->mapSettings().destinationCrs().mapUnits() == QgsUnitTypes::DistanceDegrees
193-
&& mDistanceUnits == QgsUnitTypes::DistanceDegrees ) )
194-
{
195-
mDa.setEllipsoid( GEO_NONE );
196-
mForceCartesian = true;
197-
}
198-
else
199-
{
200-
mDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
201-
mForceCartesian = false;
202-
}
203-
204207
mLastMousePoint = point;
205208
// show current distance/area while moving the point
206209
// by creating a temporary copy of point array
@@ -217,9 +220,8 @@ void QgsMeasureDialog::mouseMove( const QgsPointXY &point )
217220
QVector< QgsPointXY > tmpPoints = mTool->points();
218221
QgsPointXY p1( tmpPoints.at( tmpPoints.size() - 1 ) ), p2( point );
219222
double d = mDa.measureLine( p1, p2 );
220-
editTotal->setText( formatDistance( mTotal + d, !mForceCartesian ) );
221-
if ( !mForceCartesian )
222-
d = convertLength( d, mDistanceUnits );
223+
editTotal->setText( formatDistance( mTotal + d, mConvertToDisplayUnits ) );
224+
d = convertLength( d, mDistanceUnits );
223225

224226
// Set moving
225227
QTreeWidgetItem *item = mTable->topLevelItem( mTable->topLevelItemCount() - 1 );
@@ -250,7 +252,7 @@ void QgsMeasureDialog::addPoint()
250252
if ( numPoints > 1 )
251253
{
252254
mTotal = mDa.measureLine( mTool->points() );
253-
editTotal->setText( formatDistance( mTotal, !mForceCartesian ) );
255+
editTotal->setText( formatDistance( mTotal, mConvertToDisplayUnits ) );
254256
}
255257
}
256258
}
@@ -294,7 +296,7 @@ void QgsMeasureDialog::removeLastPoint()
294296
}
295297
else
296298
{
297-
editTotal->setText( formatDistance( mTotal, !mForceCartesian ) );
299+
editTotal->setText( formatDistance( mTotal, mConvertToDisplayUnits ) );
298300
}
299301
}
300302
}
@@ -359,19 +361,25 @@ void QgsMeasureDialog::updateUi()
359361
QString toolTip = tr( "The calculations are based on:" );
360362

361363
mDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
362-
mForceCartesian = false;
363-
bool convertToDisplayUnits = true;
364+
mConvertToDisplayUnits = true;
364365

365366
if ( mMeasureArea )
366367
{
367-
if ( !mCanvas->mapSettings().destinationCrs().isValid() )
368+
if ( mCartesian->isChecked() || !mCanvas->mapSettings().destinationCrs().isValid() )
368369
{
369-
// no CRS => no units, newb!
370-
toolTip += "<br> * " + tr( "No map projection set, so area is calculated using Cartesian calculations." );
371-
toolTip += "<br> * " + tr( "Units are unknown." );
370+
toolTip += "<br> * ";
371+
if ( mCartesian->isChecked() )
372+
{
373+
toolTip += tr( "Cartesian calculation selected, so area is calculated using Cartesian calculations." );
374+
mConvertToDisplayUnits = true;
375+
}
376+
else
377+
{
378+
toolTip += tr( "No map projection set, so area is calculated using Cartesian calculations." );
379+
toolTip += "<br> * " + tr( "Units are unknown." );
380+
mConvertToDisplayUnits = false;
381+
}
372382
mDa.setEllipsoid( GEO_NONE );
373-
mForceCartesian = true;
374-
convertToDisplayUnits = false;
375383
}
376384
else if ( mCanvas->mapSettings().destinationCrs().mapUnits() == QgsUnitTypes::DistanceDegrees
377385
&& ( mAreaUnits == QgsUnitTypes::AreaSquareDegrees || mAreaUnits == QgsUnitTypes::AreaUnknownUnit ) )
@@ -380,8 +388,7 @@ void QgsMeasureDialog::updateUi()
380388
toolTip += "<br> * " + tr( "Both project CRS (%1) and measured area are in degrees, so area is calculated using Cartesian calculations in square degrees." ).arg(
381389
mCanvas->mapSettings().destinationCrs().description() );
382390
mDa.setEllipsoid( GEO_NONE );
383-
mForceCartesian = true;
384-
convertToDisplayUnits = false; //not required since we will be measuring in degrees
391+
mConvertToDisplayUnits = false; //not required since we will be measuring in degrees
385392
}
386393
else
387394
{
@@ -436,14 +443,21 @@ void QgsMeasureDialog::updateUi()
436443
}
437444
else
438445
{
439-
if ( !mCanvas->mapSettings().destinationCrs().isValid() )
446+
if ( mCartesian->isChecked() || !mCanvas->mapSettings().destinationCrs().isValid() )
440447
{
441-
// no CRS => no units, newb!
442-
toolTip += "<br> * " + tr( "No map projection set, so distance is calculated using Cartesian calculations." );
443-
toolTip += "<br> * " + tr( "Units are unknown." );
448+
toolTip += "<br> * ";
449+
if ( mCartesian->isChecked() )
450+
{
451+
toolTip += tr( "Cartesian calculation selected, so area is calculated using Cartesian calculations." );
452+
mConvertToDisplayUnits = true;
453+
}
454+
else
455+
{
456+
toolTip += tr( "No map projection set, so area is calculated using Cartesian calculations." );
457+
toolTip += "<br> * " + tr( "Units are unknown." );
458+
mConvertToDisplayUnits = false;
459+
}
444460
mDa.setEllipsoid( GEO_NONE );
445-
mForceCartesian = true;
446-
convertToDisplayUnits = false;
447461
}
448462
else if ( mCanvas->mapSettings().destinationCrs().mapUnits() == QgsUnitTypes::DistanceDegrees
449463
&& mDistanceUnits == QgsUnitTypes::DistanceDegrees )
@@ -452,8 +466,7 @@ void QgsMeasureDialog::updateUi()
452466
toolTip += "<br> * " + tr( "Both project CRS (%1) and measured length are in degrees, so distance is calculated using Cartesian calculations in degrees." ).arg(
453467
mCanvas->mapSettings().destinationCrs().description() );
454468
mDa.setEllipsoid( GEO_NONE );
455-
mForceCartesian = true;
456-
convertToDisplayUnits = false; //not required since we will be measuring in degrees
469+
mConvertToDisplayUnits = false; //not required since we will be measuring in degrees
457470
}
458471
else
459472
{
@@ -560,7 +573,7 @@ void QgsMeasureDialog::updateUi()
560573
{
561574
double d = -1;
562575
d = mDa.measureLine( p1, p2 );
563-
if ( !mForceCartesian )
576+
if ( mConvertToDisplayUnits )
564577
{
565578
if ( mDistanceUnits == QgsUnitTypes::DistanceUnknownUnit && mMapDistanceUnits != QgsUnitTypes::DistanceUnknownUnit )
566579
d = convertLength( d, mMapDistanceUnits );
@@ -579,7 +592,7 @@ void QgsMeasureDialog::updateUi()
579592

580593
mTotal = mDa.measureLine( mTool->points() );
581594
mTable->show(); // Show the table with items
582-
editTotal->setText( formatDistance( mTotal, convertToDisplayUnits ) );
595+
editTotal->setText( formatDistance( mTotal, mConvertToDisplayUnits ) );
583596
}
584597
}
585598

src/app/qgsmeasuredialog.h

+4-5
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ class APP_EXPORT QgsMeasureDialog : public QDialog, private Ui::QgsMeasureBase
7272

7373
void crsChanged();
7474

75+
void projChanged();
76+
7577
private:
7678

7779
//! formats distance to most appropriate units
@@ -101,11 +103,8 @@ class APP_EXPORT QgsMeasureDialog : public QDialog, private Ui::QgsMeasureBase
101103
//! Indicates whether the user chose "Map units" instead of directly selecting a unit
102104
bool mUseMapUnits = false;
103105

104-
/**
105-
* Indicates whether we need to measure distances in Cartesian instead of
106-
* spherical coordinates, such as when measuring in degrees in a geographic CRS
107-
*/
108-
bool mForceCartesian = true;
106+
//! Indicates whether we need to convert units.
107+
bool mConvertToDisplayUnits = true;
109108

110109
//! Number of decimal places we want.
111110
int mDecimalPlaces = 3;

src/ui/qgsmeasurebase.ui

+24-5
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
</property>
2222
<property name="windowIcon">
2323
<iconset>
24-
<normaloff/>
25-
</iconset>
24+
<normaloff>.</normaloff>.</iconset>
2625
</property>
2726
<layout class="QGridLayout">
2827
<property name="leftMargin">
@@ -101,19 +100,19 @@
101100
<string>Segments</string>
102101
</property>
103102
<property name="textAlignment">
104-
<set>AlignRight|AlignVCenter</set>
103+
<set>AlignTrailing|AlignVCenter</set>
105104
</property>
106105
</column>
107106
</widget>
108107
</item>
109-
<item row="6" column="0" colspan="4">
108+
<item row="7" column="0" colspan="4">
110109
<widget class="QDialogButtonBox" name="buttonBox">
111110
<property name="standardButtons">
112111
<set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
113112
</property>
114113
</widget>
115114
</item>
116-
<item row="5" column="0" colspan="4">
115+
<item row="6" column="0" colspan="4">
117116
<widget class="QgsCollapsibleGroupBox" name="groupBox">
118117
<property name="title">
119118
<string>Info</string>
@@ -132,6 +131,26 @@
132131
</layout>
133132
</widget>
134133
</item>
134+
<item row="5" column="0">
135+
<widget class="QRadioButton" name="mCartesian">
136+
<property name="text">
137+
<string>Cartesian</string>
138+
</property>
139+
<property name="checked">
140+
<bool>false</bool>
141+
</property>
142+
</widget>
143+
</item>
144+
<item row="5" column="2">
145+
<widget class="QRadioButton" name="mEllipsoidal">
146+
<property name="text">
147+
<string>Ellipsoidal</string>
148+
</property>
149+
<property name="checked">
150+
<bool>true</bool>
151+
</property>
152+
</widget>
153+
</item>
135154
</layout>
136155
</widget>
137156
<layoutdefault spacing="6" margin="11"/>

0 commit comments

Comments
 (0)