QGIS API Documentation 3.41.0-Master (af5edcb665c)
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#include "moc_qgssensorthingsprovider.cpp"
21#include "qgsapplication.h"
24#include "qgsthreadingutils.h"
25#include "qgsreadwritelocker.h"
29#include "qgsmessagelog.h"
30
31#include <QIcon>
32#include <QNetworkRequest>
33#include <nlohmann/json.hpp>
34
36
37QgsSensorThingsProvider::QgsSensorThingsProvider( const QString &uri, const ProviderOptions &options, Qgis::DataProviderReadFlags flags )
38 : QgsVectorDataProvider( uri, options, flags )
39{
40 mSharedData = std::make_shared< QgsSensorThingsSharedData >( uri );
41
42 const QUrl url( QgsSensorThingsSharedData::parseUrl( mSharedData->mRootUri ) );
43
44 QNetworkRequest request = QNetworkRequest( url );
45 QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsSensorThingsProvider" ) )
46 mSharedData->mHeaders.updateNetworkRequest( request );
47
48 QgsBlockingNetworkRequest networkRequest;
49 networkRequest.setAuthCfg( mSharedData->mAuthCfg );
50
51 switch ( networkRequest.get( request ) )
52 {
54 break;
55
59 appendError( QgsErrorMessage( tr( "Connection failed: %1" ).arg( networkRequest.errorMessage() ), QStringLiteral( "SensorThings" ) ) );
60 return;
61 }
62
63 const QgsNetworkReplyContent content = networkRequest.reply();
64
65 try
66 {
67 auto rootContent = json::parse( content.content().toStdString() );
68 if ( !rootContent.contains( "value" ) )
69 {
70 appendError( QgsErrorMessage( tr( "No 'value' array in response" ), QStringLiteral( "SensorThings" ) ) );
71 return;
72 }
73
74 bool foundMatchingEntity = false;
75 for ( const auto &valueJson : rootContent["value"] )
76 {
77 if ( valueJson.contains( "name" ) && valueJson.contains( "url" ) )
78 {
79 const QString name = QString::fromStdString( valueJson["name"].get<std::string>() );
81 if ( entityType == mSharedData->mEntityType )
82 {
83 const QString url = QString::fromStdString( valueJson["url"].get<std::string>() );
84 if ( !url.isEmpty() )
85 {
86 foundMatchingEntity = true;
87 mSharedData->mEntityBaseUri = url;
88
89 // TODO:
90 // if we always retrieve feature count, is that less expensive then deferring this till we need it?
91 // by retrieving upfront, we can save a lot of requests where we've fetched features from spatial extents
92 // as we'll have a way of determining whether we've fetched all features from the source. Otherwise
93 // we never know if we've got everything yet, and are forced to re-fetched everything when a non-filtered request
94 // comes in...
95 ( void ) mSharedData->featureCount();
96 }
97 }
98 }
99 }
100
101 if ( !foundMatchingEntity )
102 {
103 switch ( mSharedData->mEntityType )
104 {
105
115 appendError( QgsErrorMessage( tr( "Could not find url for %1" ).arg( qgsEnumValueToKey( mSharedData->mEntityType ) ), QStringLiteral( "SensorThings" ) ) );
116 QgsMessageLog::logMessage( tr( "Could not find url for %1" ).arg( qgsEnumValueToKey( mSharedData->mEntityType ) ), tr( "SensorThings" ) );
117 break;
118
120 appendError( QgsErrorMessage( tr( "MultiDatastreams are not supported by this connection" ), QStringLiteral( "SensorThings" ) ) );
121 QgsMessageLog::logMessage( tr( "MultiDatastreams are not supported by this connection" ), tr( "SensorThings" ) );
122 break;
123 }
124
125 return;
126 }
127 }
128 catch ( const json::parse_error &ex )
129 {
130 appendError( QgsErrorMessage( tr( "Error parsing response: %1" ).arg( ex.what() ), QStringLiteral( "SensorThings" ) ) );
131 return;
132 }
133
134 mValid = true;
135}
136
137QString QgsSensorThingsProvider::storageType() const
138{
140
141 return QStringLiteral( "OGC SensorThings API" );
142}
143
144QgsAbstractFeatureSource *QgsSensorThingsProvider::featureSource() const
145{
147
148 return new QgsSensorThingsFeatureSource( mSharedData );
149}
150
151QgsFeatureIterator QgsSensorThingsProvider::getFeatures( const QgsFeatureRequest &request ) const
152{
154
155 return new QgsSensorThingsFeatureIterator( new QgsSensorThingsFeatureSource( mSharedData ), true, request );
156}
157
158Qgis::WkbType QgsSensorThingsProvider::wkbType() const
159{
161
162 return mSharedData->mGeometryType;
163}
164
165long long QgsSensorThingsProvider::featureCount() const
166{
168
169 if ( ( mReadFlags & Qgis::DataProviderReadFlag::SkipFeatureCount ) != 0 )
170 {
171 return static_cast< long long >( Qgis::FeatureCountState::UnknownCount );
172 }
173
174 const long long count = mSharedData->featureCount();
175 if ( !mSharedData->error().isEmpty() )
176 pushError( mSharedData->error() );
177
178 return count;
179}
180
181QgsFields QgsSensorThingsProvider::fields() const
182{
184
185 return mSharedData->mFields;
186}
187
188QgsLayerMetadata QgsSensorThingsProvider::layerMetadata() const
189{
191
192 return mLayerMetadata;
193}
194
195QString QgsSensorThingsProvider::htmlMetadata() const
196{
198
199 QString metadata;
200
201 QgsReadWriteLocker locker( mSharedData->mReadWriteLock, QgsReadWriteLocker::Read );
202
203 metadata += QStringLiteral( "<tr><td class=\"highlight\">" ) % tr( "Entity Type" ) % QStringLiteral( "</td><td>%1" ).arg( qgsEnumValueToKey( mSharedData->mEntityType ) ) % QStringLiteral( "</td></tr>\n" );
204 metadata += QStringLiteral( "<tr><td class=\"highlight\">" ) % tr( "Endpoint" ) % QStringLiteral( "</td><td><a href=\"%1\">%1</a>" ).arg( mSharedData->mEntityBaseUri ) % QStringLiteral( "</td></tr>\n" );
205
206 return metadata;
207}
208
209Qgis::DataProviderFlags QgsSensorThingsProvider::flags() const
210{
212
214}
215
216Qgis::VectorProviderCapabilities QgsSensorThingsProvider::capabilities() const
217{
219
223
224 return c;
225}
226
227bool QgsSensorThingsProvider::supportsSubsetString() const
228{
230 return true;
231}
232
233QString QgsSensorThingsProvider::subsetStringDialect() const
234{
235 return tr( "OGC SensorThings filter" );
236}
237
238QString QgsSensorThingsProvider::subsetStringHelpUrl() const
239{
240 return QStringLiteral( "https://docs.ogc.org/is/18-088/18-088.html#filter" );
241}
242
243QString QgsSensorThingsProvider::subsetString() const
244{
246 return mSharedData->subsetString();
247}
248
249bool QgsSensorThingsProvider::setSubsetString( const QString &subset, bool )
250{
252
253 const QString trimmedSubset = subset.trimmed();
254 if ( trimmedSubset == mSharedData->subsetString() )
255 return true;
256
257 // store this and restore it after the data source is changed,
258 // to avoid an unwanted network request to retrieve this again
259 const QString baseUri = mSharedData->mEntityBaseUri;
260
261 QgsDataSourceUri uri = dataSourceUri();
262 uri.setSql( trimmedSubset );
263 setDataSourceUri( uri.uri( false ) );
264
265 mSharedData->mEntityBaseUri = baseUri;
266
267 clearMinMaxCache();
268
269 emit dataChanged();
270
271 return true;
272}
273
274void QgsSensorThingsProvider::setDataSourceUri( const QString &uri )
275{
277
278 mSharedData = std::make_shared< QgsSensorThingsSharedData >( uri );
280}
281
282QgsCoordinateReferenceSystem QgsSensorThingsProvider::crs() const
283{
285
286 return mSharedData->mSourceCRS;
287}
288
289QgsRectangle QgsSensorThingsProvider::extent() const
290{
292 return mSharedData->extent();
293}
294
295QString QgsSensorThingsProvider::name() const
296{
298
299 return SENSORTHINGS_PROVIDER_KEY;
300}
301
302QString QgsSensorThingsProvider::providerKey()
303{
304 return SENSORTHINGS_PROVIDER_KEY;
305}
306
307void QgsSensorThingsProvider::handlePostCloneOperations( QgsVectorDataProvider *source )
308{
309 mSharedData = qobject_cast<QgsSensorThingsProvider *>( source )->mSharedData;
310}
311
312QString QgsSensorThingsProvider::description() const
313{
314 return SENSORTHINGS_PROVIDER_DESCRIPTION;
315}
316
317bool QgsSensorThingsProvider::renderInPreview( const PreviewContext & )
318{
319 // be nice to the endpoint and don't make any requests we don't have to!
320 return false;
321}
322
323void QgsSensorThingsProvider::reloadProviderData()
324{
325#if 0
326 mSharedData->clearCache();
327#endif
328}
329
330//
331// QgsSensorThingsProviderMetadata
332//
333
334QgsSensorThingsProviderMetadata::QgsSensorThingsProviderMetadata():
335 QgsProviderMetadata( QgsSensorThingsProvider::SENSORTHINGS_PROVIDER_KEY, QgsSensorThingsProvider::SENSORTHINGS_PROVIDER_DESCRIPTION )
336{
337}
338
339QIcon QgsSensorThingsProviderMetadata::icon() const
340{
341 return QgsApplication::getThemeIcon( QStringLiteral( "mIconSensorThings.svg" ) );
342}
343
344QList<QgsDataItemProvider *> QgsSensorThingsProviderMetadata::dataItemProviders() const
345{
346 return { new QgsSensorThingsDataItemProvider() };
347}
348
349QVariantMap QgsSensorThingsProviderMetadata::decodeUri( const QString &uri ) const
350{
351 const QgsDataSourceUri dsUri = QgsDataSourceUri( uri );
352
353 QVariantMap components;
354 components.insert( QStringLiteral( "url" ), dsUri.param( QStringLiteral( "url" ) ) );
355
356 if ( !dsUri.authConfigId().isEmpty() )
357 {
358 components.insert( QStringLiteral( "authcfg" ), dsUri.authConfigId() );
359 }
360 if ( !dsUri.username().isEmpty() )
361 {
362 components.insert( QStringLiteral( "username" ), dsUri.username() );
363 }
364 if ( !dsUri.password().isEmpty() )
365 {
366 components.insert( QStringLiteral( "password" ), dsUri.password() );
367 }
368
369 // there's two different ways the referer can be set, so we need to check both. Which way it has been
370 // set depends on the widget used to create the URI. It's messy, but QgsHttpHeaders has a bunch of logic in
371 // it to handle upgrading old referer handling for connections created before QgsHttpHeaders was invented,
372 // and if we rely on that entirely then we get multiple "referer" parameters included in the URI, which is
373 // both ugly and unnecessary for a provider created post QgsHttpHeaders.
374 if ( !dsUri.param( QStringLiteral( "referer" ) ).isEmpty() )
375 {
376 components.insert( QStringLiteral( "referer" ), dsUri.param( QStringLiteral( "referer" ) ) );
377 }
378 if ( !dsUri.param( QStringLiteral( "http-header:referer" ) ).isEmpty() )
379 {
380 components.insert( QStringLiteral( "referer" ), dsUri.param( QStringLiteral( "http-header:referer" ) ) );
381 }
382
383 const QString entityParam = dsUri.param( QStringLiteral( "entity" ) );
385 if ( entity == Qgis::SensorThingsEntity::Invalid )
386 entity = QgsSensorThingsUtils::stringToEntity( entityParam );
387
388 if ( entity != Qgis::SensorThingsEntity::Invalid )
389 components.insert( QStringLiteral( "entity" ), qgsEnumValueToKey( entity ) );
390
391 const QStringList expandToParam = dsUri.param( QStringLiteral( "expandTo" ) ).split( ';', Qt::SkipEmptyParts );
392 if ( !expandToParam.isEmpty() )
393 {
394 QVariantList expandParts;
395 for ( const QString &expandString : expandToParam )
396 {
398 if ( definition.isValid() )
399 {
400 expandParts.append( QVariant::fromValue( definition ) );
401 }
402 }
403 if ( !expandParts.isEmpty() )
404 {
405 components.insert( QStringLiteral( "expandTo" ), expandParts );
406 }
407 }
408
409 bool ok = false;
410 const int maxPageSizeParam = dsUri.param( QStringLiteral( "pageSize" ) ).toInt( &ok );
411 if ( ok )
412 {
413 components.insert( QStringLiteral( "pageSize" ), maxPageSizeParam );
414 }
415
416 ok = false;
417 const int featureLimitParam = dsUri.param( QStringLiteral( "featureLimit" ) ).toInt( &ok );
418 if ( ok )
419 {
420 components.insert( QStringLiteral( "featureLimit" ), featureLimitParam );
421 }
422
423 switch ( QgsWkbTypes::geometryType( dsUri.wkbType() ) )
424 {
426 if ( QgsWkbTypes::isMultiType( dsUri.wkbType() ) )
427 components.insert( QStringLiteral( "geometryType" ), QStringLiteral( "multipoint" ) );
428 else
429 components.insert( QStringLiteral( "geometryType" ), QStringLiteral( "point" ) );
430 break;
432 components.insert( QStringLiteral( "geometryType" ), QStringLiteral( "line" ) );
433 break;
435 components.insert( QStringLiteral( "geometryType" ), QStringLiteral( "polygon" ) );
436 break;
437
440 break;
441 }
442
443 const QStringList bbox = dsUri.param( QStringLiteral( "bbox" ) ).split( ',' );
444 if ( bbox.size() == 4 )
445 {
446 QgsRectangle r;
447 bool xminOk = false;
448 bool yminOk = false;
449 bool xmaxOk = false;
450 bool ymaxOk = false;
451 r.setXMinimum( bbox[0].toDouble( &xminOk ) );
452 r.setYMinimum( bbox[1].toDouble( &yminOk ) );
453 r.setXMaximum( bbox[2].toDouble( &xmaxOk ) );
454 r.setYMaximum( bbox[3].toDouble( &ymaxOk ) );
455 if ( xminOk && yminOk && xmaxOk && ymaxOk )
456 components.insert( QStringLiteral( "bounds" ), r );
457 }
458
459 if ( !dsUri.sql().isEmpty() )
460 components.insert( QStringLiteral( "sql" ), dsUri.sql() );
461
462 return components;
463}
464
465QString QgsSensorThingsProviderMetadata::encodeUri( const QVariantMap &parts ) const
466{
467 QgsDataSourceUri dsUri;
468 dsUri.setParam( QStringLiteral( "url" ), parts.value( QStringLiteral( "url" ) ).toString() );
469
470 if ( !parts.value( QStringLiteral( "authcfg" ) ).toString().isEmpty() )
471 {
472 dsUri.setAuthConfigId( parts.value( QStringLiteral( "authcfg" ) ).toString() );
473 }
474 if ( !parts.value( QStringLiteral( "username" ) ).toString().isEmpty() )
475 {
476 dsUri.setUsername( parts.value( QStringLiteral( "username" ) ).toString() );
477 }
478 if ( !parts.value( QStringLiteral( "password" ) ).toString().isEmpty() )
479 {
480 dsUri.setPassword( parts.value( QStringLiteral( "password" ) ).toString() );
481 }
482 if ( !parts.value( QStringLiteral( "referer" ) ).toString().isEmpty() )
483 {
484 dsUri.setParam( QStringLiteral( "referer" ), parts.value( QStringLiteral( "referer" ) ).toString() );
485 }
486
488 parts.value( QStringLiteral( "entity" ) ).toString() );
489 if ( entity == Qgis::SensorThingsEntity::Invalid )
490 entity = QgsSensorThingsUtils::stringToEntity( parts.value( QStringLiteral( "entity" ) ).toString() );
491
492 if ( entity != Qgis::SensorThingsEntity::Invalid )
493 {
494 dsUri.setParam( QStringLiteral( "entity" ),
495 qgsEnumValueToKey( entity ) );
496 }
497
498 const QVariantList expandToParam = parts.value( QStringLiteral( "expandTo" ) ).toList();
499 if ( !expandToParam.isEmpty() )
500 {
501 QStringList expandToStringList;
502 for ( const QVariant &expansion : expandToParam )
503 {
504 const QgsSensorThingsExpansionDefinition expansionDefinition = expansion.value< QgsSensorThingsExpansionDefinition >();
505 if ( !expansionDefinition.isValid() )
506 continue;
507
508 expandToStringList.append( expansionDefinition.toString() );
509 }
510 if ( !expandToStringList.isEmpty() )
511 {
512 dsUri.setParam( QStringLiteral( "expandTo" ), expandToStringList.join( ';' ) );
513 }
514 }
515
516 bool ok = false;
517 const int maxPageSizeParam = parts.value( QStringLiteral( "pageSize" ) ).toInt( &ok );
518 if ( ok )
519 {
520 dsUri.setParam( QStringLiteral( "pageSize" ), QString::number( maxPageSizeParam ) );
521 }
522
523 ok = false;
524 const int featureLimitParam = parts.value( QStringLiteral( "featureLimit" ) ).toInt( &ok );
525 if ( ok )
526 {
527 dsUri.setParam( QStringLiteral( "featureLimit" ), QString::number( featureLimitParam ) );
528 }
529
530 const QString geometryType = parts.value( QStringLiteral( "geometryType" ) ).toString();
531 if ( geometryType.compare( QLatin1String( "point" ), Qt::CaseInsensitive ) == 0 )
532 {
534 }
535 else if ( geometryType.compare( QLatin1String( "multipoint" ), Qt::CaseInsensitive ) == 0 )
536 {
538 }
539 else if ( geometryType.compare( QLatin1String( "line" ), Qt::CaseInsensitive ) == 0 )
540 {
542 }
543 else if ( geometryType.compare( QLatin1String( "polygon" ), Qt::CaseInsensitive ) == 0 )
544 {
546 }
547
548 if ( parts.contains( QStringLiteral( "bounds" ) ) && parts.value( QStringLiteral( "bounds" ) ).userType() == qMetaTypeId<QgsRectangle>() )
549 {
550 const QgsRectangle bBox = parts.value( QStringLiteral( "bounds" ) ).value< QgsRectangle >();
551 dsUri.setParam( QStringLiteral( "bbox" ), QStringLiteral( "%1,%2,%3,%4" ).arg( bBox.xMinimum() ).arg( bBox.yMinimum() ).arg( bBox.xMaximum() ).arg( bBox.yMaximum() ) );
552 }
553
554 if ( !parts.value( QStringLiteral( "sql" ) ).toString().isEmpty() )
555 dsUri.setSql( parts.value( QStringLiteral( "sql" ) ).toString() );
556
557 return dsUri.uri( false );
558}
559
560QgsSensorThingsProvider *QgsSensorThingsProviderMetadata::createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, Qgis::DataProviderReadFlags flags )
561{
562 return new QgsSensorThingsProvider( uri, options, flags );
563}
564
565QList<Qgis::LayerType> QgsSensorThingsProviderMetadata::supportedLayerTypes() const
566{
567 return { Qgis::LayerType::Vector };
568}
569
570QMap<QString, QgsAbstractProviderConnection *> QgsSensorThingsProviderMetadata::connections( bool cached )
571{
572 return connectionsProtected<QgsSensorThingsProviderConnection, QgsSensorThingsProviderConnection>( cached );
573}
574
575QgsAbstractProviderConnection *QgsSensorThingsProviderMetadata::createConnection( const QString &name )
576{
577 return new QgsSensorThingsProviderConnection( name );
578}
579
580void QgsSensorThingsProviderMetadata::deleteConnection( const QString &name )
581{
582 deleteConnectionProtected<QgsSensorThingsProviderConnection>( name );
583}
584
585void QgsSensorThingsProviderMetadata::saveConnection( const QgsAbstractProviderConnection *connection, const QString &name )
586{
587 saveConnectionProtected( connection, name );
588}
589
@ 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:2210
@ 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:5627
@ 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
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...
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:6257
#define QgsSetRequestInitiatorClass(request, _class)
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
Setting options for creating vector data providers.