mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-17 00:09:36 -04:00
Support decimal degrees with [N,S,W,E] suffixes in the goto locator filter
This commit is contained in:
parent
67e1987fb7
commit
218c124e9d
@ -45,7 +45,7 @@ void QgsGotoLocatorFilter::fetchResults( const QString &string, const QgsLocator
|
||||
bool okY = false;
|
||||
double posX = 0.0;
|
||||
double posY = 0.0;
|
||||
bool posIsDms = false;
|
||||
bool posIsWgs84 = false;
|
||||
const QLocale locale;
|
||||
|
||||
// Coordinates such as 106.8468,-6.3804
|
||||
@ -71,6 +71,22 @@ void QgsGotoLocatorFilter::fetchResults( const QString &string, const QgsLocator
|
||||
}
|
||||
}
|
||||
|
||||
if ( !match.hasMatch() )
|
||||
{
|
||||
// Check if the string is a pair of decimal degrees with [N,S,E,W] suffixes
|
||||
separatorRx = QRegularExpression( QStringLiteral( "^\\s*([0-9\\-\\.]*\\s*[NSEWnsew])[\\s\\,]*([0-9\\-\\.]*\\s*[NSEWnsew])\\s*$" ) );
|
||||
match = separatorRx.match( string.trimmed() );
|
||||
if ( match.hasMatch() )
|
||||
{
|
||||
posIsWgs84 = true;
|
||||
bool isEasting = false;
|
||||
posX = QgsCoordinateUtils::degreeToDecimal( match.captured( 1 ), &okX, &isEasting );
|
||||
posY = QgsCoordinateUtils::degreeToDecimal( match.captured( 2 ), &okY );
|
||||
if ( !isEasting )
|
||||
std::swap( posX, posY );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !match.hasMatch() )
|
||||
{
|
||||
// Check if the string is a pair of degree minute second
|
||||
@ -78,7 +94,7 @@ void QgsGotoLocatorFilter::fetchResults( const QString &string, const QgsLocator
|
||||
match = separatorRx.match( string.trimmed() );
|
||||
if ( match.hasMatch() )
|
||||
{
|
||||
posIsDms = true;
|
||||
posIsWgs84 = true;
|
||||
bool isEasting = false;
|
||||
posX = QgsCoordinateUtils::dmsToDecimal( match.captured( 1 ), &okX, &isEasting );
|
||||
posY = QgsCoordinateUtils::dmsToDecimal( match.captured( 3 ), &okY );
|
||||
@ -94,7 +110,7 @@ void QgsGotoLocatorFilter::fetchResults( const QString &string, const QgsLocator
|
||||
data.insert( QStringLiteral( "point" ), point );
|
||||
|
||||
const bool withinWgs84 = wgs84Crs.bounds().contains( point );
|
||||
if ( !posIsDms && currentCrs != wgs84Crs )
|
||||
if ( !posIsWgs84 && currentCrs != wgs84Crs )
|
||||
{
|
||||
QgsLocatorResult result;
|
||||
result.filter = this;
|
||||
|
@ -142,6 +142,40 @@ QString QgsCoordinateUtils::formatExtentForProject( QgsProject *project, const Q
|
||||
QgsCoordinateUtils::formatCoordinateForProject( project, p2, destCrs, precision ) );
|
||||
}
|
||||
|
||||
double QgsCoordinateUtils::degreeToDecimal( const QString &string, bool *ok, bool *isEasting )
|
||||
{
|
||||
const QString negative( QStringLiteral( "swSW" ) );
|
||||
const QString easting( QStringLiteral( "eEwW" ) );
|
||||
double value = 0.0;
|
||||
bool okValue = false;
|
||||
|
||||
if ( ok )
|
||||
{
|
||||
*ok = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = &okValue;
|
||||
}
|
||||
|
||||
QRegularExpression degreeWithSuffix( QStringLiteral( "^\\s*([0-9\\-\\.]*)\\s*([NSEWnsew])\\s*$" ) );
|
||||
QRegularExpressionMatch match = degreeWithSuffix.match( string );
|
||||
if ( match.hasMatch() )
|
||||
{
|
||||
const QString suffix = match.captured( 2 );
|
||||
value = std::abs( match.captured( 1 ).toDouble( ok ) );
|
||||
if ( ok )
|
||||
{
|
||||
value *= ( negative.contains( suffix ) ? -1 : 1 );
|
||||
if ( isEasting )
|
||||
{
|
||||
*isEasting = easting.contains( suffix );
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
double QgsCoordinateUtils::dmsToDecimal( const QString &string, bool *ok, bool *isEasting )
|
||||
{
|
||||
const QString negative( QStringLiteral( "swSW-" ) );
|
||||
|
@ -92,6 +92,14 @@ class CORE_EXPORT QgsCoordinateUtils
|
||||
*/
|
||||
Q_INVOKABLE static double dmsToDecimal( const QString &string, bool *ok = nullptr, bool *isEasting = nullptr );
|
||||
|
||||
/**
|
||||
* Converts a decimal degree with suffix string to its raw decimal equivalent.
|
||||
* \param string decimal degree to convert (must include a [N,S,E,W] suffix)
|
||||
* \returns Double decimal value
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
Q_INVOKABLE static double degreeToDecimal( const QString &string, bool *ok = nullptr, bool *isEasting = nullptr );
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -374,6 +374,17 @@ void TestQgsAppLocatorFilters::testGoto()
|
||||
QCOMPARE( results.at( 0 ).displayString, QObject::tr( "Go to 1,234.56 789.012 (Map CRS, )" ) );
|
||||
QCOMPARE( results.at( 0 ).userData.toMap()[QStringLiteral( "point" )].value<QgsPointXY>(), QgsPointXY( 1234.56, 789.012 ) );
|
||||
|
||||
// decimal degree with suffixes
|
||||
results = gatherResults( &filter, QStringLiteral( "12.345N, 67.890W" ), QgsLocatorContext() );
|
||||
QCOMPARE( results.count(), 1 );
|
||||
QCOMPARE( results.at( 0 ).displayString, QObject::tr( "Go to -67.89° 12.345° (EPSG:4326 - WGS 84)" ) );
|
||||
QCOMPARE( results.at( 0 ).userData.toMap()[QStringLiteral( "point" )].value<QgsPointXY>(), QgsPointXY( -67.890, 12.345 ) );
|
||||
|
||||
results = gatherResults( &filter, QStringLiteral( "12.345 e, 67.890 s" ), QgsLocatorContext() );
|
||||
QCOMPARE( results.count(), 1 );
|
||||
QCOMPARE( results.at( 0 ).displayString, QObject::tr( "Go to 12.345° -67.89° (EPSG:4326 - WGS 84)" ) );
|
||||
QCOMPARE( results.at( 0 ).userData.toMap()[QStringLiteral( "point" )].value<QgsPointXY>(), QgsPointXY( 12.345, -67.890 ) );
|
||||
|
||||
// degree/minuste/second coordinates goto
|
||||
// easting northing
|
||||
results = gatherResults( &filter, QStringLiteral( "40deg 1' 0\" E 11deg 55' 0\" S" ), QgsLocatorContext() );
|
||||
|
@ -40,6 +40,7 @@ set(TESTS
|
||||
testqgsconnectionpool.cpp
|
||||
testqgscoordinatereferencesystemregistry.cpp
|
||||
testqgscoordinatetransform.cpp
|
||||
testqgscoordinateutils.cpp
|
||||
testqgscopyfiletask.cpp
|
||||
testqgscredentials.cpp
|
||||
testqgscurve.cpp
|
||||
|
66
tests/src/core/testqgscoordinateutils.cpp
Normal file
66
tests/src/core/testqgscoordinateutils.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/***************************************************************************
|
||||
testqgscoordinateutils.cpp
|
||||
--------------------------------------
|
||||
Date : March 2022
|
||||
Copyright : (C) 2022 Mathieu Pellerin
|
||||
Email : nirvn dot asia at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QString>
|
||||
#include "qgstest.h"
|
||||
#include "qgscoordinateutils.h"
|
||||
|
||||
class TestQgsCoordinateUtils : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
|
||||
void testDegreeWithSuffix();
|
||||
};
|
||||
|
||||
|
||||
void TestQgsCoordinateUtils::testDegreeWithSuffix()
|
||||
{
|
||||
bool ok = false ;
|
||||
bool isEasting = false;
|
||||
double value = 0.0;
|
||||
|
||||
value = QgsCoordinateUtils::degreeToDecimal( QStringLiteral( "1.234W" ), &ok, &isEasting );
|
||||
QCOMPARE( ok, true );
|
||||
QCOMPARE( isEasting, true );
|
||||
QCOMPARE( value, -1.234 );
|
||||
|
||||
value = QgsCoordinateUtils::degreeToDecimal( QStringLiteral( "-1.234 w" ), &ok, &isEasting );
|
||||
QCOMPARE( ok, true );
|
||||
QCOMPARE( isEasting, true );
|
||||
QCOMPARE( value, -1.234 );
|
||||
|
||||
value = QgsCoordinateUtils::degreeToDecimal( QStringLiteral( "1.234s" ), &ok, &isEasting );
|
||||
QCOMPARE( ok, true );
|
||||
QCOMPARE( isEasting, false );
|
||||
QCOMPARE( value, -1.234 );
|
||||
|
||||
value = QgsCoordinateUtils::degreeToDecimal( QStringLiteral( "1.234N" ), &ok, &isEasting );
|
||||
QCOMPARE( ok, true );
|
||||
QCOMPARE( isEasting, false );
|
||||
QCOMPARE( value, 1.234 );
|
||||
|
||||
value = QgsCoordinateUtils::degreeToDecimal( QStringLiteral( "1.234 e" ), &ok, &isEasting );
|
||||
QCOMPARE( ok, true );
|
||||
QCOMPARE( isEasting, true );
|
||||
QCOMPARE( value, 1.234 );
|
||||
|
||||
value = QgsCoordinateUtils::degreeToDecimal( QStringLiteral( "bad string" ), &ok, &isEasting );
|
||||
QCOMPARE( ok, false );
|
||||
QCOMPARE( value, 0.0 );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsCoordinateUtils )
|
||||
#include "testqgscoordinateutils.moc"
|
Loading…
x
Reference in New Issue
Block a user