File: GeoUriParser.cpp

package info (click to toggle)
marble 4%3A17.08.3-3.2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 141,596 kB
  • sloc: cpp: 189,322; xml: 39,420; ansic: 7,204; python: 2,244; sh: 1,137; makefile: 236; perl: 222; ruby: 97; java: 66
file content (137 lines) | stat: -rw-r--r-- 4,643 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014      Levente Kurusa <levex@linux.com>
//

#include <QString>
#include <QUrl>
#include <QUrlQuery>

#include "Planet.h"
#include "PlanetFactory.h"
#include "GeoUriParser.h"
#include "MarbleDebug.h"

namespace Marble {

GeoUriParser::GeoUriParser( const QString& geoUri )
    : m_geoUri( geoUri ),
      m_coordinates(),
      m_planet(PlanetFactory::construct(QStringLiteral("earth")))
{
}

void GeoUriParser::setGeoUri( const QString &geoUri )
{
    m_geoUri = geoUri;
    m_coordinates = GeoDataCoordinates();
    m_planet = PlanetFactory::construct(QStringLiteral("earth"));
}

QString GeoUriParser::geoUri() const
{
    return m_geoUri;
}

GeoDataCoordinates GeoUriParser::coordinates() const
{
    return m_coordinates;
}

Planet GeoUriParser::planet() const
{
    return m_planet;
}

QString GeoUriParser::queryValue(const QUrl& url, const QString& one, const QString& two)
{
    QUrlQuery query( url );
    if ( query.hasQueryItem( one ) ) {
        return query.queryItemValue( one );
    } else if ( query.hasQueryItem( two )  ) {
        return query.queryItemValue( two );
    }

    return QString();
}

bool GeoUriParser::parse()
{
    if ( m_geoUri.isEmpty() ) {
        return false;
    }

    QString const floatRegexp = "[-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?";

    QRegExp geoUriRegexp( "geo:(" + floatRegexp + "),(" + floatRegexp + "),?(" + floatRegexp + ")?(?:;(crs|u)=([\\w\\d-]+))?(?:;(crs|u)=([\\w\\d-]+))?" , Qt::CaseInsensitive, QRegExp::RegExp2 );


    if ( geoUriRegexp.indexIn( m_geoUri ) > -1 && geoUriRegexp.captureCount() > 1 ) {
        double const lat = geoUriRegexp.capturedTexts()[1].toDouble();
        double const lon = geoUriRegexp.capturedTexts()[2].toDouble();
        double const alt = geoUriRegexp.captureCount() > 2 ? geoUriRegexp.capturedTexts()[3].toDouble() : 0.0;

        if ( geoUriRegexp.captureCount() > 3 ) {
            // this is not a bug! The '<=' was intended, otherwise we would skip that last Cgroups's data!
            for ( int i = 4; i <= geoUriRegexp.captureCount(); ++i )
            {
                if (geoUriRegexp.capturedTexts()[i] == QLatin1String("crs")) {
                    for ( const QString& str: PlanetFactory::planetList()) {
                        if ( geoUriRegexp.captureCount() < i+1 ) {
                            i = geoUriRegexp.captureCount() + 1;
                            break;
                        }
                        if ( geoUriRegexp.capturedTexts()[i+1].contains(str, Qt::CaseInsensitive) ) {
                            m_planet = PlanetFactory::construct( str );
                            break;
                        }
                    }
                    ++i;
                } else if (geoUriRegexp.capturedTexts()[i] == QLatin1String("u")) {
                    mDebug() << "Captured uncertainity parameter, but this is not supported by Marble (yet).";
                    ++i;
                }
            }
        }
        GeoDataCoordinates const coordinates( lon, lat, alt, GeoDataCoordinates::Degree );
        if ( coordinates.isValid() ) {
            m_coordinates = coordinates;
            return true;
        }
    }
    if ( m_geoUri.startsWith(QLatin1String("worldwind://goto/")) ) {
        m_geoUri.replace(QStringLiteral("goto/"), QStringLiteral("goto/?"));
        QUrl worldwindUrl( m_geoUri );

        double lat = queryValue(worldwindUrl, "lat", "latitude").toDouble();
        double lon = queryValue(worldwindUrl, "lon", "longitude").toDouble();
        double alt = queryValue(worldwindUrl, "alt", "altitude").toDouble();
        //double bank = getDoubleFromParameter(worldwindUrl, "bank", "");
        //double dir = getDoubleFromParameter(worldwindUrl, "dir", "direction");
        //double tilt = getDoubleFromParameter(worldwindUrl, "tilt", "");
        //QString layer = worldwindUrl.queryItemValue("layer");
        QString world = queryValue(worldwindUrl, "world");

        for ( const QString& str: PlanetFactory::planetList()) {
            if ( world.contains(str, Qt::CaseInsensitive) ) {
                m_planet = PlanetFactory::construct( str );
                break;
            }
        }

        GeoDataCoordinates const coordinates( lon, lat, alt, GeoDataCoordinates::Degree );
        if ( coordinates.isValid() ) {
            m_coordinates = coordinates;
            return true;
        }
    }

    return false;
}

}