Travaux pratiques : Configuration et utilisation de IstSOS
Pré-processing
Les jeux de données doivent subir des pré-traitements afin d'être intégrées dans la base de données à l'aide des requètes http SOS ou Rest. Ces prétraitements sont dépendants du type de requètes et du mode d'insertion. Un complément d'information sera apporté en aval lors des exercices d'insertion.
Accès à la description du service
http://istsos.org/en/latest/doc/examples/getcapabilities.html
La description du service depuis notre navigateur est à l'adresse suivante:
http://localhost/istsos/monobservatoire?request=getCapabilities&service=SOS&version=1.0.0
plus d'info : Le terme monobservatoire peut etre changé en fonction du nom du service saisie dans l'Interface d'administration de istsos. monobservatoire = nom du service
Description du retour XMl :
- GetCapabilities
- DescribeSensor
- GetObservation
- RegisterSensor
- InsertObservation
L'ensemble des paramètres et des valeurs autorisées des requètes SOS sont précisées par GetCapabilities. Les valeurs autorisées (et exposées) sont parfois dépendantes des ajouts dans la base comme pour les sensors/procedures, featureOfInterest, observedProperty, offering.
Gestion de données de capteurs
Gestion des propriétés observées (ObservedProperty)
Deux options sont possibles afin d'inserer/supprimer une observedProperty dans IstSOS.
Par le client web istSOS
- Insertion Selectionner le service concerné puis se rendre sur l'onglet "Observed Properties"
Se rendre sur "New" afin d'ouvrir les formulaires nécéssaires
En bas de page, remplir l'ensemble des champs de l'ObservedProperty avant de valider l'insertion ("Insert") :
Remplisser les champs par des éléments de votre choix en essayant de respecter une certaine logique entre "Name" et "Definition URN". La propriétée description est à remplir afin de comprendre plus en detail l'observedProperty. La propriété "Quality Index" n'est pas obligatoire mais peut etre intéréssante à utiliser d'évaluer les valeur selon des "bornes" selon une grille : http://istsos.org/en/latest/doc/ws_datavalidation.html. Les valeurs bornées peuvent servir ensuite dans les requètes d'extraction pour n'avoir que celles jugées "correctes".
- Modification
Selectionner la propriété dans la liste et se rendre en bas de page afin de modifier les formulaires souhaités avant de valider la modification par "Update".
- Suppression
Selectionner d'abord une propriété dans la liste (celle que vous venez de créer/modifier) avant de la supprimer avec "Remove selected" à coté de "New".
Par une requète de l'APi REST
L'insertion, la suppréssion ou la modification en REST (reposant sur le protocol http) peuvent être réalisées par la méthode POST, DELETE, ou PUT. Le protocole http peut quant à lui étre implémenté avec de nombreux langages et leur bibliothèques associées. Nous utiliserons ici cURL (client URL request library) une bibliothèque développée en langage C reposant sur la bibliothèque "libcurl".
L'API REST est plutot destinée à un usage interne pour la gestion de votre service par le biais de scripts et utilisation de langage de programmation.
Liste des opérations possibles avec l'API REST : http://istsos.org/en/latest/doc/examples/istsos_wa.html
- Insertion
Requète d'insertion d'une observedProperty par la methode POST :
curl --location --request POST 'http://localhost/istsos/wa/istsos/services/monobservatoire/observedproperties' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--header 'Content-Type: text/plain' \
--data-raw '{
"name": "lake-water-level-test",
"definition": "urn:ogc:def:parameter:x-istsos:1.0:lake:water:level-test",
"description": "lake water level",
"constraint": {
"interval": [
"-100",
"100"
],
"role": "urn:x-ogc:def:classifiers:x-istsos:1.0:qualityIndexCheck:level0"
}
}'
*notes:
- le contenu de la commande est disponible sur postman dans ISTSOS - REST / Requetes -Transaction / InsertObservedProperty - lake-water-level*
-
sur postman, vous pouvez visualiser différentes façons d'inserer des requètes en cliquant sur "Code"*
-
Modification
Requète de modification de l'observedProperty précédement ajouté par la methode PUT :
curl --location --request PUT 'http://localhost/istsos/wa/istsos/services/monobservatoire/observedproperties/urn:ogc:def:parameter:x-istsos:1.0:lake:water:level-test' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--header 'Content-Type: text/plain' \
--data-raw '{
"name": "lake-water-level",
"definition": "urn:ogc:def:parameter:x-istsos:1.0:lake:water:level-test",
"description": "lake water level",
"constraint": {
"interval": [
"-100",
"100"
],
"role": "urn:x-ogc:def:classifiers:x-istsos:1.0:qualityIndexCheck:level0"
}
}'
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / Requetes -Transaction / UpdateObservedProperty - lake-water-level
- Supression
Requète de suppression d'une observedProperty par la methode DELETE :
curl --location --request DELETE 'http://localhost/istsos/wa/istsos/services/monobservatoire/observedproperties/urn:ogc:def:parameter:x-istsos:1.0:lake:water:level-test' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--data-raw ''
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / Requetes -Transaction / DeleteObservedProperty - lake-water-level
Gestion des capteurs (procedure)
Avant propos : Avec istsos, l'ajout d'une procedure doit être effectueé obligatoirement après la création de l'observedProperty. La réstriction n'est cependant pas présente dans le cas d'une insertion REST (à condition de définir correctement l'observedProperty dans le body).
L'insertion d'une procedure peut être réalisée de trois façons différentes : par le client Istsos, via une requète SOS ou encore par l'utilisation de l'API REST de IstSOS. Chaque solution est dataillée directement ci-après.
Par le client web istSOS
- Insertion de capteur (procedure) :
Se rendre sur "New procedure" dans le menu du service :
Insertion des valeurs dans les formulaires :
L'ajout d'une procédure doit respecter l'insertion de paramètres obligatoires à la déscription d'un capteur selon le standard SML : - General info : Name (M), Description (O), Keywords (O) - Classification : System Type (M), Sensor Type (M) - Location : FOI name : (M), EPSG (M), Coordinate (M) - Outputs : Observed property (M), Unit of measure (M), Description (O), Statistical Quality Index Constraints (O)
M = Mandatory - O = Optional
note: Plusieurs ObservedProperties peuvent être ajoutées en cliquant sur ""add"" après avoir completé les formulaires de cette catégorie.
D'autres informations peuvent être intégrées optionnellement par le remplissage des formulaires en dessous de la procedure:
Une fois l'ensemble des informations saisies, valider l'insertion de la procedure par "Submit" au sommet des formulaires.
Modification d'un capteur (procedure) :
Se rendre sur "Procedures" dans le menu du service et cliquer sur le nom de la procedure que vous souhaitez modifier :
Affichage du menu de modification de la procedure :
note: L'ensemble des éléments sont modifiables sauf les propriétés observées par le capteur. Celles-ci sont à définir lors de la création de la procedure et ne pourront pas être modifiées par la suite. Il faut prendre en compte que les données sont ajoutées au capteur avec le même pas temporel peu importe le nombre de propriétés observées.
Supression d'un capteur (procedure) :
Se rendre sur "Procedures" dans le menu du service, selectionner la procedure à supprimer, et cliquer sur "Delete selected" :
Par une requète SOS
Les requêtes d'insertion et réponses sont sous un format XML, la requète RegisterSensor de SOS (v 1.0.0) est basée sur le standard de description SensorML en version 1.0.1 :
source : http://istsos.org/en/latest/doc/examples/registersensor.html
Commande et contenu d'une requète SOS d'insertion de capteur "simple" :
curl --location --request POST 'http://localhost/istsos/monobservatoire' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--header 'Content-Type: application/xml' \
--data-raw '<?xml version="1.0" encoding="UTF-8"?>
<sos:RegisterSensor
service="SOS"
version="1.0.0"
xmlns:sos="http://www.opengis.net/sos/1.0"
xmlns:gml="http://www.opengis.net/gml"
xmlns:om="http://www.opengis.net/om"
xmlns:sml="http://www.opengis.net/sensorML/1.0.1"
xmlns:swe="http://www.opengis.net/swe/1.0.1"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://schemas.opengis.net/sos/1.0.0/sosRegisterSensor.xsd">
<sos:SensorDescription>
<sml:member>
<sml:System xmlns:gml="http://www.opengis.net/gml" gml:id="H_TREVANO">
<gml:name>H_TREVANO</gml:name>
<sml:identification/>
<sml:classification>
<sml:ClassifierList>
<sml:classifier name="System Type">
<sml:Term definition="urn:ogc:def:classifier:x-istsos:1.0:systemType">
<sml:value>insitu-fixed-point</sml:value>
</sml:Term>
</sml:classifier>
<sml:classifier name="Sensor Type">
<sml:Term definition="urn:ogc:def:classifier:x-istsos:1.0:sensorType">
<sml:value>humidity sensor</sml:value>
</sml:Term>
</sml:classifier>
</sml:ClassifierList>
</sml:classification>
<sml:capabilities>
<swe:DataRecord/>
</sml:capabilities>
<sml:location>
<gml:Point gml:id="trevano" srsName="EPSG:4326">
<gml:coordinates>8.961435,46.028235,350</gml:coordinates>
</gml:Point>
</sml:location>
<sml:outputs>
<sml:OutputList>
<sml:output name="output data">
<swe:DataRecord xmlns:swe="http://www.opengis.net/swe/1.0.1" definition="urn:ogc:def:dataType:x-istsos:1.0:timeSeries">
<swe:field name="Time">
<swe:Time definition="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601" gml:id="1">
<swe:uom code="iso8601"/>
</swe:Time>
</swe:field>
<swe:field name="air-relative-humidity">
<swe:Quantity definition="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:humidity:relative" gml:id="2">
<swe:uom code="%"/>
</swe:Quantity>
</swe:field>
</swe:DataRecord>
</sml:output>
</sml:OutputList>
</sml:outputs>
</sml:System>
</sml:member>
</sos:SensorDescription>
<sos:ObservationTemplate>
<om:Observation>
<om:procedure xlink:href="urn:ogc:object:procedure:x-istsos:1.0:H_TREVANO"/>
<om:samplingTime>
<gml:TimePeriod>
<gml:TimeLength/>
</gml:TimePeriod>
</om:samplingTime>
<om:observedProperty>
<swe:CompositePhenomenon dimension="2">
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601"/>
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:humidity:relative"/>
</swe:CompositePhenomenon>
</om:observedProperty>
<om:featureOfInterest xlink:href="trevano">
<gml:FeatureCollection>
<gml:location>
<gml:Point gml:id="trevano" srsName="EPSG:4326">
<gml:coordinates>8.961435,46.028235,350</gml:coordinates>
</gml:Point>
</gml:location>
</gml:FeatureCollection>
</om:featureOfInterest>
<om:result>
<swe:DataArray>
<swe:elementCount>
<swe:value>2</swe:value>
</swe:elementCount>
<swe:elementType name="SimpleDataArray" xlink:href="urn:ogc:def:dataType:x-istsos:1.0:timeSeriesDataRecord">
<swe:DataRecord xmlns:swe="http://www.opengis.net/swe/1.0.1" definition="urn:ogc:def:dataType:x-istsos:1.0:timeSeries">
<swe:field name="Time">
<swe:Time definition="urn:ogc:def:parameter:x-istsos::time:iso8601" gml:id="1">
<swe:uom code="iso8601"/>
</swe:Time>
</swe:field>
<swe:field name="air-relative-humidity">
<swe:Quantity definition="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:humidity:relative" gml:id="2">
<swe:uom code="%"/>
</swe:Quantity>
</swe:field>
</swe:DataRecord>
</swe:elementType>
<swe:encoding>
<swe:TextBlock blockSeparator="@" decimalSeparator="." tokenSeparator=","/>
</swe:encoding>
<swe:values/>
</swe:DataArray>
</om:result>
</om:Observation>
</sos:ObservationTemplate>
</sos:RegisterSensor>'
note: le contenu de la commande est disponible sur postman dans ISTSOS - SOS / Requetes -Transaction / RegisterSensor - H_TREVANO - Simple
Exercice 1 : - Inserer le capteur H_TREVANO à composante "simple" via une requète http (Post) registerSensor. - Réaliser l'insertion en utilisant Postman ou en ligne de commande. - Observez la reponse de la requète d'insertion : un identifiant unique est créé pour le capteur. - Verifier la présence du capteur dans la base via le client IstSOS et une requète GetCapabilities.
Il est aussi possible de rajouter directement le fichier xml en pointant la position de celui-ci à la place du contenu de la requète :
curl --location --request POST 'http://localhost/istsos/monobservatoire' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--header 'Content-Type: application/xml' \
--data-binary '@/chemin vers le fichier xml'
Commande et contenu d'une requète SOS d'insertion de capteur "complexe" :
curl --location --request POST 'http://localhost/istsos/monobservatoire' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--header 'Content-Type: application/xml' \
--data-raw '<?xml version="1.0" encoding="UTF-8"?>
<sos:RegisterSensor
service="SOS"
version="1.0.0"
xmlns:sos="http://www.opengis.net/sos/1.0"
xmlns:gml="http://www.opengis.net/gml"
xmlns:om="http://www.opengis.net/om"
xmlns:sml="http://www.opengis.net/sensorML/1.0.1"
xmlns:swe="http://www.opengis.net/swe/1.0.1"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://schemas.opengis.net/sos/1.0.0/sosRegisterSensor.xsd">
<sos:SensorDescription>
<sml:member>
<sml:System
xmlns:gml="http://www.opengis.net/gml" gml:id="LOCARNO">
<!--System Description-->
<gml:description>temperature weather station in Locarno</gml:description>
<gml:name>LOCARNO</gml:name>
<!--System Search Keywords-->
<sml:keywords>
<sml:KeywordList>
<sml:keyword>weather</sml:keyword>
<sml:keyword>station</sml:keyword>
<sml:keyword>meteorological</sml:keyword>
</sml:KeywordList>
</sml:keywords>
<!--System Identifiers-->
<sml:identification>
<sml:IdentifierList>
<sml:identifier name="uniqueID">
<sml:Term definition="urn:ogc:def:identifier:OGC:uniqueID">
<sml:value>urn:ogc:def:procedure:x-istsos:1.0:LOCARNO</sml:value>
</sml:Term>
</sml:identifier>
<sml:identifier name="deviceID">
<sml:Term definition="urn:x-ogc:def:identifier:x-istsos:1.0:deviceID">
<sml:value>TDSCHSMWLLUGANO</sml:value>
</sml:Term>
</sml:identifier>
<sml:identifier name="serialNumber">
<sml:Term definition="urn:x-ogc:def:identifier:x-istsos:1.0:serialNumber">
<sml:value>EXZU70012987712ABC</sml:value>
</sml:Term>
</sml:identifier>
<sml:identifier name="modelNumber">
<sml:Term definition="urn:x-ogc:def:identifier:x-istsos:1.0:modelNumber">
<sml:value>TDS-001</sml:value>
</sml:Term>
</sml:identifier>
<sml:identifier name="manufacturerName">
<sml:Term definition="urn:x-ogc:def:identifier:x-istsos:1.0:manufacturerName">
<sml:value>Technical Department - SUPSI</sml:value>
</sml:Term>
</sml:identifier>
<sml:identifier name="longName">
<sml:Term definition="urn:x-ogc:def:identifier:x-istsos:1.0:longName">
<sml:value>weather sensors model 001</sml:value>
</sml:Term>
</sml:identifier>
<sml:identifier name="shortName">
<sml:Term definition="urn:x-ogc:def:identifier:x-istsos:1.0:shortName">
<sml:value>CHS001</sml:value>
</sml:Term>
</sml:identifier>
</sml:IdentifierList>
</sml:identification>
<!--System Classifiers-->
<sml:classification>
<sml:ClassifierList>
<sml:classifier name="System Type">
<sml:Term definition="urn:ogc:def:classifier:x-istsos:1.0:systemType">
<sml:value>insitu-fixed-point</sml:value>
</sml:Term>
</sml:classifier>
<sml:classifier name="Sensor Type">
<sml:Term definition="urn:ogc:def:classifier:x-istsos:1.0:sensorType">
<sml:value>"Davis weather station"</sml:value>
</sml:Term>
</sml:classifier>
</sml:ClassifierList>
</sml:classification>
<!--System Capabilities-->
<sml:capabilities>
<swe:DataRecord
xmlns:swe="http://www.opengis.net/swe/1.0.1"/>
</sml:capabilities>
<!--Relevant Contacts-->
<sml:contact
xmlns:xlink="http://www.w3.org/1999/xlink" xlink:role="urn:x-ogc:def:classifiers:x-istsos:1.0:contactType:owner">
<sml:ResponsibleParty>
<sml:individualName>Saperli</sml:individualName>
<sml:organizationName>popette</sml:organizationName>
<sml:contactInfo>
<sml:phone>
<sml:voice>0125478512</sml:voice>
<sml:facsimile>5482136547</sml:facsimile>
</sml:phone>
<sml:address>
<sml:deliveryPoint>rue du test</sml:deliveryPoint>
<sml:city>Montpellier</sml:city>
<sml:administrativeArea>Herault</sml:administrativeArea>
<sml:postalCode>34090</sml:postalCode>
<sml:country>France</sml:country>
<sml:electronicMailAddress>chou@croute.fr</sml:electronicMailAddress>
</sml:address>
<sml:onlineResource xlink:href="example.com"/>
</sml:contactInfo>
</sml:ResponsibleParty>
</sml:contact>
<sml:contact
xmlns:xlink="http://www.w3.org/1999/xlink" xlink:role="urn:x-ogc:def:classifiers:x-istsos:1.0:contactType:manufacturer">
<sml:ResponsibleParty>
<sml:organizationName>Saperlipopetto</sml:organizationName>
</sml:ResponsibleParty>
</sml:contact>
<sml:contact
xmlns:xlink="http://www.w3.org/1999/xlink" xlink:role="urn:x-ogc:def:classifiers:x-istsos:1.0:contactType:operator">
<sml:ResponsibleParty>
<sml:organizationName>Saperlipopetta</sml:organizationName>
</sml:ResponsibleParty>
</sml:contact>
<!--System Documentation-->
<sml:documentation>
<sml:Document>
<gml:description>description_capteur.pdf</gml:description>
<sml:date>2021-01-14</sml:date>
<sml:format>application/pdf</sml:format>
<sml:onlineResource
xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="test.com/description_capteur.pdf"/>
</sml:Document>
</sml:documentation>
<!--System Location-->
<sml:location>
<gml:Point gml:id="locarno" srsName="EPSG:4326">
<gml:coordinates>8.79212,46.15515,197.8</gml:coordinates>
</gml:Point>
</sml:location>
<!--System Outputs-->
<sml:outputs>
<sml:OutputList>
<sml:output name="output data">
<swe:DataRecord
xmlns:swe="http://www.opengis.net/swe/1.0.1" definition="urn:ogc:def:dataType:x-istsos:1.0:timeSeries">
<swe:field name="Time">
<swe:Time gml:id="IDT_1" definition="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601">
<swe:uom code="iso8601"/>
</swe:Time>
</swe:field>
<swe:field name="air-temperature">
<swe:Quantity gml:id="IDQ_2" definition="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature">
<swe:uom code="°C"/>
</swe:Quantity>
</swe:field>
<swe:field name="air-rainfall">
<swe:Quantity gml:id="IDQ_3" definition="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:rainfall">
<swe:uom code="mm"/>
</swe:Quantity>
</swe:field>
</swe:DataRecord>
</sml:output>
</sml:OutputList>
</sml:outputs>
</sml:System>
</sml:member>
</sos:SensorDescription>
<sos:ObservationTemplate>
<om:Observation>
<om:procedure xlink:href="urn:ogc:object:procedure:x-istsos:1.0:LOCARNO"/>
<om:samplingTime>
<gml:TimePeriod>
<gml:TimeLength/>
</gml:TimePeriod>
</om:samplingTime>
<om:observedProperty>
<swe:CompositePhenomenon dimension="2">
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601"/>
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature"/>
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:rainfall"/>
</swe:CompositePhenomenon>
</om:observedProperty>
<om:featureOfInterest xlink:href="locarno">
<gml:FeatureCollection>
<gml:location>
<gml:Point gml:id="locarno" srsName="EPSG:4326">
<gml:coordinates>8.79212,46.15515,197.8</gml:coordinates>
</gml:Point>
</gml:location>
</gml:FeatureCollection>
</om:featureOfInterest>
<om:result>
<swe:DataArray>
<swe:elementCount>
<swe:value>2</swe:value>
</swe:elementCount>
<swe:elementType name="SimpleDataArray" xlink:href="urn:ogc:def:dataType:x-istsos:1.0:timeSeriesDataRecord">
<swe:DataRecord xmlns:swe="http://www.opengis.net/swe/1.0.1" definition="urn:ogc:def:dataType:x-istsos:1.0:timeSeries">
<swe:field name="Time">
<swe:Time definition="urn:ogc:def:parameter:x-istsos:time:iso8601" gml:id="1">
<swe:uom code="iso8601"/>
</swe:Time>
</swe:field>
<swe:field name="air-temperature">
<swe:Quantity gml:id="IDQ_2" definition="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature">
<swe:uom code="°C"/>
</swe:Quantity>
</swe:field>
<swe:field name="air-rainfall">
<swe:Quantity gml:id="IDQ_3" definition="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:rainfall">
<swe:uom code="mm"/>
</swe:Quantity>
</swe:field>
</swe:DataRecord>
</swe:elementType>
<swe:encoding>
<swe:TextBlock blockSeparator="@" decimalSeparator="." tokenSeparator=","/>
</swe:encoding>
<swe:values/>
</swe:DataArray>
</om:result>
</om:Observation>
</sos:ObservationTemplate>
</sos:RegisterSensor>'
note: le contenu de la commande est disponible sur postman dans ISTSOS - SOS / Requetes -Transaction / RegisterSensor - LOCARNO - Complex
Exercice 2 : - Inserer le capteur LOCARNO à composante "complexe" via une requète http (Post) registerSensor. - Réaliser l'insertion en utilisant Postman ou en ligne de commande. - Verifier la présence du capteur dans la base via le client IstSOS et via une requète GetCapabilities. - Observer les champs de la procedure H_TREVANO et LOCARNO via le client istsos. - Consulter le remplissage dans la base de données via le client PGAdmin4 : procedure, foi, observed_properties
A savoir :
- Istsos enregistre/génère des fichiers xml pour chaque capteur inséré en plus de les ajouter à sa base de données. Leur lieu de stockage physique se trouve dans le dossier d'installation de IstSOS, ici : /usr/share/istsos/services/monobservatoire/sml
.
- D'autres elements peuvent être ajoutés à la description du capteur de façon libre en ajoutant du contenu (elements) dans le fichier XML ( requète SOS) à condition de respecter la hierarchie etablie (sml) et de faire reference autant que possible à des standards de descriptions de métadonnées existants.
Supression d'un capteur (procedure) :
Il n'y a aucun moyen de supprimer une procedure avec une requète SOS.
Par une requète de l'API REST
Avant propos : L'insertion d'un capteur avec l'API REST permet de se passer de la création au préalable de la/les ObservedProperty(ies) concernée(s). Il est alors impératif de préciser clairement chaque ObersevedProperty.
Commande et contenu d'une requète permettant l'insertion de capteur "simple" avec l'API REST de Istsos :
L'insertion d'une procedure s'effectue avec la methode http "POST" via la commande suivante :
curl --location --request POST 'http://localhost/istsos/wa/istsos/services/monobservatoire/procedures' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--header 'Content-Type: application/json' \
--data-raw '{
"system_id":"T_LUGANO",
"system":"T_LUGANO",
"description":"temperature weather station in Lugano",
"keywords": "weather, meteorological, IST",
"identification":[
{
"name":"uniqueID",
"definition":"urn:ogc:def:identifier:OGC:uniqueID",
"value":"urn:ogc:def:procedure:x-istsos:1.0:T_LUGANO"
}
],
"classification":[
{
"name":"System Type",
"definition":"urn:ogc:def:classifier:x-istsos:1.0:systemType",
"value":"insitu-fixed-point"
},
{
"name":"Sensor Type",
"definition":"urn:ogc:def:classifier:x-istsos:1.0:sensorType",
"value":"Davis weather station"
}
],
"characteristics":"",
"contacts":[],
"documentation":[],
"capabilities":[],
"location":{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":["8.96127","46.02723","344.1"]
},
"crs":{
"type":"name",
"properties":{"name":"4326"}
},
"properties":{
"name":"LUGANO"
}
},
"interfaces":"",
"inputs":[],
"outputs":[
{
"name":"Time",
"definition":"urn:ogc:def:parameter:x-istsos:1.0:time:iso8601",
"uom":"iso8601",
"description":"",
"constraint":{}
},
{
"name":"air-temperature",
"definition":"urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature",
"uom":"°C",
"description":"conversion from resistance to temperature",
"constraint":{
"role":"urn:ogc:def:classifiers:x-istsos:1.0:qualityIndex:check:reasonable",
"interval":["-40","60"]
}
}
],
"history":[]
}'
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / Requetes -Transaction / RegisterSensor - T_LUGANO - Simple
Modification d'un capteur (procedure) :
Comme mentionné précédment, le contenu de la procedure peut être modifié mais le FOI et les ObervedProperties ne peuvent l'être. La requète suit les mêmes paramètres dans le body que la requète POST (Insert) auquel on peut modifier les éléments souhaités.
Ce n'est plus la méthode POST mais la méthode PUT qui est utilisé à la place.
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / Requetes -Transaction / UpdateSensor - T_LUGANO
Supression d'un capteur (procedure) :
La suppression d'une procedure s'effectue avec la methode http "DELETE" via la commande suivante :
curl --location --request DELETE 'localhost/istsos/wa/istsos/services/monobservatoire/procedures/T_LUGANO' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--data-raw ''
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / Requetes -Transaction / DeleteSensor - T_LUGANO
Exercice 3 : - Inserer le capteur T_LUGANO via une requète http (Post) registerSensor utilisant l'API REST. - Réaliser l'insertion en utilisant Postman ou en ligne de commande. - Verifier la présence du capteur dans la base via le client IstSOS et une requète GetCapabilities. - Supprimer la procedure T_LUGANO. Mais ne pas oublier de la réinserer car nous en aurons besoin dans la suite du TD.
plus d'info: http://istsos.org/en/latest/doc/examples/registersensor.html
Insertion de données sur un capteur (procedure)
Avant propos: Afin de pouvoir inserer des données sur une procedure il est obligatoire de connaitre l'ID qui lui a été attribué.
Il est disponible de trois façons différentes :
- En reponse à une requète d'insertion de capteur.
- Par le client web, lors de la visualisation de son contenu sur la ligne "Sensor ID" :
- Par une requète REST avec la méthode GET sous la variable "assignedSensorId" :
http://localhost/istsos/wa/istsos/services/monobservatoire/procedures/T_LUGANO
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / Requetes -Transaction / UpdateSensor - T_LUGANO
Reponse :
{
"success": true,
"message": "Sensor Description successfully loaded",
"data": {
"assignedSensorId": "6bb258bc5cf111eb9c38080027bbaa62",
"mqtt": null,
"system_id": "T_LUGANO",
"system": "T_LUGANO", ...
Avec cet ID, il devient enfin possible d'ajouter de la donnée de trois façons différentes : Par une transaction SOS, avec l'API REST ou encore avec le script .
Par une requète SOS
L'insertion de données par une requète SOS s'effectue par la méthode POST. Seule la version 1.0 du standard SOS est compatible pour une insertion de données. Elle est basée sur le standard O&M lui aussi en version 1.0.
Dans l'exemple ci dessous, la procedure T_LUGANO va recevoir des données selon les dimensions qui lui ont été définies : urn:ogc:def:parameter:x-istsos:1.0:time:iso8601 & urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature.
Plusieurs paramètres importants sont à prendre en compte dans le contenu XML :
<sos:AssignedSensorId>
a completer avec l'id de la procedure</sos:AssignedSensorId>
<sos:ForceInsert>true</sos:ForceInsert>
: la valeur 'true' permet de spécifier que les valeurs de la base possédant une date identique à celles qui seront insérées seront écrasées.<om:procedure xlink:href="urn:ogc:def:procedure:x-istsos:1.0:T_LUGANO"/>
: le nom de la procéduregml:TimePeriod
: l'étendu temporelle des observations à enregister avec une date de debut et de fin.- Le nombre de dimension de données (observedProperty), leur ID et l'ordre de leur enregistrement.
<om:featureOfInterest xlink:href="urn:ogc:def:feature:x-istsos:1.0:Point:LUGANO"/>
: le FOI doit correspondre avec le FOI de la procedure.<swe:TextBlock blockSeparator="@" decimalSeparator="." tokenSeparator=","/>
: l'encoding des données à inserer. Dans l'exemple ci-dessous, les données à inserer seront alors présentées de cette façon :2015-06-03T14:10:00+02,0.1@2015-06-03T14:20:00+02,0.5
Requète d'insertion de données sur la procédure T_LUGANO
curl --location --request POST 'http://localhost/istsos/monobservatoire' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--header 'Content-Type: application/xml' \
--data-raw '<?xml version="1.0" encoding="UTF-8"?>
<sos:InsertObservation
xmlns:gml="http://www.opengis.net/gml"
xmlns:om="http://www.opengis.net/om/1.0"
xmlns:sos="http://www.opengis.net/sos/1.0"
xmlns:swe="http://www.opengis.net/swe"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
service="SOS"
version="1.0.0">
<sos:AssignedSensorId>03660f66453511ebbdee080027bbaa62</sos:AssignedSensorId>
<sos:ForceInsert>true</sos:ForceInsert>
<om:Observation>
<om:procedure xlink:href="urn:ogc:def:procedure:x-istsos:1.0:T_LUGANO"/>
<om:samplingTime>
<gml:TimePeriod>
<gml:beginPosition>2015-06-03T14:10:00+02</gml:beginPosition>
<gml:endPosition>2015-06-03T14:50:00+02</gml:endPosition>
</gml:TimePeriod>
</om:samplingTime>
<om:observedProperty>
<swe:CompositePhenomenon dimension="2">
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601"/>
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature"/>
</swe:CompositePhenomenon>
</om:observedProperty>
<om:featureOfInterest xlink:href="urn:ogc:def:feature:x-istsos:1.0:Point:LUGANO"/>
<om:result>
<swe:DataArray>
<swe:elementCount>
<swe:value>5</swe:value>
</swe:elementCount>
<swe:elementType name="SimpleDataArray">
<swe:DataRecord definition="urn:ogc:def:dataType:x-istsos:1.0:timeSeries">
<swe:field name="Time">
<swe:Time definition="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601"/>
</swe:field>
<swe:field name="air-temperature">
<swe:Quantity definition="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature">
<swe:uom code="°C"/>
</swe:Quantity>
</swe:field>
</swe:DataRecord>
</swe:elementType>
<swe:encoding>
<swe:TextBlock blockSeparator="@" decimalSeparator="." tokenSeparator=","/>
</swe:encoding> <swe:values>2015-06-03T14:10:00+02,0.1@2015-06-03T14:20:00+02,0.5@2015-06-03T14:30:00+02,0.6@2015-06-03T14:40:00+02,0.7@2015-06-03T14:50:00+02,0.8</swe:values>
</swe:DataArray>
</om:result>
</om:Observation>
</sos:InsertObservation>'
note: le contenu de la commande est disponible sur postman dans ISTSOS - SOS / Requetes -Transaction / InsertObservation - T_LUGANO
Exercice 4:
- Recuperer l'ID du capteur de la façon de votre choix.
- Inserer les données correspondant au capteur "T_LUGANO" dans la base de données.
Par une requète de l'API REST
L'insertion par une requète REST s'effectue encore une fois par la méthode POST. Il faut là aussi tenir compte des différents points important d'une observation (observedProperty, FOI etc...) ainsi que l'ID de la procedure concernée.
Insertion de données sur un capteur à double observedProperty:
curl --location --request POST 'localhost/istsos/wa/istsos/services/monobservatoire/operations/insertobservation' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--header 'Content-Type: application/json' \
--data-raw '{
"ForceInsert" : "true",
"AssignedSensorId" : "6695660860e811eba0ce0800272e1ca8",
"Observation" : {
"procedure": "urn:ogc:def:procedure:x-istsos:1.0:LOCARNO",
"samplingTime": {
"beginPosition": "2010-02-10T16:10:00+01:00",
"endPosition": "2010-02-10T18:00:00+01:00"
},
"observedProperty": {
"CompositePhenomenon": {
"dimension": "3"
},
"component": [
"urn:ogc:def:parameter:x-istsos:1.0:time:iso8601",
"urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature",
"urn:ogc:def:parameter:x-istsos:1.0:meteo:air:rainfal"
]
},
"featureOfInterest": {
"geom": [
"<gml:Point srsName='EPSG:4326'>",
"<gml:coordinates>'8.79212','46.15515','197.8'</gml:coordinates>",
"</gml:Point>"],
"name": "urn:ogc:object:feature:x-istsos:1.0:locarno"
},
"result": {
"DataArray": {
"elementCount": "3",
"values": [
[
"2010-02-10T16:10:00+01:00",
"12.8",
"0.2"
],
[
"2010-02-10T16:20:00+01:00",
"12.7",
"0.3"
]
,
[
"2010-02-10T16:30:00+01:00",
"12.5",
"0.2"
]
],
"field": [
{
"definition": "urn:ogc:def:parameter:x-istsos:1.0.0:time:iso8601",
"name": "Time"
},
{
"name": "air-temperature",
"definition": "urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature",
"description": "",
"uom": "°C"
},
{
"name": "air-rainfall",
"definition": "urn:ogc:def:parameter:x-istsos:1.0:meteo:air:rainfall",
"description": "",
"uom": "mm"
}
]
}
}
}
}'
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / Requetes -Transaction / InsertObservation - LOCARNO
Exercice 5 :
- Chercher l'ID du capteur LOCARNO
- Inserer les données du capteur LOCARNO avec une requète REST
Entracte : insertion d'une nouvelle procedure et son peuplement
Pour les besoins de l'explication de l'utilité d'une offering, du peuplement et des requètes getObservation, il est nécéssaire de rajouter le sensor T_NEARLU et de peupler la procedure avec des données :
- Le contenu de la commande d'insertion de la procedure est disponible sur postman dans ISTSOS - REST / Requetes -Transaction / RegisterSensor - T_NEARLU - Simple
- Le contenu de la commande d'insertion des données est disponible sur postman dans ISTSOS - SOS / Requetes -Transaction / InsertObservation - T_NEARLU*
Par le script python "csvtoistsos.py"
Une autre façon d'inserer des données sur une procédure est d'utiliser le script d'insertion "csvtoistsos.py" situé au chemin suivant : "/istsos/scripts". Ce script (que vous pouvez consulter librement), va venir parser et extraire le contenu de votre fichier CSV (.dat) afin d'envoyer des requètes REST au serveur.
Description des arguments du script avec la commande : python3 scripts/csv2istsos.py -h
usage: csv2istsos.py [-h] [-v] [-t] [-o offering] -p procedures
[procedures ...] [-m max observations] [-q quality index]
[-noqi] [-f] [-u url] -s service -w working directory
[-e file extension] [-user user name]
[-password password]
Import data from a csv file.
optional arguments:
-h, --help show this help message and exit
-v, --verbose Activate verbose debug
-t, --test Test the script, deactivating the insert observation
operations.
-o offering The name of the offering
-p procedures [procedures ...]
List of procedures to be aggregated.
-m max observations Maximum number of observations inserted per
InsertObservation request (default: 5000).
-q quality index The quality index to set for all the measures of the
CSV file, if not set into the CSV. (default: 100).
-noqi Do not export quality index
-f, --force-disabled To disable force insert
-u url IstSOS Server address IP (or domain name) used for all
request. (default: http://localhost:80/istsos).
-s service The name of the service instance.
-w working directory Working directory where the csv files are located.
-e file extension Extension of the CSV file. (default: .dat)
-user user name
-password password
Avant toute chose :
-
le fichier doit être nomé avec le nom de la procédure, suivi de la date complete de la dernière mesure et être en format csv (default en .dat) :
- exemple : T_LUGANO_20150603142000000.date
-
le fichier doit respecter une certaine hierarchie de l'information :
- 1ere ligne (en-tête) : propriétées observées dans l'ordre de leur description de capteur.
- 2eme & + : les données dans l'ordre des en-têtes, séparés par une virgule.
exemple de contenu :
urn:ogc:def:parameter:x-istsos:1.0:time:iso8601,urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature,urn:ogc:def:parameter:x-istsos:1.0:meteo:air:rainfall
2015-05-03T16:30:00.000000+0200,22.200000,0.000000
2015-05-03T16:40:00.000000+0200,22.100000,0.000000
2015-05-03T16:50:00.000000+0200,22.100000,0.000000
2015-05-03T17:00:00.000000+0200,21.800000,0.000000
Il est possible d'inserer des données sur plusieurs procedures en même temps en spécifiant leur nom dans la requète. Un seul service et une seule offering peut être utilisé à la fois dans la commande d'insertion.
La requète à executer directement dans le terminal au niveau du dossier d'installation de istsos (/usr/share/istsos) :
python3 scripts/csv2istsos.py -p T_LUGANO T_NEARLUG LOCARNO H_TREVANO -u http://localhost/istsos -s monobservatoire -w '/home/istsos/Documents/measures' -user admin -password istsos
Déroulement de la requète d'insertion :
Offering: temporary
Procedure: T_LUGANO
T_LUGANO > Sensor Description successfully loaded
T_LUGANO > GetObservation requested successfully executed
Searching: /home/istsos/Documents/measures/T_LUGANO_[0-9]*.dat
Before insert ST: T_LUGANO
> Begin: 2015-01-01T00:10:00+00:00
+ End: 2015-06-03T14:20:00+00:00
Insert ST: T_LUGANO
> Begin: 2015-05-03T16:30:00+02:00
+ End: 2015-06-03T14:20:00+00:00
> Values: 4464
> Insert observation success: True
Procedure: T_NEARLUG
T_NEARLUG > Sensor Description successfully loaded
T_NEARLUG > GetObservation requested successfully executed
Searching: /home/istsos/Documents/measures/T_NEARLUG_[0-9]*.dat
Before insert ST: T_NEARLUG
> Begin: 2015-05-03T14:30:00+00:00
+ End: 2015-06-03T14:20:00+00:00
Insert ST: T_NEARLUG
> Begin: 2015-05-03T16:30:00+02:00
+ End: 2015-06-03T14:20:00+00:00
> Values: 4464
> Insert observation success: True
Procedure: LOCARNO
LOCARNO > Sensor Description successfully loaded
LOCARNO > GetObservation requested successfully executed
Searching: /home/istsos/Documents/measures/LOCARNO_[0-9]*.dat
Before insert ST: LOCARNO
> Begin: 2010-02-10T15:10:00+00:00
+ End: 2015-06-03T12:00:00+00:00
Insert ST: LOCARNO
> Begin: 2015-05-03T16:30:00+02:00
+ End: 2015-06-03T12:00:00+00:00
> Values: 4450
> Insert observation success: True
Procedure: H_TREVANO
H_TREVANO > Sensor Description successfully loaded
H_TREVANO > GetObservation requested successfully executed
Searching: /home/istsos/Documents/measures/H_TREVANO_[0-9]*.dat
Before insert ST: H_TREVANO
Insert ST: H_TREVANO
> Begin: 2015-05-03T16:30:00+02:00
+ End: 2015-06-03T12:50:00+00:00
> Values: 4455
> Insert observation success: True
Exercice 6:
-Inserer l'ensemble des données de capteurs
note:D'autres scripts sont disponibles dans le dossier de "/istsos/scripts" qui vous sont donnés en accès libre pour utilisation comme par exemple :
registercsv.py
permettant d'ajouter des sensors à partir d'un fichier .csv .
plus d'info :http://istsos.org/en/latest/doc/examples/insertobservation.html
Lecture des métadonnées, des données et des capteurs
L'outil intègre les deux concepts de standards , a savoir , SensorML et O&M. Il est alors possible d'interroger la base de données afin d'avoir des informations sur le capteur, mais aussi sur les données associées au capteur.
Requète DescribeSensor - Description du capteur (procedure)
Ce type de requète permet de faire ressortir les informations relatives à la description d'un capteur présent dans la base de données. La requète, en plus d'interoger la base de données, va venir livrer le fichier .xml qui a été enregistré dans le dossier d'installation de IstSOS lors de l'execution de la requète RegisterSensor.
Par une requète SOS
La requète de description en SOS est sous la forme d'une requète http GET et possède les paramètres obligatoires suivants :
La requète s'écrit de la façon suivante :
http://localhost/istsos/monobservatoire?request=describeSensor&procedure=urn:ogc:def:procedure:x-istsos:1.0:T_LUGANO&outputFormat=text%2Fxml%3Bsubtype%3D%22sensorML%2F1.0.1%22&&service=SOS&version=1.0.0
note: le contenu de la commande est disponible sur postman dans ISTSOS - SOS / DescribeSensor / DescribeSensor - SOS 1.0.0 - T_LUGANO
Retour de la requète avec le format XML - sensorML v.1.0.1 :
<?xml version="1.0" encoding="UTF-8"?>
<sml:SensorML xmlns:sml="http://www.opengis.net/sensorML/1.0.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/sensorML/1.0.1 http://schemas.opengis.net/sensorML/1.0.1/sensorML.xsd" version="1.0.1" xmlns="http://www.opengis.net/sensorML/1.0.1">
<sml:member>
<sml:System xmlns:gml="http://www.opengis.net/gml" gml:id="T_LUGANO">
<!--System Description-->
<gml:description>temperature weather station in Lugano</gml:description>
<gml:name>T_LUGANO</gml:name>
<!--System Search Keywords-->
<sml:keywords>
<sml:KeywordList>
<sml:keyword>weather</sml:keyword>
<sml:keyword> meteorological</sml:keyword>
<sml:keyword> IST</sml:keyword>
</sml:KeywordList>
</sml:keywords>
<!--System Identifiers-->
<sml:identification>
<sml:IdentifierList>
<sml:identifier name="uniqueID">
<sml:Term definition="urn:ogc:def:identifier:OGC:uniqueID">
<sml:value>urn:ogc:def:procedure:x-istsos:1.0:T_LUGANO</sml:value>
</sml:Term>
</sml:identifier>
</sml:IdentifierList>
</sml:identification>
<!--System Classifiers-->
<sml:classification>
<sml:ClassifierList>
<sml:classifier name="System Type">
<sml:Term definition="urn:ogc:def:classifier:x-istsos:1.0:systemType">
<sml:value>insitu-fixed-point</sml:value>
</sml:Term>
</sml:classifier>
<sml:classifier name="Sensor Type">
<sml:Term definition="urn:ogc:def:classifier:x-istsos:1.0:sensorType">
<sml:value>Davis weather station</sml:value>
</sml:Term>
</sml:classifier>
</sml:ClassifierList>
</sml:classification>
<!--System Capabilities-->
<sml:capabilities>
<swe:DataRecord xmlns:swe="http://www.opengis.net/swe/1.0.1"/>
</sml:capabilities>
<!--System Location-->
<sml:location>
<gml:Point gml:id="loc_LUGANO" srsName="EPSG:4326">
<gml:coordinates>8.96127,46.02723,344.1</gml:coordinates>
</gml:Point>
</sml:location>
<!--System Outputs-->
<sml:outputs>
<sml:OutputList>
<sml:output name="output data">Exercice
<swe:DataRecord xmlns:swe="http://www.opengis.net/swe/1.0.1" definition="urn:ogc:def:dataType:x-istsos:1.0:timeSeries">
<swe:field name="Time">
<swe:Time definition="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601">
<swe:constraint>
<swe:AllowedTimes>
<swe:interval>2015-01-01T00:10:00.000000Z 2015-06-03T14:20:00.000000Z</swe:interval>
</swe:AllowedTimes>
</swe:constraint>
</swe:Time>
</swe:field>
<swe:field name="air-temperature">
<swe:Quantity definition="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature">
<swe:uom code="°C"/>
<swe:constraint xmlns:xlink="http://www.w3.org/1999/xlink" xlink:role="urn:ogc:def:classifiers:x-istsos:1.0:qualityIndex:check:reasonable">
<swe:AllowedValues>
<swe:interval>-40.0 60.0</swe:interval>
</swe:AllowedValues>
</swe:constraint>
</swe:Quantity>
</swe:field>
</swe:DataRecord>
</sml:output>
</sml:OutputList>
</sml:outputs>
</sml:System>
</sml:member>
</sml:SensorML>
Exercice 7 :
- Executez la requète sur votre machine.
- Repetez l'opération sur les capteurs qui sont enregistrés afin de vous familiariser avec les rendus
Par une requète Rest
La requète de description avec l'API REST est sous la forme d'une requète http GET.
La requète s'écrit de la façon suivante :
http://localhost/istsos/wa/istsos/services/monobservatoire/procedures/LOCARNO
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / DescribeSensor / DescribeSensor - LOCARNO
Résultat JSON de la requète :
{
"success": true,
"message": "Sensor Description successfully loaded",
"data": {
"assignedSensorId": "747204f25f5311eb930f080027bbaa62",
"mqtt": null,
"system_id": "LOCARNO",
"system": "LOCARNO",
"description": "temperature weather station in Locarno",
"keywords": "weather,station,meteorological",
"identification": [
{
"name": "uniqueID",
"definition": "urn:ogc:def:identifier:OGC:uniqueID",
"value": "urn:ogc:def:procedure:x-istsos:1.0:LOCARNO"
},
{
"name": "deviceID",
"definition": "urn:x-ogc:def:identifier:x-istsos:1.0:deviceID",
"value": "TDSCHSMWLLUGANO"
},
{
"name": "serialNumber",
"definition": "urn:x-ogc:def:identifier:x-istsos:1.0:serialNumber",
"value": "EXZU70012987712ABC"
},
{
"name": "modelNumber",
"definition": "urn:x-ogc:def:identifier:x-istsos:1.0:modelNumber",
"value": "TDS-001"
},
{
"name": "manufacturerName",
"definition": "urn:x-ogc:def:identifier:x-istsos:1.0:manufacturerName",
"value": "Technical Department - SUPSI"
},
{
"name": "longName",
"definition": "urn:x-ogc:def:identifier:x-istsos:1.0:longName",
"value": "weather sensors model 001"
},
{
"name": "shortName",
"definition": "urn:x-ogc:def:identifier:x-istsos:1.0:shortName",
"value": "CHS001"
}
],
"classification": [
{
"name": "System Type",
"definition": "urn:ogc:def:classifier:x-istsos:1.0:systemType",
"value": "insitu-fixed-point"
},
{
"name": "Sensor Type",
"definition": "urn:ogc:def:classifier:x-istsos:1.0:sensorType",
"value": "\"Davis weather station\""
}
],
"characteristics": "",
"capabilities": [],
"contacts": [
{
"role": "urn:x-ogc:def:classifiers:x-istsos:1.0:contactType:owner",
"organizationName": "popette",
"individualName": "Saperli",
"voice": "0125478512",
"fax": "5482136547",
"deliveryPoint": "rue du test",
"city": "Montpellier",
"administrativeArea": "Herault",
"postalcode": "34090",
"country": "France",
"email": "chou@croute.fr",
"web": "example.com"
},
{
"role": "urn:x-ogc:def:classifiers:x-istsos:1.0:contactType:manufacturer",
"organizationName": "Saperlipopetto",
"individualName": "",
"voice": "",
"fax": "",
"deliveryPoint": "",
"city": "",
"administrativeArea": "",
"postalcode": "",
"country": "",
"email": "",
"web": ""
},
{
"role": "urn:x-ogc:def:classifiers:x-istsos:1.0:contactType:operator",
"organizationName": "Saperlipopetta",
"individualName": "",
"voice": "",
"fax": "",
"deliveryPoint": "",
"city": "",
"administrativeArea": "",
"postalcode": "",
"country": "",
"email": "",
"web": ""
}
],
"documentation": [
{
"description": "description_capteur.pdf",
"link": "test.com/description_capteur.pdf",
"date": "2021-01-14",
"format": "application/pdf"
}
],
"location": {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
"8.79212",
"46.15515",
"197.8"
]
},
"crs": {
"type": "name",
"properties": {
"name": "EPSG:4326"
}
},
"properties": {
"name": "locarno"
}
},
"interfaces": "",
"inputs": [],
"outputs": [
{
"name": "Time",
"definition": "urn:ogc:def:parameter:x-istsos:1.0:time:iso8601",
"description": "",
"uom": "",
"constraint": {
"interval": [
"2010-02-10T15:10:00.000000Z",
"2015-06-03T12:00:00.000000Z"
]
}
},
{
"name": "air-temperature",
"definition": "urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature",
"description": "",
"uom": "°C"
},
{
"name": "air-rainfall",
"definition": "urn:ogc:def:parameter:x-istsos:1.0:meteo:air:rainfall",
"description": "",
"uom": "mm"
}
],
"history": []
},
"total": 0
}
Exercice 8 :
- Executez la requète sur votre machine.
- Repetez l'opération sur les capteurs qui sont enregistrés si vous le souhaitez.
note: Il n'est pas nécéssaire de spécifier le nom complet du capteur dans istsos, le nom court peut tout à fait correspondre aux valeurs attendus dans les requètes SOS et REST.
plus d'infos: http://istsos.org/en/latest/doc/examples/describesensor.html
Requètes GetObservation - Etraction de données sur un/des capteur(s) (procedure)
Par une requète SOS
La requète GetObservation en SOS utilise la méthode http GET et renvoi les informations de séléctions au format XML.
Paramètres d'une requète "GetObservation" selon la définition du standard:
Exemple d'un requète avec les paramètres suivant :
- Procedure = T_Lugano
- eventTime = 2015-05-03T16:30:00.000000+0200/2015-06-03T14:00.000000+0200
- ObservedProperty = urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature
http://localhost/istsos/monobservatoire?service=SOS&version=1.0.0&request=GetObservation&offering=temporary&procedure=urn:ogc:def:procedure:x-istsos:1.0:T_LUGANO&eventTime=2015-05-03T16:30:00.000000+0200/2015-06-03T14:00.000000+0200&observedProperty=urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature&responseFormat=text/xml;subtype="om/1.0.0"&service=SOS&version=1.0.0
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / GetObservation / GetObservation - T_Lugano - Procedure, time, property
Reponse au format XML :
<om:ObservationCollection xmlns:sos="http://www.opengis.net/sos/1.0"
xmlns:om="http://www.opengis.net/om/1.0" xmlns:swe="http://www.opengis.net/swe/1.0.1"
xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/om/1.0 http://schemas.opengis.net/om/1.0.0/om.xsd">
<gml:description>temporary offering to hold self-registered procedures/sensors waiting for service adimistration acceptance</gml:description>
<gml:name>temporary</gml:name>
<om:member>
<om:Observation>
<gml:name>T_LUGANO</gml:name>
<om:samplingTime>
<gml:TimePeriod>
<gml:beginPosition>2015-01-01T02:10:00+02:00</gml:beginPosition>
<gml:endPosition>2015-06-03T16:20:00+02:00</gml:endPosition>
<gml:duration>P153DT14H10M</gml:duration>
</gml:TimePeriod>
</om:samplingTime>
<om:procedure xlink:href="urn:ogc:def:procedure:x-istsos:1.0:T_LUGANO"/>
<om:observedProperty>
<swe:CompositePhenomenon gml:id="comp_37" dimension="2">
<gml:name>timeSeriesOfObservations</gml:name>
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601"/>
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature"/>
</swe:CompositePhenomenon>
</om:observedProperty>
<om:featureOfInterest xlink:href="urn:ogc:def:feature:x-istsos:1.0:Point:LUGANO">
<gml:FeatureCollection>
<gml:location>
<gml:Point srsName="EPSG:4326">
<gml:coordinates>8.961270000000001,46.027230000000003,344.100000000000023</gml:coordinates>
</gml:Point>
</gml:location>
</gml:FeatureCollection>
</om:featureOfInterest>
<om:result>
<swe:DataArray>
<swe:elementCount>
<swe:Count>
<swe:value>2</swe:value>
</swe:Count>
</swe:elementCount>
<swe:elementType name="SimpleDataArray">
<swe:DataRecord>
<swe:field name="Time">
<swe:Time definition="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601"/>
</swe:field>
<swe:field name="air-temperature">
<swe:Quantity definition="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature">
<swe:uom code="°C"/>
</swe:Quantity>
</swe:field>
</swe:DataRecord>
</swe:elementType>
<swe:encoding>
<swe:TextBlock tokenSeparator="," blockSeparator="@" decimalSeparator="."/>
</swe:encoding>
<swe:values>2015-05-03T16:40:00+02:00,20.810000@2015-05-03T16:50:00+02:00,20.770000@2015-05-03T17:00:00+02:00,20.580000@2015-05-03T17:10:00+02:00,20.270000@2015-05-03T17:20:00+02:00,19.960000@2015-05-03T17:30:00+02:00,19.640000@2015-05-03T17:40:00+02:00,19.610000@2015-05-03T17:50:00+02:00,19.640000@2015-05-03T18:00:00+02:00,19.610000@2015-05-03T18:10:00+02:00,19.260000@ ....
Exemple d'une requète avec les paramètres suivant :
- ObservedProperty = urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature
- featureOfInterest - bbox = 18,45 30,55
- eventTime = 2015-05-03T16:30:00.000000+0200/2015-06-03T14:00.000000+0200
http://localhost/istsos/monobservatoire?service=SOS&request=GetObservation&offering=temporary&observedProperty=urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature&responseFormat=text/xml;subtype="om/1.0.0"&service=SOS&version=1.0.0&eventTime=2015-05-03T16:30:00.000000+0200/2015-06-03T14:00.000000+0200&featureOfInterest=&<ogc:BBOX><ogc:PropertyName>the_geom</ogc:PropertyName><gml:Box srsName='EPSG:4326'><gml:coordinates>18,45 30,55</gml:coordinates></gml:Box></ogc:BBOX>&service=SOS&version=1.0.0
note: le contenu de la commande est disponible sur postman dans ISTSOS - SOS / GetObservation / GetObservation - Property, bbox
Reponse au format XML :
<om:ObservationCollection xmlns:sos="http://www.opengis.net/sos/1.0"
xmlns:om="http://www.opengis.net/om/1.0" xmlns:swe="http://www.opengis.net/swe/1.0.1"
xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/om/1.0 http://schemas.opengis.net/om/1.0.0/om.xsd">
<gml:description>temporary offering to hold self-registered procedures/sensors waiting for service adimistration acceptance</gml:description>
<gml:name>temporary</gml:name>
<om:member>
<om:Observation>
<gml:name>T_LUGANO</gml:name>
<om:samplingTime>
<gml:TimePeriod>
<gml:beginPosition>2015-01-01T02:10:00+02:00</gml:beginPosition>
<gml:endPosition>2015-06-03T16:20:00+02:00</gml:endPosition>
<gml:duration>P153DT14H10M</gml:duration>
</gml:TimePeriod>
</om:sam<om:ObservationCollection xmlns:sos="http://www.opengis.net/sos/1.0"
xmlns:om="http://www.opengis.net/om/1.0" xmlns:swe="http://www.opengis.net/swe/1.0.1"
xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/om/1.0 http://schemas.opengis.net/om/1.0.0/om.xsd">
<gml:description>temporary offering to hold self-registered procedures/sensors waiting for service adimistration acceptance</gml:description>
<gml:name>temporary</gml:name>
<om:member>
<om:Observation>
<gml:name>T_LUGANO</gml:name>
<om:samplingTime>
<gml:TimePeriod>
<gml:beginPosition>2015-01-01T02:10:00+02:00</gml:beginPosition>
<gml:endPosition>2015-06-03T16:20:00+02:00</gml:endPosition>
<gml:duration>P153DT14H10M</gml:duration>
</gml:TimePeriod>
</om:samplingTime>
<om:procedure xlink:href="urn:ogc:def:procedure:x-istsos:1.0:T_LUGANO"/>
<om:observedProperty>
<swe:CompositePhenomenon gml:id="comp_37" dimension="2">
<gml:name>timeSeriesOfObservations</gml:name>
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601"/>
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature"/>
</swe:CompositePhenomenon>
</om:observedProperty>
<om:featureOfInterest xlink:href="urn:ogc:def:feature:x-istsos:1.0:Point:LUGANO">
<gml:FeatureCollection>
<gml:location>
<gml:Point srsName="EPSG:4326">
<gml:coordinates>8.961270000000001,46.027230000000003,344.100000000000023</gml:coordinates>
</gml:Point>
</gml:location>
</gml:FeatureCollection>
</om:featureOfInterest>
<om:result>
<swe:DataArray>
<swe:elementCount>
<swe:Count>
<swe:value>2</swe:value>
</swe:Count>
</swe:elementCount>
<swe:elementType name="SimpleDataArray">
<swe:DataRecord>
<swe:field name="Time">
<swe:Time definition="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601"/>
</swe:field>
<swe:field name="air-temperature">
<swe:Quantity definition="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature">
<swe:uom code="°C"/>
</swe:Quantity>
</swe:field>
</swe:DataRecord>
</swe:elementType>
<swe:encoding>
<swe:TextBlock tokenSeparator="," blockSeparator="@" decimalSeparator="."/>
</swe:encoding>
<swe:values>2015-05-03T16:40:00+02:00,20.810000@2015-05-03T16:50:00+02:00,20.770000@2015-05-03T17:00:00+02:00,20.580000@2015-05-03T17:10:00+02:00,20.270000@2015-05-03T17:20:00+02:00,19.960000@2015-05-03T17:30:00+02:00,19.640000@2015-05-03T17:40:00+02:00,19.610000@2015-05-03T17:50:00+02:00,19.640000@2015-05-03T18:00:00+02:00,19.610000@2015-05-03T18:10:plingTime>
<om:procedure xlink:href="urn:ogc:def:procedure:x-istsos:1.0:T_LUGANO"/>
<om:observedProperty>
<swe:CompositePhenomenon gml:id="comp_37" dimension="2">
<gml:name>timeSeriesOfObservations</gml:name>
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601"/>
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature"/>
</swe:CompositePhenomenon>
</om:observedProperty>
<om:featureOfInterest xlink:href="urn:ogc:def:feature:x-istsos:1.0:Point:LUGANO">
<gml:FeatureCollection>
<gml:location>
<gml:Point srsName="EPSG:4326">
<gml:coordinates>8.961270000000001,46.027230000000003,344.100000000000023</gml:coordinates>
</gml:Point>
</gml:location>
</gml:FeatureCollection>
</om:featureOfInterest>
<om:result>
<swe:DataArray>
<swe:elementCount>
<swe:Count>
<swe:value>2</swe:value>
</swe:Count>
</swe:elementCount>
<swe:elementType name="SimpleDataArray">
<swe:DataRecord>
<swe:field name="Time">
<swe:Time definition="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601"/>
</swe:field>
<swe:field name="air-temperature">
<swe:Quantity definition="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature">
<swe:uom code="°C"/>
</swe:Quantity>
</swe:field>
</swe:DataRecord>
</swe:elementType>
<swe:encoding>
<swe:TextBlock tokenSeparator="," blockSeparator="@" decimalSeparator="."/>
</swe:encoding>
<swe:values>2015-05-03T16:40:00+02:00,20.810000@2015-05-03T16:50:00+02:00,20.770000@2015-05-03T17:00:00+02:00,20.580000@2015-05-03T17:10:00+02:00,20.270000@2015-05-03T17:20:00+02:00,19.960000@2015-05-03T17:30:00+02:00,19.640000@2015-05-03T17:40:00+02:00,19.610000@2015-05-03T17:50:00+02:00,19.640000@2015-05-03T18:00:00+02:00,19.610000@2015-05-03T18:10: ...
Etant donné que la requète ne précise pas de procedure la recherche est lancée sur toutes les stations comprises dans la BBOX et avec l'observedProcedure selectionnée.
Exemple d'une requète GetObservation avec la methode POST :
<?xml version="1.0" encoding="UTF-8"?>
<sos:GetObservation
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://schemas.opengis.net/sos/1.0.0/sosAll.xsd"
xmlns:sos="http://www.opengis.net/sos/1.0"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:om="http://www.opengis.net/om/1.0"
service="SOS" version='1.0.0'>
<!--
Get an Observation:
- in a given instant (1-many Optional)
- with EPSG code (1 Optional)
- from a specific procedure (stationary, in-situ) (1-many Optional)
- from an offering (1 Mandatory)
-->
<offering>urn:ogc:def:offering:x-istsos:1.0:temporary</offering>
<procedure>urn:ogc:def:procedure:x-istsos:1.0:BELLINZONA</procedure>
<eventTime>
<gml:TimeInstant>
<gml:timePosition>2013-01-07T00:00:00+01:00</gml:timePosition>
</gml:TimeInstant>
</eventTime>
<responseFormat>text/xml;subtype='sensorML/1.0.0'</responseFormat>
<srsName>urn:ogc:crs:EPSG:4326</srsName>
<observedProperty>urn:ogc:def:parameter:x-ist:1.0:meteo:air:temperature</observedProperty>
<observedProperty>urn:ogc:def:parameter:x-ist:1.0:meteo:air:rainfall</observedProperty>
</sos:GetObservation>
note: d'autres exemples sont disponibles à l'adresse suivante https://github.com/istSOS/istsos2/tree/master/docs/examples/xml
En plus des paramètres obligatoires que doit fournir une requète GetObservation, IstSOS offre à ses utilisateurs des paramètres supplémentaires :
- Sorties en CSV : "responseFormat=text/plain"
- Sorties en JSON : "responseFormat=application/json"
-
Agregation des données selon une durée avec l'ajout des paramètres :
- aggregateInterval: ISO 8601 Durations (P1DT = 1 Day, PT12H = 12 hours)
-
aggregateFunction: AVG, SUM, MAX, MIN
exemple ici en se basant sur la requète GetObservation de T_LUGANO avec une agregation par moyenne sur l'interval P7DT (7 jours) :
http://localhost/istsos/monobservatoire?service=SOS&version=1.0.0&request=GetObservation&offering=temporary&procedure=urn:ogc:def:procedure:x-istsos:1.0:T_LUGANO&eventTime=2015-05-03T16:30:00.000000+0200/2015-06-03T14:00.000000+0200&observedProperty=urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature&aggregateInterval=P7DT&aggregateFunction=AVG&responseFormat=text/plain&&service=SOS&version=1.0.0
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / GetObservation / GetObservation - Agregation - 7 Jours - AVG - T_Lugano - Procedure, time, propertyResultat de la requète:
urn:ogc:def:parameter:x-istsos:1.0:time:iso8601,urn:ogc:def:procedure,urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature
2015-05-10T16:30:00+02:00,T_LUGANO,15.6012519841269841
2015-05-17T16:30:00+02:00,T_LUGANO,15.1967936507936508
2015-05-24T16:30:00+02:00,T_LUGANO,17.0397123015873016
2015-05-31T16:30:00+02:00,T_LUGANO,16.6627083333333333
- Filtre sur les indexes de qualité
Faire apparaitres les indexes de qualités dans la reponse, ajouter : &qualityIndex=True
Executer une requète avec un filtre sur la qualité des données : qualityfilter=>110
Les opérateur permetant d'utiliser les filtre de qualités d'indexe sont les suivant :
Source d'une http://istsos.org/en/latest/doc/ws_dataaccess.html
Précision sur les requètes temporelles
Il est possible de réaliser plusieurs type de séléction temporelle dans une requète GetObservation :
- durée: 2012-11-19T14:00:00+01:00/2012-11-19T14:15:00+01:00
- egale: 2012-11-19T14:00:00.000+01:00
- combinaison: 2012-11-19T14:00:00+01:00/2012-11-19T14:15:00+01:00,2012-11-19T14:00:00.000+01:00
Exercice 9:
- Executer une requète GetObservation sur le seul paramètre disponible de la procédure H_TREVANO afin de sortir l'ensemble des observations enregistrées. Vous avez donc besoin de connaitre les procédures disponbiles sur H_TREVANO, et l'emprise temporelle afin de réaliser cette requète.
- Faire une sortie de ces résultats au format CSV.
- Réaliser une requète d'aggregation sur H_TREVANO sur les valeurs Max toutes les 6h (PT6H).
Par une requète Rest
La construction d'une requète REST GetObservation est relativement simple à prendre en main mais n'offre pas autant de possibilité que la requète SOS.
Construction d'une requète GetObservation :
/istsos/services/{name}/operations/ getobservation/offerings/{name}/ procedures/{*|name|name1&name2&…}/ observedproperties/{name|name1&name2}/ eventtime/{begin}/{end}|{instant}|{last}
Exercice 10:
- Faire une recherche sur LOCARNO afin d'avoir l'ensemble des valeurs disponibles sur le capteur.
- Vous pouvez trouver des informations relatives à la description des procédures disponibles et l'ensemble des valeurs nécéssaires aux paramètres de GetObservation via la requète REST suivante :
http://localhost/istsos/wa/istsos/services/monobservatoire/procedures/operations/getlist
plus d'infos: http://istsos.org/en/latest/doc/examples/getobservation.html
Gestion Procedure/Offering
Avant propos : Avec SOS 1.0.0, le concept d'Offering Observation est équivalent à celui d'une constellation de capteurs. Il permet alors de regrouper des capteurs dans une recherche par observedProperty.**
Gestion par le client IstSOS
Creation d'une offering
Toujours dans le menu du service "monobservatoire" cliquer sur "Offerings" afin de visualiser les offerings disponibles :
note: toutes les procédures créées sont automatiquement associées à l'offering "temporary" qui doit être gerer par le gestionnaire afin de specifier sa destination finale.
Cliquer sur "New" pour en créer une nouvelle offering. Des formulaires permettant la création d'une offering s'affichent, remplir les formulaires :
Cliquer enfin sur Insert en bas de page afin de valider sa création.
Modification des paramètres d'une offering
Cliquer sur l'offering nouvellement créée afin de modifier le formulaire et cliquer sur "Update" afin de valider la modification :
Peuplement d'une offering
Acceder au peuplement d'une offering en cliquant sur l'onglet "Offering-Procedure memberships" situé à coté de l'onglet "offerings" et selectionnez l'offering nouvellement créée :
Le peuplement d'une offering s'effetue par glisser/deposer des procedures disponibles :
notes: - Le peuplement est reversible, vous pouvez retirer une procedure d'une offering à tout moment ! - Un capteur peut appartenir à plusieurs Offering - Une offering peut être composée de capteurs ayant des observedProperty différentes
Supression d'une offering
Afin de supprimer il vous suffit de cliquer sur "Remove selected" après avoir selectionner l'offering souhaitée.
Ne pas la supprimer car elle nous servira plus tard afin d'illustrer les possibilités qu'offre son utilisation dans le cadre de la requète GetObservation.
Gestion par des requètes REST
Creation d'une offering
La création d'une offering s'effectue par une requète POST :
curl --location --request POST 'http://localhost/istsos/wa/istsos/services/monobservatoire/offerings' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--header 'Content-Type: text/plain' \
--data-raw '{
"name" : "meteorology",
"description" : "meteo information",
"expiration" : "",
"active" : "true"
} '
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / Offering / Offering - Create Offering
Lister les offering disponibles
La liste des offering disponible est accessible par une requète GET :
http://localhost/istsos/wa/istsos/services/monobservatoire/offerings
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / Offering / Offering - Return a detailed list of offerings
Lister les procedures disponibles
La liste des procedures reliées à une offering est accessible par une requète GET :
http://localhost/istsos/wa/istsos/services/monobservatoire/offerings/temporary/procedures/operations/memberslist
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / Offering / Offering - Return details members list of one offering
Peuplement d'une offering
La création de lien entre une procedure et une offering est réalisée par la méthode POST de l'API :
curl --location --request POST 'http://localhost/istsos/wa/istsos/services/monobservatoire/offerings/meteorology/procedures' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--header 'Content-Type: text/plain' \
--data-raw ' [
{
"offering": "meteorology",
"procedure": "T_LUGANO"
}
] '
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / Offering / Offering - Create Link procedure with Offering
Supression du lien entre une procedure et une offering
La suppresion s'effetue par la méthode DELETE en spécifiant simplement la procédure à supprimer de l'offering :
curl --location --request DELETE 'http://localhost/istsos/wa/istsos/services/monobservatoire/offerings/meteorology/procedures/T_LUGANO' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--data-raw ''
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / Offering / Offering - Delete Link procedure with Offering
Supression d'une offering
Là encore l'utilisation de la méthode DELETE permet de supprimer cette fois ci l'offering souhaité :
curl --location --request DELETE 'http://localhost/istsos/wa/istsos/services/monobservatoire/offerings/meteorology' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--header 'Content-Type: text/plain' \
--data-raw ''
note: le contenu de la commande est disponible sur postman dans ISTSOS - REST / Offering / Offering - Delete Offering
Offering et GetObservation
Le concept d'offering permet de cibler directement une constellation de capteur que l'on souhaite faire ressortir dans une requète GetObservation.
Requète SOS GetObservation sur une offering
La liste des offering disponibles est affichée via la requète GetCapabilities :
http://localhost/istsos/demo?request=getCapabilities§ion=contents&service=SOS&version=1.0.0
Requète GetObservation afin de rassembler les observations d'une même observedProperty sur une offering donnée :
http://localhost/istsos/monobservatoire?service=SOS&request=GetObservation&offering=offeringdetest&observedproperty=urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature&eventTime=2015-06-03T14:00:00+02/2015-06-03T14:51:00+02&responseFormat=text/xml;subtype=%27sensorML/1.0.0%27&service=SOS&version=1.0.0
note: le contenu de la commande est disponible sur postman dans ISTSOS - SOS / Offering / GetObservation - Offering - offeringdetest
*note: on cherche ici à avoir les données de l'observedProperty urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature
sur l'offering offeringdetest
sur la plage temporelle 2015-06-03T14:00:00+02/2015-06-03T14:51:00+02
.
Subtilité de la version 2.0.0 de SOS
L'utilisation de la version 2.0.0 du standard SOS ne permet plus l'utilisation des offering. L'offering est à présent égale au nom de la station :
http://localhost/istsos/monobservatoire?request=GetCapabilities&service=SOS&acceptVersions=2.0.0
Supplément 1 : Gestion d'un capteur mobile
Les capteurs mobiles sont une catégorie de capteur reprenant l'ensemble des concepts précédant mais en inserant une dimension spatiale pour chaque mesure. Cela se manifeste par l'insertion de propriétés x,y,z dans la description de la procédure et dans les mesures à inserer.
Nous verrons dans cet exemple uniquement l'insersion par le service SOS, l'utilisation de l'API REST est la même que pour l'insertion d'un capteur et de données.
Insertion d'un capteur mobile
Exemple d'une requète SOS Post sur un capteur mobile :
curl --location --request POST 'http://localhost/istsos/monobservatoire' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--header 'Content-Type: application/xml' \
--data-raw '<?xml version="1.0" encoding="UTF-8"?>
<sos:RegisterSensor
service="SOS"
version="1.0.0"
xmlns:sos="http://www.opengis.net/sos/1.0"
xmlns:gml="http://www.opengis.net/gml"
xmlns:om="http://www.opengis.net/om"
xmlns:sml="http://www.opengis.net/sensorML/1.0.1"
xmlns:swe="http://www.opengis.net/swe/1.0.1"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://schemas.opengis.net/sos/1.0.0/sosRegisterSensor.xsd">
<sos:SensorDescription>
<sml:member>
<sml:System xmlns:gml="http://www.opengis.net/gml" gml:id="mobile-test">
<gml:name>mobile-test</gml:name>
<sml:identification/>
<sml:classification>
<sml:ClassifierList>
<sml:classifier name="System Type">
<sml:Term definition="urn:ogc:def:classifier:x-istsos:1.0:systemType">
<sml:value>insitu-mobile-point</sml:value>
</sml:Term>
</sml:classifier>
<sml:classifier name="Sensor Type">
<sml:Term definition="urn:ogc:def:classifier:x-istsos:1.0:sensorType">
<sml:value>humidity sensor</sml:value>
</sml:Term>
</sml:classifier>
</sml:ClassifierList>
</sml:classification>
<sml:capabilities>
<swe:DataRecord/>
</sml:capabilities>
<sml:location>
<gml:Point gml:id="mobile_test_" srsName="EPSG:4326">
<gml:coordinates>9,43,100</gml:coordinates>
</gml:Point>
</sml:location>
<sml:outputs>
<sml:OutputList>
<sml:output name="output data">
<swe:DataRecord xmlns:swe="http://www.opengis.net/swe/1.0.1" definition="urn:ogc:def:dataType:x-istsos:1.0:timeSeries">
<swe:field name="Time">
<swe:Time definition="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601">
<swe:uom code="iso8601"/>
</swe:Time>
</swe:field>
<swe:field name="Time">
<swe:Time definition="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601">
<swe:uom code="iso8601"/>
</swe:Time>
</swe:field>
<swe:field name="x">
<swe:Quantity definition="urn:ogc:crs:EPSG:4326:x-position">
<swe:uom code=""/>
</swe:Quantity>
</swe:field>
<swe:field name="y">
<swe:Quantity definition="urn:ogc:crs:EPSG:4326:y-position">
<swe:uom code=""/>
</swe:Quantity>
</swe:field>
<swe:field name="z">
<swe:Quantity definition="urn:ogc:crs:EPSG:4326:z-position">
<swe:uom code=""/>
</swe:Quantity>
</swe:field>
<swe:field name="air-temperature">
<swe:Quantity definition="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature">
<swe:uom code="°C"/>
</swe:Quantity>
</swe:field>
</swe:DataRecord>
</sml:output>
</sml:OutputList>
</sml:outputs>
</sml:System>
</sml:member>
</sos:SensorDescription>
<sos:ObservationTemplate>
<om:Observation>
<om:procedure xlink:href="urn:ogc:object:procedure:x-istsos:1.0:mobile-test"/>
<om:samplingTime>
<gml:TimePeriod>
<gml:TimeLength/>
</gml:TimePeriod>
</om:samplingTime>
<om:observedProperty>
<swe:CompositePhenomenon dimension="5">
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601"/>
<swe:component xlink:href="urn:ogc:crs:EPSG:4326:x-position"/>
<swe:component xlink:href="urn:ogc:crs:EPSG:4326:y-position"/>
<swe:component xlink:href="urn:ogc:crs:EPSG:4326:z-position"/>
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature"/>
</swe:CompositePhenomenon>
</om:observedProperty>
<om:featureOfInterest xlink:href="mobile-test_">
<gml:FeatureCollection>
<gml:location>
<gml:Point gml:id="mobile_test_" srsName="EPSG:4326">
<gml:coordinates>9,43,100</gml:coordinates>
</gml:Point>
</gml:location>
</gml:FeatureCollection>
</om:featureOfInterest>
<om:result>
<swe:DataArray>
<swe:elementCount>
<swe:value>5</swe:value>
</swe:elementCount>
<swe:elementType name="SimpleDataArray">
<swe:DataRecord xmlns:swe="http://www.opengis.net/swe/1.0.1" definition="urn:ogc:def:dataType:x-istsos:1.0:timeSeries">
<swe:field name="Time">
<swe:Time definition="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601">
<swe:uom code="iso8601"/>
</swe:Time>
</swe:field>
<swe:field name="x">
<swe:Quantity definition="urn:ogc:crs:EPSG:4326:x-position">
<swe:uom code=""/>
</swe:Quantity>
</swe:field>
<swe:field name="y">
<swe:Quantity definition="urn:ogc:crs:EPSG:4326:y-position">
<swe:uom code=""/>
</swe:Quantity>
</swe:field>
<swe:field name="z">
<swe:Quantity definition="urn:ogc:crs:EPSG:4326:z-position">
<swe:uom code=""/>
</swe:Quantity>
</swe:field>
<swe:field name="air-temperature">
<swe:Quantity definition="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature">
<swe:uom code="°C"/>
</swe:Quantity>
</swe:field>
</swe:DataRecord>
</swe:elementType>
<swe:encoding>
<swe:TextBlock blockSeparator="@" decimalSeparator="." tokenSeparator=","/>
</swe:encoding>
<swe:values/>
</swe:DataArray>
</om:result>
</om:Observation>
</sos:ObservationTemplate>
</sos:RegisterSensor>'
note: le contenu de la commande est disponible sur postman dans ISTSOS - SOS / Requetes - Transaction / RegisterSensor - Mobile-Point - test
Insertion de données sur un capteur mobile
Problème apres mise à jour PostGis, besoin de modifier le fichier IOresponse.py en ligne 576 :
- Ouvrez le fichier IOresponse.py :
sudo gedit '/usr/share/istsos/istsoslib/responders/IOresponse.py'
- Modifier la ligne 576 :
ST_SetSRID(ST_MakePoint(%s, %s, %s), %s), %s))"""
>>>>> ST_SetSRID(ST_MakePoint(%s, %s, %s), %s), %s::int))"""
Requète d'insertion de données sur un capteur mobile :
curl --location --request POST 'http://localhost/istsos/monobservatoire' \
--header 'Authorization: Basic YWRtaW46aXN0c29z' \
--header 'Content-Type: application/xml' \
--data-raw '<?xml version="1.0" encoding="UTF-8"?>
<sos:InsertObservation
xmlns:gml="http://www.opengis.net/gml"
xmlns:om="http://www.opengis.net/om/1.0"
xmlns:sos="http://www.opengis.net/sos/1.0"
xmlns:swe="http://www.opengis.net/swe"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
service="SOS"
version="1.0.0">
<sos:AssignedSensorId>5f6dde1a60b011ebb7bc080027bbaa62</sos:AssignedSensorId>
<sos:ForceInsert>true</sos:ForceInsert>
<om:Observation>
<om:procedure xlink:href="urn:ogc:def:procedure:x-istsos:1.0:mobile-test"/>
<om:samplingTime>
<gml:TimePeriod>
<gml:beginPosition>2015-06-03T14:10:00+02</gml:beginPosition>
<gml:endPosition>2015-06-03T15:15:00+02</gml:endPosition>
</gml:TimePeriod>
</om:samplingTime>
<om:observedProperty>
<swe:CompositePhenomenon dimension="5">
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601"/>
<swe:component xlink:href="urn:ogc:crs:EPSG:4326:x-position"/>
<swe:component xlink:href="urn:ogc:crs:EPSG:4326:y-position"/>
<swe:component xlink:href="urn:ogc:crs:EPSG:4326:z-position"/>
<swe:component xlink:href="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature"/>
</swe:CompositePhenomenon>
</om:observedProperty>
<om:featureOfInterest xlink:href="mobile-test_"/>
<om:result>
<swe:DataArray>
<swe:elementCount>
<swe:value>5</swe:value>
</swe:elementCount>
<swe:elementType name="SimpleDataArray">
<swe:DataRecord definition="urn:ogc:def:dataType:x-istsos:1.0:timeSeries">
<swe:field name="Time">
<swe:Time definition="urn:ogc:def:parameter:x-istsos:1.0:time:iso8601"/>
</swe:field>
<swe:field name="x">
<swe:Quantity definition="urn:ogc:crs:EPSG:4326:x-position"/>
</swe:field>
<swe:field name="y">
<swe:Quantity definition="urn:ogc:crs:EPSG:4326:y-position"/>
</swe:field>
<swe:field name="z">
<swe:Quantity definition="urn:ogc:crs:EPSG:4326:z-position"/>
</swe:field>
<swe:field name="air-temperature">
<swe:Quantity definition="urn:ogc:def:parameter:x-istsos:1.0:meteo:air:temperature">
<swe:uom code="°C"/>
</swe:Quantity>
</swe:field>
</swe:DataRecord>
</swe:elementType>
<swe:encoding>
<swe:TextBlock blockSeparator="@" decimalSeparator="." tokenSeparator=","/>
</swe:encoding> <swe:values>2015-06-03T14:10:00+02,6,43.14,100,0.1@2015-06-03T14:20:00+02,5.2145,43.258,100,0.5@2015-06-03T15:15:00+02,5.2145,43.285,100,0.8</swe:values>
</swe:DataArray>
</om:result>
</om:Observation>
</sos:InsertObservation>
'
note: le contenu de la commande est disponible sur postman dans ISTSOS - SOS / Requetes - Transaction / InsertObservation - Mobile-Point - test
Exercice 11 :
- Inserer le capteur mobile de test
- Verifier la présence du capteur avec une requète descibeSensor
- Modifier le fichier IOresponse.py
- Inserer les données de capteurs
- Executer une requète GetObservation sur le capteur afin de visualiser le contenu
Supplément 2 : Gestion d'un capteur "virtuel"
Le concept de capteur virtuel permet de réaliser des liens avec d'autres capteurs (rééls ou non) afin de :
-
les lier entre eux : exemple de capteurs le long d'une profondeur donnée (http://istsos.org/en/latest/doc/profile.html). Le but est de créer un capteur virtuel (ne contenant pas de données) à des capteurs de données le long d'une position Z. Une fois le lien réalisé, la requète GetObservation (sur la procedure virtuelle) va permettre de faire ressortir les données des deux capteurs en même temps.
-
les lier et réaliser des calculs sur les capteurs afin de fournir une nouvelle données (http://istsos.org/en/latest/doc/ws_virtualprocedures.html). Cela peut etre simplement de transformer des °C en °F jusqu'à réaliser des calculs d'evapotranspiration à partir de données de capteur in-situ. Le retour sera donc dépendant des calculs insérés.
note: il n'y a pas d'utilitaire simplifié permettant d'utiliser une syntax propre à ISTSOS, il s'agit simplement d'un script en python
Voir : http://istsos.org/en/latest/doc/ws_virtualprocedures.html
Exercice 12 :
Nous allons suivre l'exemple proposé par IstSOS à l'adresse suivante: http://istsos.org/en/latest/doc/profile.html
Plus d'information : - Detail des opérations possibles par le biais de l'utilisation de l'API REST de IstSOS : http://istsos.org/en/latest/doc/examples/istsos_wa.html - Examples des requètes SOS disponibles et etat des lieux des requètes pas encore supportées : http://istsos.org/en/latest/doc/examples.html
Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Pas de Modification 2.0 France.