Browse Source

Add map.py + take into account transilien in README.md and report"

Olivier Marty 8 years ago
parent
commit
80fae1b025
5 changed files with 56 additions and 19 deletions
  1. 3 2
      README.md
  2. 1 1
      main.py
  3. 27 0
      map.py
  4. 20 12
      rapport/rapport.tex
  5. 5 4
      source.py

+ 3 - 2
README.md

@@ -38,8 +38,9 @@ Pour lancer la démo :
 
 ### API utilisées
 
-RATP, jcdecaux_vls (Vélib', Vélo'V, Bicloo, etc) et Transilien (pas vraiment
-intégré car on ne connait pas (encore) la localisation des stations).
+RATP, jcdecaux_vls (Vélib', Vélo'V, Bicloo, etc) et Transilien.
+
+Une visualisation des stations connues est disponible : https://www.google.com/maps/d/edit?mid=z6ibLBE5MDrk.kudB9LIy9Cws&usp=sharing
 
 ## Note
 

+ 1 - 1
main.py

@@ -25,7 +25,7 @@ def gen_sources(sourceProviders, location):
     for sp in sourceProviders:
       # keep 2 nearest sources (and distance equivalent), if distance < 2 km
       ids_pos = {id: pos for (dist, pos, id) in k_neighbors(sp.dic_of_positions(), position, 2) if dist < 2}
-      print('Cherche les sources : ', list(ids_pos.keys()))
+      print('Cherche les sources :', list(ids_pos.keys()))
       for source in sp.sources_of_ids(ids_pos):
           yield source
 

+ 27 - 0
map.py

@@ -0,0 +1,27 @@
+from geocoding import *
+import webbrowser
+import main
+import notification
+import tempfile
+import os
+
+def str_of_pos(pos):
+  return '"' + str(pos[0]) + ',' + str(pos[1]) + '"'
+
+
+sourceProviders = [SourceProvider_ratp(),
+  SourceProvider_jcdecaux_vls(),
+  SourceProvider_transilien()]
+
+dic_inv = {}
+for sp in sourceProviders:
+    dic = sp.dic_of_positions()
+    for (id, pos) in dic.items():
+        for p in pos:
+            if not p in dic_inv:
+              dic_inv[p] = set()
+            dic_inv[p].add(id)
+
+print("position,noms")
+for (pos, ids) in dic_inv.items():
+    print(str_of_pos(pos) + ',"' + ";".join(ids) + '"')

+ 20 - 12
rapport/rapport.tex

@@ -28,8 +28,7 @@ Pour cela on se connecte à son agenda (Google Calendar), et on analyse ses emai
 (Gmail) pour prévoir ses déplacements, mais d'autres sources pourrait être
 ajoutées, de façon modulaire.
 Pour chaque événement, on géolocalise l'adresse avec l'API d'OpenStreetMap,
-puis on cherche les moyens de transport utiles pour ce rendre à ces coordonnées~:
-lignes passant par une station proche, stations de vélos proches...
+puis on cherche les moyens de transport utiles pour se rendre à ces coordonnées.
 En cas de problème sur l'un de ces moyens de transport, l'utilisateur est
 notifié par le medium de son choix (email, ou sms via l'API de free mobile).
 
@@ -50,7 +49,7 @@ le 22/02/2016 08h45\\
 pour le cours de WDM"
 
 
-\subsection{Les sources de trafic}
+\subsection{Les sources d'état du trafic}
 
 Une information concernant l'état d'un moyen de transport est représenté par un
 objet contenant un identifiant unique, un message, et un attribut booléen qui
@@ -60,16 +59,19 @@ Les données proviennent de différentes sources :
 \begin{itemize}
   \item \textbf{État des lignes de la RATP} Les données sont récupérées en scrapant l'url
   \url{http://ratp.fr/meteo/}.
-  En effet la ratp ne fournit aucune API publique dynamique (l'API statique a
+  En effet la ratp ne fournit aucune API publique dynamique (l'API statique
+  \url{http://data.ratp.fr/explore/dataset/offre-transport-de-la-ratp-format-gtfs/}
+  a
   cependant été utilisée pour obtenir la localisation des stations et les lignes
   les traversant).
 
   \item \textbf{État des lignes Transilien} Les données sont récupérées en scrapant l'url \url{http://www.transilien.com/info-trafic/temps-reel}.
-  La SNCF fournit une API pour chercher des itinéraires, ou avoir les prochains
-  horaires, mais pas, à notre connaissance, pour avoir des informations de trafic.
+  L'API SNCF (\url{https://ressources.data.sncf.com/explore/dataset/osm-mapping-idf/})
+  est par contre utilisée pour determiner la postition des stations et les
+  lignes les traversant.
 
-  \item \textbf{Vélos en libre service jcdecaux} Les données sont récupérées via
-  l'API jcdecaux\_vls (voir \url{https://developer.jcdecaux.com/#/opendata/vls}).
+  \item \textbf{Vélos en libre service JCDecaux} Les données sont récupérées via
+  l'API vls de JCDecaux (voir \url{https://developer.jcdecaux.com/#/opendata/vls}).
 \end{itemize}
 
 \subsection{La boucle principale}
@@ -104,9 +106,15 @@ différentes API.
 
 \paragraph{ratp\_preprocessing.py} Les données statiques fournies par la ratp
 n'était pas dans un format qui nous convenait, en plus de peser plus de 500Mo~!
-Ce fichier extrait de ces données la liste des stations et les lignes les
-traversant, le fichier final ne pesant que 500Ko.
-L'url ou l'on peut trouver les données brut est indiqué en
-commentaire dans ce fichier.
+Ce fichier extrait de ces données la liste des stations, leurs localisations et
+les lignes les traversant.
+Le fichier final ne pèse que 500Ko.
+L'url où l'on peut trouver les données brut est indiqués en commentaire dans ce
+fichier.
+
+\paragraph{map.py} Génère un fichier cvs contenant la liste des identifiants
+associés à des coordonnées d'intérêt.
+Une visualisation de ces données est disponible à l'adresse
+\url{https://www.google.com/maps/d/edit?mid=z6ibLBE5MDrk.kudB9LIy9Cws&usp=sharing}
 
 \end{document}

+ 5 - 4
source.py

@@ -44,7 +44,7 @@ class SourceProvider_ratp(SourceProvider):
 
   def dic_of_names(self):
     if not self.names:
-      print('Téléchargement de la liste des lignes ratp...')
+      print('Téléchargement de la liste des lignes RATP...')
       xml = XML(url='http://www.ratp.fr/meteo/', lang='html')
       self.names = {tag['id']: tag['id'].replace('_', ' ') for tag in xml.data.select('.encadre_ligne')}
     return self.names
@@ -53,6 +53,7 @@ class SourceProvider_ratp(SourceProvider):
     if not self.positions:
       self.positions = {}
       try:
+        print('Chargement de la liste des stations RATP...')
         with open("ratp.csv", "r") as stations:
           for fields in csv.reader(stations, delimiter=',', quotechar='"'):
             lines = filter(lambda l: 'bus' not in l, fields[2].split(':')) # filter out bus line
@@ -136,7 +137,7 @@ class SourceProvider_jcdecaux_vls(SourceProvider):
 
   def get_xml_all(self):
     if not self.xml_all:
-      print('Téléchargement de la liste des stations...')
+      print('Téléchargement de la liste des stations JCDecaux...')
       self.xml_all = XML(url='https://api.jcdecaux.com/vls/v1/stations?apiKey=' + config.api_key['jcdecaux_vls'], lang='json')
     return self.xml_all
 
@@ -144,7 +145,7 @@ class SourceProvider_jcdecaux_vls(SourceProvider):
     contract = contract or 'all'
     if contract not in self.contracts:
       self.contracts.add(contract)
-      print('Téléchargement de la liste des stations pour le contrat ' + contract + '...')
+      print('Téléchargement de la liste des stations JCDecaux pour le contrat ' + contract + '...')
       if contract != 'all':
         xml = XML(url='https://api.jcdecaux.com/vls/v1/stations?contract=' + contract + '&apiKey=' + config.api_key['jcdecaux_vls'], lang='json')
       else:
@@ -217,7 +218,7 @@ class SourceProvider_transilien(SourceProvider):
 
   def dic_of_positions(self):
     if not self.positions:
-      print('Téléchargement de la liste des stations transilien...')
+      print('Téléchargement de la liste des stations Transilien...')
       xml = XML(url='https://ressources.data.sncf.com/api/records/1.0/search/?dataset=osm-mapping-idf&rows=1000&refine.railway=station', lang='json')
       self.positions = {}
       for sta in xml.data.json.records.find_all("item", recursive=False):