28#include <QCryptographicHash>
30#include <QImageReader>
31#include <QJsonParseError>
32#include <QRegularExpression>
37#include "moc_qgsarcgisrestquery.cpp"
39using namespace Qt::StringLiterals;
42 const QString &baseurl,
const QString &authcfg, QString &errorTitle, QString &errorText,
const QgsHttpHeaders &requestHeaders,
const QString &urlPrefix,
bool forceRefresh
46 QUrl queryUrl( baseurl );
47 QUrlQuery query( queryUrl );
48 query.addQueryItem( u
"f"_s, u
"json"_s );
49 queryUrl.setQuery( query );
50 return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders,
nullptr, urlPrefix, forceRefresh );
56 QUrl queryUrl( layerurl );
57 QUrlQuery query( queryUrl );
58 query.addQueryItem( u
"f"_s, u
"json"_s );
59 queryUrl.setQuery( query );
60 return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders,
nullptr, urlPrefix );
64 const QString &layerurl,
const QString &authcfg, QString &errorTitle, QString &errorText,
const QgsHttpHeaders &requestHeaders,
const QString &urlPrefix,
const QgsRectangle &bbox,
const QString &whereClause
68 QUrl queryUrl( layerurl +
"/query" );
69 QUrlQuery query( queryUrl );
70 query.addQueryItem( u
"f"_s, u
"json"_s );
71 query.addQueryItem( u
"where"_s, whereClause.isEmpty() ? u
"1=1"_s : whereClause );
72 query.addQueryItem( u
"returnIdsOnly"_s, u
"true"_s );
75 query.addQueryItem( u
"geometry"_s, u
"%1,%2,%3,%4"_s.arg( bbox.
xMinimum(), 0,
'f', -1 ).arg( bbox.
yMinimum(), 0,
'f', -1 ).arg( bbox.
xMaximum(), 0,
'f', -1 ).arg( bbox.
yMaximum(), 0,
'f', -1 ) );
76 query.addQueryItem( u
"geometryType"_s, u
"esriGeometryEnvelope"_s );
77 query.addQueryItem( u
"spatialRel"_s, u
"esriSpatialRelEnvelopeIntersects"_s );
79 queryUrl.setQuery( query );
80 return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders,
nullptr, urlPrefix );
86 QUrl queryUrl( layerurl +
"/query" );
87 QUrlQuery query( queryUrl );
88 query.addQueryItem( u
"f"_s, u
"json"_s );
89 query.addQueryItem( u
"where"_s, whereClause );
90 query.addQueryItem( u
"returnExtentOnly"_s, u
"true"_s );
91 queryUrl.setQuery( query );
94 const QVariantMap res =
queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders,
nullptr, urlPrefix );
97 QgsDebugError( u
"getExtent failed: %1 - %2"_s.arg( errorTitle, errorText ) );
105 const QString &layerurl,
106 const QString &authcfg,
107 const QList<quint32> &objectIds,
110 const QStringList &fetchAttributes,
117 const QString &urlPrefix
121 for (
const int id : objectIds )
123 ids.append( QString::number(
id ) );
125 QUrl queryUrl( layerurl +
"/query" );
126 QUrlQuery query( queryUrl );
127 query.addQueryItem( u
"f"_s, u
"json"_s );
128 query.addQueryItem( u
"objectIds"_s, ids.join(
','_L1 ) );
129 if ( !crs.isEmpty() && crs.contains(
':' ) )
131 const QString wkid = crs.indexOf(
':'_L1 ) >= 0 ? crs.split(
':' )[1] : QString();
132 query.addQueryItem( u
"inSR"_s, wkid );
133 query.addQueryItem( u
"outSR"_s, wkid );
136 query.addQueryItem( u
"returnGeometry"_s, fetchGeometry ? u
"true"_s : u
"false"_s );
139 if ( fetchAttributes.isEmpty() )
142 outFields = fetchAttributes.join(
',' );
143 query.addQueryItem( u
"outFields"_s, outFields );
145 query.addQueryItem( u
"returnM"_s, fetchM ? u
"true"_s : u
"false"_s );
146 query.addQueryItem( u
"returnZ"_s, fetchZ ? u
"true"_s : u
"false"_s );
147 queryUrl.setQuery( query );
148 return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders, feedback, urlPrefix );
152 const QString &layerurl,
156 const QString &authcfg,
159 const QString &whereClause,
160 const QString &urlPrefix
163 QUrl queryUrl( layerurl +
"/query" );
164 QUrlQuery query( queryUrl );
165 query.addQueryItem( u
"f"_s, u
"json"_s );
166 query.addQueryItem( u
"where"_s, whereClause.isEmpty() ? u
"1=1"_s : whereClause );
167 query.addQueryItem( u
"returnIdsOnly"_s, u
"true"_s );
168 query.addQueryItem( u
"geometry"_s, u
"%1,%2,%3,%4"_s.arg( filterRect.
xMinimum(), 0,
'f', -1 ).arg( filterRect.
yMinimum(), 0,
'f', -1 ).arg( filterRect.
xMaximum(), 0,
'f', -1 ).arg( filterRect.
yMaximum(), 0,
'f', -1 ) );
169 query.addQueryItem( u
"geometryType"_s, u
"esriGeometryEnvelope"_s );
170 query.addQueryItem( u
"spatialRel"_s, u
"esriSpatialRelEnvelopeIntersects"_s );
171 queryUrl.setQuery( query );
172 const QVariantMap objectIdData =
queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders, feedback, urlPrefix );
174 if ( objectIdData.isEmpty() )
176 return QList<quint32>();
180 const QVariantList objectIdsList = objectIdData[u
"objectIds"_s].toList();
181 ids.reserve( objectIdsList.size() );
182 for (
const QVariant &objectId : objectIdsList )
184 ids << objectId.toInt();
190 const QUrl &u,
const QString &authcfg, QString &errorTitle, QString &errorText,
const QgsHttpHeaders &requestHeaders,
QgsFeedback *feedback, QString *contentType,
const QString &urlPrefix,
bool forceRefresh
195 if ( !urlPrefix.isEmpty() )
196 url = QUrl( urlPrefix + url.toString() );
198 QNetworkRequest request( url );
213 errorTitle = u
"Network error"_s;
217 const QString content = networkRequest.
reply().
content();
218 const thread_local QRegularExpression errorRx( u
"Error: <.*?>(.*?)<"_s );
219 const QRegularExpressionMatch match = errorRx.match( content );
220 if ( match.hasMatch() )
222 errorText = match.captured( 1 );
230 *contentType = content.
rawHeader(
"Content-Type" );
235 const QUrl &url,
const QString &authcfg, QString &errorTitle, QString &errorText,
const QgsHttpHeaders &requestHeaders,
QgsFeedback *feedback,
const QString &urlPrefix,
bool forceRefresh
238 const QByteArray reply =
queryService( url, authcfg, errorTitle, errorText, requestHeaders, feedback,
nullptr, urlPrefix, forceRefresh );
239 if ( !errorTitle.isEmpty() )
241 return QVariantMap();
244 return QVariantMap();
248 const QJsonDocument doc = QJsonDocument::fromJson( reply, &err );
251 errorTitle = u
"Parsing error"_s;
252 errorText = err.errorString();
253 QgsDebugError( u
"Parsing error: %1"_s.arg( err.errorString() ) );
254 return QVariantMap();
256 const QVariantMap res = doc.object().toVariantMap();
257 if ( res.contains( u
"error"_s ) )
259 const QVariantMap error = res.value( u
"error"_s ).toMap();
260 errorText = error.value( u
"message"_s ).toString();
261 errorTitle = QObject::tr(
"Error %1" ).arg( error.value( u
"code"_s ).toString() );
262 return QVariantMap();
269 if ( isTestEndpoint )
270 *isTestEndpoint =
false;
272 QUrl modifiedUrl( url );
273 if ( modifiedUrl.toString().contains(
"fake_qgis_http_endpoint"_L1 ) )
275 if ( isTestEndpoint )
276 *isTestEndpoint =
true;
279 QString modifiedUrlString = modifiedUrl.toString();
281 modifiedUrlString = QUrl::fromPercentEncoding( modifiedUrlString.toUtf8() );
282 modifiedUrlString.replace(
"fake_qgis_http_endpoint/"_L1,
"fake_qgis_http_endpoint_"_L1 );
284 modifiedUrlString = modifiedUrlString.mid( u
"http://"_s.size() );
285 QString args = modifiedUrlString.indexOf(
'?' ) >= 0 ? modifiedUrlString.mid( modifiedUrlString.indexOf(
'?' ) ) : QString();
286 if ( modifiedUrlString.size() > 150 )
288 args = QCryptographicHash::hash( args.toUtf8(), QCryptographicHash::Md5 ).toHex();
292 args.replace(
"?"_L1,
"_"_L1 );
293 args.replace(
"&"_L1,
"_"_L1 );
294 args.replace(
"<"_L1,
"_"_L1 );
295 args.replace(
">"_L1,
"_"_L1 );
296 args.replace(
"'"_L1,
"_"_L1 );
297 args.replace(
"\""_L1,
"_"_L1 );
298 args.replace(
" "_L1,
"_"_L1 );
299 args.replace(
":"_L1,
"_"_L1 );
300 args.replace(
"/"_L1,
"_"_L1 );
301 args.replace(
"\n"_L1,
"_"_L1 );
306 if ( modifiedUrlString[1] ==
'/' )
308 modifiedUrlString = modifiedUrlString[0] +
":/" + modifiedUrlString.mid( 2 );
311 modifiedUrlString = modifiedUrlString.mid( 0, modifiedUrlString.indexOf(
'?' ) ) + args;
312 QgsDebugMsgLevel( u
"Get %1 (after laundering)"_s.arg( modifiedUrlString ), 2 );
313 modifiedUrl = QUrl::fromLocalFile( modifiedUrlString );
314 if ( !QFile::exists( modifiedUrlString ) )
316 QgsDebugError( u
"Local test file %1 for URL %2 does not exist!!!"_s.arg( modifiedUrlString, url.toString() ) );
323void QgsArcGisRestQueryUtils::adjustBaseUrl( QString &baseUrl,
const QString &name )
325 const QStringList parts = name.split(
'/' );
327 for (
const QString &part : parts )
329 if ( !checkString.isEmpty() )
330 checkString += QString(
'/' );
333 if ( baseUrl.indexOf( QRegularExpression( checkString.replace(
'/',
"\\/"_L1 ) + u
"\\/?$"_s ) ) > -1 )
335 baseUrl = baseUrl.left( baseUrl.length() - checkString.length() - 1 );
343 QString base( baseUrl );
344 bool baseChecked =
false;
345 if ( !base.endsWith(
'/' ) )
348 const QStringList folderList = serviceData.value( u
"folders"_s ).toStringList();
349 for (
const QString &folder : folderList )
353 adjustBaseUrl( base, folder );
356 visitor( folder, base + folder );
362 QString base( baseUrl );
363 bool baseChecked =
false;
364 if ( !base.endsWith(
'/' ) )
367 const QVariantList serviceList = serviceData.value( u
"services"_s ).toList();
368 for (
const QVariant &service : serviceList )
370 const QVariantMap serviceMap = service.toMap();
371 const QString serviceTypeString = serviceMap.value( u
"type"_s ).toString();
374 switch ( serviceType )
391 const QString serviceName = serviceMap.value( u
"name"_s ).toString();
392 const QString displayName = serviceName.split(
'/' ).last();
395 adjustBaseUrl( base, serviceName );
399 visitor( displayName, base + serviceName +
'/' + serviceTypeString, serviceType );
404 const std::function<
void(
const LayerItemDetails &details )> &visitor,
const QVariantMap &serviceData,
const QString &parentUrl,
const QString &parentSupportedFormats,
const ServiceTypeFilter filter
410 const QList<QByteArray> supportedFormats = QImageReader::supportedImageFormats();
411 const QStringList supportedImageFormatTypes = serviceData.value( u
"supportedImageFormatTypes"_s ).toString().isEmpty() ? parentSupportedFormats.split(
',' )
412 : serviceData.value( u
"supportedImageFormatTypes"_s ).toString().split(
',' );
413 QString format = supportedImageFormatTypes.value( 0 );
414 for (
const QString &encoding : supportedImageFormatTypes )
416 for (
const QByteArray &fmt : supportedFormats )
418 if ( encoding.startsWith( fmt, Qt::CaseInsensitive ) )
432 if ( serviceData.value( u
"serviceDataType"_s ).toString().startsWith(
"esriImageService"_L1 ) )
439 const QVariantList layerInfoList = serviceData.value( u
"layers"_s ).toList();
440 for (
const QVariant &layerInfo : layerInfoList )
442 const QVariantMap layerInfoMap = layerInfo.toMap();
445 details.
layerId = layerInfoMap.value( u
"id"_s ).toString();
446 details.
parentLayerId = layerInfoMap.value( u
"parentLayerId"_s ).toString();
447 details.
name = layerInfoMap.value( u
"name"_s ).toString();
448 details.
description = layerInfoMap.value( u
"description"_s ).toString();
450 const QString geometryType = layerInfoMap.value( u
"geometryType"_s ).toString();
463 if ( geometryType.isEmpty() )
472 details.
url = parentUrl;
482 bool exposedAsVector =
false;
485 exposedAsVector =
true;
489 details.
url = parentUrl +
'/' + details.
layerId;
492 if ( !layerInfoMap.value( u
"subLayerIds"_s ).toList().empty() )
514 details.
url = parentUrl +
'/' + details.
layerId;
517 if ( !layerInfoMap.value( u
"subLayerIds"_s ).toList().empty() )
519 if ( !exposedAsVector )
535 const QVariantList tableInfoList = serviceData.value( u
"tables"_s ).toList();
536 for (
const QVariant &tableInfo : tableInfoList )
538 const QVariantMap tableInfoMap = tableInfo.toMap();
541 details.
layerId = tableInfoMap.value( u
"id"_s ).toString();
542 details.
parentLayerId = tableInfoMap.value( u
"parentLayerId"_s ).toString();
543 details.
name = tableInfoMap.value( u
"name"_s ).toString();
544 details.
description = tableInfoMap.value( u
"description"_s ).toString();
550 details.
url = parentUrl +
'/' + details.
layerId;
553 if ( !tableInfoMap.value( u
"subLayerIds"_s ).toList().empty() )
569 if ( filter !=
ServiceTypeFilter::Vector && layerInfoList.count() > 1 && serviceData.contains( u
"supportedImageFormatTypes"_s ) )
575 details.
url = parentUrl;
585 if ( serviceData.value( u
"serviceDataType"_s ).toString().startsWith(
"esriImageService"_L1 ) )
590 details.
name = serviceData.value( u
"name"_s ).toString();
591 details.
description = serviceData.value( u
"description"_s ).toString();
594 details.
url = parentUrl;
610QgsArcGisAsyncQuery::QgsArcGisAsyncQuery( QObject *parent )
614QgsArcGisAsyncQuery::~QgsArcGisAsyncQuery()
617 mReply->deleteLater();
620void QgsArcGisAsyncQuery::start(
const QUrl &url,
const QString &authCfg, QByteArray *result,
bool allowCache,
const QgsHttpHeaders &headers,
const QString &urlPrefix )
624 if ( !urlPrefix.isEmpty() )
625 mUrl = QUrl( urlPrefix + url.toString() );
626 QNetworkRequest request( mUrl );
632 const QString error = tr(
"network request update failed for authentication config" );
633 emit failed( u
"Network"_s, error );
638 request.setAttribute( QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy );
641 request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
642 request.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
true );
646 connect( mReply, &QNetworkReply::finished,
this, &QgsArcGisAsyncQuery::handleReply );
649void QgsArcGisAsyncQuery::handleReply()
651 mReply->deleteLater();
653 if ( mReply->error() != QNetworkReply::NoError )
655 QgsDebugError( u
"Network error: %1"_s.arg( mReply->errorString() ) );
656 emit failed( u
"Network error"_s, mReply->errorString() );
661 const QVariant redirect = mReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
664 QNetworkRequest request = mReply->request();
665 request.setAttribute( QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy );
668 request.setUrl( redirect.toUrl() );
670 connect( mReply, &QNetworkReply::finished,
this, &QgsArcGisAsyncQuery::handleReply );
674 *mResult = mReply->readAll();
683QgsArcGisAsyncParallelQuery::QgsArcGisAsyncParallelQuery(
const QString &authcfg,
const QgsHttpHeaders &requestHeaders, QObject *parent )
685 , mAuthCfg( authcfg )
686 , mRequestHeaders( requestHeaders )
689void QgsArcGisAsyncParallelQuery::start(
const QVector<QUrl> &urls, QVector<QByteArray> *results,
bool allowCache )
691 Q_ASSERT( results->size() == urls.size() );
693 mPendingRequests = mResults->size();
694 for (
int i = 0, n = urls.size(); i < n; ++i )
696 QNetworkRequest request( urls[i] );
700 mRequestHeaders.updateNetworkRequest( request );
703 const QString error = tr(
"network request update failed for authentication config" );
704 mErrors.append( error );
709 request.setAttribute( QNetworkRequest::HttpPipeliningAllowedAttribute,
true );
712 request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
713 request.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
true );
714 request.setRawHeader(
"Connection",
"keep-alive" );
717 reply->setProperty(
"idx", i );
718 connect( reply, &QNetworkReply::finished,
this, &QgsArcGisAsyncParallelQuery::handleReply );
722void QgsArcGisAsyncParallelQuery::handleReply()
724 QNetworkReply *reply = qobject_cast<QNetworkReply *>( QObject::sender() );
725 const QVariant redirect = reply->attribute( QNetworkRequest::RedirectionTargetAttribute );
726 const int idx = reply->property(
"idx" ).toInt();
727 reply->deleteLater();
728 if ( reply->error() != QNetworkReply::NoError )
731 mErrors.append( reply->errorString() );
737 QNetworkRequest request = reply->request();
738 request.setAttribute( QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy );
741 request.setUrl( redirect.toUrl() );
743 reply->setProperty(
"idx", idx );
744 connect( reply, &QNetworkReply::finished,
this, &QgsArcGisAsyncParallelQuery::handleReply );
749 ( *mResults )[idx] = reply->readAll();
752 if ( mPendingRequests == 0 )
754 emit finished( mErrors );
ArcGisRestServiceType
Available ArcGIS REST service types.
@ GeocodeServer
GeocodeServer.
@ SceneServer
SceneServer.
@ Unknown
Other unknown/unsupported type.
@ GlobeServer
GlobeServer.
@ ImageServer
ImageServer.
@ FeatureServer
FeatureServer.
QFlags< ArcGisRestServiceCapability > ArcGisRestServiceCapabilities
Available ArcGIS REST service capabilities.
WkbType
The WKB type describes the number of dimensions a geometry has.
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
static void visitFolderItems(const std::function< void(const QString &folderName, const QString &url)> &visitor, const QVariantMap &serviceData, const QString &baseUrl)
Calls the specified visitor function on all folder items found within the given service data.
static QVariantMap queryServiceJSON(const QUrl &url, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsHttpHeaders &requestHeaders=QgsHttpHeaders(), QgsFeedback *feedback=nullptr, const QString &urlPrefix=QString(), bool forceRefresh=false)
Performs a blocking request to a URL and returns the retrieved JSON content.
static QgsRectangle getExtent(const QString &layerurl, const QString &whereClause, const QString &authcfg, const QgsHttpHeaders &requestHeaders=QgsHttpHeaders(), const QString &urlPrefix=QString())
Retrieves the extent for the features matching a whereClause.
static QVariantMap getObjectIds(const QString &layerurl, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsHttpHeaders &requestHeaders=QgsHttpHeaders(), const QString &urlPrefix=QString(), const QgsRectangle &bbox=QgsRectangle(), const QString &whereClause=QString())
Retrieves all object IDs for the specified layer URL.
static QUrl parseUrl(const QUrl &url, bool *isTestEndpoint=nullptr)
Parses and processes a url.
static QByteArray queryService(const QUrl &url, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsHttpHeaders &requestHeaders=QgsHttpHeaders(), QgsFeedback *feedback=nullptr, QString *contentType=nullptr, const QString &urlPrefix=QString(), bool forceRefresh=false)
Performs a blocking request to a URL and returns the retrieved data.
static QVariantMap getServiceInfo(const QString &baseurl, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsHttpHeaders &requestHeaders=QgsHttpHeaders(), const QString &urlPrefix=QString(), bool forceRefresh=false)
Retrieves JSON service info for the specified base URL.
ServiceTypeFilter
Service types.
static QVariantMap getLayerInfo(const QString &layerurl, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsHttpHeaders &requestHeaders=QgsHttpHeaders(), const QString &urlPrefix=QString())
Retrieves JSON layer info for the specified layer URL.
static void visitServiceItems(const std::function< void(const QString &serviceName, const QString &url, Qgis::ArcGisRestServiceType serviceType)> &visitor, const QVariantMap &serviceData, const QString &baseUrl)
Calls the specified visitor function on all service items found within the given service data.
static QList< quint32 > getObjectIdsByExtent(const QString &layerurl, const QgsRectangle &filterRect, QString &errorTitle, QString &errorText, const QString &authcfg, const QgsHttpHeaders &requestHeaders=QgsHttpHeaders(), QgsFeedback *feedback=nullptr, const QString &whereClause=QString(), const QString &urlPrefix=QString())
Gets a list of object IDs which fall within the specified extent.
static void addLayerItems(const std::function< void(const LayerItemDetails &details)> &visitor, const QVariantMap &serviceData, const QString &parentUrl, const QString &parentSupportedFormats, const ServiceTypeFilter filter=ServiceTypeFilter::AllTypes)
Calls the specified visitor function on all layer items found within the given service data.
static QVariantMap getObjects(const QString &layerurl, const QString &authcfg, const QList< quint32 > &objectIds, const QString &crs, bool fetchGeometry, const QStringList &fetchAttributes, bool fetchM, bool fetchZ, QString &errorTitle, QString &errorText, const QgsHttpHeaders &requestHeaders=QgsHttpHeaders(), QgsFeedback *feedback=nullptr, const QString &urlPrefix=QString())
Retrieves all matching objects from the specified layer URL.
static QgsCoordinateReferenceSystem convertSpatialReference(const QVariantMap &spatialReferenceMap)
Converts a spatial reference JSON definition to a QgsCoordinateReferenceSystem value.
static Qgis::WkbType convertGeometryType(const QString &type)
Converts an ESRI REST geometry type to a WKB type.
static Qgis::ArcGisRestServiceType serviceTypeFromString(const QString &type)
Converts a string value to a REST service type.
static Qgis::ArcGisRestServiceCapabilities serviceCapabilitiesFromString(const QString &capabilities)
Parses a capabilities string to known values.
static QgsRectangle convertRectangle(const QVariant &value)
Converts a rectangle value to a QgsRectangle.
A thread safe class for performing blocking (sync) network requests, with full support for QGIS proxy...
void setAuthCfg(const QString &authCfg)
Sets the authentication config id which should be used during the request.
QString errorMessage() const
Returns the error message string, after a get(), post(), head() or put() request has been made.
ErrorCode get(QNetworkRequest &request, bool forceRefresh=false, QgsFeedback *feedback=nullptr, RequestFlags requestFlags=QgsBlockingNetworkRequest::RequestFlags())
Performs a "get" operation on the specified request.
@ NoError
No error was encountered.
QgsNetworkReplyContent reply() const
Returns the content of the network reply, after a get(), post(), head() or put() request has been mad...
Represents a coordinate reference system (CRS).
Base class for feedback objects to be used for cancellation of something running in a worker thread.
bool isCanceled() const
Tells whether the operation has been canceled already.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
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...
QByteArray content() const
Returns the reply content.
QByteArray rawHeader(const QByteArray &headerName) const
Returns the content of the header with the specified headerName, or an empty QByteArray if the specif...
A rectangle specified with double values.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
static Qgis::GeometryType geometryType(Qgis::WkbType type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
#define QgsSetRequestInitiatorClass(request, _class)
#define QgsSetRequestInitiatorId(request, str)
Encapsulates details relating to a layer item.
ServiceTypeFilter serviceType
Service type.
bool isMapServerWithQueryCapability
true if layer is a map server with the query capability
QString description
Description.
QString format
Map server image format.
QgsCoordinateReferenceSystem crs
Coordinate reference system.
bool isMapServerSpecialAllLayersOption
true if layer is the special map server "all layers" layer
bool isParentLayer
true if layer item represents a parent layer
QString parentLayerId
Parent layer ID.
Qgis::GeometryType geometryType
Geometry type.