27 #include <QImageReader>
28 #include <QRegularExpression>
33 QUrl queryUrl( baseurl );
34 QUrlQuery query( queryUrl );
35 query.addQueryItem( QStringLiteral(
"f" ), QStringLiteral(
"json" ) );
36 queryUrl.setQuery( query );
37 return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders );
43 QUrl queryUrl( layerurl );
44 QUrlQuery query( queryUrl );
45 query.addQueryItem( QStringLiteral(
"f" ), QStringLiteral(
"json" ) );
46 queryUrl.setQuery( query );
47 return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders );
53 QUrl queryUrl( layerurl +
"/query" );
54 QUrlQuery query( queryUrl );
55 query.addQueryItem( QStringLiteral(
"f" ), QStringLiteral(
"json" ) );
56 query.addQueryItem( QStringLiteral(
"where" ), QStringLiteral(
"1=1" ) );
57 query.addQueryItem( QStringLiteral(
"returnIdsOnly" ), QStringLiteral(
"true" ) );
60 query.addQueryItem( QStringLiteral(
"geometry" ), QStringLiteral(
"%1,%2,%3,%4" )
63 query.addQueryItem( QStringLiteral(
"geometryType" ), QStringLiteral(
"esriGeometryEnvelope" ) );
64 query.addQueryItem( QStringLiteral(
"spatialRel" ), QStringLiteral(
"esriSpatialRelEnvelopeIntersects" ) );
66 queryUrl.setQuery( query );
67 return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders );
71 bool fetchGeometry,
const QStringList &fetchAttributes,
72 bool fetchM,
bool fetchZ,
77 for (
int id : objectIds )
79 ids.append( QString::number(
id ) );
81 QUrl queryUrl( layerurl +
"/query" );
82 QUrlQuery query( queryUrl );
83 query.addQueryItem( QStringLiteral(
"f" ), QStringLiteral(
"json" ) );
84 query.addQueryItem( QStringLiteral(
"objectIds" ), ids.join( QLatin1Char(
',' ) ) );
85 QString wkid =
crs.indexOf( QLatin1Char(
':' ) ) >= 0 ?
crs.split(
':' )[1] : QString();
86 query.addQueryItem( QStringLiteral(
"inSR" ), wkid );
87 query.addQueryItem( QStringLiteral(
"outSR" ), wkid );
89 query.addQueryItem( QStringLiteral(
"returnGeometry" ), fetchGeometry ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
92 if ( fetchAttributes.isEmpty() )
93 outFields = QStringLiteral(
"*" );
95 outFields = fetchAttributes.join(
',' );
96 query.addQueryItem( QStringLiteral(
"outFields" ), outFields );
98 query.addQueryItem( QStringLiteral(
"returnM" ), fetchM ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
99 query.addQueryItem( QStringLiteral(
"returnZ" ), fetchZ ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
100 if ( !filterRect.
isNull() )
102 query.addQueryItem( QStringLiteral(
"geometry" ), QStringLiteral(
"%1,%2,%3,%4" )
103 .arg( filterRect.
xMinimum(), 0,
'f', -1 ).arg( filterRect.
yMinimum(), 0,
'f', -1 )
104 .arg( filterRect.
xMaximum(), 0,
'f', -1 ).arg( filterRect.
yMaximum(), 0,
'f', -1 ) );
105 query.addQueryItem( QStringLiteral(
"geometryType" ), QStringLiteral(
"esriGeometryEnvelope" ) );
106 query.addQueryItem( QStringLiteral(
"spatialRel" ), QStringLiteral(
"esriSpatialRelEnvelopeIntersects" ) );
108 queryUrl.setQuery( query );
109 return queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders, feedback );
114 QUrl queryUrl( layerurl +
"/query" );
115 QUrlQuery query( queryUrl );
116 query.addQueryItem( QStringLiteral(
"f" ), QStringLiteral(
"json" ) );
117 query.addQueryItem( QStringLiteral(
"where" ), QStringLiteral(
"1=1" ) );
118 query.addQueryItem( QStringLiteral(
"returnIdsOnly" ), QStringLiteral(
"true" ) );
119 query.addQueryItem( QStringLiteral(
"geometry" ), QStringLiteral(
"%1,%2,%3,%4" )
120 .arg( filterRect.
xMinimum(), 0,
'f', -1 ).arg( filterRect.
yMinimum(), 0,
'f', -1 )
121 .arg( filterRect.
xMaximum(), 0,
'f', -1 ).arg( filterRect.
yMaximum(), 0,
'f', -1 ) );
122 query.addQueryItem( QStringLiteral(
"geometryType" ), QStringLiteral(
"esriGeometryEnvelope" ) );
123 query.addQueryItem( QStringLiteral(
"spatialRel" ), QStringLiteral(
"esriSpatialRelEnvelopeIntersects" ) );
124 queryUrl.setQuery( query );
125 const QVariantMap objectIdData =
queryServiceJSON( queryUrl, authcfg, errorTitle, errorText, requestHeaders, feedback );
127 if ( objectIdData.isEmpty() )
129 return QList<quint32>();
133 const QVariantList objectIdsList = objectIdData[QStringLiteral(
"objectIds" )].toList();
134 ids.reserve( objectIdsList.size() );
135 for (
const QVariant &objectId : objectIdsList )
137 ids << objectId.toInt();
144 QUrl url = parseUrl( u );
146 QNetworkRequest request( url );
148 for (
auto it = requestHeaders.constBegin(); it != requestHeaders.constEnd(); ++it )
150 request.setRawHeader( it.key().toUtf8(), it.value().toUtf8() );
164 errorTitle = QStringLiteral(
"Network error" );
171 *contentType = content.
rawHeader(
"Content-Type" );
177 QByteArray reply =
queryService( url, authcfg, errorTitle, errorText, requestHeaders, feedback );
178 if ( !errorTitle.isEmpty() )
180 return QVariantMap();
183 return QVariantMap();
187 QJsonDocument doc = QJsonDocument::fromJson( reply, &err );
190 errorTitle = QStringLiteral(
"Parsing error" );
191 errorText = err.errorString();
192 QgsDebugMsg( QStringLiteral(
"Parsing error: %1" ).arg( err.errorString() ) );
193 return QVariantMap();
195 const QVariantMap res = doc.object().toVariantMap();
196 if ( res.contains( QStringLiteral(
"error" ) ) )
198 const QVariantMap error = res.value( QStringLiteral(
"error" ) ).toMap();
199 errorText = error.value( QStringLiteral(
"message" ) ).toString();
200 errorTitle = QObject::tr(
"Error %1" ).arg( error.value( QStringLiteral(
"code" ) ).toString() );
201 return QVariantMap();
206 QUrl QgsArcGisRestQueryUtils::parseUrl(
const QUrl &url )
208 QUrl modifiedUrl( url );
209 if ( modifiedUrl.toString().contains( QLatin1String(
"fake_qgis_http_endpoint" ) ) )
212 QString modifiedUrlString = modifiedUrl.toString();
214 modifiedUrlString = QUrl::fromPercentEncoding( modifiedUrlString.toUtf8() );
215 modifiedUrlString.replace( QLatin1String(
"fake_qgis_http_endpoint/" ), QLatin1String(
"fake_qgis_http_endpoint_" ) );
216 QgsDebugMsg( QStringLiteral(
"Get %1" ).arg( modifiedUrlString ) );
217 modifiedUrlString = modifiedUrlString.mid( QStringLiteral(
"http://" ).size() );
218 QString args = modifiedUrlString.mid( modifiedUrlString.indexOf(
'?' ) );
219 if ( modifiedUrlString.size() > 150 )
221 args = QCryptographicHash::hash( args.toUtf8(), QCryptographicHash::Md5 ).toHex();
225 args.replace( QLatin1String(
"?" ), QLatin1String(
"_" ) );
226 args.replace( QLatin1String(
"&" ), QLatin1String(
"_" ) );
227 args.replace( QLatin1String(
"<" ), QLatin1String(
"_" ) );
228 args.replace( QLatin1String(
">" ), QLatin1String(
"_" ) );
229 args.replace( QLatin1String(
"'" ), QLatin1String(
"_" ) );
230 args.replace( QLatin1String(
"\"" ), QLatin1String(
"_" ) );
231 args.replace( QLatin1String(
" " ), QLatin1String(
"_" ) );
232 args.replace( QLatin1String(
":" ), QLatin1String(
"_" ) );
233 args.replace( QLatin1String(
"/" ), QLatin1String(
"_" ) );
234 args.replace( QLatin1String(
"\n" ), QLatin1String(
"_" ) );
239 if ( modifiedUrlString[1] ==
'/' )
241 modifiedUrlString = modifiedUrlString[0] +
":/" + modifiedUrlString.mid( 2 );
244 modifiedUrlString = modifiedUrlString.mid( 0, modifiedUrlString.indexOf(
'?' ) ) + args;
245 QgsDebugMsg( QStringLiteral(
"Get %1 (after laundering)" ).arg( modifiedUrlString ) );
246 modifiedUrl = QUrl::fromLocalFile( modifiedUrlString );
252 void QgsArcGisRestQueryUtils::adjustBaseUrl( QString &baseUrl,
const QString &name )
254 const QStringList parts = name.split(
'/' );
256 for (
const QString &part : parts )
258 if ( !checkString.isEmpty() )
259 checkString += QString(
'/' );
262 if ( baseUrl.indexOf( QRegularExpression( checkString.replace(
'/', QLatin1String(
"\\/" ) ) + QStringLiteral(
"\\/?$" ) ) ) > -1 )
264 baseUrl = baseUrl.left( baseUrl.length() - checkString.length() - 1 );
272 QString base( baseUrl );
273 bool baseChecked =
false;
274 if ( !base.endsWith(
'/' ) )
275 base += QLatin1Char(
'/' );
277 const QStringList folderList = serviceData.value( QStringLiteral(
"folders" ) ).toStringList();
278 for (
const QString &folder : folderList )
282 adjustBaseUrl( base, folder );
285 visitor( folder, base + folder );
291 QString base( baseUrl );
292 bool baseChecked =
false;
293 if ( !base.endsWith(
'/' ) )
294 base += QLatin1Char(
'/' );
296 const QVariantList serviceList = serviceData.value( QStringLiteral(
"services" ) ).toList();
297 for (
const QVariant &service : serviceList )
299 const QVariantMap serviceMap = service.toMap();
300 const QString serviceType = serviceMap.value( QStringLiteral(
"type" ) ).toString();
301 if ( serviceType != QLatin1String(
"MapServer" ) && serviceType != QLatin1String(
"ImageServer" ) && serviceType != QLatin1String(
"FeatureServer" ) )
306 const QString serviceName = serviceMap.value( QStringLiteral(
"name" ) ).toString();
307 QString displayName = serviceName.split(
'/' ).last();
310 adjustBaseUrl( base, serviceName );
314 visitor( displayName, base + serviceName +
'/' + serviceType, serviceType, type );
318 void QgsArcGisRestQueryUtils::addLayerItems(
const std::function<
void (
const QString &,
ServiceTypeFilter,
QgsWkbTypes::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 )
323 const QList<QByteArray> supportedFormats = QImageReader::supportedImageFormats();
324 const QStringList supportedImageFormatTypes = serviceData.value( QStringLiteral(
"supportedImageFormatTypes" ) ).toString().isEmpty() ? parentSupportedFormats.split(
',' ) : serviceData.value( QStringLiteral(
"supportedImageFormatTypes" ) ).toString().split(
',' );
325 QString format = supportedImageFormatTypes.value( 0 );
326 for (
const QString &encoding : supportedImageFormatTypes )
328 for (
const QByteArray &fmt : supportedFormats )
330 if ( encoding.startsWith( fmt, Qt::CaseInsensitive ) )
340 const QStringList capabilities = serviceData.value( QStringLiteral(
"capabilities" ) ).toString().split(
',' );
343 const bool serviceMayHaveQueryCapability = capabilities.contains( QStringLiteral(
"Query" ) ) ||
344 serviceData.value( QStringLiteral(
"serviceDataType" ) ).toString().startsWith( QLatin1String(
"esriImageService" ) );
346 const bool serviceMayRenderMaps = capabilities.contains( QStringLiteral(
"Map" ) ) ||
347 serviceData.value( QStringLiteral(
"serviceDataType" ) ).toString().startsWith( QLatin1String(
"esriImageService" ) );
349 const QVariantList layerInfoList = serviceData.value( QStringLiteral(
"layers" ) ).toList();
350 for (
const QVariant &layerInfo : layerInfoList )
352 const QVariantMap layerInfoMap = layerInfo.toMap();
353 const QString
id = layerInfoMap.value( QStringLiteral(
"id" ) ).toString();
354 const QString parentLayerId = layerInfoMap.value( QStringLiteral(
"parentLayerId" ) ).toString();
355 const QString name = layerInfoMap.value( QStringLiteral(
"name" ) ).toString();
356 const QString description = layerInfoMap.value( QStringLiteral(
"description" ) ).toString();
359 if ( serviceMayRenderMaps && ( filter ==
Raster || filter ==
AllTypes ) )
361 if ( !layerInfoMap.value( QStringLiteral(
"subLayerIds" ) ).toList().empty() )
371 if ( serviceMayHaveQueryCapability && ( filter ==
Vector || filter ==
AllTypes ) )
373 const QString geometryType = layerInfoMap.value( QStringLiteral(
"geometryType" ) ).toString();
384 if ( serviceMayRenderMaps )
386 if ( geometryType.isEmpty() )
394 if ( !layerInfoMap.value( QStringLiteral(
"subLayerIds" ) ).toList().empty() )
406 if ( filter !=
Vector && layerInfoList.count() > 1 && serviceData.contains( QStringLiteral(
"supportedImageFormatTypes" ) ) )
408 const QString name = QStringLiteral(
"(%1)" ).arg( QObject::tr(
"All layers" ) );
409 const QString description = serviceData.value( QStringLiteral(
"Comments" ) ).toString();
414 if ( serviceData.value( QStringLiteral(
"serviceDataType" ) ).toString().startsWith( QLatin1String(
"esriImageService" ) ) )
416 const QString name = serviceData.value( QStringLiteral(
"name" ) ).toString();
417 const QString description = serviceData.value( QStringLiteral(
"description" ) ).toString();
429 QgsArcGisAsyncQuery::QgsArcGisAsyncQuery( QObject *parent )
434 QgsArcGisAsyncQuery::~QgsArcGisAsyncQuery()
437 mReply->deleteLater();
440 void QgsArcGisAsyncQuery::start(
const QUrl &url,
const QString &authCfg, QByteArray *result,
bool allowCache,
const QgsStringMap &headers )
443 QNetworkRequest request( url );
445 for (
auto it = headers.constBegin(); it != headers.constEnd(); ++it )
447 request.setRawHeader( it.key().toUtf8(), it.value().toUtf8() );
452 const QString error = tr(
"network request update failed for authentication config" );
453 emit failed( QStringLiteral(
"Network" ), error );
460 request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
461 request.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
true );
464 connect( mReply, &QNetworkReply::finished,
this, &QgsArcGisAsyncQuery::handleReply );
467 void QgsArcGisAsyncQuery::handleReply()
469 mReply->deleteLater();
471 if ( mReply->error() != QNetworkReply::NoError )
473 QgsDebugMsg( QStringLiteral(
"Network error: %1" ).arg( mReply->errorString() ) );
474 emit failed( QStringLiteral(
"Network error" ), mReply->errorString() );
479 QVariant redirect = mReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
480 if ( !redirect.isNull() )
482 QNetworkRequest request = mReply->request();
484 QgsDebugMsg(
"redirecting to " + redirect.toUrl().toString() );
485 request.setUrl( redirect.toUrl() );
487 connect( mReply, &QNetworkReply::finished,
this, &QgsArcGisAsyncQuery::handleReply );
491 *mResult = mReply->readAll();
500 QgsArcGisAsyncParallelQuery::QgsArcGisAsyncParallelQuery(
const QString &authcfg,
const QgsStringMap &requestHeaders, QObject *parent )
502 , mAuthCfg( authcfg )
503 , mRequestHeaders( requestHeaders )
507 void QgsArcGisAsyncParallelQuery::start(
const QVector<QUrl> &urls, QVector<QByteArray> *results,
bool allowCache )
509 Q_ASSERT( results->size() == urls.size() );
511 mPendingRequests = mResults->size();
512 for (
int i = 0, n = urls.size(); i < n; ++i )
514 QNetworkRequest request( urls[i] );
518 for (
auto it = mRequestHeaders.constBegin(); it != mRequestHeaders.constEnd(); ++it )
520 request.setRawHeader( it.key().toUtf8(), it.value().toUtf8() );
524 const QString error = tr(
"network request update failed for authentication config" );
525 mErrors.append( error );
530 request.setAttribute( QNetworkRequest::HttpPipeliningAllowedAttribute,
true );
533 request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
534 request.setAttribute( QNetworkRequest::CacheSaveControlAttribute,
true );
535 request.setRawHeader(
"Connection",
"keep-alive" );
538 reply->setProperty(
"idx", i );
539 connect( reply, &QNetworkReply::finished,
this, &QgsArcGisAsyncParallelQuery::handleReply );
543 void QgsArcGisAsyncParallelQuery::handleReply()
545 QNetworkReply *reply = qobject_cast<QNetworkReply *>( QObject::sender() );
546 QVariant redirect = reply->attribute( QNetworkRequest::RedirectionTargetAttribute );
547 int idx = reply->property(
"idx" ).toInt();
548 reply->deleteLater();
549 if ( reply->error() != QNetworkReply::NoError )
552 mErrors.append( reply->errorString() );
555 else if ( !redirect.isNull() )
558 QNetworkRequest request = reply->request();
560 QgsDebugMsg(
"redirecting to " + redirect.toUrl().toString() );
561 request.setUrl( redirect.toUrl() );
563 reply->setProperty(
"idx", idx );
564 connect( reply, &QNetworkReply::finished,
this, &QgsArcGisAsyncParallelQuery::handleReply );
569 ( *mResults )[idx] = reply->readAll();
572 if ( mPendingRequests == 0 )
574 emit finished( mErrors );
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 void addLayerItems(const std::function< void(const QString &parentLayerId, ServiceTypeFilter serviceType, QgsWkbTypes::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=AllTypes)
Calls the specified visitor function on all layer 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 QgsStringMap &requestHeaders=QgsStringMap(), QgsFeedback *feedback=nullptr)
Gets a list of object IDs which fall within the specified extent.
static QVariantMap getObjectIds(const QString &layerurl, const QString &authcfg, QString &errorTitle, QString &errorText, const QMap< QString, QString > &requestHeaders=QMap< QString, QString >(), const QgsRectangle &bbox=QgsRectangle())
Retrieves all object IDs for the specified layer URL.
static QVariantMap queryServiceJSON(const QUrl &url, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsStringMap &requestHeaders=QgsStringMap(), QgsFeedback *feedback=nullptr)
Performs a blocking request to a URL and returns the retrieved JSON content.
ServiceTypeFilter
Service types.
static QVariantMap getLayerInfo(const QString &layerurl, const QString &authcfg, QString &errorTitle, QString &errorText, const QMap< QString, QString > &requestHeaders=QMap< QString, QString >())
Retrieves JSON layer info for the specified layer URL.
static void visitServiceItems(const std::function< void(const QString &serviceName, const QString &url, const QString &service, ServiceTypeFilter 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 getServiceInfo(const QString &baseurl, const QString &authcfg, QString &errorTitle, QString &errorText, const QMap< QString, QString > &requestHeaders=QMap< QString, QString >())
Retrieves JSON service info for the specified base URL.
static QByteArray queryService(const QUrl &url, const QString &authcfg, QString &errorTitle, QString &errorText, const QgsStringMap &requestHeaders=QgsStringMap(), QgsFeedback *feedback=nullptr, QString *contentType=nullptr)
Performs a blocking request to a URL and returns the retrieved 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 QgsStringMap &requestHeaders=QgsStringMap(), QgsFeedback *feedback=nullptr)
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 QgsWkbTypes::Type convertGeometryType(const QString &type)
Converts an ESRI REST geometry type to a WKB 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() or post() request has been made.
@ NoError
No error was encountered.
QgsNetworkReplyContent reply() const
Returns the content of the network reply, after a get() or post() request has been made.
QString authid() const
Returns the authority identifier for the CRS.
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).
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
static GeometryType geometryType(Type type) SIP_HOLDGIL
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Type
The WKB type describes the number of dimensions a geometry has.
QMap< QString, QString > QgsStringMap
#define QgsSetRequestInitiatorClass(request, _class)
#define QgsSetRequestInitiatorId(request, str)
const QgsCoordinateReferenceSystem & crs