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
qgeocodingmanagerengineosm.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 Aaron McCarthy <mccarthy.aaron@gmail.com>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#include <QtCore/QVariantMap>
8#include <QtCore/QUrl>
9#include <QtCore/QUrlQuery>
10#include <QtCore/QLocale>
11#include <QtNetwork/QNetworkAccessManager>
12#include <QtNetwork/QNetworkRequest>
13#include <QtPositioning/QGeoCoordinate>
14#include <QtPositioning/QGeoAddress>
15#include <QtPositioning/QGeoShape>
16#include <QtPositioning/QGeoRectangle>
18
19
21
22static QString addressToQuery(const QGeoAddress &address)
23{
24 return address.street() + QStringLiteral(", ") +
25 address.district() + QStringLiteral(", ") +
26 address.city() + QStringLiteral(", ") +
27 address.state() + QStringLiteral(", ") +
28 address.country();
29}
30
31static QString boundingBoxToLtrb(const QGeoRectangle &rect)
32{
33 return QString::number(rect.topLeft().longitude()) + QLatin1Char(',') +
34 QString::number(rect.topLeft().latitude()) + QLatin1Char(',') +
35 QString::number(rect.bottomRight().longitude()) + QLatin1Char(',') +
36 QString::number(rect.bottomRight().latitude());
37}
38
39QGeoCodingManagerEngineOsm::QGeoCodingManagerEngineOsm(const QVariantMap &parameters,
40 QGeoServiceProvider::Error *error,
41 QString *errorString)
42: QGeoCodingManagerEngine(parameters), m_networkManager(new QNetworkAccessManager(this))
43{
44 if (parameters.contains(QStringLiteral("osm.useragent")))
45 m_userAgent = parameters.value(QStringLiteral("osm.useragent")).toString().toLatin1();
46 else
47 m_userAgent = "Qt Location based application";
48
49 if (parameters.contains(QStringLiteral("osm.geocoding.host")))
50 m_urlPrefix = parameters.value(QStringLiteral("osm.geocoding.host")).toString().toLatin1();
51 else
52 m_urlPrefix = QStringLiteral("https://nominatim.openstreetmap.org");
53
54 if (parameters.contains(QStringLiteral("osm.geocoding.debug_query")))
55 m_debugQuery = parameters.value(QStringLiteral("osm.geocoding.debug_query")).toBool();
56 if (parameters.contains(QStringLiteral("osm.geocoding.include_extended_data")))
57 m_includeExtraData = parameters.value(QStringLiteral("osm.geocoding.include_extended_data")).toBool();
58
59 *error = QGeoServiceProvider::NoError;
60 errorString->clear();
61}
62
66
67QGeoCodeReply *QGeoCodingManagerEngineOsm::geocode(const QGeoAddress &address, const QGeoShape &bounds)
68{
69 return geocode(addressToQuery(address), -1, -1, bounds);
70}
71
72QGeoCodeReply *QGeoCodingManagerEngineOsm::geocode(const QString &address, int limit, int offset, const QGeoShape &bounds)
73{
74 Q_UNUSED(offset);
75
76 QNetworkRequest request;
77 request.setRawHeader("User-Agent", m_userAgent);
78
79 QUrl url(QString("%1/search").arg(m_urlPrefix));
80 QUrlQuery query;
81 query.addQueryItem(QStringLiteral("q"), address);
82 query.addQueryItem(QStringLiteral("format"), QStringLiteral("json"));
83 query.addQueryItem(QStringLiteral("accept-language"), locale().name().left(2));
84 //query.addQueryItem(QStringLiteral("countrycodes"), QStringLiteral("au,jp"));
85 if (bounds.type() != QGeoShape::UnknownType) {
86 query.addQueryItem(QStringLiteral("viewbox"), boundingBoxToLtrb(bounds.boundingGeoRectangle()));
87 query.addQueryItem(QStringLiteral("bounded"), QStringLiteral("1"));
88 }
89 query.addQueryItem(QStringLiteral("polygon_geojson"), QStringLiteral("1"));
90 query.addQueryItem(QStringLiteral("addressdetails"), QStringLiteral("1"));
91 if (limit != -1)
92 query.addQueryItem(QStringLiteral("limit"), QString::number(limit));
93
94 url.setQuery(query);
95 request.setUrl(url);
96
97 QNetworkReply *reply = m_networkManager->get(request);
98
99 QGeoCodeReplyOsm *geocodeReply = new QGeoCodeReplyOsm(reply, m_includeExtraData, this);
100
101 connect(geocodeReply, &QGeoCodeReplyOsm::finished,
102 this, &QGeoCodingManagerEngineOsm::replyFinished);
103 connect(geocodeReply, &QGeoCodeReplyOsm::errorOccurred,
104 this, &QGeoCodingManagerEngineOsm::replyError);
105
106 return geocodeReply;
107}
108
109QGeoCodeReply *QGeoCodingManagerEngineOsm::reverseGeocode(const QGeoCoordinate &coordinate,
110 const QGeoShape &bounds)
111{
112 Q_UNUSED(bounds);
113
114 QNetworkRequest request;
115 request.setRawHeader("User-Agent", m_userAgent);
116
117 QUrl url(QString("%1/reverse").arg(m_urlPrefix));
118 QUrlQuery query;
119 query.addQueryItem(QStringLiteral("format"), QStringLiteral("json"));
120 query.addQueryItem(QStringLiteral("accept-language"), locale().name().left(2));
121 query.addQueryItem(QStringLiteral("lat"), QString::number(coordinate.latitude()));
122 query.addQueryItem(QStringLiteral("lon"), QString::number(coordinate.longitude()));
123 query.addQueryItem(QStringLiteral("zoom"), QStringLiteral("18"));
124 query.addQueryItem(QStringLiteral("addressdetails"), QStringLiteral("1"));
125
126 url.setQuery(query);
127 request.setUrl(url);
128
129 QNetworkReply *reply = m_networkManager->get(request);
130
131 QGeoCodeReplyOsm *geocodeReply = new QGeoCodeReplyOsm(reply, m_includeExtraData, this);
132
133 connect(geocodeReply, &QGeoCodeReplyOsm::finished,
134 this, &QGeoCodingManagerEngineOsm::replyFinished);
135 connect(geocodeReply, &QGeoCodeReplyOsm::errorOccurred,
136 this, &QGeoCodingManagerEngineOsm::replyError);
137
138 return geocodeReply;
139}
140
141void QGeoCodingManagerEngineOsm::replyFinished()
142{
143 QGeoCodeReply *reply = qobject_cast<QGeoCodeReply *>(sender());
144 if (reply)
145 emit finished(reply);
146}
147
148void QGeoCodingManagerEngineOsm::replyError(QGeoCodeReply::Error errorCode, const QString &errorString)
149{
150 QGeoCodeReply *reply = qobject_cast<QGeoCodeReply *>(sender());
151 if (reply)
152 emit errorOccurred(reply, errorCode, errorString);
153}
154
155QT_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.
Combined button and popup list for selecting options.
static QString boundingBoxToLtrb(const QGeoRectangle &rect)
static QT_BEGIN_NAMESPACE QString addressToQuery(const QGeoAddress &address)