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"

Selection_onglet_observed_properties


Se rendre sur "New" afin d'ouvrir les formulaires nécéssaires

Selection_onglet_new


En bas de page, remplir l'ensemble des champs de l'ObservedProperty avant de valider l'insertion ("Insert") :

remplissage_propriete_obsprop

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".

remplissage_propriete_obsprop

  • 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".

Selection_onglet_remove

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 :

Selection_de_new_procedure

Insertion des valeurs dans les formulaires :

inserer_une_procedure

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:

inserer_une_procedure_2

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 :

modification_procedure

Affichage du menu de modification de la procedure :

modification_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" :

suppression_procedure

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 :

parametre_registersensor 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" :

new_offering

  • 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édure
  • gml: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 :

getobservaton_parameter

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="&#176;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:

getobservaton_parameter

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, property

      Resultat 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 :

quality_index_operator

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.**

offering_constellation

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 :

new_offering

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 :

new_offering_2

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 :

update_offering_1

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 :

acces_memberships_1

Le peuplement d'une offering s'effetue par glisser/deposer des procedures disponibles :

membership_offerings_1

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.

remove_offerings_1

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&section=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

Licence Creative Commons
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.