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