Dans la première partie, j’ai expliqué comment obtenir les données gtfs. Maintenant je vais importer les fichiers GTFS dans ArangoDB.
ArangoDB est une base de données, open-source gratuite en version community, développée par l’entreprise du même nom. Elle est développée en C++ et javascript et propose une IHM web pour l’administration de la BDD. ArangoDB est une base de données hybride, NoSQL et Graphe. Elle a son propre language AQL (Arango Query Language), ressemblant au SQL, qui permet de faire des requêtes.
J’ai installé la version community d’ArangoDB localement via un fichier docker compose.
services:
arangodb:
container_name: arangodb
image: arangodb:3.9.3
ports:
- "8529:8529"
command:
- "arangod"
- "--cache.size"
- "1048576"
- "--rocksdb.block-cache-size"
- "1048576"
- "--rocksdb.enforce-block-cache-size-limit"
volumes:
- arangodbdata:/var/lib/arangodb3
environment:
- ARANGO_NO_AUTH=1
volumes:
arangodbdata:
Ceci n’est pas obligatoire car il le calcule automatiquement suivant la taille totale de votre mémoire RAM. J’ai ajouté un réglage sur la taille du cache. Ceci n’est pas obligatoire il le calcule automatiquement suivant la taille totale de votre mémoire RAM
ArangoDB contient des bases de données qui contiennent des collections. ArangoDB à une base _SYSTEM à partir de laquelle nous pouvons ajouter des bases de données ou bien accéder au dashboard.
Il y a différents types de collections : le type Document ou le type Edges.
Les documents contiennent des objets JSON. Ils sont considérés comme les sommets (vertex) de la bdd graph.
{
"_id": "stops/IDFM:monomodalStopPlace:47052", // l'id de l'objet formé du nom de la collection et sa clef
"_rev": "_e3we666---", /* la révision est générée à la création du document et est mise à jour
à la modification ou au remplacement. Il est en lecture seule pour l'utilisateur.*/
"_key": "IDFM:monomodalStopPlace:47052", // la clef de l'objet
... // les données
}
Les “edges” contiennent des objets JSON qui seront des arêtes.
Les arêtes font partie de la définition des graphes. Ils décrivent quelles collections d’arêtes (edges) connectent quelles collections de sommets (vertex).
Les collections d’arêtes auront également un index d’arêtes créé automatiquement, qui ne peut pas être modifié. Cet index permet un accès rapide aux documents via les attributs _from et _to.
{
"_id":"part_of_stop/251428286",
"_rev":"_e3wf-uq--C",
"_key":"251428286",
"_from":"stops/IDFM:monomodalStopPlace:47052", // sommet de départ
"_to":"stops/IDFM:62951" // sommet d'arrivé
}
Les documents peuvent avoir des index de types différents.
La description des index est ici : https://www.arangodb.com/docs/stable/http/indexes.html
FOR vertex, edge, path
IN min..max
ANY startVertex
edgeCollection1, ..., edgeCollectionN
Un parcours commence à un document spécifique (startVertex) et suit toutes les arêtes connectées à ce document. Pour tous les documents (sommets) qui sont ciblés par ces bords, il suivra à nouveau tous les bords qui leurs sont connectés et ainsi de suite. Il est possible de définir combien de ces itérations suivantes doivent être exécutées au minimum et maximum.
Dans le but d’importer les données du GTFS dans la base de données j’ai créé un script qui permet d’importer automatiquement dans la base.
Voici le modèle de donnée de type graphe que je souhaite :
Schéma du graphe :
Voici le projet sur gihub pour l’import :
https://github.com/gregoire78/GTFS-arangodb--import
npm run build && \
npm start
Cela peut prendre un certain temps, car il y a beaucoup de données à relier.
Une fois l’import fait on peut ouvrir la page pour faire des requêtes dans l’interface web d’ArangoDB (http://127.0.0.1:8529/_db/GTFS/)
Sélectionnez la base de données “GTFS” en haut à droite en cliquant sur “_SYSTEM”.
Il faut aller ensuite dans “QUERIES” à gauche.
Il y a des tutoriels AQL très bien sur le github.
ArrangoDB permet de faire des requêtes avec des données géographiques (coordonnées gps)
// boucle sur la collection "stops"
for s in stops
// récupère la distance (en mètre) entre le point que l'on souhaite et les points dans la collection
let d = distance(s.lat, s.lon, 48.8497477377042, 2.4180963749631648)
// filtre les points d'arrêts dans un rayon de moins d'un kilomètre
filter s.locationType == 1 and d < 1000
// ceci retourne le résultat
return {name: s.name, distance: d}
Le résultat de la requête est visible sous la forme d’une table :
Script pour afficher les noeuds qui dépendent d’un arrêt et afficher le graphe on peut exécuter le script suivant :
for s in stops
let d = distance(s.lat, s.lon, 48.8497477377042, 2.4180963749631648)
filter d < 1000
limit 1000
for stop,e,b IN 1 inbound s._id part_of_stop
return b
Maintenant il est facile de jouer avec les données pour afficher de jolies graphes.
Dans la troisième partie, le but sera de montrer la récupération de données et afficher sur une carte les horaires des points d’arrêts.