Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qgeocodereplyosm.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 Aaron McCarthy <mccarthy.aaron@gmail.com>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtCore/QJsonDocument>
7#include <QtCore/QJsonObject>
8#include <QtCore/QJsonArray>
9#include <QtPositioning/QGeoCoordinate>
10#include <QtPositioning/QGeoAddress>
11#include <QtPositioning/QGeoLocation>
12#include <QtPositioning/QGeoRectangle>
13#include <QtLocation/private/qgeojson_p.h>
14
16
17QGeoCodeReplyOsm::QGeoCodeReplyOsm(QNetworkReply *reply, bool includeExtraData, QObject *parent)
18: QGeoCodeReply(parent), m_includeExtraData(includeExtraData)
19{
20 if (!reply) {
21 setError(UnknownError, QStringLiteral("Null reply"));
22 return;
23 }
24 connect(reply, &QNetworkReply::finished,
25 this, &QGeoCodeReplyOsm::networkReplyFinished);
26 connect(reply, &QNetworkReply::errorOccurred,
27 this, &QGeoCodeReplyOsm::networkReplyError);
28 connect(this, &QGeoCodeReply::aborted, reply, &QNetworkReply::abort);
29 connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
30 setLimit(1);
31 setOffset(0);
32}
33
34QGeoCodeReplyOsm::~QGeoCodeReplyOsm()
35{
36}
37
38static QGeoAddress parseAddressObject(const QJsonObject &object)
39{
40 QGeoAddress address;
41 address.setText(object.value(QStringLiteral("display_name")).toString());
42 QJsonObject ao = object.value(QStringLiteral("address")).toObject();
43 // setCountry
44 address.setCountry(ao.value(QStringLiteral("country")).toString());
45 // setCountryCode
46 address.setCountryCode(ao.value(QStringLiteral("country_code")).toString());
47 // setState
48 address.setState(ao.value(QStringLiteral("state")).toString());
49 // setCity
50 if (ao.contains(QLatin1String("city")))
51 address.setCity(ao.value(QStringLiteral("city")).toString());
52 else if (ao.contains(QLatin1String("town")))
53 address.setCity(ao.value(QLatin1String("town")).toString());
54 else if (ao.contains(QLatin1String("village")))
55 address.setCity(ao.value(QLatin1String("village")).toString());
56 else
57 address.setCity(ao.value(QLatin1String("hamlet")).toString());
58 // setDistrict
59 address.setDistrict(ao.value(QStringLiteral("suburb")).toString());
60 // setPostalCode
61 address.setPostalCode(ao.value(QStringLiteral("postcode")).toString());
62 // setStreet
63 address.setStreet(ao.value(QStringLiteral("road")).toString());
64 return address;
65}
66
67static void injectExtra(QGeoLocation &location, const QJsonObject &object)
68{
69 QVariantMap extra;
70 static const QList<QString> extraKeys = { QStringLiteral("geojson"),
71 QStringLiteral("icon"),
72 QStringLiteral("importance"),
73 QStringLiteral("type"),
74 QStringLiteral("osm_id"),
75 QStringLiteral("osm_type"),
76 QStringLiteral("licence"),
77 QStringLiteral("place_id"),
78 QStringLiteral("class") };
79
80 for (const auto &k: extraKeys) {
81 if (object.contains(k)) {
82 extra[k] = object.value(k).toVariant();
83 if (k == QStringLiteral("geojson"))
84 extra[QStringLiteral("geojson_model")] =
85 QGeoJson::importGeoJson(QJsonDocument::fromVariant(extra[k]));
86 }
87 }
88
89 location.setExtendedAttributes(extra);
90}
91
92void QGeoCodeReplyOsm::networkReplyFinished()
93{
94 QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
95 reply->deleteLater();
96
97 if (reply->error() != QNetworkReply::NoError)
98 return;
99
100 QList<QGeoLocation> locations;
101 QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
102
103 if (document.isObject()) {
104 QJsonObject object = document.object();
105
106 QGeoCoordinate coordinate;
107
108 coordinate.setLatitude(object.value(QStringLiteral("lat")).toString().toDouble());
109 coordinate.setLongitude(object.value(QStringLiteral("lon")).toString().toDouble());
110
111 QGeoLocation location;
112 location.setCoordinate(coordinate);
113 location.setAddress(parseAddressObject(object));
114
115 if (m_includeExtraData)
116 injectExtra(location, object);
117 locations.append(location);
118
119 setLocations(locations);
120 } else if (document.isArray()) {
121 QJsonArray results = document.array();
122
123 for (int i = 0; i < results.count(); ++i) {
124 if (!results.at(i).isObject())
125 continue;
126
127 QJsonObject object = results.at(i).toObject();
128
129 QGeoCoordinate coordinate;
130
131 coordinate.setLatitude(object.value(QStringLiteral("lat")).toString().toDouble());
132 coordinate.setLongitude(object.value(QStringLiteral("lon")).toString().toDouble());
133
134 QGeoRectangle rectangle;
135
136 if (object.contains(QStringLiteral("boundingbox"))) {
137 QJsonArray a = object.value(QStringLiteral("boundingbox")).toArray();
138 if (a.count() == 4) {
139 rectangle.setTopLeft(QGeoCoordinate(a.at(1).toString().toDouble(),
140 a.at(2).toString().toDouble()));
141 rectangle.setBottomRight(QGeoCoordinate(a.at(0).toString().toDouble(),
142 a.at(3).toString().toDouble()));
143 }
144 }
145
146 QGeoLocation location;
147 location.setCoordinate(coordinate);
148 location.setBoundingShape(rectangle);
149 location.setAddress(parseAddressObject(object));
150 if (m_includeExtraData)
151 injectExtra(location, object);
152 locations.append(location);
153 }
154
155 }
156
157 setLocations(locations);
158 setFinished(true);
159}
160
161void QGeoCodeReplyOsm::networkReplyError(QNetworkReply::NetworkError error)
162{
163 Q_UNUSED(error);
164 QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
165 reply->deleteLater();
166 setError(QGeoCodeReply::CommunicationError, reply->errorString());
167}
168
169QT_END_NAMESPACE
The QNetworkReply class contains the data and headers for a request sent with QNetworkAccessManager.
QObject * parent
Definition qobject.h:73
Combined button and popup list for selecting options.
static QGeoAddress parseAddressObject(const QJsonObject &object)
static void injectExtra(QGeoLocation &location, const QJsonObject &object)