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