QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsgeonoderequest.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgeonoderequest.h
3  ---------------------
4  begin : Jul 2017
5  copyright : (C) 2017 by Muhammad Yarjuna Rohmat, Ismail Sunni
6  email : rohmat at kartoza dot com, ismail at kartoza dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 #include "qgssettings.h"
18 #include "qgsmessagelog.h"
19 #include "qgslogger.h"
20 #include "qgsgeonoderequest.h"
21 
22 #include <QEventLoop>
23 #include <QNetworkCacheMetaData>
24 #include <QByteArray>
25 #include <QJsonDocument>
26 #include <QJsonObject>
27 #include <QUrl>
28 #include <QDomDocument>
29 #include <QRegularExpression>
30 
31 QgsGeoNodeRequest::QgsGeoNodeRequest( const QString &baseUrl, bool forceRefresh, QObject *parent )
32  : QObject( parent )
33  , mBaseUrl( baseUrl )
34  , mForceRefresh( forceRefresh )
35 {
36 
37 }
38 
40 {
41  abort();
42 }
43 
45 {
46  mIsAborted = true;
47  if ( mGeoNodeReply )
48  {
49  mGeoNodeReply->deleteLater();
50  mGeoNodeReply = nullptr;
51  }
52 }
53 
55 {
56  request( QStringLiteral( "/api/layers/" ) );
57  QObject *obj = new QObject( this );
58 
59  connect( this, &QgsGeoNodeRequest::requestFinished, obj, [obj, this ]
60  {
61  QList<QgsGeoNodeRequest::ServiceLayerDetail> layers;
62  if ( mError.isEmpty() )
63  {
64  layers = parseLayers( this->lastResponse() );
65  }
66  emit layersFetched( layers );
67 
68  obj->deleteLater();
69  } );
70 }
71 
72 QList<QgsGeoNodeRequest::ServiceLayerDetail> QgsGeoNodeRequest::fetchLayersBlocking()
73 {
74  QList<QgsGeoNodeRequest::ServiceLayerDetail> layers;
75 
76  QEventLoop loop;
77  connect( this, &QgsGeoNodeRequest::requestFinished, &loop, &QEventLoop::quit );
78  QObject *obj = new QObject( this );
79  connect( this, &QgsGeoNodeRequest::layersFetched, obj, [&]( const QList<QgsGeoNodeRequest::ServiceLayerDetail> &fetched )
80  {
81  layers = fetched;
82  } );
83  fetchLayers();
84  loop.exec( QEventLoop::ExcludeUserInputEvents );
85  delete obj;
86  return layers;
87 }
88 
90 {
91  QgsGeoNodeStyle defaultStyle;
92  bool success = requestBlocking( QStringLiteral( "/api/layers?name=" ) + layerName );
93  if ( !success )
94  {
95  return defaultStyle;
96  }
97 
98  const QJsonDocument jsonDocument = QJsonDocument::fromJson( this->lastResponse() );
99  const QJsonObject jsonObject = jsonDocument.object();
100  const QList<QVariant> layers = jsonObject.toVariantMap().value( QStringLiteral( "objects" ) ).toList();
101  if ( layers.count() < 1 )
102  {
103  return defaultStyle;
104  }
105  QString defaultStyleUrl = layers.at( 0 ).toMap().value( QStringLiteral( "default_style" ) ).toString();
106 
107  defaultStyle = retrieveStyle( defaultStyleUrl );
108 
109  return defaultStyle;
110 
111 }
112 
113 QList<QgsGeoNodeStyle> QgsGeoNodeRequest::fetchStylesBlocking( const QString &layerName )
114 {
115  QList<QgsGeoNodeStyle> geoNodeStyles;
116  bool success = requestBlocking( QStringLiteral( "/api/styles?layer__name=" ) + layerName );
117  if ( !success )
118  {
119  return geoNodeStyles;
120  }
121 
122  const QJsonDocument jsonDocument = QJsonDocument::fromJson( this->lastResponse() );
123  const QJsonObject jsobObject = jsonDocument.object();
124  const QList<QVariant> styles = jsobObject.toVariantMap().value( QStringLiteral( "objects" ) ).toList();
125 
126  for ( const QVariant &style : styles )
127  {
128  const QVariantMap styleMap = style.toMap();
129  QString styleUrl = styleMap.value( QStringLiteral( "resource_uri" ) ).toString();
130  QgsGeoNodeStyle geoNodeStyle = retrieveStyle( styleUrl );
131  if ( !geoNodeStyle.name.isEmpty() )
132  {
133  geoNodeStyles.append( geoNodeStyle );
134  }
135  }
136 
137  return geoNodeStyles;
138 
139 }
140 
142 {
143  QString endPoint = QStringLiteral( "/api/styles/" ) + styleId;
144 
145  return retrieveStyle( endPoint );
146 }
147 
148 void QgsGeoNodeRequest::replyProgress( qint64 bytesReceived, qint64 bytesTotal )
149 {
150  QString msg = tr( "%1 of %2 bytes of request downloaded." ).arg( bytesReceived ).arg( bytesTotal < 0 ? QStringLiteral( "unknown number of" ) : QString::number( bytesTotal ) );
151  QgsDebugMsgLevel( msg, 3 );
152  emit statusChanged( msg );
153 }
154 
156 {
157  return mProtocol;
158 }
159 
160 void QgsGeoNodeRequest::setProtocol( const QString &protocol )
161 {
162  mProtocol = protocol;
163 }
164 
165 void QgsGeoNodeRequest::replyFinished()
166 {
167  QgsDebugMsgLevel( QStringLiteral( "Reply finished" ), 2 );
168  if ( !mIsAborted && mGeoNodeReply )
169  {
170  if ( mGeoNodeReply->error() == QNetworkReply::NoError )
171  {
172  QgsDebugMsgLevel( QStringLiteral( "reply OK" ), 2 );
173  QVariant redirect = mGeoNodeReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
174  if ( !redirect.isNull() )
175  {
176 
177  emit statusChanged( QStringLiteral( "GeoNode request redirected." ) );
178 
179  const QUrl &toUrl = redirect.toUrl();
180  if ( toUrl == mGeoNodeReply->url() )
181  {
182  mError = tr( "Redirect loop detected: %1" ).arg( toUrl.toString() );
183  QgsMessageLog::logMessage( mError, tr( "GeoNode" ) );
184  mHttpGeoNodeResponse.clear();
185  }
186  else
187  {
188  QNetworkRequest request( toUrl );
189  QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsGeoNodeRequest" ) );
190  request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, mForceRefresh ? QNetworkRequest::AlwaysNetwork : QNetworkRequest::PreferCache );
191  request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );
192 
193  mGeoNodeReply->deleteLater();
194  mGeoNodeReply = nullptr;
195 
196  QgsDebugMsgLevel( QStringLiteral( "redirected getcapabilities: %1 forceRefresh=%2" ).arg( redirect.toString() ).arg( mForceRefresh ), 3 );
197  mGeoNodeReply = QgsNetworkAccessManager::instance()->get( request );
198 
199  connect( mGeoNodeReply, &QNetworkReply::finished, this, &QgsGeoNodeRequest::replyFinished, Qt::DirectConnection );
200  connect( mGeoNodeReply, &QNetworkReply::downloadProgress, this, &QgsGeoNodeRequest::replyProgress, Qt::DirectConnection );
201  return;
202  }
203  }
204  else
205  {
207 
208  if ( nam->cache() )
209  {
210  QNetworkCacheMetaData cmd = nam->cache()->metaData( mGeoNodeReply->request().url() );
211 
212  QNetworkCacheMetaData::RawHeaderList hl;
213  const QNetworkCacheMetaData::RawHeaderList cmdHeaders = cmd.rawHeaders();
214  for ( const QNetworkCacheMetaData::RawHeader &h : cmdHeaders )
215  {
216  if ( h.first != QStringLiteral( "Cache-Control" ) )
217  hl.append( h );
218  }
219  cmd.setRawHeaders( hl );
220 
221  QgsDebugMsgLevel( QStringLiteral( "expirationDate:%1" ).arg( cmd.expirationDate().toString() ), 2 );
222  if ( cmd.expirationDate().isNull() )
223  {
224  QgsSettings settings;
225  cmd.setExpirationDate( QDateTime::currentDateTime().addSecs( settings.value( QStringLiteral( "qgis/defaultCapabilitiesExpiry" ), "24", QgsSettings::Providers ).toInt() * 60 * 60 ) );
226  }
227 
228  nam->cache()->updateMetaData( cmd );
229  }
230  else
231  {
232  QgsDebugMsg( QStringLiteral( "No cache for capabilities!" ) );
233  }
234 
235  mHttpGeoNodeResponse = mGeoNodeReply->readAll();
236 
237  if ( mHttpGeoNodeResponse.isEmpty() )
238  {
239  mError = tr( "Empty capabilities: %1" ).arg( mGeoNodeReply->errorString() );
240  }
241  }
242  }
243  else
244  {
245  mError = tr( "Request failed: %1" ).arg( mGeoNodeReply->errorString() );
246  QgsMessageLog::logMessage( mError, tr( "GeoNode" ) );
247  mHttpGeoNodeResponse.clear();
248  }
249  }
250 
251  if ( mGeoNodeReply )
252  {
253  mGeoNodeReply->deleteLater();
254  mGeoNodeReply = nullptr;
255  }
256 
257  emit requestFinished();
258 }
259 
260 QList<QgsGeoNodeRequest::ServiceLayerDetail> QgsGeoNodeRequest::parseLayers( const QByteArray &layerResponse )
261 {
262  QList<QgsGeoNodeRequest::ServiceLayerDetail> layers;
263  if ( layerResponse.isEmpty() )
264  {
265  return layers;
266  }
267 
268  const QJsonDocument jsonDocument = QJsonDocument::fromJson( layerResponse );
269  const QJsonObject jsonObject = jsonDocument.object();
270  const QVariantMap jsonVariantMap = jsonObject.toVariantMap();
271  const QVariantList layerList = jsonVariantMap.value( QStringLiteral( "objects" ) ).toList();
272 
273  QString wmsURLFormat, wfsURLFormat, xyzURLFormat;
274 
275  for ( const QVariant &layer : qgis::as_const( layerList ) )
276  {
278  const QVariantMap layerMap = layer.toMap();
279  QVariantList layerLinks = layerMap.value( QStringLiteral( "links" ) ).toList();
280 
281  if ( layerMap.value( QStringLiteral( "typename" ) ).toString().isEmpty() )
282  {
283  const QStringList splitUrl = layerMap.value( QStringLiteral( "detail_url" ) ).toString().split( '/' );
284  layerStruct.typeName = !splitUrl.isEmpty() ? splitUrl.last() : QString();
285  }
286  layerStruct.uuid = layerMap.value( QStringLiteral( "uuid" ) ).toString();
287  layerStruct.id = layerMap.value( QStringLiteral( "id" ) ).toString();
288  layerStruct.name = layerMap.value( QStringLiteral( "name" ) ).toString();
289  layerStruct.typeName = layerMap.value( QStringLiteral( "typename" ) ).toString();
290  layerStruct.title = layerMap.value( QStringLiteral( "title" ) ).toString();
291 
292  if ( ! layerMap.contains( QStringLiteral( "links" ) ) )
293  {
294  if ( wmsURLFormat.isEmpty() && wfsURLFormat.isEmpty() && xyzURLFormat.isEmpty() )
295  {
296  bool success = requestBlocking( QStringLiteral( "/api/layers/" ) + layerStruct.id );
297  if ( success )
298  {
299  const QJsonDocument resourceUriDocument = QJsonDocument::fromJson( this->lastResponse() );
300  const QJsonObject resourceUriObject = resourceUriDocument.object();
301  const QVariantMap resourceUriMap = resourceUriObject.toVariantMap();
302  QVariantList resourceUriLinks = resourceUriMap.value( QStringLiteral( "links" ) ).toList();
304  tempLayerStruct = parseOwsUrl( tempLayerStruct, resourceUriLinks );
305 
306  if ( tempLayerStruct.wmsURL.isEmpty() && tempLayerStruct.wfsURL.isEmpty() && tempLayerStruct.xyzURL.isEmpty() )
307  continue;
308 
309  // Avoid iterating all the layers to get the service url. Instead, generate a string format once we found one service url
310  // for every service (wms, wfs, xyz). And then use the string format for the other layers since they are identical.
311  switch ( tempLayerStruct.server )
312  {
314  {
315  wmsURLFormat = ! tempLayerStruct.wmsURL.isEmpty() ? tempLayerStruct.wmsURL.replace( layerStruct.name, QStringLiteral( "%1" ) ) : QString();
316  wfsURLFormat = ! tempLayerStruct.wfsURL.isEmpty() ? tempLayerStruct.wfsURL.replace( layerStruct.name, QStringLiteral( "%1" ) ) : QString();
317  xyzURLFormat = ! tempLayerStruct.xyzURL.isEmpty() ? tempLayerStruct.xyzURL.replace( layerStruct.name, QStringLiteral( "%1" ) ) : QString();
318  break;
319  }
321  {
322  wmsURLFormat = ! tempLayerStruct.wmsURL.isEmpty() ? tempLayerStruct.wmsURL : QString();
323  wfsURLFormat = ! tempLayerStruct.wfsURL.isEmpty() ? tempLayerStruct.wfsURL : QString();
324  xyzURLFormat = ! tempLayerStruct.xyzURL.isEmpty() ? tempLayerStruct.xyzURL.replace( layerStruct.name, QStringLiteral( "%1" ) ) : QString();
325  break;
326  }
328  break;
329  }
330  }
331  else
332  continue;
333  }
334  else
335  {
336  // Replace string argument with the layer id.
337  layerStruct.wmsURL = wmsURLFormat.contains( "%1" ) ? wmsURLFormat.arg( layerStruct.name ) : wmsURLFormat;
338  layerStruct.wfsURL = wfsURLFormat.contains( "%1" ) ? wfsURLFormat.arg( layerStruct.name ) : wfsURLFormat;
339  layerStruct.xyzURL = xyzURLFormat.contains( "%1" ) ? xyzURLFormat.arg( layerStruct.name ) : xyzURLFormat;
340  }
341  }
342  else
343  layerStruct = parseOwsUrl( layerStruct, layerLinks );
344 
345  layers.append( layerStruct );
346  }
347 
348  return layers;
349 }
350 
352 {
353  QString urlFound;
354  for ( const QVariant &link : layerLinks )
355  {
356  const QVariantMap linkMap = link.toMap();
357  if ( linkMap.contains( QStringLiteral( "link_type" ) ) )
358  {
359  if ( linkMap.value( QStringLiteral( "link_type" ) ) == QLatin1String( "OGC:WMS" ) )
360  {
361  urlFound = layerStruct.wmsURL = linkMap.value( QStringLiteral( "url" ) ).toString();
362  }
363  else if ( linkMap.value( QStringLiteral( "link_type" ) ) == QLatin1String( "OGC:WFS" ) )
364  {
365  urlFound = layerStruct.wfsURL = linkMap.value( QStringLiteral( "url" ) ).toString();
366  }
367  else if ( linkMap.value( QStringLiteral( "link_type" ) ) == QLatin1String( "image" ) )
368  {
369  if ( linkMap.contains( QStringLiteral( "name" ) ) && linkMap.value( QStringLiteral( "name" ) ) == QLatin1String( "Tiles" ) )
370  {
371  urlFound = layerStruct.xyzURL = linkMap.value( QStringLiteral( "url" ) ).toString();
372  }
373  }
374  }
375 
376  switch ( layerStruct.server )
377  {
380  break;
381 
383  {
384  layerStruct.server = urlFound.contains( QStringLiteral( "qgis-server" ) ) ? QgsGeoNodeRequest::BackendServer::QgisServer : QgsGeoNodeRequest::BackendServer::Geoserver;
385  break;
386  }
387  }
388  }
389 
390  return layerStruct;
391 }
392 
393 QgsGeoNodeStyle QgsGeoNodeRequest::retrieveStyle( const QString &styleUrl )
394 {
395  QgsGeoNodeStyle geoNodeStyle;
396 
397  bool success = requestBlocking( styleUrl );
398  if ( !success )
399  {
400  return geoNodeStyle;
401  }
402  const QJsonDocument jsonDocument = QJsonDocument::fromJson( this->lastResponse() );
403  const QJsonObject jsonObject = jsonDocument.object();
404 
405  const QVariantMap jsonMap = jsonObject.toVariantMap();
406  geoNodeStyle.id = jsonMap.value( QStringLiteral( "id" ) ).toString();
407  geoNodeStyle.name = jsonMap.value( QStringLiteral( "name" ) ).toString();
408  geoNodeStyle.title = jsonMap.value( QStringLiteral( "title" ) ).toString();
409  geoNodeStyle.styleUrl = jsonMap.value( QStringLiteral( "style_url" ) ).toString();
410 
411  success = requestBlocking( geoNodeStyle.styleUrl );
412  if ( !success )
413  {
414  return geoNodeStyle;
415  }
416 
417  success = geoNodeStyle.body.setContent( this->lastResponse() );
418  if ( !success )
419  {
420  return geoNodeStyle;
421  }
422 
423  return geoNodeStyle;
424 }
425 
426 QStringList QgsGeoNodeRequest::fetchServiceUrlsBlocking( const QString &serviceType )
427 {
428  QStringList urls;
429 
430  const QList<QgsGeoNodeRequest::ServiceLayerDetail> layers = fetchLayersBlocking();
431 
432  if ( layers.empty() )
433  {
434  return urls;
435  }
436 
437  for ( const QgsGeoNodeRequest::ServiceLayerDetail &layer : layers )
438  {
439  QString url;
440  if ( QString::compare( serviceType, QStringLiteral( "wms" ), Qt::CaseInsensitive ) == 0 )
441  {
442  url = layer.wmsURL;
443  }
444  else if ( QString::compare( serviceType, QStringLiteral( "wfs" ), Qt::CaseInsensitive ) == 0 )
445  {
446  url = layer.wfsURL;
447  }
448  else if ( QString::compare( serviceType, QStringLiteral( "xyz" ), Qt::CaseInsensitive ) == 0 )
449  {
450  url = layer.xyzURL;
451  }
452 
453  if ( url.isEmpty() )
454  continue;
455 
456  if ( !url.contains( QLatin1String( "://" ) ) )
457  {
458  url.prepend( protocol() );
459  }
460  if ( !urls.contains( url ) )
461  {
462  urls.append( url );
463  }
464  }
465 
466  return urls;
467 }
468 
470 {
471  QgsStringMap urls;
472 
473  const QList<QgsGeoNodeRequest::ServiceLayerDetail> layers = fetchLayersBlocking();
474 
475  if ( layers.empty() )
476  {
477  return urls;
478  }
479 
480  for ( const QgsGeoNodeRequest::ServiceLayerDetail &layer : layers )
481  {
482  QString url;
483 
484  if ( QString::compare( serviceType, QStringLiteral( "wms" ), Qt::CaseInsensitive ) == 0 )
485  {
486  url = layer.wmsURL;
487  }
488  else if ( QString::compare( serviceType, QStringLiteral( "wfs" ), Qt::CaseInsensitive ) == 0 )
489  {
490  url = layer.wfsURL;
491  }
492  else if ( QString::compare( serviceType, QStringLiteral( "xyz" ), Qt::CaseInsensitive ) == 0 )
493  {
494  url = layer.xyzURL;
495  }
496 
497  if ( url.isEmpty() )
498  continue;
499 
500  QString layerName = layer.name;
501  if ( !url.contains( QLatin1String( "://" ) ) )
502  {
503  url.prepend( protocol() );
504  }
505  if ( !urls.contains( url ) )
506  {
507  urls.insert( layerName, url );
508  }
509  }
510 
511  return urls;
512 }
513 
514 void QgsGeoNodeRequest::request( const QString &endPoint )
515 {
516  abort();
517  mIsAborted = false;
518  // Handle case where the endpoint is full url
519  QString url = endPoint.startsWith( mBaseUrl ) ? endPoint : mBaseUrl + endPoint;
520  QgsDebugMsgLevel( "Requesting to " + url, 2 );
521  setProtocol( url.split( QStringLiteral( "://" ) ).at( 0 ) );
522  QUrl layerUrl( url );
523  layerUrl.setScheme( protocol() );
524 
525  mError.clear();
526 
527  mGeoNodeReply = requestUrl( url );
528  connect( mGeoNodeReply, &QNetworkReply::finished, this, &QgsGeoNodeRequest::replyFinished, Qt::DirectConnection );
529  connect( mGeoNodeReply, &QNetworkReply::downloadProgress, this, &QgsGeoNodeRequest::replyProgress, Qt::DirectConnection );
530 }
531 
532 bool QgsGeoNodeRequest::requestBlocking( const QString &endPoint )
533 {
534  request( endPoint );
535 
536  QEventLoop loop;
537  connect( this, &QgsGeoNodeRequest::requestFinished, &loop, &QEventLoop::quit );
538  loop.exec( QEventLoop::ExcludeUserInputEvents );
539 
540  return mError.isEmpty();
541 }
542 
543 QNetworkReply *QgsGeoNodeRequest::requestUrl( const QString &url )
544 {
545  QNetworkRequest request( url );
546  request.setAttribute( QNetworkRequest::FollowRedirectsAttribute, true );
547 
548  QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsGeoNodeRequest" ) );
549  // Add authentication check here
550 
551  request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, mForceRefresh ? QNetworkRequest::AlwaysNetwork : QNetworkRequest::PreferCache );
552  request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );
553 
555 }
556 
557 
QgsGeoNodeRequest::fetchLayers
void fetchLayers()
Triggers a new request to fetch the list of available layers from the server.
Definition: qgsgeonoderequest.cpp:54
qgsgeonoderequest.h
QgsSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Definition: qgssettings.cpp:174
QgsGeoNodeRequest::~QgsGeoNodeRequest
~QgsGeoNodeRequest() override
Definition: qgsgeonoderequest.cpp:39
QgsGeoNodeRequest::layersFetched
void layersFetched(const QList< QgsGeoNodeRequest::ServiceLayerDetail > &layers)
Emitted when the result of a fetchLayers call has been received and processed.
QgsGeoNodeRequest::ServiceLayerDetail::typeName
QString typeName
Layer type name.
Definition: qgsgeonoderequest.h:92
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsGeoNodeRequest::ServiceLayerDetail::wmsURL
QString wmsURL
WMS URL for layer.
Definition: qgsgeonoderequest.h:96
QgsGeoNodeRequest::setProtocol
void setProtocol(const QString &protocol)
Sets the network protocol (e.g.
Definition: qgsgeonoderequest.cpp:160
QgsGeoNodeStyle::id
QString id
Unique style ID.
Definition: qgsgeonoderequest.h:40
QgsGeoNodeRequest::fetchServiceUrlDataBlocking
QgsStringMap fetchServiceUrlDataBlocking(const QString &serviceType)
Obtains a map of layer name to URL for available services with matching serviceType from the server.
Definition: qgsgeonoderequest.cpp:469
QgsGeoNodeStyle
Encapsulates information about a GeoNode layer style.
Definition: qgsgeonoderequest.h:32
QgsSettings::Providers
@ Providers
Definition: qgssettings.h:76
QgsGeoNodeRequest::fetchStylesBlocking
QList< QgsGeoNodeStyle > fetchStylesBlocking(const QString &layerName)
Requests the list of available styles for the layer with matching layerName from the server.
Definition: qgsgeonoderequest.cpp:113
QgsGeoNodeStyle::name
QString name
Style name.
Definition: qgsgeonoderequest.h:43
QgsSettings
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsGeoNodeRequest::lastResponse
QByteArray lastResponse() const
Returns the most recent response obtained from the server.
Definition: qgsgeonoderequest.h:216
QgsGeoNodeRequest::request
void request(const QString &endPoint)
Triggers a new request to the GeoNode server, with the requested endPoint.
Definition: qgsgeonoderequest.cpp:514
QgsSetRequestInitiatorClass
#define QgsSetRequestInitiatorClass(request, _class)
Definition: qgsnetworkaccessmanager.h:41
QgsGeoNodeStyle::title
QString title
Style title.
Definition: qgsgeonoderequest.h:46
QgsGeoNodeRequest::statusChanged
void statusChanged(const QString &statusQString)
Emitted when the status of an ongoing request is changed.
QgsGeoNodeRequest::fetchDefaultStyleBlocking
QgsGeoNodeStyle fetchDefaultStyleBlocking(const QString &layerName)
Requests the default style for the layer with matching layerName from the server.
Definition: qgsgeonoderequest.cpp:89
qgsnetworkaccessmanager.h
QgsGeoNodeStyle::styleUrl
QString styleUrl
Associated URL.
Definition: qgsgeonoderequest.h:52
QgsGeoNodeRequest::ServiceLayerDetail::title
QString title
Layer title.
Definition: qgsgeonoderequest.h:94
QgsNetworkAccessManager
network access manager for QGIS
Definition: qgsnetworkaccessmanager.h:252
QgsNetworkAccessManager::instance
static QgsNetworkAccessManager * instance(Qt::ConnectionType connectionType=Qt::BlockingQueuedConnection)
Returns a pointer to the active QgsNetworkAccessManager for the current thread.
Definition: qgsnetworkaccessmanager.cpp:121
QgsGeoNodeRequest::fetchLayersBlocking
QList< QgsGeoNodeRequest::ServiceLayerDetail > fetchLayersBlocking()
Requests the list of available layers from the server.
Definition: qgsgeonoderequest.cpp:72
QgsGeoNodeRequest::BackendServer::Geoserver
@ Geoserver
Geoserver used as backend.
QgsGeoNodeRequest::ServiceLayerDetail::xyzURL
QString xyzURL
XYZ tileserver URL for layer.
Definition: qgsgeonoderequest.h:100
QgsGeoNodeRequest::ServiceLayerDetail::wfsURL
QString wfsURL
WFS URL for layer.
Definition: qgsgeonoderequest.h:98
QgsGeoNodeRequest::ServiceLayerDetail
Service layer details for an individual layer from a GeoNode connection.
Definition: qgsgeonoderequest.h:84
QgsGeoNodeRequest::ServiceLayerDetail::uuid
QUuid uuid
Unique identifier (generate on the client side, not at the GeoNode server)
Definition: qgsgeonoderequest.h:86
QgsStringMap
QMap< QString, QString > QgsStringMap
Definition: qgis.h:758
QgsGeoNodeRequest::ServiceLayerDetail::id
QString id
Layer id.
Definition: qgsgeonoderequest.h:88
QgsGeoNodeRequest::BackendServer::QgisServer
@ QgisServer
QGIS server used as backend.
QgsGeoNodeRequest::ServiceLayerDetail::name
QString name
Layer name.
Definition: qgsgeonoderequest.h:90
qgssettings.h
QgsMessageLog::logMessage
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Definition: qgsmessagelog.cpp:27
QgsGeoNodeRequest::parseOwsUrl
QgsGeoNodeRequest::ServiceLayerDetail parseOwsUrl(QgsGeoNodeRequest::ServiceLayerDetail &layerStruct, const QVariantList &layerLinks)
Returns the updated ServiceLayerDetail struct with WMS/WFS/XYZ url.
Definition: qgsgeonoderequest.cpp:351
QgsGeoNodeStyle::body
QDomDocument body
DOM documenting containing style.
Definition: qgsgeonoderequest.h:49
QgsGeoNodeRequest::QgsGeoNodeRequest
QgsGeoNodeRequest(const QString &baseUrl, bool forceRefresh, QObject *parent=nullptr)
Constructor for QgsGeoNodeRequest.
Definition: qgsgeonoderequest.cpp:31
QgsGeoNodeRequest::requestFinished
void requestFinished()
Emitted when the existing request has been completed.
QgsGeoNodeRequest::requestBlocking
bool requestBlocking(const QString &endPoint)
Triggers a new request to the GeoNode server, with the requested endPoint.
Definition: qgsgeonoderequest.cpp:532
qgslogger.h
QgsGeoNodeRequest::fetchStyleBlocking
QgsGeoNodeStyle fetchStyleBlocking(const QString &styleId)
Requests the details for the style with matching styleId from the server.
Definition: qgsgeonoderequest.cpp:141
QgsGeoNodeRequest::protocol
QString protocol() const
Returns the network protocol (e.g.
Definition: qgsgeonoderequest.cpp:155
QgsGeoNodeRequest::BackendServer::Unknown
@ Unknown
Unknown backend.
QgsGeoNodeRequest::fetchServiceUrlsBlocking
QStringList fetchServiceUrlsBlocking(const QString &serviceType)
Requests the list of unique URLs for available services with matching serviceType from the server.
Definition: qgsgeonoderequest.cpp:426
QgsGeoNodeRequest::ServiceLayerDetail::server
BackendServer server
Backend server (geoserver or qgis-server)
Definition: qgsgeonoderequest.h:102
QgsGeoNodeRequest::abort
void abort()
Aborts any active network request immediately.
Definition: qgsgeonoderequest.cpp:44
qgsmessagelog.h