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 address.setStreetNumber(ao.value(QStringLiteral("house_number")).toString());
65 return address;
66}
67
68static void injectExtra(QGeoLocation &location, const QJsonObject &object)
69{
70 QVariantMap extra;
71 static const QList<QString> extraKeys = { QStringLiteral("geojson"),
72 QStringLiteral("icon"),
73 QStringLiteral("importance"),
74 QStringLiteral("type"),
75 QStringLiteral("osm_id"),
76 QStringLiteral("osm_type"),
77 QStringLiteral("licence"),
78 QStringLiteral("place_id"),
79 QStringLiteral("class") };
80
81 for (const auto &k: extraKeys) {
82 if (object.contains(k)) {
83 extra[k] = object.value(k).toVariant();
84 if (k == QStringLiteral("geojson"))
85 extra[QStringLiteral("geojson_model")] =
86 QGeoJson::importGeoJson(QJsonDocument::fromVariant(extra[k]));
87 }
88 }
89
90 location.setExtendedAttributes(extra);
91}
92
93void QGeoCodeReplyOsm::networkReplyFinished()
94{
95 QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
96 reply->deleteLater();
97
98 if (reply->error() != QNetworkReply::NoError)
99 return;
100
101 QList<QGeoLocation> locations;
102 QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
103
104 if (document.isObject()) {
105 QJsonObject object = document.object();
106
107 QGeoCoordinate coordinate;
108
109 coordinate.setLatitude(object.value(QStringLiteral("lat")).toString().toDouble());
110 coordinate.setLongitude(object.value(QStringLiteral("lon")).toString().toDouble());
111
112 QGeoLocation location;
113 location.setCoordinate(coordinate);
114 location.setAddress(parseAddressObject(object));
115
116 if (m_includeExtraData)
117 injectExtra(location, object);
118 locations.append(location);
119
120 setLocations(locations);
121 } else if (document.isArray()) {
122 QJsonArray results = document.array();
123
124 for (int i = 0; i < results.count(); ++i) {
125 if (!results.at(i).isObject())
126 continue;
127
128 QJsonObject object = results.at(i).toObject();
129
130 QGeoCoordinate coordinate;
131
132 coordinate.setLatitude(object.value(QStringLiteral("lat")).toString().toDouble());
133 coordinate.setLongitude(object.value(QStringLiteral("lon")).toString().toDouble());
134
135 QGeoRectangle rectangle;
136
137 if (object.contains(QStringLiteral("boundingbox"))) {
138 QJsonArray a = object.value(QStringLiteral("boundingbox")).toArray();
139 if (a.count() == 4) {
140 rectangle.setTopLeft(QGeoCoordinate(a.at(1).toString().toDouble(),
141 a.at(2).toString().toDouble()));
142 rectangle.setBottomRight(QGeoCoordinate(a.at(0).toString().toDouble(),
143 a.at(3).toString().toDouble()));
144 }
145 }
146
147 QGeoLocation location;
148 location.setCoordinate(coordinate);
149 location.setBoundingShape(rectangle);
150 location.setAddress(parseAddressObject(object));
151 if (m_includeExtraData)
152 injectExtra(location, object);
153 locations.append(location);
154 }
155
156 }
157
158 setLocations(locations);
159 setFinished(true);
160}
161
162void QGeoCodeReplyOsm::networkReplyError(QNetworkReply::NetworkError error)
163{
164 Q_UNUSED(error);
165 QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
166 reply->deleteLater();
167 setError(QGeoCodeReply::CommunicationError, reply->errorString());
168}
169
170QT_END_NAMESPACE
The QNetworkReply class contains the data and headers for a request sent with QNetworkAccessManager.
QObject * parent
Definition qobject.h:73
static QGeoAddress parseAddressObject(const QJsonObject &object)
static void injectExtra(QGeoLocation &location, const QJsonObject &object)