File indexing completed on 2024-04-21 03:49:36
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2014 Levente Kurusa <levex@linux.com> 0004 // 0005 0006 #include "GeoUriParser.h" 0007 0008 #include <QString> 0009 #include <QUrl> 0010 #include <QUrlQuery> 0011 0012 #include "PlanetFactory.h" 0013 #include "MarbleDebug.h" 0014 0015 namespace Marble { 0016 0017 GeoUriParser::GeoUriParser( const QString& geoUri ) 0018 : m_geoUri( geoUri ), 0019 m_coordinates(), 0020 m_planet(PlanetFactory::construct(QStringLiteral("earth"))) 0021 { 0022 } 0023 0024 void GeoUriParser::setGeoUri( const QString &geoUri ) 0025 { 0026 m_geoUri = geoUri; 0027 m_coordinates = GeoDataCoordinates(); 0028 m_planet = PlanetFactory::construct(QStringLiteral("earth")); 0029 } 0030 0031 QString GeoUriParser::geoUri() const 0032 { 0033 return m_geoUri; 0034 } 0035 0036 GeoDataCoordinates GeoUriParser::coordinates() const 0037 { 0038 return m_coordinates; 0039 } 0040 0041 Planet GeoUriParser::planet() const 0042 { 0043 return m_planet; 0044 } 0045 0046 QString GeoUriParser::queryValue(const QUrl& url, const QString& one, const QString& two) 0047 { 0048 QUrlQuery query( url ); 0049 if ( query.hasQueryItem( one ) ) { 0050 return query.queryItemValue( one ); 0051 } else if ( query.hasQueryItem( two ) ) { 0052 return query.queryItemValue( two ); 0053 } 0054 0055 return QString(); 0056 } 0057 0058 bool GeoUriParser::parse() 0059 { 0060 if ( m_geoUri.isEmpty() ) { 0061 return false; 0062 } 0063 0064 QString const floatRegexp = "[-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?"; 0065 0066 QRegExp geoUriRegexp( "geo:(" + floatRegexp + "),(" + floatRegexp + "),?(" + floatRegexp + ")?(?:;(crs|u)=([\\w\\d-]+))?(?:;(crs|u)=([\\w\\d-]+))?" , Qt::CaseInsensitive, QRegExp::RegExp2 ); 0067 0068 0069 if ( geoUriRegexp.indexIn( m_geoUri ) > -1 && geoUriRegexp.captureCount() > 1 ) { 0070 double const lat = geoUriRegexp.capturedTexts()[1].toDouble(); 0071 double const lon = geoUriRegexp.capturedTexts()[2].toDouble(); 0072 double const alt = geoUriRegexp.captureCount() > 2 ? geoUriRegexp.capturedTexts()[3].toDouble() : 0.0; 0073 0074 if ( geoUriRegexp.captureCount() > 3 ) { 0075 // this is not a bug! The '<=' was intended, otherwise we would skip that last Cgroups's data! 0076 for ( int i = 4; i <= geoUriRegexp.captureCount(); ++i ) 0077 { 0078 if (geoUriRegexp.capturedTexts()[i] == QLatin1String("crs")) { 0079 for ( const QString& str: PlanetFactory::planetList()) { 0080 if ( geoUriRegexp.captureCount() < i+1 ) { 0081 i = geoUriRegexp.captureCount() + 1; 0082 break; 0083 } 0084 if ( geoUriRegexp.capturedTexts()[i+1].contains(str, Qt::CaseInsensitive) ) { 0085 m_planet = PlanetFactory::construct( str ); 0086 break; 0087 } 0088 } 0089 ++i; 0090 } else if (geoUriRegexp.capturedTexts()[i] == QLatin1String("u")) { 0091 mDebug() << "Captured uncertainty parameter, but this is not supported by Marble (yet)."; 0092 ++i; 0093 } 0094 } 0095 } 0096 GeoDataCoordinates const coordinates( lon, lat, alt, GeoDataCoordinates::Degree ); 0097 if ( coordinates.isValid() ) { 0098 m_coordinates = coordinates; 0099 return true; 0100 } 0101 } 0102 if ( m_geoUri.startsWith(QLatin1String("worldwind://goto/")) ) { 0103 m_geoUri.replace(QStringLiteral("goto/"), QStringLiteral("goto/?")); 0104 QUrl worldwindUrl( m_geoUri ); 0105 0106 double lat = queryValue(worldwindUrl, "lat", "latitude").toDouble(); 0107 double lon = queryValue(worldwindUrl, "lon", "longitude").toDouble(); 0108 double alt = queryValue(worldwindUrl, "alt", "altitude").toDouble(); 0109 //double bank = getDoubleFromParameter(worldwindUrl, "bank", ""); 0110 //double dir = getDoubleFromParameter(worldwindUrl, "dir", "direction"); 0111 //double tilt = getDoubleFromParameter(worldwindUrl, "tilt", ""); 0112 //QString layer = worldwindUrl.queryItemValue("layer"); 0113 QString world = queryValue(worldwindUrl, "world"); 0114 0115 for ( const QString& str: PlanetFactory::planetList()) { 0116 if ( world.contains(str, Qt::CaseInsensitive) ) { 0117 m_planet = PlanetFactory::construct( str ); 0118 break; 0119 } 0120 } 0121 0122 GeoDataCoordinates const coordinates( lon, lat, alt, GeoDataCoordinates::Degree ); 0123 if ( coordinates.isValid() ) { 0124 m_coordinates = coordinates; 0125 return true; 0126 } 0127 } 0128 0129 return false; 0130 } 0131 0132 }