28#include <QImageReader> 
   29#include <QRegularExpression> 
   30#include <QJsonParseError> 
   35  QUrl queryUrl( baseurl );
 
   36  QUrlQuery query( queryUrl );
 
   37  query.addQueryItem( QStringLiteral( 
"f" ), QStringLiteral( 
"json" ) );
 
   38  queryUrl.setQuery( query );
 
   39  return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders );
 
   45  QUrl queryUrl( layerurl );
 
   46  QUrlQuery query( queryUrl );
 
   47  query.addQueryItem( QStringLiteral( 
"f" ), QStringLiteral( 
"json" ) );
 
   48  queryUrl.setQuery( query );
 
   49  return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders );
 
   55  QUrl queryUrl( layerurl + 
"/query" );
 
   56  QUrlQuery query( queryUrl );
 
   57  query.addQueryItem( QStringLiteral( 
"f" ), QStringLiteral( 
"json" ) );
 
   58  query.addQueryItem( QStringLiteral( 
"where" ), whereClause.isEmpty() ? QStringLiteral( 
"1=1" ) : whereClause );
 
   59  query.addQueryItem( QStringLiteral( 
"returnIdsOnly" ), QStringLiteral( 
"true" ) );
 
   62    query.addQueryItem( QStringLiteral( 
"geometry" ), QStringLiteral( 
"%1,%2,%3,%4" )
 
   65    query.addQueryItem( QStringLiteral( 
"geometryType" ), QStringLiteral( 
"esriGeometryEnvelope" ) );
 
   66    query.addQueryItem( QStringLiteral( 
"spatialRel" ), QStringLiteral( 
"esriSpatialRelEnvelopeIntersects" ) );
 
   68  queryUrl.setQuery( query );
 
   69  return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders );
 
   75  QUrl queryUrl( layerurl + 
"/query" );
 
   76  QUrlQuery query( queryUrl );
 
   77  query.addQueryItem( QStringLiteral( 
"f" ), QStringLiteral( 
"json" ) );
 
   78  query.addQueryItem( QStringLiteral( 
"where" ), whereClause );
 
   79  query.addQueryItem( QStringLiteral( 
"returnExtentOnly" ), QStringLiteral( 
"true" ) );
 
   80  queryUrl.setQuery( query );
 
   83  const QVariantMap res = 
queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders );
 
   86    QgsDebugError( QStringLiteral( 
"getExtent failed: %1 - %2" ).arg( errorTitle, errorText ) );
 
   91  const QVariantMap coords = res.value( QStringLiteral( 
"extent" ) ).toMap();
 
   92  rect.
setXMinimum( coords.value( QStringLiteral( 
"xmin" ) ).toDouble() );
 
   93  rect.
setYMinimum( coords.value( QStringLiteral( 
"ymin" ) ).toDouble() );
 
   94  rect.
setXMaximum( coords.value( QStringLiteral( 
"xmax" ) ).toDouble() );
 
   95  rect.
setYMaximum( coords.value( QStringLiteral( 
"ymax" ) ).toDouble() );
 
  100    bool fetchGeometry, 
const QStringList &fetchAttributes,
 
  101    bool fetchM, 
bool fetchZ,
 
  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  const QString wkid = 
crs.indexOf( QLatin1Char( 
':' ) ) >= 0 ? 
crs.split( 
':' )[1] : QString();
 
  115  query.addQueryItem( QStringLiteral( 
"inSR" ), wkid );
 
  116  query.addQueryItem( QStringLiteral( 
"outSR" ), wkid );
 
  118  query.addQueryItem( QStringLiteral( 
"returnGeometry" ), fetchGeometry ? QStringLiteral( 
"true" ) : QStringLiteral( 
"false" ) );
 
  121  if ( fetchAttributes.isEmpty() )
 
  122    outFields = QStringLiteral( 
"*" );
 
  124    outFields = fetchAttributes.join( 
',' );
 
  125  query.addQueryItem( QStringLiteral( 
"outFields" ), outFields );
 
  127  query.addQueryItem( QStringLiteral( 
"returnM" ), fetchM ? QStringLiteral( 
"true" ) : QStringLiteral( 
"false" ) );
 
  128  query.addQueryItem( QStringLiteral( 
"returnZ" ), fetchZ ? QStringLiteral( 
"true" ) : QStringLiteral( 
"false" ) );
 
  129  if ( !filterRect.
isNull() )
 
  131    query.addQueryItem( QStringLiteral( 
"geometry" ), QStringLiteral( 
"%1,%2,%3,%4" )
 
  132                        .arg( filterRect.
xMinimum(), 0, 
'f', -1 ).arg( filterRect.
yMinimum(), 0, 
'f', -1 )
 
  133                        .arg( filterRect.
xMaximum(), 0, 
'f', -1 ).arg( filterRect.
yMaximum(), 0, 
'f', -1 ) );
 
  134    query.addQueryItem( QStringLiteral( 
"geometryType" ), QStringLiteral( 
"esriGeometryEnvelope" ) );
 
  135    query.addQueryItem( QStringLiteral( 
"spatialRel" ), QStringLiteral( 
"esriSpatialRelEnvelopeIntersects" ) );
 
  137  queryUrl.setQuery( query );
 
  138  return queryServiceJSON( queryUrl,  authcfg, errorTitle, errorText, requestHeaders, feedback );
 
  143  QUrl queryUrl( layerurl + 
"/query" );
 
  144  QUrlQuery query( queryUrl );
 
  145  query.addQueryItem( QStringLiteral( 
"f" ), QStringLiteral( 
"json" ) );
 
  146  query.addQueryItem( QStringLiteral( 
"where" ), whereClause.isEmpty() ? QStringLiteral( 
"1=1" ) : whereClause );
 
  147  query.addQueryItem( QStringLiteral( 
"returnIdsOnly" ), QStringLiteral( 
"true" ) );
 
  148  query.addQueryItem( QStringLiteral( 
"geometry" ), QStringLiteral( 
"%1,%2,%3,%4" )
 
  149                      .arg( filterRect.
xMinimum(), 0, 
'f', -1 ).arg( filterRect.
yMinimum(), 0, 
'f', -1 )
 
  150                      .arg( filterRect.
xMaximum(), 0, 
'f', -1 ).arg( filterRect.
yMaximum(), 0, 
'f', -1 ) );
 
  151  query.addQueryItem( QStringLiteral( 
"geometryType" ), QStringLiteral( 
"esriGeometryEnvelope" ) );
 
  152  query.addQueryItem( QStringLiteral( 
"spatialRel" ), QStringLiteral( 
"esriSpatialRelEnvelopeIntersects" ) );
 
  153  queryUrl.setQuery( query );
 
  154  const QVariantMap objectIdData = 
queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders, feedback );
 
  156  if ( objectIdData.isEmpty() )
 
  158    return QList<quint32>();
 
  162  const QVariantList objectIdsList = objectIdData[QStringLiteral( 
"objectIds" )].toList();
 
  163  ids.reserve( objectIdsList.size() );
 
  164  for ( 
const QVariant &objectId : objectIdsList )
 
  166    ids << objectId.toInt();
 
  175  QNetworkRequest request( url );
 
  190    errorTitle = QStringLiteral( 
"Network error" );
 
  194    const QString content = networkRequest.
reply().
content();
 
  195    const thread_local QRegularExpression errorRx( QStringLiteral( 
"Error: <.*?>(.*?)<" ) );
 
  196    const QRegularExpressionMatch match = errorRx.match( content );
 
  197    if ( match.hasMatch() )
 
  199      errorText = match.captured( 1 );
 
  207    *contentType = content.
rawHeader( 
"Content-Type" );
 
  213  const QByteArray reply = 
queryService( url, authcfg, errorTitle, errorText, requestHeaders, feedback );
 
  214  if ( !errorTitle.isEmpty() )
 
  216    return QVariantMap();
 
  219    return QVariantMap();
 
  223  const QJsonDocument doc = QJsonDocument::fromJson( reply, &err );
 
  226    errorTitle = QStringLiteral( 
"Parsing error" );
 
  227    errorText = err.errorString();
 
  228    QgsDebugError( QStringLiteral( 
"Parsing error: %1" ).arg( err.errorString() ) );
 
  229    return QVariantMap();
 
  231  const QVariantMap res = doc.object().toVariantMap();
 
  232  if ( res.contains( QStringLiteral( 
"error" ) ) )
 
  234    const QVariantMap error = res.value( QStringLiteral( 
"error" ) ).toMap();
 
  235    errorText = error.value( QStringLiteral( 
"message" ) ).toString();
 
  236    errorTitle = QObject::tr( 
"Error %1" ).arg( error.value( QStringLiteral( 
"code" ) ).toString() );
 
  237    return QVariantMap();
 
  244  if ( isTestEndpoint )
 
  245    *isTestEndpoint = 
false;
 
  247  QUrl modifiedUrl( url );
 
  248  if ( modifiedUrl.toString().contains( QLatin1String( 
"fake_qgis_http_endpoint" ) ) )
 
  250    if ( isTestEndpoint )
 
  251      *isTestEndpoint = 
true;
 
  254    QString modifiedUrlString = modifiedUrl.toString();
 
  256    modifiedUrlString = QUrl::fromPercentEncoding( modifiedUrlString.toUtf8() );
 
  257    modifiedUrlString.replace( QLatin1String( 
"fake_qgis_http_endpoint/" ), QLatin1String( 
"fake_qgis_http_endpoint_" ) );
 
  259    modifiedUrlString = modifiedUrlString.mid( QStringLiteral( 
"http://" ).size() );
 
  260    QString args = modifiedUrlString.indexOf( 
'?' ) >= 0 ? modifiedUrlString.mid( modifiedUrlString.indexOf( 
'?' ) ) : QString();
 
  261    if ( modifiedUrlString.size() > 150 )
 
  263      args = QCryptographicHash::hash( args.toUtf8(), QCryptographicHash::Md5 ).toHex();
 
  267      args.replace( QLatin1String( 
"?" ), QLatin1String( 
"_" ) );
 
  268      args.replace( QLatin1String( 
"&" ), QLatin1String( 
"_" ) );
 
  269      args.replace( QLatin1String( 
"<" ), QLatin1String( 
"_" ) );
 
  270      args.replace( QLatin1String( 
">" ), QLatin1String( 
"_" ) );
 
  271      args.replace( QLatin1String( 
"'" ), QLatin1String( 
"_" ) );
 
  272      args.replace( QLatin1String( 
"\"" ), QLatin1String( 
"_" ) );
 
  273      args.replace( QLatin1String( 
" " ), QLatin1String( 
"_" ) );
 
  274      args.replace( QLatin1String( 
":" ), QLatin1String( 
"_" ) );
 
  275      args.replace( QLatin1String( 
"/" ), QLatin1String( 
"_" ) );
 
  276      args.replace( QLatin1String( 
"\n" ), QLatin1String( 
"_" ) );
 
  281    if ( modifiedUrlString[1] == 
'/' )
 
  283      modifiedUrlString = modifiedUrlString[0] + 
":/" + modifiedUrlString.mid( 2 );
 
  286    modifiedUrlString = modifiedUrlString.mid( 0, modifiedUrlString.indexOf( 
'?' ) ) + args;
 
  287    QgsDebugMsgLevel( QStringLiteral( 
"Get %1 (after laundering)" ).arg( modifiedUrlString ), 2 );
 
  288    modifiedUrl = QUrl::fromLocalFile( modifiedUrlString );
 
  289    if ( !QFile::exists( modifiedUrlString ) )
 
  291      QgsDebugError( QStringLiteral( 
"Local test file %1 for URL %2 does not exist!!!" ).arg( modifiedUrlString, url.toString() ) );
 
  298void QgsArcGisRestQueryUtils::adjustBaseUrl( QString &baseUrl, 
const QString &name )
 
  300  const QStringList parts = name.split( 
'/' );
 
  302  for ( 
const QString &part : parts )
 
  304    if ( !checkString.isEmpty() )
 
  305      checkString += QString( 
'/' );
 
  308    if ( baseUrl.indexOf( QRegularExpression( checkString.replace( 
'/', QLatin1String( 
"\\/" ) ) + QStringLiteral( 
"\\/?$" ) ) ) > -1 )
 
  310      baseUrl = baseUrl.left( baseUrl.length() - checkString.length() - 1 );
 
  318  QString base( baseUrl );
 
  319  bool baseChecked = 
false;
 
  320  if ( !base.endsWith( 
'/' ) )
 
  321    base += QLatin1Char( 
'/' );
 
  323  const QStringList folderList = serviceData.value( QStringLiteral( 
"folders" ) ).toStringList();
 
  324  for ( 
const QString &folder : folderList )
 
  328      adjustBaseUrl( base, folder );
 
  331    visitor( folder, base + folder );
 
  337  QString base( baseUrl );
 
  338  bool baseChecked = 
false;
 
  339  if ( !base.endsWith( 
'/' ) )
 
  340    base += QLatin1Char( 
'/' );
 
  342  const QVariantList serviceList = serviceData.value( QStringLiteral( 
"services" ) ).toList();
 
  343  for ( 
const QVariant &service : serviceList )
 
  345    const QVariantMap serviceMap = service.toMap();
 
  346    const QString serviceTypeString = serviceMap.value( QStringLiteral( 
"type" ) ).toString();
 
  349    switch ( serviceType )
 
  351      case Qgis::ArcGisRestServiceType::FeatureServer:
 
  352      case Qgis::ArcGisRestServiceType::MapServer:
 
  353      case Qgis::ArcGisRestServiceType::ImageServer:
 
  365    const QString serviceName = serviceMap.value( QStringLiteral( 
"name" ) ).toString();
 
  366    const QString displayName = serviceName.split( 
'/' ).last();
 
  369      adjustBaseUrl( base, serviceName );
 
  373    visitor( displayName, base + serviceName + 
'/' + serviceTypeString, serviceType );
 
  377void QgsArcGisRestQueryUtils::addLayerItems( 
const std::function<
void ( 
const QString &, 
ServiceTypeFilter, 
Qgis::GeometryType, 
const QString &, 
const QString &, 
const QString &, 
const QString &, 
bool, 
const QString &, 
const QString & )> &visitor, 
const QVariantMap &serviceData, 
const QString &parentUrl, 
const QString &parentSupportedFormats, 
const ServiceTypeFilter filter )
 
  382  const QList<QByteArray> supportedFormats = QImageReader::supportedImageFormats();
 
  383  const QStringList supportedImageFormatTypes = serviceData.value( QStringLiteral( 
"supportedImageFormatTypes" ) ).toString().isEmpty() ? parentSupportedFormats.split( 
',' ) : serviceData.value( QStringLiteral( 
"supportedImageFormatTypes" ) ).toString().split( 
',' );
 
  384  QString format = supportedImageFormatTypes.value( 0 );
 
  385  for ( 
const QString &encoding : supportedImageFormatTypes )
 
  387    for ( 
const QByteArray &fmt : supportedFormats )
 
  389      if ( encoding.startsWith( fmt, Qt::CaseInsensitive ) )
 
  399  const QStringList capabilities = serviceData.value( QStringLiteral( 
"capabilities" ) ).toString().split( 
',' );
 
  402  const bool serviceMayHaveQueryCapability = capabilities.contains( QStringLiteral( 
"Query" ) ) ||
 
  403      serviceData.value( QStringLiteral( 
"serviceDataType" ) ).toString().startsWith( QLatin1String( 
"esriImageService" ) );
 
  405  const bool serviceMayRenderMaps = capabilities.contains( QStringLiteral( 
"Map" ) ) ||
 
  406                                    serviceData.value( QStringLiteral( 
"serviceDataType" ) ).toString().startsWith( QLatin1String( 
"esriImageService" ) );
 
  408  const QVariantList layerInfoList = serviceData.value( QStringLiteral( 
"layers" ) ).toList();
 
  409  for ( 
const QVariant &layerInfo : layerInfoList )
 
  411    const QVariantMap layerInfoMap = layerInfo.toMap();
 
  412    const QString 
id = layerInfoMap.value( QStringLiteral( 
"id" ) ).toString();
 
  413    const QString parentLayerId = layerInfoMap.value( QStringLiteral( 
"parentLayerId" ) ).toString();
 
  414    const QString name = layerInfoMap.value( QStringLiteral( 
"name" ) ).toString();
 
  415    const QString description = layerInfoMap.value( QStringLiteral( 
"description" ) ).toString();
 
  420      if ( !layerInfoMap.value( QStringLiteral( 
"subLayerIds" ) ).toList().empty() )
 
  422        visitor( parentLayerId, 
ServiceTypeFilter::Raster, Qgis::GeometryType::Unknown, 
id, name, description, parentUrl + 
'/' + 
id, 
true, QString(), format );
 
  426        visitor( parentLayerId, 
ServiceTypeFilter::Raster, Qgis::GeometryType::Unknown, 
id, name, description, parentUrl + 
'/' + 
id, 
false, authid, format );
 
  432      const QString geometryType = layerInfoMap.value( QStringLiteral( 
"geometryType" ) ).toString();
 
  443      if ( serviceMayRenderMaps )
 
  445        if ( geometryType.isEmpty() )
 
  453      if ( !layerInfoMap.value( QStringLiteral( 
"subLayerIds" ) ).toList().empty() )
 
  464  const QVariantList tableInfoList = serviceData.value( QStringLiteral( 
"tables" ) ).toList();
 
  465  for ( 
const QVariant &tableInfo : tableInfoList )
 
  467    const QVariantMap tableInfoMap = tableInfo.toMap();
 
  468    const QString 
id = tableInfoMap.value( QStringLiteral( 
"id" ) ).toString();
 
  469    const QString parentLayerId = tableInfoMap.value( QStringLiteral( 
"parentLayerId" ) ).toString();
 
  470    const QString name = tableInfoMap.value( QStringLiteral( 
"name" ) ).toString();
 
  471    const QString description = tableInfoMap.value( QStringLiteral( 
"description" ) ).toString();
 
  475      if ( !tableInfoMap.value( QStringLiteral( 
"subLayerIds" ) ).toList().empty() )
 
  477        visitor( parentLayerId, 
ServiceTypeFilter::Vector, Qgis::GeometryType::Null, 
id, name, description, parentUrl + 
'/' + 
id, 
true, QString(), format );
 
  481        visitor( parentLayerId, 
ServiceTypeFilter::Vector, Qgis::GeometryType::Null, 
id, name, description, parentUrl + 
'/' + 
id, 
false, authid, format );
 
  487  if ( filter != 
ServiceTypeFilter::Vector && layerInfoList.count() > 1 && serviceData.contains( QStringLiteral( 
"supportedImageFormatTypes" ) ) )
 
  489    const QString name = QStringLiteral( 
"(%1)" ).arg( QObject::tr( 
"All layers" ) );
 
  490    const QString description = serviceData.value( QStringLiteral( 
"Comments" ) ).toString();
 
  491    visitor( 
nullptr, 
ServiceTypeFilter::Raster, Qgis::GeometryType::Unknown, 
nullptr, name, description, parentUrl, 
false, authid, format );
 
  495  if ( serviceData.value( QStringLiteral( 
"serviceDataType" ) ).toString().startsWith( QLatin1String( 
"esriImageService" ) ) )
 
  497    const QString name = serviceData.value( QStringLiteral( 
"name" ) ).toString();
 
  498    const QString description = serviceData.value( QStringLiteral( 
"description" ) ).toString();
 
  499    visitor( 
nullptr, 
ServiceTypeFilter::Raster, Qgis::GeometryType::Unknown, 
nullptr, name, description, parentUrl, 
false, authid, format );
 
  510QgsArcGisAsyncQuery::QgsArcGisAsyncQuery( QObject *parent )
 
  515QgsArcGisAsyncQuery::~QgsArcGisAsyncQuery()
 
  518    mReply->deleteLater();
 
  521void QgsArcGisAsyncQuery::start( 
const QUrl &url, 
const QString &authCfg, QByteArray *result, 
bool allowCache, 
const QgsHttpHeaders &headers )
 
  524  QNetworkRequest request( url );
 
  530    const QString error = tr( 
"network request update failed for authentication config" );
 
  531    emit failed( QStringLiteral( 
"Network" ), error );
 
  538    request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
 
  539    request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, 
true );
 
  542  connect( mReply, &QNetworkReply::finished, 
this, &QgsArcGisAsyncQuery::handleReply );
 
  545void QgsArcGisAsyncQuery::handleReply()
 
  547  mReply->deleteLater();
 
  549  if ( mReply->error() != QNetworkReply::NoError )
 
  551    QgsDebugError( QStringLiteral( 
"Network error: %1" ).arg( mReply->errorString() ) );
 
  552    emit failed( QStringLiteral( 
"Network error" ), mReply->errorString() );
 
  557  const QVariant redirect = mReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
 
  560    QNetworkRequest request = mReply->request();
 
  563    request.setUrl( redirect.toUrl() );
 
  565    connect( mReply, &QNetworkReply::finished, 
this, &QgsArcGisAsyncQuery::handleReply );
 
  569  *mResult = mReply->readAll();
 
  578QgsArcGisAsyncParallelQuery::QgsArcGisAsyncParallelQuery( 
const QString &authcfg, 
const QgsHttpHeaders &requestHeaders, QObject *parent )
 
  580  , mAuthCfg( authcfg )
 
  581  , mRequestHeaders( requestHeaders )
 
  585void QgsArcGisAsyncParallelQuery::start( 
const QVector<QUrl> &urls, QVector<QByteArray> *results, 
bool allowCache )
 
  587  Q_ASSERT( results->size() == urls.size() );
 
  589  mPendingRequests = mResults->size();
 
  590  for ( 
int i = 0, n = urls.size(); i < n; ++i )
 
  592    QNetworkRequest request( urls[i] );
 
  596    mRequestHeaders.updateNetworkRequest( request );
 
  599      const QString error = tr( 
"network request update failed for authentication config" );
 
  600      mErrors.append( error );
 
  605    request.setAttribute( QNetworkRequest::HttpPipeliningAllowedAttribute, 
true );
 
  608      request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
 
  609      request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, 
true );
 
  610      request.setRawHeader( 
"Connection", 
"keep-alive" );
 
  613    reply->setProperty( 
"idx", i );
 
  614    connect( reply, &QNetworkReply::finished, 
this, &QgsArcGisAsyncParallelQuery::handleReply );
 
  618void QgsArcGisAsyncParallelQuery::handleReply()
 
  620  QNetworkReply *reply = qobject_cast<QNetworkReply *>( QObject::sender() );
 
  621  const QVariant redirect = reply->attribute( QNetworkRequest::RedirectionTargetAttribute );
 
  622  const int idx = reply->property( 
"idx" ).toInt();
 
  623  reply->deleteLater();
 
  624  if ( reply->error() != QNetworkReply::NoError )
 
  627    mErrors.append( reply->errorString() );
 
  633    QNetworkRequest request = reply->request();
 
  636    request.setUrl( redirect.toUrl() );
 
  638    reply->setProperty( 
"idx", idx );
 
  639    connect( reply, &QNetworkReply::finished, 
this, &QgsArcGisAsyncParallelQuery::handleReply );
 
  644    ( *mResults )[idx] = reply->readAll();
 
  647  if ( mPendingRequests == 0 )
 
  649    emit finished( mErrors );
 
ArcGisRestServiceType
Available ArcGIS REST service types.
 
@ GeocodeServer
GeocodeServer.
 
@ Unknown
Other unknown/unsupported type.
 
@ GlobeServer
GlobeServer.
 
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 QgsRectangle getExtent(const QString &layerurl, const QString &whereClause, const QString &authcfg, const QgsHttpHeaders &requestHeaders=QgsHttpHeaders())
Retrieves the extent for the features matching a whereClause.
 
static QVariantMap getLayerInfo(const QString &layerurl, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsHttpHeaders &requestHeaders=QgsHttpHeaders())
Retrieves JSON layer info for the specified layer URL.
 
static QUrl parseUrl(const QUrl &url, bool *isTestEndpoint=nullptr)
Parses and processes a 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 QString &authid, 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.
 
ServiceTypeFilter
Service types.
 
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())
Gets a list of object IDs which fall within the specified extent.
 
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 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)
Retrieves all matching objects from the specified layer URL.
 
static QVariantMap queryServiceJSON(const QUrl &url, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsHttpHeaders &requestHeaders=QgsHttpHeaders(), QgsFeedback *feedback=nullptr)
Performs a blocking request to a URL and returns the retrieved JSON content.
 
static QByteArray queryService(const QUrl &url, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsHttpHeaders &requestHeaders=QgsHttpHeaders(), QgsFeedback *feedback=nullptr, QString *contentType=nullptr)
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())
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 QgsRectangle &bbox=QgsRectangle(), const QString &whereClause=QString())
Retrieves all object IDs for 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.
 
bool updateNetworkRequest(QNetworkRequest &request, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkRequest with an authentication config.
 
A thread safe class for performing blocking (sync) network requests, with full support for QGIS proxy...
 
ErrorCode get(QNetworkRequest &request, bool forceRefresh=false, QgsFeedback *feedback=nullptr)
Performs a "get" operation on the specified request.
 
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.
 
@ 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...
 
Base class for feedback objects to be used for cancellation of something running in a worker thread.
 
bool isCanceled() const SIP_HOLDGIL
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)
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.
 
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
 
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
 
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
 
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
 
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
 
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
 
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
 
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
 
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
 
static bool isNull(const QVariant &variant)
Returns true if the specified variant should be considered a NULL value.
 
static Qgis::GeometryType geometryType(Qgis::WkbType type) SIP_HOLDGIL
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)
 
const QgsCoordinateReferenceSystem & crs