31#include <QNetworkRequest>
32#include <nlohmann/json.hpp>
36QgsSensorThingsProvider::QgsSensorThingsProvider(
const QString &uri,
const ProviderOptions &options,
QgsDataProvider::ReadFlags flags )
39 mSharedData = std::make_shared< QgsSensorThingsSharedData >( uri );
41 const QUrl url( QgsSensorThingsSharedData::parseUrl( mSharedData->mRootUri ) );
43 QNetworkRequest request = QNetworkRequest( url );
45 mSharedData->mHeaders.updateNetworkRequest( request );
48 networkRequest.setAuthCfg( mSharedData->mAuthCfg );
50 switch ( networkRequest.get( request ) )
58 appendError(
QgsErrorMessage( tr(
"Connection failed: %1" ).arg( networkRequest.
errorMessage() ), QStringLiteral(
"SensorThings" ) ) );
67 if ( !rootContent.contains(
"value" ) )
69 appendError(
QgsErrorMessage( tr(
"No 'value' array in response" ), QStringLiteral(
"SensorThings" ) ) );
73 bool foundMatchingEntity =
false;
74 for (
const auto &valueJson : rootContent[
"value"] )
76 if ( valueJson.contains(
"name" ) && valueJson.contains(
"url" ) )
78 const QString name = QString::fromStdString( valueJson[
"name"].get<std::string>() );
80 if ( entityType == mSharedData->mEntityType )
82 const QString url = QString::fromStdString( valueJson[
"url"].get<std::string>() );
85 foundMatchingEntity =
true;
86 mSharedData->mEntityBaseUri = url;
94 ( void ) mSharedData->featureCount();
100 if ( !foundMatchingEntity )
106 catch (
const json::parse_error &ex )
108 appendError(
QgsErrorMessage( tr(
"Error parsing response: %1" ).arg( ex.what() ), QStringLiteral(
"SensorThings" ) ) );
115QString QgsSensorThingsProvider::storageType()
const
119 return QStringLiteral(
"OGC SensorThings API" );
126 return new QgsSensorThingsFeatureSource( mSharedData );
133 return new QgsSensorThingsFeatureIterator(
new QgsSensorThingsFeatureSource( mSharedData ),
true, request );
140 return mSharedData->mGeometryType;
143long long QgsSensorThingsProvider::featureCount()
const
152 const long long count = mSharedData->featureCount();
153 if ( !mSharedData->error().isEmpty() )
154 pushError( mSharedData->error() );
159QgsFields QgsSensorThingsProvider::fields()
const
163 return mSharedData->mFields;
170 return mLayerMetadata;
173QString QgsSensorThingsProvider::htmlMetadata()
const
181 metadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) % tr(
"Entity Type" ) % QStringLiteral(
"</td><td>%1" ).arg(
qgsEnumValueToKey( mSharedData->mEntityType ) ) % QStringLiteral(
"</td></tr>\n" );
182 metadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) % tr(
"Endpoint" ) % QStringLiteral(
"</td><td><a href=\"%1\">%1</a>" ).arg( mSharedData->mEntityBaseUri ) % QStringLiteral(
"</td></tr>\n" );
200 | QgsVectorDataProvider::Capability::ReloadData;
205bool QgsSensorThingsProvider::supportsSubsetString()
const
211QString QgsSensorThingsProvider::subsetString()
const
214 return mSharedData->subsetString();
217bool QgsSensorThingsProvider::setSubsetString(
const QString &subset,
bool )
221 const QString trimmedSubset = subset.trimmed();
222 if ( trimmedSubset == mSharedData->subsetString() )
227 const QString baseUri = mSharedData->mEntityBaseUri;
230 uri.
setSql( trimmedSubset );
231 setDataSourceUri( uri.
uri(
false ) );
233 mSharedData->mEntityBaseUri = baseUri;
242void QgsSensorThingsProvider::setDataSourceUri(
const QString &uri )
246 mSharedData = std::make_shared< QgsSensorThingsSharedData >( uri );
254 return mSharedData->mSourceCRS;
260 return mSharedData->extent();
263QString QgsSensorThingsProvider::name()
const
267 return SENSORTHINGS_PROVIDER_KEY;
270QString QgsSensorThingsProvider::providerKey()
272 return SENSORTHINGS_PROVIDER_KEY;
277 mSharedData = qobject_cast<QgsSensorThingsProvider *>( source )->mSharedData;
280QString QgsSensorThingsProvider::description()
const
282 return SENSORTHINGS_PROVIDER_DESCRIPTION;
285bool QgsSensorThingsProvider::renderInPreview(
const PreviewContext & )
291void QgsSensorThingsProvider::reloadProviderData()
294 mSharedData->clearCache();
302QgsSensorThingsProviderMetadata::QgsSensorThingsProviderMetadata():
303 QgsProviderMetadata( QgsSensorThingsProvider::SENSORTHINGS_PROVIDER_KEY, QgsSensorThingsProvider::SENSORTHINGS_PROVIDER_DESCRIPTION )
307QIcon QgsSensorThingsProviderMetadata::icon()
const
313QList<QgsDataItemProvider *> QgsSensorThingsProviderMetadata::dataItemProviders()
const
315 return {
new QgsSensorThingsDataItemProvider() };
318QVariantMap QgsSensorThingsProviderMetadata::decodeUri(
const QString &uri )
const
322 QVariantMap components;
323 components.insert( QStringLiteral(
"url" ), dsUri.
param( QStringLiteral(
"url" ) ) );
327 components.insert( QStringLiteral(
"authcfg" ), dsUri.
authConfigId() );
331 components.insert( QStringLiteral(
"username" ), dsUri.
username() );
335 components.insert( QStringLiteral(
"password" ), dsUri.
password() );
343 if ( !dsUri.
param( QStringLiteral(
"referer" ) ).isEmpty() )
345 components.insert( QStringLiteral(
"referer" ), dsUri.
param( QStringLiteral(
"referer" ) ) );
347 if ( !dsUri.
param( QStringLiteral(
"http-header:referer" ) ).isEmpty() )
349 components.insert( QStringLiteral(
"referer" ), dsUri.
param( QStringLiteral(
"http-header:referer" ) ) );
352 const QString entityParam = dsUri.
param( QStringLiteral(
"entity" ) );
361 const int maxPageSizeParam = dsUri.
param( QStringLiteral(
"pageSize" ) ).toInt( &ok );
364 components.insert( QStringLiteral(
"pageSize" ), maxPageSizeParam );
368 const int featureLimitParam = dsUri.
param( QStringLiteral(
"featureLimit" ) ).toInt( &ok );
371 components.insert( QStringLiteral(
"featureLimit" ), featureLimitParam );
378 components.insert( QStringLiteral(
"geometryType" ), QStringLiteral(
"multipoint" ) );
380 components.insert( QStringLiteral(
"geometryType" ), QStringLiteral(
"point" ) );
383 components.insert( QStringLiteral(
"geometryType" ), QStringLiteral(
"line" ) );
386 components.insert( QStringLiteral(
"geometryType" ), QStringLiteral(
"polygon" ) );
394 const QStringList bbox = dsUri.
param( QStringLiteral(
"bbox" ) ).split(
',' );
395 if ( bbox.size() == 4 )
406 if ( xminOk && yminOk && xmaxOk && ymaxOk )
407 components.insert( QStringLiteral(
"bounds" ), r );
410 if ( !dsUri.
sql().isEmpty() )
411 components.insert( QStringLiteral(
"sql" ), dsUri.
sql() );
416QString QgsSensorThingsProviderMetadata::encodeUri(
const QVariantMap &parts )
const
419 dsUri.
setParam( QStringLiteral(
"url" ), parts.value( QStringLiteral(
"url" ) ).toString() );
421 if ( !parts.value( QStringLiteral(
"authcfg" ) ).toString().isEmpty() )
423 dsUri.
setAuthConfigId( parts.value( QStringLiteral(
"authcfg" ) ).toString() );
425 if ( !parts.value( QStringLiteral(
"username" ) ).toString().isEmpty() )
427 dsUri.
setUsername( parts.value( QStringLiteral(
"username" ) ).toString() );
429 if ( !parts.value( QStringLiteral(
"password" ) ).toString().isEmpty() )
431 dsUri.
setPassword( parts.value( QStringLiteral(
"password" ) ).toString() );
433 if ( !parts.value( QStringLiteral(
"referer" ) ).toString().isEmpty() )
435 dsUri.
setParam( QStringLiteral(
"referer" ), parts.value( QStringLiteral(
"referer" ) ).toString() );
439 parts.value( QStringLiteral(
"entity" ) ).toString() );
445 dsUri.
setParam( QStringLiteral(
"entity" ),
450 const int maxPageSizeParam = parts.value( QStringLiteral(
"pageSize" ) ).toInt( &ok );
453 dsUri.
setParam( QStringLiteral(
"pageSize" ), QString::number( maxPageSizeParam ) );
457 const int featureLimitParam = parts.value( QStringLiteral(
"featureLimit" ) ).toInt( &ok );
460 dsUri.
setParam( QStringLiteral(
"featureLimit" ), QString::number( featureLimitParam ) );
463 const QString geometryType = parts.value( QStringLiteral(
"geometryType" ) ).toString();
464 if ( geometryType.compare( QLatin1String(
"point" ), Qt::CaseInsensitive ) == 0 )
468 else if ( geometryType.compare( QLatin1String(
"multipoint" ), Qt::CaseInsensitive ) == 0 )
472 else if ( geometryType.compare( QLatin1String(
"line" ), Qt::CaseInsensitive ) == 0 )
476 else if ( geometryType.compare( QLatin1String(
"polygon" ), Qt::CaseInsensitive ) == 0 )
481 if ( parts.contains( QStringLiteral(
"bounds" ) ) && parts.value( QStringLiteral(
"bounds" ) ).userType() == QMetaType::type(
"QgsRectangle" ) )
487 if ( !parts.value( QStringLiteral(
"sql" ) ).toString().isEmpty() )
488 dsUri.
setSql( parts.value( QStringLiteral(
"sql" ) ).toString() );
490 return dsUri.
uri(
false );
495 return new QgsSensorThingsProvider( uri, options, flags );
498QList<Qgis::LayerType> QgsSensorThingsProviderMetadata::supportedLayerTypes()
const
503QMap<QString, QgsAbstractProviderConnection *> QgsSensorThingsProviderMetadata::connections(
bool cached )
505 return connectionsProtected<QgsSensorThingsProviderConnection, QgsSensorThingsProviderConnection>( cached );
513void QgsSensorThingsProviderMetadata::deleteConnection(
const QString &name )
515 deleteConnectionProtected<QgsSensorThingsProviderConnection>( name );
520 saveConnectionProtected( connection, name );
QFlags< DataProviderFlag > DataProviderFlags
Data provider flags.
@ FastExtent2D
Provider's 2D extent retrieval via QgsDataProvider::extent() is always guaranteed to be trivial/fast ...
SensorThingsEntity
OGC SensorThings API entity types.
@ Invalid
An invalid/unknown entity.
WkbType
The WKB type describes the number of dimensions a geometry has.
@ MultiPointZ
MultiPointZ.
@ 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).
@ SkipFeatureCount
Make featureCount() return -1 to indicate unknown, and subLayers() to return a unknown feature count ...
QFlags< ReadFlag > ReadFlags
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.
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.
Encapsulates a network reply within a container which is inexpensive to copy and safe to pass between...
QByteArray content() const
Returns the reply content.
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.
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.
@ ReadLayerMetadata
Provider can read layer metadata from data store. Since QGIS 3.0. See QgsDataProvider::layerMetadata(...
@ SelectAtId
Fast access to features using their ID.
QFlags< Capability > Capabilities
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.
#define QgsSetRequestInitiatorClass(request, _class)
QgsSQLStatement::Node * parse(const QString &str, QString &parserErrorMsg, bool allowFragments)
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
const QgsCoordinateReferenceSystem & crs
Setting options for creating vector data providers.