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
qplacedetailsreplyimpl.cpp
Go to the documentation of this file.
1// Copyright (C) 2015 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6#include "../qplacemanagerengine_nokiav2.h"
7#include "../qgeoerror_messages.h"
8
9#include <QCoreApplication>
10#include <QtCore/QJsonDocument>
11#include <QtCore/QJsonObject>
12#include <QtCore/QJsonArray>
13#include <QtNetwork/QNetworkReply>
14#include <QtPositioning/QGeoAddress>
15#include <QtPositioning/QGeoCoordinate>
16#include <QtPositioning/QGeoLocation>
17#include <QtPositioning/QGeoRectangle>
18#include <QtLocation/QPlace>
19#include <QtLocation/QPlaceAttribute>
20#include <QtLocation/QPlaceContactDetail>
21#include <QtLocation/QPlaceManager>
22#include <QtLocation/QPlaceSupplier>
23#include <QtLocation/QPlaceIcon>
24#include <QtLocation/QPlaceRatings>
25#include <QtLocation/QPlaceUser>
26
28
29// These countries format the street address as: {house number} {street name}
30// All other countries format it as: {street name} {house number}
31static const char COUNTRY_TABLE_string[] =
32 "CAN\0"
33 "NZL\0"
34 "GBR\0"
35 "AUS\0"
36 "LKA\0"
37 "USA\0"
38 "SGP\0"
39 "FRA\0"
40 "BHS\0"
41 "CHN\0"
42 "IND\0"
43 "IRL\0"
44 "ARE\0"
45 "\0";
46
47static const int COUNTRY_TABLE_indices[] = {
48 0, 4, 8, 12, 16, 20, 24, 28,
49 32, 36, 40, 44, 48, -1
50};
51
52static bool countryTableContains(const QString &countryCode)
53{
54 for (int i = 0; COUNTRY_TABLE_indices[i] != -1; ++i) {
55 if (countryCode == QLatin1String(COUNTRY_TABLE_string + COUNTRY_TABLE_indices[i]))
56 return true;
57 }
58
59 return false;
60}
61
62QPlaceDetailsReplyImpl::QPlaceDetailsReplyImpl(QNetworkReply *reply,
64: QPlaceDetailsReply(parent), m_engine(parent)
65{
66 if (!reply) {
67 setError(UnknownError, QStringLiteral("Null reply"));
68 return;
69 }
70 connect(reply, &QNetworkReply::finished,
71 this, &QPlaceDetailsReplyImpl::replyFinished);
72 connect(reply, &QNetworkReply::errorOccurred,
73 this, &QPlaceDetailsReplyImpl::replyError);
74 connect(this, &QPlaceReply::aborted, reply, &QNetworkReply::abort);
75 connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
76}
77
81
82void QPlaceDetailsReplyImpl::setError(QPlaceReply::Error error_, const QString &errorString)
83{
84 QPlaceReply::setError(error_, errorString);
85 emit errorOccurred(error_, errorString);
86 setFinished(true);
87 emit finished();
88}
89
90void QPlaceDetailsReplyImpl::replyFinished()
91{
92 QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
93 reply->deleteLater();
94
95 if (reply->error() != QNetworkReply::NoError)
96 return;
97
98 QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
99 if (!document.isObject()) {
100 setError(ParseError, QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, PARSE_ERROR));
101 return;
102 }
103
104 QJsonObject object = document.object();
105
106 QPlace place;
107
108 place.setPlaceId(object.value(QLatin1String("placeId")).toString());
109
110 //const QUrl view = object.value(QLatin1String("view")).toString();
111
112 place.setName(object.value(QLatin1String("name")).toString());
113
114 //if (object.contains(QLatin1String("distance")))
115 // double distance = object.value(QLatin1String("distance")).toDouble();
116
117 //if (object.contains(QLatin1String("alternativeNames"))) {
118 // QJsonArray alternativeNames = object.value(QLatin1String("alternativeNames")).toArray();
119 //}
120
121 QGeoLocation location;
122
123 QJsonObject locationObject = object.value(QLatin1String("location")).toObject();
124
125 //if (locationObject.contains(QLatin1String("locationId")))
126 // const QString locationId = locationObject.value(QLatin1String("locationId")).toString();
127
128 QJsonArray position = locationObject.value(QLatin1String("position")).toArray();
129 location.setCoordinate(QGeoCoordinate(position.at(0).toDouble(), position.at(1).toDouble()));
130
131 QGeoAddress address;
132
133 QJsonObject addressObject = locationObject.value(QLatin1String("address")).toObject();
134
135 address.setText(addressObject.value(QLatin1String("text")).toString());
136
137 address.setCountry(addressObject.value(QLatin1String("country")).toString());
138 address.setCountryCode(addressObject.value(QLatin1String("countryCode")).toString());
139
140 QString house;
141 QString street;
142
143 if (addressObject.contains(QLatin1String("house")))
144 house = addressObject.value(QLatin1String("house")).toString();
145 if (addressObject.contains(QLatin1String("street")))
146 street = addressObject.value(QLatin1String("street")).toString();
147
148 if (countryTableContains(address.countryCode())) {
149 if (!house.isEmpty() && !street.startsWith(house))
150 street = house + QLatin1Char(' ') + street;
151 } else {
152 if (!house.isEmpty() && !street.endsWith(house))
153 street += QLatin1Char(' ') + house;
154 }
155
156 address.setStreet(street);
157
158 if (addressObject.contains(QLatin1String("city")))
159 address.setCity(addressObject.value(QLatin1String("city")).toString());
160 if (addressObject.contains(QLatin1String("district")))
161 address.setDistrict(addressObject.value(QLatin1String("district")).toString());
162 if (addressObject.contains(QLatin1String("state")))
163 address.setState(addressObject.value(QLatin1String("state")).toString());
164 if (addressObject.contains(QLatin1String("county")))
165 address.setCounty(addressObject.value(QLatin1String("county")).toString());
166 if (addressObject.contains(QLatin1String("postalCode")))
167 address.setPostalCode(addressObject.value(QLatin1String("postalCode")).toString());
168
169 location.setAddress(address);
170
171 if (locationObject.contains(QLatin1String("bbox"))) {
172 QJsonArray bbox = locationObject.value(QLatin1String("bbox")).toArray();
173 QGeoRectangle box(QGeoCoordinate(bbox.at(3).toDouble(), bbox.at(0).toDouble()),
174 QGeoCoordinate(bbox.at(1).toDouble(), bbox.at(2).toDouble()));
175 location.setBoundingShape(box);
176 }
177
178 place.setLocation(location);
179
180 place.setCategories(parseCategories(object.value(QLatin1String("categories")).toArray(),
181 m_engine));
182
183 place.setIcon(m_engine->icon(object.value(QLatin1String("icon")).toString(),
184 place.categories()));
185
186 if (object.contains(QLatin1String("contacts"))) {
187 QJsonObject contactsObject = object.value(QLatin1String("contacts")).toObject();
188
189 if (contactsObject.contains(QLatin1String("phone"))) {
190 place.setContactDetails(QPlaceContactDetail::Phone,
191 parseContactDetails(contactsObject.value(QLatin1String("phone")).toArray()));
192 }
193 if (contactsObject.contains(QLatin1String("fax"))) {
194 place.setContactDetails(QPlaceContactDetail::Fax,
195 parseContactDetails(contactsObject.value(QLatin1String("fax")).toArray()));
196 }
197 if (contactsObject.contains(QLatin1String("website"))) {
198 place.setContactDetails(QPlaceContactDetail::Website,
199 parseContactDetails(contactsObject.value(QLatin1String("website")).toArray()));
200 }
201 if (contactsObject.contains(QLatin1String("email"))) {
202 place.setContactDetails(QPlaceContactDetail::Email,
203 parseContactDetails(contactsObject.value(QLatin1String("email")).toArray()));
204 }
205 }
206
207 //if (object.contains(QLatin1String("verifiedByOwner")))
208 // bool verifiedByOwner = object.value(QLatin1String("verifiedByOwner")).toBool();
209
210 if (object.contains(QLatin1String("attribution")))
211 place.setAttribution(object.value(QLatin1String("attribution")).toString());
212
213 if (object.contains(QLatin1String("supplier"))) {
214 place.setSupplier(parseSupplier(object.value(QLatin1String("supplier")).toObject(),
215 m_engine));
216 }
217
218 if (object.contains(QLatin1String("ratings"))) {
219 QJsonObject ratingsObject = object.value(QLatin1String("ratings")).toObject();
220
221 QPlaceRatings ratings;
222 ratings.setAverage(ratingsObject.value(QLatin1String("average")).toDouble());
223 ratings.setCount(ratingsObject.value(QLatin1String("count")).toDouble());
224 ratings.setMaximum(5.0);
225
226 place.setRatings(ratings);
227 }
228
229 if (object.contains(QLatin1String("extended"))) {
230 QJsonObject extendedObject = object.value(QLatin1String("extended")).toObject();
231
232 for (auto it = extendedObject.constBegin(), end = extendedObject.constEnd(); it != end; ++it) {
233 QJsonObject attributeObject = it.value().toObject();
234
235 QPlaceAttribute attribute;
236
237 attribute.setLabel(attributeObject.value(QLatin1String("label")).toString());
238 attribute.setText(attributeObject.value(QLatin1String("text")).toString());
239
240 QString key = it.key();
241 if (key == QLatin1String("payment"))
242 place.setExtendedAttribute(QPlaceAttribute::Payment, attribute);
243 else if (key == QLatin1String("openingHours"))
244 place.setExtendedAttribute(QPlaceAttribute::OpeningHours, attribute);
245 else
246 place.setExtendedAttribute(key, attribute);
247 }
248 }
249
250 if (object.contains(QLatin1String("media"))) {
251 QJsonObject mediaObject = object.value(QLatin1String("media")).toObject();
252
253 if (mediaObject.contains(QLatin1String("images"))) {
254 QPlaceContent::Collection collection;
255 int totalCount = 0;
256
257 parseCollection(QPlaceContent::ImageType,
258 mediaObject.value(QLatin1String("images")).toObject(),
259 &collection, &totalCount, 0, 0, m_engine);
260
261 place.setTotalContentCount(QPlaceContent::ImageType, totalCount);
262 place.setContent(QPlaceContent::ImageType, collection);
263 }
264 if (mediaObject.contains(QLatin1String("editorials"))) {
265 QPlaceContent::Collection collection;
266 int totalCount = 0;
267
268 parseCollection(QPlaceContent::EditorialType,
269 mediaObject.value(QLatin1String("editorials")).toObject(),
270 &collection, &totalCount, 0, 0, m_engine);
271
272 place.setTotalContentCount(QPlaceContent::EditorialType, totalCount);
273 place.setContent(QPlaceContent::EditorialType, collection);
274 }
275 if (mediaObject.contains(QLatin1String("reviews"))) {
276 QPlaceContent::Collection collection;
277 int totalCount = 0;
278
279 parseCollection(QPlaceContent::ReviewType,
280 mediaObject.value(QLatin1String("reviews")).toObject(),
281 &collection, &totalCount, 0, 0, m_engine);
282
283 place.setTotalContentCount(QPlaceContent::ReviewType, totalCount);
284 place.setContent(QPlaceContent::ReviewType, collection);
285 }
286 }
287
288 //if (object.contains(QLatin1String("related"))) {
289 // QJsonObject relatedObject = object.value(QLatin1String("related")).toObject();
290 //}
291
292 QPlaceAttribute provider;
293 provider.setText(QLatin1String("here"));
294 place.setExtendedAttribute(QPlaceAttribute::Provider, provider);
295
296 place.setVisibility(QLocation::PublicVisibility);
297 place.setDetailsFetched(true);
298 setPlace(place);
299
300 setFinished(true);
301 emit finished();
302}
303
304void QPlaceDetailsReplyImpl::replyError(QNetworkReply::NetworkError error)
305{
306 QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
307 reply->deleteLater();
308 if (error == QNetworkReply::OperationCanceledError) {
309 setError(QPlaceReply::CancelError, QStringLiteral("Request cancelled"));
310 } else if (error == QNetworkReply::ContentNotFoundError) {
311 setError(QPlaceReply::PlaceDoesNotExistError,
312 QString::fromLatin1("The id, %1, does not reference an existing place")
313 .arg(m_placeId));
314 } else {
315 setError(QPlaceReply::CommunicationError, reply->errorString());
316 }
317}
318
319QT_END_NAMESPACE
static bool countryTableContains(const QString &countryCode)
static const int COUNTRY_TABLE_indices[]
static QT_BEGIN_NAMESPACE const char COUNTRY_TABLE_string[]