4#include <QtLocation/private/qgeotilespec_p.h>
5#include <QtNetwork/QNetworkAccessManager>
6#include <QtNetwork/QSslError>
24 : QGeoTiledMapReply(spec, parent)
25 , _networkManager(networkManager)
28 qCDebug(QGeoTiledMapReplyQGCLog) <<
this;
33 if (QNetworkReply*
const reply = _networkReply.data()) {
34 _networkReply.clear();
35 (void) disconnect(reply,
nullptr,
this,
nullptr);
39 qCDebug(QGeoTiledMapReplyQGCLog) <<
this;
50 _initDataFromResources();
52 (void) connect(
this, &QGeoTiledMapReplyQGC::errorOccurred,
this, [
this](QGeoTiledMapReply::Error
error,
const QString &
errorString) {
54 setMapImageData(_badTile);
55 setMapImageFormat(QStringLiteral(
"png"));
57 }, Qt::AutoConnection);
61 qCWarning(QGeoTiledMapReplyQGCLog) <<
"Failed to create fetch tile task";
62 m_initialized =
false;
66 (void) connect(task, &
QGCMapTask::error,
this, &QGeoTiledMapReplyQGC::_cacheError);
69 m_initialized =
false;
76void QGeoTiledMapReplyQGC::_initDataFromResources()
78 if (_bingNoTileImage.isEmpty()) {
79 QFile file(
":/res/BingNoTileBytes.dat");
80 if (file.open(QFile::ReadOnly)) {
81 _bingNoTileImage = file.readAll();
86 if (_badTile.isEmpty()) {
87 QFile file(
":/res/images/notile.png");
88 if (file.open(QFile::ReadOnly)) {
89 _badTile = file.readAll();
95void QGeoTiledMapReplyQGC::_networkReplyFinished()
97 QNetworkReply*
const reply = qobject_cast<QNetworkReply*>(sender());
99 setError(QGeoTiledMapReply::UnknownError, tr(
"Unexpected Error"));
102 if (reply == _networkReply) {
103 _networkReply.clear();
105 reply->deleteLater();
107 if (reply->error() != QNetworkReply::NoError) {
111 if (!reply->isOpen()) {
112 setError(QGeoTiledMapReply::ParseError, tr(
"Empty Reply"));
116 const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
118 setError(QGeoTiledMapReply::CommunicationError, reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString());
122 QByteArray image = reply->readAll();
123 if (image.isEmpty()) {
124 setError(QGeoTiledMapReply::ParseError, tr(
"Image is Empty"));
130 setError(QGeoTiledMapReply::UnknownError, tr(
"Invalid Map Provider"));
134 if (mapProvider->isBingProvider() && (image == _bingNoTileImage)) {
135 setError(QGeoTiledMapReply::CommunicationError, tr(
"Bing Tile Above Zoom Level"));
139 if (mapProvider->isElevationProvider()) {
140 const SharedElevationProvider elevationProvider = std::dynamic_pointer_cast<const ElevationProvider>(mapProvider);
141 image = elevationProvider->serialize(image);
142 if (image.isEmpty()) {
143 setError(QGeoTiledMapReply::ParseError, tr(
"Failed to Serialize Terrain Tile"));
147 setMapImageData(image);
149 const QString
format = mapProvider->getImageFormat(image);
151 setError(QGeoTiledMapReply::ParseError, tr(
"Unknown Format"));
154 setMapImageFormat(format);
161void QGeoTiledMapReplyQGC::_networkReplyError(QNetworkReply::NetworkError
error)
163 if (
error != QNetworkReply::OperationCanceledError) {
164 const QNetworkReply*
const reply = qobject_cast<const QNetworkReply*>(sender());
166 setError(QGeoTiledMapReply::CommunicationError, tr(
"Invalid Reply"));
168 setError(QGeoTiledMapReply::CommunicationError, reply->errorString());
175void QGeoTiledMapReplyQGC::_networkReplySslErrors(
const QList<QSslError> &errors)
178 for (
const QSslError &
error : errors) {
186 setError(QGeoTiledMapReply::CommunicationError,
errorString);
190void QGeoTiledMapReplyQGC::_cacheReply(
QGCCacheTile *tile)
193 setMapImageData(tile->
img);
194 setMapImageFormat(tile->
format);
199 setError(QGeoTiledMapReply::UnknownError, tr(
"Invalid Cache Tile"));
208 setError(QGeoTiledMapReply::UnknownError, tr(
"Unexpected Cache Error"));
212 if (!_networkManager) {
213 setError(QGeoTiledMapReply::CommunicationError, tr(
"Network Manager Not Available"));
218 setError(QGeoTiledMapReply::CommunicationError, tr(
"Network Not Available"));
222 _request.setOriginatingObject(
this);
224 _networkReply = _networkManager->get(_request);
225 if (!_networkReply) {
226 setError(QGeoTiledMapReply::CommunicationError, tr(
"Failed to Create Network Reply"));
230 QNetworkReply*
const reply = _networkReply.data();
233 (void) connect(reply, &QNetworkReply::finished,
this, &QGeoTiledMapReplyQGC::_networkReplyFinished);
234 (void) connect(reply, &QNetworkReply::errorOccurred,
this, &QGeoTiledMapReplyQGC::_networkReplyError);
235 (void) connect(reply, &QNetworkReply::sslErrors,
this, &QGeoTiledMapReplyQGC::_networkReplySslErrors);
236 (void) connect(
this, &QGeoTiledMapReplyQGC::aborted, reply, &QNetworkReply::abort);
241 QGeoTiledMapReply::abort();
#define QGC_LOGGING_CATEGORY(name, categoryStr)
QGCMapEngine * getQGCMapEngine()
std::shared_ptr< const ElevationProvider > SharedElevationProvider
std::shared_ptr< const MapProvider > SharedMapProvider
void tileFetched(QGCCacheTile *tile)
bool addTask(QGCMapTask *task)
void error(QGCMapTask::TaskType type, const QString &errorString)
static QGCFetchTileTask * createFetchTileTask(const QString &type, int x, int y, int z)
static void cacheTile(const QString &type, int x, int y, int z, const QByteArray &image, const QString &format, qulonglong set=UINT64_MAX)
static QString getProviderTypeFromQtMapId(int qtMapId)
static std::shared_ptr< const MapProvider > getMapProviderFromQtMapId(int qtMapId)
void ignoreSslErrorsIfNeeded(QNetworkReply *reply)
bool isHttpSuccess(int statusCode)
Check if HTTP status indicates success (2xx)
bool isInternetAvailable()
Check if internet is reachable (online state, stricter than isNetworkAvailable)