-
Notifications
You must be signed in to change notification settings - Fork 1
/
create_osm.py
148 lines (130 loc) · 5.88 KB
/
create_osm.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
import xml.sax
import six
def convert_opening(timetable):
# Loop over all days
ordered_days = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']
ret = None
# A common pattern for 24/7 is all days with same open and close values
if not timetable.get('auto', False) and \
len([day for day in ordered_days
if day in timetable and timetable[day][0]['open'] == timetable[day][0]['close']]) != 7:
all_hours = {day : ','.join(['{0}-{1}'.format(hours['open'], hours['close'])
for hours in timetable[day]])
for day in ordered_days if day in timetable}
def _format_range(start, end, hours):
ret = ''
if start and end and hours:
ret = '{0} {1}'.format('{0}-{1}'.format(start, end) if start != end else start,
hours)
return ret
start = None
end = None
hours = None
ranges = []
for day in ordered_days:
if day in all_hours:
if not start:
start = day
hours = all_hours[day]
elif hours != all_hours[day]:
ranges.append(_format_range(start, end, hours))
start = day
hours = all_hours[day]
end = day
elif start and end:
ranges.append(_format_range(start, end, hours))
start = None
end = None
hours = None
ranges.append(_format_range(start, end, hours))
# The ranges may contain empty strings, filter them out
ret = '; '.join([opening_range for opening_range in ranges if opening_range])
return ret or '24/7'
class PrixCarburantHandler(xml.sax.ContentHandler):
def __init__(self, output):
xml.sax.ContentHandler.__init__(self)
self.shop = None
self.day = None
self.out = open(output, 'w')
self.out.writelines(["<?xml version='1.0' encoding='UTF-8'?>\n",
"<osm version='0.5'>\n"])
def endDocument(self):
self.out.write('</osm>')
self.out.close()
def startElement(self, name, attrs):
if name == 'pdv':
self.shop = {'id': attrs.get('id'),
'lat': float(attrs.get('latitude') or 0) / 100000.0,
'lng': float(attrs.get('longitude') or 0) / 100000.0,
'price': {},
'timetable': {}}
elif name == 'prix':
update = attrs.get('maj')[:attrs.get('maj').find('T')]
self.shop['price'][attrs.get('nom')] = {'value': float(attrs.get('valeur')),
'update': update}
elif name == 'jour':
days_map = {'Lundi': 'Mo',
'Mardi': 'Tu',
'Mercredi': 'We',
'Jeudi': 'Th',
'Vendredi': 'Fr',
'Samedi': 'Sa',
'Dimanche': 'Su'}
self.day = {'name': days_map[attrs.get('nom')],
'opened': attrs.get('ferme') != '1'}
elif name == 'horaire' and self.day:
timetable = self.shop['timetable'].get(self.day['name'], [])
timetable.append({'open': attrs.get('ouverture').replace('.', ':'),
'close': attrs.get('fermeture').replace('.', ':')})
self.shop['timetable'][self.day['name']] = timetable
elif name == 'horaires' and attrs.get('automate-24-24') == '1':
self.shop['timetable'] = {'auto': True}
def endElement(self, name):
if name == 'pdv':
self._writeShop()
elif name == 'jour':
if not self.shop['timetable'].get(self.day['name']) and self.day['opened']:
self.shop['timetable'][self.day['name']] = [{'open': '00:00', 'close': '00:00'}]
self.day = None
def _writeShop(self):
if self.shop['lat'] and self.shop['lng'] and self.shop['price']:
fuel_map = {'Gazole': 'diesel',
'SP95': 'octane_95',
'SP98': 'octane_98',
'GPLc': 'lgp',
'E85': 'e85',
'E10': 'e10'}
name = ' | '.join(['{0} {1}€'.format(k, v['value'])
for k, v in six.iteritems(self.shop['price'])])
description = ' '.join(['{0}: {1}€ ({2})'.format(k, v['value'], v['update'])
for k, v in six.iteritems(self.shop['price'])])
fuel_tags = '\n'.join(["<tag k='fuel:{0}' v='yes'/>".format(fuel_map[fuel])
for fuel in self.shop['price']])
opening_hours = ''
if self.shop['timetable']:
opening_hours = "<tag k='opening_hours' v='{0}'/>".format(
convert_opening(self.shop['timetable']))
self.out.write('''
<node id='{0}' visible='true' lat='{1}' lon='{2}'>
<tag k='name' v='{3}'/>
<tag k='description' v='{4}'/>
{5}
<tag k='amenity' v='fuel'/>
{6}
<tag k='source' v='prix-carburant.economie.gouv.fr'/>
</node>'''.format(self.shop['id'],
self.shop['lat'],
self.shop['lng'],
name,
description,
opening_hours,
fuel_tags))
self.shop = None
def main(args):
handler = PrixCarburantHandler(args[2])
xml.sax.parse(args[1], handler)
if __name__ == '__main__':
main(sys.argv)