28#include <QCryptographicHash>
30#include <QImageReader>
31#include <QJsonParseError>
32#include <QRegularExpression>
36#include "moc_qgsarcgisrestquery.cpp"
41 QUrl queryUrl( baseurl );
42 QUrlQuery query( queryUrl );
43 query.addQueryItem( QStringLiteral(
"f" ), QStringLiteral(
"json" ) );
44 queryUrl.setQuery( query );
45 return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders,
nullptr, urlPrefix );
51 QUrl queryUrl( layerurl );
52 QUrlQuery query( queryUrl );
53 query.addQueryItem( QStringLiteral(
"f" ), QStringLiteral(
"json" ) );
54 queryUrl.setQuery( query );
55 return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders,
nullptr, urlPrefix );
61 QUrl queryUrl( layerurl +
"/query" );
62 QUrlQuery query( queryUrl );
63 query.addQueryItem( QStringLiteral(
"f" ), QStringLiteral(
"json" ) );
64 query.addQueryItem( QStringLiteral(
"where" ), whereClause.isEmpty() ? QStringLiteral(
"1=1" ) : whereClause );
65 query.addQueryItem( QStringLiteral(
"returnIdsOnly" ), QStringLiteral(
"true" ) );
68 query.addQueryItem( QStringLiteral(
"geometry" ), QStringLiteral(
"%1,%2,%3,%4" )
71 query.addQueryItem( QStringLiteral(
"geometryType" ), QStringLiteral(
"esriGeometryEnvelope" ) );
72 query.addQueryItem( QStringLiteral(
"spatialRel" ), QStringLiteral(
"esriSpatialRelEnvelopeIntersects" ) );
74 queryUrl.setQuery( query );
75 return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders,
nullptr, urlPrefix );
81 QUrl queryUrl( layerurl +
"/query" );
82 QUrlQuery query( queryUrl );
83 query.addQueryItem( QStringLiteral(
"f" ), QStringLiteral(
"json" ) );
84 query.addQueryItem( QStringLiteral(
"where" ), whereClause );
85 query.addQueryItem( QStringLiteral(
"returnExtentOnly" ), QStringLiteral(
"true" ) );
86 queryUrl.setQuery( query );
89 const QVariantMap res =
queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders,
nullptr, urlPrefix );
92 QgsDebugError( QStringLiteral(
"getExtent failed: %1 - %2" ).arg( errorTitle, errorText ) );
100 bool fetchGeometry,
const QStringList &fetchAttributes,
101 bool fetchM,
bool fetchZ,
103 QString &errorTitle, QString &errorText,
const QgsHttpHeaders &requestHeaders,
QgsFeedback *feedback,
const QString &urlPrefix )
106 for (
const int id : objectIds )
108 ids.append( QString::number(
id ) );
110 QUrl queryUrl( layerurl +
"/query" );
111 QUrlQuery query( queryUrl );
112 query.addQueryItem( QStringLiteral(
"f" ), QStringLiteral(
"json" ) );
113 query.addQueryItem( QStringLiteral(
"objectIds" ), ids.join( QLatin1Char(
',' ) ) );
114 if ( !crs.isEmpty() && crs.contains(
':' ) )
116 const QString wkid = crs.indexOf( QLatin1Char(
':' ) ) >= 0 ? crs.split(
':' )[1] : QString();
117 query.addQueryItem( QStringLiteral(
"inSR" ), wkid );
118 query.addQueryItem( QStringLiteral(
"outSR" ), wkid );
121 query.addQueryItem( QStringLiteral(
"returnGeometry" ), fetchGeometry ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
124 if ( fetchAttributes.isEmpty() )
125 outFields = QStringLiteral(
"*" );
127 outFields = fetchAttributes.join(
',' );
128 query.addQueryItem( QStringLiteral(
"outFields" ), outFields );
130 query.addQueryItem( QStringLiteral(
"returnM" ), fetchM ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
131 query.addQueryItem( QStringLiteral(
"returnZ" ), fetchZ ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
132 if ( !filterRect.
isNull() )
134 query.addQueryItem( QStringLiteral(
"geometry" ), QStringLiteral(
"%1,%2,%3,%4" )
135 .arg( filterRect.
xMinimum(), 0,
'f', -1 ).arg( filterRect.
yMinimum(), 0,
'f', -1 )
136 .arg( filterRect.
xMaximum(), 0,
'f', -1 ).arg( filterRect.
yMaximum(), 0,
'f', -1 ) );
137 query.addQueryItem( QStringLiteral(
"geometryType" ), QStringLiteral(
"esriGeometryEnvelope" ) );
138 query.addQueryItem( QStringLiteral(
"spatialRel" ), QStringLiteral(
"esriSpatialRelEnvelopeIntersects" ) );
140 queryUrl.setQuery( query );
141 return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders, feedback, urlPrefix );
146 QUrl queryUrl( layerurl +
"/query" );
147 QUrlQuery query( queryUrl );
148 query.addQueryItem( QStringLiteral(
"f" ), QStringLiteral(
"json" ) );
149 query.addQueryItem( QStringLiteral(
"where" ), whereClause.isEmpty() ? QStringLiteral(
"1=1" ) : whereClause );
150 query.addQueryItem( QStringLiteral(
"returnIdsOnly" ), QStringLiteral(
"true" ) );
151 query.addQueryItem( QStringLiteral(
"geometry" ), QStringLiteral(
"%1,%2,%3,%4" )
152 .arg( filterRect.
xMinimum(), 0,
'f', -1 ).arg( filterRect.
yMinimum(), 0,
'f', -1 )
153 .arg( filterRect.
xMaximum(), 0,
'f', -1 ).arg( filterRect.
yMaximum(), 0,
'f', -1 ) );
154 query.addQueryItem( QStringLiteral(
"geometryType" ), QStringLiteral(
"esriGeometryEnvelope" ) );
155 query.addQueryItem( QStringLiteral(
"spatialRel" ), QStringLiteral(
"esriSpatialRelEnvelopeIntersects" ) );
156 queryUrl.setQuery( query );
157 const QVariantMap objectIdData =
queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders, feedback, urlPrefix );
159 if ( objectIdData.isEmpty() )
161 return QList<quint32>();
165 const QVariantList objectIdsList = objectIdData[QStringLiteral(
"objectIds" )].toList();
166 ids.reserve( objectIdsList.size() );
167 for (
const QVariant &objectId : objectIdsList )
169 ids << objectId.toInt();
178 if ( !urlPrefix.isEmpty() )
179 url = QUrl( urlPrefix + url.toString() );
181 QNetworkRequest request( url );
196 errorTitle = QStringLiteral(
"Network error" );
200 const QString content = networkRequest.
reply().
content();
201 const thread_local QRegularExpression errorRx( QStringLiteral(
"Error: <.*?>(.*?)<" ) );
202 const QRegularExpressionMatch match = errorRx.match( content );
203 if ( match.hasMatch() )
205 errorText = match.captured( 1 );
213 *contentType = content.
rawHeader(
"Content-Type" );
219 const QByteArray reply =
queryService( url, authcfg, errorTitle, errorText, requestHeaders, feedback,
nullptr, urlPrefix );
220 if ( !errorTitle.isEmpty() )
222 return QVariantMap();
225 return QVariantMap();
229 const QJsonDocument doc = QJsonDocument::fromJson( reply, &err );
232 errorTitle = QStringLiteral(
"Parsing error" );
233 errorText = err.errorString();
234 QgsDebugError( QStringLiteral(
"Parsing error: %1" ).arg( err.errorString() ) );
235 return QVariantMap();
237 const QVariantMap res = doc.object().toVariantMap();
238 if ( res.contains( QStringLiteral(
"error" ) ) )
240 const QVariantMap error = res.value( QStringLiteral(
"error" ) ).toMap();
241 errorText = error.value( QStringLiteral(
"message" ) ).toString();
242 errorTitle = QObject::tr(
"Error %1" ).arg( error.value( QStringLiteral(
"code" ) ).toString() );
243 return QVariantMap();
250 if ( isTestEndpoint )
251 *isTestEndpoint =
false;
253 QUrl modifiedUrl( url );
254 if ( modifiedUrl.toString().contains( QLatin1String(
"fake_qgis_http_endpoint" ) ) )
256 if ( isTestEndpoint )
257 *isTestEndpoint =
true;
260 QString modifiedUrlString = modifiedUrl.toString();
262 modifiedUrlString = QUrl::fromPercentEncoding( modifiedUrlString.toUtf8() );
263 modifiedUrlString.replace( QLatin1String(
"fake_qgis_http_endpoint/" ), QLatin1String(
"fake_qgis_http_endpoint_" ) );
265 modifiedUrlString = modifiedUrlString.mid( QStringLiteral(
"http://" ).size() );
266 QString args = modifiedUrlString.indexOf(
'?' ) >= 0 ? modifiedUrlString.mid( modifiedUrlString.indexOf(
'?' ) ) : QString();
267 if ( modifiedUrlString.size() > 150 )
269 args = QCryptographicHash::hash( args.toUtf8(), QCryptographicHash::Md5 ).toHex();
273 args.replace( QLatin1String(
"?" ), QLatin1String(
"_" ) );
274 args.replace( QLatin1String(
"&" ), QLatin1String(
"_" ) );
275 args.replace( QLatin1String(
"<" ), QLatin1String(
"_" ) );
276 args.replace( QLatin1String(
">" ), QLatin1String(
"_" ) );
277 args.replace( QLatin1String(
"'" ), QLatin1String(
"_" ) );
278 args.replace( QLatin1String(
"\"" ), QLatin1String(
"_" ) );
279 args.replace( QLatin1String(
" " ), QLatin1String(
"_" ) );
280 args.replace( QLatin1String(
":" ), QLatin1String(
"_" ) );
281 args.replace( QLatin1String(
"/" ), QLatin1String(
"_" ) );
282 args.replace( QLatin1String(
"\n" ), QLatin1String(
"_" ) );
287 if ( modifiedUrlString[1] ==
'/' )
289 modifiedUrlString = modifiedUrlString[0] +
":/" + modifiedUrlString.mid( 2 );
292 modifiedUrlString = modifiedUrlString.mid( 0, modifiedUrlString.indexOf(
'?' ) ) + args;
293 QgsDebugMsgLevel( QStringLiteral(
"Get %1 (after laundering)" ).arg( modifiedUrlString ), 2 );
294 modifiedUrl = QUrl::fromLocalFile( modifiedUrlString );
295 if ( !QFile::exists( modifiedUrlString ) )
297 QgsDebugError( QStringLiteral(
"Local test file %1 for URL %2 does not exist!!!" ).arg( modifiedUrlString, url.toString() ) );
304void QgsArcGisRestQueryUtils::adjustBaseUrl( QString &baseUrl,
const QString &name )
306 const QStringList parts = name.split(
'/' );
308 for (
const QString &part : parts )
310 if ( !checkString.isEmpty() )
311 checkString += QString(
'/' );
314 if ( baseUrl.indexOf( QRegularExpression( checkString.replace(
'/', QLatin1String(
"\\/" ) ) + QStringLiteral(
"\\/?$" ) ) ) > -1 )
316 baseUrl = baseUrl.left( baseUrl.length() - checkString.length() - 1 );
324 QString base( baseUrl );
325 bool baseChecked =
false;
326 if ( !base.endsWith(
'/' ) )
327 base += QLatin1Char(
'/' );
329 const QStringList folderList = serviceData.value( QStringLiteral(
"folders" ) ).toStringList();
330 for (
const QString &folder : folderList )
334 adjustBaseUrl( base, folder );
337 visitor( folder, base + folder );
343 QString base( baseUrl );
344 bool baseChecked =
false;
345 if ( !base.endsWith(
'/' ) )
346 base += QLatin1Char(
'/' );
348 const QVariantList serviceList = serviceData.value( QStringLiteral(
"services" ) ).toList();
349 for (
const QVariant &service : serviceList )
351 const QVariantMap serviceMap = service.toMap();
352 const QString serviceTypeString = serviceMap.value( QStringLiteral(
"type" ) ).toString();
355 switch ( serviceType )
372 const QString serviceName = serviceMap.value( QStringLiteral(
"name" ) ).toString();
373 const QString displayName = serviceName.split(
'/' ).last();
376 adjustBaseUrl( base, serviceName );
380 visitor( displayName, base + serviceName +
'/' + serviceTypeString, serviceType );
384void QgsArcGisRestQueryUtils::addLayerItems(
const std::function<
void (
const QString &,
ServiceTypeFilter,
Qgis::GeometryType,
const QString &,
const QString &,
const QString &,
const QString &,
bool,
const QgsCoordinateReferenceSystem &,
const QString & )> &visitor,
const QVariantMap &serviceData,
const QString &parentUrl,
const QString &parentSupportedFormats,
const ServiceTypeFilter filter )
389 const QList<QByteArray> supportedFormats = QImageReader::supportedImageFormats();
390 const QStringList supportedImageFormatTypes = serviceData.value( QStringLiteral(
"supportedImageFormatTypes" ) ).toString().isEmpty() ? parentSupportedFormats.split(
',' ) : serviceData.value( QStringLiteral(
"supportedImageFormatTypes" ) ).toString().split(
',' );
391 QString format = supportedImageFormatTypes.value( 0 );
392 for (
const QString &encoding : supportedImageFormatTypes )
394 for (
const QByteArray &fmt : supportedFormats )
396 if ( encoding.startsWith( fmt, Qt::CaseInsensitive ) )
406 const QStringList capabilities = serviceData.value( QStringLiteral(
"capabilities" ) ).toString().split(
',' );
409 const bool serviceMayHaveQueryCapability = capabilities.contains( QStringLiteral(
"Query" ) ) ||
410 serviceData.value( QStringLiteral(
"serviceDataType" ) ).toString().startsWith( QLatin1String(
"esriImageService" ) );
412 const bool serviceMayRenderMaps = capabilities.contains( QStringLiteral(
"Map" ) ) ||
413 serviceData.value( QStringLiteral(
"serviceDataType" ) ).toString().startsWith( QLatin1String(
"esriImageService" ) );
415 const QVariantList layerInfoList = serviceData.value( QStringLiteral(
"layers" ) ).toList();
416 for (
const QVariant &layerInfo : layerInfoList )
418 const QVariantMap layerInfoMap = layerInfo.toMap();
419 const QString
id = layerInfoMap.value( QStringLiteral(
"id" ) ).toString();
420 const QString parentLayerId = layerInfoMap.value( QStringLiteral(
"parentLayerId" ) ).toString();
421 const QString name = layerInfoMap.value( QStringLiteral(
"name" ) ).toString();
422 const QString description = layerInfoMap.value( QStringLiteral(
"description" ) ).toString();
433 if ( !layerInfoMap.value( QStringLiteral(
"subLayerIds" ) ).toList().empty() )
445 const QString geometryType = layerInfoMap.value( QStringLiteral(
"geometryType" ) ).toString();
456 if ( serviceMayRenderMaps )
458 if ( geometryType.isEmpty() )
466 if ( !layerInfoMap.value( QStringLiteral(
"subLayerIds" ) ).toList().empty() )
477 const QVariantList tableInfoList = serviceData.value( QStringLiteral(
"tables" ) ).toList();
478 for (
const QVariant &tableInfo : tableInfoList )
480 const QVariantMap tableInfoMap = tableInfo.toMap();
481 const QString
id = tableInfoMap.value( QStringLiteral(
"id" ) ).toString();
482 const QString parentLayerId = tableInfoMap.value( QStringLiteral(
"parentLayerId" ) ).toString();
483 const QString name = tableInfoMap.value( QStringLiteral(
"name" ) ).toString();
484 const QString description = tableInfoMap.value( QStringLiteral(
"description" ) ).toString();
488 if ( !tableInfoMap.value( QStringLiteral(
"subLayerIds" ) ).toList().empty() )
500 if ( filter !=
ServiceTypeFilter::Vector && layerInfoList.count() > 1 && serviceData.contains( QStringLiteral(
"supportedImageFormatTypes" ) ) )
502 const QString name = QStringLiteral(
"(%1)" ).arg( QObject::tr(
"All layers" ) );
503 const QString description = serviceData.value( QStringLiteral(
"Comments" ) ).toString();
508 if ( serviceData.value( QStringLiteral(
"serviceDataType" ) ).toString().startsWith( QLatin1String(
"esriImageService" ) ) )
510 const QString name = serviceData.value( QStringLiteral(
"name" ) ).toString();
511 const QString description = serviceData.value( QStringLiteral(
"description" ) ).toString();
523QgsArcGisAsyncQuery::QgsArcGisAsyncQuery( QObject *parent )
528QgsArcGisAsyncQuery::~QgsArcGisAsyncQuery()
531 mReply->deleteLater();
534void QgsArcGisAsyncQuery::start(
const QUrl &url,
const QString &authCfg, QByteArray *result,
bool allowCache,
const QgsHttpHeaders &headers,
const QString &urlPrefix )
538 if ( !urlPrefix.isEmpty() )
539 mUrl = QUrl( urlPrefix + url.toString() );
540 QNetworkRequest request( mUrl );
546 const QString error = tr(
"network request update failed for authentication config" );
547 emit failed( QStringLiteral(
"Network" ), error );
552 request.setAttribute( QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy );
555 request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
556 request.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
true );
560 connect( mReply, &QNetworkReply::finished,
this, &QgsArcGisAsyncQuery::handleReply );
563void QgsArcGisAsyncQuery::handleReply()
565 mReply->deleteLater();
567 if ( mReply->error() != QNetworkReply::NoError )
569 QgsDebugError( QStringLiteral(
"Network error: %1" ).arg( mReply->errorString() ) );
570 emit failed( QStringLiteral(
"Network error" ), mReply->errorString() );
575 const QVariant redirect = mReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
578 QNetworkRequest request = mReply->request();
579 request.setAttribute( QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy );
582 request.setUrl( redirect.toUrl() );
584 connect( mReply, &QNetworkReply::finished,
this, &QgsArcGisAsyncQuery::handleReply );
588 *mResult = mReply->readAll();
597QgsArcGisAsyncParallelQuery::QgsArcGisAsyncParallelQuery(
const QString &authcfg,
const QgsHttpHeaders &requestHeaders, QObject *parent )
599 , mAuthCfg( authcfg )
600 , mRequestHeaders( requestHeaders )
604void QgsArcGisAsyncParallelQuery::start(
const QVector<QUrl> &urls, QVector<QByteArray> *results,
bool allowCache )
606 Q_ASSERT( results->size() == urls.size() );
608 mPendingRequests = mResults->size();
609 for (
int i = 0, n = urls.size(); i < n; ++i )
611 QNetworkRequest request( urls[i] );
615 mRequestHeaders.updateNetworkRequest( request );
618 const QString error = tr(
"network request update failed for authentication config" );
619 mErrors.append( error );
624 request.setAttribute( QNetworkRequest::HttpPipeliningAllowedAttribute,
true );
627 request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
628 request.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
true );
629 request.setRawHeader(
"Connection",
"keep-alive" );
632 reply->setProperty(
"idx", i );
633 connect( reply, &QNetworkReply::finished,
this, &QgsArcGisAsyncParallelQuery::handleReply );
637void QgsArcGisAsyncParallelQuery::handleReply()
639 QNetworkReply *reply = qobject_cast<QNetworkReply *>( QObject::sender() );
640 const QVariant redirect = reply->attribute( QNetworkRequest::RedirectionTargetAttribute );
641 const int idx = reply->property(
"idx" ).toInt();
642 reply->deleteLater();
643 if ( reply->error() != QNetworkReply::NoError )
646 mErrors.append( reply->errorString() );
652 QNetworkRequest request = reply->request();
653 request.setAttribute( QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy );
656 request.setUrl( redirect.toUrl() );
658 reply->setProperty(
"idx", idx );
659 connect( reply, &QNetworkReply::finished,
this, &QgsArcGisAsyncParallelQuery::handleReply );
664 ( *mResults )[idx] = reply->readAll();
667 if ( mPendingRequests == 0 )
669 emit finished( mErrors );
ArcGisRestServiceType
Available ArcGIS REST service types.
@ GeocodeServer
GeocodeServer.
@ SceneServer
SceneServer.
@ Unknown
Other unknown/unsupported type.
@ GlobeServer
GlobeServer.
@ ImageServer
ImageServer.
@ FeatureServer
FeatureServer.
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
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())
Performs a blocking request to a URL and returns the retrieved JSON content.
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, const QgsRectangle &filterRect, 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 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 getServiceInfo(const QString &baseurl, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsHttpHeaders &requestHeaders=QgsHttpHeaders(), const QString &urlPrefix=QString())
Retrieves JSON service info for the specified base URL.
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.
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 addLayerItems(const std::function< void(const QString &parentLayerId, ServiceTypeFilter serviceType, Qgis::GeometryType geometryType, const QString &layerId, const QString &name, const QString &description, const QString &url, bool isParentLayer, const QgsCoordinateReferenceSystem &crs, const QString &format)> &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 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 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())
Performs a blocking request to a URL and returns the retrieved 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 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 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())
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)