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
placesearchreply_esri.cpp
Go to the documentation of this file.
1// Copyright (C) 2013-2018 Esri <contracts@esri.com>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6
7#include <QtCore/QJsonDocument>
8#include <QtCore/QJsonArray>
9#include <QtCore/QJsonObject>
10#include <QtNetwork/QNetworkReply>
11#include <QtPositioning/QGeoAddress>
12#include <QtPositioning/QGeoCircle>
13#include <QtPositioning/QGeoLocation>
14#include <QtPositioning/QGeoRectangle>
15#include <QtLocation/QPlace>
16#include <QtLocation/QPlaceAttribute>
17#include <QtLocation/QPlaceContactDetail>
18#include <QtLocation/QPlaceRatings>
19#include <QtLocation/QPlaceResult>
20#include <QtLocation/QPlaceSearchRequest>
21#include <QtLocation/private/qplacesearchrequest_p.h>
22
23static const QString kCandidatesKey(QStringLiteral("candidates"));
24static const QString kAttributesKey(QStringLiteral("attributes"));
25static const QString kAddressKey(QStringLiteral("address"));
26static const QString kLongLabelKey(QStringLiteral("LongLabel"));
27static const QString kCityKey(QStringLiteral("City"));
28static const QString kCountryKey(QStringLiteral("Country"));
29static const QString kRegionKey(QStringLiteral("Region"));
30static const QString kPostalKey(QStringLiteral("Postal"));
31static const QString kStAddrKey(QStringLiteral("StAddr"));
32static const QString kStateKey(QStringLiteral("State"));
33static const QString kDistrictKey(QStringLiteral("District"));
34static const QString kLocationKey(QStringLiteral("location"));
35static const QString kXKey(QStringLiteral("x"));
36static const QString kYKey(QStringLiteral("y"));
37static const QString kDistanceKey(QStringLiteral("Distance"));
38static const QString kPhoneKey(QStringLiteral("Phone"));
39static const QString kExtentKey(QStringLiteral("extent"));
40static const QString kXminKey(QStringLiteral("xmin"));
41static const QString kYminKey(QStringLiteral("ymin"));
42static const QString kXmaxKey(QStringLiteral("xmax"));
43static const QString kYmaxKey(QStringLiteral("ymax"));
44
45QT_BEGIN_NAMESPACE
46
47PlaceSearchReplyEsri::PlaceSearchReplyEsri(const QPlaceSearchRequest &request, QNetworkReply *reply,
48 const QHash<QString, QString> &candidateFields,
49 const QHash<QString, QString> &countries, PlaceManagerEngineEsri *parent) :
50 QPlaceSearchReply(parent), m_candidateFields(candidateFields), m_countries(countries)
51{
52 Q_ASSERT(parent);
53 if (!reply) {
54 setError(UnknownError, QStringLiteral("Null reply"));
55 return;
56 }
57 setRequest(request);
58
59 connect(reply, &QNetworkReply::finished, this, &PlaceSearchReplyEsri::replyFinished);
60 connect(reply, &QNetworkReply::errorOccurred, this, &PlaceSearchReplyEsri::networkError);
61 connect(this, &QPlaceReply::aborted, reply, &QNetworkReply::abort);
62 connect(this, &QObject::destroyed, reply, &QObject::deleteLater);
63}
64
68
69void PlaceSearchReplyEsri::setError(QPlaceReply::Error errorCode, const QString &errorString)
70{
71 QPlaceReply::setError(errorCode, errorString);
72 emit errorOccurred(errorCode, errorString);
73 setFinished(true);
74 emit finished();
75}
76
77void PlaceSearchReplyEsri::replyFinished()
78{
79 QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
80 reply->deleteLater();
81
82 if (reply->error() != QNetworkReply::NoError)
83 return;
84
85 QJsonDocument document = QJsonDocument::fromJson(reply->readAll());
86 if (!document.isObject()) {
87 setError(ParseError, tr("Response parse error"));
88 return;
89 }
90
91 QJsonValue suggestions = document.object().value(kCandidatesKey);
92 if (!suggestions.isArray()) {
93 setError(ParseError, tr("Response parse error"));
94 return;
95 }
96
97 const QJsonArray resultsArray = suggestions.toArray();
98
99 QList<QPlaceSearchResult> results;
100 for (const auto result : resultsArray)
101 results.append(parsePlaceResult(result.toObject()));
102
103 setResults(results);
104 setFinished(true);
105 emit finished();
106}
107
108void PlaceSearchReplyEsri::networkError(QNetworkReply::NetworkError error)
109{
110 Q_UNUSED(error);
111 QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
112 reply->deleteLater();
113 setError(QPlaceReply::CommunicationError, reply->errorString());
114}
115
116QPlaceResult PlaceSearchReplyEsri::parsePlaceResult(const QJsonObject &item) const
117{
118 QPlace place;
119 QHash<QString, QString> keys;
120
121 // set attributes
122 const QJsonObject attributes = item.value(kAttributesKey).toObject();
123 for (const QString &key: attributes.keys())
124 {
125 const QString value = attributes.value(key).toVariant().toString();
126 if (!value.isEmpty())
127 {
128 QPlaceAttribute attribute;
129 attribute.setLabel(m_candidateFields.value(key, key)); // local name or key
130 attribute.setText(value);
131 place.setExtendedAttribute(key, attribute);
132 keys.insert(key, value);
133 }
134 }
135
136 if (keys.contains(kPhoneKey))
137 {
138 QPlaceContactDetail contactDetail;
139 contactDetail.setLabel(m_candidateFields.value(kPhoneKey, kPhoneKey)); // local name or key
140 contactDetail.setValue(keys.value(kPhoneKey));
141 place.appendContactDetail(QPlaceContactDetail::Phone, contactDetail);
142 }
143
144 // set address
145 QGeoAddress geoAddress;
146 geoAddress.setCity(keys.value(kCityKey));
147 geoAddress.setCountry(m_countries.value(keys.value(kCountryKey))); // mismatch code ISO2 vs ISO3
148 geoAddress.setCounty(keys.value(kRegionKey));
149 geoAddress.setPostalCode(keys.value(kPostalKey));
150 geoAddress.setStreet(keys.value(kStAddrKey));
151 geoAddress.setState(keys.value(kStateKey));
152 geoAddress.setDistrict(keys.value(kDistrictKey));
153
154 // set location
155 const QJsonObject location = item.value(kLocationKey).toObject();
156 const QGeoCoordinate coordinate = QGeoCoordinate(location.value(kYKey).toDouble(),
157 location.value(kXKey).toDouble());
158
159 // set boundingBox
160 const QJsonObject extent = item.value(kExtentKey).toObject();
161 const QGeoCoordinate topLeft(extent.value(kYminKey).toDouble(),
162 extent.value(kXminKey).toDouble());
163 const QGeoCoordinate bottomRight(extent.value(kYmaxKey).toDouble(),
164 extent.value(kXmaxKey).toDouble());
165 const QGeoRectangle boundingBox(topLeft, bottomRight);
166
167 // set geolocation
168 QGeoLocation geoLocation;
169 geoLocation.setCoordinate(coordinate);
170 geoLocation.setAddress(geoAddress);
171 geoLocation.setBoundingShape(boundingBox);
172
173 // set place
174 place.setName(keys.value(kLongLabelKey));
175 place.setLocation(geoLocation);
176 place.setPlaceId(attributes.value(kLongLabelKey).toString());
177
178 // set place result
179 QPlaceResult result;
180 result.setPlace(place);
181 result.setTitle(keys.value(kAddressKey));
182 result.setDistance(keys.value(kDistanceKey).toDouble());
183
184 return result;
185}
186
187QT_END_NAMESPACE
static const QString kPostalKey(QStringLiteral("Postal"))
static const QString kYmaxKey(QStringLiteral("ymax"))
static const QString kPhoneKey(QStringLiteral("Phone"))
static const QString kAddressKey(QStringLiteral("address"))
static const QString kCountryKey(QStringLiteral("Country"))
static const QString kDistanceKey(QStringLiteral("Distance"))
static const QString kStAddrKey(QStringLiteral("StAddr"))
static const QString kAttributesKey(QStringLiteral("attributes"))
static const QString kLongLabelKey(QStringLiteral("LongLabel"))
static const QString kXminKey(QStringLiteral("xmin"))
static const QString kCityKey(QStringLiteral("City"))
static const QString kLocationKey(QStringLiteral("location"))
static const QString kDistrictKey(QStringLiteral("District"))
static const QString kXKey(QStringLiteral("x"))
static const QString kYminKey(QStringLiteral("ymin"))
static const QString kExtentKey(QStringLiteral("extent"))
static const QString kYKey(QStringLiteral("y"))
static const QString kXmaxKey(QStringLiteral("xmax"))
static const QString kRegionKey(QStringLiteral("Region"))
static const QString kStateKey(QStringLiteral("State"))