30#include <QNetworkRequest>
31#include <nlohmann/json.hpp>
35QgsSensorThingsProvider::QgsSensorThingsProvider(
const QString &uri,
const ProviderOptions &options, QgsDataProvider::ReadFlags flags )
38 mSharedData = std::make_shared< QgsSensorThingsSharedData >( uri );
40 const QUrl url( QgsSensorThingsSharedData::parseUrl( mSharedData->mRootUri ) );
42 QNetworkRequest request = QNetworkRequest( url );
44 mSharedData->mHeaders.updateNetworkRequest( request );
47 networkRequest.setAuthCfg( mSharedData->mAuthCfg );
49 switch ( networkRequest.get( request ) )
57 appendError(
QgsErrorMessage( tr(
"Connection failed: %1" ).arg( networkRequest.
errorMessage() ), QStringLiteral(
"SensorThings" ) ) );
65 auto rootContent = json::parse( content.
content().toStdString() );
66 if ( !rootContent.contains(
"value" ) )
68 appendError(
QgsErrorMessage( tr(
"No 'value' array in response" ), QStringLiteral(
"SensorThings" ) ) );
72 bool foundMatchingEntity =
false;
73 for (
const auto &valueJson : rootContent[
"value"] )
75 if ( valueJson.contains(
"name" ) && valueJson.contains(
"url" ) )
77 const QString name = QString::fromStdString( valueJson[
"name"].get<std::string>() );
79 if ( entityType == mSharedData->mEntityType )
81 const QString url = QString::fromStdString( valueJson[
"url"].get<std::string>() );
84 foundMatchingEntity =
true;
85 mSharedData->mEntityBaseUri = url;
93 ( void ) mSharedData->featureCount();
99 if ( !foundMatchingEntity )
105 catch (
const json::parse_error &ex )
107 appendError(
QgsErrorMessage( tr(
"Error parsing response: %1" ).arg( ex.what() ), QStringLiteral(
"SensorThings" ) ) );
114QString QgsSensorThingsProvider::storageType()
const
118 return QStringLiteral(
"OGC SensorThings API" );
125 return new QgsSensorThingsFeatureSource( mSharedData );
132 return new QgsSensorThingsFeatureIterator(
new QgsSensorThingsFeatureSource( mSharedData ),
true, request );
139 return mSharedData->mGeometryType;
142long long QgsSensorThingsProvider::featureCount()
const
151 const long long count = mSharedData->featureCount();
152 if ( !mSharedData->error().isEmpty() )
153 pushError( mSharedData->error() );
158QgsFields QgsSensorThingsProvider::fields()
const
162 return mSharedData->mFields;
169 return mLayerMetadata;
172QString QgsSensorThingsProvider::htmlMetadata()
const
180 metadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) % tr(
"Entity Type" ) % QStringLiteral(
"</td><td>%1" ).arg(
qgsEnumValueToKey( mSharedData->mEntityType ) ) % QStringLiteral(
"</td></tr>\n" );
181 metadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) % tr(
"Endpoint" ) % QStringLiteral(
"</td><td><a href=\"%1\">%1</a>" ).arg( mSharedData->mEntityBaseUri ) % QStringLiteral(
"</td></tr>\n" );
186QgsVectorDataProvider::Capabilities QgsSensorThingsProvider::capabilities()
const
197void QgsSensorThingsProvider::setDataSourceUri(
const QString &uri )
199 mSharedData = std::make_shared< QgsSensorThingsSharedData >( uri );
207 return mSharedData->mSourceCRS;
215 return mSharedData->extent();
221QString QgsSensorThingsProvider::name()
const
225 return SENSORTHINGS_PROVIDER_KEY;
228QString QgsSensorThingsProvider::providerKey()
230 return SENSORTHINGS_PROVIDER_KEY;
235 mSharedData = qobject_cast<QgsSensorThingsProvider *>( source )->mSharedData;
238QString QgsSensorThingsProvider::description()
const
240 return SENSORTHINGS_PROVIDER_DESCRIPTION;
243void QgsSensorThingsProvider::reloadProviderData()
246 mSharedData->clearCache();
254QgsSensorThingsProviderMetadata::QgsSensorThingsProviderMetadata():
255 QgsProviderMetadata( QgsSensorThingsProvider::SENSORTHINGS_PROVIDER_KEY, QgsSensorThingsProvider::SENSORTHINGS_PROVIDER_DESCRIPTION )
259QIcon QgsSensorThingsProviderMetadata::icon()
const
265QList<QgsDataItemProvider *> QgsSensorThingsProviderMetadata::dataItemProviders()
const
267 return {
new QgsSensorThingsDataItemProvider() };
270QVariantMap QgsSensorThingsProviderMetadata::decodeUri(
const QString &uri )
const
274 QVariantMap components;
275 components.insert( QStringLiteral(
"url" ), dsUri.
param( QStringLiteral(
"url" ) ) );
279 components.insert( QStringLiteral(
"authcfg" ), dsUri.
authConfigId() );
283 components.insert( QStringLiteral(
"username" ), dsUri.
username() );
287 components.insert( QStringLiteral(
"password" ), dsUri.
password() );
295 if ( !dsUri.
param( QStringLiteral(
"referer" ) ).isEmpty() )
297 components.insert( QStringLiteral(
"referer" ), dsUri.
param( QStringLiteral(
"referer" ) ) );
299 if ( !dsUri.
param( QStringLiteral(
"http-header:referer" ) ).isEmpty() )
301 components.insert( QStringLiteral(
"referer" ), dsUri.
param( QStringLiteral(
"http-header:referer" ) ) );
304 const QString entityParam = dsUri.
param( QStringLiteral(
"entity" ) );
313 const int maxPageSizeParam = dsUri.
param( QStringLiteral(
"pageSize" ) ).toInt( &ok );
316 components.insert( QStringLiteral(
"pageSize" ), maxPageSizeParam );
323 components.insert( QStringLiteral(
"geometryType" ), QStringLiteral(
"multipoint" ) );
325 components.insert( QStringLiteral(
"geometryType" ), QStringLiteral(
"point" ) );
328 components.insert( QStringLiteral(
"geometryType" ), QStringLiteral(
"line" ) );
331 components.insert( QStringLiteral(
"geometryType" ), QStringLiteral(
"polygon" ) );
342QString QgsSensorThingsProviderMetadata::encodeUri(
const QVariantMap &parts )
const
345 dsUri.
setParam( QStringLiteral(
"url" ), parts.value( QStringLiteral(
"url" ) ).toString() );
347 if ( !parts.value( QStringLiteral(
"authcfg" ) ).toString().isEmpty() )
349 dsUri.
setAuthConfigId( parts.value( QStringLiteral(
"authcfg" ) ).toString() );
351 if ( !parts.value( QStringLiteral(
"username" ) ).toString().isEmpty() )
353 dsUri.
setUsername( parts.value( QStringLiteral(
"username" ) ).toString() );
355 if ( !parts.value( QStringLiteral(
"password" ) ).toString().isEmpty() )
357 dsUri.
setPassword( parts.value( QStringLiteral(
"password" ) ).toString() );
359 if ( !parts.value( QStringLiteral(
"referer" ) ).toString().isEmpty() )
361 dsUri.
setParam( QStringLiteral(
"referer" ), parts.value( QStringLiteral(
"referer" ) ).toString() );
365 parts.value( QStringLiteral(
"entity" ) ).toString() );
371 dsUri.
setParam( QStringLiteral(
"entity" ),
376 const int maxPageSizeParam = parts.value( QStringLiteral(
"pageSize" ) ).toInt( &ok );
379 dsUri.
setParam( QStringLiteral(
"pageSize" ), QString::number( maxPageSizeParam ) );
382 const QString geometryType = parts.value( QStringLiteral(
"geometryType" ) ).toString();
383 if ( geometryType.compare( QLatin1String(
"point" ), Qt::CaseInsensitive ) == 0 )
387 else if ( geometryType.compare( QLatin1String(
"multipoint" ), Qt::CaseInsensitive ) == 0 )
391 else if ( geometryType.compare( QLatin1String(
"line" ), Qt::CaseInsensitive ) == 0 )
395 else if ( geometryType.compare( QLatin1String(
"polygon" ), Qt::CaseInsensitive ) == 0 )
400 return dsUri.
uri(
false );
403QgsSensorThingsProvider *QgsSensorThingsProviderMetadata::createProvider(
const QString &uri,
const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags )
405 return new QgsSensorThingsProvider( uri, options, flags );
408QList<Qgis::LayerType> QgsSensorThingsProviderMetadata::supportedLayerTypes()
const
413QMap<QString, QgsAbstractProviderConnection *> QgsSensorThingsProviderMetadata::connections(
bool cached )
415 return connectionsProtected<QgsSensorThingsProviderConnection, QgsSensorThingsProviderConnection>( cached );
423void QgsSensorThingsProviderMetadata::deleteConnection(
const QString &name )
425 deleteConnectionProtected<QgsSensorThingsProviderConnection>( name );
430 saveConnectionProtected( connection, name );
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 ...
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 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.
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.
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.
@ ReloadData
Provider is able to force reload data.
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)
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
Setting options for creating vector data providers.