11#include <QtPositioning/QGeoAddress>
12#include <QtPositioning/QGeoCoordinate>
13#include <QtPositioning/QGeoCircle>
14#include <QtPositioning/QGeoRectangle>
15#include <QtPositioning/QGeoShape>
24 QGeoNetworkAccessManager *networkManager,
25 const QVariantMap ¶meters,
26 QGeoServiceProvider::Error *error,
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))
33 Q_ASSERT(networkManager);
34 m_networkManager->setParent(
this);
36 if (parameters.contains(QStringLiteral(
"here.apiKey")))
37 m_apiKey = parameters.value(QStringLiteral(
"here.apiKey")).toString();
40 *error = QGeoServiceProvider::NoError;
50 QString authenticationString;
52 if (!m_apiKey.isEmpty()) {
53 authenticationString +=
"?apiKey=";
54 authenticationString += m_apiKey;
57 return authenticationString;
62 const QGeoShape &bounds)
64 QString requestString =
"https://";
65 requestString += m_uriProvider->getCurrentHost();
66 requestString +=
"/6.2/geocode.json";
68 requestString += getAuthenticationString();
69 requestString +=
"&gen=9";
71 requestString +=
"&language=";
72 requestString += languageToMarc(locale().language());
74 bool manualBoundsRequired =
false;
75 if (bounds.type() == QGeoShape::UnknownType) {
76 manualBoundsRequired =
true;
77 }
else if (bounds.type() == QGeoShape::CircleType) {
78 QGeoCircle circ(bounds);
80 requestString +=
"?prox=";
81 requestString += trimDouble(circ.center().latitude());
83 requestString += trimDouble(circ.center().longitude());
85 requestString += trimDouble(circ.radius());
88 QGeoRectangle rect = bounds.boundingGeoRectangle();
90 requestString +=
"&bbox=";
91 requestString += trimDouble(rect.topLeft().latitude());
93 requestString += trimDouble(rect.topLeft().longitude());
95 requestString += trimDouble(rect.bottomRight().latitude());
97 requestString += trimDouble(rect.bottomRight().longitude());
101 if (address.country().isEmpty()) {
104 if (!address.state().isEmpty())
105 parts << address.state();
107 if (!address.city().isEmpty())
108 parts << address.city();
110 if (!address.postalCode().isEmpty())
111 parts << address.postalCode();
113 if (!address.street().isEmpty())
114 parts << address.street();
116 requestString +=
"&searchtext=";
117 requestString += parts.join(
"+").replace(
' ',
'+');
119 requestString +=
"&country=";
120 requestString += address.country();
122 if (!address.state().isEmpty()) {
123 requestString +=
"&state=";
124 requestString += address.state();
127 if (!address.city().isEmpty()) {
128 requestString +=
"&city=";
129 requestString += address.city();
132 if (!address.postalCode().isEmpty()) {
133 requestString +=
"&postalcode=";
134 requestString += address.postalCode();
137 if (!address.street().isEmpty()) {
138 requestString +=
"&street=";
139 requestString += address.street();
143 return geocode(requestString, bounds, manualBoundsRequired);
149 const QGeoShape &bounds)
151 QString requestString =
"https://";
152 requestString += m_uriProvider->getCurrentHost();
153 requestString +=
"/6.2/geocode.json";
155 requestString += getAuthenticationString();
156 requestString +=
"&gen=9";
158 requestString +=
"&language=";
159 requestString += languageToMarc(locale().language());
161 requestString +=
"&searchtext=";
162 requestString += QString(address).replace(
' ',
'+');
165 requestString +=
"&maxresults=";
166 requestString += QString::number(limit);
175 requestString +=
"&pageinformation=";
176 requestString += QString::number(offset/limit);
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());
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());
203 manualBoundsRequired =
true;
206 return geocode(requestString, bounds, manualBoundsRequired, limit, offset);
210 const QGeoShape &bounds,
211 bool manualBoundsRequired,
216 m_networkManager->get(QNetworkRequest(QUrl(requestString))),
217 limit, offset, bounds, manualBoundsRequired,
this);
219 connect(reply, &QGeoCodeReplyNokia::finished,
220 this, &QGeoCodingManagerEngineNokia::placesFinished);
222 connect(reply, &QGeoCodeReplyNokia::errorOccurred,
223 this, &QGeoCodingManagerEngineNokia::placesError);
229 const QGeoShape &bounds)
231 QString requestString =
"https://";
232 requestString += m_reverseGeocodingUriProvider->getCurrentHost();
233 requestString +=
"/6.2/reversegeocode.json";
235 requestString += getAuthenticationString();
236 requestString +=
"&gen=9";
238 requestString +=
"&mode=retrieveAddresses";
240 requestString +=
"&prox=";
241 requestString += trimDouble(coordinate.latitude());
242 requestString +=
",";
243 requestString += trimDouble(coordinate.longitude());
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());
252 manualBoundsRequired =
true;
255 manualBoundsRequired =
true;
258 requestString +=
"&language=";
259 requestString += languageToMarc(locale().language());
261 return geocode(requestString, bounds, manualBoundsRequired);
266 QString sDegree = QString::number(degree,
'g', decimalDigits);
268 int index = sDegree.indexOf(
'.');
273 return QString::number(degree,
'g', decimalDigits + index);
278 QGeoCodeReply *reply = qobject_cast<QGeoCodeReply *>(sender());
283 if (receivers(SIGNAL(finished(QGeoCodeReply*))) == 0) {
284 reply->deleteLater();
288 emit finished(reply);
293 QGeoCodeReply *reply = qobject_cast<QGeoCodeReply *>(sender());
298 if (receivers(SIGNAL(errorOccurred(QGeoCodeReply*,QGeoCodeReply::Error,QString))) == 0) {
299 reply->deleteLater();
303 emit errorOccurred(reply, error, errorString);
308 uint offset = 3 * (uint(language));
309 if (language == QLocale::C || offset + 3 >
sizeof(marc_language_code_list))
310 return QLatin1String(
"eng");
314 return QLatin1String(
"eng");
316 QString code(3, Qt::Uninitialized);
317 code[0] = ushort(c[0]);
318 code[1] = ushort(c[1]);
319 code[2] = ushort(c[2]);
QGeoCodeReply * geocode(const QString &searchString, int limit, int offset, const QGeoShape &bounds) override
Begins geocoding for a location matching address.
QGeoCodeReply * reverseGeocode(const QGeoCoordinate &coordinate, const QGeoShape &bounds) override
Begins the reverse geocoding of coordinate.
~QGeoCodingManagerEngineNokia()
QGeoCodeReply * geocode(const QGeoAddress &address, const QGeoShape &bounds) override
Begins the geocoding of address.
static QT_BEGIN_NAMESPACE const unsigned char marc_language_code_list[]