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,
118 const QString &urlPrefix
122 for (
const int id : objectIds )
124 ids.append( QString::number(
id ) );
126 QUrl queryUrl( layerurl +
"/query" );
127 QUrlQuery query( queryUrl );
128 query.addQueryItem( u
"f"_s, u
"json"_s );
129 query.addQueryItem( u
"objectIds"_s, ids.join(
','_L1 ) );
130 if ( !crs.isEmpty() && crs.contains(
':' ) )
132 const QString wkid = crs.indexOf(
':'_L1 ) >= 0 ? crs.split(
':' )[1] : QString();
133 query.addQueryItem( u
"inSR"_s, wkid );
134 query.addQueryItem( u
"outSR"_s, wkid );
137 query.addQueryItem( u
"returnGeometry"_s, fetchGeometry ? u
"true"_s : u
"false"_s );
140 if ( fetchAttributes.isEmpty() )
143 outFields = fetchAttributes.join(
',' );
144 query.addQueryItem( u
"outFields"_s, outFields );
146 query.addQueryItem( u
"returnM"_s, fetchM ? u
"true"_s : u
"false"_s );
147 query.addQueryItem( u
"returnZ"_s, fetchZ ? u
"true"_s : u
"false"_s );
148 if ( !filterRect.
isNull() )
150 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 ) );
151 query.addQueryItem( u
"geometryType"_s, u
"esriGeometryEnvelope"_s );
152 query.addQueryItem( u
"spatialRel"_s, u
"esriSpatialRelEnvelopeIntersects"_s );
154 queryUrl.setQuery( query );
155 return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders, feedback, urlPrefix );
159 const QString &layerurl,
163 const QString &authcfg,
166 const QString &whereClause,
167 const QString &urlPrefix
170 QUrl queryUrl( layerurl +
"/query" );
171 QUrlQuery query( queryUrl );
172 query.addQueryItem( u
"f"_s, u
"json"_s );
173 query.addQueryItem( u
"where"_s, whereClause.isEmpty() ? u
"1=1"_s : whereClause );
174 query.addQueryItem( u
"returnIdsOnly"_s, u
"true"_s );
175 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 ) );
176 query.addQueryItem( u
"geometryType"_s, u
"esriGeometryEnvelope"_s );
177 query.addQueryItem( u
"spatialRel"_s, u
"esriSpatialRelEnvelopeIntersects"_s );
178 queryUrl.setQuery( query );
179 const QVariantMap objectIdData =
queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders, feedback, urlPrefix );
181 if ( objectIdData.isEmpty() )
183 return QList<quint32>();
187 const QVariantList objectIdsList = objectIdData[u
"objectIds"_s].toList();
188 ids.reserve( objectIdsList.size() );
189 for (
const QVariant &objectId : objectIdsList )
191 ids << objectId.toInt();
197 const QUrl &u,
const QString &authcfg, QString &errorTitle, QString &errorText,
const QgsHttpHeaders &requestHeaders,
QgsFeedback *feedback, QString *contentType,
const QString &urlPrefix,
bool forceRefresh
202 if ( !urlPrefix.isEmpty() )
203 url = QUrl( urlPrefix + url.toString() );
205 QNetworkRequest request( url );
220 errorTitle = u
"Network error"_s;
224 const QString content = networkRequest.
reply().
content();
225 const thread_local QRegularExpression errorRx( u
"Error: <.*?>(.*?)<"_s );
226 const QRegularExpressionMatch match = errorRx.match( content );
227 if ( match.hasMatch() )
229 errorText = match.captured( 1 );
237 *contentType = content.
rawHeader(
"Content-Type" );
242 const QUrl &url,
const QString &authcfg, QString &errorTitle, QString &errorText,
const QgsHttpHeaders &requestHeaders,
QgsFeedback *feedback,
const QString &urlPrefix,
bool forceRefresh
245 const QByteArray reply =
queryService( url, authcfg, errorTitle, errorText, requestHeaders, feedback,
nullptr, urlPrefix, forceRefresh );
246 if ( !errorTitle.isEmpty() )
248 return QVariantMap();
251 return QVariantMap();
255 const QJsonDocument doc = QJsonDocument::fromJson( reply, &err );
258 errorTitle = u
"Parsing error"_s;
259 errorText = err.errorString();
260 QgsDebugError( u
"Parsing error: %1"_s.arg( err.errorString() ) );
261 return QVariantMap();
263 const QVariantMap res = doc.object().toVariantMap();
264 if ( res.contains( u
"error"_s ) )
266 const QVariantMap error = res.value( u
"error"_s ).toMap();
267 errorText = error.value( u
"message"_s ).toString();
268 errorTitle = QObject::tr(
"Error %1" ).arg( error.value( u
"code"_s ).toString() );
269 return QVariantMap();
276 if ( isTestEndpoint )
277 *isTestEndpoint =
false;
279 QUrl modifiedUrl( url );
280 if ( modifiedUrl.toString().contains(
"fake_qgis_http_endpoint"_L1 ) )
282 if ( isTestEndpoint )
283 *isTestEndpoint =
true;
286 QString modifiedUrlString = modifiedUrl.toString();
288 modifiedUrlString = QUrl::fromPercentEncoding( modifiedUrlString.toUtf8() );
289 modifiedUrlString.replace(
"fake_qgis_http_endpoint/"_L1,
"fake_qgis_http_endpoint_"_L1 );
291 modifiedUrlString = modifiedUrlString.mid( u
"http://"_s.size() );
292 QString args = modifiedUrlString.indexOf(
'?' ) >= 0 ? modifiedUrlString.mid( modifiedUrlString.indexOf(
'?' ) ) : QString();
293 if ( modifiedUrlString.size() > 150 )
295 args = QCryptographicHash::hash( args.toUtf8(), QCryptographicHash::Md5 ).toHex();
299 args.replace(
"?"_L1,
"_"_L1 );
300 args.replace(
"&"_L1,
"_"_L1 );
301 args.replace(
"<"_L1,
"_"_L1 );
302 args.replace(
">"_L1,
"_"_L1 );
303 args.replace(
"'"_L1,
"_"_L1 );
304 args.replace(
"\""_L1,
"_"_L1 );
305 args.replace(
" "_L1,
"_"_L1 );
306 args.replace(
":"_L1,
"_"_L1 );
307 args.replace(
"/"_L1,
"_"_L1 );
308 args.replace(
"\n"_L1,
"_"_L1 );
313 if ( modifiedUrlString[1] ==
'/' )
315 modifiedUrlString = modifiedUrlString[0] +
":/" + modifiedUrlString.mid( 2 );
318 modifiedUrlString = modifiedUrlString.mid( 0, modifiedUrlString.indexOf(
'?' ) ) + args;
319 QgsDebugMsgLevel( u
"Get %1 (after laundering)"_s.arg( modifiedUrlString ), 2 );
320 modifiedUrl = QUrl::fromLocalFile( modifiedUrlString );
321 if ( !QFile::exists( modifiedUrlString ) )
323 QgsDebugError( u
"Local test file %1 for URL %2 does not exist!!!"_s.arg( modifiedUrlString, url.toString() ) );
330void QgsArcGisRestQueryUtils::adjustBaseUrl( QString &baseUrl,
const QString &name )
332 const QStringList parts = name.split(
'/' );
334 for (
const QString &part : parts )
336 if ( !checkString.isEmpty() )
337 checkString += QString(
'/' );
340 if ( baseUrl.indexOf( QRegularExpression( checkString.replace(
'/',
"\\/"_L1 ) + u
"\\/?$"_s ) ) > -1 )
342 baseUrl = baseUrl.left( baseUrl.length() - checkString.length() - 1 );
350 QString base( baseUrl );
351 bool baseChecked =
false;
352 if ( !base.endsWith(
'/' ) )
355 const QStringList folderList = serviceData.value( u
"folders"_s ).toStringList();
356 for (
const QString &folder : folderList )
360 adjustBaseUrl( base, folder );
363 visitor( folder, base + folder );
369 QString base( baseUrl );
370 bool baseChecked =
false;
371 if ( !base.endsWith(
'/' ) )
374 const QVariantList serviceList = serviceData.value( u
"services"_s ).toList();
375 for (
const QVariant &service : serviceList )
377 const QVariantMap serviceMap = service.toMap();
378 const QString serviceTypeString = serviceMap.value( u
"type"_s ).toString();
381 switch ( serviceType )
398 const QString serviceName = serviceMap.value( u
"name"_s ).toString();
399 const QString displayName = serviceName.split(
'/' ).last();
402 adjustBaseUrl( base, serviceName );
406 visitor( displayName, base + serviceName +
'/' + serviceTypeString, serviceType );
412 void(
const QString &,
ServiceTypeFilter,
Qgis::GeometryType,
const QString &,
const QString &,
const QString &,
const QString &,
bool,
const QgsCoordinateReferenceSystem &,
const QString & )> &visitor,
413 const QVariantMap &serviceData,
414 const QString &parentUrl,
415 const QString &parentSupportedFormats,
422 const QList<QByteArray> supportedFormats = QImageReader::supportedImageFormats();
423 const QStringList supportedImageFormatTypes = serviceData.value( u
"supportedImageFormatTypes"_s ).toString().isEmpty() ? parentSupportedFormats.split(
',' )
424 : serviceData.value( u
"supportedImageFormatTypes"_s ).toString().split(
',' );
425 QString format = supportedImageFormatTypes.value( 0 );
426 for (
const QString &encoding : supportedImageFormatTypes )
428 for (
const QByteArray &fmt : supportedFormats )
430 if ( encoding.startsWith( fmt, Qt::CaseInsensitive ) )
440 const QStringList capabilities = serviceData.value( u
"capabilities"_s ).toString().split(
',' );
443 const bool serviceMayHaveQueryCapability = capabilities.contains( u
"Query"_s ) || serviceData.value( u
"serviceDataType"_s ).toString().startsWith(
"esriImageService"_L1 );
445 const bool serviceMayRenderMaps = capabilities.contains( u
"Map"_s ) || serviceData.value( u
"serviceDataType"_s ).toString().startsWith(
"esriImageService"_L1 );
447 const QVariantList layerInfoList = serviceData.value( u
"layers"_s ).toList();
448 for (
const QVariant &layerInfo : layerInfoList )
450 const QVariantMap layerInfoMap = layerInfo.toMap();
451 const QString
id = layerInfoMap.value( u
"id"_s ).toString();
452 const QString parentLayerId = layerInfoMap.value( u
"parentLayerId"_s ).toString();
453 const QString name = layerInfoMap.value( u
"name"_s ).toString();
454 const QString description = layerInfoMap.value( u
"description"_s ).toString();
465 if ( !layerInfoMap.value( u
"subLayerIds"_s ).toList().empty() )
477 const QString geometryType = layerInfoMap.value( u
"geometryType"_s ).toString();
488 if ( serviceMayRenderMaps )
490 if ( geometryType.isEmpty() )
498 if ( !layerInfoMap.value( u
"subLayerIds"_s ).toList().empty() )
509 const QVariantList tableInfoList = serviceData.value( u
"tables"_s ).toList();
510 for (
const QVariant &tableInfo : tableInfoList )
512 const QVariantMap tableInfoMap = tableInfo.toMap();
513 const QString
id = tableInfoMap.value( u
"id"_s ).toString();
514 const QString parentLayerId = tableInfoMap.value( u
"parentLayerId"_s ).toString();
515 const QString name = tableInfoMap.value( u
"name"_s ).toString();
516 const QString description = tableInfoMap.value( u
"description"_s ).toString();
520 if ( !tableInfoMap.value( u
"subLayerIds"_s ).toList().empty() )
532 if ( filter !=
ServiceTypeFilter::Vector && layerInfoList.count() > 1 && serviceData.contains( u
"supportedImageFormatTypes"_s ) )
534 const QString name = u
"(%1)"_s.arg( QObject::tr(
"All layers" ) );
535 const QString description = serviceData.value( u
"Comments"_s ).toString();
540 if ( serviceData.value( u
"serviceDataType"_s ).toString().startsWith(
"esriImageService"_L1 ) )
542 const QString name = serviceData.value( u
"name"_s ).toString();
543 const QString description = serviceData.value( u
"description"_s ).toString();
555QgsArcGisAsyncQuery::QgsArcGisAsyncQuery( QObject *parent )
559QgsArcGisAsyncQuery::~QgsArcGisAsyncQuery()
562 mReply->deleteLater();
565void QgsArcGisAsyncQuery::start(
const QUrl &url,
const QString &authCfg, QByteArray *result,
bool allowCache,
const QgsHttpHeaders &headers,
const QString &urlPrefix )
569 if ( !urlPrefix.isEmpty() )
570 mUrl = QUrl( urlPrefix + url.toString() );
571 QNetworkRequest request( mUrl );
577 const QString error = tr(
"network request update failed for authentication config" );
578 emit failed( u
"Network"_s, error );
583 request.setAttribute( QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy );
586 request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
587 request.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
true );
591 connect( mReply, &QNetworkReply::finished,
this, &QgsArcGisAsyncQuery::handleReply );
594void QgsArcGisAsyncQuery::handleReply()
596 mReply->deleteLater();
598 if ( mReply->error() != QNetworkReply::NoError )
600 QgsDebugError( u
"Network error: %1"_s.arg( mReply->errorString() ) );
601 emit failed( u
"Network error"_s, mReply->errorString() );
606 const QVariant redirect = mReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
609 QNetworkRequest request = mReply->request();
610 request.setAttribute( QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy );
613 request.setUrl( redirect.toUrl() );
615 connect( mReply, &QNetworkReply::finished,
this, &QgsArcGisAsyncQuery::handleReply );
619 *mResult = mReply->readAll();
628QgsArcGisAsyncParallelQuery::QgsArcGisAsyncParallelQuery(
const QString &authcfg,
const QgsHttpHeaders &requestHeaders, QObject *parent )
630 , mAuthCfg( authcfg )
631 , mRequestHeaders( requestHeaders )
634void QgsArcGisAsyncParallelQuery::start(
const QVector<QUrl> &urls, QVector<QByteArray> *results,
bool allowCache )
636 Q_ASSERT( results->size() == urls.size() );
638 mPendingRequests = mResults->size();
639 for (
int i = 0, n = urls.size(); i < n; ++i )
641 QNetworkRequest request( urls[i] );
645 mRequestHeaders.updateNetworkRequest( request );
648 const QString error = tr(
"network request update failed for authentication config" );
649 mErrors.append( error );
654 request.setAttribute( QNetworkRequest::HttpPipeliningAllowedAttribute,
true );
657 request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
658 request.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
true );
659 request.setRawHeader(
"Connection",
"keep-alive" );
662 reply->setProperty(
"idx", i );
663 connect( reply, &QNetworkReply::finished,
this, &QgsArcGisAsyncParallelQuery::handleReply );
667void QgsArcGisAsyncParallelQuery::handleReply()
669 QNetworkReply *reply = qobject_cast<QNetworkReply *>( QObject::sender() );
670 const QVariant redirect = reply->attribute( QNetworkRequest::RedirectionTargetAttribute );
671 const int idx = reply->property(
"idx" ).toInt();
672 reply->deleteLater();
673 if ( reply->error() != QNetworkReply::NoError )
676 mErrors.append( reply->errorString() );
682 QNetworkRequest request = reply->request();
683 request.setAttribute( QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy );
686 request.setUrl( redirect.toUrl() );
688 reply->setProperty(
"idx", idx );
689 connect( reply, &QNetworkReply::finished,
this, &QgsArcGisAsyncParallelQuery::handleReply );
694 ( *mResults )[idx] = reply->readAll();
697 if ( mPendingRequests == 0 )
699 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(), bool forceRefresh=false)
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 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 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 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(), 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)