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