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
geocodingmanagerengine_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 <QVariantMap>
8#include <QUrl>
9#include <QUrlQuery>
10#include <QLocale>
11#include <QNetworkAccessManager>
12#include <QNetworkRequest>
13#include <QGeoCoordinate>
14#include <QGeoAddress>
15#include <QGeoShape>
16#include <QGeoRectangle>
17
19
20// https://developers.arcgis.com/rest/geocode/api-reference/geocoding-find-address-candidates.htm
21// https://developers.arcgis.com/rest/geocode/api-reference/geocoding-reverse-geocode.htm
22
23static const QString kPrefixEsri(QStringLiteral("esri."));
24static const QString kParamUserAgent(kPrefixEsri + QStringLiteral("useragent"));
25
26static const QString kUrlGeocode(QStringLiteral("https://geocode.arcgis.com/arcgis/rest/services/"
27 "World/GeocodeServer/findAddressCandidates"));
28static const QString kUrlReverseGeocode(QStringLiteral(
29 "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode"));
30
31static QString addressToQuery(const QGeoAddress &address)
32{
33 return address.street() + QStringLiteral(", ")
34 + address.district() + QStringLiteral(", ")
35 + address.city() + QStringLiteral(", ")
36 + address.state() + QStringLiteral(", ")
37 + address.country();
38}
39
40static QString boundingBoxToLtrb(const QGeoRectangle &rect)
41{
42 return QString::number(rect.topLeft().longitude()) + QLatin1Char(',')
43 + QString::number(rect.topLeft().latitude()) + QLatin1Char(',')
44 + QString::number(rect.bottomRight().longitude()) + QLatin1Char(',')
45 + QString::number(rect.bottomRight().latitude());
46}
47
48GeoCodingManagerEngineEsri::GeoCodingManagerEngineEsri(const QVariantMap &parameters,
49 QGeoServiceProvider::Error *error,
50 QString *errorString)
51: QGeoCodingManagerEngine(parameters), m_networkManager(new QNetworkAccessManager(this))
52{
53 if (parameters.contains(kParamUserAgent))
54 m_userAgent = parameters.value(kParamUserAgent).toString().toLatin1();
55 else
56 m_userAgent = QByteArrayLiteral("Qt Location based application");
57
58 *error = QGeoServiceProvider::NoError;
59 errorString->clear();
60}
61
65
67 const QGeoShape &bounds)
68{
69 return geocode(addressToQuery(address), 1, -1, bounds);
70}
71
72QGeoCodeReply *GeoCodingManagerEngineEsri::geocode(const QString &address, int limit, int offset,
73 const QGeoShape &bounds)
74{
75 Q_UNUSED(offset);
76
77 QNetworkRequest request;
78 request.setHeader(QNetworkRequest::UserAgentHeader, m_userAgent);
79
80 QUrl url(kUrlGeocode);
81
82 QUrlQuery query;
83 query.addQueryItem(QStringLiteral("singleLine"), address);
84 query.addQueryItem(QStringLiteral("f"), QStringLiteral("json"));
85 query.addQueryItem(QStringLiteral("outFields"), "*");
86
87 if (bounds.type() != QGeoShape::UnknownType)
88 query.addQueryItem(QStringLiteral("searchExtent"), boundingBoxToLtrb(bounds.boundingGeoRectangle()));
89
90 if (limit != -1)
91 query.addQueryItem(QStringLiteral("maxLocations"), QString::number(limit));
92
93 url.setQuery(query);
94 request.setUrl(url);
95
96 QNetworkReply *reply = m_networkManager->get(request);
97 GeoCodeReplyEsri *geocodeReply = new GeoCodeReplyEsri(reply, GeoCodeReplyEsri::Geocode, this);
98
99 connect(geocodeReply, &GeoCodeReplyEsri::finished,
100 this, &GeoCodingManagerEngineEsri::replyFinished);
101 connect(geocodeReply, &GeoCodeReplyEsri::errorOccurred,
102 this, &GeoCodingManagerEngineEsri::replyError);
103
104 return geocodeReply;
105}
106
107QGeoCodeReply *GeoCodingManagerEngineEsri::reverseGeocode(const QGeoCoordinate &coordinate,
108 const QGeoShape &bounds)
109{
110 Q_UNUSED(bounds);
111
112 QNetworkRequest request;
113 request.setHeader(QNetworkRequest::UserAgentHeader, m_userAgent);
114
115 QUrl url(kUrlReverseGeocode);
116
117 QUrlQuery query;
118
119 query.addQueryItem(QStringLiteral("f"), QStringLiteral("json"));
120 query.addQueryItem(QStringLiteral("langCode"), locale().name().left(2));
121 query.addQueryItem(QStringLiteral("location"), QString::number(coordinate.longitude()) + QLatin1Char(',')
122 + QString::number(coordinate.latitude()));
123
124 url.setQuery(query);
125 request.setUrl(url);
126
127 QNetworkReply *reply = m_networkManager->get(request);
128 GeoCodeReplyEsri *geocodeReply = new GeoCodeReplyEsri(reply, GeoCodeReplyEsri::ReverseGeocode,
129 this);
130
131 connect(geocodeReply, &GeoCodeReplyEsri::finished,
132 this, &GeoCodingManagerEngineEsri::replyFinished);
133 connect(geocodeReply, &GeoCodeReplyEsri::errorOccurred,
134 this, &GeoCodingManagerEngineEsri::replyError);
135
136 return geocodeReply;
137}
138
139void GeoCodingManagerEngineEsri::replyFinished()
140{
141 QGeoCodeReply *reply = qobject_cast<QGeoCodeReply *>(sender());
142 if (reply)
143 emit finished(reply);
144}
145
146void GeoCodingManagerEngineEsri::replyError(QGeoCodeReply::Error errorCode,
147 const QString &errorString)
148{
149 QGeoCodeReply *reply = qobject_cast<QGeoCodeReply *>(sender());
150 if (reply)
151 emit errorOccurred(reply, errorCode, errorString);
152}
153
154QT_END_NAMESPACE
QGeoCodeReply * geocode(const QString &address, 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.
QGeoCodeReply * geocode(const QGeoAddress &address, const QGeoShape &bounds) override
Begins the geocoding of address.
static const QString kUrlGeocode(QStringLiteral("https://geocode.arcgis.com/arcgis/rest/services/" "World/GeocodeServer/findAddressCandidates"))
static QString boundingBoxToLtrb(const QGeoRectangle &rect)
static const QString kParamUserAgent(kPrefixEsri+QStringLiteral("useragent"))
static QString addressToQuery(const QGeoAddress &address)
static const QString kUrlReverseGeocode(QStringLiteral("https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode"))
static QT_BEGIN_NAMESPACE const QString kPrefixEsri(QStringLiteral("esri."))