Exploiter l'Open Data SNCF

Sur l'application Retard Ligne J, j'utilise différents jeux de données publiés par la SNCF dont le jeu "Horaires théoriques des lignes Transilien au format GTFS".
Dans ce billet, je vous livre quelques informations sur ce format de données.

Le GTFS (General Transit Feed Specification), est un format informatique standardisé permettant de communiquer différentes informations relatives aux transports en commun : lignes, horaires, arrêt, emplacement des arrêts...

Les données publiées par la SNCF se composent de différents fichiers :

  • agency.txt : liste des différents réseaux (agences commerciales).  Par ex. Paris St Lazare, Paris Nord.
  • calendar.txt : liste des jours et périodes de circulation des différentes courses (services).
  • calendar_dates.txt : liste des exceptions des courses (services).
  • routes.txt : liste des lignes de transport en commun ( par ex. L, J).
  • stop_times.txt : liste des horaires prévus pour chaque arrêt de chaque mission.
  • stops.txt : liste des arrêts et stations desservis.
  • transfers.txt : listes des correspondances entre arrêts à proximité.
  • trips.txt : liste des parcours par ligne de transport.

Chaque fichier est au format CSV. Il est donc très facile d'intégrer ces données dans une base de données (MySQL, Oracle ou autre).

 

Sources de données

 

Données libérées en Open Data

agency.txt

Variable Format Définition
agency_id texte Identifiant unique du réseau (agence commerciale).
ex. "DUA854"
agency_name texte Nom complet du réseau.
ex. "Paris St Lazare"
agency_url texte URL du réseau.
ex. "http://www.transilien.com"
agency_timezone texte Fuseau horaire du réseau.
ex. "Europe/Paris"
agency_lang char(2) Langue principale utilisée (ISO 639-1).
ex. "fr"

 

calendar.txt

Variable Format Définition
service_id num. Identifiant de la course (du service).
Référencé dans trips.txt
ex. "9006"
monday 0 ou 1 0 : ne circule pas
1 : circule
tuesday 0 ou 1 0 : ne circule pas
1 : circule
wednesday 0 ou 1 0 : ne circule pas
1 : circule
thursday 0 ou 1 0 : ne circule pas
1 : circule
friday 0 ou 1 0 : ne circule pas
1 : circule
saturday 0 ou 1 0 : ne circule pas
1 : circule
sunday 0 ou 1 0 : ne circule pas
1 : circule
start_date AAAAMMJJ Début de la période
end_date AAAAMMJJ Fin de la période

 

calendar_dates.txt

Variable Format Définition
service_id num. Identifiant de la course (du service).
Référencé dans trips.txt
ex. "9006"
date AAAAMMJJ Jour de l'exception.
exception_type 1 ou 2 Type d’exception
1 : circule à cette date
2 : ne circule pas à cette date

 

routes.txt

Variable Format Définition
route_id texte Identifiant unique de la ligne.
ex. "DUA800854041"
agency_id texte Identifiant du réseau.
Référencé dans le fichier agency.txt
ex. "DUA854"
route_short_name texte Nom court de la ligne
ex. "J"
route_long_name texte Nom long de la ligne
ex. "Gare St-Lazare - Ermont Eaubonne / Vernon / Gisors"
route_desc texte Description de la ligne. Pas de donnée fournie.
route_type 0 à 7 Type de la ligne
0 : Tramway
1 : Métro
2 : Train
3 : Bus
7 : Funiculaire
route_url texte URL du site web de la ligne. Pas de donnée fournie.
route_color texte Code couleur de la ligne.
ex. "CDCD00"
route_text_color texte Code couleur du texte de la ligne
ex. "FFFFFF".

 

stop_times.txt

Variable Format Définition
trip_id texte Identifiant du parcours
Référencé dans le fichier trips.txt
arrival_time HH:MM:SS Heure d’arrivée à l’arrêt
departure_time HH:MM:SS Heure de départ à l’arrêt
stop_id texte Identifiant de l’arrêt
Référencé dans le fichier stops.txt
stop_sequence num. Numéro d’ordre de l’arrêt dans la parcours
stop_headsign texte Texte qui apparaît sur un panneau qui identifie la destination du voyage.
Equivalent à la variable trip_headsign (trips.txt).
Pas de donnée fournie.
pickup_type 0 à 3 Type d'embarquement :
0 : embarquement régulier (valeur par défaut)
1 : pas d'embarquement
2 : nécessite de prévenir l'agence par téléphone
3 : faire signe au conducteur
drop_off_type 0 à 3 Type de débarquement :
0 : débarquement régulier (valeur par défaut)
1 : pas de débarquement
2 : nécessite de prévenir l'agence par téléphone
3 : faire signe au conducteur

Attention, pour les parcours qui couvrent plusieurs jours, les heures d’arrivées et de départs seront supérieurs à 24:00:00. Par exemple, si un parcours débute à 23:30:00 et se termine à 01:45:00, les temps de passage seront 23:30:00 et 25:45:00.

 

stops.txt

Variable Format Définition
stop_id texte Identifiant unique de l’arrêt.
Arrêt physique : "StopPoint:xxx"
Arrêt commercial : "StopArea:xxx
stop_name texte Nom de l’arrêt
stop_desc texte Description de l'arrêt. Pas de donnée fournie.
stop_lat déc. Latitude de l’arrêt
stop_lon déc. Longitude de l’arrêt
zone_id   Zone tarifaire. Pas de donnée fournie.
stop_url texte URL de l'arrêt. Pas de donnée fournie.
location_type 0 ou 1 Type d’arrêt.
0 ou vide : arrêt physique (StopPoint). Un endroit où les passagers embarquent ou débarquent d'un véhicule de transport en commun.
1 : arrêt commercial (StopArea). Une structure physique ou une zone qui contient un ou plusieurs arrêts.
parent_station texte Arrêt "parent" : identifiant de l’arrêt commercial (StopArea) auquel est rattaché l’arrêt physique (StopPoint)

 

transfers.txt

Variable Format Définition
from_stop_id texte Identifiant du premier arrêt physique en correspondance (StopPoint).
to_stop_id texte Identifiant du second arrêt physique en correspondance (StopPoint).
transfer_type 0 à 3 Type de correspondance :
0 (ou vide) : point de transfert recommandé entre deux routes.
1 : point de transfert temporisé entre deux routes. Le véhicule en partance devrait attendre l'arrivée, avec un temps suffisant pour un passager de transférer entre les itinéraires.
2 : le transfert nécessite un minimum de temps entre l'arrivée et le départ pour assurer une connexion. Le temps requis pour le transfert est spécifié par min_transfer_time.
3: Les transferts ne sont pas possibles entre les itinéraires à cet endroit.
min_transfer_time int. Durée de correspondance en secondes.

 

trips.txt

Variable Format Définition
route_id texte Identifiant de la ligne.
Référencé dans le fichier routes.txt
ex. "DUA800854041"
service_id num. Identifiant de la course.
Référencé dans les fichiers calendar.txt et calendar_dates.txt
ex. "9006"
trip_id texte Identifiant unique du parcours
ex. "DUASN003104F01006-1_308190"
trip_headsign texte Code mission du parcours
ex. "3104", "PUCE", "YOLA",
direction_id 0 ou 1 Direction du trajet.
0 : aller
1 : retour
block_id   Bloc auquel appartient le voyage. Pas de donnée fournie

 

Schéma de la structure de données

La SNCF ne publie pas de fichier "service.txt" qui pourrait contenir l'ensemble des "service_id". Une telle ressource pourrait être la bienvenue pour faciliter la structure des données. En effet, certains "service_id" contenus dans "trips" n'existent pas dans "calendar" ou dans "calendar_dates". De même, les "service_id" contenus dans "calendar" n'apparaissent dans "calendar_dates" que s'il s'agit d'une exception de type 2. Inversement, dans calendar dates, un "service_id" associé à une exception de type 1 n'apparaît pas forcement dans "calendar"...

Alors, oui, je pourrais reconstruire une table "service", mais en toute honnêteté, ça me gonfle et on peut facilement s'en passer...

 

Schéma de la structure de données

 

Exemples d'utilisation

Liste des trains passant par un arrêt

Afficher la liste des départs (heures de départ, missions) des trains de la ligne J au départ de la gare de Bois Colombes le 26 mars 2017 entre 19h et 20h.

SELECT TIMES.departure_time, TRIPS.trip_headsign
FROM gtfs_stop_times as TIMES  
INNER JOIN gtfs_trips as TRIPS ON TRIPS.trip_id = TIMES.trip_id 
INNER JOIN gtfs_routes as ROUTES ON ( ROUTES.route_id = TRIPS.route_id AND ROUTES.route_type = "2" AND ROUTES.route_short_name = 'J' )
LEFT JOIN gtfs_calendar as CALENDAR ON (CALENDAR.service_id = TRIPS.service_id AND CALENDAR.sunday = 1 )
LEFT JOIN gtfs_calendar_dates as CALENDARDATES ON ( CALENDARDATES.service_id = TRIPS.service_id AND CALENDARDATES.date = '20170326' )
WHERE
TIMES.stop_id = "StopPoint:DUA8738107"
AND ( TIMES.departure_time BETWEEN '19:00:00' AND '20:00:00' )
AND
( 
  (  CALENDAR.start_date <= '20170326' AND CALENDAR.end_date >= '20170326' AND ( CALENDARDATES.exception_type IS NULL OR CALENDARDATES.exception_type != 2 ) )
  OR
  (  CALENDARDATES.exception_type = 1  )
)
ORDER BY TIMES.departure_time ASC

 

Liste des trains passant par un arrêt et leurs destinations

Afficher la liste des départs (heures de départ, missions et destinations) des trains de la ligne J au départ de la gare de Bois Colombes le 26 mars 2017 entre 19h et 20h.

SELECT TIMES.departure_time, TRIPS.trip_headsign, TIMES3.T3STOPSNAME
FROM gtfs_stop_times as TIMES 
INNER JOIN gtfs_trips as TRIPS ON TRIPS.trip_id = TIMES.trip_id 
INNER JOIN gtfs_routes as ROUTES ON ( ROUTES.route_id = TRIPS.route_id AND ROUTES.route_type = "2" AND ROUTES.route_short_name = 'J' )
LEFT JOIN gtfs_calendar as CALENDAR ON ( CALENDAR.service_id = TRIPS.service_id AND CALENDAR.sunday = 1 )
LEFT JOIN gtfs_calendar_dates as CALENDARDATES ON ( CALENDARDATES.service_id = TRIPS.service_id AND CALENDARDATES.date = '20170326' )
INNER JOIN 
(
 SELECT MAX(stop_sequence) as T2STOPSEQUENCE, trip_id 
 FROM gtfs_stop_times 
 GROUP BY trip_id
) as TIMES2 on ( TIMES2.trip_id = TIMES.trip_id  )
INNER JOIN 
(
  SELECT ST.stop_id as T3STOPID, trip_id , stop_sequence, stop_name as T3STOPSNAME
  FROM gtfs_stop_times as ST
  INNER JOIN gtfs_stops as S ON S.stop_id = ST.stop_id
) as TIMES3 on ( TIMES3.trip_id = TIMES.trip_id  AND TIMES3.stop_sequence = TIMES2.T2STOPSEQUENCE )

WHERE
TIMES.stop_id = "StopPoint:DUA8738107"
AND (TIMES.departure_time BETWEEN '19:00:00' AND '20:00:00' )
AND 
( 
  (  CALENDAR.start_date <= '20170326' AND CALENDAR.end_date >= '20170326' AND ( CALENDARDATES.exception_type IS NULL OR CALENDARDATES.exception_type != 2 ) )
  OR
  (  CALENDARDATES.exception_type = 1  )
)
ORDER BY TIMES.departure_time ASC

 

Liste des trains au départ d'un arrêt en direction d'un autre arrêt

Afficher la liste des heures de départ, des heures d'arrivées et des missions, des trains de la ligne J au départ de la gare de Bois Colombes en direction de Paris Saint Lazare le 26 mars 2017 entre 19h et 20h.

SELECT TIMES1.departure_time, TIMES2.arrival_time, TRIPS.trip_headsign
FROM gtfs_stop_times as TIMES1
INNER JOIN gtfs_stop_times as TIMES2 ON ( TIMES1.trip_id = TIMES2.trip_id AND TIMES1.stop_sequence <  TIMES2.stop_sequence )
INNER JOIN gtfs_trips as TRIPS ON TIMES1.trip_id = TRIPS.trip_id
INNER JOIN gtfs_routes ROUTES ON ( TRIPS.route_id = ROUTES.route_id AND ROUTES.route_type = "2" AND ROUTES.route_short_name = 'J' )
LEFT JOIN gtfs_calendar as CALENDAR ON ( CALENDAR.service_id = TRIPS.service_id AND CALENDAR.sunday = 1 ) 
LEFT JOIN gtfs_calendar_dates as CALENDARDATES ON (CALENDARDATES.service_id = TRIPS.service_id AND CALENDARDATES.date = '20170326')

WHERE TIMES1.stop_id = 'StopPoint:DUA8738107' AND  TIMES2.stop_id = 'StopPoint:DUA8738400' 
AND (TIMES1.departure_time BETWEEN '19:00:00' AND '20:00:00' )
AND 
( 
  (  CALENDAR.start_date <= '20170326' AND CALENDAR.end_date >= '20170326' AND ( CALENDARDATES.exception_type IS NULL OR CALENDARDATES.exception_type != 2 ) )
  OR
  (  CALENDARDATES.exception_type = 1  )
)
ORDER BY TIMES1.departure_time ASC

 

 

Étiquettes