Marble

GeoUriParser.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2014 Levente Kurusa <levex@linux.com>
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
15namespace Marble {
16
18 : m_geoUri( geoUri ),
19 m_coordinates(),
20 m_planet(PlanetFactory::construct(QStringLiteral("earth")))
21{
22}
23
24void 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
42{
43 return m_planet;
44}
45
46QString 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.
void setGeoUri(const QString &geoUri)
Set the Geo URI to be parsed.
QString geoUri() const
Returns the Geo URI stored in this parser.
GeoUriParser(const QString &geoUri=QString())
Constructs a new GeoUriParser with the given Geo URI.
Planet planet() const
Returns the Planet on which the coordinates are valid.
GeoDataCoordinates coordinates() const
Returns the coordinates parsed.
bool parse()
Parse the given Geo URI.
The PlanetFactory class provides static methods to construct any planet known to Marble.
static Planet construct(const QString &id)
Creates the planet with the given ID, or one with default values if ID is not among planetList()
static QList< QString > planetList()
Provides a list of known planet IDs.
Binds a QML item to a specific geodetic location in screen coordinates.
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
double toDouble(bool *ok) const const
CaseInsensitive
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:17 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.