QGIS API Documentation 4.1.0-Master (3fcefe620d1)
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 "qgslogger.h"
25#include "qgsmessagelog.h"
26#include "qgsreadwritelocker.h"
32#include "qgsthreadingutils.h"
33
34#include <QIcon>
35#include <QNetworkRequest>
36#include <QString>
37
38#include "moc_qgssensorthingsprovider.cpp"
39
40using namespace Qt::StringLiterals;
41
43
44QgsSensorThingsProvider::QgsSensorThingsProvider( const QString &uri, const ProviderOptions &options, Qgis::DataProviderReadFlags flags )
45 : QgsVectorDataProvider( uri, options, flags )
46{
47 mSharedData = std::make_shared< QgsSensorThingsSharedData >( uri );
48
49 const QUrl url( QgsSensorThingsSharedData::parseUrl( mSharedData->mRootUri ) );
50
51 QNetworkRequest request = QNetworkRequest( url );
52 QgsSetRequestInitiatorClass( request, u"QgsSensorThingsProvider"_s ) 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
75 // try to determine sensorthings version
76 if ( rootContent.contains( "serverSettings" ) && rootContent["serverSettings"].contains( "conformance" ) )
77 {
78 for ( const auto &valueJson : rootContent["serverSettings"]["conformance"] )
79 {
80 const QString conformance = QString::fromStdString( valueJson.get<std::string>() );
81 const thread_local QRegularExpression sDataModelRx( u".*/datamodel\\b"_s );
82 if ( sDataModelRx.match( conformance ).hasMatch() )
83 {
84 // extract version from datamodel value
85 const thread_local QRegularExpression sVersionRx( u"\\d+\\.\\d+"_s );
86 const QRegularExpressionMatch versionMatch = sVersionRx.match( conformance );
87 if ( versionMatch.hasMatch() )
88 {
89 const QString versionString = versionMatch.captured( 0 );
90 mSharedData->mVersion = QVersionNumber::fromString( versionString );
91 }
92 }
93 }
94 }
95
96 if ( !rootContent.contains( "value" ) )
97 {
98 appendError( QgsErrorMessage( tr( "No 'value' array in response" ), u"SensorThings"_s ) );
99 return;
100 }
101
102 bool foundMatchingEntity = false;
103 for ( const auto &valueJson : rootContent["value"] )
104 {
105 if ( valueJson.contains( "name" ) && valueJson.contains( "url" ) )
106 {
107 const QString name = QString::fromStdString( valueJson["name"].get<std::string>() );
109 if ( entityType == mSharedData->mEntityType )
110 {
111 const QString url = QString::fromStdString( valueJson["url"].get<std::string>() );
112 if ( !url.isEmpty() )
113 {
114 foundMatchingEntity = true;
115 mSharedData->mEntityBaseUri = url;
116
117 // TODO:
118 // if we always retrieve feature count, is that less expensive then deferring this till we need it?
119 // by retrieving upfront, we can save a lot of requests where we've fetched features from spatial extents
120 // as we'll have a way of determining whether we've fetched all features from the source. Otherwise
121 // we never know if we've got everything yet, and are forced to re-fetched everything when a non-filtered request
122 // comes in...
123 ( void ) mSharedData->featureCount();
124 }
125 }
126 }
127 }
128
129 if ( !foundMatchingEntity )
130 {
131 switch ( mSharedData->mEntityType )
132 {
142 appendError( QgsErrorMessage( tr( "Could not find url for %1" ).arg( qgsEnumValueToKey( mSharedData->mEntityType ) ), u"SensorThings"_s ) );
143 QgsMessageLog::logMessage( tr( "Could not find url for %1" ).arg( qgsEnumValueToKey( mSharedData->mEntityType ) ), tr( "SensorThings" ) );
144 break;
145
147 appendError( QgsErrorMessage( tr( "MultiDatastreams are not supported by this connection" ), u"SensorThings"_s ) );
148 QgsMessageLog::logMessage( tr( "MultiDatastreams are not supported by this connection" ), tr( "SensorThings" ) );
149 break;
150
152 appendError( QgsErrorMessage( tr( "FeaturesOfInterest are not supported by this connection" ), u"SensorThings"_s ) );
153 QgsMessageLog::logMessage( tr( "FeaturesOfInterest are not supported by this connection" ), tr( "SensorThings" ) );
154 break;
155
157 appendError( QgsErrorMessage( tr( "FeatureTypes are not supported by this connection" ), u"SensorThings"_s ) );
158 QgsMessageLog::logMessage( tr( "FeatureTypes are not supported by this connection" ), tr( "SensorThings" ) );
159 break;
160
162 appendError( QgsErrorMessage( tr( "Deployments are not supported by this connection" ), u"SensorThings"_s ) );
163 QgsMessageLog::logMessage( tr( "Deployments are not supported by this connection" ), tr( "SensorThings" ) );
164 break;
165
167 appendError( QgsErrorMessage( tr( "ObservingProcedures are not supported by this connection" ), u"SensorThings"_s ) );
168 QgsMessageLog::logMessage( tr( "ObservingProcedures are not supported by this connection" ), tr( "SensorThings" ) );
169 break;
170
172 appendError( QgsErrorMessage( tr( "Samplings are not supported by this connection" ), u"SensorThings"_s ) );
173 QgsMessageLog::logMessage( tr( "Samplings are not supported by this connection" ), tr( "SensorThings" ) );
174 break;
175
177 appendError( QgsErrorMessage( tr( "SamplingProcedures are not supported by this connection" ), u"SensorThings"_s ) );
178 QgsMessageLog::logMessage( tr( "SamplingProcedures are not supported by this connection" ), tr( "SensorThings" ) );
179 break;
180
182 appendError( QgsErrorMessage( tr( "Samplers are not supported by this connection" ), u"SensorThings"_s ) );
183 QgsMessageLog::logMessage( tr( "Samplers are not supported by this connection" ), tr( "SensorThings" ) );
184 break;
185
187 appendError( QgsErrorMessage( tr( "PreparationSteps are not supported by this connection" ), u"SensorThings"_s ) );
188 QgsMessageLog::logMessage( tr( "PreparationSteps are not supported by this connection" ), tr( "SensorThings" ) );
189 break;
190
192 appendError( QgsErrorMessage( tr( "PreparationProcedures are not supported by this connection" ), u"SensorThings"_s ) );
193 QgsMessageLog::logMessage( tr( "PreparationProcedures are not supported by this connection" ), tr( "SensorThings" ) );
194 break;
195
197 appendError( QgsErrorMessage( tr( "ThingRelations are not supported by this connection" ), u"SensorThings"_s ) );
198 QgsMessageLog::logMessage( tr( "ThingRelations are not supported by this connection" ), tr( "SensorThings" ) );
199 break;
200
202 appendError( QgsErrorMessage( tr( "RelationRoles are not supported by this connection" ), u"SensorThings"_s ) );
203 QgsMessageLog::logMessage( tr( "RelationRoles are not supported by this connection" ), tr( "SensorThings" ) );
204 break;
205
207 appendError( QgsErrorMessage( tr( "FeatureRelations are not supported by this connection" ), u"SensorThings"_s ) );
208 QgsMessageLog::logMessage( tr( "FeatureRelations are not supported by this connection" ), tr( "SensorThings" ) );
209 break;
210
212 appendError( QgsErrorMessage( tr( "DatastreamRelations are not supported by this connection" ), u"SensorThings"_s ) );
213 QgsMessageLog::logMessage( tr( "DatastreamRelations are not supported by this connection" ), tr( "SensorThings" ) );
214 break;
215
217 appendError( QgsErrorMessage( tr( "ObservationRelations are not supported by this connection" ), u"SensorThings"_s ) );
218 QgsMessageLog::logMessage( tr( "ObservationRelations are not supported by this connection" ), tr( "SensorThings" ) );
219 break;
220 }
221
222 return;
223 }
224 }
225 catch ( const json::parse_error &ex )
226 {
227 appendError( QgsErrorMessage( tr( "Error parsing response: %1" ).arg( ex.what() ), u"SensorThings"_s ) );
228 return;
229 }
230
231 mValid = true;
232}
233
234QString QgsSensorThingsProvider::storageType() const
235{
237
238 return u"OGC SensorThings API"_s;
239}
240
241QgsAbstractFeatureSource *QgsSensorThingsProvider::featureSource() const
242{
244
245 return new QgsSensorThingsFeatureSource( mSharedData );
246}
247
248QgsFeatureIterator QgsSensorThingsProvider::getFeatures( const QgsFeatureRequest &request ) const
249{
251
252 return new QgsSensorThingsFeatureIterator( new QgsSensorThingsFeatureSource( mSharedData ), true, request );
253}
254
255Qgis::WkbType QgsSensorThingsProvider::wkbType() const
256{
258
259 return mSharedData->mGeometryType;
260}
261
262long long QgsSensorThingsProvider::featureCount() const
263{
265
266 if ( ( mReadFlags & Qgis::DataProviderReadFlag::SkipFeatureCount ) != 0 )
267 {
268 return static_cast< long long >( Qgis::FeatureCountState::UnknownCount );
269 }
270
271 const long long count = mSharedData->featureCount();
272 if ( !mSharedData->error().isEmpty() )
273 pushError( mSharedData->error() );
274
275 return count;
276}
277
278QgsFields QgsSensorThingsProvider::fields() const
279{
281
282 return mSharedData->mFields;
283}
284
285QgsLayerMetadata QgsSensorThingsProvider::layerMetadata() const
286{
288
289 return mLayerMetadata;
290}
291
292QString QgsSensorThingsProvider::htmlMetadata() const
293{
295
296 QString metadata;
297
298 QgsReadWriteLocker locker( mSharedData->mReadWriteLock, QgsReadWriteLocker::Read );
299 metadata += u"<tr><td class=\"highlight\">"_s % tr( "SensorThings Version" ) % u"</td><td>%1"_s.arg( mSharedData->mVersion.toString() ) % u"</td></tr>\n"_s;
300 metadata += u"<tr><td class=\"highlight\">"_s % tr( "Entity Type" ) % u"</td><td>%1"_s.arg( qgsEnumValueToKey( mSharedData->mEntityType ) ) % u"</td></tr>\n"_s;
301 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;
302
303 return metadata;
304}
305
306QVariantMap QgsSensorThingsProvider::metadata() const
307{
309
310 QVariantMap metadata;
311
312 QgsReadWriteLocker locker( mSharedData->mReadWriteLock, QgsReadWriteLocker::Read );
313 metadata.insert( u"SensorThingsVersion"_s, mSharedData->mVersion.toString() );
314 return metadata;
315}
316
317Qgis::DataProviderFlags QgsSensorThingsProvider::flags() const
318{
320
322}
323
324Qgis::VectorProviderCapabilities QgsSensorThingsProvider::capabilities() const
325{
327
329
330 return c;
331}
332
333bool QgsSensorThingsProvider::supportsSubsetString() const
334{
336 return true;
337}
338
339QString QgsSensorThingsProvider::subsetStringDialect() const
340{
341 return tr( "OGC SensorThings filter" );
342}
343
344QString QgsSensorThingsProvider::subsetStringHelpUrl() const
345{
346 return u"https://docs.ogc.org/is/18-088/18-088.html#filter"_s;
347}
348
349QString QgsSensorThingsProvider::subsetString() const
350{
352 return mSharedData->subsetString();
353}
354
355bool QgsSensorThingsProvider::setSubsetString( const QString &subset, bool )
356{
358
359 const QString trimmedSubset = subset.trimmed();
360 if ( trimmedSubset == mSharedData->subsetString() )
361 return true;
362
363 // store this and restore it after the data source is changed,
364 // to avoid an unwanted network request to retrieve this again
365 const QString baseUri = mSharedData->mEntityBaseUri;
366
367 QgsDataSourceUri uri = dataSourceUri();
368 uri.setSql( trimmedSubset );
369 setDataSourceUri( uri.uri( false ) );
370
371 mSharedData->mEntityBaseUri = baseUri;
372
373 clearMinMaxCache();
374
375 emit dataChanged();
376
377 return true;
378}
379
380void QgsSensorThingsProvider::setDataSourceUri( const QString &uri )
381{
383
384 mSharedData = std::make_shared< QgsSensorThingsSharedData >( uri );
386}
387
388QgsCoordinateReferenceSystem QgsSensorThingsProvider::crs() const
389{
391
392 return mSharedData->mSourceCRS;
393}
394
395QgsRectangle QgsSensorThingsProvider::extent() const
396{
398 return mSharedData->extent();
399}
400
401QString QgsSensorThingsProvider::name() const
402{
404
405 return SENSORTHINGS_PROVIDER_KEY;
406}
407
408QString QgsSensorThingsProvider::providerKey()
409{
410 return SENSORTHINGS_PROVIDER_KEY;
411}
412
413void QgsSensorThingsProvider::handlePostCloneOperations( QgsVectorDataProvider *source )
414{
415 mSharedData = qobject_cast<QgsSensorThingsProvider *>( source )->mSharedData;
416}
417
418QString QgsSensorThingsProvider::description() const
419{
420 return SENSORTHINGS_PROVIDER_DESCRIPTION;
421}
422
423bool QgsSensorThingsProvider::renderInPreview( const PreviewContext & )
424{
425 // be nice to the endpoint and don't make any requests we don't have to!
426 return false;
427}
428
429void QgsSensorThingsProvider::reloadProviderData()
430{
431#if 0
432 mSharedData->clearCache();
433#endif
434}
435
436//
437// QgsSensorThingsProviderMetadata
438//
439
440QgsSensorThingsProviderMetadata::QgsSensorThingsProviderMetadata()
441 : QgsProviderMetadata( QgsSensorThingsProvider::SENSORTHINGS_PROVIDER_KEY, QgsSensorThingsProvider::SENSORTHINGS_PROVIDER_DESCRIPTION )
442{}
443
444QgsProviderMetadata::ProviderCapabilities QgsSensorThingsProviderMetadata::providerCapabilities() const
445{
447}
448
449QIcon QgsSensorThingsProviderMetadata::icon() const
450{
451 return QgsApplication::getThemeIcon( u"mIconSensorThings.svg"_s );
452}
453
454QList<QgsDataItemProvider *> QgsSensorThingsProviderMetadata::dataItemProviders() const
455{
456 return { new QgsSensorThingsDataItemProvider() };
457}
458
459QVariantMap QgsSensorThingsProviderMetadata::decodeUri( const QString &uri ) const
460{
461 const QgsDataSourceUri dsUri = QgsDataSourceUri( uri );
462
463 QVariantMap components;
464 components.insert( u"url"_s, dsUri.param( u"url"_s ) );
465
466 if ( !dsUri.authConfigId().isEmpty() )
467 {
468 components.insert( u"authcfg"_s, dsUri.authConfigId() );
469 }
470 if ( !dsUri.username().isEmpty() )
471 {
472 components.insert( u"username"_s, dsUri.username() );
473 }
474 if ( !dsUri.password().isEmpty() )
475 {
476 components.insert( u"password"_s, dsUri.password() );
477 }
478
479 // there's two different ways the referer can be set, so we need to check both. Which way it has been
480 // set depends on the widget used to create the URI. It's messy, but QgsHttpHeaders has a bunch of logic in
481 // it to handle upgrading old referer handling for connections created before QgsHttpHeaders was invented,
482 // and if we rely on that entirely then we get multiple "referer" parameters included in the URI, which is
483 // both ugly and unnecessary for a provider created post QgsHttpHeaders.
484 if ( !dsUri.param( u"referer"_s ).isEmpty() )
485 {
486 components.insert( u"referer"_s, dsUri.param( u"referer"_s ) );
487 }
488 if ( !dsUri.param( u"http-header:referer"_s ).isEmpty() )
489 {
490 components.insert( u"referer"_s, dsUri.param( u"http-header:referer"_s ) );
491 }
492
493 const QString entityParam = dsUri.param( u"entity"_s );
495 if ( entity == Qgis::SensorThingsEntity::Invalid )
496 entity = QgsSensorThingsUtils::stringToEntity( entityParam );
497
498 if ( entity != Qgis::SensorThingsEntity::Invalid )
499 components.insert( u"entity"_s, qgsEnumValueToKey( entity ) );
500
501 const QStringList expandToParam = dsUri.param( u"expandTo"_s ).split( ';', Qt::SkipEmptyParts );
502 if ( !expandToParam.isEmpty() )
503 {
504 QVariantList expandParts;
505 for ( const QString &expandString : expandToParam )
506 {
508 if ( definition.isValid() )
509 {
510 expandParts.append( QVariant::fromValue( definition ) );
511 }
512 }
513 if ( !expandParts.isEmpty() )
514 {
515 components.insert( u"expandTo"_s, expandParts );
516 }
517 }
518
519 bool ok = false;
520 const int maxPageSizeParam = dsUri.param( u"pageSize"_s ).toInt( &ok );
521 if ( ok )
522 {
523 components.insert( u"pageSize"_s, maxPageSizeParam );
524 }
525
526 ok = false;
527 const int featureLimitParam = dsUri.param( u"featureLimit"_s ).toInt( &ok );
528 if ( ok )
529 {
530 components.insert( u"featureLimit"_s, featureLimitParam );
531 }
532
533 switch ( QgsWkbTypes::geometryType( dsUri.wkbType() ) )
534 {
536 if ( QgsWkbTypes::isMultiType( dsUri.wkbType() ) )
537 components.insert( u"geometryType"_s, u"multipoint"_s );
538 else
539 components.insert( u"geometryType"_s, u"point"_s );
540 break;
542 components.insert( u"geometryType"_s, u"line"_s );
543 break;
545 components.insert( u"geometryType"_s, u"polygon"_s );
546 break;
547
550 break;
551 }
552
553 const QStringList bbox = dsUri.param( u"bbox"_s ).split( ',' );
554 if ( bbox.size() == 4 )
555 {
556 QgsRectangle r;
557 bool xminOk = false;
558 bool yminOk = false;
559 bool xmaxOk = false;
560 bool ymaxOk = false;
561 r.setXMinimum( bbox[0].toDouble( &xminOk ) );
562 r.setYMinimum( bbox[1].toDouble( &yminOk ) );
563 r.setXMaximum( bbox[2].toDouble( &xmaxOk ) );
564 r.setYMaximum( bbox[3].toDouble( &ymaxOk ) );
565 if ( xminOk && yminOk && xmaxOk && ymaxOk )
566 components.insert( u"bounds"_s, r );
567 }
568
569 if ( !dsUri.sql().isEmpty() )
570 components.insert( u"sql"_s, dsUri.sql() );
571
572 return components;
573}
574
575QString QgsSensorThingsProviderMetadata::encodeUri( const QVariantMap &parts ) const
576{
577 QgsDataSourceUri dsUri;
578 dsUri.setParam( u"url"_s, parts.value( u"url"_s ).toString() );
579
580 if ( !parts.value( u"authcfg"_s ).toString().isEmpty() )
581 {
582 dsUri.setAuthConfigId( parts.value( u"authcfg"_s ).toString() );
583 }
584 if ( !parts.value( u"username"_s ).toString().isEmpty() )
585 {
586 dsUri.setUsername( parts.value( u"username"_s ).toString() );
587 }
588 if ( !parts.value( u"password"_s ).toString().isEmpty() )
589 {
590 dsUri.setPassword( parts.value( u"password"_s ).toString() );
591 }
592 if ( !parts.value( u"referer"_s ).toString().isEmpty() )
593 {
594 dsUri.setParam( u"referer"_s, parts.value( u"referer"_s ).toString() );
595 }
596
597 Qgis::SensorThingsEntity entity = QgsSensorThingsUtils::entitySetStringToEntity( parts.value( u"entity"_s ).toString() );
598 if ( entity == Qgis::SensorThingsEntity::Invalid )
599 entity = QgsSensorThingsUtils::stringToEntity( parts.value( u"entity"_s ).toString() );
600
601 if ( entity != Qgis::SensorThingsEntity::Invalid )
602 {
603 dsUri.setParam( u"entity"_s, qgsEnumValueToKey( entity ) );
604 }
605
606 const QVariantList expandToParam = parts.value( u"expandTo"_s ).toList();
607 if ( !expandToParam.isEmpty() )
608 {
609 QStringList expandToStringList;
610 for ( const QVariant &expansion : expandToParam )
611 {
612 const QgsSensorThingsExpansionDefinition expansionDefinition = expansion.value< QgsSensorThingsExpansionDefinition >();
613 if ( !expansionDefinition.isValid() )
614 continue;
615
616 expandToStringList.append( expansionDefinition.toString() );
617 }
618 if ( !expandToStringList.isEmpty() )
619 {
620 dsUri.setParam( u"expandTo"_s, expandToStringList.join( ';' ) );
621 }
622 }
623
624 bool ok = false;
625 const int maxPageSizeParam = parts.value( u"pageSize"_s ).toInt( &ok );
626 if ( ok )
627 {
628 dsUri.setParam( u"pageSize"_s, QString::number( maxPageSizeParam ) );
629 }
630
631 ok = false;
632 const int featureLimitParam = parts.value( u"featureLimit"_s ).toInt( &ok );
633 if ( ok )
634 {
635 dsUri.setParam( u"featureLimit"_s, QString::number( featureLimitParam ) );
636 }
637
638 const QString geometryType = parts.value( u"geometryType"_s ).toString();
639 if ( geometryType.compare( "point"_L1, Qt::CaseInsensitive ) == 0 )
640 {
642 }
643 else if ( geometryType.compare( "multipoint"_L1, Qt::CaseInsensitive ) == 0 )
644 {
646 }
647 else if ( geometryType.compare( "line"_L1, Qt::CaseInsensitive ) == 0 )
648 {
650 }
651 else if ( geometryType.compare( "polygon"_L1, Qt::CaseInsensitive ) == 0 )
652 {
654 }
655
656 if ( parts.contains( u"bounds"_s ) && parts.value( u"bounds"_s ).userType() == qMetaTypeId<QgsRectangle>() )
657 {
658 const QgsRectangle bBox = parts.value( u"bounds"_s ).value< QgsRectangle >();
659 dsUri.setParam( u"bbox"_s, u"%1,%2,%3,%4"_s.arg( bBox.xMinimum() ).arg( bBox.yMinimum() ).arg( bBox.xMaximum() ).arg( bBox.yMaximum() ) );
660 }
661
662 if ( !parts.value( u"sql"_s ).toString().isEmpty() )
663 dsUri.setSql( parts.value( u"sql"_s ).toString() );
664
665 return dsUri.uri( false );
666}
667
668QgsSensorThingsProvider *QgsSensorThingsProviderMetadata::createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, Qgis::DataProviderReadFlags flags )
669{
670 return new QgsSensorThingsProvider( uri, options, flags );
671}
672
673QList<Qgis::LayerType> QgsSensorThingsProviderMetadata::supportedLayerTypes() const
674{
675 return { Qgis::LayerType::Vector };
676}
677
678QMap<QString, QgsAbstractProviderConnection *> QgsSensorThingsProviderMetadata::connections( bool cached )
679{
680 return connectionsProtected<QgsSensorThingsProviderConnection, QgsSensorThingsProviderConnection>( cached );
681}
682
683QgsAbstractProviderConnection *QgsSensorThingsProviderMetadata::createConnection( const QString &name )
684{
685 return new QgsSensorThingsProviderConnection( name );
686}
687
688void QgsSensorThingsProviderMetadata::deleteConnection( const QString &name )
689{
690 deleteConnectionProtected<QgsSensorThingsProviderConnection>( name );
691}
692
693void QgsSensorThingsProviderMetadata::saveConnection( const QgsAbstractProviderConnection *connection, const QString &name )
694{
695 saveConnectionProtected( connection, name );
696}
697
@ 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:2451
@ FastExtent2D
Provider's 2D extent retrieval via QgsDataProvider::extent() is always guaranteed to be trivial/fast ...
Definition qgis.h:2446
SensorThingsEntity
OGC SensorThings API entity types.
Definition qgis.h:6625
@ Sensor
A Sensor is an instrument that observes a property or phenomenon with the goal of producing an estima...
Definition qgis.h:6631
@ MultiDatastream
A MultiDatastream groups a collection of Observations and the Observations in a MultiDatastream have ...
Definition qgis.h:6635
@ Sampling
The Sampling is the act of taking one or more Samples. The Sampling takes Samples from a SampledFeatu...
Definition qgis.h:6641
@ DatastreamRelation
A DatastreamRelation Entity relates a source Datastream to a target Datastream, or to an external res...
Definition qgis.h:6649
@ Feature
A Feature is an abstraction of real-world phenomena. It acts as an independent entity that can repres...
Definition qgis.h:6637
@ FeatureRelation
A FeatureRelation Entity relates a source Feature to a target Feature, or to an external resource,...
Definition qgis.h:6648
@ ObservedProperty
An ObservedProperty specifies the phenomenon of an Observation.
Definition qgis.h:6632
@ Invalid
An invalid/unknown entity.
Definition qgis.h:6626
@ Sampler
The Sampler describes the machine, device, human or other entity that executed the sampling procedure...
Definition qgis.h:6643
@ PreparationStep
When applying a PreparationProcdedure to a Sample, the process is recorded in individual PreparationS...
Definition qgis.h:6644
@ RelationRole
The RelationRole Entity holds a name and definition for both directions of the relation....
Definition qgis.h:6647
@ SamplingProcedure
The SamplingProcedure describes the method, or procedure, that the Sampler uses to create Samples....
Definition qgis.h:6642
@ ObservationRelation
A ObservationRelation Entity relates a source Observation to a target Observation,...
Definition qgis.h:6650
@ FeatureOfInterest
In the context of the Internet of Things, many Observations’ FeatureOfInterest can be the Location of...
Definition qgis.h:6634
@ Datastream
A Datastream groups a collection of Observations measuring the same ObservedProperty and produced by ...
Definition qgis.h:6630
@ PreparationProcedure
After a sample is taken, a preparation procedure can be applied to it. The difference with the sampli...
Definition qgis.h:6645
@ Observation
An Observation is the act of measuring or otherwise determining the value of a property.
Definition qgis.h:6633
@ ObservingProcedure
An Observing Procedure. Implemented in the "Sensing Extension (Observations & Measurements)".
Definition qgis.h:6640
@ Location
A Location entity locates the Thing or the Things it associated with. A Thing’s Location entity is de...
Definition qgis.h:6628
@ ThingRelation
A ThingRelation Entity relates a source Thing to a target Thing, or to an external resource,...
Definition qgis.h:6646
@ FeatureType
A FeatureType provides the classification and schema definition for a Feature, describing the common ...
Definition qgis.h:6638
@ Thing
A Thing is an object of the physical world (physical things) or the information world (virtual things...
Definition qgis.h:6627
@ Deployment
A Deployment is the association of a Sensor to a Thing that hosts this Sensor, and to the Datastreams...
Definition qgis.h:6639
@ HistoricalLocation
A Thing’s HistoricalLocation entity set provides the times of the current (i.e., last known) and prev...
Definition qgis.h:6629
@ 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:564
@ 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...
QFlags< ProviderCapability > ProviderCapabilities
@ ParallelCreateProvider
Indicates that the provider supports parallel creation, that is, can be created on another thread tha...
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:575
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:7576
#define QgsSetRequestInitiatorClass(request, _class)
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
Setting options for creating vector data providers.