QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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#include "qgis.h"
19
20#include <memory>
21#include <iostream>
22#include <locale>
23#include <iomanip>
24
25struct formatter : std::numpunct<wchar_t>
26{
27 formatter( QChar thousands, bool showThousands, QChar decimal )
28 : mThousands( thousands.unicode() )
29 , mDecimal( decimal.unicode() )
30 , mShowThousands( showThousands )
31 {}
32 wchar_t do_decimal_point() const override { return mDecimal; }
33 wchar_t do_thousands_sep() const override { return mThousands; }
34 std::string do_grouping() const override { return mShowThousands ? "\3" : "\0"; }
35
36 wchar_t mThousands;
37 wchar_t mDecimal;
38 bool mShowThousands = true;
39};
40
41
43{
44}
45
47{
48 return QStringLiteral( "geographiccoordinate" );
49}
50
52{
53 return QObject::tr( "Geographic Coordinate" );
54}
55
57{
58 return DEFAULT_SORT_KEY;
59}
60
62{
63 return 3.7555;
64}
65
67{
68 const QChar decimal = decimalSeparator().isNull() ? context.decimalSeparator() : decimalSeparator();
69 std::basic_stringstream<wchar_t> os;
70 os.imbue( std::locale( os.getloc(), new formatter( thousandsSeparator().isNull() ? context.thousandsSeparator() : thousandsSeparator(),
71 false,
72 decimal ) ) );
73
74 switch ( context.interpretation() )
75 {
77 return formatLatitude( value, os, context );
78
81 return formatLongitude( value, os, context );
82 }
84}
85
87{
88 return new QgsGeographicCoordinateNumericFormat( *this );
89}
90
91QgsNumericFormat *QgsGeographicCoordinateNumericFormat::create( const QVariantMap &configuration, const QgsReadWriteContext &context ) const
92{
93 std::unique_ptr< QgsGeographicCoordinateNumericFormat > res = std::make_unique< QgsGeographicCoordinateNumericFormat >();
94 res->setConfiguration( configuration, context );
95 res->mAngleFormat = qgsEnumKeyToValue( configuration.value( QStringLiteral( "angle_format" ) ).toString(), AngleFormat::DecimalDegrees );
96 res->mShowLeadingZeros = configuration.value( QStringLiteral( "show_leading_zeros" ), false ).toBool();
97 res->mShowLeadingDegreeZeros = configuration.value( QStringLiteral( "show_leading_degree_zeros" ), false ).toBool();
98 res->mUseSuffix = configuration.value( QStringLiteral( "show_suffix" ), false ).toBool();
99 return res.release();
100}
101
103{
104 QVariantMap res = QgsBasicNumericFormat::configuration( context );
105 res.insert( QStringLiteral( "angle_format" ), qgsEnumValueToKey( mAngleFormat ) );
106 res.insert( QStringLiteral( "show_leading_zeros" ), mShowLeadingZeros );
107 res.insert( QStringLiteral( "show_leading_degree_zeros" ), mShowLeadingDegreeZeros );
108 res.insert( QStringLiteral( "show_suffix" ), mUseSuffix );
109 return res;
110}
111
113{
114 return mAngleFormat;
115}
116
118{
119 mAngleFormat = format;
120}
121
122void QgsGeographicCoordinateNumericFormat::setConfiguration( const QVariantMap &configuration, const QgsReadWriteContext &context )
123{
125 mAngleFormat = qgsEnumKeyToValue( configuration.value( QStringLiteral( "angle_format" ) ).toString(), AngleFormat::DecimalDegrees );
126 mShowLeadingZeros = configuration.value( QStringLiteral( "show_leading_zeros" ), false ).toBool();
127 mShowLeadingDegreeZeros = configuration.value( QStringLiteral( "show_leading_degree_zeros" ), false ).toBool();
128 mUseSuffix = configuration.value( QStringLiteral( "show_suffix" ), false ).toBool();
129}
130
132{
133 return mShowLeadingZeros;
134}
135
137{
138 mShowLeadingZeros = newShowLeadingZeros;
139}
140
142{
143 return mShowLeadingDegreeZeros;
144}
145
147{
148 mShowLeadingDegreeZeros = show;
149}
150
152{
153 return mUseSuffix;
154}
155
157{
158 mUseSuffix = show;
159}
160
161QString QgsGeographicCoordinateNumericFormat::formatLongitude( double value, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
162{
163 switch ( mAngleFormat )
164 {
166 return formatLongitudeAsDegreesMinutesSeconds( value, ss, context );
168 return formatLongitudeAsDegreesMinutes( value, ss, context );
170 return formatLongitudeAsDegrees( value, ss, context );
171 }
173}
174
175QString QgsGeographicCoordinateNumericFormat::formatLatitude( double value, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
176{
177 switch ( mAngleFormat )
178 {
180 return formatLatitudeAsDegreesMinutesSeconds( value, ss, context );
182 return formatLatitudeAsDegreesMinutes( value, ss, context );
184 return formatLatitudeAsDegrees( value, ss, context );
185 }
187}
188
189QString QgsGeographicCoordinateNumericFormat::formatLatitudeAsDegreesMinutesSeconds( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
190{
191 //first, limit latitude to -180 to 180 degree range
192 double wrappedY = std::fmod( val, 180.0 );
193 //next, wrap around latitudes > 90 or < -90 degrees, so that eg "110S" -> "70N"
194 if ( wrappedY > 90.0 )
195 {
196 wrappedY = wrappedY - 180.0;
197 }
198 else if ( wrappedY < -90.0 )
199 {
200 wrappedY = wrappedY + 180.0;
201 }
202
203 const int precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
204
205 int degreesY = int( std::fabs( wrappedY ) );
206 const double floatMinutesY = ( std::fabs( wrappedY ) - degreesY ) * 60.0;
207 int intMinutesY = int( floatMinutesY );
208 double secondsY = ( floatMinutesY - intMinutesY ) * 60.0;
209
210 //make sure rounding to specified precision doesn't create seconds >= 60
211 if ( std::round( secondsY * precisionMultiplier ) >= 60 * precisionMultiplier )
212 {
213 secondsY = std::max( secondsY - 60, 0.0 );
214 intMinutesY++;
215 if ( intMinutesY >= 60 )
216 {
217 intMinutesY -= 60;
218 degreesY++;
219 }
220 }
221
222 QString hemisphere;
223 QString sign;
224 if ( mUseSuffix )
225 {
226 hemisphere = wrappedY < 0 ? QObject::tr( "S" ) : QObject::tr( "N" );
227 }
228 else
229 {
230 if ( wrappedY < 0 )
231 {
232 sign = context.negativeSign();
233 }
234 }
235 //check if coordinate is all zeros for the specified precision, and if so,
236 //remove the sign and hemisphere strings
237 if ( degreesY == 0 && intMinutesY == 0 && std::round( secondsY * precisionMultiplier ) == 0 )
238 {
239 sign = QString();
240 hemisphere.clear();
241 }
242
243 QString strMinutesY;
244 QString strSecondsY;
245
246 ss << std::fixed << std::setprecision( 0 );
247 ss << intMinutesY;
248
249 strMinutesY = QString::fromStdWString( ss.str() );
250 ss.str( std::wstring() );
251
252 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
253 ss << secondsY;
254 strSecondsY = QString::fromStdWString( ss.str() );
255 ss.str( std::wstring() );
256
257 trimTrailingZeros( strSecondsY, context );
258
259 //pad with leading digits if required
260 if ( mShowLeadingZeros && intMinutesY < 10 )
261 strMinutesY = '0' + strMinutesY;
262
263 if ( mShowLeadingZeros && secondsY < 10 )
264 strSecondsY = '0' + strSecondsY;
265
266 ss << std::fixed << std::setprecision( 0 );
267 ss << degreesY;
268 QString degreesYStr = QString::fromStdWString( ss.str() );
269 ss.str( std::wstring() );
270
271 if ( mShowLeadingDegreeZeros )
272 degreesYStr = QString( QStringLiteral( "00" ) + degreesYStr ).right( 2 );
273
274 return sign + degreesYStr + QChar( 176 ) +
275 strMinutesY + QChar( 0x2032 ) +
276 strSecondsY + QChar( 0x2033 ) +
277 hemisphere;
278}
279
280QString QgsGeographicCoordinateNumericFormat::formatLongitudeAsDegreesMinutesSeconds( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
281{
282 //first, limit longitude to -360 to 360 degree range
283 double wrappedX = std::fmod( val, 360.0 );
284 //next, wrap around longitudes > 180 or < -180 degrees, so that eg "190E" -> "170W"
285 if ( wrappedX > 180.0 )
286 {
287 wrappedX = wrappedX - 360.0;
288 }
289 else if ( wrappedX < -180.0 )
290 {
291 wrappedX = wrappedX + 360.0;
292 }
293
294 const int precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
295
296 int degreesX = int( std::fabs( wrappedX ) );
297 const double floatMinutesX = ( std::fabs( wrappedX ) - degreesX ) * 60.0;
298 int intMinutesX = int( floatMinutesX );
299 double secondsX = ( floatMinutesX - intMinutesX ) * 60.0;
300
301 //make sure rounding to specified precision doesn't create seconds >= 60
302 if ( std::round( secondsX * precisionMultiplier ) >= 60 * precisionMultiplier )
303 {
304 secondsX = std::max( secondsX - 60, 0.0 );
305 intMinutesX++;
306 if ( intMinutesX >= 60 )
307 {
308 intMinutesX -= 60;
309 degreesX++;
310 }
311 }
312
313 QString hemisphere;
314 QString sign;
315 if ( mUseSuffix )
316 {
317 hemisphere = wrappedX < 0 ? QObject::tr( "W" ) : QObject::tr( "E" );
318 }
319 else
320 {
321 if ( wrappedX < 0 )
322 {
323 sign = context.negativeSign();
324 }
325 }
326 //check if coordinate is all zeros for the specified precision, and if so,
327 //remove the sign and hemisphere strings
328 if ( degreesX == 0 && intMinutesX == 0 && std::round( secondsX * precisionMultiplier ) == 0 )
329 {
330 sign.clear();
331 hemisphere.clear();
332 }
333
334 //also remove directional prefix from 180 degree longitudes
335 if ( degreesX == 180 && intMinutesX == 0 && std::round( secondsX * precisionMultiplier ) == 0 )
336 {
337 hemisphere.clear();
338 }
339
340 QString minutesX;
341 QString strSecondsX;
342
343 ss << std::fixed << std::setprecision( 0 );
344 ss << intMinutesX;
345
346 minutesX = QString::fromStdWString( ss.str() );
347 ss.str( std::wstring() );
348
349 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
350 ss << secondsX;
351 strSecondsX = QString::fromStdWString( ss.str() );
352 ss.str( std::wstring() );
353
354 trimTrailingZeros( strSecondsX, context );
355
356 //pad with leading digits if required
357 if ( mShowLeadingZeros && intMinutesX < 10 )
358 minutesX = '0' + minutesX;
359
360 if ( mShowLeadingZeros && secondsX < 10 )
361 strSecondsX = '0' + strSecondsX;
362
363 ss << std::fixed << std::setprecision( 0 );
364 ss << degreesX;
365 QString degreesXStr = QString::fromStdWString( ss.str() );
366 ss.str( std::wstring() );
367
368 if ( mShowLeadingDegreeZeros )
369 degreesXStr = QString( QStringLiteral( "000" ) + degreesXStr ).right( 3 );
370
371 return sign + degreesXStr + QChar( 176 ) +
372 minutesX + QChar( 0x2032 ) +
373 strSecondsX + QChar( 0x2033 ) +
374 hemisphere;
375}
376
377QString QgsGeographicCoordinateNumericFormat::formatLatitudeAsDegreesMinutes( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
378{
379 //first, limit latitude to -180 to 180 degree range
380 double wrappedY = std::fmod( val, 180.0 );
381 //next, wrap around latitudes > 90 or < -90 degrees, so that eg "110S" -> "70N"
382 if ( wrappedY > 90.0 )
383 {
384 wrappedY = wrappedY - 180.0;
385 }
386 else if ( wrappedY < -90.0 )
387 {
388 wrappedY = wrappedY + 180.0;
389 }
390
391 int degreesY = int( std::fabs( wrappedY ) );
392 double floatMinutesY = ( std::fabs( wrappedY ) - degreesY ) * 60.0;
393
394 const int precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
395
396 //make sure rounding to specified precision doesn't create minutes >= 60
397 if ( std::round( floatMinutesY * precisionMultiplier ) >= 60 * precisionMultiplier )
398 {
399 floatMinutesY = std::max( floatMinutesY - 60, 0.0 );
400 degreesY++;
401 }
402
403 QString hemisphere;
404 QString sign;
405 if ( mUseSuffix )
406 {
407 hemisphere = wrappedY < 0 ? QObject::tr( "S" ) : QObject::tr( "N" );
408 }
409 else
410 {
411 if ( wrappedY < 0 )
412 {
413 sign = context.negativeSign();
414 }
415 }
416 //check if coordinate is all zeros for the specified precision, and if so,
417 //remove the sign and hemisphere strings
418 if ( degreesY == 0 && std::round( floatMinutesY * precisionMultiplier ) == 0 )
419 {
420 sign.clear();
421 hemisphere.clear();
422 }
423
424 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
425 ss << floatMinutesY;
426 QString strMinutesY = QString::fromStdWString( ss.str() );
427 ss.str( std::wstring() );
428
429 trimTrailingZeros( strMinutesY, context );
430
431 //pad with leading digits if required
432 if ( mShowLeadingZeros && floatMinutesY < 10 )
433 strMinutesY = '0' + strMinutesY;
434
435 ss << std::fixed << std::setprecision( 0 );
436 ss << degreesY;
437 QString degreesYStr = QString::fromStdWString( ss.str() );
438 ss.str( std::wstring() );
439
440 if ( mShowLeadingDegreeZeros )
441 degreesYStr = QString( QStringLiteral( "00" ) + degreesYStr ).right( 2 );
442
443 return sign + degreesYStr + QChar( 176 ) +
444 strMinutesY + QChar( 0x2032 ) +
445 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 int 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( QStringLiteral( "000" ) + degreesXStr ).right( 3 );
519
520 return sign + degreesXStr + QChar( 176 ) +
521 strMinutesX + QChar( 0x2032 ) +
522 hemisphere;
523}
524
525QString QgsGeographicCoordinateNumericFormat::formatLatitudeAsDegrees( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
526{
527 //first, limit latitude to -180 to 180 degree range
528 double wrappedY = std::fmod( val, 180.0 );
529 //next, wrap around latitudes > 90 or < -90 degrees, so that eg "110S" -> "70N"
530 if ( wrappedY > 90.0 )
531 {
532 wrappedY = wrappedY - 180.0;
533 }
534 else if ( wrappedY < -90.0 )
535 {
536 wrappedY = wrappedY + 180.0;
537 }
538
539 const double absY = std::fabs( wrappedY );
540
541 const int precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
542
543 QString hemisphere;
544 QString sign;
545 if ( mUseSuffix )
546 {
547 hemisphere = wrappedY < 0 ? QObject::tr( "S" ) : QObject::tr( "N" );
548 }
549 else
550 {
551 if ( wrappedY < 0 )
552 {
553 sign = context.negativeSign();
554 }
555 }
556 //check if coordinate is all zeros for the specified precision, and if so,
557 //remove the sign and hemisphere strings
558 if ( std::round( absY * precisionMultiplier ) == 0 )
559 {
560 sign.clear();
561 hemisphere.clear();
562 }
563
564 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
565 ss << absY;
566 QString strDegreesY = QString::fromStdWString( ss.str() );
567 ss.str( std::wstring() );
568
569 trimTrailingZeros( strDegreesY, context );
570
571 if ( mShowLeadingDegreeZeros && absY < 10 )
572 strDegreesY = '0' + strDegreesY;
573
574 return sign + strDegreesY + QChar( 176 ) + hemisphere;
575}
576
577QString QgsGeographicCoordinateNumericFormat::formatLongitudeAsDegrees( double val, std::basic_stringstream<wchar_t> &ss, const QgsNumericFormatContext &context ) const
578{
579 //first, limit longitude to -360 to 360 degree range
580 double wrappedX = std::fmod( val, 360.0 );
581 //next, wrap around longitudes > 180 or < -180 degrees, so that eg "190E" -> "170W"
582 if ( wrappedX > 180.0 )
583 {
584 wrappedX = wrappedX - 360.0;
585 }
586 else if ( wrappedX < -180.0 )
587 {
588 wrappedX = wrappedX + 360.0;
589 }
590
591 const double absX = std::fabs( wrappedX );
592
593 const int precisionMultiplier = std::pow( 10.0, numberDecimalPlaces() );
594
595 QString hemisphere;
596 QString sign;
597 if ( mUseSuffix )
598 {
599 hemisphere = wrappedX < 0 ? QObject::tr( "W" ) : QObject::tr( "E" );
600 }
601 else
602 {
603 if ( wrappedX < 0 )
604 {
605 sign = context.negativeSign();
606 }
607 }
608 //check if coordinate is all zeros for the specified precision, and if so,
609 //remove the sign and hemisphere strings
610 if ( std::round( absX * precisionMultiplier ) == 0 )
611 {
612 sign.clear();
613 hemisphere.clear();
614 }
615
616 //also remove directional prefix from 180 degree longitudes
617 if ( std::round( absX * precisionMultiplier ) == 180 * precisionMultiplier )
618 {
619 sign.clear();
620 hemisphere.clear();
621 }
622
623 ss << std::fixed << std::setprecision( numberDecimalPlaces() );
624 ss << absX;
625 QString strDegreesX = QString::fromStdWString( ss.str() );
626 ss.str( std::wstring() );
627
628 trimTrailingZeros( strDegreesX, context );
629
630 if ( mShowLeadingDegreeZeros && absX < 100 )
631 strDegreesX = '0' + strDegreesX;
632 if ( mShowLeadingDegreeZeros && absX < 10 )
633 strDegreesX = '0' + strDegreesX;
634
635 return sign + strDegreesX + QChar( 176 ) + hemisphere;
636}
637
638void QgsGeographicCoordinateNumericFormat::trimTrailingZeros( QString &input, const QgsNumericFormatContext &context ) const
639{
640 const QChar decimal = decimalSeparator().isNull() ? context.decimalSeparator() : decimalSeparator();
641 if ( !showTrailingZeros() && input.contains( decimal ) )
642 {
643 int trimPoint = input.length() - 1;
644
645 while ( input.at( trimPoint ) == context.zeroDigit() )
646 trimPoint--;
647
648 if ( input.at( trimPoint ) == decimal )
649 trimPoint--;
650
651 input.truncate( trimPoint + 1 );
652 }
653}
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.
A numeric formatter which returns a text representation of a geographic coordinate (latitude or longi...
void setConfiguration(const QVariantMap &configuration, const QgsReadWriteContext &context) override
Sets the format's configuration.
@ DegreesMinutes
Degrees and decimal minutes, eg 30 degrees 45.55'.
@ DecimalDegrees
Decimal degrees, eg 30.7555 degrees.
@ 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.
A numeric formatter allows for formatting a numeric value for display, using a variety of different f...
static constexpr int DEFAULT_SORT_KEY
The class is used as a container of context for various read/write operations on other 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:2700
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition: qgis.h:2681
#define BUILTIN_UNREACHABLE
Definition: qgis.h:3148
wchar_t do_decimal_point() const override
std::string do_grouping() const override
wchar_t do_thousands_sep() const override
formatter(QChar thousands, bool showThousands, QChar decimal)