QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
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 ) mSharedData->mHeaders.updateNetworkRequest( request );
52
53 QgsBlockingNetworkRequest networkRequest;
54 networkRequest.setAuthCfg( mSharedData->mAuthCfg );
55
56 switch ( networkRequest.get( request ) )
57 {
59 break;
60
64 appendError( QgsErrorMessage( tr( "Connection failed: %1" ).arg( networkRequest.errorMessage() ), u"SensorThings"_s ) );
65 return;
66 }
67
68 const QgsNetworkReplyContent content = networkRequest.reply();
69
70 try
71 {
72 auto rootContent = json::parse( content.content().toStdString() );
73 if ( !rootContent.contains( "value" ) )
74 {
75 appendError( QgsErrorMessage( tr( "No 'value' array in response" ), u"SensorThings"_s ) );
76 return;
77 }
78
79 bool foundMatchingEntity = false;
80 for ( const auto &valueJson : rootContent["value"] )
81 {
82 if ( valueJson.contains( "name" ) && valueJson.contains( "url" ) )
83 {
84 const QString name = QString::fromStdString( valueJson["name"].get<std::string>() );
86 if ( entityType == mSharedData->mEntityType )
87 {
88 const QString url = QString::fromStdString( valueJson["url"].get<std::string>() );
89 if ( !url.isEmpty() )
90 {
91 foundMatchingEntity = true;
92 mSharedData->mEntityBaseUri = url;
93
94 // TODO:
95 // if we always retrieve feature count, is that less expensive then deferring this till we need it?
96 // by retrieving upfront, we can save a lot of requests where we've fetched features from spatial extents
97 // as we'll have a way of determining whether we've fetched all features from the source. Otherwise
98 // we never know if we've got everything yet, and are forced to re-fetched everything when a non-filtered request
99 // comes in...
100 ( void ) mSharedData->featureCount();
101 }
102 }
103 }
104 }
105
106 if ( !foundMatchingEntity )
107 {
108 switch ( mSharedData->mEntityType )
109 {
119 appendError( QgsErrorMessage( tr( "Could not find url for %1" ).arg( qgsEnumValueToKey( mSharedData->mEntityType ) ), u"SensorThings"_s ) );
120 QgsMessageLog::logMessage( tr( "Could not find url for %1" ).arg( qgsEnumValueToKey( mSharedData->mEntityType ) ), tr( "SensorThings" ) );
121 break;
122
124 appendError( QgsErrorMessage( tr( "MultiDatastreams are not supported by this connection" ), u"SensorThings"_s ) );
125 QgsMessageLog::logMessage( tr( "MultiDatastreams are not supported by this connection" ), tr( "SensorThings" ) );
126 break;
127 }
128
129 return;
130 }
131 }
132 catch ( const json::parse_error &ex )
133 {
134 appendError( QgsErrorMessage( tr( "Error parsing response: %1" ).arg( ex.what() ), u"SensorThings"_s ) );
135 return;
136 }
137
138 mValid = true;
139}
140
141QString QgsSensorThingsProvider::storageType() const
142{
144
145 return u"OGC SensorThings API"_s;
146}
147
148QgsAbstractFeatureSource *QgsSensorThingsProvider::featureSource() const
149{
151
152 return new QgsSensorThingsFeatureSource( mSharedData );
153}
154
155QgsFeatureIterator QgsSensorThingsProvider::getFeatures( const QgsFeatureRequest &request ) const
156{
158
159 return new QgsSensorThingsFeatureIterator( new QgsSensorThingsFeatureSource( mSharedData ), true, request );
160}
161
162Qgis::WkbType QgsSensorThingsProvider::wkbType() const
163{
165
166 return mSharedData->mGeometryType;
167}
168
169long long QgsSensorThingsProvider::featureCount() const
170{
172
173 if ( ( mReadFlags & Qgis::DataProviderReadFlag::SkipFeatureCount ) != 0 )
174 {
175 return static_cast< long long >( Qgis::FeatureCountState::UnknownCount );
176 }
177
178 const long long count = mSharedData->featureCount();
179 if ( !mSharedData->error().isEmpty() )
180 pushError( mSharedData->error() );
181
182 return count;
183}
184
185QgsFields QgsSensorThingsProvider::fields() const
186{
188
189 return mSharedData->mFields;
190}
191
192QgsLayerMetadata QgsSensorThingsProvider::layerMetadata() const
193{
195
196 return mLayerMetadata;
197}
198
199QString QgsSensorThingsProvider::htmlMetadata() const
200{
202
203 QString metadata;
204
205 QgsReadWriteLocker locker( mSharedData->mReadWriteLock, QgsReadWriteLocker::Read );
206
207 metadata += u"<tr><td class=\"highlight\">"_s % tr( "Entity Type" ) % u"</td><td>%1"_s.arg( qgsEnumValueToKey( mSharedData->mEntityType ) ) % u"</td></tr>\n"_s;
208 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;
209
210 return metadata;
211}
212
213Qgis::DataProviderFlags QgsSensorThingsProvider::flags() const
214{
216
218}
219
220Qgis::VectorProviderCapabilities QgsSensorThingsProvider::capabilities() const
221{
223
225
226 return c;
227}
228
229bool QgsSensorThingsProvider::supportsSubsetString() const
230{
232 return true;
233}
234
235QString QgsSensorThingsProvider::subsetStringDialect() const
236{
237 return tr( "OGC SensorThings filter" );
238}
239
240QString QgsSensorThingsProvider::subsetStringHelpUrl() const
241{
242 return u"https://docs.ogc.org/is/18-088/18-088.html#filter"_s;
243}
244
245QString QgsSensorThingsProvider::subsetString() const
246{
248 return mSharedData->subsetString();
249}
250
251bool QgsSensorThingsProvider::setSubsetString( const QString &subset, bool )
252{
254
255 const QString trimmedSubset = subset.trimmed();
256 if ( trimmedSubset == mSharedData->subsetString() )
257 return true;
258
259 // store this and restore it after the data source is changed,
260 // to avoid an unwanted network request to retrieve this again
261 const QString baseUri = mSharedData->mEntityBaseUri;
262
263 QgsDataSourceUri uri = dataSourceUri();
264 uri.setSql( trimmedSubset );
265 setDataSourceUri( uri.uri( false ) );
266
267 mSharedData->mEntityBaseUri = baseUri;
268
269 clearMinMaxCache();
270
271 emit dataChanged();
272
273 return true;
274}
275
276void QgsSensorThingsProvider::setDataSourceUri( const QString &uri )
277{
279
280 mSharedData = std::make_shared< QgsSensorThingsSharedData >( uri );
282}
283
284QgsCoordinateReferenceSystem QgsSensorThingsProvider::crs() const
285{
287
288 return mSharedData->mSourceCRS;
289}
290
291QgsRectangle QgsSensorThingsProvider::extent() const
292{
294 return mSharedData->extent();
295}
296
297QString QgsSensorThingsProvider::name() const
298{
300
301 return SENSORTHINGS_PROVIDER_KEY;
302}
303
304QString QgsSensorThingsProvider::providerKey()
305{
306 return SENSORTHINGS_PROVIDER_KEY;
307}
308
309void QgsSensorThingsProvider::handlePostCloneOperations( QgsVectorDataProvider *source )
310{
311 mSharedData = qobject_cast<QgsSensorThingsProvider *>( source )->mSharedData;
312}
313
314QString QgsSensorThingsProvider::description() const
315{
316 return SENSORTHINGS_PROVIDER_DESCRIPTION;
317}
318
319bool QgsSensorThingsProvider::renderInPreview( const PreviewContext & )
320{
321 // be nice to the endpoint and don't make any requests we don't have to!
322 return false;
323}
324
325void QgsSensorThingsProvider::reloadProviderData()
326{
327#if 0
328 mSharedData->clearCache();
329#endif
330}
331
332//
333// QgsSensorThingsProviderMetadata
334//
335
336QgsSensorThingsProviderMetadata::QgsSensorThingsProviderMetadata()
337 : QgsProviderMetadata( QgsSensorThingsProvider::SENSORTHINGS_PROVIDER_KEY, QgsSensorThingsProvider::SENSORTHINGS_PROVIDER_DESCRIPTION )
338{}
339
340QIcon QgsSensorThingsProviderMetadata::icon() const
341{
342 return QgsApplication::getThemeIcon( u"mIconSensorThings.svg"_s );
343}
344
345QList<QgsDataItemProvider *> QgsSensorThingsProviderMetadata::dataItemProviders() const
346{
347 return { new QgsSensorThingsDataItemProvider() };
348}
349
350QVariantMap QgsSensorThingsProviderMetadata::decodeUri( const QString &uri ) const
351{
352 const QgsDataSourceUri dsUri = QgsDataSourceUri( uri );
353
354 QVariantMap components;
355 components.insert( u"url"_s, dsUri.param( u"url"_s ) );
356
357 if ( !dsUri.authConfigId().isEmpty() )
358 {
359 components.insert( u"authcfg"_s, dsUri.authConfigId() );
360 }
361 if ( !dsUri.username().isEmpty() )
362 {
363 components.insert( u"username"_s, dsUri.username() );
364 }
365 if ( !dsUri.password().isEmpty() )
366 {
367 components.insert( u"password"_s, dsUri.password() );
368 }
369
370 // there's two different ways the referer can be set, so we need to check both. Which way it has been
371 // set depends on the widget used to create the URI. It's messy, but QgsHttpHeaders has a bunch of logic in
372 // it to handle upgrading old referer handling for connections created before QgsHttpHeaders was invented,
373 // and if we rely on that entirely then we get multiple "referer" parameters included in the URI, which is
374 // both ugly and unnecessary for a provider created post QgsHttpHeaders.
375 if ( !dsUri.param( u"referer"_s ).isEmpty() )
376 {
377 components.insert( u"referer"_s, dsUri.param( u"referer"_s ) );
378 }
379 if ( !dsUri.param( u"http-header:referer"_s ).isEmpty() )
380 {
381 components.insert( u"referer"_s, dsUri.param( u"http-header:referer"_s ) );
382 }
383
384 const QString entityParam = dsUri.param( u"entity"_s );
386 if ( entity == Qgis::SensorThingsEntity::Invalid )
387 entity = QgsSensorThingsUtils::stringToEntity( entityParam );
388
389 if ( entity != Qgis::SensorThingsEntity::Invalid )
390 components.insert( u"entity"_s, qgsEnumValueToKey( entity ) );
391
392 const QStringList expandToParam = dsUri.param( u"expandTo"_s ).split( ';', Qt::SkipEmptyParts );
393 if ( !expandToParam.isEmpty() )
394 {
395 QVariantList expandParts;
396 for ( const QString &expandString : expandToParam )
397 {
399 if ( definition.isValid() )
400 {
401 expandParts.append( QVariant::fromValue( definition ) );
402 }
403 }
404 if ( !expandParts.isEmpty() )
405 {
406 components.insert( u"expandTo"_s, expandParts );
407 }
408 }
409
410 bool ok = false;
411 const int maxPageSizeParam = dsUri.param( u"pageSize"_s ).toInt( &ok );
412 if ( ok )
413 {
414 components.insert( u"pageSize"_s, maxPageSizeParam );
415 }
416
417 ok = false;
418 const int featureLimitParam = dsUri.param( u"featureLimit"_s ).toInt( &ok );
419 if ( ok )
420 {
421 components.insert( u"featureLimit"_s, featureLimitParam );
422 }
423
424 switch ( QgsWkbTypes::geometryType( dsUri.wkbType() ) )
425 {
427 if ( QgsWkbTypes::isMultiType( dsUri.wkbType() ) )
428 components.insert( u"geometryType"_s, u"multipoint"_s );
429 else
430 components.insert( u"geometryType"_s, u"point"_s );
431 break;
433 components.insert( u"geometryType"_s, u"line"_s );
434 break;
436 components.insert( u"geometryType"_s, u"polygon"_s );
437 break;
438
441 break;
442 }
443
444 const QStringList bbox = dsUri.param( u"bbox"_s ).split( ',' );
445 if ( bbox.size() == 4 )
446 {
447 QgsRectangle r;
448 bool xminOk = false;
449 bool yminOk = false;
450 bool xmaxOk = false;
451 bool ymaxOk = false;
452 r.setXMinimum( bbox[0].toDouble( &xminOk ) );
453 r.setYMinimum( bbox[1].toDouble( &yminOk ) );
454 r.setXMaximum( bbox[2].toDouble( &xmaxOk ) );
455 r.setYMaximum( bbox[3].toDouble( &ymaxOk ) );
456 if ( xminOk && yminOk && xmaxOk && ymaxOk )
457 components.insert( u"bounds"_s, r );
458 }
459
460 if ( !dsUri.sql().isEmpty() )
461 components.insert( u"sql"_s, dsUri.sql() );
462
463 return components;
464}
465
466QString QgsSensorThingsProviderMetadata::encodeUri( const QVariantMap &parts ) const
467{
468 QgsDataSourceUri dsUri;
469 dsUri.setParam( u"url"_s, parts.value( u"url"_s ).toString() );
470
471 if ( !parts.value( u"authcfg"_s ).toString().isEmpty() )
472 {
473 dsUri.setAuthConfigId( parts.value( u"authcfg"_s ).toString() );
474 }
475 if ( !parts.value( u"username"_s ).toString().isEmpty() )
476 {
477 dsUri.setUsername( parts.value( u"username"_s ).toString() );
478 }
479 if ( !parts.value( u"password"_s ).toString().isEmpty() )
480 {
481 dsUri.setPassword( parts.value( u"password"_s ).toString() );
482 }
483 if ( !parts.value( u"referer"_s ).toString().isEmpty() )
484 {
485 dsUri.setParam( u"referer"_s, parts.value( u"referer"_s ).toString() );
486 }
487
488 Qgis::SensorThingsEntity entity = QgsSensorThingsUtils::entitySetStringToEntity( parts.value( u"entity"_s ).toString() );
489 if ( entity == Qgis::SensorThingsEntity::Invalid )
490 entity = QgsSensorThingsUtils::stringToEntity( parts.value( u"entity"_s ).toString() );
491
492 if ( entity != Qgis::SensorThingsEntity::Invalid )
493 {
494 dsUri.setParam( u"entity"_s, qgsEnumValueToKey( entity ) );
495 }
496
497 const QVariantList expandToParam = parts.value( u"expandTo"_s ).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( u"expandTo"_s, expandToStringList.join( ';' ) );
512 }
513 }
514
515 bool ok = false;
516 const int maxPageSizeParam = parts.value( u"pageSize"_s ).toInt( &ok );
517 if ( ok )
518 {
519 dsUri.setParam( u"pageSize"_s, QString::number( maxPageSizeParam ) );
520 }
521
522 ok = false;
523 const int featureLimitParam = parts.value( u"featureLimit"_s ).toInt( &ok );
524 if ( ok )
525 {
526 dsUri.setParam( u"featureLimit"_s, QString::number( featureLimitParam ) );
527 }
528
529 const QString geometryType = parts.value( u"geometryType"_s ).toString();
530 if ( geometryType.compare( "point"_L1, Qt::CaseInsensitive ) == 0 )
531 {
533 }
534 else if ( geometryType.compare( "multipoint"_L1, Qt::CaseInsensitive ) == 0 )
535 {
537 }
538 else if ( geometryType.compare( "line"_L1, Qt::CaseInsensitive ) == 0 )
539 {
541 }
542 else if ( geometryType.compare( "polygon"_L1, Qt::CaseInsensitive ) == 0 )
543 {
545 }
546
547 if ( parts.contains( u"bounds"_s ) && parts.value( u"bounds"_s ).userType() == qMetaTypeId<QgsRectangle>() )
548 {
549 const QgsRectangle bBox = parts.value( u"bounds"_s ).value< QgsRectangle >();
550 dsUri.setParam( u"bbox"_s, u"%1,%2,%3,%4"_s.arg( bBox.xMinimum() ).arg( bBox.yMinimum() ).arg( bBox.xMaximum() ).arg( bBox.yMaximum() ) );
551 }
552
553 if ( !parts.value( u"sql"_s ).toString().isEmpty() )
554 dsUri.setSql( parts.value( u"sql"_s ).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.
Definition qgis.h:533
@ ReloadData
Provider is able to force reload data.
Definition qgis.h:549
@ ReadLayerMetadata
Provider can read layer metadata from data store. Since QGIS 3.0. See QgsDataProvider::layerMetadata(...
Definition qgis.h:544
QFlags< DataProviderFlag > DataProviderFlags
Data provider flags.
Definition qgis.h:2397
@ FastExtent2D
Provider's 2D extent retrieval via QgsDataProvider::extent() is always guaranteed to be trivial/fast ...
Definition qgis.h:2392
SensorThingsEntity
OGC SensorThings API entity types.
Definition qgis.h:6324
@ Sensor
A Sensor is an instrument that observes a property or phenomenon with the goal of producing an estima...
Definition qgis.h:6330
@ MultiDatastream
A MultiDatastream groups a collection of Observations and the Observations in a MultiDatastream have ...
Definition qgis.h:6334
@ ObservedProperty
An ObservedProperty specifies the phenomenon of an Observation.
Definition qgis.h:6331
@ Invalid
An invalid/unknown entity.
Definition qgis.h:6325
@ FeatureOfInterest
In the context of the Internet of Things, many Observations’ FeatureOfInterest can be the Location of...
Definition qgis.h:6333
@ Datastream
A Datastream groups a collection of Observations measuring the same ObservedProperty and produced by ...
Definition qgis.h:6329
@ Observation
An Observation is the act of measuring or otherwise determining the value of a property.
Definition qgis.h:6332
@ Location
A Location entity locates the Thing or the Things it associated with. A Thing’s Location entity is de...
Definition qgis.h:6327
@ Thing
A Thing is an object of the physical world (physical things) or the information world (virtual things...
Definition qgis.h:6326
@ HistoricalLocation
A Thing’s HistoricalLocation entity set provides the times of the current (i.e., last known) and prev...
Definition qgis.h:6328
@ Point
Points.
Definition qgis.h:380
@ Line
Lines.
Definition qgis.h:381
@ Polygon
Polygons.
Definition qgis.h:382
@ Unknown
Unknown types.
Definition qgis.h:383
@ Null
No geometry.
Definition qgis.h:384
QFlags< DataProviderReadFlag > DataProviderReadFlags
Flags which control data provider construction.
Definition qgis.h:512
QFlags< VectorProviderCapability > VectorProviderCapabilities
Vector data provider capabilities.
Definition qgis.h:562
@ Vector
Vector layer.
Definition qgis.h:207
@ SkipFeatureCount
Make featureCount() return -1 to indicate unknown, and subLayers() to return a unknown feature count ...
Definition qgis.h:494
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:294
@ MultiPointZ
MultiPointZ.
Definition qgis.h:317
@ PointZ
PointZ.
Definition qgis.h:313
@ MultiLineStringZ
MultiLineStringZ.
Definition qgis.h:318
@ MultiPolygonZ
MultiPolygonZ.
Definition qgis.h:319
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(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
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:573
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:7157
#define QgsSetRequestInitiatorClass(request, _class)
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
Setting options for creating vector data providers.