Skip to content

Commit caed3a9

Browse files
committed
choose system of measurement for scalebar or position
1 parent 54a5059 commit caed3a9

11 files changed

+283
-37
lines changed

python/core/auto_generated/qgsunittypes.sip.in

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ Helper functions for various unit types.
2626
static const QMetaObject staticMetaObject;
2727

2828
public:
29+
enum SystemOfMeasurement
30+
{
31+
UnknownSystem,
32+
MetricSystem,
33+
ImperialSystem,
34+
USCSSystem
35+
};
36+
2937
enum DistanceUnit
3038
{
3139
DistanceMeters,

src/core/qgsunittypes.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ class CORE_EXPORT QgsUnitTypes
3939
Q_GADGET
4040

4141
public:
42+
enum SystemOfMeasurement
43+
{
44+
UnknownSystem = 0, //!< Unknown system of measurement
45+
MetricSystem, //!< International System of Units (SI)
46+
ImperialSystem, //!< British Imperial
47+
USCSSystem //!< United States customary system
48+
};
49+
4250
//! Units of distance
4351
enum DistanceUnit
4452
{

src/quickgui/plugin/qgsquickplugin.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ void QgsQuickPlugin::registerTypes( const char *uri )
6161
qRegisterMetaType< QgsPoint >( "QgsPoint" );
6262
qRegisterMetaType< QgsPointXY >( "QgsPointXY" );
6363
qRegisterMetaType< QgsQuickFeatureLayerPair >( "QgsQuickFeatureLayerPair" );
64+
qRegisterMetaType< QgsUnitTypes::SystemOfMeasurement >( "QgsUnitTypes::SystemOfMeasurement" );
6465
qRegisterMetaType< QgsUnitTypes::DistanceUnit >( "QgsUnitTypes::DistanceUnit" );
6566
qRegisterMetaType< QgsCoordinateFormatter::FormatFlags >( "QgsCoordinateFormatter::FormatFlags" );
6667
qRegisterMetaType< QgsCoordinateFormatter::Format >( "QgsCoordinateFormatter::Format" );

src/quickgui/plugin/qgsquickscalebar.qml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ Item {
3232
* representation
3333
*/
3434
property alias preferredWidth: scaleBarKit.preferredWidth
35+
/**
36+
* Preferred system of measurement for the resulting distance. Default is metric system
37+
*/
38+
property alias systemOfMeasurement: scaleBarKit.systemOfMeasurement
3539
/**
3640
* Kit for all calculation of width and text of the scalebar
3741
*

src/quickgui/qgsquickpositionkit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ class QUICK_EXPORT QgsQuickPositionKit : public QObject
162162
/**
163163
* Coordinate reference system of position - WGS84 (constant)
164164
*/
165-
QgsCoordinateReferenceSystem positionCRS() const;
165+
Q_INVOKABLE QgsCoordinateReferenceSystem positionCRS() const;
166166

167167
/**
168168
* Use simulated GPS source.

src/quickgui/qgsquickscalebarkit.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,14 @@ void QgsQuickScaleBarKit::updateScaleBar()
8282
if ( !mMapSettings )
8383
return;
8484

85-
double dist = QgsQuickUtils().screenUnitsToMeters( mMapSettings, mPreferredWidth ); // meters
86-
if ( dist > 1000.0 )
87-
{
88-
dist = dist / 1000.0; // meters to kilometers
89-
mUnits = QgsUnitTypes::toAbbreviatedString( QgsUnitTypes::DistanceKilometers );
90-
}
91-
else
92-
{
93-
mUnits = QgsUnitTypes::toAbbreviatedString( QgsUnitTypes::DistanceMeters );
94-
}
85+
double distInMeters = QgsQuickUtils().screenUnitsToMeters( mMapSettings, mPreferredWidth ); // meters
86+
double dist;
87+
QgsUnitTypes::DistanceUnit distUnits;
88+
QgsQuickUtils().humanReadableDistance( distInMeters, QgsUnitTypes::DistanceMeters,
89+
mSystemOfMeasurement,
90+
dist, distUnits );
91+
92+
mUnits = QgsUnitTypes::toAbbreviatedString( distUnits );
9593

9694
// we want to show nice round distances e.g. 200 km instead of e.g. 273 km
9795
// so we determine which "nice" number to use and also update the scale bar

src/quickgui/qgsquickscalebarkit.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ class QgsQuickMapSettings;
3737
* distance in meters or kilometers (int) rounded to "nice" number (e.g. 72.4 to 100)
3838
* and units text (e.g. km)
3939
*
40+
* System of measurement for result could be set too, so for example the resulting scalebar
41+
* can show results in the imperial units.
42+
*
4043
* \note QML Type: ScaleBarKit
4144
*
4245
* \since QGIS 3.2
@@ -56,12 +59,19 @@ class QUICK_EXPORT QgsQuickScaleBarKit : public QObject
5659
Q_PROPERTY( int preferredWidth MEMBER mPreferredWidth NOTIFY preferredWidthChanged )
5760

5861
/**
59-
* Units of distance (e.g. km or m) Read-only (result).
62+
* Preferred system of measurement for the result
63+
*/
64+
Q_PROPERTY( QgsUnitTypes::SystemOfMeasurement systemOfMeasurement MEMBER mSystemOfMeasurement NOTIFY systemOfMeasurementChanged )
65+
66+
/**
67+
* Units of distance (e.g. km or m) of result in desired systemOfMeasurement Read-only (result).
6068
*/
6169
Q_PROPERTY( QString units READ units NOTIFY scaleBarChanged )
6270

6371
/**
64-
* Distance rounded to "nice" number (e.g. 100, 20) corresponding to width. To be used with units property for labels. Read-only (result).
72+
* Distance rounded to "nice" number (e.g. 100, 20) corresponding to width and system of measurement
73+
*
74+
* To be used with units property for labels. Read-only (result).
6575
*/
6676
Q_PROPERTY( int distance READ distance NOTIFY scaleBarChanged )
6777

@@ -107,6 +117,9 @@ class QUICK_EXPORT QgsQuickScaleBarKit : public QObject
107117
//! \copydoc QgsQuickScaleBarKit::preferredWidth
108118
void preferredWidthChanged();
109119

120+
//! \copydoc QgsQuickScaleBarKit::systemOfMeasurement
121+
void systemOfMeasurementChanged();
122+
110123
public slots:
111124
//! recalculate width, distance and units.
112125
void updateScaleBar();
@@ -116,7 +129,8 @@ class QUICK_EXPORT QgsQuickScaleBarKit : public QObject
116129
int mPreferredWidth; // pixels
117130
int mWidth; // pixels
118131
int mDistance; // in meters or kilometers, rounded
119-
QString mUnits; // km or m
132+
QString mUnits; // e.g. km or m
133+
QgsUnitTypes::SystemOfMeasurement mSystemOfMeasurement = QgsUnitTypes::MetricSystem;
120134
};
121135

122136

src/quickgui/qgsquickutils.cpp

Lines changed: 151 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,27 @@ QgsQuickFeatureLayerPair QgsQuickUtils::featureFactory( const QgsFeature &featur
9494
return QgsQuickFeatureLayerPair( feature, layer );
9595
}
9696

97-
QUrl QgsQuickUtils::getThemeIcon( const QString &name )
97+
const QUrl QgsQuickUtils::getThemeIcon( const QString &name ) const
98+
{
9899
QString path = QStringLiteral( "qrc:/%1.svg" ).arg( name );
99100
QgsDebugMsg( QStringLiteral( "Using icon %1 from %2" ).arg( name, path ) );
100101
return QUrl( path );
101102
}
102103

104+
QgsUnitTypes::SystemOfMeasurement QgsQuickUtils::systemOfMeasurementFactory( const QString &type )
105+
{
106+
if ( type == QStringLiteral( "Metric" ) )
107+
return QgsUnitTypes::MetricSystem;
108+
109+
if ( type == QStringLiteral( "Imperial" ) )
110+
return QgsUnitTypes::ImperialSystem;
111+
112+
if ( type == QStringLiteral( "USCS" ) )
113+
return QgsUnitTypes::USCSSystem;
114+
115+
return QgsUnitTypes::UnknownSystem;
116+
}
117+
103118
QString QgsQuickUtils::formatPoint(
104119
const QgsPoint &point,
105120
QgsCoordinateFormatter::Format format,
@@ -109,30 +124,151 @@ QString QgsQuickUtils::formatPoint(
109124
return QgsCoordinateFormatter::format( point, format, decimals, flags );
110125
}
111126

112-
QString QgsQuickUtils::formatDistance( double distance, QgsUnitTypes::DistanceUnit units, int decimals )
127+
QString QgsQuickUtils::formatDistance( double distance,
128+
QgsUnitTypes::DistanceUnit units,
129+
int decimals,
130+
QgsUnitTypes::SystemOfMeasurement destSystem )
113131
{
114-
double dist = distance * QgsUnitTypes::fromUnitToUnitFactor( units, QgsUnitTypes::DistanceMeters );
132+
double destDistance;
133+
QgsUnitTypes::DistanceUnit destUnits;
134+
135+
humanReadableDistance( distance, units, destSystem, destDistance, destUnits );
136+
137+
return QStringLiteral( "%1 %2" )
138+
.arg( QString::number( destDistance, 'f', decimals ) )
139+
.arg( QgsUnitTypes::toAbbreviatedString( destUnits ) );
140+
}
141+
142+
143+
void QgsQuickUtils::humanReadableDistance( double srcDistance, QgsUnitTypes::DistanceUnit srcUnits,
144+
QgsUnitTypes::SystemOfMeasurement destSystem,
145+
double &destDistance, QgsUnitTypes::DistanceUnit &destUnits )
146+
{
147+
if ( ( destSystem == QgsUnitTypes::MetricSystem ) || ( destSystem == QgsUnitTypes::UnknownSystem ) )
148+
{
149+
return formatToMetricDistance( srcDistance, srcUnits, destDistance, destUnits );
150+
}
151+
else if ( destSystem == QgsUnitTypes::ImperialSystem )
152+
{
153+
return formatToImperialDistance( srcDistance, srcUnits, destDistance, destUnits );
154+
}
155+
else if ( destSystem == QgsUnitTypes::USCSSystem )
156+
{
157+
return formatToUSCSDistance( srcDistance, srcUnits, destDistance, destUnits );
158+
}
159+
else
160+
{
161+
Q_ASSERT( false ); //should never happen
162+
}
163+
}
115164

165+
void QgsQuickUtils::formatToMetricDistance( double srcDistance,
166+
QgsUnitTypes::DistanceUnit srcUnits,
167+
double &destDistance,
168+
QgsUnitTypes::DistanceUnit &destUnits )
169+
{
170+
double dist = srcDistance * QgsUnitTypes::fromUnitToUnitFactor( srcUnits, QgsUnitTypes::DistanceMillimeters );
116171
if ( dist < 0 )
117172
{
118-
return QStringLiteral( "0 %1" ).arg( QgsUnitTypes::toAbbreviatedString( QgsUnitTypes::DistanceMeters ) );
173+
destDistance = 0;
174+
destUnits = QgsUnitTypes::DistanceMillimeters;
175+
return;
119176
}
120177

121-
if ( dist > 1000 )
178+
double mmToKm = QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceKilometers, QgsUnitTypes::DistanceMillimeters );
179+
if ( dist > mmToKm )
122180
{
123-
return QStringLiteral( "%1 %2" ).arg( QString::number( dist / 1000.0, 'f', decimals ) ).arg( QgsUnitTypes::toAbbreviatedString( QgsUnitTypes::DistanceKilometers ) );
181+
destDistance = dist / mmToKm;
182+
destUnits = QgsUnitTypes::DistanceKilometers;
183+
return;
124184
}
125-
else
185+
186+
double mmToM = QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceMeters, QgsUnitTypes::DistanceMillimeters );
187+
if ( dist > mmToM )
188+
{
189+
destDistance = dist / mmToM;
190+
destUnits = QgsUnitTypes::DistanceMeters;
191+
return;
192+
}
193+
194+
double mmToCm = QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceCentimeters, QgsUnitTypes::DistanceMillimeters );
195+
if ( dist > mmToCm )
196+
{
197+
destDistance = dist / mmToCm;
198+
destUnits = QgsUnitTypes::DistanceCentimeters;
199+
return;
200+
}
201+
202+
destDistance = dist;
203+
destUnits = QgsUnitTypes::DistanceMillimeters;
204+
}
205+
206+
void QgsQuickUtils::formatToImperialDistance( double srcDistance,
207+
QgsUnitTypes::DistanceUnit srcUnits,
208+
double &destDistance,
209+
QgsUnitTypes::DistanceUnit &destUnits )
210+
{
211+
double dist = srcDistance * QgsUnitTypes::fromUnitToUnitFactor( srcUnits, QgsUnitTypes::DistanceFeet );
212+
if ( dist < 0 )
213+
{
214+
destDistance = 0;
215+
destUnits = QgsUnitTypes::DistanceFeet;
216+
return;
217+
}
218+
219+
double feetToMile = QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceMiles, QgsUnitTypes::DistanceFeet );
220+
if ( dist > feetToMile )
221+
{
222+
destDistance = dist / feetToMile;
223+
destUnits = QgsUnitTypes::DistanceMiles;
224+
return;
225+
}
226+
227+
double feetToYard = QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceYards, QgsUnitTypes::DistanceFeet );
228+
if ( dist > feetToYard )
126229
{
127-
if ( dist > 1 )
128-
{
129-
return QStringLiteral( "%1 %2" ).arg( QString::number( dist, 'f', decimals ) ).arg( QgsUnitTypes::toAbbreviatedString( QgsUnitTypes::DistanceMeters ) );
130-
}
131-
else
132-
{
133-
return QStringLiteral( "%1 %2" ).arg( QString::number( dist * 1000, 'f', decimals ) ).arg( QgsUnitTypes::toAbbreviatedString( QgsUnitTypes::DistanceMillimeters ) );
134-
}
230+
destDistance = dist / feetToYard;
231+
destUnits = QgsUnitTypes::DistanceYards;
232+
return;
135233
}
234+
235+
destDistance = dist;
236+
destUnits = QgsUnitTypes::DistanceFeet;
237+
return;
238+
}
239+
240+
void QgsQuickUtils::formatToUSCSDistance( double srcDistance,
241+
QgsUnitTypes::DistanceUnit srcUnits,
242+
double &destDistance,
243+
QgsUnitTypes::DistanceUnit &destUnits )
244+
{
245+
double dist = srcDistance * QgsUnitTypes::fromUnitToUnitFactor( srcUnits, QgsUnitTypes::DistanceFeet );
246+
if ( dist < 0 )
247+
{
248+
destDistance = 0;
249+
destUnits = QgsUnitTypes::DistanceFeet;
250+
return;
251+
}
252+
253+
double feetToMile = QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceNauticalMiles, QgsUnitTypes::DistanceFeet );
254+
if ( dist > feetToMile )
255+
{
256+
destDistance = dist / feetToMile;
257+
destUnits = QgsUnitTypes::DistanceNauticalMiles;
258+
return;
259+
}
260+
261+
double feetToYard = QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceYards, QgsUnitTypes::DistanceFeet );
262+
if ( dist > feetToYard )
263+
{
264+
destDistance = dist / feetToYard;
265+
destUnits = QgsUnitTypes::DistanceYards;
266+
return;
267+
}
268+
269+
destDistance = dist;
270+
destUnits = QgsUnitTypes::DistanceFeet;
271+
return;
136272
}
137273

138274
QString QgsQuickUtils::dumpScreenInfo() const

0 commit comments

Comments
 (0)