QGIS API Documentation 3.39.0-Master (d85f3c2a281)
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
20#include "qgsapplication.h"
23#include "qgsthreadingutils.h"
24#include "qgsreadwritelocker.h"
28#include "qgsmessagelog.h"
29
30#include <QIcon>
31#include <QNetworkRequest>
32#include <nlohmann/json.hpp>
33
35
36QgsSensorThingsProvider::QgsSensorThingsProvider( const QString &uri, const ProviderOptions &options, Qgis::DataProviderReadFlags flags )
37 : QgsVectorDataProvider( uri, options, flags )
38{
39 mSharedData = std::make_shared< QgsSensorThingsSharedData >( uri );
40
41 const QUrl url( QgsSensorThingsSharedData::parseUrl( mSharedData->mRootUri ) );
42
43 QNetworkRequest request = QNetworkRequest( url );
44 QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsSensorThingsProvider" ) )
45 mSharedData->mHeaders.updateNetworkRequest( request );
46
47 QgsBlockingNetworkRequest networkRequest;
48 networkRequest.setAuthCfg( mSharedData->mAuthCfg );
49
50 switch ( networkRequest.get( request ) )
51 {
53 break;
54
58 appendError( QgsErrorMessage( tr( "Connection failed: %1" ).arg( networkRequest.errorMessage() ), QStringLiteral( "SensorThings" ) ) );
59 return;
60 }
61
62 const QgsNetworkReplyContent content = networkRequest.reply();
63
64 try
65 {
66 auto rootContent = json::parse( content.content().toStdString() );
67 if ( !rootContent.contains( "value" ) )
68 {
69 appendError( QgsErrorMessage( tr( "No 'value' array in response" ), QStringLiteral( "SensorThings" ) ) );
70 return;
71 }
72
73 bool foundMatchingEntity = false;
74 for ( const auto &valueJson : rootContent["value"] )
75 {
76 if ( valueJson.contains( "name" ) && valueJson.contains( "url" ) )
77 {
78 const QString name = QString::fromStdString( valueJson["name"].get<std::string>() );
80 if ( entityType == mSharedData->mEntityType )
81 {
82 const QString url = QString::fromStdString( valueJson["url"].get<std::string>() );
83 if ( !url.isEmpty() )
84 {
85 foundMatchingEntity = true;
86 mSharedData->mEntityBaseUri = url;
87
88 // TODO:
89 // if we always retrieve feature count, is that less expensive then deferring this till we need it?
90 // by retrieving upfront, we can save a lot of requests where we've fetched features from spatial extents
91 // as we'll have a way of determining whether we've fetched all features from the source. Otherwise
92 // we never know if we've got everything yet, and are forced to re-fetched everything when a non-filtered request
93 // comes in...
94 ( void ) mSharedData->featureCount();
95 }
96 }
97 }
98 }
99
100 if ( !foundMatchingEntity )
101 {
102 switch ( mSharedData->mEntityType )
103 {
104
114 appendError( QgsErrorMessage( tr( "Could not find url for %1" ).arg( qgsEnumValueToKey( mSharedData->mEntityType ) ), QStringLiteral( "SensorThings" ) ) );
115 QgsMessageLog::logMessage( tr( "Could not find url for %1" ).arg( qgsEnumValueToKey( mSharedData->mEntityType ) ), tr( "SensorThings" ) );
116 break;
117
119 appendError( QgsErrorMessage( tr( "MultiDatastreams are not supported by this connection" ), QStringLiteral( "SensorThings" ) ) );
120 QgsMessageLog::logMessage( tr( "MultiDatastreams are not supported by this connection" ), tr( "SensorThings" ) );
121 break;
122 }
123
124 return;
125 }
126 }
127 catch ( const json::parse_error &ex )
128 {
129 appendError( QgsErrorMessage( tr( "Error parsing response: %1" ).arg( ex.what() ), QStringLiteral( "SensorThings" ) ) );
130 return;
131 }
132
133 mValid = true;
134}
135
136QString QgsSensorThingsProvider::storageType() const
137{
139
140 return QStringLiteral( "OGC SensorThings API" );
141}
142
143QgsAbstractFeatureSource *QgsSensorThingsProvider::featureSource() const
144{
146
147 return new QgsSensorThingsFeatureSource( mSharedData );
148}
149
150QgsFeatureIterator QgsSensorThingsProvider::getFeatures( const QgsFeatureRequest &request ) const
151{
153
154 return new QgsSensorThingsFeatureIterator( new QgsSensorThingsFeatureSource( mSharedData ), true, request );
155}
156
157Qgis::WkbType QgsSensorThingsProvider::wkbType() const
158{
160
161 return mSharedData->mGeometryType;
162}
163
164long long QgsSensorThingsProvider::featureCount() const
165{
167
168 if ( ( mReadFlags & Qgis::DataProviderReadFlag::SkipFeatureCount ) != 0 )
169 {
170 return static_cast< long long >( Qgis::FeatureCountState::UnknownCount );
171 }
172
173 const long long count = mSharedData->featureCount();
174 if ( !mSharedData->error().isEmpty() )
175 pushError( mSharedData->error() );
176
177 return count;
178}
179
180QgsFields QgsSensorThingsProvider::fields() const
181{
183
184 return mSharedData->mFields;
185}
186
187QgsLayerMetadata QgsSensorThingsProvider::layerMetadata() const
188{
190
191 return mLayerMetadata;
192}
193
194QString QgsSensorThingsProvider::htmlMetadata() const
195{
197
198 QString metadata;
199
200 QgsReadWriteLocker locker( mSharedData->mReadWriteLock, QgsReadWriteLocker::Read );
201
202 metadata += QStringLiteral( "<tr><td class=\"highlight\">" ) % tr( "Entity Type" ) % QStringLiteral( "</td><td>%1" ).arg( qgsEnumValueToKey( mSharedData->mEntityType ) ) % QStringLiteral( "</td></tr>\n" );
203 metadata += QStringLiteral( "<tr><td class=\"highlight\">" ) % tr( "Endpoint" ) % QStringLiteral( "</td><td><a href=\"%1\">%1</a>" ).arg( mSharedData->mEntityBaseUri ) % QStringLiteral( "</td></tr>\n" );
204
205 return metadata;
206}
207
208Qgis::DataProviderFlags QgsSensorThingsProvider::flags() const
209{
211
213}
214
215Qgis::VectorProviderCapabilities QgsSensorThingsProvider::capabilities() const
216{
218
222
223 return c;
224}
225
226bool QgsSensorThingsProvider::supportsSubsetString() const
227{
229 return true;
230}
231
232QString QgsSensorThingsProvider::subsetStringDialect() const
233{
234 return tr( "OGC SensorThings filter" );
235}
236
237QString QgsSensorThingsProvider::subsetStringHelpUrl() const
238{
239 return QStringLiteral( "https://docs.ogc.org/is/18-088/18-088.html#filter" );
240}
241
242QString QgsSensorThingsProvider::subsetString() const
243{
245 return mSharedData->subsetString();
246}
247
248bool QgsSensorThingsProvider::setSubsetString( const QString &subset, bool )
249{
251
252 const QString trimmedSubset = subset.trimmed();
253 if ( trimmedSubset == mSharedData->subsetString() )
254 return true;
255
256 // store this and restore it after the data source is changed,
257 // to avoid an unwanted network request to retrieve this again
258 const QString baseUri = mSharedData->mEntityBaseUri;
259
260 QgsDataSourceUri uri = dataSourceUri();
261 uri.setSql( trimmedSubset );
262 setDataSourceUri( uri.uri( false ) );
263
264 mSharedData->mEntityBaseUri = baseUri;
265
266 clearMinMaxCache();
267
268 emit dataChanged();
269
270 return true;
271}
272
273void QgsSensorThingsProvider::setDataSourceUri( const QString &uri )
274{
276
277 mSharedData = std::make_shared< QgsSensorThingsSharedData >( uri );
279}
280
281QgsCoordinateReferenceSystem QgsSensorThingsProvider::crs() const
282{
284
285 return mSharedData->mSourceCRS;
286}
287
288QgsRectangle QgsSensorThingsProvider::extent() const
289{
291 return mSharedData->extent();
292}
293
294QString QgsSensorThingsProvider::name() const
295{
297
298 return SENSORTHINGS_PROVIDER_KEY;
299}
300
301QString QgsSensorThingsProvider::providerKey()
302{
303 return SENSORTHINGS_PROVIDER_KEY;
304}
305
306void QgsSensorThingsProvider::handlePostCloneOperations( QgsVectorDataProvider *source )
307{
308 mSharedData = qobject_cast<QgsSensorThingsProvider *>( source )->mSharedData;
309}
310
311QString QgsSensorThingsProvider::description() const
312{
313 return SENSORTHINGS_PROVIDER_DESCRIPTION;
314}
315
316bool QgsSensorThingsProvider::renderInPreview( const PreviewContext & )
317{
318 // be nice to the endpoint and don't make any requests we don't have to!
319 return false;
320}
321
322void QgsSensorThingsProvider::reloadProviderData()
323{
324#if 0
325 mSharedData->clearCache();
326#endif
327}
328
329//
330// QgsSensorThingsProviderMetadata
331//
332
333QgsSensorThingsProviderMetadata::QgsSensorThingsProviderMetadata():
334 QgsProviderMetadata( QgsSensorThingsProvider::SENSORTHINGS_PROVIDER_KEY, QgsSensorThingsProvider::SENSORTHINGS_PROVIDER_DESCRIPTION )
335{
336}
337
338QIcon QgsSensorThingsProviderMetadata::icon() const
339{
340 return QgsApplication::getThemeIcon( QStringLiteral( "mIconSensorThings.svg" ) );
341}
342
343QList<QgsDataItemProvider *> QgsSensorThingsProviderMetadata::dataItemProviders() const
344{
345 return { new QgsSensorThingsDataItemProvider() };
346}
347
348QVariantMap QgsSensorThingsProviderMetadata::decodeUri( const QString &uri ) const
349{
350 const QgsDataSourceUri dsUri = QgsDataSourceUri( uri );
351
352 QVariantMap components;
353 components.insert( QStringLiteral( "url" ), dsUri.param( QStringLiteral( "url" ) ) );
354
355 if ( !dsUri.authConfigId().isEmpty() )
356 {
357 components.insert( QStringLiteral( "authcfg" ), dsUri.authConfigId() );
358 }
359 if ( !dsUri.username().isEmpty() )
360 {
361 components.insert( QStringLiteral( "username" ), dsUri.username() );
362 }
363 if ( !dsUri.password().isEmpty() )
364 {
365 components.insert( QStringLiteral( "password" ), dsUri.password() );
366 }
367
368 // there's two different ways the referer can be set, so we need to check both. Which way it has been
369 // set depends on the widget used to create the URI. It's messy, but QgsHttpHeaders has a bunch of logic in
370 // it to handle upgrading old referer handling for connections created before QgsHttpHeaders was invented,
371 // and if we rely on that entirely then we get multiple "referer" parameters included in the URI, which is
372 // both ugly and unnecessary for a provider created post QgsHttpHeaders.
373 if ( !dsUri.param( QStringLiteral( "referer" ) ).isEmpty() )
374 {
375 components.insert( QStringLiteral( "referer" ), dsUri.param( QStringLiteral( "referer" ) ) );
376 }
377 if ( !dsUri.param( QStringLiteral( "http-header:referer" ) ).isEmpty() )
378 {
379 components.insert( QStringLiteral( "referer" ), dsUri.param( QStringLiteral( "http-header:referer" ) ) );
380 }
381
382 const QString entityParam = dsUri.param( QStringLiteral( "entity" ) );
384 if ( entity == Qgis::SensorThingsEntity::Invalid )
385 entity = QgsSensorThingsUtils::stringToEntity( entityParam );
386
387 if ( entity != Qgis::SensorThingsEntity::Invalid )
388 components.insert( QStringLiteral( "entity" ), qgsEnumValueToKey( entity ) );
389
390 const QStringList expandToParam = dsUri.param( QStringLiteral( "expandTo" ) ).split( ';', Qt::SkipEmptyParts );
391 if ( !expandToParam.isEmpty() )
392 {
393 QVariantList expandParts;
394 for ( const QString &expandString : expandToParam )
395 {
397 if ( definition.isValid() )
398 {
399 expandParts.append( QVariant::fromValue( definition ) );
400 }
401 }
402 if ( !expandParts.isEmpty() )
403 {
404 components.insert( QStringLiteral( "expandTo" ), expandParts );
405 }
406 }
407
408 bool ok = false;
409 const int maxPageSizeParam = dsUri.param( QStringLiteral( "pageSize" ) ).toInt( &ok );
410 if ( ok )
411 {
412 components.insert( QStringLiteral( "pageSize" ), maxPageSizeParam );
413 }
414
415 ok = false;
416 const int featureLimitParam = dsUri.param( QStringLiteral( "featureLimit" ) ).toInt( &ok );
417 if ( ok )
418 {
419 components.insert( QStringLiteral( "featureLimit" ), featureLimitParam );
420 }
421
422 switch ( QgsWkbTypes::geometryType( dsUri.wkbType() ) )
423 {
425 if ( QgsWkbTypes::isMultiType( dsUri.wkbType() ) )
426 components.insert( QStringLiteral( "geometryType" ), QStringLiteral( "multipoint" ) );
427 else
428 components.insert( QStringLiteral( "geometryType" ), QStringLiteral( "point" ) );
429 break;
431 components.insert( QStringLiteral( "geometryType" ), QStringLiteral( "line" ) );
432 break;
434 components.insert( QStringLiteral( "geometryType" ), QStringLiteral( "polygon" ) );
435 break;
436
439 break;
440 }
441
442 const QStringList bbox = dsUri.param( QStringLiteral( "bbox" ) ).split( ',' );
443 if ( bbox.size() == 4 )
444 {
445 QgsRectangle r;
446 bool xminOk = false;
447 bool yminOk = false;
448 bool xmaxOk = false;
449 bool ymaxOk = false;
450 r.setXMinimum( bbox[0].toDouble( &xminOk ) );
451 r.setYMinimum( bbox[1].toDouble( &yminOk ) );
452 r.setXMaximum( bbox[2].toDouble( &xmaxOk ) );
453 r.setYMaximum( bbox[3].toDouble( &ymaxOk ) );
454 if ( xminOk && yminOk && xmaxOk && ymaxOk )
455 components.insert( QStringLiteral( "bounds" ), r );
456 }
457
458 if ( !dsUri.sql().isEmpty() )
459 components.insert( QStringLiteral( "sql" ), dsUri.sql() );
460
461 return components;
462}
463
464QString QgsSensorThingsProviderMetadata::encodeUri( const QVariantMap &parts ) const
465{
466 QgsDataSourceUri dsUri;
467 dsUri.setParam( QStringLiteral( "url" ), parts.value( QStringLiteral( "url" ) ).toString() );
468
469 if ( !parts.value( QStringLiteral( "authcfg" ) ).toString().isEmpty() )
470 {
471 dsUri.setAuthConfigId( parts.value( QStringLiteral( "authcfg" ) ).toString() );
472 }
473 if ( !parts.value( QStringLiteral( "username" ) ).toString().isEmpty() )
474 {
475 dsUri.setUsername( parts.value( QStringLiteral( "username" ) ).toString() );
476 }
477 if ( !parts.value( QStringLiteral( "password" ) ).toString().isEmpty() )
478 {
479 dsUri.setPassword( parts.value( QStringLiteral( "password" ) ).toString() );
480 }
481 if ( !parts.value( QStringLiteral( "referer" ) ).toString().isEmpty() )
482 {
483 dsUri.setParam( QStringLiteral( "referer" ), parts.value( QStringLiteral( "referer" ) ).toString() );
484 }
485
487 parts.value( QStringLiteral( "entity" ) ).toString() );
488 if ( entity == Qgis::SensorThingsEntity::Invalid )
489 entity = QgsSensorThingsUtils::stringToEntity( parts.value( QStringLiteral( "entity" ) ).toString() );
490
491 if ( entity != Qgis::SensorThingsEntity::Invalid )
492 {
493 dsUri.setParam( QStringLiteral( "entity" ),
494 qgsEnumValueToKey( entity ) );
495 }
496
497 const QVariantList expandToParam = parts.value( QStringLiteral( "expandTo" ) ).toList();
498 if ( !expandToParam.isEmpty() )
499 {
500 QStringList expandToStringList;
501 for ( const QVariant &expansion : expandToParam )
502 {
503 const QgsSensorThingsExpansionDefinition expansionDefinition = expansion.value< QgsSensorThingsExpansionDefinition >();
504 if ( !expansionDefinition.isValid() )
505 continue;
506
507 expandToStringList.append( expansionDefinition.toString() );
508 }
509 if ( !expandToStringList.isEmpty() )
510 {
511 dsUri.setParam( QStringLiteral( "expandTo" ), expandToStringList.join( ';' ) );
512 }
513 }
514
515 bool ok = false;
516 const int maxPageSizeParam = parts.value( QStringLiteral( "pageSize" ) ).toInt( &ok );
517 if ( ok )
518 {
519 dsUri.setParam( QStringLiteral( "pageSize" ), QString::number( maxPageSizeParam ) );
520 }
521
522 ok = false;
523 const int featureLimitParam = parts.value( QStringLiteral( "featureLimit" ) ).toInt( &ok );
524 if ( ok )
525 {
526 dsUri.setParam( QStringLiteral( "featureLimit" ), QString::number( featureLimitParam ) );
527 }
528
529 const QString geometryType = parts.value( QStringLiteral( "geometryType" ) ).toString();
530 if ( geometryType.compare( QLatin1String( "point" ), Qt::CaseInsensitive ) == 0 )
531 {
533 }
534 else if ( geometryType.compare( QLatin1String( "multipoint" ), Qt::CaseInsensitive ) == 0 )
535 {
537 }
538 else if ( geometryType.compare( QLatin1String( "line" ), Qt::CaseInsensitive ) == 0 )
539 {
541 }
542 else if ( geometryType.compare( QLatin1String( "polygon" ), Qt::CaseInsensitive ) == 0 )
543 {
545 }
546
547 if ( parts.contains( QStringLiteral( "bounds" ) ) && parts.value( QStringLiteral( "bounds" ) ).userType() == qMetaTypeId<QgsRectangle>() )
548 {
549 const QgsRectangle bBox = parts.value( QStringLiteral( "bounds" ) ).value< QgsRectangle >();
550 dsUri.setParam( QStringLiteral( "bbox" ), QStringLiteral( "%1,%2,%3,%4" ).arg( bBox.xMinimum() ).arg( bBox.yMinimum() ).arg( bBox.xMaximum() ).arg( bBox.yMaximum() ) );
551 }
552
553 if ( !parts.value( QStringLiteral( "sql" ) ).toString().isEmpty() )
554 dsUri.setSql( parts.value( QStringLiteral( "sql" ) ).toString() );
555
556 return dsUri.uri( false );
557}
558
559QgsSensorThingsProvider *QgsSensorThingsProviderMetadata::createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, Qgis::DataProviderReadFlags flags )
560{
561 return new QgsSensorThingsProvider( uri, options, flags );
562}
563
564QList<Qgis::LayerType> QgsSensorThingsProviderMetadata::supportedLayerTypes() const
565{
566 return { Qgis::LayerType::Vector };
567}
568
569QMap<QString, QgsAbstractProviderConnection *> QgsSensorThingsProviderMetadata::connections( bool cached )
570{
571 return connectionsProtected<QgsSensorThingsProviderConnection, QgsSensorThingsProviderConnection>( cached );
572}
573
574QgsAbstractProviderConnection *QgsSensorThingsProviderMetadata::createConnection( const QString &name )
575{
576 return new QgsSensorThingsProviderConnection( name );
577}
578
579void QgsSensorThingsProviderMetadata::deleteConnection( const QString &name )
580{
581 deleteConnectionProtected<QgsSensorThingsProviderConnection>( name );
582}
583
584void QgsSensorThingsProviderMetadata::saveConnection( const QgsAbstractProviderConnection *connection, const QString &name )
585{
586 saveConnectionProtected( connection, name );
587}
588
@ SelectAtId
Fast access to features using their ID.
@ ReloadData
Provider is able to force reload data.
@ ReadLayerMetadata
Provider can read layer metadata from data store. Since QGIS 3.0. See QgsDataProvider::layerMetadata(...
QFlags< DataProviderFlag > DataProviderFlags
Data provider flags.
Definition qgis.h:2147
@ FastExtent2D
Provider's 2D extent retrieval via QgsDataProvider::extent() is always guaranteed to be trivial/fast ...
SensorThingsEntity
OGC SensorThings API entity types.
Definition qgis.h:5493
@ Sensor
A Sensor is an instrument that observes a property or phenomenon with the goal of producing an estima...
@ MultiDatastream
A MultiDatastream groups a collection of Observations and the Observations in a MultiDatastream have ...
@ ObservedProperty
An ObservedProperty specifies the phenomenon of an Observation.
@ Invalid
An invalid/unknown entity.
@ FeatureOfInterest
In the context of the Internet of Things, many Observations’ FeatureOfInterest can be the Location of...
@ Datastream
A Datastream groups a collection of Observations measuring the same ObservedProperty and produced by ...
@ Observation
An Observation is the act of measuring or otherwise determining the value of a property.
@ Location
A Location entity locates the Thing or the Things it associated with. A Thing’s Location entity is de...
@ Thing
A Thing is an object of the physical world (physical things) or the information world (virtual things...
@ HistoricalLocation
A Thing’s HistoricalLocation entity set provides the times of the current (i.e., last known) and prev...
@ Polygon
Polygons.
@ Unknown
Unknown types.
@ Null
No geometry.
QFlags< DataProviderReadFlag > DataProviderReadFlags
Flags which control data provider construction.
Definition qgis.h:450
QFlags< VectorProviderCapability > VectorProviderCapabilities
Vector data provider capabilities.
Definition qgis.h:500
@ Vector
Vector layer.
@ SkipFeatureCount
Make featureCount() return -1 to indicate unknown, and subLayers() to return a unknown feature count ...
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:256
@ MultiPointZ
MultiPointZ.
@ PointZ
PointZ.
@ MultiLineStringZ
MultiLineStringZ.
@ MultiPolygonZ
MultiPolygonZ.
Base class that can be used for any class that is capable of returning features.
The QgsAbstractProviderConnection provides 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...
QString errorMessage() const
Returns the error message string, after a get(), post(), head() or put() request has been made.
@ 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...
This class represents a coordinate reference system (CRS).
virtual void setDataSourceUri(const QString &uri)
Set the data source specification.
Class for storing the component parts of a RDBMS 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.
QgsErrorMessage represents single error message.
Definition qgserror.h:33
Wrapper for iterator of features from vector data provider or vector layer.
This class 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)
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...
The QgsReadWriteLocker class is a convenience class that simplifies locking and unlocking QReadWriteL...
A rectangle specified with double values.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
void setYMinimum(double y)
Set the minimum y value.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
void setXMinimum(double x)
Set the minimum x value.
double xMaximum() const
Returns the x maximum value (right side of rectangle).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
void setYMaximum(double y)
Set the maximum y value.
void setXMaximum(double x)
Set the maximum x value.
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...
This is the 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 bool isMultiType(Qgis::WkbType type)
Returns true if the WKB type is a multi type.
@ UnknownCount
Provider returned an unknown feature count.
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:6048
#define QgsSetRequestInitiatorClass(request, _class)
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
Setting options for creating vector data providers.