33#include "moc_qgsstaccontroller.cpp"
35using namespace Qt::StringLiterals;
39 qDeleteAll( mReplies );
40 qDeleteAll( mFetchedStacObjects );
41 qDeleteAll( mFetchedItemCollections );
42 qDeleteAll( mFetchedCollections );
47 QNetworkReply *reply = fetchAsync( url );
48 connect( reply, &QNetworkReply::finished,
this, &QgsStacController::handleStacObjectReply );
50 return reply->property(
"requestId" ).toInt();
55 QNetworkReply *reply = fetchAsync( url );
56 connect( reply, &QNetworkReply::finished,
this, &QgsStacController::handleItemCollectionReply );
58 return reply->property(
"requestId" ).toInt();
63 QNetworkReply *reply = fetchAsync( url );
64 connect( reply, &QNetworkReply::finished,
this, &QgsStacController::handleCollectionsReply );
66 return reply->property(
"requestId" ).toInt();
71 for ( QNetworkReply *reply : std::as_const( mReplies ) )
79QNetworkReply *QgsStacController::fetchAsync(
const QUrl &url )
81 QNetworkRequest req( url );
84 req.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
85 req.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
true );
87 if ( !mAuthCfg.isEmpty() )
94 QNetworkReply *reply = nam->get( req );
96 if ( !mAuthCfg.isEmpty() )
101 mReplies.append( reply );
103 QgsDebugMsgLevel( u
"Fired STAC request with id %1"_s.arg( reply->property(
"requestId" ).toInt() ), 2 );
108void QgsStacController::handleStacObjectReply()
110 QNetworkReply *reply = qobject_cast<QNetworkReply *>( QObject::sender() );
114 const int requestId = reply->property(
"requestId" ).toInt();
115 QgsDebugMsgLevel( u
"Finished STAC request with id %1"_s.arg( requestId ), 2 );
117 if ( reply->error() != QNetworkReply::NoError )
119 const QString contentType = reply->header( QNetworkRequest::ContentTypeHeader ).toString();
120 const QString errorMessage = contentType.startsWith(
"text/plain"_L1 ) ? reply->readAll() : reply->errorString();
123 reply->deleteLater();
124 mReplies.removeOne( reply );
128 const QByteArray data = reply->readAll();
129 QgsStacParser parser;
134 std::unique_ptr< QgsStacObject > object;
135 switch ( parser.
type() )
144 object = parser.
item();
148 error = parser.
error().isEmpty() ? u
"Parsed STAC data is not a Catalog, Collection or Item"_s : parser.
error();
151 mFetchedStacObjects.insert( requestId,
object.release() );
153 reply->deleteLater();
154 mReplies.removeOne( reply );
157void QgsStacController::handleItemCollectionReply()
159 QNetworkReply *reply = qobject_cast<QNetworkReply *>( QObject::sender() );
163 const int requestId = reply->property(
"requestId" ).toInt();
164 QgsDebugMsgLevel( u
"Finished STAC request with id %1"_s.arg( requestId ), 2 );
166 if ( reply->error() != QNetworkReply::NoError )
168 const QString contentType = reply->header( QNetworkRequest::ContentTypeHeader ).toString();
169 const QString errorMessage = contentType.startsWith(
"text/plain"_L1 ) ? reply->readAll() : reply->errorString();
172 reply->deleteLater();
173 mReplies.removeOne( reply );
177 const QByteArray data = reply->readAll();
178 QgsStacParser parser;
182 std::unique_ptr<QgsStacItemCollection> fc = parser.
itemCollection();
183 mFetchedItemCollections.insert( requestId, fc.release() );
185 reply->deleteLater();
186 mReplies.removeOne( reply );
189void QgsStacController::handleCollectionsReply()
191 QNetworkReply *reply = qobject_cast<QNetworkReply *>( QObject::sender() );
195 const int requestId = reply->property(
"requestId" ).toInt();
196 QgsDebugMsgLevel( u
"Finished STAC request with id %1"_s.arg( requestId ), 2 );
198 if ( reply->error() != QNetworkReply::NoError )
200 const QString contentType = reply->header( QNetworkRequest::ContentTypeHeader ).toString();
201 const QString errorMessage = contentType.startsWith(
"text/plain"_L1 ) ? reply->readAll() : reply->errorString();
204 reply->deleteLater();
205 mReplies.removeOne( reply );
209 const QByteArray data = reply->readAll();
210 QgsStacParser parser;
214 QgsStacCollectionList *cols = parser.
collections();
215 mFetchedCollections.insert( requestId, cols );
217 reply->deleteLater();
218 mReplies.removeOne( reply );
223 std::unique_ptr< QgsStacObject > obj( mFetchedStacObjects.take( requestId ) );
225 if ( T *downCastObj =
dynamic_cast< T *
>( obj.get() ) )
227 ( void ) obj.release();
228 return std::unique_ptr< T >( downCastObj );
239 std::unique_ptr< QgsStacItemCollection > col( mFetchedItemCollections.take( requestId ) );
245 std::unique_ptr< QgsStacCollectionList > cols( mFetchedCollections.take( requestId ) );
253 if ( content.
error() != QNetworkReply::NoError )
261 const QByteArray data = content.
content();
266 std::unique_ptr< QgsStacItemCollection > ic( parser.
itemCollection() );
269 *error = parser.
error();
278 if ( content.
error() != QNetworkReply::NoError )
286 const QByteArray data = content.
content();
290 std::unique_ptr< QgsStacCollectionList > col( parser.
collections() );
293 *error = parser.
error();
300 QNetworkRequest req( url );
303 req.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
304 req.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
true );
323 QFile file( fileName );
324 const bool ok = file.open( QIODevice::ReadOnly );
332 parser.
setData( file.readAll() );
340 QFile file( fileName );
341 const bool ok = file.open( QIODevice::ReadOnly );
349 parser.
setData( file.readAll() );
356 QFile file( fileName );
357 const bool ok = file.open( QIODevice::ReadOnly );
365 parser.
setData( file.readAll() );
367 return parser.
item();
374 if ( content.
error() != QNetworkReply::NoError )
382 const QByteArray data = content.
content();
387 std::unique_ptr< QgsStacObject > object;
388 switch ( parser.
type() )
397 object = parser.
item();
403 std::unique_ptr< T > res;
404 if ( T *castObject =
dynamic_cast< T *
>(
object.get() ) )
406 ( void )
object.release();
407 res.reset( castObject );
411 QgsDebugError(
"Retrieved STAC object could not be cast to expected type" );
415 *error = parser.
error();
@ Unknown
Type is not known.
@ Collection
STAC collection.
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
bool updateNetworkRequest(QNetworkRequest &request, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkRequest with an authentication config.
bool updateNetworkReply(QNetworkReply *reply, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkReply with an authentication config (used to skip known SSL errors,...
QNetworkAccessManager with additional QGIS specific logic.
static QgsNetworkReplyContent blockingGet(QNetworkRequest &request, const QString &authCfg=QString(), bool forceRefresh=false, QgsFeedback *feedback=nullptr, Qgis::NetworkRequestFlags flags=Qgis::NetworkRequestFlags())
Posts a GET request to obtain the contents of the target request and returns a new QgsNetworkReplyCon...
static QgsNetworkAccessManager * instance(Qt::ConnectionType connectionType=Qt::BlockingQueuedConnection)
Returns a pointer to the active QgsNetworkAccessManager for the current thread.
Encapsulates a network reply within a container which is inexpensive to copy and safe to pass between...
QString errorString() const
Returns the error text for the reply, or an empty string if no error was encountered.
QByteArray content() const
Returns the reply content.
QNetworkReply::NetworkError error() const
Returns the reply's error message, or QNetworkReply::NoError if no error was encountered.
int fetchStacObjectAsync(const QUrl &url)
Initiates an asynchronous request for a STAC object using the url and returns an associated request i...
std::unique_ptr< QgsStacItemCollection > takeItemCollection(int requestId)
Returns the feature collection fetched with the specified requestId It should be used after the finis...
std::unique_ptr< QgsStacCollectionList > takeCollections(int requestId)
Returns the collections collection fetched with the specified requestId It should be used after the f...
std::unique_ptr< QgsStacCollection > openLocalCollection(const QString &fileName) const
Returns a STAC Collection by parsing a local file The caller takes ownership of the returned collecti...
int fetchCollectionsAsync(const QUrl &url)
Initiates an asynchronous request for a Collections collection using the url and returns an associate...
std::unique_ptr< QgsStacCatalog > openLocalCatalog(const QString &fileName) const
Returns a STAC Catalog by parsing a local file The caller takes ownership of the returned catalog.
void setAuthCfg(const QString &authCfg)
Sets the authentication config id which should be used during the request.
std::unique_ptr< QgsStacItem > openLocalItem(const QString &fileName) const
Returns a STAC Item by parsing a local file The caller takes ownership of the returned item.
std::unique_ptr< QgsStacItemCollection > fetchItemCollection(const QUrl &url, QString *error=nullptr)
Fetches a feature collection from url using a blocking network request.
~QgsStacController() override
Default destructor.
int fetchItemCollectionAsync(const QUrl &url)
Initiates an asynchronous request for a feature collection using the url and returns an associated re...
QString authCfg() const
Returns the authentication config id which will be used during the request.
void finishedCollectionsRequest(int id, QString errorMessage)
This signal is fired when an async request initiated with fetchCollectionsAsync is finished.
std::unique_ptr< T > fetchStacObject(const QUrl &url, QString *error=nullptr)
Fetches a STAC object from url using a blocking network request.
void finishedItemCollectionRequest(int id, QString errorMessage)
This signal is fired when an async request initiated with fetchItemCollectionAsync is finished.
std::unique_ptr< T > takeStacObject(int requestId)
Returns the STAC object fetched with the specified requestId.
void cancelPendingAsyncRequests()
Cancels all pending async requests.
std::unique_ptr< QgsStacCollectionList > fetchCollections(const QUrl &url, QString *error=nullptr)
Fetches collections from url using a blocking network request.
void finishedStacObjectRequest(int id, QString errorMessage)
This signal is fired when an async request initiated with fetchStacObjectAsync is finished.
SpatioTemporal Asset Catalog JSON parser.
QString error() const
Returns the last parsing error.
QgsStacCollectionList * collections()
Returns the parsed STAC API Collections If parsing failed, nullptr is returned The caller takes owner...
void setBaseUrl(const QUrl &url)
Sets the base url that will be used to resolve relative links.
std::unique_ptr< QgsStacItem > item()
Returns the parsed STAC Item If parsing failed, nullptr is returned The caller takes ownership of the...
std::unique_ptr< QgsStacItemCollection > itemCollection()
Returns the parsed STAC API Item Collection If parsing failed, nullptr is returned The caller takes o...
std::unique_ptr< QgsStacCatalog > catalog()
Returns the parsed STAC Catalog If parsing failed, nullptr is returned The caller takes ownership of ...
Qgis::StacObjectType type() const
Returns the type of the parsed object.
std::unique_ptr< QgsStacCollection > collection()
Returns the parsed STAC Collection If parsing failed, nullptr is returned The caller takes ownership ...
void setData(const QByteArray &data)
Sets the JSON data to be parsed.
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
#define QgsSetRequestInitiatorClass(request, _class)