def parse(html, points_array, steps_array): soup = BeautifulSoup(html) routes = [] route_index = 0 while True: route_node = soup.find("div", { "id" : "ts_route_" + str(route_index) }) if route_node == None: break; directions = [] total_duration = 0 steps = steps_array[route_index] points = points_array[route_index] for index in range(len(steps) - 1): step_node = route_node.find(attrs = { "id" : "step_" + str(route_index) + "_" + str(index) + "_segment" }) step = common.RouteStep() if step_node != None: step.direction = get_node_text(step_node.find(attrs = { "class" : "dir-ts-direction" })) segment_text = get_nodes_text(step_node.findAll(attrs = { "class": "dirsegtext" })) if segment_text != '': if step.direction.find('Unknown') > 0: # Prevent 'Walk to Unknown' direction step.direction = segment_text else: step.direction += ': ' + segment_text step.addinfo = get_nodes_text(step_node.findAll(attrs = { "class" : re.compile('^dir-ts-addinfo.*') })).replace('(','').replace(')','') step.duration = parse_duration(step.addinfo) step.initial_duration = step.duration total_duration += step.duration transport_type = get_transport(step.direction) if transport_type == None or transport_type == 'Walk': step.direction = clean_walk_direction(step.direction) else: line_number = get_node_text(step_node.find(attrs = { "class" : "trtline" })) step.service_interval = parse_service_interval(step.addinfo) step.transport = common.Transport(transport_type, line_number, step.service_interval) step.direction = _(step.transport.type) step.transport.stops = parse_stops(step.addinfo) if step.transport.is_subway(): step.direction += utils.subway_color(' ' + _('line') + ' ' + str(step.transport.line_number), step.transport.line_number); else: step.direction += ' ' + _('number') + ' ' + step.transport.line_number step.start_name = clean_walk_direction(get_node_text(step_node.find('b'))) if step_node.nextSibling != None: arrive_node = step_node.nextSibling.find(text = re.compile('^Arrive.*')) if arrive_node != None: step.end_name = clean_walk_direction(get_node_text(arrive_node.nextSibling)) start_point = points[steps[index]['depPoint']] end_point = points[steps[index]['arrPoint']] step.start_location = common.GeoPoint(start_point['lat'], start_point['lng']) step.end_location = common.GeoPoint(end_point['lat'], end_point['lng']) if not step.is_walk(): directions.append(step) routes.append(common.Route(directions, 'google')) route_index += 1 return routes
def process_transit_route(start_location, end_location, route): language = utils.get_language() # Add end walk end_walk = get_walking_step(route.directions[-1].end_location, end_location) if end_walk.duration > 0: route.directions.append(end_walk) first_subway = True index = 0 while index < len(route.directions) and index < 100: step = route.directions[index] previous_step = route.directions[index - 1] if index > 0 else None next_step = route.directions[index + 1] if index < len(route.directions) - 1 else None if step.transport != None: if step.transport.is_train(): station = router.resolve_name(step.start_name, 'Train', step.start_location) if station != None: step.start_name = station.name_rus if language == 'ru' else station.name step.transport.start_code = station.name_rus step.start_location.lat = station.lat step.start_location.lng = station.lng station = router.resolve_name(step.end_name, 'Train', step.end_location) if station != None: step.end_name = station.name_rus if language == 'ru' else station.name step.transport.end_code = station.name_rus step.end_location.lat = station.lat step.end_location.lng = station.lng if not step.transport.is_subway() or first_subway: from_location = previous_step.end_location if previous_step != None else start_location tostop_walk = get_walking_step(from_location, step.start_location, _(step.transport.type).lower() + ' ' + _('stop') + ' ' + step.start_name) route.directions.insert(index, tostop_walk) index += 1 if step.transport.is_train(): new_step = common.RouteStep(_('Buy the train tickets to') + ' ' + step.end_name + ', ' + _('wait for the train'), 15, '', common.Transport('Train', price = step.transport.price)) route.directions.insert(index, new_step) index += 1 step.transport.price = None if step.transport.is_subway(): if first_subway: new_step = common.RouteStep(_('Enter subway station') + ' ' + utils.subway_color(step.start_name, step.transport.line_number) + ' (' + _('buy the tokens if needed') + ')', 5, utils.duration_to_string(5) + ', ' + utils.price_to_string(27), common.Transport('Subway', price = 27)) else: to_text = _('Change to') + ' ' + utils.subway_color(_('line') + ' ' + str(step.transport.line_number), step.transport.line_number) + ' ' + _('station') + ' ' + utils.subway_color(step.start_name, step.transport.line_number) new_step = common.RouteStep(to_text, 4, utils.duration_to_string(4)) route.directions.insert(index, new_step) index += 1 step.transport.price = None first_subway = False if step.transport.stops == 0: route.directions.remove(step) continue # Set price for land transport if step.transport.type in ['Bus', 'Trolleybus', 'Tram']: step.transport.price = 23 elif step.transport.type in ['Share taxi']: step.transport.price = 35 # Make trolleybus less optimistic if step.transport.type == 'Trolleybus': step.duration *= 1.4 # Add 3/4 of service interval duration if not step.transport.is_subway(): if step.transport.interval != None: step.duration += step.transport.interval * 3 / 4 else: step.duration += get_default_service_interval(step.transport) * 3 / 4 # Do not show the map for change walks inside subway if step.is_walk() and previous_step != None and next_step != None and \ previous_step.is_subway() and next_step.is_subway(): step.duration = 4 # subway change is 4 minutes else: step.has_map = step.start_location != None and step.end_location != None if step.transport != None: if step.is_subway(): step.direction = _(step.transport.type) + ': ' + utils.subway_color(_('line') + ' ' + step.transport.line_number, step.transport.line_number) + \ ' ' + _('to') + ' ' + utils.subway_color(step.end_name, step.transport.line_number) elif step.transport.is_train(): step.direction = _(step.transport.type) + ' ' + _('to') + ' ' + step.end_name else: step.direction = _(step.transport.type) + ' ' + step.transport.line_number + ' ' + _('to') + ' ' + step.end_name # Improve walk to direction if step.is_walk() and next_step != None and not next_step.is_walk(): stop_text = _('station') if next_step.is_subway() else _('stop') step.direction = step.direction.replace(_('Walk to') + ' ', _('Walk to') + ' ' + _(next_step.transport.type).lower() + ' ' + stop_text + ' ') index += 1 # Find all subways subways = [step for step in route.directions if step.is_subway() and step.direction != None] if len(subways) > 0: # Add 4 minutes to exit subway subways[-1].direction += ', ' + _('leave the subway') subways[-1].duration += 4
def get_subway_route(start_location, end_location): route = router.get_route(start_location, end_location) if route == None: return None steps = [] first_subway = True for index, leg in enumerate(route): if leg.transport == 'Subway': if index > 0: if first_subway: to_text = 'Walk to subway station ' + utils.subway_color(leg.steps[0].station.name, leg.line) walk_time = max(int((leg.steps[0].distance + 30) / 60), 3) step = RouteStep(to_text, walk_time, utils.duration_to_string(walk_time), None, steps[-1].end_location, GeoPoint(leg.steps[0].station.lat, leg.steps[0].station.lng), True) else: to_text = 'Change to ' + utils.subway_color('line ' + str(leg.line), leg.line) + ' station ' + utils.subway_color(leg.steps[0].station.name, leg.line) change_time = max(int((leg.steps[0].distance + 30) / 60), 3) step = RouteStep(to_text, change_time, utils.duration_to_string(change_time)) steps.append(step) if first_subway: step = RouteStep('Buy the tokens if needed and enter subway station ' + utils.subway_color(leg.steps[0].station.name, leg.line), 5, utils.duration_to_string(5) + ', ' + utils.price_to_string(27), Transport('Subway', price = 27), GeoPoint(leg.steps[0].station.lat, leg.steps[0].station.lng)) #start location is needed for start walk steps.append(step) first_subway = False if len(leg.steps) > 1: # The change might be the first move => don't add a 0 steps way step = RouteStep() step.direction = 'Subway ' + utils.subway_color('line ' + str(leg.line), leg.line) + ' to ' + utils.subway_color(leg.steps[-1].station.name, leg.line) step.duration = int((sum([x.distance for x in leg.steps[1:]]) + 30) / 60) step.addinfo = utils.duration_to_string(step.duration) + ', ' + str(len(leg.steps) - 1) + ' stops' step.transport = Transport(leg.transport) step.start_location = GeoPoint(leg.steps[0].station.lat, leg.steps[0].station.lng) step.end_location = GeoPoint(leg.steps[-1].station.lat, leg.steps[-1].station.lng) step.has_map = True steps.append(step) else: if index > 0: to_text = 'Walk to ' + str(leg.transport).lower() + ' stop ' + leg.steps[0].station.name walk_time = max(int((leg.steps[0].distance + 30) / 60), 3) step = RouteStep(to_text, walk_time, utils.duration_to_string(walk_time), None, steps[-1].end_location, GeoPoint(leg.steps[0].station.lat, leg.steps[0].station.lng), True) steps.append(step) step = RouteStep() step.direction = leg.transport + ' ' + str(leg.line) + ' to ' + utils.subway_color(leg.steps[-1].station.name, leg.line) step.duration = sum([x.distance for x in leg.steps[1:]]) / 60 step.addinfo = utils.duration_to_string(step.duration) + ', ' + utils.price_to_string(23) step.transport = Transport(leg.transport, price = 23) step.start_location = GeoPoint(leg.steps[0].station.lat, leg.steps[0].station.lng) step.end_location = GeoPoint(leg.steps[-1].station.lat, leg.steps[-1].station.lng) step.has_map = True steps.append(step) start_walk = get_walking_route(start_location, steps[0].start_location) if start_walk.get_duration() > 0: steps.insert(0, start_walk.directions[0]) end_walk = get_walking_route(steps[-1].end_location, end_location) if end_walk.get_duration() > 0: steps.append(end_walk.directions[0]) if start_walk.get_duration() + end_walk.get_duration() < 40: return Route(steps)