QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
qgscoordinatenumericformat.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgscoordinatenumericformat.cpp
3 --------------------------
4 begin : April 2022
5 copyright : (C) 2022 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include <iomanip>
19#include <iostream>
20#include <locale>
21#include <memory>
22
23#include "qgis.h"
25
26#include "moc_qgscoordinatenumericformat.cpp"
27
29namespace QgsGeographicCoordinateNumericFormat_ns
30{
31 struct formatter : std::numpunct<wchar_t>
32 {
33 formatter( QChar thousands, bool showThousands, QChar decimal )
34 : mThousands( thousands.unicode() )
35 , mDecimal( decimal.unicode() )
36 , mShowThousands( showThousands )
37 {}
38 wchar_t do_decimal_point() const override { return mDecimal; }
39 wchar_t do_thousands_sep() const override { return mThousands; }
40 std::string do_grouping() const override { return mShowThousands ? "\3" : "\0"; }
41
42 wchar_t mThousands;
43 wchar_t mDecimal;
44 bool mShowThousands = true;
45 };
46}
48
52
54{
55 return QStringLiteral( "geographiccoordinate" );
56}
57
59{
60 return QObject::tr( "Geographic Coordinate" );
61}
62
67
69{
70 return 3.7555;
71}
72
74{
75 const QChar decimal = decimalSeparator().isNull() ? context.decimalSeparator() : decimalSeparator();
76 std::basic_stringstream<wchar_t> os;
77 os.imbue( std::locale( os.getloc(), new QgsGeographicCoordinateNumericFormat_ns::formatter( thousandsSeparator().isNull() ? context.thousandsSeparator() : thousandsSeparator(),
78 false,
79 decimal ) ) );
80
81 switch ( context.interpretation() )
82 {
84 return formatLatitude( value, os, context );
85
88 return formatLongitude( value, os, context );
89 }
91}
92
97
99{
100 auto res = std::make_unique< QgsGeographicCoordinateNumericFormat >();
101 res->setConfiguration( configuration, context );
102 res->mAngleFormat = qgsEnumKeyToValue( configuration.value( QStringLiteral( "angle_format" ) ).toString(), AngleFormat::DecimalDegrees );
103 res->mShowLeadingZeros = configuration.value( QStringLiteral( "show_leading_zeros" ), false ).toBool();
104 res->mShowLeadingDegreeZeros = configuration.value( QStringLiteral( "show_leading_degree_zeros" ), false ).toBool();
105 res->mUseSuffix = configuration.value( QStringLiteral( "show_suffix" ), false ).toBool();
106 return res.release();
107}
108
110{
111 QVariantMap res = QgsBasicNumericFormat::configuration( context );
112 res.insert( QStringLiteral( "angle_format" ), qgsEnumValueToKey( mAngleFormat ) );
113 res.insert( QStringLiteral( "show_leading_zeros" ), mShowLeadingZeros );
114 res.insert( QStringLiteral( "show_leading_degree_zeros" ), mShowLeadingDegreeZeros );
115 res.insert( QStringLiteral( "show_suffix" ), mUseSuffix );
116 return res;
117}
118
123
128
130{
132 mAngleFormat = qgsEnumKeyToValue( configuration.value( QStringLiteral( "angle_format" ) ).toString(), AngleFormat::DecimalDegrees );
133 mShowLeadingZeros = configuration.value( QStringLiteral( "show_leading_zeros" ), false ).toBool();
134 mShowLeadingDegreeZeros = configuration.value( QStringLiteral( "show_leading_degree_zeros" ), false ).toBool();
135 mUseSuffix = configuration.value( QStringLiteral( "show_suffix" ), false ).toBool();
136}
137
139{
140 return mShowLeadingZeros;
141}
142
144{
145 mShowLeadingZeros = newShowLeadingZeros;
146}
147
149{
150 return mShowLeadingDegreeZeros;
151}
152
154{
155 mShowLeadingDegreeZeros = show;
156}
157
159{
160 return mUseSuffix;
161}
162
164{
165 mUseSuffix = show;
166}
167
168QString QgsGeographicCoordinateNumericFormat::formatLongitude( double value, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
169{
170 switch ( mAngleFormat )
171 {
173 return formatLongitudeAsDegreesMinutesSeconds( value, ss, context );
175 return formatLongitudeAsDegreesMinutes( value, ss, context );
177 return formatLongitudeAsDegrees( value, ss, context );
178 }
180}
181
182QString QgsGeographicCoordinateNumericFormat::formatLatitude( double value, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
183{
184 switch ( mAngleFormat )
185 {
187 return formatLatitudeAsDegreesMinutesSeconds( value, ss, context );
189 return formatLatitudeAsDegreesMinutes( value, ss, context );
191 return formatLatitudeAsDegrees( value, ss, context );
192 }
194}
195
196QString QgsGeographicCoordinateNumericFormat::formatLatitudeAsDegreesMinutesSeconds( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
197{
198 //first, limit latitude to -180 to 180 degree range
199 double wrappedY = std::fmod( val, 180.0 );
200 //next, wrap around latitudes > 90 or < -90 degrees, so that eg "110S" -> "70N"
201 if ( wrappedY > 90.0 )
202 {
203 wrappedY = wrappedY - 180.0;
204 }
205 else if ( wrappedY < -90.0 )
206 {
207 wrappedY = wrappedY + 180.0;
208 }
209
210 const double precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
211
212 int degreesY = int( std::fabs( wrappedY ) );
213 const double floatMinutesY = ( std::fabs( wrappedY ) - degreesY ) * 60.0;
214 int intMinutesY = int( floatMinutesY );
215 double secondsY = ( floatMinutesY - intMinutesY ) * 60.0;
216
217 //make sure rounding to specified precision doesn't create seconds >= 60
218 if ( std::round( secondsY * precisionMultiplier ) >= 60 * precisionMultiplier )
219 {
220 secondsY = std::max( secondsY - 60, 0.0 );
221 intMinutesY++;
222 if ( intMinutesY >= 60 )
223 {
224 intMinutesY -= 60;
225 degreesY++;
226 }
227 }
228
229 QString hemisphere;
230 QString sign;
231 if ( mUseSuffix )
232 {
233 hemisphere = wrappedY < 0 ? QObject::tr( "S" ) : QObject::tr( "N" );
234 }
235 else
236 {
237 if ( wrappedY < 0 )
238 {
239 sign = context.negativeSign();
240 }
241 }
242 //check if coordinate is all zeros for the specified precision, and if so,
243 //remove the sign and hemisphere strings
244 if ( degreesY == 0 && intMinutesY == 0 && std::round( secondsY * precisionMultiplier ) == 0 )
245 {
246 sign = QString();
247 hemisphere.clear();
248 }
249
250 QString strMinutesY;
251 QString strSecondsY;
252
253 ss << std::fixed << std::setprecision( 0 );
254 ss << intMinutesY;
255
256 strMinutesY = QString::fromStdWString( ss.str() );
257 ss.str( std::wstring() );
258
259 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
260 ss << secondsY;
261 strSecondsY = QString::fromStdWString( ss.str() );
262 ss.str( std::wstring() );
263
264 trimTrailingZeros( strSecondsY, context );
265
266 //pad with leading digits if required
267 if ( mShowLeadingZeros && intMinutesY < 10 )
268 strMinutesY = '0' + strMinutesY;
269
270 if ( mShowLeadingZeros && secondsY < 10 )
271 strSecondsY = '0' + strSecondsY;
272
273 ss << std::fixed << std::setprecision( 0 );
274 ss << degreesY;
275 QString degreesYStr = QString::fromStdWString( ss.str() );
276 ss.str( std::wstring() );
277
278 if ( mShowLeadingDegreeZeros )
279 degreesYStr = QString( QStringLiteral( "00" ) + degreesYStr ).right( 2 );
280
281 return sign + degreesYStr + QChar( 176 ) +
282 strMinutesY + QChar( 0x2032 ) +
283 strSecondsY + QChar( 0x2033 ) +
284 hemisphere;
285}
286
287QString QgsGeographicCoordinateNumericFormat::formatLongitudeAsDegreesMinutesSeconds( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
288{
289 //first, limit longitude to -360 to 360 degree range
290 double wrappedX = std::fmod( val, 360.0 );
291 //next, wrap around longitudes > 180 or < -180 degrees, so that eg "190E" -> "170W"
292 if ( wrappedX > 180.0 )
293 {
294 wrappedX = wrappedX - 360.0;
295 }
296 else if ( wrappedX < -180.0 )
297 {
298 wrappedX = wrappedX + 360.0;
299 }
300
301 const double precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
302
303 int degreesX = int( std::fabs( wrappedX ) );
304 const double floatMinutesX = ( std::fabs( wrappedX ) - degreesX ) * 60.0;
305 int intMinutesX = int( floatMinutesX );
306 double secondsX = ( floatMinutesX - intMinutesX ) * 60.0;
307
308 //make sure rounding to specified precision doesn't create seconds >= 60
309 if ( std::round( secondsX * precisionMultiplier ) >= 60 * precisionMultiplier )
310 {
311 secondsX = std::max( secondsX - 60, 0.0 );
312 intMinutesX++;
313 if ( intMinutesX >= 60 )
314 {
315 intMinutesX -= 60;
316 degreesX++;
317 }
318 }
319
320 QString hemisphere;
321 QString sign;
322 if ( mUseSuffix )
323 {
324 hemisphere = wrappedX < 0 ? QObject::tr( "W" ) : QObject::tr( "E" );
325 }
326 else
327 {
328 if ( wrappedX < 0 )
329 {
330 sign = context.negativeSign();
331 }
332 }
333 //check if coordinate is all zeros for the specified precision, and if so,
334 //remove the sign and hemisphere strings
335 if ( degreesX == 0 && intMinutesX == 0 && std::round( secondsX * precisionMultiplier ) == 0 )
336 {
337 sign.clear();
338 hemisphere.clear();
339 }
340
341 //also remove directional prefix from 180 degree longitudes
342 if ( degreesX == 180 && intMinutesX == 0 && std::round( secondsX * precisionMultiplier ) == 0 )
343 {
344 hemisphere.clear();
345 }
346
347 QString minutesX;
348 QString strSecondsX;
349
350 ss << std::fixed << std::setprecision( 0 );
351 ss << intMinutesX;
352
353 minutesX = QString::fromStdWString( ss.str() );
354 ss.str( std::wstring() );
355
356 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
357 ss << secondsX;
358 strSecondsX = QString::fromStdWString( ss.str() );
359 ss.str( std::wstring() );
360
361 trimTrailingZeros( strSecondsX, context );
362
363 //pad with leading digits if required
364 if ( mShowLeadingZeros && intMinutesX < 10 )
365 minutesX = '0' + minutesX;
366
367 if ( mShowLeadingZeros && secondsX < 10 )
368 strSecondsX = '0' + strSecondsX;
369
370 ss << std::fixed << std::setprecision( 0 );
371 ss << degreesX;
372 QString degreesXStr = QString::fromStdWString( ss.str() );
373 ss.str( std::wstring() );
374
375 if ( mShowLeadingDegreeZeros )
376 degreesXStr = QString( QStringLiteral( "000" ) + degreesXStr ).right( 3 );
377
378 return sign + degreesXStr + QChar( 176 ) +
379 minutesX + QChar( 0x2032 ) +
380 strSecondsX + QChar( 0x2033 ) +
381 hemisphere;
382}
383
384QString QgsGeographicCoordinateNumericFormat::formatLatitudeAsDegreesMinutes( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
385{
386 //first, limit latitude to -180 to 180 degree range
387 double wrappedY = std::fmod( val, 180.0 );
388 //next, wrap around latitudes > 90 or < -90 degrees, so that eg "110S" -> "70N"
389 if ( wrappedY > 90.0 )
390 {
391 wrappedY = wrappedY - 180.0;
392 }
393 else if ( wrappedY < -90.0 )
394 {
395 wrappedY = wrappedY + 180.0;
396 }
397
398 int degreesY = int( std::fabs( wrappedY ) );
399 double floatMinutesY = ( std::fabs( wrappedY ) - degreesY ) * 60.0;
400
401 const double precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
402
403 //make sure rounding to specified precision doesn't create minutes >= 60
404 if ( std::round( floatMinutesY * precisionMultiplier ) >= 60 * precisionMultiplier )
405 {
406 floatMinutesY = std::max( floatMinutesY - 60, 0.0 );
407 degreesY++;
408 }
409
410 QString hemisphere;
411 QString sign;
412 if ( mUseSuffix )
413 {
414 hemisphere = wrappedY < 0 ? QObject::tr( "S" ) : QObject::tr( "N" );
415 }
416 else
417 {
418 if ( wrappedY < 0 )
419 {
420 sign = context.negativeSign();
421 }
422 }
423 //check if coordinate is all zeros for the specified precision, and if so,
424 //remove the sign and hemisphere strings
425 if ( degreesY == 0 && std::round( floatMinutesY * precisionMultiplier ) == 0 )
426 {
427 sign.clear();
428 hemisphere.clear();
429 }
430
431 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
432 ss << floatMinutesY;
433 QString strMinutesY = QString::fromStdWString( ss.str() );
434 ss.str( std::wstring() );
435
436 trimTrailingZeros( strMinutesY, context );
437
438 //pad with leading digits if required
439 if ( mShowLeadingZeros && floatMinutesY < 10 )
440 strMinutesY = '0' + strMinutesY;
441
442 ss << std::fixed << std::setprecision( 0 );
443 ss << degreesY;
444 QString degreesYStr = QString::fromStdWString( ss.str() );
445 ss.str( std::wstring() );
446
447 if ( mShowLeadingDegreeZeros )
448 degreesYStr = QString( QStringLiteral( "00" ) + degreesYStr ).right( 2 );
449
450 return sign + degreesYStr + QChar( 176 ) +
451 strMinutesY + QChar( 0x2032 ) +
452 hemisphere;
453}
454
455QString QgsGeographicCoordinateNumericFormat::formatLongitudeAsDegreesMinutes( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
456{
457 //first, limit longitude to -360 to 360 degree range
458 double wrappedX = std::fmod( val, 360.0 );
459 //next, wrap around longitudes > 180 or < -180 degrees, so that eg "190E" -> "170W"
460 if ( wrappedX > 180.0 )
461 {
462 wrappedX = wrappedX - 360.0;
463 }
464 else if ( wrappedX < -180.0 )
465 {
466 wrappedX = wrappedX + 360.0;
467 }
468
469 int degreesX = int( std::fabs( wrappedX ) );
470 double floatMinutesX = ( std::fabs( wrappedX ) - degreesX ) * 60.0;
471
472 const double precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
473
474 //make sure rounding to specified precision doesn't create minutes >= 60
475 if ( std::round( floatMinutesX * precisionMultiplier ) >= 60 * precisionMultiplier )
476 {
477 floatMinutesX = std::max( floatMinutesX - 60, 0.0 );
478 degreesX++;
479 }
480
481 QString hemisphere;
482 QString sign;
483 if ( mUseSuffix )
484 {
485 hemisphere = wrappedX < 0 ? QObject::tr( "W" ) : QObject::tr( "E" );
486 }
487 else
488 {
489 if ( wrappedX < 0 )
490 {
491 sign = context.negativeSign();
492 }
493 }
494 //check if coordinate is all zeros for the specified precision, and if so,
495 //remove the sign and hemisphere strings
496 if ( degreesX == 0 && std::round( floatMinutesX * precisionMultiplier ) == 0 )
497 {
498 sign.clear();
499 hemisphere.clear();
500 }
501
502 //also remove directional prefix from 180 degree longitudes
503 if ( degreesX == 180 && std::round( floatMinutesX * precisionMultiplier ) == 0 )
504 {
505 hemisphere.clear();
506 }
507
508 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
509 ss << floatMinutesX;
510 QString strMinutesX = QString::fromStdWString( ss.str() );
511 ss.str( std::wstring() );
512
513 trimTrailingZeros( strMinutesX, context );
514
515 //pad with leading digits if required
516 if ( mShowLeadingZeros && floatMinutesX < 10 )
517 strMinutesX = '0' + strMinutesX;
518
519 ss << std::fixed << std::setprecision( 0 );
520 ss << degreesX;
521 QString degreesXStr = QString::fromStdWString( ss.str() );
522 ss.str( std::wstring() );
523
524 if ( mShowLeadingDegreeZeros )
525 degreesXStr = QString( QStringLiteral( "000" ) + degreesXStr ).right( 3 );
526
527 return sign + degreesXStr + QChar( 176 ) +
528 strMinutesX + QChar( 0x2032 ) +
529 hemisphere;
530}
531
532QString QgsGeographicCoordinateNumericFormat::formatLatitudeAsDegrees( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
533{
534 //first, limit latitude to -180 to 180 degree range
535 double wrappedY = std::fmod( val, 180.0 );
536 //next, wrap around latitudes > 90 or < -90 degrees, so that eg "110S" -> "70N"
537 if ( wrappedY > 90.0 )
538 {
539 wrappedY = wrappedY - 180.0;
540 }
541 else if ( wrappedY < -90.0 )
542 {
543 wrappedY = wrappedY + 180.0;
544 }
545
546 const double absY = std::fabs( wrappedY );
547
548 const double precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
549
550 QString hemisphere;
551 QString sign;
552 if ( mUseSuffix )
553 {
554 hemisphere = wrappedY < 0 ? QObject::tr( "S" ) : QObject::tr( "N" );
555 }
556 else
557 {
558 if ( wrappedY < 0 )
559 {
560 sign = context.negativeSign();
561 }
562 }
563 //check if coordinate is all zeros for the specified precision, and if so,
564 //remove the sign and hemisphere strings
565 if ( std::round( absY * precisionMultiplier ) == 0 )
566 {
567 sign.clear();
568 hemisphere.clear();
569 }
570
571 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
572 ss << absY;
573 QString strDegreesY = QString::fromStdWString( ss.str() );
574 ss.str( std::wstring() );
575
576 trimTrailingZeros( strDegreesY, context );
577
578 if ( mShowLeadingDegreeZeros && absY < 10 )
579 strDegreesY = '0' + strDegreesY;
580
581 return sign + strDegreesY + QChar( 176 ) + hemisphere;
582}
583
584QString QgsGeographicCoordinateNumericFormat::formatLongitudeAsDegrees( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
585{
586 //first, limit longitude to -360 to 360 degree range
587 double wrappedX = std::fmod( val, 360.0 );
588 //next, wrap around longitudes > 180 or < -180 degrees, so that eg "190E" -> "170W"
589 if ( wrappedX > 180.0 )
590 {
591 wrappedX = wrappedX - 360.0;
592 }
593 else if ( wrappedX < -180.0 )
594 {
595 wrappedX = wrappedX + 360.0;
596 }
597
598 const double absX = std::fabs( wrappedX );
599
600 const double precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
601
602 QString hemisphere;
603 QString sign;
604 if ( mUseSuffix )
605 {
606 hemisphere = wrappedX < 0 ? QObject::tr( "W" ) : QObject::tr( "E" );
607 }
608 else
609 {
610 if ( wrappedX < 0 )
611 {
612 sign = context.negativeSign();
613 }
614 }
615 //check if coordinate is all zeros for the specified precision, and if so,
616 //remove the sign and hemisphere strings
617 if ( std::round( absX * precisionMultiplier ) == 0 )
618 {
619 sign.clear();
620 hemisphere.clear();
621 }
622
623 //also remove directional prefix from 180 degree longitudes
624 if ( std::round( absX * precisionMultiplier ) == 180 * precisionMultiplier )
625 {
626 sign.clear();
627 hemisphere.clear();
628 }
629
630 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
631 ss << absX;
632 QString strDegreesX = QString::fromStdWString( ss.str() );
633 ss.str( std::wstring() );
634
635 trimTrailingZeros( strDegreesX, context );
636
637 if ( mShowLeadingDegreeZeros && absX < 100 )
638 strDegreesX = '0' + strDegreesX;
639 if ( mShowLeadingDegreeZeros && absX < 10 )
640 strDegreesX = '0' + strDegreesX;
641
642 return sign + strDegreesX + QChar( 176 ) + hemisphere;
643}
644
645void QgsGeographicCoordinateNumericFormat::trimTrailingZeros( QString &input, const QgsNumericFormatContext &context ) const
646{
647 const QChar decimal = decimalSeparator().isNull() ? context.decimalSeparator() : decimalSeparator();
648 if ( !showTrailingZeros() && input.contains( decimal ) )
649 {
650 int trimPoint = input.length() - 1;
651
652 while ( input.at( trimPoint ) == context.zeroDigit() )
653 trimPoint--;
654
655 if ( input.at( trimPoint ) == decimal )
656 trimPoint--;
657
658 input.truncate( trimPoint + 1 );
659 }
660}
QChar thousandsSeparator() const
Returns any override for the thousands separator character.
virtual void setConfiguration(const QVariantMap &configuration, const QgsReadWriteContext &context)
Sets the format's configuration.
bool showTrailingZeros() const
Returns true if trailing zeros will be shown (up to the specified numberDecimalPlaces()).
QChar decimalSeparator() const
Returns any override for the decimal separator character.
int numberDecimalPlaces() const
Returns the maximum number of decimal places to show.
QVariantMap configuration(const QgsReadWriteContext &context) const override
Returns the current configuration of the formatter.
void setConfiguration(const QVariantMap &configuration, const QgsReadWriteContext &context) override
Sets the format's configuration.
@ DegreesMinutes
Degrees and decimal minutes, eg 30 degrees 45.55'.
@ DegreesMinutesSeconds
Degrees, minutes and seconds, eg 30 degrees 45'30.
QgsNumericFormat * create(const QVariantMap &configuration, const QgsReadWriteContext &context) const override
Creates a new copy of the format, using the supplied configuration.
void setShowDirectionalSuffix(bool show)
Sets whether directional suffixes (e.g.
QgsGeographicCoordinateNumericFormat * clone() const override
Clones the format, returning a new object.
double suggestSampleValue() const override
Returns a suggested sample value which nicely represents the current format configuration.
int sortKey() override
Returns a sorting key value, where formats with a lower sort key will be shown earlier in lists.
QString id() const override
Returns a unique id for this numeric format.
void setShowDegreeLeadingZeros(bool show)
Sets whether leading zeros for the degree values should be shown.
QString formatDouble(double value, const QgsNumericFormatContext &context) const override
Returns a formatted string representation of a numeric double value.
bool showDirectionalSuffix() const
Returns true if directional suffixes (e.g.
QVariantMap configuration(const QgsReadWriteContext &context) const override
Returns the current configuration of the formatter.
void setShowLeadingZeros(bool show)
Sets whether leading zeros in the minutes or seconds values should be shown.
AngleFormat angleFormat() const
Returns the angle format, which controls how bearing the angles are formatted described in the return...
bool showLeadingZeros() const
Returns true if leading zeros in the minutes or seconds values should be shown.
bool showDegreeLeadingZeros() const
Returns true if leading zeros for the degree values should be shown.
QString visibleName() const override
Returns the translated, user-visible name for this format.
void setAngleFormat(AngleFormat format)
Sets the directional formatting option, which controls how bearing the angles are formatted described...
A context for numeric formats.
QChar negativeSign() const
Returns the negative sign character.
QChar thousandsSeparator() const
Returns the thousands separator character.
QChar zeroDigit() const
Returns the zero digit character.
Interpretation interpretation() const
Returns the interpretation of the numbers being converted.
QChar decimalSeparator() const
Returns the decimal separator character.
static constexpr int DEFAULT_SORT_KEY
QgsNumericFormat()=default
A container for the context for various read/write operations on objects.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
Definition qgis.h:6817
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition qgis.h:6798
#define BUILTIN_UNREACHABLE
Definition qgis.h:7208