Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- # -*- coding: utf-8 -*-
- import urllib2
- from xml.dom import minidom
- import math
- import re
- API_KEY = 'Yahoo! API key'
- class Velib:
- def __init__(self):
- self.API_KEY = API_KEY
- url = 'http://www.velib.paris.fr/service/carto/'
- dom = minidom.parse(self.httpReq(url))
- self.poi_list = []
- for marker in dom.getElementsByTagName('marker'):
- attrs = marker.attributes.keys()
- poi_dict = {}
- for attr in attrs :
- value = marker.getAttribute(attr)
- poi_dict[attr] = value
- self.poi_list.append(poi_dict)
- def httpReq(self,url):
- try:
- response = urllib2.urlopen(url)
- except HTTPError, e:
- pass
- #print 'Error :', str(e.code)
- except URLError, e:
- pass
- #print 'Reason ' + str(e.reason)
- else:
- return response
- # http://pravin.insanitybegins.com/posts/euclidean-distance-calculator.html
- def _parseXML(self,xml):
- m = re.findall('<Latitude>(\d+.\d+)</Latitude><Longitude>(\d+.\d+)</Longitude>', xml)
- return m[0]
- def getCoords(self,location):
- #url = 'http://local.yahooapis.com/MapsService/V1/geocode?appid=' + self.API_KEY + '&location=' + urllib2.quote(location)
- location = location.encode("utf-8", "replace")
- url = 'http://local.yahooapis.com/MapsService/V1/geocode?appid=' + self.API_KEY + '&city=paris&street=' + urllib2.quote(location)
- response = self.httpReq(url)
- if response:
- (x, y) = self._parseXML(response.read())
- return {'lat':float(x), 'lng':float(y)}
- else:
- pass
- def getOrthodromy(self,st,end):
- direction = {}
- deg2rad = math.pi/180
- rayonTerre = 6371
- start_lat = float(st['lat']) *deg2rad
- start_long = float(st['lng']) *deg2rad
- end_lat = float(end['lat']) *deg2rad
- end_long = float(end['lng']) *deg2rad
- distance = ( math.cos(start_lat) * math.cos(end_lat) * math.cos( end_long - start_long ) + math.sin(start_lat) * math.sin(end_lat) )
- if end_lat > start_lat:
- direction['dir_lat'] = 'N'
- else:
- direction['dir_lat'] = 'S'
- if end_long > start_long:
- direction['dir_lon'] = 'E'
- else:
- direction['dir_lon'] = 'W'
- return {'distance':rayonTerre * math.acos(distance), 'direction': direction}
- def checkStation(self,val,velib_poi):
- for poi in velib_poi:
- if poi['nb'] == val:
- return poi
- def getVelibApi(self,uid):
- url = "http://www.velib.paris.fr/service/stationdetails/%s" % uid
- data = minidom.parse(self.httpReq(url))
- return {'free':data.getElementsByTagName("free")[0].firstChild.data,
- 'available':data.getElementsByTagName("available")[0].firstChild.data,
- 'total':data.getElementsByTagName("total")[0].firstChild.data}
- def displayResult(self,station,dispo):
- try:
- 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'
- except:
- return '\nOops'
- def getStation(self,m,velib_poi,q):
- l = sorted(m.iteritems(), key=lambda (k,v):(v,k))
- i = 0
- j = 5
- res = ''
- while i < j:
- station = self.checkStation(l[i][0],velib_poi)
- dispo = self.getVelibApi(station['number'])
- if q == 'p':
- if dispo['free'] == '0':
- j += 1
- else:
- res += '\n' + self.displayResult(station,dispo)
- if q == 'v':
- if dispo['available'] == '0':
- j += 1
- else:
- res += '\n' + self.displayResult(station,dispo)
- if q == None:
- res += '\n' + self.displayResult(station,dispo)
- i +=1
- continue
- return res
- def getPoi(self,place,q=None):
- point = self.getCoords(place)
- if point:
- m = {}
- i = 0
- velib_poi = self.poi_list
- while i < len(velib_poi):
- poi_data = self.getOrthodromy(point,velib_poi[i])
- m.update({i:poi_data['distance']})
- velib_poi[i]['distance'] = poi_data['distance']
- velib_poi[i]['nb'] = i
- velib_poi[i]['dir_lon'] = poi_data['direction']['dir_lon']
- velib_poi[i]['dir_lat'] = poi_data['direction']['dir_lat']
- i +=1
- continue
- return self.getStation(m,velib_poi,q)
- else:
- return 'Something went wrong'
- a = Velib()
- # Afficher les 5 stations les plus proches
- print a.getPoi('1 place italie')
- >>> 13008 - ITALIE ROSALIE
- >>> FACE 2 PLACE D'ITALIE - 75013 PARIS
- >>> 68 mètres - S/W
- >>> 0 places libres - 52 velos dispos
- >>> 13010 - PLACE D ITALIE AURIOL
- >>> FACE 11 PLACE D'ITALIE - 75013 PARIS
- >>> 105 mètres - S/E
- >>> 1 places libres - 37 velos dispos
- >>> 13029 - ITALIE
- >>> 30 AVENUE D'ITALIE - 75013 PARIS
- >>> 276 mètres - S/E
- >>> 1 places libres - 37 velos dispos
- >>> 13106 - BOBILLOT MERY
- >>> 17 RUE BOBILLOT - 75013 PARIS
- >>> 289 mètres - S/W
- >>> 2 places libres - 22 velos dispos
- >>> 13007 - LE BRUN GOBELINS
- >>> 42 RUE LE BRUN - 75013 PARIS
- >>> 342 mètres - N/W
- >>> 10 places libres - 10 velos dispos
- # Afficher les 5 stations les plus proches qui contiennent au moins 1 vélo
- print a.getPoi('1 place italie', 'v')
- >>> 13008 - ITALIE ROSALIE
- >>> FACE 2 PLACE D'ITALIE - 75013 PARIS
- >>> 68 mètres - S/W
- >>> 0 places libres - 52 velos dispos
- >>> 13010 - PLACE D ITALIE AURIOL
- >>> FACE 11 PLACE D'ITALIE - 75013 PARIS
- >>> 105 mètres - S/E
- >>> 1 places libres - 37 velos dispos
- >>> 13029 - ITALIE
- >>> 30 AVENUE D'ITALIE - 75013 PARIS
- >>> 276 mètres - S/E
- >>> 0 places libres - 38 velos dispos
- >>> 13106 - BOBILLOT MERY
- >>> 17 RUE BOBILLOT - 75013 PARIS
- >>> 289 mètres - S/W
- >>> 2 places libres - 22 velos dispos
- >>> 13007 - LE BRUN GOBELINS
- >>> 42 RUE LE BRUN - 75013 PARIS
- >>> 342 mètres - N/W
- >>> 9 places libres - 11 velos dispos
- # Afficher les 5 stations les plus proches qui contiennent au moins 1 place
- print a.getPoi('1 place italie', 'p')
- >>> 13010 - PLACE D ITALIE AURIOL
- >>> FACE 11 PLACE D'ITALIE - 75013 PARIS
- >>> 105 mètres - S/E
- >>> 1 places libres - 37 velos dispos
- >>> 13029 - ITALIE
- >>> 30 AVENUE D'ITALIE - 75013 PARIS
- >>> 276 mètres - S/E
- >>> 1 places libres - 37 velos dispos
- >>> 13106 - BOBILLOT MERY
- >>> 17 RUE BOBILLOT - 75013 PARIS
- >>> 289 mètres - S/W
- >>> 2 places libres - 22 velos dispos
- >>> 13007 - LE BRUN GOBELINS
- >>> 42 RUE LE BRUN - 75013 PARIS
- >>> 342 mètres - N/W
- >>> 10 places libres - 10 velos dispos
- >>> 13011 - COMPO FORMIO
- >>> 112 BD DE L'HOPITAL - 75013 PARIS
- >>> 423 mètres - N/E
- >>> 12 places libres - 4 velos dispos
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement