Browse Source

Add function k_neighbors

Olivier Marty 8 years ago
parent
commit
f5120513fc
3 changed files with 33 additions and 10 deletions
  1. 15 2
      geocoding.py
  2. 1 1
      main.py
  3. 17 7
      source.py

+ 15 - 2
geocoding.py

@@ -1,5 +1,6 @@
 from geopy.geocoders import Nominatim
 from geopy.distance import vincenty
+from source import *
 
 
 geolocator = Nominatim()
@@ -24,5 +25,17 @@ def dist(posa, posb):
         return vincenty(posa, posb).km
 
 p1 = position_of_location("22 rue Henri Barbusse VILLEJUIF")
-p2 = position_of_location("Université paris diderot")
-print(p1, p2, dist(p1, p2))
+#p2 = position_of_location("Université paris diderot")
+#print(p1, p2, dist(p1, p2))
+
+
+def k_neighbors(positions, fro, n):
+  """returns a list of (dist, id) of the n nearest points from fro
+  positions is a dictionary id -> (lat, long)"""
+  distances = sorted([(dist(fro, pos), id) for (id, pos) in positions.items()])
+  return distances[:n]
+
+res = k_neighbors(SourceProvider_jcdecaux_vls().dic_of_positions(), p1, 5)
+names = SourceProvider_jcdecaux_vls().dic_of_names()
+for (dist, id) in res:
+  print(names[id] + ' at ' + str(dist) + 'km')

+ 1 - 1
main.py

@@ -57,7 +57,7 @@ def main():
 
             # get useful ids of sources for this location
             ids_sources = source.from_location(event.location)
-            # flatten this dictionnary
+            # flatten this dictionary
             ids_sources_flat = [item for (key, sublist) in ids_sources.items() for item in sublist]
             # grab info from internet for these sources
             sources=source.gen_sources(ids_sources)

+ 17 - 7
source.py

@@ -10,11 +10,11 @@ class Source:
 
 class SourceProvider:
   def dic_of_names(self):
-    """Returns a dictionnary mapping ids to name (for find.py)"""
+    """Returns a dictionary mapping ids to name (for find.py)"""
     return []
 
   def dic_of_positions(self):
-    """Returns a disctionnary mapping ids to position (for geocoding.py)"""
+    """Returns a dictionary mapping ids to position (for geocoding.py)"""
     return []
 
   def sources_of_ids(self, ids):
@@ -110,12 +110,14 @@ class Source_jcdecaux_vls_empty(Source_jcdecaux_vls):
 
 class SourceProvider_jcdecaux_vls(SourceProvider):
   def __init__(self):
-    self.names = None
+    self.names = {}
+    self.positions = None
 
   def dic_of_names(self, contract=None):
-    if not self.names:
-      print('Téléchargement de la liste des stations...')
-      if contract:
+    contract = contract or 'all'
+    if contract not in self.names:
+      print('Téléchargement de la liste des stations 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:
         xml = XML(url='https://api.jcdecaux.com/vls/v1/stations?apiKey=' + config.api_key['jcdecaux_vls'], lang='json')
@@ -127,7 +129,15 @@ class SourceProvider_jcdecaux_vls(SourceProvider):
     return self.names
 
   def dic_of_positions(self):
-    return {} # TODO
+    if not self.positions:
+      print('Téléchargement de la liste des stations...')
+      xml = XML(url='https://api.jcdecaux.com/vls/v1/stations?apiKey=' + config.api_key['jcdecaux_vls'], lang='json')
+      self.positions = {}
+      for sta in xml.data.json.find_all("item", recursive=False):
+        self.positions[sta.contract_name.string.lower() + '_' + sta.number.string] =\
+          (sta.lat.string, sta.lng.string)
+        # we use find('name') because .name is the current tag name
+    return self.positions
 
   def sources_of_ids(self, ids):
     ids_set = set(map(lambda s : s.rsplit('_', 1)[0], ids))