Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qgeocodingmanagerengine_nokia.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 "marclanguagecodes.h"
8#include "qgeouriprovider.h"
9#include "uri_constants.h"
10
11#include <QtPositioning/QGeoAddress>
12#include <QtPositioning/QGeoCoordinate>
13#include <QtPositioning/QGeoCircle>
14#include <QtPositioning/QGeoRectangle>
15#include <QtPositioning/QGeoShape>
16
17#include <QUrl>
18#include <QMap>
19#include <QStringList>
20
22
24 QGeoNetworkAccessManager *networkManager,
25 const QVariantMap &parameters,
27 QString *errorString)
28 : QGeoCodingManagerEngine(parameters)
29 , m_networkManager(networkManager)
30 , m_uriProvider(new QGeoUriProvider(this, parameters, QStringLiteral("here.geocoding.host"), GEOCODING_HOST))
31 , m_reverseGeocodingUriProvider(new QGeoUriProvider(this, parameters, QStringLiteral("here.reversegeocoding.host"), REVERSE_GEOCODING_HOST))
32{
33 Q_ASSERT(networkManager);
34 m_networkManager->setParent(this);
35
36 if (parameters.contains(QStringLiteral("here.apiKey")))
37 m_apiKey = parameters.value(QStringLiteral("here.apiKey")).toString();
38
39 if (error)
41
42 if (errorString)
43 *errorString = "";
44}
45
47
48QString QGeoCodingManagerEngineNokia::getAuthenticationString() const
49{
50 QString authenticationString;
51
52 if (!m_apiKey.isEmpty()) {
53 authenticationString += "?apiKey=";
54 authenticationString += m_apiKey;
55 }
56
57 return authenticationString;
58}
59
60
62 const QGeoShape &bounds)
63{
64 QString requestString = "https://";
65 requestString += m_uriProvider->getCurrentHost();
66 requestString += "/6.2/geocode.json";
67
68 requestString += getAuthenticationString();
69 requestString += "&gen=9";
70
71 requestString += "&language=";
72 requestString += languageToMarc(locale().language());
73
74 bool manualBoundsRequired = false;
75 if (bounds.type() == QGeoShape::UnknownType) {
76 manualBoundsRequired = true;
77 } else if (bounds.type() == QGeoShape::CircleType) {
78 QGeoCircle circ(bounds);
79 if (circ.isValid()) {
80 requestString += "?prox=";
81 requestString += trimDouble(circ.center().latitude());
82 requestString += ",";
83 requestString += trimDouble(circ.center().longitude());
84 requestString += ",";
85 requestString += trimDouble(circ.radius());
86 }
87 } else {
89 if (rect.isValid()) {
90 requestString += "&bbox=";
91 requestString += trimDouble(rect.topLeft().latitude());
92 requestString += ",";
93 requestString += trimDouble(rect.topLeft().longitude());
94 requestString += ";";
95 requestString += trimDouble(rect.bottomRight().latitude());
96 requestString += ",";
97 requestString += trimDouble(rect.bottomRight().longitude());
98 }
99 }
100
101 if (address.country().isEmpty()) {
102 QStringList parts;
103
104 if (!address.state().isEmpty())
105 parts << address.state();
106
107 if (!address.city().isEmpty())
108 parts << address.city();
109
110 if (!address.postalCode().isEmpty())
111 parts << address.postalCode();
112
113 if (!address.street().isEmpty())
114 parts << address.street();
115
116 requestString += "&searchtext=";
117 requestString += parts.join("+").replace(' ', '+');
118 } else {
119 requestString += "&country=";
120 requestString += address.country();
121
122 if (!address.state().isEmpty()) {
123 requestString += "&state=";
124 requestString += address.state();
125 }
126
127 if (!address.city().isEmpty()) {
128 requestString += "&city=";
129 requestString += address.city();
130 }
131
132 if (!address.postalCode().isEmpty()) {
133 requestString += "&postalcode=";
134 requestString += address.postalCode();
135 }
136
137 if (!address.street().isEmpty()) {
138 requestString += "&street=";
139 requestString += address.street();
140 }
141 }
142
143 return geocode(requestString, bounds, manualBoundsRequired);
144}
145
147 int limit,
148 int offset,
149 const QGeoShape &bounds)
150{
151 QString requestString = "https://";
152 requestString += m_uriProvider->getCurrentHost();
153 requestString += "/6.2/geocode.json";
154
155 requestString += getAuthenticationString();
156 requestString += "&gen=9";
157
158 requestString += "&language=";
159 requestString += languageToMarc(locale().language());
160
161 requestString += "&searchtext=";
162 requestString += QString(address).replace(' ', '+');
163
164 if (limit > 0) {
165 requestString += "&maxresults=";
166 requestString += QString::number(limit);
167 }
168 if (offset > 0) {
169 // We cannot do this precisely, since HERE doesn't allow
170 // precise result-set offset to be supplied; instead, it
171 // returns "pages" of results at a time.
172 // So, we tell HERE which page of results we want, and the
173 // client has to filter out duplicates if they changed
174 // the limit param since the last call.
175 requestString += "&pageinformation=";
176 requestString += QString::number(offset/limit);
177 }
178
179 bool manualBoundsRequired = false;
180 if (bounds.type() == QGeoShape::RectangleType) {
181 QGeoRectangle rect(bounds);
182 if (rect.isValid()) {
183 requestString += "&bbox=";
184 requestString += trimDouble(rect.topLeft().latitude());
185 requestString += ",";
186 requestString += trimDouble(rect.topLeft().longitude());
187 requestString += ";";
188 requestString += trimDouble(rect.bottomRight().latitude());
189 requestString += ",";
190 requestString += trimDouble(rect.bottomRight().longitude());
191 }
192 } else if (bounds.type() == QGeoShape::CircleType) {
193 QGeoCircle circ(bounds);
194 if (circ.isValid()) {
195 requestString += "?prox=";
196 requestString += trimDouble(circ.center().latitude());
197 requestString += ",";
198 requestString += trimDouble(circ.center().longitude());
199 requestString += ",";
200 requestString += trimDouble(circ.radius());
201 }
202 } else {
203 manualBoundsRequired = true;
204 }
205
206 return geocode(requestString, bounds, manualBoundsRequired, limit, offset);
207}
208
210 const QGeoShape &bounds,
211 bool manualBoundsRequired,
212 int limit,
213 int offset)
214{
216 m_networkManager->get(QNetworkRequest(QUrl(requestString))),
217 limit, offset, bounds, manualBoundsRequired, this);
218
220 this, &QGeoCodingManagerEngineNokia::placesFinished);
221
223 this, &QGeoCodingManagerEngineNokia::placesError);
224
225 return reply;
226}
227
229 const QGeoShape &bounds)
230{
231 QString requestString = "https://";
232 requestString += m_reverseGeocodingUriProvider->getCurrentHost();
233 requestString += "/6.2/reversegeocode.json";
234
235 requestString += getAuthenticationString();
236 requestString += "&gen=9";
237
238 requestString += "&mode=retrieveAddresses";
239
240 requestString += "&prox=";
241 requestString += trimDouble(coordinate.latitude());
242 requestString += ",";
243 requestString += trimDouble(coordinate.longitude());
244
245 bool manualBoundsRequired = false;
246 if (bounds.type() == QGeoShape::CircleType) {
247 QGeoCircle circ(bounds);
248 if (circ.isValid() && circ.center() == coordinate) {
249 requestString += ",";
250 requestString += trimDouble(circ.radius());
251 } else {
252 manualBoundsRequired = true;
253 }
254 } else {
255 manualBoundsRequired = true;
256 }
257
258 requestString += "&language=";
259 requestString += languageToMarc(locale().language());
260
261 return geocode(requestString, bounds, manualBoundsRequired);
262}
263
264QString QGeoCodingManagerEngineNokia::trimDouble(double degree, int decimalDigits)
265{
266 QString sDegree = QString::number(degree, 'g', decimalDigits);
267
268 int index = sDegree.indexOf('.');
269
270 if (index == -1)
271 return sDegree;
272 else
273 return QString::number(degree, 'g', decimalDigits + index);
274}
275
276void QGeoCodingManagerEngineNokia::placesFinished()
277{
278 QGeoCodeReply *reply = qobject_cast<QGeoCodeReply *>(sender());
279
280 if (!reply)
281 return;
282
283 if (receivers(SIGNAL(finished(QGeoCodeReply*))) == 0) {
285 return;
286 }
287
289}
290
291void QGeoCodingManagerEngineNokia::placesError(QGeoCodeReply::Error error, const QString &errorString)
292{
293 QGeoCodeReply *reply = qobject_cast<QGeoCodeReply *>(sender());
294
295 if (!reply)
296 return;
297
300 return;
301 }
302
303 emit errorOccurred(reply, error, errorString);
304}
305
306QString QGeoCodingManagerEngineNokia::languageToMarc(QLocale::Language language)
307{
308 uint offset = 3 * (uint(language));
309 if (language == QLocale::C || offset + 3 > sizeof(marc_language_code_list))
310 return QLatin1String("eng");
311
312 const unsigned char *c = marc_language_code_list + offset;
313 if (c[0] == 0)
314 return QLatin1String("eng");
315
317 code[0] = ushort(c[0]);
318 code[1] = ushort(c[1]);
319 code[2] = ushort(c[2]);
320
321 return code;
322}
323
\inmodule QtPositioning
Definition qgeoaddress.h:18
\inmodule QtPositioning
Definition qgeocircle.h:15
\inmodule QtLocation
void finished()
This signal is emitted when this reply has finished processing.
void errorOccurred(QGeoCodeReply::Error error, const QString &errorString=QString())
This signal is emitted when an error has been detected in the processing of this reply.
Error
Describes an error which prevented the completion of the operation.
QGeoCodeReply * reverseGeocode(const QGeoCoordinate &coordinate, const QGeoShape &bounds) override
Begins the reverse geocoding of coordinate.
QGeoCodingManagerEngineNokia(QGeoNetworkAccessManager *networkManager, const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString)
QGeoCodeReply * geocode(const QGeoAddress &address, const QGeoShape &bounds) override
Begins the geocoding of address.
void errorOccurred(QGeoCodeReply *reply, QGeoCodeReply::Error error, const QString &errorString=QString())
void finished(QGeoCodeReply *reply)
QLocale locale() const
Returns the locale used to hint to this geocoding manager about what language to use for the results.
\inmodule QtPositioning
double longitude
This property holds the longitude in decimal degrees.
double latitude
This property holds the latitude in decimal degrees.
virtual QNetworkReply * get(const QNetworkRequest &request)=0
\inmodule QtPositioning
Error
Describes an error related to the loading and setup of a service provider plugin.
\inmodule QtPositioning
Definition qgeoshape.h:17
ShapeType type
This property holds the type of this geo shape.
Definition qgeoshape.h:19
Q_INVOKABLE QGeoRectangle boundingGeoRectangle() const
Returns a QGeoRectangle representing the geographical bounding rectangle of the geo shape,...
@ UnknownType
Definition qgeoshape.h:31
@ RectangleType
Definition qgeoshape.h:32
QString getCurrentHost() const
T value(const Key &key, const T &defaultValue=T()) const
Definition qmap.h:357
bool contains(const Key &key) const
Definition qmap.h:341
The QNetworkRequest class holds a request to be sent with QNetworkAccessManager.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
QObject * sender() const
Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; othe...
Definition qobject.cpp:2658
void setParent(QObject *parent)
Makes the object a child of parent.
Definition qobject.cpp:2195
int receivers(const char *signal) const
Returns the number of receivers connected to the signal.
Definition qobject.cpp:2740
void deleteLater()
\threadsafe
Definition qobject.cpp:2435
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString & replace(qsizetype i, qsizetype len, QChar after)
Definition qstring.cpp:3824
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
\inmodule QtCore
Definition qurl.h:94
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
#define this
Definition dialogs.cpp:9
rect
[4]
static QT_BEGIN_NAMESPACE const unsigned char marc_language_code_list[]
Combined button and popup list for selecting options.
constexpr Initialization Uninitialized
DBusConnection const char DBusError * error
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLuint index
[2]
GLenum GLuint GLintptr offset
const GLubyte * c
GLint limit
GLuint GLuint64EXT address
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
#define emit
unsigned int uint
Definition qtypes.h:34
unsigned short ushort
Definition qtypes.h:33
QNetworkReply * reply
const QString REVERSE_GEOCODING_HOST
const QString GEOCODING_HOST