def ORS_query_directions(query, profile='driving-car', toll_price=True, _id=0, geometry=True): ''' start (class point) end (class point) profile= ["driving-car", "driving-hgv", "foot-walking","foot-hiking", "cycling-regular", "cycling-road","cycling-mountain", "cycling-electric",] ''' ORS_client = start_ORS_client() coord = [query.start_point[::-1], query.end_point[::-1]] # WARNING it seems that [lon,lat] are not in the same order than for other API. try: ORS_step = ORS_client.directions( coord, profile=profile, instructions=False, geometry=geometry, options={'avoid_features': ['ferries']}, ) except: return None geojson = convert.decode_polyline(ORS_step['routes'][0]['geometry']) local_distance = ORS_step['routes'][0]['summary']['distance'] local_emissions = co2_emissions.calculate_co2_emissions(constants.TYPE_COACH, constants.DEFAULT_CITY, constants.DEFAULT_FUEL, constants.DEFAULT_NB_SEATS, constants.DEFAULT_NB_KM) * \ constants.DEFAULT_NB_PASSENGERS * local_distance step = tmw.Journey_step(_id, _type=ORS_profile(profile), label=profile, distance_m=local_distance, duration_s=ORS_step['routes'][0]['summary']['duration'], price_EUR=[ORS_gas_price(ORS_step['routes'][0]['summary']['distance'])], gCO2=local_emissions, geojson=geojson, departure_date=query.departure_date ) # Correct arrival_date based on departure_date step.arrival_date = (step.departure_date + timedelta(seconds=step.duration_s)) # Add toll price (optional) step = ORS_add_toll_price(step) if toll_price else step ors_journey = tmw.Journey(0, departure_date=query.departure_date, arrival_date=step.arrival_date, steps=[step]) # Add category category_journey = list() for step in ors_journey.steps: if step.type not in [constants.TYPE_TRANSFER, constants.TYPE_WAIT]: category_journey.append(step.type) ors_journey.category = list(set(category_journey)) ors_journey.update() ors_journey.arrival_date = ors_journey.departure_date + timedelta(seconds=ors_journey.total_duration) return ors_journey
def navitia_journeys_sections_type_street_network(json, _id=0): mode = json['mode'] mode_to_type = { 'walking': constants.TYPE_WALK, 'bike': constants.TYPE_BIKE, 'car': constants.TYPE_CAR, } label = '{} FROM {} TO {}'.format( mode_to_type[mode], json['from']['name'], json['to']['name'], ) step = tmw.Journey_step(_id, _type=mode_to_type[mode], label=label, distance_m=json['geojson']['properties'][0]['length'], duration_s=json['duration'], price_EUR=[0], gCO2=json['co2_emission']['value'], departure_point=json['from']['name'], arrival_point=json['to']['name'], departure_stop_name=json['from']['name'], arrival_stop_name=json['to']['name'], departure_date=datetime.strptime(json['departure_date_time'], '%Y%m%dT%H%M%S'), arrival_date=datetime.strptime(json['arrival_date_time'], '%Y%m%dT%H%M%S'), geojson=json['geojson'], ) return step
def navitia_journeys_sections_type_on_demand(json, _id=0): display_information = json['display_informations'] label = '{} {} / {} / direction: {}'.format( display_information['physical_mode'], display_information['code'], display_information['name'], display_information['direction'], ) step = tmw.Journey_step( _id, _type=display_information['network'].lower(), label=label, distance_m=json['geojson']['properties'][0]['length'], duration_s=json['duration'], price_EUR=[0], gCO2=json['co2_emission']['value'], departure_point=json['from']['name'], arrival_point=json['to']['name'], departure_stop_name=json['from']['name'], arrival_stop_name=json['to']['name'], departure_date=datetime.strptime(json['departure_date_time'], '%Y%m%dT%H%M%S'), arrival_date=datetime.strptime(json['arrival_date_time'], '%Y%m%dT%H%M%S'), geojson=json['geojson'], ) return step
def navitia_journeys_sections_type_public_transport(json, _id=0): display_information = json['display_informations'] label = '{} {} / {} / direction: {}'.format( display_information['physical_mode'], display_information['code'], display_information['name'], display_information['direction'], ) switcher_public_transport_type = { 'Métro': constants.TYPE_METRO, 'Bus': constants.TYPE_BUS, 'Tramway': constants.TYPE_TRAM, 'RER': constants.TYPE_METRO, } _type = switcher_public_transport_type.get(display_information['commercial_mode'], "unknown public transport") # _type = display_information['commercial_mode'] # _type = unicodedata.normalize('NFD', _type).encode('ascii', 'ignore').lower() step = tmw.Journey_step(_id, _type=_type, label=label, distance_m=json['geojson']['properties'][0]['length'], duration_s=json['duration'], price_EUR=[0], gCO2=json['co2_emission']['value'], departure_point=json['from']['name'], arrival_point=json['to']['name'], departure_stop_name=json['from']['name'], arrival_stop_name=json['to']['name'], departure_date=datetime.strptime(json['departure_date_time'], '%Y%m%dT%H%M%S'), arrival_date=datetime.strptime(json['arrival_date_time'], '%Y%m%dT%H%M%S'), geojson=json['geojson'], ) return step
def compute_complete_journey(departure_date='2019-11-25T09:00:00+0200', geoloc_dep=[48.85, 2.35], geoloc_arrival=[43.60, 1.44]): # Let's create the start to finish query query_start_finish = tmw.query(0, geoloc_dep, geoloc_arrival, departure_date) # First we look for intercities journeys trainline_journeys = Trainline.main(query_start_finish) skyscanner_journeys = Skyscanner.main(query_start_finish) ouibus_journeys = OuiBus.main(query_start_finish) # ors_step = ORS.ORS_query_directions(query_start_finish) all_journeys = trainline_journeys + skyscanner_journeys + ouibus_journeys # Then we call Navitia to get for interurban_journey in all_journeys: start_to_station_query = tmw.query( 0, geoloc_dep, interurban_journey.steps[0].departure_point, departure_date) start_to_station_steps = Navitia.navitia_query_directions( start_to_station_query) station_to_arrival_query = tmw.query( 0, interurban_journey.steps[-1].arrival_point, geoloc_arrival, departure_date) station_to_arrival_steps = Navitia.navitia_query_directions( station_to_arrival_query) if (start_to_station_steps is not None) & (station_to_arrival_steps is not None): interurban_journey.add_steps(start_to_station_steps[0].steps, start_end=True) print( f'arrival point is :{interurban_journey.steps[-1].arrival_point}' ) interurban_journey.add_steps(station_to_arrival_steps[0].steps, start_end=False) interurban_journey.update() else: interurban_journey.reset() # all_journeys = all_journeys + ors_step return all_journeys
def navitia_journeys_sections_type_waiting(json, _id=0): step = tmw.journey_step( _id, _type=constants.TYPE_WAIT, label='wait', distance_m=None, duration_s=json['duration'], price_EUR=[0], gCO2=json['co2_emission']['value'], geojson='', ) return step
def create_fake_plane_journey(locations, airport_dep, airport_arrival): """ We create a fake plane journey with only the approximate eqCO2 to be used in the computation in the front end :param query: :return: fake_journey """ geoloc_dep = locations['departure'][locations['departure'].city_sky == airport_dep].sample().geoloc geoloc_arrival = locations['arrival'][locations['arrival'].city_sky == airport_arrival].sample().geoloc distance_m = distance(geoloc_dep, geoloc_arrival).m local_range_km = get_range_km(distance_m) local_emissions = calculate_co2_emissions(constants.TYPE_PLANE, constants.DEFAULT_CITY, constants.DEFAULT_FUEL, constants.NB_SEATS_TEST, local_range_km) * \ constants.DEFAULT_NB_PASSENGERS * distance_m fake_journey_list = list() fake_journey_step = tmw.Journey_step( 0, _type=constants.TYPE_PLANE, label= f'Arrive at the airport {format_timespan(_AIRPORT_WAITING_PERIOD)} before departure', distance_m=0, duration_s=_AIRPORT_WAITING_PERIOD, price_EUR=[0], gCO2=local_emissions, departure_point=geoloc_dep, arrival_point=geoloc_arrival, departure_date=dt.now(), arrival_date=dt.now(), geojson=[], ) fake_journey_list.append(fake_journey_step) fake_journey = tmw.Journey(0, steps=fake_journey_list, departure_date=fake_journey_step.departure_date, arrival_date=fake_journey_step.arrival_date) fake_journey.total_gCO2 = local_emissions fake_journey.is_real_journey = False return fake_journey
def navitia_journeys_sections_type_waiting(json, _id=0): step = tmw.Journey_step(_id, _type=constants.TYPE_WAIT, label='wait', distance_m=0, duration_s=json['duration'], price_EUR=[0], gCO2=0, departure_point=[0,0], arrival_point=[0,0], departure_stop_name='', arrival_stop_name='', departure_date=datetime.strptime(json['departure_date_time'], '%Y%m%dT%H%M%S'), arrival_date=datetime.strptime(json['arrival_date_time'], '%Y%m%dT%H%M%S'), geojson='', ) return step
def navitia_journeys_sections_type_public_transport(json, _id=0): display_information = json['display_informations'] label = '{} {} / {} / direction: {}'.format( display_information['physical_mode'], display_information['code'], display_information['name'], display_information['direction'], ) step = tmw.journey_step( _id, _type=display_information['network'].lower(), label=label, distance_m=None, duration_s=json['duration'], price_EUR=[0], gCO2=json['co2_emission']['value'], geojson=json['geojson'], ) return step
def navitia_journeys_sections_type_transfer(json, _id=0): mode = json['transfer_type'] mode_to_type = { 'walking': constants.TYPE_WALK, 'bike': constants.TYPE_BIKE, 'car': constants.TYPE_CAR, } label = '{} FROM {} TO {}'.format(mode_to_type[mode], json['from']['name'], json['to']['name']) step = tmw.journey_step( _id, _type=mode_to_type[mode], label=label, distance_m=None, duration_s=json['duration'], price_EUR=[0], gCO2=json['co2_emission']['value'], geojson=json['geojson'], ) return step
def navitia_journeys(json, _id=0): # all journeys loop lst_journeys = list() try: journeys = json['journeys'] except: logger.warning('ERROR {}'.format(json['error'])) return None for j in json['journeys']: i = _id # journey loop lst_sections = list() for section in j['sections']: try: lst_sections.append(navitia_journeys_sections_type(section, _id=i)) except: logger.warning('Navitia ERROR : ') logger.warning('id: {}'.format(i)) logger.warning(section) i = i + 1 lst_journeys.append(tmw.Journey(_id, steps=lst_sections)) return lst_journeys
def get_ferries(date_departure, date_return, departure_point, arrival_point): """ We create a ferry journey based on the ferry database we scraped """ # Find relevant ports port_deps, port_arrs = get_ports_from_geo_locs(departure_point, arrival_point) # Find journeys journeys = _FERRY_DATA[ (_FERRY_DATA.port_dep.isin(port_deps.port_clean.unique())) & _FERRY_DATA.port_arr.isin(port_arrs.port_clean.unique())] journeys['date_dep'] = pd.to_datetime(journeys.date_dep) journeys = journeys[journeys.date_dep > date_departure] if len(journeys) == 0: logger.info(f'No ferry journey was found') return None journey_list = list() for index, row in journeys.iterrows(): distance_m = row.distance_m local_emissions = calculate_co2_emissions(constants.TYPE_PLANE, constants.DEFAULT_CITY, constants.DEFAULT_FUEL, constants.NB_SEATS_TEST, constants.DEFAULT_NB_KM) * \ constants.DEFAULT_NB_PASSENGERS * distance_m journey_steps = list() journey_step = tmw.Journey_step( 0, _type=constants.TYPE_WAIT, label= f'Arrive at the port {format_timespan(_PORT_WAITING_PERIOD)} before departure', distance_m=0, duration_s=_PORT_WAITING_PERIOD, price_EUR=[0], gCO2=0, departure_point=[row.lat_clean_dep, row.long_clean_dep], arrival_point=[row.lat_clean_dep, row.long_clean_dep], departure_date=row.date_dep - timedelta(seconds=_PORT_WAITING_PERIOD), arrival_date=row.date_dep, geojson=[], ) journey_steps.append(journey_step) journey_step = tmw.Journey_step( 1, _type=constants.TYPE_FERRY, label=f'Sail Ferry from {row.port_dep} to {row.port_arr}', distance_m=distance_m, duration_s=(row.date_arr - row.date_dep).seconds, price_EUR=[row.price_clean_ar_eur / 2], gCO2=local_emissions, departure_point=[row.lat_clean_dep, row.long_clean_dep], arrival_point=[row.lat_clean_arr, row.long_clean_arr], departure_date=row.date_dep, arrival_date=row.date_arr, geojson=[], ) journey_steps.append(journey_step) journey = tmw.Journey( 0, steps=journey_steps, departure_date=journey_steps[0].departure_date, arrival_date=journey_steps[1].arrival_date, ) journey.total_gCO2 = local_emissions journey.category = constants.CATEGORY_FERRY_JOURNEY journey.booking_link = 'https://www.ferrysavers.co.uk/ferry-routes.htm' journey.departure_point = [row.lat_clean_dep, row.long_clean_dep] journey.arrival_point = [row.lat_clean_arr, row.long_clean_arr] journey.update() journey_list.append(journey) return journey_list
def trainline_journeys(df_response, _id=0): """ This function takes in a DF with detailled info about all the Trainline trips It returns a list of TMW journey objects """ # affect a price to each leg (otherwise we would multiply the price by the number of legs df_response['price_step'] = df_response.cents / (df_response.nb_segments*100) # Compute distance for each leg # print(df_response.columns) df_response['distance_step'] = df_response.apply(lambda x: distance(x.geoloc_depart_seg, x.geoloc_arrival_seg).m, axis=1) df_response['trip_code'] = df_response.train_name + ' ' + df_response.train_number tranportation_mean_to_type = { 'coach': constants.TYPE_COACH, 'train': constants.TYPE_TRAIN, } lst_journeys = list() # all itineraries : # print(f'nb itinerary : {df_response.id_global.nunique()}') for itinerary_id in df_response.id_global.unique(): itinerary = df_response[df_response.id_global == itinerary_id].reset_index(drop=True) # boolean to know whether and when there will be a transfer after the leg itinerary['next_departure'] = itinerary.departure_date_seg.shift(-1) itinerary['next_stop_name'] = itinerary.name_depart_seg.shift(-1) itinerary['next_geoloc'] = itinerary.geoloc_depart_seg.shift(-1) itinerary['trip_code'] = itinerary.trip_code.fillna('') # get the slugs to create the booking link origin_slug = itinerary.origin_slug.unique()[0] destination_slug = itinerary.destination_slug.unique()[0] i = _id lst_sections = list() # We add a waiting period at the station of 15 minutes step = tmw.Journey_step(i, _type=constants.TYPE_WAIT, label=f'Arrive at the station {format_timespan(_STATION_WAITING_PERIOD)} before departure', distance_m=0, duration_s=_STATION_WAITING_PERIOD, price_EUR=[0], gCO2=0, departure_point=[itinerary.latitude.iloc[0], itinerary.longitude.iloc[0]], arrival_point=[itinerary.latitude.iloc[0], itinerary.longitude.iloc[0]], departure_date=itinerary.departure_date_seg[0] - timedelta(seconds=_STATION_WAITING_PERIOD), arrival_date=itinerary.departure_date_seg[0], bike_friendly=True, geojson=[], ) lst_sections.append(step) i = i + 1 # Go through all steps of the journey for index, leg in itinerary.iterrows(): local_distance_m = distance(leg.geoloc_depart_seg, leg.geoloc_arrival_seg).m local_transportation_type = tranportation_mean_to_type[leg.transportation_mean] local_emissions = co2_emissions.calculate_co2_emissions(local_transportation_type, constants.DEFAULT_CITY, constants.DEFAULT_FUEL, constants.DEFAULT_NB_SEATS, constants.DEFAULT_NB_KM) * \ constants.DEFAULT_NB_PASSENGERS * local_distance_m step = tmw.Journey_step(i, _type=local_transportation_type, label=f'{leg.trip_code} to {leg.name_arrival_seg}', distance_m=local_distance_m, duration_s=(leg.arrival_date_seg - leg.departure_date_seg).seconds, price_EUR=[leg.price_step], gCO2=local_emissions, departure_point=leg.geoloc_depart_seg, arrival_point=leg.geoloc_arrival_seg, departure_stop_name=leg.name_depart_seg, arrival_stop_name=leg.name_arrival_seg, departure_date=leg.departure_date_seg, arrival_date=leg.arrival_date_seg, trip_code=leg.trip_code, bike_friendly='bicycle' in leg.bike_friendliness, geojson=[], ) lst_sections.append(step) i = i + 1 # add transfer steps if not pd.isna(leg.next_departure): step = tmw.Journey_step(i, _type=constants.TYPE_TRANSFER, label=f'Transfer at {leg.name_arrival_seg}', distance_m=0, duration_s=(leg['next_departure'] - leg['arrival_date_seg']).seconds, price_EUR=[0], departure_point=leg.geoloc_arrival_seg, arrival_point=leg.next_geoloc, departure_stop_name=leg.name_depart_seg, arrival_stop_name=leg.name_arrival_seg, departure_date=leg.arrival_date_seg, arrival_date=leg.next_departure, gCO2=0, bike_friendly=True, geojson=[], ) lst_sections.append(step) i = i + 1 departure_date_formated = dt.strptime(str(lst_sections[0].departure_date)[0:15], '%Y-%m-%d %H:%M').strftime('%Y-%m-%d %H:00') journey_train = tmw.Journey(_id, steps=lst_sections, departure_date= lst_sections[0].departure_date, arrival_date= lst_sections[-1].arrival_date, booking_link=f'https://www.trainline.fr/search/{origin_slug}/{destination_slug}/{departure_date_formated}') # Add category category_journey = list() for step in journey_train.steps: if step.type not in [constants.TYPE_TRANSFER, constants.TYPE_WAIT]: category_journey.append(step.type) journey_train.category = list(set(category_journey)) lst_journeys.append(journey_train) # for journey in lst_journeys: # journey.update() return lst_journeys
def create_plane_journey_from_flightradar_data(airports, departure_date): """ We create a fake plane journey with only the approximate eqCO2 to be used in the computation in the front end :param query: :return: fake_journey """ day_of_week = departure_date.weekday() hour_of_day = departure_date.hour relevant_flights = _FLIGHTRADAR_DATA[ _FLIGHTRADAR_DATA.city_sky.isin(airports['departure']) & _FLIGHTRADAR_DATA.city_sky_arr.isin(airports['arrival'])] relevant_flights = relevant_flights[relevant_flights.day_of_week == day_of_week] relevant_flights['hour_dep'] = relevant_flights.apply( lambda x: dt.strptime(x.hour_dep, '%H:%M:%S') + timedelta(hours=1), axis=1) relevant_flights['hour_dep_int'] = relevant_flights.apply( lambda x: x.hour_dep.hour, axis=1) response_flights = pd.DataFrame() for airport_dep in airports['departure']: for airport_arr in airports['arrival']: flights_df = relevant_flights[ (relevant_flights.city_sky == airport_dep) & (relevant_flights.city_sky_arr == airport_arr) & (relevant_flights.hour_dep_int >= hour_of_day)] response_flights = response_flights.append(flights_df) # distance_m = distance(geoloc_dep, geoloc_arrival).m response_flights['local_range_km'] = response_flights.apply( lambda x: get_range_km(x.distance_m), axis=1) response_flights['local_emissions'] = response_flights.apply( lambda x: calculate_co2_emissions( constants.TYPE_PLANE, constants.DEFAULT_CITY, constants. DEFAULT_FUEL, constants.NB_SEATS_TEST, x.local_range_km) * constants.DEFAULT_NB_PASSENGERS * x.distance_m, axis=1) # merge global departure date and flight time to create flight actual departure datetime response_flights['flight_departure_date'] = response_flights.apply( lambda x: dt.combine(departure_date, dt_time(x.hour_dep.hour, x.hour_dep.minute)), axis=1) response_flights['flight_arrival_date'] = response_flights.apply( lambda x: x.flight_departure_date + timedelta(seconds=x.flight_time_s), axis=1) journey_list = list() for index, flight in response_flights.iterrows(): lst_sections = list() # We add a waiting period at the airport of x hours step = tmw.Journey_step( 0, _type=constants.TYPE_WAIT, label= f'Arrive at the airport {format_timespan(_AIRPORT_WAITING_PERIOD)} before departure', distance_m=0, duration_s=_AIRPORT_WAITING_PERIOD, price_EUR=[], gCO2=0, departure_point=[flight.latitude, flight.longitude], arrival_point=[flight.latitude, flight.longitude], departure_date=flight.flight_departure_date - timedelta(seconds=_AIRPORT_WAITING_PERIOD), arrival_date=flight.flight_departure_date, geojson=[], ) lst_sections.append(step) step = tmw.Journey_step( 1, _type=constants.TYPE_PLANE, label=f'Flight {flight.flight_number} to {flight.airport_to_code}', distance_m=flight.distance_m, duration_s=flight.flight_time_s, price_EUR=[], gCO2=flight.local_emissions, departure_point=[flight.latitude, flight.longitude], arrival_point=[flight.latitude_arr, flight.longitude_arr], departure_stop_name=flight.airport_from, arrival_stop_name=flight.airport_to_code, departure_date=flight.flight_departure_date, arrival_date=flight.flight_arrival_date, trip_code=flight.flight_number, geojson=[], ) lst_sections.append(step) departure_date_formated = dt.strptime( str(lst_sections[0].departure_date)[0:10], '%Y-%m-%d') departure_date_formated = str(departure_date_formated.year)[2:4]+\ ('0'+str(departure_date_formated.month))[-2:]+\ ('0'+str(departure_date_formated.day))[-2:] journey_flightradar = tmw.Journey( 0, steps=lst_sections, departure_date=lst_sections[0].departure_date, arrival_date=lst_sections[-1].arrival_date, booking_link= f'https://www.skyscanner.fr/transport/vols/{flight.airport_from}/{flight.airport_to_code}/{departure_date_formated}/' ) journey_flightradar.category = [constants.TYPE_PLANE] journey_flightradar.update() journey_flightradar.is_real_journey = False journey_list.append(journey_flightradar) return journey_list
def ouibus_journeys(df_response, _id=0): """ This function takes in a DF with detailled info about all the OuiBus trips It returns a list of TMW journey objects """ # affect a price to each leg df_response['price_step'] = df_response.price_cents / ( df_response.nb_segments * 100) # Compute distance for each leg # print(df_response.columns) df_response['distance_step'] = df_response.apply( lambda x: distance(x.geoloc_origin_seg, x.geoloc_destination_seg).m, axis=1) lst_journeys = list() # all itineraries : # logger.info(f'nb itinerary : {df_response.id.nunique()}') for itinerary_id in df_response.id.unique(): itinerary = df_response[df_response.id == itinerary_id].reset_index( drop=True) # boolean to know whether and when there will be a transfer after the leg itinerary['next_departure'] = itinerary.departure_seg.shift(-1) itinerary['next_stop_name'] = itinerary.short_name_origin_seg.shift(1) itinerary['next_geoloc'] = itinerary.geoloc_origin_seg.shift(-1) # get the slugs to create the booking link origin_slug = itinerary.origin_slug.unique()[0] destination_slug = itinerary.destination_slug.unique()[0] i = _id lst_sections = list() # We add a waiting period at the station of 15 minutes step = tmw.Journey_step( i, _type=constants.TYPE_WAIT, label= f'Arrive at the station {format_timespan(_STATION_WAITING_PERIOD)} before departure', distance_m=0, duration_s=_STATION_WAITING_PERIOD, price_EUR=[0], gCO2=0, departure_point=itinerary.geoloc.iloc[0], arrival_point=itinerary.geoloc.iloc[0], departure_date=itinerary.departure_seg[0] - timedelta(seconds=_STATION_WAITING_PERIOD), arrival_date=itinerary.departure_seg[0], geojson=[], ) lst_sections.append(step) i = i + 1 for index, leg in itinerary.iterrows(): local_distance_m = leg.distance_step local_emissions = calculate_co2_emissions(constants.TYPE_COACH, constants.DEFAULT_CITY, constants.DEFAULT_FUEL, constants.DEFAULT_NB_SEATS, constants.DEFAULT_NB_KM) *\ constants.DEFAULT_NB_PASSENGERS*local_distance_m step = tmw.Journey_step( i, _type=constants.TYPE_COACH, label= f'Coach OuiBus {leg.bus_number} to {leg.short_name_destination_seg}', distance_m=local_distance_m, duration_s=(leg.arrival_seg - leg.departure_seg).seconds, price_EUR=[leg.price_step], gCO2=local_emissions, departure_point=leg.geoloc_origin_seg, arrival_point=leg.geoloc_destination_seg, departure_stop_name=leg.short_name_origin_seg, arrival_stop_name=leg.short_name_destination_seg, departure_date=leg.departure_seg, arrival_date=leg.arrival_seg, trip_code='OuiBus ' + leg.bus_number, geojson=[], ) lst_sections.append(step) i = i + 1 # add transfer steps if not pd.isna(leg.next_departure): step = tmw.Journey_step( i, _type=constants.TYPE_TRANSFER, label=f'Transfer at {leg.short_name_destination_seg}', distance_m=distance(leg.geoloc_destination_seg, leg.next_geoloc).m, duration_s=(leg['next_departure'] - leg['arrival_seg']).seconds, price_EUR=[0], departure_point=leg.geoloc_destination_seg, arrival_point=leg.next_geoloc, departure_stop_name=leg.short_name_destination_seg, arrival_stop_name=leg.next_stop_name, gCO2=0, geojson=[], ) lst_sections.append(step) i = i + 1 departure_date_formated = dt.strptime( str(lst_sections[0].departure_date)[0:15], '%Y-%m-%d %H:%M').strftime('%Y-%m-%d %H:00') journey_ouibus = tmw.Journey( _id, steps=lst_sections, booking_link= f'https://fr.ouibus.com/recherche?origin={origin_slug}&destination={destination_slug}&outboundDate={departure_date_formated}' ) # Add category category_journey = list() for step in journey_ouibus.steps: if step.type not in [constants.TYPE_TRANSFER, constants.TYPE_WAIT]: category_journey.append(step.type) journey_ouibus.category = list(set(category_journey)) lst_journeys.append(journey_ouibus) # for journey in lst_journeys: # journey.update() return lst_journeys
def skyscanner_journeys(df_response, _id=0): """ This function takes in a dataframe with detailled information on the plane journeys returned by Skyscanner API and returns a list containing one TMW journey object for each of those plane journey """ # affect a price to each leg df_response[ 'price_step'] = df_response.PriceTotal_AR / df_response.nb_segments df_response['DepartureDateTime'] = pd.to_datetime( df_response['DepartureDateTime']) df_response['ArrivalDateTime'] = pd.to_datetime( df_response['ArrivalDateTime']) # Compute distance for each leg df_response['distance_step'] = df_response.apply( lambda x: distance(x.geoloc_origin_seg, x.geoloc_destination_seg).m, axis=1) lst_journeys = list() # all itineraries : for itinerary_id in df_response.itinerary_id.unique(): itinerary = df_response[df_response.itinerary_id == itinerary_id].reset_index(drop=True) i = _id # boolean to know whether and when there will be a transfer after the leg itinerary['next_departure'] = itinerary.DepartureDateTime.shift(-1) itinerary['next_stop_name'] = itinerary.Name_origin_seg.shift(-1) itinerary['next_geoloc'] = itinerary.geoloc_origin_seg.shift(-1) # get the slugs to create the booking link departure_slug = itinerary.departure_slug.unique()[0].lower()[0:4] arrival_slug = itinerary.arrival_slug.unique()[0].lower()[0:4] lst_sections = list() # We add a waiting period at the airport of x hours step = tmw.Journey_step( i, _type=constants.TYPE_WAIT, label= f'Arrive at the airport {format_timespan(_AIRPORT_WAITING_PERIOD)} before departure', distance_m=0, duration_s=_AIRPORT_WAITING_PERIOD, price_EUR=[0], gCO2=0, departure_point=itinerary.geoloc.iloc[0], arrival_point=itinerary.geoloc.iloc[0], departure_date=itinerary.DepartureDateTime[0] - timedelta(seconds=_AIRPORT_WAITING_PERIOD), arrival_date=itinerary.DepartureDateTime[0], geojson=[], ) lst_sections.append(step) i = i + 1 for index, leg in itinerary.sort_values( by='DepartureDateTime').iterrows(): local_distance_m = leg.distance_step local_range_km = get_range_km(local_distance_m) local_emissions = calculate_co2_emissions(constants.TYPE_PLANE, constants.DEFAULT_CITY, constants.DEFAULT_FUEL, constants.NB_SEATS_TEST, local_range_km) * \ constants.DEFAULT_NB_PASSENGERS * local_distance_m step = tmw.Journey_step( i, _type=constants.TYPE_PLANE, label=f'Flight {leg.FlightNumber_rich} to {leg.Name}', distance_m=leg.distance_step, duration_s=leg.Duration_seg * 60, price_EUR=[leg.price_step], gCO2=local_emissions, departure_point=leg.geoloc_origin_seg, arrival_point=leg.geoloc_destination_seg, departure_stop_name=leg.Name_origin_seg, arrival_stop_name=leg.Name, departure_date=leg.DepartureDateTime, arrival_date=leg.ArrivalDateTime, trip_code=leg.FlightNumber_rich, geojson=[], ) lst_sections.append(step) i = i + 1 # add transfer steps if not pd.isna(leg.next_departure): #duration = dt.strptime(leg['next_departure'], '%Y-%m-%dT%H:%M:%S') - \ # dt.strptime(leg['ArrivalDateTime'], '%Y-%m-%dT%H:%M:%S') step = tmw.Journey_step( i, _type=constants.TYPE_TRANSFER, label=f'Transfer at {leg.Name}', distance_m=0, duration_s=(leg.next_departure - leg.ArrivalDateTime).seconds, price_EUR=[0], departure_point=leg.geoloc_destination_seg, arrival_point=leg.next_geoloc, departure_date=leg.ArrivalDateTime, arrival_date=leg.next_departure, departure_stop_name=leg.Name, arrival_stop_name=leg.next_stop_name, gCO2=0, geojson=[], ) lst_sections.append(step) i = i + 1 departure_date_formated = dt.strptime( str(lst_sections[0].departure_date)[0:10], '%Y-%m-%d') departure_date_formated = str(departure_date_formated.year)[2:4]+\ ('0'+str(departure_date_formated.month))[-2:]+\ ('0'+str(departure_date_formated.day))[-2:] journey_sky = tmw.Journey( _id, steps=lst_sections, departure_date=lst_sections[0].departure_date, arrival_date=lst_sections[-1].arrival_date, booking_link= f'https://www.skyscanner.fr/transport/vols/{departure_slug}/{arrival_slug}/{departure_date_formated}/' ) # journey_sky = tmw.Journey(_id, steps=lst_sections) # Add category category_journey = list() for step in journey_sky.steps: if step.type not in [constants.TYPE_TRANSFER, constants.TYPE_WAIT]: category_journey.append(step.type) journey_sky.category = list(set(category_journey)) lst_journeys.append(journey_sky) for journey in lst_journeys: journey.update() return lst_journeys
def trainline_journeys(df_response, _id=0): # affect a price to each leg df_response['price_step'] = df_response.cents / 100 # Compute distance for each leg # print(df_response.columns) df_response['distance_step'] = df_response.apply( lambda x: distance(x.geoloc_depart_seg, x.geoloc_arrival_seg).m, axis=1) df_response[ 'trip_code'] = df_response.train_name + ' ' + df_response.train_number tranportation_mean_to_type = { 'coach': constants.TYPE_COACH, 'train': constants.TYPE_TRAIN, } lst_journeys = list() # all itineraries : print(f'nb itinerary : {df_response.id_global.nunique()}') for itinerary_id in df_response.id_global.unique(): itinerary = df_response[df_response.id_global == itinerary_id] # boolean to know whether and when there will be a transfer after the leg itinerary['next_departure'] = itinerary.departure_date_seg.shift(-1) itinerary['next_stop_name'] = itinerary.name_depart_seg.shift(1) itinerary['next_geoloc'] = itinerary.geoloc_depart_seg.shift(-1) i = _id lst_sections = list() # We add a waiting period at the station of 15 minutes step = tmw.journey_step( i, _type=constants.TYPE_WAIT, label='', distance_m=0, duration_s=_STATION_WAITING_PERIOD, price_EUR=[0], gCO2=0, departure_point=[ itinerary.latitude.iloc[0], itinerary.longitude.iloc[0] ], arrival_point=[ itinerary.latitude.iloc[0], itinerary.longitude.iloc[0] ], geojson=[], ) lst_sections.append(step) i = i + 1 for index, leg in itinerary.iterrows(): local_distance_m = distance(leg.geoloc_depart_seg, leg.geoloc_arrival_seg).m local_emissions = calculate_co2_emissions(constants.TYPE_TRAIN, '', '', '', '') * \ constants.DEFAULT_NB_PASSENGERS * local_distance_m step = tmw.journey_step( i, _type=tranportation_mean_to_type[leg.transportation_mean], label='', distance_m=local_distance_m, duration_s=(leg.arrival_date_seg - leg.departure_date_seg).seconds, price_EUR=[leg.price_step], gCO2=local_emissions, departure_point=leg.geoloc_depart_seg, arrival_point=leg.geoloc_arrival_seg, departure_stop_name=leg.name_depart_seg, arrival_stop_name=leg.name_arrival_seg, departure_date=leg.departure_date_seg, arrival_date=leg.arrival_date_seg, trip_code=leg.trip_code, geojson=[], ) lst_sections.append(step) i = i + 1 # add transfer steps if not pd.isna(leg.next_departure): step = tmw.journey_step( i, _type=constants.TYPE_TRANSFER, label='', distance_m=0, duration_s=(leg['next_departure'] - leg['arrival_date_seg']).seconds, price_EUR=[0], departure_point=leg.geoloc_arrival_seg, arrival_point=leg.next_geoloc, departure_stop_name=leg.name_depart_seg, arrival_stop_name=leg.name_arrival_seg, departure_date=leg.arrival_date_seg, arrival_date=leg.next_departure, gCO2=0, geojson=[], ) lst_sections.append(step) i = i + 1 journey_sky = tmw.journey(_id, steps=lst_sections) lst_journeys.append(journey_sky) # for journey in lst_journeys: # journey.update() return lst_journeys
def compute_complete_journey(departure_date='2019-11-28', geoloc_dep=[48.85, 2.35], geoloc_arrival=[43.60, 1.44]): """ Build a multi-modal journey: First we call each API to get a few journeys for each type of transportation Then we create a multi-modal trip by calling NAvitia between the departure point and departure station and between arrival station and arrival point. To limit the nb of Navitia calls, we first create all the necessary Navitia queries, and deduplicate them to make sure we call Navitia only once for each query Finally we call the filter function to choose which journeys we keep """ # format date from %Y-%m-%dT%H:%M:%S.xxxZ without considering ms departure_date = datetime.datetime.strptime( str(departure_date)[0:19], "%Y-%m-%dT%H:%M:%S") # We only accept date up to 9 month in the future date_within_range = (datetime.datetime.today() + datetime.timedelta(days=9 * 30)) \ > departure_date if not date_within_range: raise Exception('Date out of range') # Let's create the start to finish query query_start_finish = tmw.Query(0, geoloc_dep, geoloc_arrival, departure_date) # logger.info(f'query_start_finish{query_start_finish.to_json()}') # Start the stopwatch / counter t1_start = perf_counter() # First we look for intercities journeys # Création des threads thread_skyscanner = tmw.ThreadComputeJourney(api='Skyscanner', query=query_start_finish) thread_ouibus = tmw.ThreadComputeJourney(api='OuiBus', query=query_start_finish) thread_trainline = tmw.ThreadComputeJourney(api='Trainline', query=query_start_finish) thread_ors = tmw.ThreadComputeJourney(api='ORS', query=query_start_finish) # Lancement des threads thread_skyscanner.start() thread_ouibus.start() thread_trainline.start() thread_ors.start() # Attendre que les threads se terminent skyscanner_journeys, time_skyscanner = thread_skyscanner.join() ouibus_journeys, time_ouibus = thread_ouibus.join() trainline_journeys, time_trainline = thread_trainline.join() ors_journey, time_or = thread_ors.join() if skyscanner_journeys is None: skyscanner_journeys = list() if trainline_journeys is None: trainline_journeys = list() if ouibus_journeys is None: ouibus_journeys = list() all_journeys = trainline_journeys + skyscanner_journeys + ouibus_journeys # all_journeys = trainline_journeys i = 0 logger.info(f'we found {len(all_journeys)} inter urban journeys') logger.info( f'it took for computing the interrurban journeys {perf_counter() - t1_start}' ) # Then we call Navitia to get the beginning and the end of the journey # Let's record all the query we need to send to Navitia, deduplicate them and call NAvitia only once navitia_queries = list() for interurban_journey in all_journeys: # if fake journey no call to Navitia if not interurban_journey.is_real_journey: continue interurban_journey.id = i i = i + 1 navitia_queries.append( tmw.Query(0, geoloc_dep, interurban_journey.steps[0].departure_point, departure_date)) navitia_queries.append( tmw.Query(0, interurban_journey.steps[-1].arrival_point, geoloc_arrival, departure_date)) nav_start = perf_counter() # Call Navitia only once each time: navitia_dict = {} navitia_query_done = list() navitia_thread_list = list() i = 0 for navitia_query in navitia_queries: if navitia_query.to_json() in navitia_query_done: # if query has been called then skip continue # logger.info(f'call Navitia with {navitia_query.to_json()}') navitia_thread_list.append(tmw.ThreadNavitiaCall(navitia_query)) navitia_thread_list[i].start() i = i + 1 # navitia_steps = Navitia.navitia_query_directions(navitia_query) # navitia_dict[str(navitia_query.to_json())] = navitia_steps navitia_query_done.append(navitia_query.to_json()) # navitia_dict_list.append(navitia_dict) for navitia_thread in navitia_thread_list: navitia_steps, navitia_query = navitia_thread.join() navitia_dict[str(navitia_query.to_json())] = navitia_steps logger.info(f'navitia_dict is {navitia_dict}') # Reconsiliate between navitia queries and interrurban journeys for interurban_journey in all_journeys: # if fake journey no call to Navitia # if not interurban_journey.is_real_journey: # continue # Get start to station query start_to_station_query = tmw.Query( 0, geoloc_dep, interurban_journey.steps[0].departure_point, departure_date) start_to_station_steps = navitia_dict[str( start_to_station_query.to_json())] station_to_arrival_query = tmw.Query( 0, interurban_journey.steps[-1].arrival_point, geoloc_arrival, departure_date) station_to_arrival_steps = navitia_dict[str( station_to_arrival_query.to_json())] if (start_to_station_steps is not None) & (station_to_arrival_steps is not None): interurban_journey.add_steps(start_to_station_steps[0].steps, start_end=True) interurban_journey.add_steps(station_to_arrival_steps[0].steps, start_end=False) interurban_journey.update() else: logger.info(f'remove category {interurban_journey.category}') # logger.info(f'remove price {interurban_journey.total_price_EUR}')# # logger.info(f'remove price {interurban_journey.total_distance}') # logger.info(f'remove legs nb {len(interurban_journey.steps)}') # logger.info(f'last leg departs from {interurban_journey.steps[-1].departure_stop_name}') # logger.info(f'last leg arrives in {interurban_journey.steps[-1].arrival_stop_name}') all_journeys.remove(interurban_journey) nav_stop = perf_counter() if ors_journey is not None: all_journeys.append(ors_journey) if len(all_journeys) > 0: # Filter most relevant Journeys filtered_journeys = filter_and_label_relevant_journey(all_journeys) filtered_journeys = [ filtered_journey.to_json() for filtered_journey in filtered_journeys ] else: filtered_journeys = all_journeys t1_stop = perf_counter() logger.info(f'Elapsed time during computation: {t1_stop-t1_start} s') logger.info(f'including: {time_trainline}s for trainline ') logger.info(f'including: {time_skyscanner}s for skyscanner ') logger.info(f'including: {time_ouibus}s for ouibus ') logger.info(f'including: {time_or}s for ors ') logger.info(f'including: {nav_stop - nav_start}s for navitia ') return filtered_journeys
def skyscanner_journeys(df_response, _id=0): # affect a price to each leg df_response[ 'price_step'] = df_response.PriceTotal_AR / df_response.nb_segments # Compute distance for each leg print(df_response.columns) df_response['distance_step'] = df_response.apply( lambda x: distance(x.geoloc_origin_seg, x.geoloc_destination_seg).m, axis=1) lst_journeys = list() # all itineraries : for itinerary_id in df_response.itinerary_id.unique(): itinerary = df_response[df_response.itinerary_id == itinerary_id] i = _id # boolean to know whether and when there will be a transfert after the leg itinerary['next_departure'] = itinerary.DepartureDateTime.shift(1) itinerary['next_stop_name'] = itinerary.Name_origin_seg.shift(1) itinerary['next_geoloc'] = itinerary.geoloc_origin_seg.shift(-1) lst_sections = list() # We add a waiting period at the airport of 2 hours step = tmw.journey_step( i, _type=constants.TYPE_WAIT, label='', distance_m=0, duration_s=_AIRPORT_WAITING_PERIOD, price_EUR=[0], gCO2=0, departure_point=itinerary.geoloc.iloc[0], arrival_point=itinerary.geoloc.iloc[0], geojson=[], ) lst_sections.append(step) i = i + 1 for index, leg in itinerary.sort_values( by='DepartureDateTime').iterrows(): local_distance_m = leg.distance_step local_range_km = get_range_km(local_distance_m) local_emissions = calculate_co2_emissions(constants.TYPE_PLANE, '', constants.DEFAULT_PLANE_FUEL, constants.DEFAULT_NB_SEATS, local_range_km) * \ constants.DEFAULT_NB_PASSENGERS * local_distance_m step = tmw.journey_step( i, _type=constants.TYPE_PLANE, label='', distance_m=leg.distance_step, duration_s=leg.Duration_seg * 60, price_EUR=[leg.price_step], gCO2=local_emissions, departure_point=leg.geoloc_origin_seg, arrival_point=leg.geoloc_destination_seg, departure_stop_name=leg.Name_origin_seg, arrival_stop_name=leg.Name, departure_date=leg.DepartureDateTime, arrival_date=leg.ArrivalDateTime, trip_code=leg.FlightNumber_rich, geojson=[], ) lst_sections.append(step) i = i + 1 # add transfer steps if not pd.isna(leg.next_departure): duration = dt.strptime(leg['next_departure'], '%Y-%m-%dT%H:%M:%S') - \ dt.strptime(leg['ArrivalDateTime'], '%Y-%m-%dT%H:%M:%S') step = tmw.journey_step( i, _type=constants.TYPE_TRANSFER, label='', distance_m=0, duration_s=duration.seconds, price_EUR=[0], departure_point=leg.geoloc_destination_seg, arrival_point=leg.next_geoloc, departure_date=leg.ArrivalDateTime, arrival_date=leg.next_departure, departure_stop_name=leg.Name, arrival_stop_name=leg.next_stop_name, gCO2=0, geojson=[], ) lst_sections.append(step) i = i + 1 journey_sky = tmw.journey(_id, steps=lst_sections) lst_journeys.append(journey_sky) for journey in lst_journeys: journey.update() return lst_journeys
def ouibus_journeys(df_response, _id=0): # affect a price to each leg df_response['price_step'] = df_response.price_cents / ( df_response.nb_segments * 100) # Compute distance for each leg # print(df_response.columns) df_response['distance_step'] = df_response.apply( lambda x: distance(x.geoloc_origin_seg, x.geoloc_destination_seg).m, axis=1) lst_journeys = list() # all itineraries : print(f'nb itinerary : {df_response.id.nunique()}') for itinerary_id in df_response.id.unique(): itinerary = df_response[df_response.id == itinerary_id] # boolean to know whether and when there will be a transfer after the leg itinerary['next_departure'] = itinerary.departure_seg.shift(-1) itinerary['next_stop_name'] = itinerary.short_name_origin_seg.shift(1) itinerary['next_geoloc'] = itinerary.geoloc_origin_seg.shift(-1) i = _id lst_sections = list() # We add a waiting period at the station of 15 minutes step = tmw.journey_step( i, _type=constants.TYPE_WAIT, label='', distance_m=0, duration_s=_STATION_WAITING_PERIOD, price_EUR=[0], gCO2=0, departure_point=itinerary.geoloc.iloc[0], arrival_point=itinerary.geoloc.iloc[0], geojson=[], ) lst_sections.append(step) i = i + 1 for index, leg in itinerary.iterrows(): local_distance_m = leg.distance_step local_emissions = calculate_co2_emissions(constants.TYPE_COACH, constants.BIG_CITY, '', '', '')*\ constants.DEFAULT_NB_PASSENGERS*local_distance_m step = tmw.journey_step( i, _type=constants.TYPE_COACH, label='', distance_m=local_distance_m, duration_s=(leg.arrival_seg - leg.departure_seg).seconds, price_EUR=[leg.price_step], gCO2=local_emissions, departure_point=leg.geoloc_origin_seg, arrival_point=leg.geoloc_destination_seg, departure_stop_name=leg.short_name_origin_seg, arrival_stop_name=leg.short_name_destination_seg, departure_date=leg.departure_seg, arrival_date=leg.arrival_seg, trip_code='OuiBus ' + leg.bus_number, geojson=[], ) lst_sections.append(step) i = i + 1 # add transfer steps if not pd.isna(leg.next_departure): step = tmw.journey_step( i, _type=constants.TYPE_TRANSFER, label='', distance_m=distance(leg.geoloc_destination_seg, leg.next_geoloc).m, duration_s=(leg['next_departure'] - leg['arrival_seg']).seconds, price_EUR=[0], departure_point=leg.geoloc_destination_seg, arrival_point=leg.next_geoloc, departure_stop_name=leg.short_name_destination_seg, arrival_stop_name=leg.next_stop_name, gCO2=0, geojson=[], ) lst_sections.append(step) i = i + 1 journey_ouibus = tmw.journey(_id, steps=lst_sections) lst_journeys.append(journey_ouibus) # for journey in lst_journeys: # journey.update() return lst_journeys
def blablacar_journey(df_response, departure_date, start_point, end_point): """ This function takes in a DF with detailled info about all the BlaBlaCar trips It returns a list of TMW journey objects """ lst_journeys = list() # all itineraries : # print(f'nb itinerary : {df_response.id_global.nunique()}') _id = 0 for trip_id in df_response.trip_id.unique(): itinerary = df_response[df_response.trip_id == trip_id] # Get the arrival info on the same line itinerary['date_time_arrival'] = itinerary.date_time.shift(-1) itinerary['city_arrival'] = itinerary.city.shift(-1) itinerary['address_arrival'] = itinerary.address.shift(-1) itinerary['latitude_arrival'] = itinerary.latitude.shift(-1) itinerary['longitude_arrival'] = itinerary.longitude.shift(-1) # boolean to know whether and when there will be a transfer after the leg itinerary['next_departure'] = itinerary.date_time.shift(1) # Get rid of the "last line" for the last leg of the blablacar trip itinerary = itinerary[~pd.isna(itinerary.city_arrival)] # Divide price between legs weighted by distance and distance itinerary['total_distance'] = itinerary.distance_in_meters.sum() itinerary['price'] = float(itinerary['price']) itinerary['price_leg'] = itinerary.apply( lambda x: x.distance_in_meters / x.total_distance * x.price, axis=1) i = _id lst_sections = list() # We add a waiting period at the pick up point of 15 minutes #print(itinerary.date_time.get_values()) #print(type(itinerary.date_time.get_value(0))) #print(type(timedelta(seconds=_BLABLACAR_WAITING_PERIOD))) #print(itinerary.date_time.get_value(0)-timedelta(seconds=_BLABLACAR_WAITING_PERIOD)) step = tmw.Journey_step( i, _type=constants.TYPE_WAIT, label= f'Arrive at pick up point {format_timespan(_BLABLACAR_WAITING_PERIOD)} before departure', distance_m=0, duration_s=_BLABLACAR_WAITING_PERIOD, price_EUR=[0], gCO2=0, departure_point=[ itinerary.latitude.iloc[0], itinerary.longitude.iloc[0] ], arrival_point=[ itinerary.latitude.iloc[0], itinerary.longitude.iloc[0] ], departure_date=itinerary.date_time.iat[0] - timedelta(seconds=_BLABLACAR_WAITING_PERIOD), arrival_date=itinerary.date_time.iat[0], bike_friendly=True, geojson=[], ) lst_sections.append(step) i = i + 1 # Go through all steps of the journey for index, leg in itinerary.iterrows(): local_distance_m = leg.distance_in_meters local_transportation_type = constants.TYPE_CAR local_emissions = co2_emissions.calculate_co2_emissions(local_transportation_type, constants.DEFAULT_CITY, constants.DEFAULT_FUEL, constants.DEFAULT_NB_SEATS, constants.DEFAULT_NB_KM) * \ constants.DEFAULT_NB_PASSENGERS * local_distance_m step = tmw.Journey_step( i, _type=constants.TYPE_CARPOOOLING, label=f'BlablaCar trip from {leg.city} to {leg.city_arrival}', distance_m=local_distance_m, duration_s=leg.duration_in_seconds, price_EUR=[leg.price_leg], gCO2=local_emissions, departure_point=[leg.latitude, leg.longitude], arrival_point=[leg.latitude_arrival, leg.longitude_arrival], departure_stop_name=leg.address + ' ' + leg.city, arrival_stop_name=leg.address_arrival + ' ' + leg.city_arrival, departure_date=leg.date_time, arrival_date=leg.date_time_arrival, trip_code='BlaBlaCar_' + str(leg.trip_id), bike_friendly=False, geojson=[], ) lst_sections.append(step) i = i + 1 # add transfer steps if not pd.isna(leg.next_departure): step = tmw.Journey_step( i, _type=constants.TYPE_TRANSFER, label=f'Transfer at {leg.name_arrival_seg}', distance_m=0, duration_s=(leg['next_departure'] - leg['arrival_date_seg']).seconds, price_EUR=[0], departure_point=[ leg.latitude_arrival, leg.longitude_arrival ], arrival_point=[ leg.latitude_arrival, leg.longitude_arrival ], departure_stop_name=leg.address_arrival + ' ' + leg.city_arrival, arrival_stop_name=leg.address_arrival + ' ' + leg.city_arrival, departure_date=leg.date_time_arrival, arrival_date=leg.next_departure, gCO2=0, bike_friendly=False, geojson=[], ) lst_sections.append(step) i = i + 1 journey_blablacar = tmw.Journey( _id, steps=lst_sections, departure_date=lst_sections[0].departure_date, arrival_date=lst_sections[-1].arrival_date, booking_link=leg.link) # Add category category_journey = list() for step in journey_blablacar.steps: if step.type not in [constants.TYPE_TRANSFER, constants.TYPE_WAIT]: category_journey.append(step.type) journey_blablacar.category = list(set(category_journey)) lst_journeys.append(journey_blablacar) # for journey in lst_journeys: # journey.update() return lst_journeys