Branch data Line data Source code
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 : : #ifndef QGSGEONODEREQUEST_H 16 : : #define QGSGEONODEREQUEST_H 17 : : 18 : : #include "qgis.h" 19 : : #include "qgis_core.h" 20 : : #include <QNetworkReply> 21 : : #include <QDomDocument> 22 : : #include <QObject> 23 : : #include <QUuid> 24 : : 25 : : /** 26 : : * \ingroup core 27 : : * \class QgsGeoNodeStyle 28 : : * \brief Encapsulates information about a GeoNode layer style. 29 : : * \since QGIS 3.0 30 : : */ 31 : 0 : struct CORE_EXPORT QgsGeoNodeStyle 32 : : { 33 : : #ifdef SIP_RUN 34 : : % TypeHeaderCode 35 : : #include <qgsgeonoderequest.h> 36 : : % End 37 : : #endif 38 : : 39 : : //! Unique style ID 40 : : QString id; 41 : : 42 : : //! Style name 43 : : QString name; 44 : : 45 : : //! Style title 46 : : QString title; 47 : : 48 : : //! DOM documenting containing style 49 : : QDomDocument body; 50 : : 51 : : //! Associated URL 52 : : QString styleUrl; 53 : : }; 54 : : 55 : : /** 56 : : * \ingroup core 57 : : * \class QgsGeoNodeRequest 58 : : * \brief Request handler for GeoNode servers. 59 : : * 60 : : * QgsGeoNodeRequest handles requesting and parsing service details from a GeoNode 61 : : * server instance, for instance requesting all available layers or layer styles. 62 : : * 63 : : * \since QGIS 3.0 64 : : */ 65 : : class CORE_EXPORT QgsGeoNodeRequest : public QObject 66 : : { 67 : 0 : Q_OBJECT 68 : : public: 69 : : 70 : : /** 71 : : * GeoNode backend server type. 72 : : */ 73 : : enum class BackendServer 74 : : { 75 : : Unknown, //!< Unknown backend 76 : : QgisServer, //!< QGIS server used as backend 77 : : Geoserver //!< Geoserver used as backend 78 : : }; 79 : : 80 : : /** 81 : : * Service layer details for an individual layer from a GeoNode connection. 82 : : */ 83 : 0 : struct ServiceLayerDetail 84 : : { 85 : : //! Unique identifier (generate on the client side, not at the GeoNode server) 86 : : QUuid uuid; 87 : : //! Layer id 88 : : QString id; 89 : : //! Layer name 90 : : QString name; 91 : : //! Layer type name 92 : : QString typeName; 93 : : //! Layer title 94 : : QString title; 95 : : //! WMS URL for layer 96 : : QString wmsURL; 97 : : //! WFS URL for layer 98 : : QString wfsURL; 99 : : //! XYZ tileserver URL for layer 100 : : QString xyzURL; 101 : : //! Backend server (geoserver or qgis-server) 102 : 0 : BackendServer server{}; 103 : : }; 104 : : 105 : : /** 106 : : * Constructor for QgsGeoNodeRequest. 107 : : * 108 : : * If \a forceRefresh is FALSE, then cached copies of the request may be reused. 109 : : */ 110 : : QgsGeoNodeRequest( const QString &baseUrl, bool forceRefresh, QObject *parent = nullptr ); 111 : : 112 : : ~QgsGeoNodeRequest() override; 113 : : 114 : : /** 115 : : * Triggers a new request to the GeoNode server, with the requested \a endPoint. 116 : : * Any existing request will be aborted. 117 : : * 118 : : * Calling this method does not block while waiting for a result. 119 : : * 120 : : * \warning When using the non-blocking methods in this class, sending 121 : : * overlapping requests results in undefined behavior. Use separate instances 122 : : * of QgsGeoNodeRequest instead to avoid this. 123 : : * 124 : : * \see requestBlocking() 125 : : */ 126 : : void request( const QString &endPoint ); 127 : : 128 : : /** 129 : : * Triggers a new request to the GeoNode server, with the requested \a endPoint. 130 : : * Any existing request will be aborted. 131 : : * 132 : : * Calling this method will block while waiting for a result. It should not be 133 : : * used from any code which potentially blocks operation in the main GUI thread. 134 : : * 135 : : * \see request() 136 : : */ 137 : : bool requestBlocking( const QString &endPoint ); 138 : : 139 : : /** 140 : : * Triggers a new request to fetch the list of available layers from the 141 : : * server. When complete, the layersFetched() signal will be emitted 142 : : * with the result. 143 : : * 144 : : * This method is non-blocking and returns immediately. 145 : : * 146 : : * \warning When using the non-blocking methods in this class, sending 147 : : * overlapping requests results in undefined behavior. Use separate instances 148 : : * of QgsGeoNodeRequest instead to avoid this. 149 : : * 150 : : * \see layersFetched() 151 : : * \see fetchLayersBlocking() 152 : : */ 153 : : void fetchLayers(); 154 : : 155 : : /** 156 : : * Requests the list of available layers from the server. 157 : : * 158 : : * This method is blocking and will wait for results from the server before returning. 159 : : * Accordingly it should not be used from any code which potentially blocks operation in the main GUI thread. 160 : : * 161 : : * \see fetchLayers() 162 : : */ 163 : : QList<QgsGeoNodeRequest::ServiceLayerDetail> fetchLayersBlocking(); 164 : : 165 : : /** 166 : : * Requests the list of available styles for the layer 167 : : * with matching \a layerName from the server. 168 : : * 169 : : * This method is blocking and will wait for results from the server before returning. 170 : : * Accordingly it should not be used from any code which potentially blocks operation in the main GUI thread. 171 : : * 172 : : */ 173 : : QList<QgsGeoNodeStyle> fetchStylesBlocking( const QString &layerName ); 174 : : 175 : : /** 176 : : * Requests the default style for the layer with matching \a layerName from the server. 177 : : * 178 : : * This method is blocking and will wait for results from the server before returning. 179 : : * Accordingly it should not be used from any code which potentially blocks operation in the main GUI thread. 180 : : */ 181 : : QgsGeoNodeStyle fetchDefaultStyleBlocking( const QString &layerName ); 182 : : 183 : : /** 184 : : * Requests the details for the style with matching \a styleId from the server. 185 : : * 186 : : * This method is blocking and will wait for results from the server before returning. 187 : : * Accordingly it should not be used from any code which potentially blocks operation in the main GUI thread. 188 : : */ 189 : : QgsGeoNodeStyle fetchStyleBlocking( const QString &styleId ); 190 : : 191 : : /** 192 : : * Requests the list of unique URLs for available services with matching \a serviceType from the server. 193 : : * 194 : : * This method is blocking and will wait for results from the server before returning. 195 : : * Accordingly it should not be used from any code which potentially blocks operation in the main GUI thread. 196 : : */ 197 : : QStringList fetchServiceUrlsBlocking( const QString &serviceType ); 198 : : 199 : : /** 200 : : * Obtains a map of layer name to URL for available services with matching \a serviceType from the server. 201 : : * 202 : : * This method is blocking and will wait for results from the server before returning. 203 : : * Accordingly it should not be used from any code which potentially blocks operation in the main GUI thread. 204 : : */ 205 : : QgsStringMap fetchServiceUrlDataBlocking( const QString &serviceType ); 206 : : 207 : : /** 208 : : * Returns the most recent error string for any encountered errors, or an empty string if 209 : : * no errors have been encountered. 210 : : */ 211 : : QString lastError() const { return mError; } 212 : : 213 : : /** 214 : : * Returns the most recent response obtained from the server. 215 : : */ 216 : 0 : QByteArray lastResponse() const { return mHttpGeoNodeResponse; } 217 : : 218 : : /** 219 : : * Returns the network protocol (e.g. 'http') used for connecting with the server. 220 : : * \see setProtocol() 221 : : */ 222 : : QString protocol() const; 223 : : 224 : : /** 225 : : * Sets the network \a protocol (e.g. 'http') used for connecting with the server. 226 : : * \see protocol() 227 : : */ 228 : : void setProtocol( const QString &protocol ); 229 : : 230 : : /** 231 : : * Returns the updated ServiceLayerDetail struct with WMS/WFS/XYZ url. 232 : : */ 233 : : QgsGeoNodeRequest::ServiceLayerDetail parseOwsUrl( QgsGeoNodeRequest::ServiceLayerDetail &layerStruct, const QVariantList &layerLinks ); 234 : : 235 : : public slots: 236 : : 237 : : /** 238 : : * Aborts any active network request immediately. 239 : : */ 240 : : void abort(); 241 : : 242 : : signals: 243 : : 244 : : /** 245 : : * Emitted when the status of an ongoing request is changed. 246 : : */ 247 : : void statusChanged( const QString &statusQString ); 248 : : 249 : : /** 250 : : * Emitted when the existing request has been completed. 251 : : */ 252 : : void requestFinished(); 253 : : 254 : : /** 255 : : * Emitted when the result of a fetchLayers call has been received and processed. 256 : : */ 257 : : void layersFetched( const QList<QgsGeoNodeRequest::ServiceLayerDetail> &layers ); 258 : : 259 : : private slots: 260 : : void replyFinished(); 261 : : void replyProgress( qint64, qint64 ); 262 : : 263 : : private: 264 : : 265 : : //! URL part of URI (httpuri) 266 : : QString mProtocol; 267 : : 268 : : //! URL part of URI (httpuri) 269 : : QString mBaseUrl; 270 : : 271 : : //! The reply to the geonode request 272 : : QNetworkReply *mGeoNodeReply = nullptr; 273 : : 274 : : //! The error message associated with the last error. 275 : : QString mError; 276 : : 277 : : //! The mime type of the message 278 : : QString mErrorFormat; 279 : : 280 : : //! Response 281 : : QByteArray mHttpGeoNodeResponse; 282 : : 283 : : bool mIsAborted = false; 284 : : bool mForceRefresh = false; 285 : : 286 : : QList<QgsGeoNodeRequest::ServiceLayerDetail> parseLayers( const QByteArray &layerResponse ); 287 : : QgsGeoNodeStyle retrieveStyle( const QString &styleUrl ); 288 : : 289 : : QNetworkReply *requestUrl( const QString &url ); 290 : : 291 : : }; 292 : : 293 : : #endif // QGSGEONODEREQUEST_H