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 <QRegExp>
9#include <QString>
10#include <QUrl>
11#include <QUrlQuery>
12
13#include "MarbleDebug.h"
14#include "PlanetFactory.h"
15
16namespace Marble
17{
18
20 : m_geoUri(geoUri)
21 , m_coordinates()
22 , m_planet(PlanetFactory::construct(QStringLiteral("earth")))
23{
24}
25
27{
28 m_geoUri = geoUri;
29 m_coordinates = GeoDataCoordinates();
30 m_planet = PlanetFactory::construct(QStringLiteral("earth"));
31}
32
34{
35 return m_geoUri;
36}
37
39{
40 return m_coordinates;
41}
42
44{
45 return m_planet;
46}
47
48QString GeoUriParser::queryValue(const QUrl &url, const QString &one, const QString &two)
49{
50 QUrlQuery query(url);
51 if (query.hasQueryItem(one)) {
52 return query.queryItemValue(one);
53 } else if (query.hasQueryItem(two)) {
54 return query.queryItemValue(two);
55 }
56
57 return {};
58}
59
61{
62 if (m_geoUri.isEmpty()) {
63 return false;
64 }
65
66 QString const floatRegexp = QStringLiteral("[-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?");
67
68 QRegExp geoUriRegexp(QStringLiteral("geo:(") + floatRegexp + QStringLiteral("),(") + floatRegexp + QStringLiteral("),?(") + floatRegexp
69 + QStringLiteral(R"()?(?:;(crs|u)=([\w\d-]+))?(?:;(crs|u)=([\w\d-]+))?)"),
71 QRegExp::RegExp2);
72
73 if (geoUriRegexp.indexIn(m_geoUri) > -1 && geoUriRegexp.captureCount() > 1) {
74 double const lat = geoUriRegexp.capturedTexts()[1].toDouble();
75 double const lon = geoUriRegexp.capturedTexts()[2].toDouble();
76 double const alt = geoUriRegexp.captureCount() > 2 ? geoUriRegexp.capturedTexts()[3].toDouble() : 0.0;
77
78 if (geoUriRegexp.captureCount() > 3) {
79 // this is not a bug! The '<=' was intended, otherwise we would skip that last Cgroups's data!
80 for (int i = 4; i <= geoUriRegexp.captureCount(); ++i) {
81 if (geoUriRegexp.capturedTexts()[i] == QLatin1StringView("crs")) {
82 for (const QString &str : PlanetFactory::planetList()) {
83 if (geoUriRegexp.captureCount() < i + 1) {
84 i = geoUriRegexp.captureCount() + 1;
85 break;
86 }
87 if (geoUriRegexp.capturedTexts()[i + 1].contains(str, Qt::CaseInsensitive)) {
88 m_planet = PlanetFactory::construct(str);
89 break;
90 }
91 }
92 ++i;
93 } else if (geoUriRegexp.capturedTexts()[i] == QLatin1StringView("u")) {
94 mDebug() << "Captured uncertainty parameter, but this is not supported by Marble (yet).";
95 ++i;
96 }
97 }
98 }
99 GeoDataCoordinates const coordinates(lon, lat, alt, GeoDataCoordinates::Degree);
100 if (coordinates.isValid()) {
101 m_coordinates = coordinates;
102 return true;
103 }
104 }
105 if (m_geoUri.startsWith(QLatin1StringView("worldwind://goto/"))) {
106 m_geoUri.replace(QStringLiteral("goto/"), QStringLiteral("goto/?"));
107 QUrl worldwindUrl(m_geoUri);
108
109 double lat = queryValue(worldwindUrl, QStringLiteral("lat"), QStringLiteral("latitude")).toDouble();
110 double lon = queryValue(worldwindUrl, QStringLiteral("lon"), QStringLiteral("longitude")).toDouble();
111 double alt = queryValue(worldwindUrl, QStringLiteral("alt"), QStringLiteral("altitude")).toDouble();
112 // double bank = getDoubleFromParameter(worldwindUrl, "bank", "");
113 // double dir = getDoubleFromParameter(worldwindUrl, "dir", "direction");
114 // double tilt = getDoubleFromParameter(worldwindUrl, "tilt", "");
115 // QString layer = worldwindUrl.queryItemValue("layer");
116 QString world = queryValue(worldwindUrl, QStringLiteral("world"));
117
118 for (const QString &str : PlanetFactory::planetList()) {
119 if (world.contains(str, Qt::CaseInsensitive)) {
120 m_planet = PlanetFactory::construct(str);
121 break;
122 }
123 }
124
125 GeoDataCoordinates const coordinates(lon, lat, alt, GeoDataCoordinates::Degree);
126 if (coordinates.isValid()) {
127 m_coordinates = coordinates;
128 return true;
129 }
130 }
131
132 return false;
133}
134
135}
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 Sat Dec 21 2024 17:04:14 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.