Codesprint définissant 2 groupes de travail:
- Documentation
- Analyse / état de l'Art, et proposition de PoC autour de geOrchestra et SOS
Nous sommes partis d'un document de travail de Rennes-Métropole, mis à jour en mai 2017, évoquant quelques pistes concernant les logiciels implémentant les normes.
Je suis donc parti pour investiguer la webapp SOS de l'entreprise allemande 52North.
Le code source de l'application est disponible sur GitHub: https://github.com/52north/SOS/
Le projet fournit une composition docker permettant aisément de tester la solution. La composition présentant une erreur, je me suis permis d'ouvrir une anomalie sur le projet (52North/SOS#578).
Après un:
$ mvn clean package
Il est possible de lancer la composition:
$ cd docker
$ docker-compose up
Puis de naviguer sur http://localhost/52n-sos-webapp.
Mon premier réflexe, après avoir testé quelques requêtes sur le point d'entrée du service SOS (http://localhost/52n-sos-webapp/service), a été d'aller voir dans la base de données de la composition ce qui avait été créé automatiquement par la webapp à son lancement.
On se retrouve avec 54 tables dans le schéma public. Il va falloir se tourner vers JPA / Hibernate et le code source de l'applicatif si on souhaite en tirer des informations utiles.
Le dépot github en lui-même est tentaculaire, en effet l'import dans Eclipse révèle 89 projets distincts.
L'après midi a commencé en paralléle sur un partage de connaissances sur les différences standards ainsi que sur les données et services qui pourraient nous servir pour nos tests et développements.
Hervé nous présente IST-SOS, qu'ils ont eu l'occasion de tester il y a quelques années. Les sources sont disponibles ur github (https://github.com/istSOS/istsos2). Contrairement à ce que fait 52North, l'implémentation proposée ici est en Python.
Tous ces standards ont l'air de tourner autour des bases de données orientées "timeseries". Il existe d'autres domaines autour de ce concept, comme le monitoring dans le monde "devops / surveillance d'infrastructures informatiques", avec des systèmes d'informations propres (Prometheus, InfluxDB, ...). Pourquoi ne retrouve-on pas ces technologies dans les 2 mondes ? Le seul dénominateur commun à l'heure actuelle semble être postgresql.
- 52North SOS (en cours)
- istSOS
- open-Sensor-hub
Modification du DNS pour ajouter un CNAME sur sos.georchestra.org, installation d'un 52north sur le serveur.
Le github est ici: https://github.com/opensensorhub/osh-core, mais difficile de savoir si c'est effectivement le "bon" projet (à priori on en cherche un qui permet de générer une webapp).
Les tests ne passent pas dans gradle, une fois désactivés, la compilation passe, mais on n'a pas de webapp générée. En s'attardant un peu sur la documentation (http://docs.opensensorhub.org/dev/dev-guide/#building-from-source), aucune trace de la chaîne "webapp" dans le dépot.
Francois indique que partir des binaires fournis par le projet est peut-être plus pertinent pour une expérimentation rapide.
Par Francois VdB (aspects SOS), Zoé & Fabrice (aspects doc).
9h00: on passe les logs de postgresql pour afficher toutes les requêtes qui passent, on trashe la base de données et on recommence, l'idée étant de voir ce qui est touché niveau persistence en base lors de l'insertion de données de capteurs via SOS transactionnel.
Après quelques essais, on récupère les dumps des logs et on analyse dans quoi la webapp écrit lors des différents appels transactionnels.
Mael part sur l'idée d'insérer quelques données, je compte plutot voir ce qui importe un peu dans le protocole et les points d'entrée des différentes opérations.
- GetCapabilities: http://localhost/52n-sos-webapp/service?service=SOS&request=GetCapabilities
- GetObservation: http://localhost/52n-sos-webapp/service?service=SOS&request=GetObservation&version=2.0.0
Le GetObservation nécessite un paramêtre de version, mais rien permettant de limiter à un capteur en particulier ?! D'après le GetCapabilities précédent, l'opération accepte les paramêtres suivants:
- featureOfInterest
- observedProperty
- offering
- procedure
Ainsi que deux paramêtres permettant de filtrer sur critères spatiaux et temporels (spatialFilter et temporalFilter).
Il faudrait passer un peu de temps dans la norme et comprendre ce qui se cachent derrière chacun de ces concepts.
- DescribeSensor:
Nécessite les paramêtres procedure
et procedureDescriptionFormat
. Les
valeurs possibles sont renvoyées par la réponse du GetCapabilities.
Pour procedure
:
<ows:Parameter name="procedure">
<ows:AllowedValues>
<ows:Value>http://rennesmetropole.fr/comptage_routier_auto/procedure/1</ows:Value>
<ows:Value>http://www.52north.org/test/procedure/1</ows:Value>
</ows:AllowedValues>
</ows:Parameter>
Pour ProcedureDescriptionFormat
:
<ows:Parameter name="procedureDescriptionFormat">
<ows:AllowedValues>
<ows:Value>http://inspire.ec.europa.eu/schemas/ompr/3.0</ows:Value>
<ows:Value>http://www.opengis.net/sensorML/1.0.1</ows:Value>
<ows:Value>http://www.opengis.net/sensorml/2.0</ows:Value>
<ows:Value>http://www.opengis.net/waterml/2.0/observationProcess</ows:Value>
</ows:AllowedValues>
</ows:Parameter>
D'après Wikipedia, il semble que la seule intéressante soit InsertObservation (mais nécessite déjà que le capteur soit référencé, via une opération RegisterSensor).
Si on analyse le GetCapabilities, nous avons besoin des 2 paramêtre suivant sur une opération d'insertion:
<ows:Parameter name="observation">
<ows:AnyValue/>
<ows:DataType ows:reference="http://schemas.opengis.net/om/2.0/observation.xsd#OM_Observation"/>
</ows:Parameter>
<ows:Parameter name="offering">
<ows:AllowedValues>
<ows:Value>http://rennesmetropole.fr/comptage_routier_auto/offering/1</ows:Value>
<ows:Value>http://www.52north.org/test/offering/1</ows:Value>
</ows:AllowedValues>
</ows:Parameter>
On retrouve les 2 capteurs de Mael insérés précédemment dans les valeurs possibles d'"offering". Pour la valeur du paramêtre observation, c'est un peu plus complexe, car on doit utiliser un objet XML dont un exemple peut être trouvé sur la page suivante:
http://www.ral.ucar.edu/projects/css-wx/external/wxxm/doc/2.0.0-RC2/xsd/om_2_0.html
<om:OM_Observation xmlns:om="http://www.opengis.net/om/2.0">
<om:type>{0,1}</om:type>
<om:metadata>{0,1}</om:metadata>
<om:relatedObservation>{0,unbounded}</om:relatedObservation>
<om:phenomenonTime>{1,1}</om:phenomenonTime>
<om:resultTime>{1,1}</om:resultTime>
<om:validTime>{0,1}</om:validTime>
<om:procedure>{1,1}</om:procedure>
<om:parameter>{0,unbounded}</om:parameter>
<om:observedProperty>{1,1}</om:observedProperty>
<om:featureOfInterest>{1,1}</om:featureOfInterest>
<om:resultQuality>{0,unbounded}</om:resultQuality>
<om:result>{1,1}</om:result>
</om:OM_Observation>
Finalement, l'interface cliente de 52North propose des exemples permettant de générer des requêtes XML de type InsertObservation, ci-après:
<?xml version="1.0" encoding="UTF-8"?>
<sos:InsertObservation
xmlns:sos="http://www.opengis.net/sos/2.0"
xmlns:swes="http://www.opengis.net/swes/2.0"
xmlns:swe="http://www.opengis.net/swe/2.0"
xmlns:sml="http://www.opengis.net/sensorML/1.0.1"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:om="http://www.opengis.net/om/2.0"
xmlns:sams="http://www.opengis.net/samplingSpatial/2.0"
xmlns:sf="http://www.opengis.net/sampling/2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" service="SOS" version="2.0.0" xsi:schemaLocation="http://www.opengis.net/sos/2.0 http://schemas.opengis.net/sos/2.0/sos.xsd
http://www.opengis.net/samplingSpatial/2.0 http://schemas.opengis.net/samplingSpatial/2.0/spatialSamplingFeature.xsd">
<sos:offering>http://www.52north.org/test/offering/9</sos:offering>
<sos:observation>
<om:OM_Observation gml:id="o1">
<om:type xlink:href="http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_CountObservation"/>
<om:phenomenonTime>
<gml:TimeInstant gml:id="phenomenonTime">
<gml:timePosition>2012-11-19T13:45:15.000+00:00</gml:timePosition>
</gml:TimeInstant>
</om:phenomenonTime>
<om:resultTime xlink:href="#phenomenonTime"/>
<om:procedure xlink:href="http://www.52north.org/test/procedure/9"/>
<om:observedProperty xlink:href="http://www.52north.org/test/observableProperty/9_2"/>
<om:featureOfInterest>
<sams:SF_SpatialSamplingFeature gml:id="ssf_test_feature_9">
<gml:identifier codeSpace="">http://www.52north.org/test/featureOfInterest/9</gml:identifier>
<gml:name>52°North</gml:name>
<sf:type xlink:href="http://www.opengis.net/def/samplingFeatureType/OGC-OM/2.0/SF_SamplingPoint"/>
<sf:sampledFeature xlink:href="http://www.52north.org/test/featureOfInterest/1"/>
<sams:shape>
<gml:Point gml:id="test_feature_9">
<gml:pos srsName="http://www.opengis.net/def/crs/EPSG/0/4326">51.935101100104916 7.651968812254194</gml:pos>
</gml:Point>
</sams:shape>
</sams:SF_SpatialSamplingFeature>
</om:featureOfInterest>
<om:result xsi:type="xs:integer">3</om:result>
</om:OM_Observation>
</sos:observation>
</sos:InsertObservation>
cf. le sous-répertoire "moulinette/", après une rapide tentative d'utilisation de OWSLib en python (qui n'est que Read-Only), je pense que ne coupera pas à utiliser du "bare-metal" XML si on souhaite créer des objets de facon automatique dans 52North.
Nous espérons parvenir à insérer les données de capteurs de Rennes-Métropole sur le comptage des véhicules. Mael est parti sur l'utilisation de templates pour "insérer en batch", tandis que je cherche toujours à importer les valeurs une par une avec l'opération précédente.
Je dois toutefois créer un nouveau capteur acceptant l'utilisation du
CountObservation
.
- Présentation de l'équipe sur la documentation et du travail sur gitbooks.
- Restitution de l'équipe sur SOS
Une partie du travail n'a pas permis de creuser une autre norme liée à l'exploitation de données de capteurs (SensorThings), dont des implémentations existent déjà.