Remove assumptions and added some api stuff

Thu, 26 Oct 2017 16:54:29 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Thu, 26 Oct 2017 16:54:29 +0300
changeset 71
d2e19670b772
parent 70
c2fc50748efd
child 72
65408ed066b3

Remove assumptions and added some api stuff

abbreviations.ini file | annotate | diff | comparison | revisions
buses.py file | annotate | diff | comparison | revisions
busroute.py file | annotate | diff | comparison | revisions
misc.py file | annotate | diff | comparison | revisions
profiles/föli.ini file | annotate | diff | comparison | revisions
profiles/junat.ini file | annotate | diff | comparison | revisions
regions.ini file | annotate | diff | comparison | revisions
service.py file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/abbreviations.ini	Thu Oct 26 16:54:29 2017 +0300
@@ -0,0 +1,235 @@
+[abbreviations]
+aaslaluoto = Aas
+ahteentaka = Aht
+airismaa = Air
+ajola = Ajo
+artukainen = Ar
+asikko = Ask
+aura = Au
+auvaismäki = Auv
+avanti = Ava
+björkhagen = Bjö
+eerikvalla = Ev
+friskala = Frs
+haapala = Haa
+haarla = Hla
+hadvala = Hdv
+haijainen = Hja
+hakkinen = Hak
+halinen = Hn
+hanhijoki = Han
+harittu = Har
+helsingin valtatie = Hgv
+hemmola = Hem
+hepokulta = Hp
+herttula = Hert
+hyrköinen = Hyr
+hämölä = Hmö
+häppilä = Häp
+härkämäki = Häm
+ihala = Ih
+illoinen = Ill
+ilmarinen = Ilm
+ilpoinen = Ilp
+impivaara = Imv
+iso-heikkilä = Ish
+ispoinen = Isp
+itäharju = Ith
+itäranta = Itr
+jokila = Jkl
+jyrkkälä = Jyr
+jäkärlä = Jäk
+jänessaari = Jäs
+kaanaa = Kaa
+kaarina = Ka
+kahari = Kah
+kaistarniemi = Krn
+kaivola = Kaiv
+kaivopuisto = Kvp
+kakskerta = Kk
+karvetti = Kav
+kasarmialue = Krm
+kasnäs = Knä
+kastu = Kas
+katariina = Kat
+mylly = My
+kauppatori = Kt
+kemiö = Kö
+kemiönsaari = Kös
+kerttuli = Ker
+kesämäki = Ksä
+kirjala = Kij
+kirkkotien terveyskeskus = Kttk
+kohmo = Km
+koivula = Koi
+konserttitalo = Kns
+korpo = Kpo
+koski tl = Ktl
+kuivalahti = Kvl
+kukola = Kuk
+kultaranta = Klr
+kuninkoja = Kni
+kupittaa as = Kua
+kupittaa = Ku
+kupittaanpuisto = Kup
+kurala = Kur
+kurala (naantali) = Kurn
+kurjenmäki = Kj
+kuusisto = Kst
+kuuvuori = Kuu
+kyrkäng = Kyr
+kårkulla = Kår
+kähäri = Käh
+käkölä = Käk
+lauste = Ls
+lauttaranta = Ltr
+lehmusvalkama = Lmv
+lemu = Lemu
+lentoasema = Len
+lieranta = Lie
+lieto as = Lta
+lieto = Lt
+liedon keskusta = Lik
+liljalaakso = Llj
+linja-autoasema = La
+linnavuori = Liv
+littoinen = Lit
+logomo = Lg
+loukinainen = Lna
+luolavuori = Llv
+luostarinmäki = Lum
+länsikeskus = Läk
+länsinummi = Lä
+maanpää = Mpä
+majakkaranta = Mj
+maksla = Mks
+marjaniemi = Man
+marttila = Mla
+martti = Mar
+merimasku = Mma
+meripirtti = Mpi
+messukeskus = Mes
+metsäaro = Mta
+metsämäki = Met
+moikoinen = Mo
+moisio = Msi
+montola = Mon
+muhkuri = Mhk
+munittula = Mni
+munkviken = Mkv
+mälikkälä = Mäl
+mäntymäki = Män
+naantali = Na
+naantalin pikatie = Nnpt
+nagu = Nv
+naskarla = Nsk
+norrby = Nor
+nummen koulu = Nuk
+nummenmäki = Num
+nuorikkala = Nuo
+nättinummi = Nät
+ojanto = Oja
+okala = Oka
+oriketo = Ork
+oriniemi = Orn
+paasniittu = Ptu
+paattinen = Paa
+paimion sairaala = Pms
+paimio = Pm
+pansio = Ps
+papinsaari = Pap
+pargas = Pa
+patterinhaka = Pat
+peijerlä = Pej
+peltola = Pel
+pernon telakka = Pnt
+perno = Pn
+petäsmäki = Pem
+piikkiö = Pkö
+piispala = Ppla
+piispanlähde = Pplä
+piispanristi = Pri
+pikisaari = Pik
+pläkkikaupunki = Plä
+pohjola = Phj
+poikko = Pko
+pompo = Ppo
+porhonkallio = Porh
+port arthur = Par
+puosta = Puo
+puutori = Puu
+pyöli = Pyö
+pärnäs = Pnä
+pääskyvuori = Päv
+raadelma = Raa
+raisio = Rs
+rauduinen = Rau
+rauhakylä = Rhk
+raunistulan puistotie = Rnp
+raunistula = Rni
+rautatieasema = Ra
+ruissalo = Rus
+runko = Rnk
+runosmäki = Rum
+ruona = Ruo
+rusko = Rko
+rymättylä = Rym
+räntämäki = Räm
+röölä = Röö
+saaro = Sro
+salonkylä = Sak
+salo = Sl
+saramäki = Srm
+satakunnantie = Sat
+satama = Sm
+satava = Sv
+sauvo = Sg
+sillilä = Sil
+silvola = Siv
+sipilänmäki = Spm
+skanssi = Ska
+somero = Sro
+storäng = Str
+suikkila = Ski
+suovuori = Sv
+suutarla = Suu
+särkilahti = Säl
+takakirves = Tka
+tamminiemi = Tamn
+tammi = Tmi
+tarvasjoki = Tj
+teerimäki = Tee
+tennby = Ten
+teräsrautela = Trä
+tikanmaa = Tik
+toijainen = Tja
+torppala = Tor
+tortinmäki = Ttm
+tuomiokirkkotori = Tk
+tuorla = Tla
+turkuhalli = Tuh
+tyks = Tyks
+uittamo = Ui
+urusvuori = Urv
+vaala = Va
+vahto = Vh
+vaisaari = Vai
+varissuo = Vs
+vasaramäki = Vm
+velkua = Ve
+velusmaa = Vlu
+verkahovi = Ver
+vienola = Vn
+vieru = Vru
+viiala = Vii
+vii kaupunginosa = Vii
+viluluoto = Vil
+vuorenpää = Vpä
+vähä-heikkilä = Väh
+yli-maaria = Ylm
+yliopisto = Yop
+ylioppilaskylä-itä = Yoi
+ylioppilaskylä-länsi = Yol
+ylioppilaskylä = Yok
+ylttinen = Ylt
+österby = Öst
--- a/buses.py	Sat Oct 07 01:52:15 2017 +0300
+++ b/buses.py	Thu Oct 26 16:54:29 2017 +0300
@@ -10,8 +10,8 @@
 	return reference
 
 class BusTrip:
-	def __init__(self, reference, route, service, length):
-		self.reference, self.route, self.service = reference, route, service
+	def __init__(self, reference, route, service, length, block_id):
+		self.reference, self.route, self.service, self.block_id = reference, route, service, block_id
 		self.length = length
 		self.schedule = []
 		self.name = transform_trip_reference(reference)
@@ -29,19 +29,22 @@
 		except KeyError:
 			return False
 	def concise_schedule(self, starting_stop = None):
-		if starting_stop and starting_stop in self.schedule:
-			schedule = copy(self.schedule)
-			schedule = schedule[schedule.index(starting_stop):]
+		if profile['regions']['use-regions']:
+			if starting_stop and starting_stop in self.schedule:
+				schedule = copy(self.schedule)
+				schedule = schedule[schedule.index(starting_stop):]
+			else:
+				schedule = self.schedule
+			used_areas = set()
+			result = []
+			for halt in schedule:
+				stop = halt.stop
+				if stop.region and stop.region not in used_areas:
+					used_areas.add(stop.region)
+					result.append(stop.region)
+			return result
 		else:
-			schedule = self.schedule
-		used_areas = set()
-		result = []
-		for halt in schedule:
-			stop = halt.stop
-			if stop.region and stop.region not in used_areas:
-				used_areas.add(stop.region)
-				result.append(stop.region)
-		return result
+			return [halt.stop.name for halt in self.schedule]
 
 class BusRoute:
 	def __init__(self, entry):
@@ -130,23 +133,33 @@
 		self.traveled_distance = traveled_distance
 	@property
 	def is_arrival(self):
-		if not hasattr(self, 'cachedIsArrival'):
-			if self.stop.region:
-				iterator = iter(self.trip.schedule)
-				stop = next(iterator)
-				while stop is not self:
+		if profile['regions']['use-regions']:
+			if not hasattr(self, 'cachedIsArrival'):
+				if self.stop.region:
+					iterator = iter(self.trip.schedule)
 					stop = next(iterator)
-				for stop in iterator:
-					if stop.stop.region != self.stop.region:
-						self.cachedIsArrival = False
-						break
+					while stop is not self:
+						stop = next(iterator)
+					for stop in iterator:
+						if stop.stop.region != self.stop.region:
+							self.cachedIsArrival = False
+							break
+					else:
+						self.cachedIsArrival = True
 				else:
-					self.cachedIsArrival = True
-			else:
-				self.cachedIsArrival = False
-		return self.cachedIsArrival
+					self.cachedIsArrival = False
+			return self.cachedIsArrival
+		else:
+			return self == self.trip.schedule[-1]
 	def __repr__(self):
 		return 'BusHalt(%r, %r, %r, %r)' % (self.arrival_time, self.departure_time, self.stop, self.trip)
+	def sign(self, long = False):
+		from busroute import reduce_schedule
+		return reduce_schedule(
+			route = self.trip.concise_schedule(self),
+			trip_length = self.trip.length - self.traveled_distance,
+			long = long,
+		)
 
 routes = {}
 routes_per_id = {}
@@ -158,7 +171,7 @@
 clusters_by_name = {}
 services_for_day = {}
 
-def load_buses(gtfs_zip_path, profile):
+def load_buses(gtfs_zip_path):
 	global viimeinen_käyttöpäivä
 	from zipfile import ZipFile
 	with ZipFile(gtfs_zip_path) as gtfs_zip:
@@ -173,9 +186,12 @@
 		print('Ladataan ajovuorot... ', file = stderr, end = '', flush = True)
 
 		shape_distances = {}
-		with gtfs_zip.open('shapes.txt') as file:
-			for row in read_csv(map(bytes.decode, file)):
-				shape_distances[row['shape_id']] = max(shape_distances.get(row['shape_id'], 0), float(row['shape_dist_traveled']))
+		try:
+			with gtfs_zip.open('shapes.txt') as file:
+				for row in read_csv(map(bytes.decode, file)):
+					shape_distances[row['shape_id']] = max(shape_distances.get(row['shape_id'], 0), float(row['shape_dist_traveled']))
+		except KeyError:
+			pass
 
 		with gtfs_zip.open('trips.txt') as file:
 			for row in read_csv(map(bytes.decode, file)):
@@ -186,11 +202,14 @@
 					reference = row['trip_id'],
 					route = route,
 					service = services[row['service_id']],
-					length = shape_distances[row['shape_id']] * float(profile['metrics']['shape-modifier'])
+					length = shape_distances.get(row.get('shape_id'), 1) * float(profile['metrics']['shape-modifier']),
+					block_id = row['block_id'],
 				)
 				route.trips.add(trip)
-				assert trip.name not in all_trips
-				all_trips[trip.name] = trip
+				if trip.name in all_trips:
+					print('Trip %s already exists' % trip.name)
+				else:
+					all_trips[trip.name] = trip
 		print('%d ajoa' % len(all_trips), file = stderr)
 
 		def read_date(teksti):
@@ -253,12 +272,16 @@
 					reference = row['stop_id'],
 					name = row['stop_name'],
 					location = location, 
-					code = row['stop_code'],
+					code = row.get('stop_code', row['stop_id']),
 				)
 				bus_stops[stop.reference] = stop
-		with open('regions-per-stop.json') as file:
-			for stop_reference, region in json.load(file).items():
-				bus_stops[stop_reference].region = region
+		if profile['regions']['use-regions']:
+			with open('regions-per-stop.json') as file:
+				for stop_reference, region in json.load(file).items():
+					try:
+						bus_stops[stop_reference].region = region
+					except KeyError:
+						pass
 		print('%d pysäkkiä' % len(bus_stops), file = stderr)
 
 
@@ -367,30 +390,31 @@
 					# Ryhmä on ainoa jolla on varaus tälle nimelle. Sen kuin vaan.
 					next(iter(clusters)).name = name
 				else:
-					# Olisiko kaikki klusterit eri alueilla?
-					common_regions = shared_elements_in_n_sets({stop.region for stop in cluster.stops} for cluster in clusters)
-					# Esitys: ryhmä -> ne alueet jotka ovat tälle ryhmälle ainutlaatuisia
-					proposal = {
-						cluster: {stop.region for stop in cluster.stops} - common_regions - {None}
+					if profile['regions']['use-regions']:
+						# Olisiko kaikki klusterit eri alueilla?
+						common_regions = shared_elements_in_n_sets({stop.region for stop in cluster.stops} for cluster in clusters)
+						# Esitys: ryhmä -> ne alueet jotka ovat tälle ryhmälle ainutlaatuisia
+						proposal = {
+							cluster: {stop.region for stop in cluster.stops} - common_regions - {None}
+							for cluster in clusters
+						}
+						# Jos enintään yksi klusteri tässä esityksessä on kokonaan ilman omaa aluetta, jolla se voisi eritellä,
+						# niin nimetään klusterit näiden alueiden mukaan.
+						# Se klusteri jolla ei ole omaa aluetta (jos on) jätetään ilman aluepäätettä.
+						if sum([1 for unique_areas in proposal.values() if not unique_areas]) <= 1:
+							for cluster, unique_areas in proposal.items():
+								individual_cluster_name = name
+								if unique_areas:
+									individual_cluster_name += ' (' + min(unique_areas) + ')'
+								cluster.name = individual_cluster_name
+								break
+					# Typerä reunatapaus. Indeksoidaan numeroin...
+					for n, (_, cluster) in enumerate(sorted(
+						min((stop.reference.lower(), cluster) for stop in cluster.stops)
 						for cluster in clusters
-					}
-					# Jos enintään yksi klusteri tässä esityksessä on kokonaan ilman omaa aluetta, jolla se voisi eritellä,
-					# niin nimetään klusterit näiden alueiden mukaan.
-					# Se klusteri jolla ei ole omaa aluetta (jos on) jätetään ilman aluepäätettä.
-					if sum([1 for unique_areas in proposal.values() if not unique_areas]) <= 1:
-						for cluster, unique_areas in proposal.items():
-							individual_cluster_name = name
-							if unique_areas:
-								individual_cluster_name += ' (' + min(unique_areas) + ')'
-							cluster.name = individual_cluster_name
-					else:
-						# Typerä reunatapaus. Indeksoidaan numeroin...
-						for n, (_, cluster) in enumerate(sorted(
-							min((stop.reference.lower(), cluster) for stop in cluster.stops)
-							for cluster in clusters
-						), 1):
-							individual_cluster_name = name + '-' + str(n)
-							cluster.name = individual_cluster_name
+					), 1):
+						individual_cluster_name = name + '-' + str(n)
+						cluster.name = individual_cluster_name
 
 		print('Ryhmitellään pysäkit...')
 		cluster_bus_stops()
@@ -408,11 +432,13 @@
 		with gtfs_zip.open('stop_times.txt') as file:
 			progress = 0
 			for row in read_csv(map(bytes.decode, file)):
+				if int(row.get('pickup_type', 0)) and int(row.get('drop_off_type', 0)):
+					continue
 				trip = all_trips[transform_trip_reference(row['trip_id'])]
 				arrival_time = read_time(row['arrival_time'])
 				departure_time = read_time(row['departure_time'])
 				stop = bus_stops[row['stop_id']]
-				traveled_distance = float(row['shape_dist_traveled']) * float(profile['metrics']['shape-modifier'])
+				traveled_distance = float(row.get('shape_dist_traveled', 1)) * float(profile['metrics']['shape-modifier'])
 				trip.schedule.append(BusHalt(arrival_time, departure_time, stop, trip, traveled_distance))
 				stop.involved_trips.add(trip)
 				progress += 1
@@ -450,19 +476,23 @@
 				route.description = simplify_name(most_common_route[0]) + ' - ' + simplify_name(most_common_route[-1])
 			except:
 				route.description = ''
-			route.trips = sorted(route.trips, key = lambda trip: trip.schedule[0].departure_time)
+			route.trips = sorted(route.trips, key = lambda trip: trip.schedule and trip.schedule[0].departure_time or timedelta())
 
 		# Fölin datassa on jotain tosi kummaa. Ilmeisesti ajovuoron viimeisen pysähdyksen saapumisaika on ihan täysin
 		# väärin. Arvaan että se on seuraavan lähdön aika, mutta joka tapauksessa se on väärin.
 		# Arvataan mikä se todellinen saapumisaika on. Se ei voi mennä kauhean paljon pahemmin vikaan kuin alkuperäinen
 		# väärin oleva data.
 		for trip in all_trips.values():
-			bus_speed_coefficient = 750 # metriä minuutissa
-			last_leg_distance = trip.schedule[-1].traveled_distance - trip.schedule[-2].traveled_distance
-			trip.schedule[-1].arrival_time = trip.schedule[-2].departure_time + timedelta(minutes = last_leg_distance / bus_speed_coefficient)
+			if len(trip.schedule) >= 2:
+				bus_speed_coefficient = 750 # metriä minuutissa
+				last_leg_distance = trip.schedule[-1].traveled_distance - trip.schedule[-2].traveled_distance
+				trip.schedule[-1].arrival_time = trip.schedule[-2].departure_time + timedelta(minutes = last_leg_distance / bus_speed_coefficient)
+
+		global trips_by_vehicle_info
+		trips_by_vehicle_info = {}
+		for trip in all_trips.values():
+			trips_by_vehicle_info[(trip.block_id, trip.schedule[0].arrival_time)] = trip
 
 if __name__ == '__main__':
-	from configparser import ConfigParser
-	profile = ConfigParser()
 	profile.read('profiles/föli.ini')
-	load_buses('gtfs.zip', profile)
+	load_buses('gtfs.zip')
--- a/busroute.py	Sat Oct 07 01:52:15 2017 +0300
+++ b/busroute.py	Thu Oct 26 16:54:29 2017 +0300
@@ -1,6 +1,7 @@
 #!/usr/bin/env python3
 
 from configparser import ConfigParser
+from math import inf
 
 replacements = {
 	"ylioppilaskylä-itä": "ylioppilaskylä",
@@ -10,8 +11,8 @@
 	'saaro': 'ruissalo',
 	'silvola': 'vahto',
 	'hemmola': 'vahto',
-	'paasniittu': 'ruskon keskusta',
-	'kahari': 'ruskon keskusta',
+	'paasniittu': 'rusko',
+	'kahari': 'rusko',
 	'kemiö': 'kemiönsaari',
 	'kasnäs': 'kemiönsaari',
 	'pernon telakka': 'perno',
@@ -19,15 +20,6 @@
 	'hanhijoki': 'paimio',
 }
 
-# nimiä joista voidaan joustaa tarvittaessa
-abbreviations = {
-	'raision keskusta': 'raisio',
-	'ruskon keskusta': 'rusko',
-	'naantalin keskusta': 'naantali',
-	'kaarinan keskusta': 'kaarina',
-	'kauppakeskus mylly': 'mylly',
-}
-
 region_info = ConfigParser()
 region_info.read('regions.ini')
 municipalities = set(region_info.sections())
@@ -42,31 +34,30 @@
 
 def simplify_name(name):
 	name = replacements.get(name, name)
-	name = abbreviations.get(name, name)
 	return name
 
-def reduce_schedule(reitti, trip_length, whole = False, long = False):
-	length = ((trip_length / 600) * 3 + len(reitti) * 2) / 5
-	if not reitti:
+def reduce_schedule(route, trip_length, whole = False, long = False):
+	length = ((trip_length / 600) * 3 + len(route) * 2) / 5
+	if not route:
 		return ''
 	have_already = set()
 	i = 0
-	while i < len(reitti):
-		if reitti[i] in replacements:
-			reitti[i] = replacements[reitti[i]]
-		if reitti[i] in have_already:
-			del reitti[i]
+	while i < len(route):
+		if route[i] in replacements:
+			route[i] = replacements[route[i]]
+		if route[i] in have_already:
+			del route[i]
 		else:
-			have_already.add(reitti[i])
+			have_already.add(route[i])
 			i += 1
 	priorities = {
 		'ihala': 150,
-		'kauppakeskus mylly': 200,
+		'mylly': 200,
 		'kuninkoja': 150,
-		'moikoinen': 80,
-		'raision keskusta': 150,
+		'moikoinen': 100,
+		'raisio': 150,
 		'kukola': 50,
-		'kaistarniemi': 50,
+		'kaistarniemi': 75,
 		'papinsaari': 80,
 		'oriniemi': 50,
 		'pikisaari': 50,
@@ -84,21 +75,21 @@
 		'kohmo': 80,
 		'kupittaa': 70,
 		'kupittaa as': 120,
-		'kauppatori': 1e15,
+		'kauppatori': inf,
 		'lentoasema': 50,
 		'runosmäki': 50,
 		'lieto': 100,
 		'lieto as': 200,
 		'ilmarinen': 50,
 		'vahto': 50,
-		'ruskon keskusta': 200,
-		'oriketo': 60,
+		'rusko': 200,
+		'oriketo': 50,
 		'harittu': 40,
-		'jäkärlä': 80,
-		'moisio': 100,
-		'paattinen': 100,
-		'kaarinan keskusta': 200,
-		'naantalin keskusta': 200,
+		'jäkärlä': 150,
+		'moisio': 150,
+		'paattinen': 25,
+		'kaarina': 200,
+		'naantali': 200,
 		'uittamo': 50,
 		'piikkiö': 100,
 		'paimio': 100,
@@ -116,7 +107,6 @@
 		'suikkila': 50,
 		'raunistula': 50,
 		'räntämäki': 50,
-		'moisio': 25,
 		'pääskyvuori': 100,
 		'logomo': 100,
 		'rymättylä': 50,
@@ -140,8 +130,8 @@
 		'satakunnantie': 25,
 		'hepokulta': 25,
 		'nättinummi': 25,
-		'nummenmäki': 25,
-		'kurala': 25,
+		'nummenmäki': 10,
+		'kurala': 10,
 		'itäharju': 25,
 		'vasaramäki': 25,
 		'pohjola': 25,
@@ -162,18 +152,18 @@
 		'port arthur': 25,
 	}
 
-	if 'kauppatori' not in reitti:
+	if 'kauppatori' not in route:
 		priorities['länsikeskus'] = priorities['skanssi'] = priorities['kauppatori']
 
-	from_place = reitti[0]
-	destination = reitti[-1]
+	from_place = route[0]
+	destination = route[-1]
 	reitti_arvot = {}
 	f = lambda i: i**-0.3
-	factor = 1 / max(f(i + 1) for i in range(len(reitti)))
-	while priorities.get(reitti[-1], 0) < 0:
-		del reitti[-1]
-		destination = reitti[-1]
-	for i, stop in enumerate(reitti):
+	factor = 1 / max(f(i + 1) for i in range(len(route)))
+	while priorities.get(route[-1], 0) < 0:
+		del route[-1]
+		destination = route[-1]
+	for i, stop in enumerate(route):
 		# muunna indeksi siten että myöhemmät alueet korostuvat
 		i = f(i + 1) * factor
 		# ota prioriteetti huomioon, jotkin alueet ovat tärkeämpiä kyltissä kuin toiset
@@ -187,7 +177,7 @@
 	# muodosta sign-tiedot järjestettynä reittiarvon mukaan
 	weights = sorted([
 		(stop, reitti_arvot[stop], i) \
-		for i, stop in enumerate(reitti) \
+		for i, stop in enumerate(route) \
 		if reitti_arvot[stop] >= 1
 		], key = lambda stop: -stop[1])
 	if long:
@@ -211,21 +201,18 @@
 	# muodostetaan sign..
 	sign = [paino[0] for paino in weights]
 	to_place = sign[-1]
-	nearby_municipalities = {'Turku', 'Raisio', 'Naantali', 'Kaarina', 'Lieto'}
-	if from_place != to_place:
-		municipality_from = municipalities_per_region.get(from_place)
-		municipality_to = municipalities_per_region.get(to_place)
-		if municipality_from and municipality_to and municipality_from not in nearby_municipalities | {municipality_to} and municipality_to not in nearby_municipalities:
-			def convert_region(region):
-				municipality = municipalities_per_region.get(region, region)
-				if municipality != municipality_from:
-					return municipality
-				else:
-					return region
-			sign = [convert_region(region) for region in sign]
-	# supista nimet tarvittaessa
-	if len(' - '.join(sign)) > 20:
-		sign = [abbreviations.get(place, place) for place in sign]
+	#nearby_municipalities = {'Turku', 'Raisio', 'Naantali', 'Kaarina', 'Lieto'}
+	#if from_place != to_place:
+	#	municipality_from = municipalities_per_region.get(from_place)
+	#	municipality_to = municipalities_per_region.get(to_place)
+	#	if municipality_from and municipality_to and municipality_from not in nearby_municipalities | {municipality_to} and municipality_to not in nearby_municipalities:
+	#		def convert_region(region):
+	#			municipality = municipalities_per_region.get(region, region)
+	#			if municipality != municipality_from:
+	#				return municipality
+	#			else:
+	#				return region
+	#		sign = [convert_region(region) for region in sign]
 	old_sign = sign.copy()
 	sign = []
 	for place in old_sign:
--- a/misc.py	Sat Oct 07 01:52:15 2017 +0300
+++ b/misc.py	Thu Oct 26 16:54:29 2017 +0300
@@ -23,3 +23,6 @@
 
 def is_night_time(time):
 	return time.hour >= 23 or time.hour < 5
+
+from configparser import ConfigParser
+profile = ConfigParser()
--- a/profiles/föli.ini	Sat Oct 07 01:52:15 2017 +0300
+++ b/profiles/föli.ini	Thu Oct 26 16:54:29 2017 +0300
@@ -1,2 +1,5 @@
 [metrics]
 shape-modifier = 1
+
+[regions]
+use-regions = 1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/profiles/junat.ini	Thu Oct 26 16:54:29 2017 +0300
@@ -0,0 +1,5 @@
+[metrics]
+shape-modifier = 1
+
+[regions]
+use-regions =
--- a/regions.ini	Sat Oct 07 01:52:15 2017 +0300
+++ b/regions.ini	Thu Oct 26 16:54:29 2017 +0300
@@ -1,5 +1,5 @@
 [Kaarina]
-Kaarinan keskusta = 6043
+Kaarina = 6043
 Piikkiö = 6175
 Hadvala = 6171
 Puosta = 6351
@@ -65,8 +65,8 @@
 Marttila = 8800
 
 [Raisio]
-Raision keskusta = 2010
-Kauppakeskus Mylly = 2117
+Raisio = 2010
+Mylly = 2117
 Petäsmäki = 2063
 Kaanaa = 2037
 Vuorenpää = 2028
@@ -79,7 +79,7 @@
 Tikanmaa = 2136
 
 [Naantali]
-Naantalin keskusta = 3016
+Naantali = 3016
 Ahteentaka = 3290
 Kurala (Naantali) = 3196
 Haapala = 3283
@@ -121,7 +121,7 @@
 Haijainen = 3231
 
 [Rusko]
-Ruskon keskusta = 4017
+Rusko = 4017
 Vahto = 4069
 Hemmola = 4077
 Silvola = 4086
--- a/service.py	Sat Oct 07 01:52:15 2017 +0300
+++ b/service.py	Thu Oct 26 16:54:29 2017 +0300
@@ -91,6 +91,43 @@
 def imminent(schedule_entry):
 	return (schedule_entry['time'] - now()) <= timedelta(minutes = 3)
 
+def first_halt_in_trip_in_place(trip, place):
+	for halt in trip.schedule:
+		if halt.stop.region == place:
+			return halt
+	else:
+		return None
+
+place_abbreviations = ConfigParser()
+place_abbreviations.read('abbreviations.ini')
+
+def place_abbreviation(place):
+	try:
+		return place_abbreviations['abbreviations'][place]
+	except KeyError:
+		return place
+
+def trip_abbreviation(trip):
+	entries = [trip.from_place]
+	old_places = None
+	starting_halt = None
+	while True:
+		remaining_length = trip.length
+		if starting_halt:
+			remaining_length -= starting_halt.traveled_distance
+		places = reduce_schedule(trip.concise_schedule(starting_stop = starting_halt), trip_length = remaining_length, long = False)
+		new_places = set(places) - set(entries)
+		if not new_places or places == old_places:
+			break
+		for place in places:
+			if place in new_places:
+				starting_halt = first_halt_in_trip_in_place(trip, place)
+				entries += [place]
+				break
+		old_places = places
+	if trip.to_place not in entries:
+		entries += [trip.to_place]
+	return trip.route.reference + ':' + '-'.join(map(place_abbreviation, entries))
 
 @app.route('/stop/<reference>')
 def bus_stop_schedule(reference):
@@ -120,6 +157,34 @@
 		tr = tr,
 	)
 
+@app.route('/api/describe_destination/<trip_reference>/<stop_reference>/<int:index>')
+def describe_destination(trip_reference, stop_reference, index):
+	from buses import bus_stops, all_trips
+	from busroute import simplify_name
+	from flask import jsonify
+	try:
+		trip = all_trips[trip_reference]
+		bus_stop = bus_stops[stop]
+		schedule_entry = [schedule_entry for schedule_entry in trip.schedule if schedule_entry.stop.reference == stop_reference][index]
+	except KeyError:
+		abort(404)
+	except ValueError:
+		abort(404)
+	return jsonify(long_form_sign({'trip': trip, 'stop': schedule_entry}))
+
+@app.route('/api/trip_abbreviation/<block_id>/<int:arrival_time_offset>')
+def api_trip_abbreviation(block_id, arrival_time_offset):
+	from buses import trips_by_vehicle_info
+	from flask import jsonify
+	from datetime import timedelta
+	try:
+		trip = trips_by_vehicle_info[block_id, timedelta(seconds = arrival_time_offset)]
+	except KeyError:
+		abort(404)
+	return jsonify({
+		'abbreviation': trip_abbreviation(trip),
+	})
+
 @app.route('/stop_display/<reference>')
 def stop_display(reference):
 	from buses import bus_stops
@@ -286,17 +351,25 @@
 	for halt in trip.schedule:
 		stop_time = datetime.combine(today(), time()) + halt.arrival_time
 		formatted_time = time_representation(stop_time)
-		if halt.stop.region != region and not (region and not halt.stop.region):
-			if len(schedule) and not schedule[-1]['name']:
-				schedule[-1]['name'] = tr(halt.stop.region or '', 'paikat')
-			else:
-				schedule.append({
-					'name': tr(halt.stop.region or '', 'paikat'),
-					'time': formatted_time,
-					'stops': [],
-					'index': len(schedule),
-				})
-			region = halt.stop.region
+		if profile['regions']['use-regions']:
+			if halt.stop.region != region and not (region and not halt.stop.region):
+				if len(schedule) and not schedule[-1]['name']:
+					schedule[-1]['name'] = tr(halt.stop.region or '', 'paikat')
+				else:
+					schedule.append({
+						'name': tr(halt.stop.region or '', 'paikat'),
+						'time': formatted_time,
+						'stops': [],
+						'index': len(schedule),
+					})
+				region = halt.stop.region
+		else:
+			schedule.append({
+				'name': tr(halt.stop.name or '', 'bus-stops'),
+				'time': formatted_time,
+				'stops': [],
+				'index': len(schedule),
+			})
 		schedule[-1]['stops'].append({
 			'time': formatted_time,
 			'id': halt.stop.reference,
@@ -367,9 +440,8 @@
 	parser.add_argument('-d', '--debug', action = 'store_true')
 
 args = parser.parse_args()
-profile = ConfigParser()
 profile.read(args.profile_path)
-buses.load_buses(args.gtfs_zip_path, profile = profile)
+buses.load_buses(args.gtfs_zip_path)
 
 if __name__ == '__main__':
 	app.run(debug = args.debug, port = args.port)

mercurial