Advertisement
Guest User

kael

a guest
Jul 29th, 2008
668
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.11 KB | None | 0 0
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3.  
  4. import urllib2
  5. from xml.dom import minidom
  6. import math
  7. import re
  8.  
  9. API_KEY = 'Yahoo! API key'
  10.  
  11. class Velib:
  12.  
  13.     def __init__(self):
  14.         self.API_KEY = API_KEY
  15.         url = 'http://www.velib.paris.fr/service/carto/'
  16.         dom = minidom.parse(self.httpReq(url))
  17.         self.poi_list = []
  18.         for marker in dom.getElementsByTagName('marker'):
  19.             attrs = marker.attributes.keys()
  20.             poi_dict = {}
  21.             for attr in attrs :
  22.                 value = marker.getAttribute(attr)
  23.                 poi_dict[attr] = value
  24.             self.poi_list.append(poi_dict)
  25.        
  26.     def httpReq(self,url):
  27.         try:
  28.             response = urllib2.urlopen(url)
  29.         except HTTPError, e:
  30.             pass
  31.             #print 'Error :', str(e.code)
  32.         except URLError, e:
  33.             pass
  34.             #print 'Reason ' +  str(e.reason)
  35.         else:
  36.             return response
  37.  
  38.     # http://pravin.insanitybegins.com/posts/euclidean-distance-calculator.html  
  39.     def _parseXML(self,xml):
  40.         m = re.findall('<Latitude>(\d+.\d+)</Latitude><Longitude>(\d+.\d+)</Longitude>', xml)
  41.         return m[0]
  42.  
  43.     def getCoords(self,location):
  44.         #url = 'http://local.yahooapis.com/MapsService/V1/geocode?appid=' + self.API_KEY + '&location=' + urllib2.quote(location)
  45.         location = location.encode("utf-8", "replace")
  46.         url = 'http://local.yahooapis.com/MapsService/V1/geocode?appid=' + self.API_KEY + '&city=paris&street=' + urllib2.quote(location)
  47.         response = self.httpReq(url)
  48.         if response:
  49.             (x, y) = self._parseXML(response.read())
  50.             return {'lat':float(x), 'lng':float(y)}
  51.         else:
  52.             pass
  53.            
  54.     def getOrthodromy(self,st,end):
  55.         direction = {}
  56.         deg2rad = math.pi/180
  57.         rayonTerre = 6371
  58.         start_lat = float(st['lat']) *deg2rad
  59.         start_long = float(st['lng']) *deg2rad
  60.         end_lat = float(end['lat']) *deg2rad
  61.         end_long = float(end['lng']) *deg2rad
  62.         distance = ( math.cos(start_lat) * math.cos(end_lat) * math.cos( end_long - start_long ) + math.sin(start_lat) * math.sin(end_lat) )
  63.         if end_lat > start_lat:
  64.             direction['dir_lat'] = 'N'
  65.         else:
  66.             direction['dir_lat'] = 'S'
  67.         if end_long > start_long:
  68.             direction['dir_lon'] = 'E'
  69.         else:
  70.             direction['dir_lon'] = 'W'
  71.         return {'distance':rayonTerre * math.acos(distance), 'direction': direction}
  72.        
  73.     def checkStation(self,val,velib_poi):
  74.         for poi in velib_poi:
  75.             if poi['nb'] == val:
  76.                 return poi
  77.                
  78.     def getVelibApi(self,uid):
  79.         url = "http://www.velib.paris.fr/service/stationdetails/%s" % uid
  80.         data = minidom.parse(self.httpReq(url))
  81.     return {'free':data.getElementsByTagName("free")[0].firstChild.data,
  82.         'available':data.getElementsByTagName("available")[0].firstChild.data,
  83.         'total':data.getElementsByTagName("total")[0].firstChild.data}
  84.  
  85.     def displayResult(self,station,dispo):
  86.         try:
  87.             return '\n' + str(station['name']) + '\n' + str(station['fullAddress']) + '\n' + str(int(station['distance']*1000))+ ' ' +'mètres - ' + str(station['dir_lat']) + '/' + str(station['dir_lon'])+'\n'+str(dispo['free'])+ ' places libres - ' +str(dispo['available'])+ ' ' +'velos dispos'
  88.         except:
  89.             return '\nOops'
  90.        
  91.     def getStation(self,m,velib_poi,q):
  92.         l = sorted(m.iteritems(), key=lambda (k,v):(v,k))
  93.         i = 0
  94.         j = 5
  95.         res = ''
  96.         while i < j:
  97.             station = self.checkStation(l[i][0],velib_poi)
  98.             dispo = self.getVelibApi(station['number'])
  99.             if q == 'p':
  100.                 if dispo['free'] == '0':
  101.                     j += 1
  102.                 else:
  103.                     res += '\n' + self.displayResult(station,dispo)
  104.             if q == 'v':
  105.                 if dispo['available'] == '0':
  106.                     j += 1
  107.                 else:
  108.                     res += '\n' + self.displayResult(station,dispo)
  109.             if q == None:
  110.                 res += '\n' + self.displayResult(station,dispo)
  111.             i +=1
  112.             continue
  113.         return res
  114.  
  115.     def getPoi(self,place,q=None):
  116.         point = self.getCoords(place)
  117.         if point:
  118.             m = {}
  119.             i = 0
  120.             velib_poi = self.poi_list
  121.             while i < len(velib_poi):
  122.             poi_data = self.getOrthodromy(point,velib_poi[i])
  123.             m.update({i:poi_data['distance']})
  124.             velib_poi[i]['distance'] = poi_data['distance']
  125.             velib_poi[i]['nb'] = i
  126.             velib_poi[i]['dir_lon'] = poi_data['direction']['dir_lon']
  127.             velib_poi[i]['dir_lat'] = poi_data['direction']['dir_lat']
  128.             i +=1
  129.             continue
  130.         return self.getStation(m,velib_poi,q)
  131.     else:
  132.         return 'Something went wrong'
  133.        
  134. a = Velib()
  135.  
  136. # Afficher les 5 stations les plus proches
  137. print a.getPoi('1 place italie')
  138.  
  139. >>> 13008 - ITALIE ROSALIE
  140. >>> FACE 2 PLACE D'ITALIE - 75013 PARIS
  141. >>> 68 mètres - S/W
  142. >>> 0 places libres - 52 velos dispos
  143.  
  144. >>> 13010 - PLACE D ITALIE AURIOL
  145. >>> FACE 11 PLACE D'ITALIE - 75013 PARIS
  146. >>> 105 mètres - S/E
  147. >>> 1 places libres - 37 velos dispos
  148.  
  149. >>> 13029 - ITALIE
  150. >>> 30 AVENUE D'ITALIE - 75013 PARIS
  151. >>> 276 mètres - S/E
  152. >>> 1 places libres - 37 velos dispos
  153.  
  154. >>> 13106 - BOBILLOT MERY
  155. >>> 17 RUE BOBILLOT - 75013 PARIS
  156. >>> 289 mètres - S/W
  157. >>> 2 places libres - 22 velos dispos
  158.  
  159. >>> 13007 - LE BRUN GOBELINS
  160. >>> 42 RUE LE BRUN - 75013 PARIS
  161. >>> 342 mètres - N/W
  162. >>> 10 places libres - 10 velos dispos
  163.  
  164. # Afficher les 5 stations les plus proches qui contiennent au moins 1 vélo
  165. print a.getPoi('1 place italie', 'v')
  166.  
  167. >>> 13008 - ITALIE ROSALIE
  168. >>> FACE 2 PLACE D'ITALIE - 75013 PARIS
  169. >>> 68 mètres - S/W
  170. >>> 0 places libres - 52 velos dispos
  171.  
  172. >>> 13010 - PLACE D ITALIE AURIOL
  173. >>> FACE 11 PLACE D'ITALIE - 75013 PARIS
  174. >>> 105 mètres - S/E
  175. >>> 1 places libres - 37 velos dispos
  176.  
  177. >>> 13029 - ITALIE
  178. >>> 30 AVENUE D'ITALIE - 75013 PARIS
  179. >>> 276 mètres - S/E
  180. >>> 0 places libres - 38 velos dispos
  181.  
  182. >>> 13106 - BOBILLOT MERY
  183. >>> 17 RUE BOBILLOT - 75013 PARIS
  184. >>> 289 mètres - S/W
  185. >>> 2 places libres - 22 velos dispos
  186.  
  187. >>> 13007 - LE BRUN GOBELINS
  188. >>> 42 RUE LE BRUN - 75013 PARIS
  189. >>> 342 mètres - N/W
  190. >>> 9 places libres - 11 velos dispos
  191.  
  192. # Afficher les 5 stations les plus proches qui contiennent au moins 1 place
  193. print a.getPoi('1 place italie', 'p')
  194.  
  195. >>> 13010 - PLACE D ITALIE AURIOL
  196. >>> FACE 11 PLACE D'ITALIE - 75013 PARIS
  197. >>> 105 mètres - S/E
  198. >>> 1 places libres - 37 velos dispos
  199.  
  200. >>> 13029 - ITALIE
  201. >>> 30 AVENUE D'ITALIE - 75013 PARIS
  202. >>> 276 mètres - S/E
  203. >>> 1 places libres - 37 velos dispos
  204.  
  205. >>> 13106 - BOBILLOT MERY
  206. >>> 17 RUE BOBILLOT - 75013 PARIS
  207. >>> 289 mètres - S/W
  208. >>> 2 places libres - 22 velos dispos
  209.  
  210. >>> 13007 - LE BRUN GOBELINS
  211. >>> 42 RUE LE BRUN - 75013 PARIS
  212. >>> 342 mètres - N/W
  213. >>> 10 places libres - 10 velos dispos
  214.  
  215. >>> 13011 - COMPO FORMIO
  216. >>> 112 BD DE L'HOPITAL - 75013 PARIS
  217. >>> 423 mètres - N/E
  218. >>> 12 places libres - 4 velos dispos
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement