Marble

GeoUriParser.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2014 Levente Kurusa <[email protected]>
4 //
5 
6 #include "GeoUriParser.h"
7 
8 #include <QString>
9 #include <QUrl>
10 #include <QUrlQuery>
11 
12 #include "PlanetFactory.h"
13 #include "MarbleDebug.h"
14 
15 namespace Marble {
16 
18  : m_geoUri( geoUri ),
19  m_coordinates(),
20  m_planet(PlanetFactory::construct(QStringLiteral("earth")))
21 {
22 }
23 
24 void GeoUriParser::setGeoUri( const QString &geoUri )
25 {
26  m_geoUri = geoUri;
27  m_coordinates = GeoDataCoordinates();
28  m_planet = PlanetFactory::construct(QStringLiteral("earth"));
29 }
30 
32 {
33  return m_geoUri;
34 }
35 
37 {
38  return m_coordinates;
39 }
40 
41 Planet GeoUriParser::planet() const
42 {
43  return m_planet;
44 }
45 
46 QString GeoUriParser::queryValue(const QUrl& url, const QString& one, const QString& two)
47 {
48  QUrlQuery query( url );
49  if ( query.hasQueryItem( one ) ) {
50  return query.queryItemValue( one );
51  } else if ( query.hasQueryItem( two ) ) {
52  return query.queryItemValue( two );
53  }
54 
55  return QString();
56 }
57 
59 {
60  if ( m_geoUri.isEmpty() ) {
61  return false;
62  }
63 
64  QString const floatRegexp = "[-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?";
65 
66  QRegExp geoUriRegexp( "geo:(" + floatRegexp + "),(" + floatRegexp + "),?(" + floatRegexp + ")?(?:;(crs|u)=([\\w\\d-]+))?(?:;(crs|u)=([\\w\\d-]+))?" , Qt::CaseInsensitive, QRegExp::RegExp2 );
67 
68 
69  if ( geoUriRegexp.indexIn( m_geoUri ) > -1 && geoUriRegexp.captureCount() > 1 ) {
70  double const lat = geoUriRegexp.capturedTexts()[1].toDouble();
71  double const lon = geoUriRegexp.capturedTexts()[2].toDouble();
72  double const alt = geoUriRegexp.captureCount() > 2 ? geoUriRegexp.capturedTexts()[3].toDouble() : 0.0;
73 
74  if ( geoUriRegexp.captureCount() > 3 ) {
75  // this is not a bug! The '<=' was intended, otherwise we would skip that last Cgroups's data!
76  for ( int i = 4; i <= geoUriRegexp.captureCount(); ++i )
77  {
78  if (geoUriRegexp.capturedTexts()[i] == QLatin1String("crs")) {
79  for ( const QString& str: PlanetFactory::planetList()) {
80  if ( geoUriRegexp.captureCount() < i+1 ) {
81  i = geoUriRegexp.captureCount() + 1;
82  break;
83  }
84  if ( geoUriRegexp.capturedTexts()[i+1].contains(str, Qt::CaseInsensitive) ) {
85  m_planet = PlanetFactory::construct( str );
86  break;
87  }
88  }
89  ++i;
90  } else if (geoUriRegexp.capturedTexts()[i] == QLatin1String("u")) {
91  mDebug() << "Captured uncertainty parameter, but this is not supported by Marble (yet).";
92  ++i;
93  }
94  }
95  }
96  GeoDataCoordinates const coordinates( lon, lat, alt, GeoDataCoordinates::Degree );
97  if ( coordinates.isValid() ) {
98  m_coordinates = coordinates;
99  return true;
100  }
101  }
102  if ( m_geoUri.startsWith(QLatin1String("worldwind://goto/")) ) {
103  m_geoUri.replace(QStringLiteral("goto/"), QStringLiteral("goto/?"));
104  QUrl worldwindUrl( m_geoUri );
105 
106  double lat = queryValue(worldwindUrl, "lat", "latitude").toDouble();
107  double lon = queryValue(worldwindUrl, "lon", "longitude").toDouble();
108  double alt = queryValue(worldwindUrl, "alt", "altitude").toDouble();
109  //double bank = getDoubleFromParameter(worldwindUrl, "bank", "");
110  //double dir = getDoubleFromParameter(worldwindUrl, "dir", "direction");
111  //double tilt = getDoubleFromParameter(worldwindUrl, "tilt", "");
112  //QString layer = worldwindUrl.queryItemValue("layer");
113  QString world = queryValue(worldwindUrl, "world");
114 
115  for ( const QString& str: PlanetFactory::planetList()) {
116  if ( world.contains(str, Qt::CaseInsensitive) ) {
117  m_planet = PlanetFactory::construct( str );
118  break;
119  }
120  }
121 
122  GeoDataCoordinates const coordinates( lon, lat, alt, GeoDataCoordinates::Degree );
123  if ( coordinates.isValid() ) {
124  m_coordinates = coordinates;
125  return true;
126  }
127  }
128 
129  return false;
130 }
131 
132 }
A 3d point representation.
Planet planet() const
Returns the Planet on which the coordinates are valid.
CaseInsensitive
bool parse()
Parse the given Geo URI.
int captureCount() const const
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
The PlanetFactory class provides static methods to construct any planet known to Marble.
Definition: PlanetFactory.h:25
QStringList capturedTexts() const const
GeoDataCoordinates coordinates() const
Returns the coordinates parsed.
static Planet construct(const QString &id)
Creates the planet with the given ID, or one with default values if ID is not among planetList()
GeoUriParser(const QString &geoUri=QString())
Constructs a new GeoUriParser with the given Geo URI.
void setGeoUri(const QString &geoUri)
Set the Geo URI to be parsed.
int indexIn(const QString &str, int offset, QRegExp::CaretMode caretMode) const const
bool isEmpty() const const
static QList< QString > planetList()
Provides a list of known planet IDs.
Binds a QML item to a specific geodetic location in screen coordinates.
bool isValid() const
Returns.
QString geoUri() const
Returns the Geo URI stored in this parser.
double toDouble(bool *ok) const const
QString & replace(int position, int n, QChar after)
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:31
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Sep 25 2023 03:50:19 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.