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
qgeocodingmanagerengineohosmapkit.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 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
4#include <QtCore/qjsondocument.h>
5#include <QtCore/qjsonobject.h>
6#include <QtCore/qlocale.h>
7#include <QtCore/qurlquery.h>
8#include <QtCore/qurl.h>
9#include <QtNetwork/qnetworkaccessmanager.h>
10#include <QtNetwork/qnetworkreply.h>
11#include <QtNetwork/qnetworkrequest.h>
12#include <QtPositioning/qgeoaddress.h>
13#include <QtPositioning/qgeocoordinate.h>
14#include <QtPositioning/qgeorectangle.h>
15#include <QtPositioning/qgeoshape.h>
16#include <qgeocodereplyohosmapkit.h>
17#include <qgeocodingmanagerengineohosmapkit.h>
18#include <qohosmapkitcommon.h>
19
21
22namespace {
23
24const QString geocodeApiBasePath = QLatin1String("https://siteapi.cloud.huawei.com/mapApi/v1/siteService/");
25const QString geocodeApiPath = geocodeApiBasePath + QLatin1String("geocode");
26const QString reverseGeocodeApiPath = geocodeApiBasePath + QLatin1String("reverseGeocode");
27
29{
30public:
32 const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString);
33
34 QGeoCodeReply *geocode(const QGeoAddress &address, const QGeoShape &bounds) override;
35 QGeoCodeReply *geocode(const QString &address, int limit, int offset, const QGeoShape &bounds) override;
36 QGeoCodeReply *reverseGeocode(const QGeoCoordinate &coordinate, const QGeoShape &bounds) override;
37
38private:
39 QGeoCodeReply *createGeoCodeReply(const QUrl &requestUrl, const QByteArray &requestBody);
40
41 void onReplyFinished();
42 void onReplyError(QGeoCodeReply::Error errorCode, const QString &errorString);
43
44 QNetworkAccessManager m_networkManager;
45 QString m_userAgent;
46 QString m_authenticationKey;
47};
48
50 const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString)
54{
55 if (error != nullptr)
56 *error = QGeoServiceProvider::NoError;
57
58 if (errorString != nullptr)
59 errorString->clear();
60}
61
63 const QGeoAddress &address, const QGeoShape &bounds)
64{
65 return geocode(address.text().simplified(), 0, 0, bounds);
66}
67
69 const QString &address, int limit, int offset, const QGeoShape &bounds)
70{
71 Q_UNUSED(limit)
72 Q_UNUSED(offset)
73
74 if (address.isEmpty()) {
75 return new QGeoCodeReply(
76 QGeoCodeReply::CombinationError,
77 tr("Cannot do geocoding query using empty address"),
78 this);
79 }
80
81 QJsonObject geocodeRequestBody;
82
83 constexpr int restApiMaxAddressLength = 512;
84 geocodeRequestBody.insert(QStringLiteral("address"), address.left(restApiMaxAddressLength));
85
86 auto coordinateBoundsObj =
87 OhosMapKit::CoordinateBoundsJson::tryConvertFromQGeoRectangle(bounds.boundingGeoRectangle());
88 if (!coordinateBoundsObj.isEmpty())
89 geocodeRequestBody.insert(QStringLiteral("bounds"), coordinateBoundsObj);
90
91 geocodeRequestBody.insert(QStringLiteral("language"), OhosMapKit::getLanguageCode());
92
93 return createGeoCodeReply(
94 QUrl(geocodeApiPath), QJsonDocument(geocodeRequestBody).toJson(QJsonDocument::Compact));
95}
96
98 const QGeoCoordinate &coordinate, const QGeoShape &bounds)
99{
100 if (!coordinate.isValid()) {
101 return new QGeoCodeReply(
102 QGeoCodeReply::CombinationError,
103 tr("Cannot do reverse geocoding query using non-valid coordinates"),
104 this);
105 }
106
107 QJsonObject reverseGeocodeRequestBody;
108 reverseGeocodeRequestBody.insert(
109 QStringLiteral("location"), OhosMapKit::CoordinateJson::tryConvertFromQGeoCoordinate(coordinate));
110 reverseGeocodeRequestBody.insert(QStringLiteral("language"), OhosMapKit::getLanguageCode());
111
112 if (bounds.isValid() && !bounds.isEmpty()) {
113 constexpr int restApiMinRadiusInMeters = 0;
114 constexpr int restApiMaxRadiusInMeters = 50;
115 const int radius = bounds.center().distanceTo(bounds.boundingGeoRectangle().topLeft());
116 reverseGeocodeRequestBody.insert(
117 QStringLiteral("radius"),
118 qBound(restApiMinRadiusInMeters, radius, restApiMaxRadiusInMeters));
119 }
120
121 return createGeoCodeReply(
122 QUrl(reverseGeocodeApiPath),
123 QJsonDocument(reverseGeocodeRequestBody).toJson(QJsonDocument::Compact));
124}
125
126QGeoCodeReply *QGeoCodingManagerEngineOhosMapKit::createGeoCodeReply(
127 const QUrl &requestUrl, const QByteArray &requestBody)
128{
129 auto *reply = makeQGeoCodeReplyOhosMapKit(
130 m_networkManager.post(
131 OhosMapKit::createOhosMapKitNetworkRequestWithJsonBody(
132 requestUrl, m_userAgent, m_authenticationKey),
133 requestBody),
134 this);
135
136 connect(
137 reply, &QGeoCodeReply::finished,
138 this, &QGeoCodingManagerEngineOhosMapKit::onReplyFinished);
139 connect(
140 reply, &QGeoCodeReply::errorOccurred,
141 this, &QGeoCodingManagerEngineOhosMapKit::onReplyError);
142
143 return reply;
144}
145
146void QGeoCodingManagerEngineOhosMapKit::onReplyFinished()
147{
148 auto *geocodeReply = qobject_cast<QGeoCodeReply *>(sender());
149 if (geocodeReply != nullptr)
150 Q_EMIT finished(geocodeReply);
151}
152
153void QGeoCodingManagerEngineOhosMapKit::onReplyError(
154 QGeoCodeReply::Error errorCode, const QString &errorString)
155{
156 auto *geocodeReply = qobject_cast<QGeoCodeReply *>(sender());
157 if (geocodeReply != nullptr)
158 Q_EMIT errorOccurred(geocodeReply, errorCode, errorString);
159}
160
161}
162
164 const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString)
165{
166 return new QGeoCodingManagerEngineOhosMapKit(parameters, error, errorString);
167}
168
169QT_END_NAMESPACE
QGeoCodingManagerEngineOhosMapKit(const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString)
QGeoCodeReply * geocode(const QGeoAddress &address, const QGeoShape &bounds) override
Begins the geocoding of address.
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.
Combined button and popup list for selecting options.
QGeoCodingManagerEngine * makeQGeoCodingManagerEngineOhosMapKit(const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString)