QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
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 <QString>
27
28#include "moc_qgscoordinatenumericformat.cpp"
29
30using namespace Qt::StringLiterals;
31
33namespace QgsGeographicCoordinateNumericFormat_ns
34{
35 struct formatter : std::numpunct<wchar_t>
36 {
37 formatter( QChar thousands, bool showThousands, QChar decimal )
38 : mThousands( thousands.unicode() )
39 , mDecimal( decimal.unicode() )
40 , mShowThousands( showThousands )
41 {}
42 wchar_t do_decimal_point() const override { return mDecimal; }
43 wchar_t do_thousands_sep() const override { return mThousands; }
44 std::string do_grouping() const override { return mShowThousands ? "\3" : "\0"; }
45
46 wchar_t mThousands;
47 wchar_t mDecimal;
48 bool mShowThousands = true;
49 };
50} //namespace QgsGeographicCoordinateNumericFormat_ns
52
55
57{
58 return u"geographiccoordinate"_s;
59}
60
62{
63 return QObject::tr( "Geographic Coordinate" );
64}
65
70
72{
73 return 3.7555;
74}
75
77{
78 const QChar decimal = decimalSeparator().isNull() ? context.decimalSeparator() : decimalSeparator();
79 std::basic_stringstream<wchar_t> os;
80 os.imbue( std::locale( os.getloc(), new QgsGeographicCoordinateNumericFormat_ns::formatter( thousandsSeparator().isNull() ? context.thousandsSeparator() : thousandsSeparator(), false, decimal ) ) );
81
82 switch ( context.interpretation() )
83 {
85 return formatLatitude( value, os, context );
86
89 return formatLongitude( value, os, context );
90 }
92}
93
98
100{
101 auto res = std::make_unique< QgsGeographicCoordinateNumericFormat >();
102 res->setConfiguration( configuration, context );
103 res->mAngleFormat = qgsEnumKeyToValue( configuration.value( u"angle_format"_s ).toString(), AngleFormat::DecimalDegrees );
104 res->mShowLeadingZeros = configuration.value( u"show_leading_zeros"_s, false ).toBool();
105 res->mShowLeadingDegreeZeros = configuration.value( u"show_leading_degree_zeros"_s, false ).toBool();
106 res->mUseSuffix = configuration.value( u"show_suffix"_s, false ).toBool();
107 return res.release();
108}
109
111{
112 QVariantMap res = QgsBasicNumericFormat::configuration( context );
113 res.insert( u"angle_format"_s, qgsEnumValueToKey( mAngleFormat ) );
114 res.insert( u"show_leading_zeros"_s, mShowLeadingZeros );
115 res.insert( u"show_leading_degree_zeros"_s, mShowLeadingDegreeZeros );
116 res.insert( u"show_suffix"_s, mUseSuffix );
117 return res;
118}
119
124
129
131{
133 mAngleFormat = qgsEnumKeyToValue( configuration.value( u"angle_format"_s ).toString(), AngleFormat::DecimalDegrees );
134 mShowLeadingZeros = configuration.value( u"show_leading_zeros"_s, false ).toBool();
135 mShowLeadingDegreeZeros = configuration.value( u"show_leading_degree_zeros"_s, false ).toBool();
136 mUseSuffix = configuration.value( u"show_suffix"_s, false ).toBool();
137}
138
140{
141 return mShowLeadingZeros;
142}
143
145{
146 mShowLeadingZeros = newShowLeadingZeros;
147}
148
150{
151 return mShowLeadingDegreeZeros;
152}
153
155{
156 mShowLeadingDegreeZeros = show;
157}
158
160{
161 return mUseSuffix;
162}
163
165{
166 mUseSuffix = show;
167}
168
169QString QgsGeographicCoordinateNumericFormat::formatLongitude( double value, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
170{
171 switch ( mAngleFormat )
172 {
174 return formatLongitudeAsDegreesMinutesSeconds( value, ss, context );
176 return formatLongitudeAsDegreesMinutes( value, ss, context );
178 return formatLongitudeAsDegrees( value, ss, context );
179 }
181}
182
183QString QgsGeographicCoordinateNumericFormat::formatLatitude( double value, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
184{
185 switch ( mAngleFormat )
186 {
188 return formatLatitudeAsDegreesMinutesSeconds( value, ss, context );
190 return formatLatitudeAsDegreesMinutes( value, ss, context );
192 return formatLatitudeAsDegrees( value, ss, context );
193 }
195}
196
197QString QgsGeographicCoordinateNumericFormat::formatLatitudeAsDegreesMinutesSeconds( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
198{
199 //first, limit latitude to -180 to 180 degree range
200 double wrappedY = std::fmod( val, 180.0 );
201 //next, wrap around latitudes > 90 or < -90 degrees, so that eg "110S" -> "70N"
202 if ( wrappedY > 90.0 )
203 {
204 wrappedY = wrappedY - 180.0;
205 }
206 else if ( wrappedY < -90.0 )
207 {
208 wrappedY = wrappedY + 180.0;
209 }
210
211 const double precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
212
213 int degreesY = int( std::fabs( wrappedY ) );
214 const double floatMinutesY = ( std::fabs( wrappedY ) - degreesY ) * 60.0;
215 int intMinutesY = int( floatMinutesY );
216 double secondsY = ( floatMinutesY - intMinutesY ) * 60.0;
217
218 //make sure rounding to specified precision doesn't create seconds >= 60
219 if ( std::round( secondsY * precisionMultiplier ) >= 60 * precisionMultiplier )
220 {
221 secondsY = std::max( secondsY - 60, 0.0 );
222 intMinutesY++;
223 if ( intMinutesY >= 60 )
224 {
225 intMinutesY -= 60;
226 degreesY++;
227 }
228 }
229
230 QString hemisphere;
231 QString sign;
232 if ( mUseSuffix )
233 {
234 hemisphere = wrappedY < 0 ? QObject::tr( "S" ) : QObject::tr( "N" );
235 }
236 else
237 {
238 if ( wrappedY < 0 )
239 {
240 sign = context.negativeSign();
241 }
242 }
243 //check if coordinate is all zeros for the specified precision, and if so,
244 //remove the sign and hemisphere strings
245 if ( degreesY == 0 && intMinutesY == 0 && std::round( secondsY * precisionMultiplier ) == 0 )
246 {
247 sign = QString();
248 hemisphere.clear();
249 }
250
251 QString strMinutesY;
252 QString strSecondsY;
253
254 ss << std::fixed << std::setprecision( 0 );
255 ss << intMinutesY;
256
257 strMinutesY = QString::fromStdWString( ss.str() );
258 ss.str( std::wstring() );
259
260 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
261 ss << secondsY;
262 strSecondsY = QString::fromStdWString( ss.str() );
263 ss.str( std::wstring() );
264
265 trimTrailingZeros( strSecondsY, context );
266
267 //pad with leading digits if required
268 if ( mShowLeadingZeros && intMinutesY < 10 )
269 strMinutesY = '0' + strMinutesY;
270
271 if ( mShowLeadingZeros && secondsY < 10 )
272 strSecondsY = '0' + strSecondsY;
273
274 ss << std::fixed << std::setprecision( 0 );
275 ss << degreesY;
276 QString degreesYStr = QString::fromStdWString( ss.str() );
277 ss.str( std::wstring() );
278
279 if ( mShowLeadingDegreeZeros )
280 degreesYStr = QString( u"00"_s + degreesYStr ).right( 2 );
281
282 return sign + degreesYStr + QChar( 176 ) + strMinutesY + QChar( 0x2032 ) + strSecondsY + QChar( 0x2033 ) + hemisphere;
283}
284
285QString QgsGeographicCoordinateNumericFormat::formatLongitudeAsDegreesMinutesSeconds( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
286{
287 //first, limit longitude to -360 to 360 degree range
288 double wrappedX = std::fmod( val, 360.0 );
289 //next, wrap around longitudes > 180 or < -180 degrees, so that eg "190E" -> "170W"
290 if ( wrappedX > 180.0 )
291 {
292 wrappedX = wrappedX - 360.0;
293 }
294 else if ( wrappedX < -180.0 )
295 {
296 wrappedX = wrappedX + 360.0;
297 }
298
299 const double precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
300
301 int degreesX = int( std::fabs( wrappedX ) );
302 const double floatMinutesX = ( std::fabs( wrappedX ) - degreesX ) * 60.0;
303 int intMinutesX = int( floatMinutesX );
304 double secondsX = ( floatMinutesX - intMinutesX ) * 60.0;
305
306 //make sure rounding to specified precision doesn't create seconds >= 60
307 if ( std::round( secondsX * precisionMultiplier ) >= 60 * precisionMultiplier )
308 {
309 secondsX = std::max( secondsX - 60, 0.0 );
310 intMinutesX++;
311 if ( intMinutesX >= 60 )
312 {
313 intMinutesX -= 60;
314 degreesX++;
315 }
316 }
317
318 QString hemisphere;
319 QString sign;
320 if ( mUseSuffix )
321 {
322 hemisphere = wrappedX < 0 ? QObject::tr( "W" ) : QObject::tr( "E" );
323 }
324 else
325 {
326 if ( wrappedX < 0 )
327 {
328 sign = context.negativeSign();
329 }
330 }
331 //check if coordinate is all zeros for the specified precision, and if so,
332 //remove the sign and hemisphere strings
333 if ( degreesX == 0 && intMinutesX == 0 && std::round( secondsX * precisionMultiplier ) == 0 )
334 {
335 sign.clear();
336 hemisphere.clear();
337 }
338
339 //also remove directional prefix from 180 degree longitudes
340 if ( degreesX == 180 && intMinutesX == 0 && std::round( secondsX * precisionMultiplier ) == 0 )
341 {
342 hemisphere.clear();
343 }
344
345 QString minutesX;
346 QString strSecondsX;
347
348 ss << std::fixed << std::setprecision( 0 );
349 ss << intMinutesX;
350
351 minutesX = QString::fromStdWString( ss.str() );
352 ss.str( std::wstring() );
353
354 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
355 ss << secondsX;
356 strSecondsX = QString::fromStdWString( ss.str() );
357 ss.str( std::wstring() );
358
359 trimTrailingZeros( strSecondsX, context );
360
361 //pad with leading digits if required
362 if ( mShowLeadingZeros && intMinutesX < 10 )
363 minutesX = '0' + minutesX;
364
365 if ( mShowLeadingZeros && secondsX < 10 )
366 strSecondsX = '0' + strSecondsX;
367
368 ss << std::fixed << std::setprecision( 0 );
369 ss << degreesX;
370 QString degreesXStr = QString::fromStdWString( ss.str() );
371 ss.str( std::wstring() );
372
373 if ( mShowLeadingDegreeZeros )
374 degreesXStr = QString( u"000"_s + degreesXStr ).right( 3 );
375
376 return sign + degreesXStr + QChar( 176 ) + minutesX + QChar( 0x2032 ) + strSecondsX + QChar( 0x2033 ) + hemisphere;
377}
378
379QString QgsGeographicCoordinateNumericFormat::formatLatitudeAsDegreesMinutes( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
380{
381 //first, limit latitude to -180 to 180 degree range
382 double wrappedY = std::fmod( val, 180.0 );
383 //next, wrap around latitudes > 90 or < -90 degrees, so that eg "110S" -> "70N"
384 if ( wrappedY > 90.0 )
385 {
386 wrappedY = wrappedY - 180.0;
387 }
388 else if ( wrappedY < -90.0 )
389 {
390 wrappedY = wrappedY + 180.0;
391 }
392
393 int degreesY = int( std::fabs( wrappedY ) );
394 double floatMinutesY = ( std::fabs( wrappedY ) - degreesY ) * 60.0;
395
396 const double precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
397
398 //make sure rounding to specified precision doesn't create minutes >= 60
399 if ( std::round( floatMinutesY * precisionMultiplier ) >= 60 * precisionMultiplier )
400 {
401 floatMinutesY = std::max( floatMinutesY - 60, 0.0 );
402 degreesY++;
403 }
404
405 QString hemisphere;
406 QString sign;
407 if ( mUseSuffix )
408 {
409 hemisphere = wrappedY < 0 ? QObject::tr( "S" ) : QObject::tr( "N" );
410 }
411 else
412 {
413 if ( wrappedY < 0 )
414 {
415 sign = context.negativeSign();
416 }
417 }
418 //check if coordinate is all zeros for the specified precision, and if so,
419 //remove the sign and hemisphere strings
420 if ( degreesY == 0 && std::round( floatMinutesY * precisionMultiplier ) == 0 )
421 {
422 sign.clear();
423 hemisphere.clear();
424 }
425
426 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
427 ss << floatMinutesY;
428 QString strMinutesY = QString::fromStdWString( ss.str() );
429 ss.str( std::wstring() );
430
431 trimTrailingZeros( strMinutesY, context );
432
433 //pad with leading digits if required
434 if ( mShowLeadingZeros && floatMinutesY < 10 )
435 strMinutesY = '0' + strMinutesY;
436
437 ss << std::fixed << std::setprecision( 0 );
438 ss << degreesY;
439 QString degreesYStr = QString::fromStdWString( ss.str() );
440 ss.str( std::wstring() );
441
442 if ( mShowLeadingDegreeZeros )
443 degreesYStr = QString( u"00"_s + degreesYStr ).right( 2 );
444
445 return sign + degreesYStr + QChar( 176 ) + strMinutesY + QChar( 0x2032 ) + hemisphere;
446}
447
448QString QgsGeographicCoordinateNumericFormat::formatLongitudeAsDegreesMinutes( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
449{
450 //first, limit longitude to -360 to 360 degree range
451 double wrappedX = std::fmod( val, 360.0 );
452 //next, wrap around longitudes > 180 or < -180 degrees, so that eg "190E" -> "170W"
453 if ( wrappedX > 180.0 )
454 {
455 wrappedX = wrappedX - 360.0;
456 }
457 else if ( wrappedX < -180.0 )
458 {
459 wrappedX = wrappedX + 360.0;
460 }
461
462 int degreesX = int( std::fabs( wrappedX ) );
463 double floatMinutesX = ( std::fabs( wrappedX ) - degreesX ) * 60.0;
464
465 const double precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
466
467 //make sure rounding to specified precision doesn't create minutes >= 60
468 if ( std::round( floatMinutesX * precisionMultiplier ) >= 60 * precisionMultiplier )
469 {
470 floatMinutesX = std::max( floatMinutesX - 60, 0.0 );
471 degreesX++;
472 }
473
474 QString hemisphere;
475 QString sign;
476 if ( mUseSuffix )
477 {
478 hemisphere = wrappedX < 0 ? QObject::tr( "W" ) : QObject::tr( "E" );
479 }
480 else
481 {
482 if ( wrappedX < 0 )
483 {
484 sign = context.negativeSign();
485 }
486 }
487 //check if coordinate is all zeros for the specified precision, and if so,
488 //remove the sign and hemisphere strings
489 if ( degreesX == 0 && std::round( floatMinutesX * precisionMultiplier ) == 0 )
490 {
491 sign.clear();
492 hemisphere.clear();
493 }
494
495 //also remove directional prefix from 180 degree longitudes
496 if ( degreesX == 180 && std::round( floatMinutesX * precisionMultiplier ) == 0 )
497 {
498 hemisphere.clear();
499 }
500
501 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
502 ss << floatMinutesX;
503 QString strMinutesX = QString::fromStdWString( ss.str() );
504 ss.str( std::wstring() );
505
506 trimTrailingZeros( strMinutesX, context );
507
508 //pad with leading digits if required
509 if ( mShowLeadingZeros && floatMinutesX < 10 )
510 strMinutesX = '0' + strMinutesX;
511
512 ss << std::fixed << std::setprecision( 0 );
513 ss << degreesX;
514 QString degreesXStr = QString::fromStdWString( ss.str() );
515 ss.str( std::wstring() );
516
517 if ( mShowLeadingDegreeZeros )
518 degreesXStr = QString( u"000"_s + degreesXStr ).right( 3 );
519
520 return sign + degreesXStr + QChar( 176 ) + strMinutesX + QChar( 0x2032 ) + hemisphere;
521}
522
523QString QgsGeographicCoordinateNumericFormat::formatLatitudeAsDegrees( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
524{
525 //first, limit latitude to -180 to 180 degree range
526 double wrappedY = std::fmod( val, 180.0 );
527 //next, wrap around latitudes > 90 or < -90 degrees, so that eg "110S" -> "70N"
528 if ( wrappedY > 90.0 )
529 {
530 wrappedY = wrappedY - 180.0;
531 }
532 else if ( wrappedY < -90.0 )
533 {
534 wrappedY = wrappedY + 180.0;
535 }
536
537 const double absY = std::fabs( wrappedY );
538
539 const double precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
540
541 QString hemisphere;
542 QString sign;
543 if ( mUseSuffix )
544 {
545 hemisphere = wrappedY < 0 ? QObject::tr( "S" ) : QObject::tr( "N" );
546 }
547 else
548 {
549 if ( wrappedY < 0 )
550 {
551 sign = context.negativeSign();
552 }
553 }
554 //check if coordinate is all zeros for the specified precision, and if so,
555 //remove the sign and hemisphere strings
556 if ( std::round( absY * precisionMultiplier ) == 0 )
557 {
558 sign.clear();
559 hemisphere.clear();
560 }
561
562 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
563 ss << absY;
564 QString strDegreesY = QString::fromStdWString( ss.str() );
565 ss.str( std::wstring() );
566
567 trimTrailingZeros( strDegreesY, context );
568
569 if ( mShowLeadingDegreeZeros && absY < 10 )
570 strDegreesY = '0' + strDegreesY;
571
572 return sign + strDegreesY + QChar( 176 ) + hemisphere;
573}
574
575QString QgsGeographicCoordinateNumericFormat::formatLongitudeAsDegrees( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
576{
577 //first, limit longitude to -360 to 360 degree range
578 double wrappedX = std::fmod( val, 360.0 );
579 //next, wrap around longitudes > 180 or < -180 degrees, so that eg "190E" -> "170W"
580 if ( wrappedX > 180.0 )
581 {
582 wrappedX = wrappedX - 360.0;
583 }
584 else if ( wrappedX < -180.0 )
585 {
586 wrappedX = wrappedX + 360.0;
587 }
588
589 const double absX = std::fabs( wrappedX );
590
591 const double precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
592
593 QString hemisphere;
594 QString sign;
595 if ( mUseSuffix )
596 {
597 hemisphere = wrappedX < 0 ? QObject::tr( "W" ) : QObject::tr( "E" );
598 }
599 else
600 {
601 if ( wrappedX < 0 )
602 {
603 sign = context.negativeSign();
604 }
605 }
606 //check if coordinate is all zeros for the specified precision, and if so,
607 //remove the sign and hemisphere strings
608 if ( std::round( absX * precisionMultiplier ) == 0 )
609 {
610 sign.clear();
611 hemisphere.clear();
612 }
613
614 //also remove directional prefix from 180 degree longitudes
615 if ( std::round( absX * precisionMultiplier ) == 180 * precisionMultiplier )
616 {
617 sign.clear();
618 hemisphere.clear();
619 }
620
621 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
622 ss << absX;
623 QString strDegreesX = QString::fromStdWString( ss.str() );
624 ss.str( std::wstring() );
625
626 trimTrailingZeros( strDegreesX, context );
627
628 if ( mShowLeadingDegreeZeros && absX < 100 )
629 strDegreesX = '0' + strDegreesX;
630 if ( mShowLeadingDegreeZeros && absX < 10 )
631 strDegreesX = '0' + strDegreesX;
632
633 return sign + strDegreesX + QChar( 176 ) + hemisphere;
634}
635
636void QgsGeographicCoordinateNumericFormat::trimTrailingZeros( QString &input, const QgsNumericFormatContext &context ) const
637{
638 const QChar decimal = decimalSeparator().isNull() ? context.decimalSeparator() : decimalSeparator();
639 if ( !showTrailingZeros() && input.contains( decimal ) )
640 {
641 int trimPoint = input.length() - 1;
642
643 while ( input.at( trimPoint ) == context.zeroDigit() )
644 trimPoint--;
645
646 if ( input.at( trimPoint ) == decimal )
647 trimPoint--;
648
649 input.truncate( trimPoint + 1 );
650 }
651}
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:7176
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition qgis.h:7157
#define BUILTIN_UNREACHABLE
Definition qgis.h:7540