MTES-MCT / dialog

Intégration de la réglementation de circulation dans les solutions numériques
https://dialog.beta.gouv.fr
GNU Affero General Public License v3.0
8 stars 0 forks source link

Questions diverses pour intégrer les données dans Zfe-LUJOP #696

Open quythytruong opened 3 months ago

quythytruong commented 3 months ago

Bonjour à l'équipe de DiaLog !

Je travaille sur l'intégration des données de Dialog dans l'outil Zfe-LUJOP, et après avoir passé du temps à explorer les données et leur structuration, je vous contacte avec quelques questions qui me sont venues.

Les voici, en vrac :

florimondmanca commented 3 months ago

Hello @quythytruong

Voici quelques éléments de réponse

D'après l'analyse de l'existant, regulationId est l'identifiant unique. Dans ce cas, qu'est-ce que l'identifiant id qui est un attribut (au sens xml) de trafficRegulationOrder ?

Comme tu le remarqueras dans l'API, le regulationId et le id sont identiques. En fait ils contiennent l'ID unique interne à DiaLog de l'arrêté.

En effet dans DATEX II l'attribut id et l'élément regulationId sont obligatoires. Il n'y a pas de définition pour id, mais regulationId est défini comme : "A (external) unique identification of the traffic regulation". Nous donnons la possibilité aux collectivités de renseigner un identifiant d'arrêté mais celui-ci n'est unique qu'au sein d'une organisation (collectivité, métropole, etc). Par conséquent le seul "identifiant" connu de DiaLog pouvant avoir une véritable garantie d'unicité est l'identifiant interne.

Pour l’instant, il n’y a qu’un seul élément dans la liste typeOfRegulation. Il est de type AccessRestriction en général, mais on observe aussi un arrêté de type SpeedLimit.

En effet

D'ailleurs, pour l'instant, la correspondance métier entre DATEX II et DiaLog (= à quoi correspond dans la réalité chaque élément DATEX II que nous utilisons) n'est pas documentée.

Est-ce que ce serait intéressant ?

Par exemple pour comprendre à quoi correspond un trafficRegulationOrder (arrêté), une trafficRegulation (mesure), et le typeOfRegulation (type de mesure : à ce jour interdiction de circulation, limitation de vitesse), en lien avec notre MCD.

Par ailleurs, nous avons déjà pensé qu'il serait intéressant que l'on produise et publie notre propre profil DATEX II qui liste ce que nous utilisons effectivement. En effet DATEX II est fait pour qu'on y pioche, on n'utilise jamais toute sa modélisation mais seulement une sous-partie, c'est aussi notre cas.

En pratique, pourrait-il y avoir plusieurs typeOfRegulation qui définiraient un trafficRegulation ?

Oui. Même si dans la vraie vie les interdictions de circulation sont souvent regroupées dans un même article, il est possible dans DATEX II comme dans DiaLog qu'un arrêté comporte plusieurs trafficRegulation (mesures) d'un même type.

D'après la doc sur le package TrafficRegulation, on voit sur le diagramme que la classe Condition peut porter sur la classe TrafficRegulationOrder et sur la classe TrafficRegulation. Dans le premier cas, j'en comprends que les conditions appliquée à un TrafficRegulationOrder vont se répercuter sur tous les arrêtés qui le composent. Est-ce bien cela ?

En effet DATEX II prévoit la possibilité de définir la validité temporelle à deux niveaux : au niveau global de l'arrêté (quand est valable l'arrêté en entier), et au niveau de chaque mesure. Cela permet de dire par exemple : l'arrêté est globalement valable du 1er mars au 30 mars (validité globale), mais telle mesure ne s'appliquer que la semaine du 18 au 24 mars (validité de la mesure).

Par contre c'est plutôt "les conditions appliquées à un TrafficRegulationOrder vont se répercuter sur toutes les mesures qui le composent".

Dans l'état actuel de la base, c'est plutôt le deuxième cas que l'on observe, c'est-à- dire que les conditions vont caractériser chaque arrêté (objet de la classe TrafficRegulation). Est-ce que c'est plutôt un choix de votre part de systématiquement noter les conditions pour chaque arrêté, ou doit-on s'attendre éventuellement à voir des conditions qui s'appliquent à un TrafficRegulationOrder ?

Force est de constater que la partie validité temporelle (validityByOrder) n'est pas correcte aujourd'hui.

D'une part nous mettons dans la validité de chaque mesure la validité globale de l'arrêté.

D'autre part la validité précise qu'il est possible de définir sur une mesure (valable tels jours de la semaine, de telle heure à telle heure), n'est pas encore reflétée dans le DATEX II. #435.

@johanricher Je pense qu'il faudrait prioriser ça ? Au nom de : tout ce qui peut être saisi dans l'interface DiaLog devrait être reflété dans le DATEX.

Je viens de voir le ticket https://github.com/MTES-MCT/dialog/issues/661 qui rejoint nos questionnements pour raccorder données Dialog sur le réseau routier de la BD TOPO. Actuellement, l'adressage utilisé dans Dialog n'est pas encore complètement raccordable avec le réseau routier de la BD TOPO, si j'ai bien compris ?

Du point de vue réutilisateur je ne suis pas sûr de ce que "raccordable" veut dire ici. Quel serait votre besoin de "raccordement" BD TOPO à partir de l'export DATEX II ?

Au niveau géographique, nous fournissons un GeoJSON dans l'élément locdx:geoJsonGeometry. Auriez-vous besoin d'un identifiant quelconque ? Si oui, lequel vous paraîtrait pertinent ?

Du point de vue de l'UI de saisie DiaLog, il existe en effet des cas où les utilisateurs saisi à saisir une voie présente dans la BAN qui ne sera pas forcément reconnue par la BD TOPO. Par exemple nous avons un cas avec la "Rue Saint-Denis" (nom BAN) à Saint-Ouen qui est connue comme "Rue de Saint-Denis" dans la BD TOPO. Aujourd'hui nous procédons à la correspondance par nom mais nous devrions probablement utiliser la clé d'interopérabilité entre la BAN et la BD TOPO, comme envisagé dans #661.

johanricher commented 3 months ago

D'une part nous mettons dans la validité de chaque mesure la validité globale de l'arrêté.

C'est un problème. D'un point de vue produit et impact, la priorité pour DiaLog c'est que les informations sur une "mesure"* soient correctes car c'est ce qui est diffusable dans les services de navigation. Il faut que cette partie-là soit robuste. Les informations liées à l'arrêté (regulation) sont secondaires.

Je pense qu'il faudrait prioriser ça ? Au nom de : tout ce qui peut être saisi dans l'interface DiaLog devrait être reflété dans le DATEX.

Absolument.

* Il y a eu (récemment ?) un glissement de vocabulaire il me semble, ce qu'on appelait "restriction de circulation" est devenu "mesure" ? Une correspondance métier DiaLog -> DATEX II, comme tu le suggères, ou à minima un glossaire, serait utile pour complémenter le MCD.

Sur ce sujet mon avis, comme je l'ai déjà exprimé, est qu'on devrait être le plus possible en cohérence avec le modèle de données (et vocabulaire) Datex II.

florimondmanca commented 3 months ago
  • Il y a eu (récemment ?) un glissement de vocabulaire il me semble, ce qu'on appelait "restriction de circulation" est devenu "mesure" ?

Oui et c'est reflété dans l'UI, un arrêté a désormais un "dispositif" qui est le nom d'affichage d'une liste de "mesures". Ça date du passage au multi-localisations

johanricher commented 3 months ago

Ca se modélise comment en Datex II ? quel est le mapping avec "mesure", "dispositif", "arrêté", "restriction"... ? Ca te dit de construire cette doc ensemble ? Asynchrone ou "pair documenting" ? :)

quythytruong commented 3 months ago

Merci pour votre réactivité !

D'ailleurs, pour l'instant, la correspondance métier entre DATEX II et DiaLog (= à quoi correspond dans la réalité chaque élément DATEX II que nous utilisons) n'est pas documentée.

Est-ce que ce serait intéressant ?

Pour nous, des développeurs qui ne sommes pas du métier, oui ce serait éclairant. En tout cas, tes réponses @florimondmanca m'ont permis d'éclaircir ces points de vocabulaire autour des concepts d'arrêté, de mesure et type de mesure. Même si je vois que la terminologie n'est pas encore tout à fait figée.

Du point de vue réutilisateur je ne suis pas sûr de ce que "raccordable" veut dire ici. Quel serait votre besoin de "raccordement" BD TOPO à partir de l'export DATEX II ?

Nous souhaitons réutiliser les données de DiaLog dans le cadre d'une application de calcul d'itinéraires soumis à des contraintes de circulation. Nous travaillons sur un graphe routier, où les arcs de ce graphe sont les tronçons du réseau routier de la BD TOPO (la couche troncon_de_route en particulier).

L'idée est d'associer à chaque tronçon des contraintes de circulation liées aux restrictions données par DiaLog. D'où le besoin d'apparier les localisations exprimées dans les LocationCondition sur les tronçons de route de la BD TOPO.

Il existe plusieurs possibilités d'apparier les données : via un appariement attributaire, ou géométrique, ou les deux. Le but est de trouver la méthode la plus directe, et qui couvre tous les cas de figure rencontrés.

Au niveau géographique, nous fournissons un GeoJSON dans l'élément locdx:geoJsonGeometry. Auriez-vous besoin d'un identifiant quelconque ? Si oui, lequel vous paraîtrait pertinent ?

Dans l'idéal, si on a l'id du ou des tronçon(s) de la BD TOPO (attribut cleabs) concernés par une mesure, on pourra plus facilement ajouter les contraintes sur notre graphe routier. En sachant que les changements de version de la BD TOPO pourraient aussi amener des changements dans les identifiants, il faudrait alors également renseigner systématiquement la version de la BD TOPO sur laquelle se base l'info.

florimondmanca commented 3 months ago

@quythytruong Merci pour la description de votre cas d'usage qui est finalement assez proche de ce qu'on s'attend à ce que fera un "GPS" (service d'aide au déplacement).

Dans l'idéal, si on a l'id du ou des tronçon(s) de la BD TOPO (attribut cleabs) concernés par une mesure, on pourra plus facilement ajouter les contraintes sur notre graphe routier.

Oui je pense comprendre l'idée. Ceci correspondrait à la méthode "attributaire" c'est bien ça ?

En l'état nous n'opérons pas (encore?) au niveau tronçon de route. D'autre part une LocationCondition pourra probablement concerner plusieurs tronçons. Mais ça n'est pas forcément bloquant, on pourrait le cas échéant utiliser une FeatureCollection avec pour chaque feature l'ID de tronçon correspondant.

Je me demande si ce travail d'exposer de quoi se raccorder à la BD TOPO pourrait aussi aider les GPS commerciaux (Waze, Apple Maps, etc) à se recaler sur un modèle de réseau routier de leur côté. On ne sait pas vraiment s'ils utilisent la BD TOPO, ça peut aussi être leur propre modèle.

Il existe plusieurs possibilités d'apparier les données : via un appariement attributaire, ou géométrique,

Concernant l'appariement "géométrique", de quoi pourrait-il s'agir ? Trouver de votre côté le/les tronçon(s) "les plus proches" de la géométrie exposée par DiaLog ? Cela serait peut-être l'approche la plus agnostique, c'est-à-dire permettant de se recaler aussi bien à la BD TOPO que sur un autre modèle (à nouveau je pense aux GPS commerciaux).

quythytruong commented 3 months ago

Ceci correspondrait à la méthode "attributaire" c'est bien ça ?

C'est ça :)

Concernant l'appariement "géométrique", de quoi pourrait-il s'agir ? Trouver de votre côté le/les tronçon(s) "les plus proches" de la géométrie exposée par DiaLog ? Cela serait peut-être l'approche la plus agnostique, c'est-à-dire permettant de se recaler aussi bien à la BD TOPO que sur un autre modèle (à nouveau je pense aux GPS commerciaux).

Exactement. L'appariement géométrique permettra de s'affranchir de la version de la BD TOPO, et de toute autre donnée routière.

Actuellement, dans les données DiaLog, j'ai vu 2 manières de localiser une mesure :

<conditions xsi:type="LocationCondition">
    <locationByOrder xsi:type="loc:SingleRoadLinearLocation">
        <loc:linearWithinLinearElement>
            <loc:linearElement xsi:type="loc:LinearElement">
                <loc:roadName>
                    <com:values>
                        <com:value lang="fr">Avenue du Stade de France, 93210 Saint-Denis</com:value>
                    </com:values>
                </loc:roadName>
            </loc:linearElement>
            <loc:fromPoint xsi:type="loc:DistanceFromLinearElementReferent">
                <loc:distanceAlong>0</loc:distanceAlong>
                <loc:fromReferent>
                    <loc:referentIdentifier>start</loc:referentIdentifier>
                    <loc:referentName>Pont SNCF</loc:referentName>
                    <loc:referentType>landmark</loc:referentType>
                    <loc:pointCoordinates>
                        <loc:latitude>48.917709</loc:latitude>
                        <loc:longitude>2.361931</loc:longitude>
                    </loc:pointCoordinates>
                </loc:fromReferent>
            </loc:fromPoint>
            <loc:toPoint xsi:type="loc:DistanceFromLinearElementReferent">
                <loc:distanceAlong>0</loc:distanceAlong>
                <loc:fromReferent>
                    <loc:referentIdentifier>end</loc:referentIdentifier>
                    <loc:referentName>Rue Francis de Préssensé</loc:referentName>
                    <loc:referentType>intersection</loc:referentType>
                    <loc:pointCoordinates>
                        <loc:latitude>48.919612</loc:latitude>
                        <loc:longitude>2.361700</loc:longitude>
                    </loc:pointCoordinates>
                </loc:fromReferent>
            </loc:toPoint>
        </loc:linearWithinLinearElement>
    </locationByOrder>
</conditions>

Dans ce deuxième cas, on doit s'assurer que l'adresse fournie "Avenue du Stade de France, 93210 Saint-Denis" nous aide à retrouver le bon tronçon, ainsi que les deux points GPS qui bordent le morceau de tronçon concerné.

florimondmanca commented 3 months ago

Avec le type SingleRoadLinearLocation où là, on a uniquement l'adresse du tronçon concerné, et 2 points GPS à une certaine distance du linéaire à retrouver.

Les arrêtés/mesures qui utilisent cette méthode 2 sont obsolètes, ils ont été saisis "en dur" à la main en août 2023.

À l'heure actuelle seule la méthode 1 est utilisée par DiaLog. La méthode 2 a été abandonnée justement car elle supposait d'autres calculs côté GPS, mais effectivement on n'a pas mis à jour ces arrêtés ajoutés "en dur" à l'époque. Qui ont d'ailleurs expiré de toute façon...

quythytruong commented 3 months ago

@florimondmanca c'est bon à savoir !

Dans ce cas, on ne traitera que la méthode 1 :+1:

florimondmanca commented 3 months ago

@quythytruong À toute fin utile, et à titre indicatif uniquement, le template XML que l'on utilise pour générer l'export DATEX II est dans le code source, ici : https://github.com/MTES-MCT/dialog/blob/4e2f8efed493684d563cb4699fc33aa132c84035/templates/api/regulations.xml.twig

Ça permet de voir un peu quels éléments et attributs on utilise et comment on les remplit, dans l'attente d'un glossaire et/ou d'un profil DATEX II en bonne et due forme

quythytruong commented 2 months ago

Hello @florimondmanca !

Depuis nos derniers échanges, j'ai avancé dans mes travaux d'import de données DiaLog, et actuellement j'arrive à récupérer 226 mesures actives. Est-ce que, d'après tes connaissances de la base, cet ordre de grandeur est cohérent ?

A part cela, j'ai aussi vu que vous avez récemment implémenté les périodes d'application des mesures, c'est top !

Par exemple, je vois que sur l'arrêté 018e09b3-1290-72ed-9e92-deee52fb7aec, il y a désormais un ConditionSet contenant plusieurs ValidityCondition dans lesquelles est spécifié un jour d'application (exemple : le mercredi). Je me demandais pourquoi vous n'aviez pas choisi de regrouper ces jours d'application dans un seul ValidityCondition, lorsque les horaires étaient les mêmes ?

Si je reprends l'arrêté 018e09b3-1290-72ed-9e92-deee52fb7aec, est-ce qu'on aurait pu avoir des conditions sous cette forme :

<conditions xsi:type="ValidityCondition">
    <validityByOrder>
        <com:validityStatus>definedByValidityTimeSpec</com:validityStatus>
        <com:validityTimeSpecification>
            <com:overallStartTime>2017-08-30T00:00:00+00:00</com:overallStartTime>
            <com:overallEndTime>2099-12-31T23:00:00+00:00</com:overallEndTime>
            <com:validPeriod>
                <com:recurringDayWeekMonthPeriod>
                    <com:applicableDay>wednesday</com:applicableDay>
                    <com:applicableDay>sunday</com:applicableDay>
                    <com:applicableDay>friday</com:applicableDay>
                    <com:applicableDay>monday</com:applicableDay>
                    <com:applicableDay>tuesday</com:applicableDay>
                </com:recurringDayWeekMonthPeriod>
            </com:validPeriod>
        </com:validityTimeSpecification>
    </validityByOrder>
</conditions>
</conditions>

?

Dans l'état actuel de la base, pour cet arrêté, j'observe 11 ValidityCondition dans lesquels on a des doublons et même une condition qui ne comporte pas de jour d'application.

Evidemment, ma question est orientée pour me simplifier dans ma tâche d'import de données, mais peut-être que vous avez de bonnes raisons de procéder comme vous le faites actuellement. En tout cas je reste intéressée de comprendre le choix qui a été fait ici :)

florimondmanca commented 2 months ago

Salut @quythytruong :wave:

Depuis nos derniers échanges, j'ai avancé dans mes travaux d'import de données DiaLog, et actuellement j'arrive à récupérer 226 mesures actives. Est-ce que, d'après tes connaissances de la base, cet ordre de grandeur est cohérent ?

Plutôt cohérent, oui !

Dans la base nous avons précisément 249 mesures publiées (244 interdictions de circulation et 5 limitations de vitesse) qui ont des localisations valides (avec géométrie non-null). Chacune de ces mesures est sensée donner lieu à un élément trafficRegulation.

A part cela, j'ai aussi vu que vous avez récemment implémenté les périodes d'application des mesures, c'est top !

Oui c'est un ajout récent :+1: C'était un oubli de notre part, content que ça serve.

Par exemple, je vois que sur l'arrêté 018e09b3-1290-72ed-9e92-deee52fb7aec,

Pour info, dans le cas de cet arrêté qui est permanent, les dates de fin au 31/12/2099 à 23h00 (UTC) sont vouées à être retirées, il n'y aura plus qu'une date de début, je vais d'ailleurs ouvrir une PR pour le faire. C'était un fix temporaire en attendant #622.

Pour les périodes, effectivement on ne fait pas de regroupement automatique dans l'export DATEX à ce stade. Les données de cet arrêté proviennent d'une source extérieure (la base de données BAC-IDF) et lors de son intégration nous ne faisons pas de regroupement particulier sur les périodes non plus.

En tout cas effectivement cet arrêté-là est étrange... Je vais ouvrir un ticket car c'est peut-être un edge case dans l'export des périodes d'application (ou alors un problème dans les données sources de BAC-IDF).

quythytruong commented 2 months ago

Dans la base nous avons précisément 249 mesures publiées (244 interdictions de circulation et 5 limitations de vitesse) qui ont des localisations valides (avec géométrie non-null).

Hm, je vais chercher quelles mesures j'ai laissé passer... Merci pour ta réponse !

Pour les périodes, effectivement on ne fait pas de regroupement automatique dans l'export DATEX à ce stade

D'accord, donc pour le moment, je vais parcourir chaque période rencontrée dans un ConditionSet. D'ailleurs, peux-tu me confirmer que si plusieurs ValidityCondition sont au sein d'un même ConditionSet, ils ont les mêmes dates et horaires d'application ?

quythytruong commented 2 months ago

Juste pour être sûre, quand tu dis "249 mesures publiées" , c'est que parmi ces mesures, certaines ne sont plus applicables à date ?

florimondmanca commented 2 months ago

D'ailleurs, peux-tu me confirmer que si plusieurs ValidityCondition sont au sein d'un même ConditionSet, ils ont les mêmes dates et horaires d'application ?

Je ne suis pas sûr d'avoir compris, mais je dirais que non.

En effet dans le ConditionSet qui définit les périodes d'application, on a une ValidityCondition par période d'application. Or chaque période peut avoir un début et une fin différente. Par exemple, une interdiction de circulation peut s'appliquer dans un premier temps du 1er au 10 avril 2024 (première période), puis reprendre du 24 au 30 avril 2024 (seconde période).

De même entre ces périodes d'application, les jours applicables éventuels (éléments recurringDayWeekMonthPeriod) et les créneaux horaires (éléments recurringTimePeriodOfDay) peuvent varier.

Cependant le cas de cet arrêté suggère peut-être un problème plus général dans l'intégration des périodes d'application pour les arrêtés provenant de BAC-IDF... Je vais créer un ticket à ce sujet

parmi ces mesures, certaines ne sont plus applicables à date ?

Oui c'est possible, actuellement dans le DATEX on renvoie les mesures actives mais aussi celles passées / expirées