QGIS API Documentation 3.99.0-Master (357b655ed83)
Loading...
Searching...
No Matches
qgssensorthingsprovider.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgssensorthingsprovider.cpp
3 ----------------
4 begin : November 2023
5 copyright : (C) 2013 Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19
20#include <nlohmann/json.hpp>
21
22#include "qgsapplication.h"
24#include "qgsmessagelog.h"
25#include "qgsreadwritelocker.h"
31#include "qgsthreadingutils.h"
32
33#include <QIcon>
34#include <QNetworkRequest>
35#include <QString>
36
37#include "moc_qgssensorthingsprovider.cpp"
38
39using namespace Qt::StringLiterals;
40
42
43QgsSensorThingsProvider::QgsSensorThingsProvider( const QString &uri, const ProviderOptions &options, Qgis::DataProviderReadFlags flags )
44 : QgsVectorDataProvider( uri, options, flags )
45{
46 mSharedData = std::make_shared< QgsSensorThingsSharedData >( uri );
47
48 const QUrl url( QgsSensorThingsSharedData::parseUrl( mSharedData->mRootUri ) );
49
50 QNetworkRequest request = QNetworkRequest( url );
51 QgsSetRequestInitiatorClass( request, u"QgsSensorThingsProvider"_s )
52 mSharedData->mHeaders.updateNetworkRequest( request );
53
54 QgsBlockingNetworkRequest networkRequest;
55 networkRequest.setAuthCfg( mSharedData->mAuthCfg );
56
57 switch ( networkRequest.get( request ) )
58 {
60 break;
61
65 appendError( QgsErrorMessage( tr( "Connection failed: %1" ).arg( networkRequest.errorMessage() ), u"SensorThings"_s ) );
66 return;
67 }
68
69 const QgsNetworkReplyContent content = networkRequest.reply();
70
71 try
72 {
73 auto rootContent = json::parse( content.content().toStdString() );
74 if ( !rootContent.contains( "value" ) )
75 {
76 appendError( QgsErrorMessage( tr( "No 'value' array in response" ), u"SensorThings"_s ) );
77 return;
78 }
79
80 bool foundMatchingEntity = false;
81 for ( const auto &valueJson : rootContent["value"] )
82 {
83 if ( valueJson.contains( "name" ) && valueJson.contains( "url" ) )
84 {
85 const QString name = QString::fromStdString( valueJson["name"].get<std::string>() );
87 if ( entityType == mSharedData->mEntityType )
88 {
89 const QString url = QString::fromStdString( valueJson["url"].get<std::string>() );
90 if ( !url.isEmpty() )
91 {
92 foundMatchingEntity = true;
93 mSharedData->mEntityBaseUri = url;
94
95 // TODO:
96 // if we always retrieve feature count, is that less expensive then deferring this till we need it?
97 // by retrieving upfront, we can save a lot of requests where we've fetched features from spatial extents
98 // as we'll have a way of determining whether we've fetched all features from the source. Otherwise
99 // we never know if we've got everything yet, and are forced to re-fetched everything when a non-filtered request
100 // comes in...
101 ( void ) mSharedData->featureCount();
102 }
103 }
104 }
105 }
106
107 if ( !foundMatchingEntity )
108 {
109 switch ( mSharedData->mEntityType )
110 {
111
121 appendError( QgsErrorMessage( tr( "Could not find url for %1" ).arg( qgsEnumValueToKey( mSharedData->mEntityType ) ), u"SensorThings"_s ) );
122 QgsMessageLog::logMessage( tr( "Could not find url for %1" ).arg( qgsEnumValueToKey( mSharedData->mEntityType ) ), tr( "SensorThings" ) );
123 break;
124
126 appendError( QgsErrorMessage( tr( "MultiDatastreams are not supported by this connection" ), u"SensorThings"_s ) );
127 QgsMessageLog::logMessage( tr( "MultiDatastreams are not supported by this connection" ), tr( "SensorThings" ) );
128 break;
129 }
130
131 return;
132 }
133 }
134 catch ( const json::parse_error &ex )
135 {
136 appendError( QgsErrorMessage( tr( "Error parsing response: %1" ).arg( ex.what() ), u"SensorThings"_s ) );
137 return;
138 }
139
140 mValid = true;
141}
142
143QString QgsSensorThingsProvider::storageType() const
144{
146
147 return u"OGC SensorThings API"_s;
148}
149
150QgsAbstractFeatureSource *QgsSensorThingsProvider::featureSource() const
151{
153
154 return new QgsSensorThingsFeatureSource( mSharedData );
155}
156
157QgsFeatureIterator QgsSensorThingsProvider::getFeatures( const QgsFeatureRequest &request ) const
158{
160
161 return new QgsSensorThingsFeatureIterator( new QgsSensorThingsFeatureSource( mSharedData ), true, request );
162}
163
164Qgis::WkbType QgsSensorThingsProvider::wkbType() const
165{
167
168 return mSharedData->mGeometryType;
169}
170
171long long QgsSensorThingsProvider::featureCount() const
172{
174
175 if ( ( mReadFlags & Qgis::DataProviderReadFlag::SkipFeatureCount ) != 0 )
176 {
177 return static_cast< long long >( Qgis::FeatureCountState::UnknownCount );
178 }
179
180 const long long count = mSharedData->featureCount();
181 if ( !mSharedData->error().isEmpty() )
182 pushError( mSharedData->error() );
183
184 return count;
185}
186
187QgsFields QgsSensorThingsProvider::fields() const
188{
190
191 return mSharedData->mFields;
192}
193
194QgsLayerMetadata QgsSensorThingsProvider::layerMetadata() const
195{
197
198 return mLayerMetadata;
199}
200
201QString QgsSensorThingsProvider::htmlMetadata() const
202{
204
205 QString metadata;
206
207 QgsReadWriteLocker locker( mSharedData->mReadWriteLock, QgsReadWriteLocker::Read );
208
209 metadata += u"<tr><td class=\"highlight\">"_s % tr( "Entity Type" ) % u"</td><td>%1"_s.arg( qgsEnumValueToKey( mSharedData->mEntityType ) ) % u"</td></tr>\n"_s;
210 metadata += u"<tr><td class=\"highlight\">"_s % tr( "Endpoint" ) % u"</td><td><a href=\"%1\">%1</a>"_s.arg( mSharedData->mEntityBaseUri ) % u"</td></tr>\n"_s;
211
212 return metadata;
213}
214
215Qgis::DataProviderFlags QgsSensorThingsProvider::flags() const
216{
218
220}
221
222Qgis::VectorProviderCapabilities QgsSensorThingsProvider::capabilities() const
223{
225
229
230 return c;
231}
232
233bool QgsSensorThingsProvider::supportsSubsetString() const
234{
236 return true;
237}
238
239QString QgsSensorThingsProvider::subsetStringDialect() const
240{
241 return tr( "OGC SensorThings filter" );
242}
243
244QString QgsSensorThingsProvider::subsetStringHelpUrl() const
245{
246 return u"https://docs.ogc.org/is/18-088/18-088.html#filter"_s;
247}
248
249QString QgsSensorThingsProvider::subsetString() const
250{
252 return mSharedData->subsetString();
253}
254
255bool QgsSensorThingsProvider::setSubsetString( const QString &subset, bool )
256{
258
259 const QString trimmedSubset = subset.trimmed();
260 if ( trimmedSubset == mSharedData->subsetString() )
261 return true;
262
263 // store this and restore it after the data source is changed,
264 // to avoid an unwanted network request to retrieve this again
265 const QString baseUri = mSharedData->mEntityBaseUri;
266
267 QgsDataSourceUri uri = dataSourceUri();
268 uri.setSql( trimmedSubset );
269 setDataSourceUri( uri.uri( false ) );
270
271 mSharedData->mEntityBaseUri = baseUri;
272
273 clearMinMaxCache();
274
275 emit dataChanged();
276
277 return true;
278}
279
280void QgsSensorThingsProvider::setDataSourceUri( const QString &uri )
281{
283
284 mSharedData = std::make_shared< QgsSensorThingsSharedData >( uri );
286}
287
288QgsCoordinateReferenceSystem QgsSensorThingsProvider::crs() const
289{
291
292 return mSharedData->mSourceCRS;
293}
294
295QgsRectangle QgsSensorThingsProvider::extent() const
296{
298 return mSharedData->extent();
299}
300
301QString QgsSensorThingsProvider::name() const
302{
304
305 return SENSORTHINGS_PROVIDER_KEY;
306}
307
308QString QgsSensorThingsProvider::providerKey()
309{
310 return SENSORTHINGS_PROVIDER_KEY;
311}
312
313void QgsSensorThingsProvider::handlePostCloneOperations( QgsVectorDataProvider *source )
314{
315 mSharedData = qobject_cast<QgsSensorThingsProvider *>( source )->mSharedData;
316}
317
318QString QgsSensorThingsProvider::description() const
319{
320 return SENSORTHINGS_PROVIDER_DESCRIPTION;
321}
322
323bool QgsSensorThingsProvider::renderInPreview( const PreviewContext & )
324{
325 // be nice to the endpoint and don't make any requests we don't have to!
326 return false;
327}
328
329void QgsSensorThingsProvider::reloadProviderData()
330{
331#if 0
332 mSharedData->clearCache();
333#endif
334}
335
336//
337// QgsSensorThingsProviderMetadata
338//
339
340QgsSensorThingsProviderMetadata::QgsSensorThingsProviderMetadata():
341 QgsProviderMetadata( QgsSensorThingsProvider::SENSORTHINGS_PROVIDER_KEY, QgsSensorThingsProvider::SENSORTHINGS_PROVIDER_DESCRIPTION )
342{
343}
344
345QIcon QgsSensorThingsProviderMetadata::icon() const
346{
347 return QgsApplication::getThemeIcon( u"mIconSensorThings.svg"_s );
348}
349
350QList<QgsDataItemProvider *> QgsSensorThingsProviderMetadata::dataItemProviders() const
351{
352 return { new QgsSensorThingsDataItemProvider() };
353}
354
355QVariantMap QgsSensorThingsProviderMetadata::decodeUri( const QString &uri ) const
356{
357 const QgsDataSourceUri dsUri = QgsDataSourceUri( uri );
358
359 QVariantMap components;
360 components.insert( u"url"_s, dsUri.param( u"url"_s ) );
361
362 if ( !dsUri.authConfigId().isEmpty() )
363 {
364 components.insert( u"authcfg"_s, dsUri.authConfigId() );
365 }
366 if ( !dsUri.username().isEmpty() )
367 {
368 components.insert( u"username"_s, dsUri.username() );
369 }
370 if ( !dsUri.password().isEmpty() )
371 {
372 components.insert( u"password"_s, dsUri.password() );
373 }
374
375 // there's two different ways the referer can be set, so we need to check both. Which way it has been
376 // set depends on the widget used to create the URI. It's messy, but QgsHttpHeaders has a bunch of logic in
377 // it to handle upgrading old referer handling for connections created before QgsHttpHeaders was invented,
378 // and if we rely on that entirely then we get multiple "referer" parameters included in the URI, which is
379 // both ugly and unnecessary for a provider created post QgsHttpHeaders.
380 if ( !dsUri.param( u"referer"_s ).isEmpty() )
381 {
382 components.insert( u"referer"_s, dsUri.param( u"referer"_s ) );
383 }
384 if ( !dsUri.param( u"http-header:referer"_s ).isEmpty() )
385 {
386 components.insert( u"referer"_s, dsUri.param( u"http-header:referer"_s ) );
387 }
388
389 const QString entityParam = dsUri.param( u"entity"_s );
391 if ( entity == Qgis::SensorThingsEntity::Invalid )
392 entity = QgsSensorThingsUtils::stringToEntity( entityParam );
393
394 if ( entity != Qgis::SensorThingsEntity::Invalid )
395 components.insert( u"entity"_s, qgsEnumValueToKey( entity ) );
396
397 const QStringList expandToParam = dsUri.param( u"expandTo"_s ).split( ';', Qt::SkipEmptyParts );
398 if ( !expandToParam.isEmpty() )
399 {
400 QVariantList expandParts;
401 for ( const QString &expandString : expandToParam )
402 {
404 if ( definition.isValid() )
405 {
406 expandParts.append( QVariant::fromValue( definition ) );
407 }
408 }
409 if ( !expandParts.isEmpty() )
410 {
411 components.insert( u"expandTo"_s, expandParts );
412 }
413 }
414
415 bool ok = false;
416 const int maxPageSizeParam = dsUri.param( u"pageSize"_s ).toInt( &ok );
417 if ( ok )
418 {
419 components.insert( u"pageSize"_s, maxPageSizeParam );
420 }
421
422 ok = false;
423 const int featureLimitParam = dsUri.param( u"featureLimit"_s ).toInt( &ok );
424 if ( ok )
425 {
426 components.insert( u"featureLimit"_s, featureLimitParam );
427 }
428
429 switch ( QgsWkbTypes::geometryType( dsUri.wkbType() ) )
430 {
432 if ( QgsWkbTypes::isMultiType( dsUri.wkbType() ) )
433 components.insert( u"geometryType"_s, u"multipoint"_s );
434 else
435 components.insert( u"geometryType"_s, u"point"_s );
436 break;
438 components.insert( u"geometryType"_s, u"line"_s );
439 break;
441 components.insert( u"geometryType"_s, u"polygon"_s );
442 break;
443
446 break;
447 }
448
449 const QStringList bbox = dsUri.param( u"bbox"_s ).split( ',' );
450 if ( bbox.size() == 4 )
451 {
452 QgsRectangle r;
453 bool xminOk = false;
454 bool yminOk = false;
455 bool xmaxOk = false;
456 bool ymaxOk = false;
457 r.setXMinimum( bbox[0].toDouble( &xminOk ) );
458 r.setYMinimum( bbox[1].toDouble( &yminOk ) );
459 r.setXMaximum( bbox[2].toDouble( &xmaxOk ) );
460 r.setYMaximum( bbox[3].toDouble( &ymaxOk ) );
461 if ( xminOk && yminOk && xmaxOk && ymaxOk )
462 components.insert( u"bounds"_s, r );
463 }
464
465 if ( !dsUri.sql().isEmpty() )
466 components.insert( u"sql"_s, dsUri.sql() );
467
468 return components;
469}
470
471QString QgsSensorThingsProviderMetadata::encodeUri( const QVariantMap &parts ) const
472{
473 QgsDataSourceUri dsUri;
474 dsUri.setParam( u"url"_s, parts.value( u"url"_s ).toString() );
475
476 if ( !parts.value( u"authcfg"_s ).toString().isEmpty() )
477 {
478 dsUri.setAuthConfigId( parts.value( u"authcfg"_s ).toString() );
479 }
480 if ( !parts.value( u"username"_s ).toString().isEmpty() )
481 {
482 dsUri.setUsername( parts.value( u"username"_s ).toString() );
483 }
484 if ( !parts.value( u"password"_s ).toString().isEmpty() )
485 {
486 dsUri.setPassword( parts.value( u"password"_s ).toString() );
487 }
488 if ( !parts.value( u"referer"_s ).toString().isEmpty() )
489 {
490 dsUri.setParam( u"referer"_s, parts.value( u"referer"_s ).toString() );
491 }
492
494 parts.value( u"entity"_s ).toString() );
495 if ( entity == Qgis::SensorThingsEntity::Invalid )
496 entity = QgsSensorThingsUtils::stringToEntity( parts.value( u"entity"_s ).toString() );
497
498 if ( entity != Qgis::SensorThingsEntity::Invalid )
499 {
500 dsUri.setParam( u"entity"_s,
501 qgsEnumValueToKey( entity ) );
502 }
503
504 const QVariantList expandToParam = parts.value( u"expandTo"_s ).toList();
505 if ( !expandToParam.isEmpty() )
506 {
507 QStringList expandToStringList;
508 for ( const QVariant &expansion : expandToParam )
509 {
510 const QgsSensorThingsExpansionDefinition expansionDefinition = expansion.value< QgsSensorThingsExpansionDefinition >();
511 if ( !expansionDefinition.isValid() )
512 continue;
513
514 expandToStringList.append( expansionDefinition.toString() );
515 }
516 if ( !expandToStringList.isEmpty() )
517 {
518 dsUri.setParam( u"expandTo"_s, expandToStringList.join( ';' ) );
519 }
520 }
521
522 bool ok = false;
523 const int maxPageSizeParam = parts.value( u"pageSize"_s ).toInt( &ok );
524 if ( ok )
525 {
526 dsUri.setParam( u"pageSize"_s, QString::number( maxPageSizeParam ) );
527 }
528
529 ok = false;
530 const int featureLimitParam = parts.value( u"featureLimit"_s ).toInt( &ok );
531 if ( ok )
532 {
533 dsUri.setParam( u"featureLimit"_s, QString::number( featureLimitParam ) );
534 }
535
536 const QString geometryType = parts.value( u"geometryType"_s ).toString();
537 if ( geometryType.compare( "point"_L1, Qt::CaseInsensitive ) == 0 )
538 {
540 }
541 else if ( geometryType.compare( "multipoint"_L1, Qt::CaseInsensitive ) == 0 )
542 {
544 }
545 else if ( geometryType.compare( "line"_L1, Qt::CaseInsensitive ) == 0 )
546 {
548 }
549 else if ( geometryType.compare( "polygon"_L1, Qt::CaseInsensitive ) == 0 )
550 {
552 }
553
554 if ( parts.contains( u"bounds"_s ) && parts.value( u"bounds"_s ).userType() == qMetaTypeId<QgsRectangle>() )
555 {
556 const QgsRectangle bBox = parts.value( u"bounds"_s ).value< QgsRectangle >();
557 dsUri.setParam( u"bbox"_s, u"%1,%2,%3,%4"_s.arg( bBox.xMinimum() ).arg( bBox.yMinimum() ).arg( bBox.xMaximum() ).arg( bBox.yMaximum() ) );
558 }
559
560 if ( !parts.value( u"sql"_s ).toString().isEmpty() )
561 dsUri.setSql( parts.value( u"sql"_s ).toString() );
562
563 return dsUri.uri( false );
564}
565
566QgsSensorThingsProvider *QgsSensorThingsProviderMetadata::createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, Qgis::DataProviderReadFlags flags )
567{
568 return new QgsSensorThingsProvider( uri, options, flags );
569}
570
571QList<Qgis::LayerType> QgsSensorThingsProviderMetadata::supportedLayerTypes() const
572{
573 return { Qgis::LayerType::Vector };
574}
575
576QMap<QString, QgsAbstractProviderConnection *> QgsSensorThingsProviderMetadata::connections( bool cached )
577{
578 return connectionsProtected<QgsSensorThingsProviderConnection, QgsSensorThingsProviderConnection>( cached );
579}
580
581QgsAbstractProviderConnection *QgsSensorThingsProviderMetadata::createConnection( const QString &name )
582{
583 return new QgsSensorThingsProviderConnection( name );
584}
585
586void QgsSensorThingsProviderMetadata::deleteConnection( const QString &name )
587{
588 deleteConnectionProtected<QgsSensorThingsProviderConnection>( name );
589}
590
591void QgsSensorThingsProviderMetadata::saveConnection( const QgsAbstractProviderConnection *connection, const QString &name )
592{
593 saveConnectionProtected( connection, name );
594}
595
@ SelectAtId
Fast access to features using their ID.
Definition qgis.h:526
@ ReloadData
Provider is able to force reload data.
Definition qgis.h:542
@ ReadLayerMetadata
Provider can read layer metadata from data store. Since QGIS 3.0. See QgsDataProvider::layerMetadata(...
Definition qgis.h:537
QFlags< DataProviderFlag > DataProviderFlags
Data provider flags.
Definition qgis.h:2373
@ FastExtent2D
Provider's 2D extent retrieval via QgsDataProvider::extent() is always guaranteed to be trivial/fast ...
Definition qgis.h:2368
SensorThingsEntity
OGC SensorThings API entity types.
Definition qgis.h:6267
@ Sensor
A Sensor is an instrument that observes a property or phenomenon with the goal of producing an estima...
Definition qgis.h:6273
@ MultiDatastream
A MultiDatastream groups a collection of Observations and the Observations in a MultiDatastream have ...
Definition qgis.h:6277
@ ObservedProperty
An ObservedProperty specifies the phenomenon of an Observation.
Definition qgis.h:6274
@ Invalid
An invalid/unknown entity.
Definition qgis.h:6268
@ FeatureOfInterest
In the context of the Internet of Things, many Observations’ FeatureOfInterest can be the Location of...
Definition qgis.h:6276
@ Datastream
A Datastream groups a collection of Observations measuring the same ObservedProperty and produced by ...
Definition qgis.h:6272
@ Observation
An Observation is the act of measuring or otherwise determining the value of a property.
Definition qgis.h:6275
@ Location
A Location entity locates the Thing or the Things it associated with. A Thing’s Location entity is de...
Definition qgis.h:6270
@ Thing
A Thing is an object of the physical world (physical things) or the information world (virtual things...
Definition qgis.h:6269
@ HistoricalLocation
A Thing’s HistoricalLocation entity set provides the times of the current (i.e., last known) and prev...
Definition qgis.h:6271
@ Point
Points.
Definition qgis.h:366
@ Line
Lines.
Definition qgis.h:367
@ Polygon
Polygons.
Definition qgis.h:368
@ Unknown
Unknown types.
Definition qgis.h:369
@ Null
No geometry.
Definition qgis.h:370
QFlags< DataProviderReadFlag > DataProviderReadFlags
Flags which control data provider construction.
Definition qgis.h:505
QFlags< VectorProviderCapability > VectorProviderCapabilities
Vector data provider capabilities.
Definition qgis.h:555
@ Vector
Vector layer.
Definition qgis.h:194
@ SkipFeatureCount
Make featureCount() return -1 to indicate unknown, and subLayers() to return a unknown feature count ...
Definition qgis.h:488
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:280
@ MultiPointZ
MultiPointZ.
Definition qgis.h:303
@ PointZ
PointZ.
Definition qgis.h:299
@ MultiLineStringZ
MultiLineStringZ.
Definition qgis.h:304
@ MultiPolygonZ
MultiPolygonZ.
Definition qgis.h:305
Base class that can be used for any class that is capable of returning features.
An interface for data provider connections.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
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.
@ NetworkError
A network error occurred.
@ ServerExceptionError
An exception was raised by the server.
@ NoError
No error was encountered.
@ TimeoutError
Timeout was reached before a reply was received.
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).
virtual void setDataSourceUri(const QString &uri)
Set the data source specification.
Stores the component parts of a data source URI (e.g.
void setSql(const QString &sql)
Sets the sql filter for the URI.
void setAuthConfigId(const QString &authcfg)
Sets the authentication configuration ID for the URI.
QString uri(bool expandAuthConfig=true) const
Returns the complete URI as a string.
void setUsername(const QString &username)
Sets the username for the URI.
QString param(const QString &key) const
Returns a generic parameter value corresponding to the specified key.
QString username() const
Returns the username stored in the URI.
Qgis::WkbType wkbType() const
Returns the WKB type associated with the URI.
void setWkbType(Qgis::WkbType type)
Sets the WKB type associated with the URI.
void setParam(const QString &key, const QString &value)
Sets a generic parameter value on the URI.
QString password() const
Returns the password stored in the URI.
QString authConfigId() const
Returns any associated authentication configuration ID stored in the URI.
QString sql() const
Returns the SQL filter stored in the URI, if set.
void setPassword(const QString &password)
Sets the password for the URI.
Represents a single error message.
Definition qgserror.h:35
Wrapper for iterator of features from vector data provider or vector layer.
Wraps a request for features to a vector layer (or directly its vector data provider).
Container of fields for a vector layer.
Definition qgsfields.h:46
A structured metadata store for a map layer.
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).
Encapsulates a network reply within a container which is inexpensive to copy and safe to pass between...
QByteArray content() const
Returns the reply content.
Holds data provider key, description, and associated shared library file or function pointer informat...
A convenience class that simplifies locking and unlocking QReadWriteLocks.
A rectangle specified with double values.
double xMinimum
double yMinimum
double xMaximum
void setYMinimum(double y)
Set the minimum y value.
void setXMinimum(double x)
Set the minimum x value.
void setYMaximum(double y)
Set the maximum y value.
void setXMaximum(double x)
Set the maximum x value.
double yMaximum
Encapsulates information about how relationships in a SensorThings API service should be expanded.
static QgsSensorThingsExpansionDefinition fromString(const QString &string)
Returns a QgsSensorThingsExpansionDefinition from a string representation.
QString toString() const
Returns a string encapsulation of the expansion definition.
bool isValid() const
Returns true if the definition is valid.
Represents connections to SensorThings data sources.
static Qgis::SensorThingsEntity stringToEntity(const QString &type)
Converts a string value to a Qgis::SensorThingsEntity type.
static Qgis::SensorThingsEntity entitySetStringToEntity(const QString &type)
Converts a string value corresponding to a SensorThings entity set to a Qgis::SensorThingsEntity type...
Base class for vector data providers.
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...
static Q_INVOKABLE bool isMultiType(Qgis::WkbType type)
Returns true if the WKB type is a multi type.
@ UnknownCount
Provider returned an unknown feature count.
Definition qgis.h:566
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition qgis.h:7126
#define QgsSetRequestInitiatorClass(request, _class)
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
Setting options for creating vector data providers.