diff --git a/python/core/auto_generated/qgscoordinateformatter.sip.in b/python/core/auto_generated/qgscoordinateformatter.sip.in index bceb1bb49f3..10381a997c8 100644 --- a/python/core/auto_generated/qgscoordinateformatter.sip.in +++ b/python/core/auto_generated/qgscoordinateformatter.sip.in @@ -72,7 +72,7 @@ Optional ``flags`` can be specified to control the output format. .. seealso:: :py:func:`formatX` %End - static QString format( const QgsPointXY &point, Format format, int precision = 12, FormatFlags flags = FlagDegreesUseStringSuffix ); + static QString format( const QgsPointXY &point, Format format, int precision = 12, FormatFlags flags = FlagDegreesUseStringSuffix, Qgis::CoordinateOrder order = Qgis::CoordinateOrder::XY ); %Docstring Formats a ``point`` according to the specified parameters. @@ -81,12 +81,16 @@ The ``format`` argument indicates the desired display format for the coordinate. The ``precision`` argument gives the number of decimal places to include for coordinates. Optional ``flags`` can be specified to control the output format. + +Since QGIS 3.26 the optional ``order`` argument can be used to control the order of the coordinates. %End - static QString asPair( double x, double y, int precision = 12 ); + static QString asPair( double x, double y, int precision = 12, Qgis::CoordinateOrder order = Qgis::CoordinateOrder::XY ); %Docstring Formats coordinates as an "``x``,``y``" pair, with optional decimal ``precision`` (number of decimal places to include). + +Since QGIS 3.26 the optional ``order`` argument can be used to control the order of the coordinates. %End static QChar separator( ); diff --git a/src/core/qgscoordinateformatter.cpp b/src/core/qgscoordinateformatter.cpp index 7f9bf7db281..3a45e141095 100644 --- a/src/core/qgscoordinateformatter.cpp +++ b/src/core/qgscoordinateformatter.cpp @@ -59,19 +59,38 @@ QString QgsCoordinateFormatter::formatY( double y, QgsCoordinateFormatter::Forma return QString(); //avoid warnings } -QString QgsCoordinateFormatter::format( const QgsPointXY &point, QgsCoordinateFormatter::Format format, int precision, FormatFlags flags ) +QString QgsCoordinateFormatter::format( const QgsPointXY &point, QgsCoordinateFormatter::Format format, int precision, FormatFlags flags, Qgis::CoordinateOrder order ) { - return QStringLiteral( "%1%2%3" ).arg( formatX( point.x(), format, precision, flags ), - QgsCoordinateFormatter::separator(), - formatY( point.y(), format, precision, flags ) ); + const QString formattedX = formatX( point.x(), format, precision, flags ); + const QString formattedY = formatY( point.y(), format, precision, flags ); + + switch ( order ) + { + case Qgis::CoordinateOrder::Default: + case Qgis::CoordinateOrder::XY: + return QStringLiteral( "%1%2%3" ).arg( formattedX, QgsCoordinateFormatter::separator(), formattedY ); + + case Qgis::CoordinateOrder::YX: + return QStringLiteral( "%1%2%3" ).arg( formattedY, QgsCoordinateFormatter::separator(), formattedX ); + } + BUILTIN_UNREACHABLE } -QString QgsCoordinateFormatter::asPair( double x, double y, int precision ) +QString QgsCoordinateFormatter::asPair( double x, double y, int precision, Qgis::CoordinateOrder order ) { - QString s = formatAsPair( x, precision ); - s += QgsCoordinateFormatter::separator(); - s += formatAsPair( y, precision ); - return s; + const QString formattedX = formatAsPair( x, precision ); + const QString formattedY = formatAsPair( y, precision ); + + switch ( order ) + { + case Qgis::CoordinateOrder::Default: + case Qgis::CoordinateOrder::XY: + return QStringLiteral( "%1%2%3" ).arg( formattedX, QgsCoordinateFormatter::separator(), formattedY ); + + case Qgis::CoordinateOrder::YX: + return QStringLiteral( "%1%2%3" ).arg( formattedY, QgsCoordinateFormatter::separator(), formattedX ); + } + BUILTIN_UNREACHABLE } QChar QgsCoordinateFormatter::separator() diff --git a/src/core/qgscoordinateformatter.h b/src/core/qgscoordinateformatter.h index f59bc2cb856..2c6dfbef544 100644 --- a/src/core/qgscoordinateformatter.h +++ b/src/core/qgscoordinateformatter.h @@ -96,14 +96,18 @@ class CORE_EXPORT QgsCoordinateFormatter * The \a precision argument gives the number of decimal places to include for coordinates. * * Optional \a flags can be specified to control the output format. + * + * Since QGIS 3.26 the optional \a order argument can be used to control the order of the coordinates. */ - static QString format( const QgsPointXY &point, Format format, int precision = 12, FormatFlags flags = FlagDegreesUseStringSuffix ); + static QString format( const QgsPointXY &point, Format format, int precision = 12, FormatFlags flags = FlagDegreesUseStringSuffix, Qgis::CoordinateOrder order = Qgis::CoordinateOrder::XY ); /** * Formats coordinates as an "\a x,\a y" pair, with optional decimal \a precision (number * of decimal places to include). + * + * Since QGIS 3.26 the optional \a order argument can be used to control the order of the coordinates. */ - static QString asPair( double x, double y, int precision = 12 ); + static QString asPair( double x, double y, int precision = 12, Qgis::CoordinateOrder order = Qgis::CoordinateOrder::XY ); /** * Returns the character used as X/Y separator, this is a `,` on locales that do not use diff --git a/tests/src/python/test_qgscoordinateformatter.py b/tests/src/python/test_qgscoordinateformatter.py index f2b20613b55..ac1befd1af0 100644 --- a/tests/src/python/test_qgscoordinateformatter.py +++ b/tests/src/python/test_qgscoordinateformatter.py @@ -12,7 +12,11 @@ __copyright__ = 'Copyright 2015, The QGIS Project' import qgis from qgis.testing import unittest -from qgis.core import QgsCoordinateFormatter, QgsPointXY +from qgis.core import ( + QgsCoordinateFormatter, + QgsPointXY, + Qgis +) from qgis.PyQt.QtCore import QLocale @@ -51,11 +55,21 @@ class TestQgsCoordinateFormatter(unittest.TestCase): self.assertEqual(QgsCoordinateFormatter.asPair(20, 10, 2), '20.00,10.00') self.assertEqual(QgsCoordinateFormatter.asPair(20, -10, 2), '20.00,-10.00') + self.assertEqual(QgsCoordinateFormatter.asPair(20, -10, 2, order=Qgis.CoordinateOrder.XY), '20.00,-10.00') + self.assertEqual(QgsCoordinateFormatter.asPair(20, -10, 2, order=Qgis.CoordinateOrder.YX), '-10.00,20.00') + def testFormat(self): self.assertEqual(QgsCoordinateFormatter.format(QgsPointXY(20.1, 30.2), QgsCoordinateFormatter.FormatPair, 0), '20,30') self.assertEqual(QgsCoordinateFormatter.format(QgsPointXY(20.1, 30.2), QgsCoordinateFormatter.FormatPair, 1), '20.1,30.2') self.assertEqual(QgsCoordinateFormatter.format(QgsPointXY(20, 30), QgsCoordinateFormatter.FormatDegreesMinutesSeconds, 0), '20°0′0″E,30°0′0″N') + self.assertEqual(QgsCoordinateFormatter.format(QgsPointXY(20.1, 30.2), QgsCoordinateFormatter.FormatPair, 1, order=Qgis.CoordinateOrder.XY), '20.1,30.2') + self.assertEqual(QgsCoordinateFormatter.format(QgsPointXY(20.1, 30.2), QgsCoordinateFormatter.FormatPair, 1, + order=Qgis.CoordinateOrder.YX), '30.2,20.1') + self.assertEqual( + QgsCoordinateFormatter.format(QgsPointXY(20, 30), QgsCoordinateFormatter.FormatDegreesMinutesSeconds, 0, order=Qgis.CoordinateOrder.YX), + '30°0′0″N,20°0′0″E') + def testFormatXFormatDegreesMinutesSeconds(self): """Test formatting x as DMS"""