def decorate_journeys(response, instance, request): # TODO: disable same journey schedule link for ridesharing journey? for journey in response.journeys: if 'ridesharing' not in journey.tags or to_be_deleted(journey): continue for i, section in enumerate(journey.sections): if section.street_network.mode == response_pb2.Ridesharing: section.additional_informations.append( response_pb2.HAS_DATETIME_ESTIMATED) period_extremity = None if len(journey.sections ) == 1: # direct path, we use the user input period_extremity = PeriodExtremity(request['datetime'], request['clockwise']) elif i == 0: # ridesharing on first section we want to arrive before the start of the pt period_extremity = PeriodExtremity(section.end_date_time, False) else: # ridesharing at the end, we search for solution starting after the end of the pt sections period_extremity = PeriodExtremity(section.begin_date_time, True) pb_rsjs, pb_tickets, pb_fps = build_ridesharing_journeys( section.origin, section.destination, period_extremity, instance) if not pb_rsjs: journey_filter.mark_as_dead( journey, 'no_matching_ridesharing_found') else: section.ridesharing_journeys.extend(pb_rsjs) response.tickets.extend(pb_tickets) response.feed_publishers.extend( (fp for fp in pb_fps if fp not in response.feed_publishers))
def decorate_journeys_with_ridesharing_offers(self, response, request, instance): greenlet_pool_actived = instance.greenlet_pool_for_ridesharing_services if greenlet_pool_actived: logging.info('ridesharing is called in async mode') else: logging.info('ridesharing is called in sequential mode') with FutureManager( instance.ridesharing_greenlet_pool_size) as future_manager: futures = {} for journey_idx, journey in enumerate(response.journeys): if 'ridesharing' not in journey.tags or to_be_deleted(journey): continue futures[journey_idx] = {} for section_idx, section in enumerate(journey.sections): if section.street_network.mode == response_pb2.Ridesharing: section.additional_informations.append( response_pb2.HAS_DATETIME_ESTIMATED) period_extremity = None if len(journey.sections ) == 1: # direct path, we use the user input period_extremity = PeriodExtremity( request['datetime'], request['clockwise']) elif ( section_idx == 0 ): # ridesharing on first section we want to arrive before the start of the pt period_extremity = PeriodExtremity( section.end_date_time, False) else: # ridesharing at the end, we search for solution starting after the end of the pt sections period_extremity = PeriodExtremity( section.begin_date_time, True) instance_params = self.InstanceParams.make_params( instance) if greenlet_pool_actived: futures[journey_idx][ section_idx] = future_manager.create_future( self.build_ridesharing_journeys, section.origin, section.destination, period_extremity, instance_params, ) else: pb_rsjs, pb_tickets, pb_fps = self.build_ridesharing_journeys( section.origin, section.destination, period_extremity, instance_params) self.add_new_ridesharing_results( pb_rsjs, pb_tickets, pb_fps, response, journey_idx, section_idx) if greenlet_pool_actived: for journey_idx in futures: for section_idx in futures[journey_idx]: pb_rsjs, pb_tickets, pb_fps = futures[journey_idx][ section_idx].wait_and_get() self.add_new_ridesharing_results( pb_rsjs, pb_tickets, pb_fps, response, journey_idx, section_idx)
def compute_fallback( from_obj, to_obj, pt_journey_pool, streetnetwork_path_pool, orig_places_free_access, dest_places_free_access, request, ): """ Launching fallback computation asynchronously once the pt_journey is finished """ logger = logging.getLogger(__name__) has_valid_direct_paths = streetnetwork_path_pool.has_valid_direct_paths() for (dep_mode, arr_mode, pt_journey_f) in pt_journey_pool: logger.debug("waiting for pt journey starts with %s and ends with %s", dep_mode, arr_mode) pt_journeys = pt_journey_f.wait_and_get() _clean_pt_journey_error_or_raise(pt_journeys, has_valid_direct_paths) if not getattr(pt_journeys, "journeys", None): continue places_free_access = orig_places_free_access.wait_and_get() orig_all_free_access = ( places_free_access.odt | places_free_access.crowfly | places_free_access.free_radius ) places_free_access = dest_places_free_access.wait_and_get() dest_all_free_access = ( places_free_access.odt | places_free_access.crowfly | places_free_access.free_radius ) for journey in pt_journeys.journeys: # from pt_orig = journey.sections[0].origin direct_path_type = StreetNetworkPathType.BEGINNING_FALLBACK fallback_extremity_dep = PeriodExtremity(journey.departure_date_time, False) if from_obj.uri != pt_orig.uri and pt_orig.uri not in orig_all_free_access: streetnetwork_path_pool.add_async_request( from_obj, pt_orig, dep_mode, fallback_extremity_dep, request, direct_path_type ) # to pt_dest = journey.sections[-1].destination direct_path_type = StreetNetworkPathType.ENDING_FALLBACK fallback_extremity_arr = PeriodExtremity(journey.arrival_date_time, True) if to_obj.uri != pt_dest.uri and pt_dest.uri not in dest_all_free_access: streetnetwork_path_pool.add_async_request( pt_dest, to_obj, arr_mode, fallback_extremity_arr, request, direct_path_type )
def compute_fallback( from_obj, to_obj, streetnetwork_path_pool, orig_places_free_access, dest_places_free_access, request, pt_journeys, ): """ Launching fallback computation asynchronously once the pt_journey is finished """ logger = logging.getLogger(__name__) places_free_access = orig_places_free_access.wait_and_get() orig_all_free_access = places_free_access.odt | places_free_access.crowfly | places_free_access.free_radius places_free_access = dest_places_free_access.wait_and_get() dest_all_free_access = places_free_access.odt | places_free_access.crowfly | places_free_access.free_radius for (dep_mode, arr_mode, journey) in pt_journeys: logger.debug( "completing pt journey that starts with %s and ends with %s", dep_mode, arr_mode) # from direct_path_type = StreetNetworkPathType.BEGINNING_FALLBACK fallback = _get_fallback_logic(direct_path_type) pt_orig = fallback.get_pt_boundaries(journey) pt_departure = fallback.get_pt_section_datetime(journey) fallback_extremity_dep = PeriodExtremity(pt_departure, False) if from_obj.uri != pt_orig.uri and pt_orig.uri not in orig_all_free_access: streetnetwork_path_pool.add_async_request(from_obj, pt_orig, dep_mode, fallback_extremity_dep, request, direct_path_type) # to direct_path_type = StreetNetworkPathType.ENDING_FALLBACK fallback = _get_fallback_logic(direct_path_type) pt_dest = fallback.get_pt_boundaries(journey) pt_arrival = fallback.get_pt_section_datetime(journey) fallback_extremity_arr = PeriodExtremity(pt_arrival, True) if to_obj.uri != pt_dest.uri and pt_dest.uri not in dest_all_free_access: streetnetwork_path_pool.add_async_request(pt_dest, to_obj, arr_mode, fallback_extremity_arr, request, direct_path_type)
def direct_path_geovelo_zero_test(): instance = MagicMock() geovelo = Geovelo(instance=instance, service_url='http://bob.com') resp_json = direct_path_response_zero() origin = make_pt_object(type_pb2.ADDRESS, lon=2, lat=48, uri='refStart1') destination = make_pt_object(type_pb2.ADDRESS, lon=2, lat=48, uri='refEnd1') fallback_extremity = PeriodExtremity(str_to_time_stamp('20161010T152000'), False) with requests_mock.Mocker() as req: req.post( 'http://bob.com/api/v2/computedroutes?instructions=true&elevations=true&geometry=true' '&single_result=true&bike_stations=false&objects_as_ids=true&', json=resp_json, ) geovelo_resp = geovelo.direct_path_with_fp( instance, 'bike', origin, destination, fallback_extremity, MOCKED_REQUEST, None, None ) assert geovelo_resp.status_code == 200 assert geovelo_resp.response_type == response_pb2.ITINERARY_FOUND assert len(geovelo_resp.journeys) == 1 assert geovelo_resp.journeys[0].duration == 0 assert len(geovelo_resp.journeys[0].sections) == 1 assert geovelo_resp.journeys[0].arrival_date_time == str_to_time_stamp('20161010T152000') assert geovelo_resp.journeys[0].departure_date_time == str_to_time_stamp('20161010T152000') assert geovelo_resp.journeys[0].sections[0].type == response_pb2.STREET_NETWORK assert geovelo_resp.journeys[0].sections[0].type == response_pb2.STREET_NETWORK assert geovelo_resp.journeys[0].sections[0].duration == 0 assert geovelo_resp.journeys[0].sections[0].length == 0 assert geovelo_resp.journeys[0].sections[0].origin == origin assert geovelo_resp.journeys[0].sections[0].destination == destination assert geovelo_resp.journeys[0].sections[0].street_network.path_items[0].name == "voie pietonne" assert geovelo_resp.journeys[0].sections[0].street_network.path_items[0].direction == 0 assert geovelo_resp.journeys[0].sections[0].street_network.path_items[0].length == 0 assert geovelo_resp.journeys[0].sections[0].street_network.path_items[0].duration == 0
def _build_to(self, journey, journey_destination, crowfly_stop_points, odt_stop_points, arr_mode, fallback_direct_path_pool, destinations_fallback): pt_destination = journey.sections[-1].destination last_section_end = journey.sections[-1].end_date_time if journey_destination.uri != pt_destination.uri: if pt_destination.uri in odt_stop_points: journey.sections[-1].destination.CopyFrom(journey_destination) elif pt_destination.uri in crowfly_stop_points or destinations_fallback.is_crowfly_needed(arr_mode, pt_destination.uri): crowfly_arrival_dt = journey.arrival_date_time + \ destinations_fallback.get_duration(arr_mode, pt_destination.uri) journey.sections.extend([create_crowfly(journey, pt_destination, journey_destination, last_section_end, crowfly_arrival_dt)]) else: fallback_extremity = PeriodExtremity(journey.arrival_date_time, True) # extend the journey with the fallback routing path o = pt_destination d = journey_destination is_fallback_at_end = False if arr_mode == 'car': o, d, is_fallback_at_end = d, o, True self._extend_journey(journey, arr_mode, o, d, fallback_extremity, fallback_direct_path_pool, is_fallback_at_end) journey.sections.sort(SectionSorter()) journey.arrival_date_time = journey.sections[-1].end_date_time return journey
def extend_journey_for_build_to_test(): # create a journey with 4 sections having PUBLIC_TRANSPORT at the begining and at the end pt_journey = create_journeys_with_pt() fallback_extremity = PeriodExtremity(pt_journey.arrival_date_time, True) # create a response having on single section CROW_FLY journey cf_origin = make_pt_object(type_pb2.STOP_POINT, 4.0, 4.0, "stop_point_4_bis") cf_destination = make_pt_object(type_pb2.ADDRESS, 5.0, 5.0, "address_1") response = create_response_with_crow_fly(start_date="20180618T075000", end_date="20180618T075500", origin=cf_origin, destination=cf_destination) _extend_journey(pt_journey, response, fallback_extremity) pt_journey.sections.sort(SectionSorter()) assert len(pt_journey.sections) == 5 # We should have CROW_FLY section at the end of last section PUBLIC_TRANSPORT crowfly_section = pt_journey.sections[-1] pt_section = pt_journey.sections[-2] assert crowfly_section.type == response_pb2.CROW_FLY assert pt_section.type == response_pb2.PUBLIC_TRANSPORT # We should have the same object used for the last pt_section.destination and crowfly_section.origin assert crowfly_section.origin == pt_section.destination assert crowfly_section.origin.uri == "stop_point_4"
def direct_path_func_with_valid_response_valhalla_test(): instance = MagicMock() instance.walking_speed = 1.12 valhalla = Valhalla(instance=instance, service_url='http://bob.com', costing_options={'bib': 'bom'}) resp_json = response_valid() origin = make_pt_object(type_pb2.ADDRESS, 2.439938, 48.572841) destination = make_pt_object(type_pb2.ADDRESS, 2.440548, 48.57307) fallback_extremity = PeriodExtremity(str_to_time_stamp('20161010T152000'), True) with requests_mock.Mocker() as req: req.post('http://bob.com/route', json=resp_json) valhalla_response = valhalla.direct_path_with_fp( instance, 'walking', origin, destination, fallback_extremity, MOCKED_REQUEST, None) assert valhalla_response.status_code == 200 assert valhalla_response.response_type == response_pb2.ITINERARY_FOUND assert len(valhalla_response.journeys) == 1 assert valhalla_response.journeys[0].duration == 6 assert len(valhalla_response.journeys[0].sections) == 1 assert valhalla_response.journeys[0].sections[ 0].type == response_pb2.STREET_NETWORK assert valhalla_response.journeys[0].sections[ 0].type == response_pb2.STREET_NETWORK assert valhalla_response.journeys[0].sections[0].length == 52 assert valhalla_response.journeys[0].sections[ 0].destination == destination
def here_basic_routing_test(valid_here_routing_response): origin = make_pt_object(type_pb2.POI, 2.439938, 48.572841) destination = make_pt_object(type_pb2.STOP_AREA, 2.440548, 48.57307) fallback_extremity = PeriodExtremity(str_to_time_stamp('20161010T152000'), True) response = Here._read_response( response=valid_here_routing_response, mode='walking', origin=origin, destination=destination, fallback_extremity=fallback_extremity, request={'datetime': str_to_time_stamp('20170621T174600')}, ) assert response.status_code == 200 assert response.response_type == response_pb2.ITINERARY_FOUND assert len(response.journeys) == 1 assert response.journeys[0].duration == 588 assert len(response.journeys[0].sections) == 1 section = response.journeys[0].sections[0] assert section.type == response_pb2.STREET_NETWORK assert section.length == 4012 assert section.duration == 588 assert section.destination == destination assert section.origin == origin assert section.begin_date_time == str_to_time_stamp('20161010T152000') assert section.end_date_time == section.begin_date_time + section.duration
def get_pt_journey_futures(self, origin, destination, fallback_direct_path_pool, origins_fallback, destinations_fallback, journey_parameters): futures_jourenys = [] is_fallback_at_end = False instance = self.instance fallback_extremity = PeriodExtremity(self.request['datetime'], self.request['clockwise']) for dep_mode, arr_mode in self.krakens_call: dp_key = make_direct_path_key(dep_mode, origin.uri, destination.uri, is_fallback_at_end, fallback_extremity) dp = fallback_direct_path_pool.get(dp_key) journey_parameters = copy.deepcopy(journey_parameters) if dp.journeys: journey_parameters.direct_path_duration = dp.journeys[0].durations.total else: journey_parameters.direct_path_duration = None origins = origins_fallback.get_locations_contexts(dep_mode) destinations = destinations_fallback.get_locations_contexts(arr_mode) # default argument to workaround late binding # http://stackoverflow.com/questions/3431676/creating-functions-in-a-loop def worker_journey(dep_mode=dep_mode, arr_mode=arr_mode, journey_parameters=journey_parameters, origins=origins, destinations=destinations): if not origins or not destinations or not self.request.get('max_duration', 0): return dep_mode, arr_mode, None bike_in_pt = (dep_mode == 'bike' and arr_mode == 'bike') return dep_mode, arr_mode, instance.planner.journeys(origins, destinations, fallback_extremity.datetime, fallback_extremity.represents_start, journey_parameters, bike_in_pt) futures_jourenys.append(self.pool.spawn(worker_journey)) return futures_jourenys
def get_response_with_leave_parking_test(): resp_json = response_valid() origin = make_pt_object(type_pb2.ADDRESS, 2.439938, 48.572841) destination = make_pt_object(type_pb2.ADDRESS, 2.440548, 48.57307) fallback_extremity = PeriodExtremity(str_to_time_stamp('20161010T152000'), True) response = Valhalla._get_response( resp_json, 'walking', origin, destination, fallback_extremity, StreetNetworkPathType.ENDING_FALLBACK, mode_park_cost=5 * 60, ) assert response.status_code == 200 assert response.response_type == response_pb2.ITINERARY_FOUND assert len(response.journeys) == 1 assert response.journeys[0].duration == 6 + 5 * 60 assert len(response.journeys[0].sections) == 2 assert response.journeys[0].sections[0].type == response_pb2.LEAVE_PARKING assert response.journeys[0].sections[0].length == 0 assert response.journeys[0].sections[0].duration == 5 * 60 assert response.journeys[0].sections[0].origin == origin assert response.journeys[0].sections[0].destination == origin assert response.journeys[0].sections[1].type == response_pb2.STREET_NETWORK assert response.journeys[0].sections[1].length == 52 assert response.journeys[0].sections[1].duration == 6 assert response.journeys[0].sections[1].destination == destination
def get_response_with_0_duration_park_test(): """even if the mode_park_cost is 0, if it's not None we got a park section""" resp_json = response_valid() origin = make_pt_object(type_pb2.ADDRESS, 2.439938, 48.572841) destination = make_pt_object(type_pb2.ADDRESS, 2.440548, 48.57307) fallback_extremity = PeriodExtremity(str_to_time_stamp('20161010T152000'), True) response = Valhalla._get_response( resp_json, 'walking', origin, destination, fallback_extremity, StreetNetworkPathType.BEGINNING_FALLBACK, mode_park_cost=0, ) assert response.status_code == 200 assert response.response_type == response_pb2.ITINERARY_FOUND assert len(response.journeys) == 1 assert response.journeys[0].duration == 6 assert len(response.journeys[0].sections) == 2 assert response.journeys[0].sections[0].type == response_pb2.STREET_NETWORK assert response.journeys[0].sections[0].length == 52 assert response.journeys[0].sections[0].duration == 6 assert response.journeys[0].sections[0].destination == destination assert response.journeys[0].sections[1].type == response_pb2.PARK assert response.journeys[0].sections[1].length == 0 assert response.journeys[0].sections[ 1].duration == 0 # very quick park section assert response.journeys[0].sections[1].origin == destination assert response.journeys[0].sections[1].destination == destination
def extend_journey_for_build_from_test(): # create a journey with 4 sections having PUBLIC_TRANSPORT at the begining and at the end pt_journey = create_journeys_with_pt() fallback_extremity = PeriodExtremity(pt_journey.departure_date_time, False) # create a response having on single section CROW_FLY journey cf_origin = make_pt_object(type_pb2.ADDRESS, 1.0, 1.0, "address_1") cf_destination = make_pt_object(type_pb2.STOP_POINT, 2.0, 2.0, "stop_point_1_bis") response = create_response_with_crow_fly(start_date="20180618T060000", end_date="20180618T060500", origin=cf_origin, destination=cf_destination) _extend_journey(pt_journey, response, fallback_extremity) pt_journey.sections.sort(SectionSorter()) assert len(pt_journey.sections) == 5 # We should have CROW_FLY section at the begining of the journey following by a section PUBLIC_TRANSPORT crowfly_section = pt_journey.sections[0] pt_section = pt_journey.sections[1] assert crowfly_section.type == response_pb2.CROW_FLY assert pt_section.type == response_pb2.PUBLIC_TRANSPORT # We should have the same object used for crowfly_section.destination and pt_section.origin assert crowfly_section.destination == pt_section.origin assert crowfly_section.destination.uri == "stop_point_1"
def _build_to( requested_dest_obj, pt_journeys, arr_mode, streetnetwork_path_pool, dest_accessible_by_crowfly, dest_fallback_durations_pool, request, ): accessibles_by_crowfly = dest_accessible_by_crowfly.wait_and_get() fallback_durations = dest_fallback_durations_pool.wait_and_get(arr_mode) for pt_journey in pt_journeys.journeys: pt_destination = pt_journey.sections[-1].destination last_section_end = pt_journey.sections[-1].end_date_time if requested_dest_obj.uri != pt_destination.uri: fallback_period_extremity = PeriodExtremity(pt_journey.arrival_date_time, True) # extend the journey with the fallback routing path direct_path_type = StreetNetworkPathType.ENDING_FALLBACK fallback_dp = streetnetwork_path_pool.wait_and_get( pt_destination, requested_dest_obj, arr_mode, fallback_period_extremity, direct_path_type, request=request, ) if pt_destination.uri in accessibles_by_crowfly.odt: pt_journey.sections[-1].destination.CopyFrom(requested_dest_obj) elif _is_crowfly_needed( pt_destination.uri, fallback_durations, accessibles_by_crowfly.crowfly, fallback_dp ): crowfly_arrival_dt = ( pt_journey.arrival_date_time + fallback_durations[pt_destination.uri].duration ) pt_journey.sections.extend( [ _create_crowfly( pt_journey, pt_destination, requested_dest_obj, last_section_end, crowfly_arrival_dt, arr_mode, ) ] ) else: _extend_journey(pt_journey, fallback_dp, fallback_period_extremity) pt_journey.sections.sort(SectionSorter()) pt_journey.arrival_date_time = pt_journey.sections[-1].end_date_time return pt_journeys
def _build_from( requested_orig_obj, pt_journeys, dep_mode, streetnetwork_path_pool, orig_accessible_by_crowfly, orig_fallback_durations_pool, request, ): accessibles_by_crowfly = orig_accessible_by_crowfly.wait_and_get() fallback_durations = orig_fallback_durations_pool.wait_and_get(dep_mode) for pt_journey in pt_journeys.journeys: pt_origin = pt_journey.sections[0].origin fallback_period_extremity = PeriodExtremity(pt_journey.departure_date_time, False) # extend the journey with the fallback routing path direct_path_type = StreetNetworkPathType.BEGINNING_FALLBACK fallback_dp = streetnetwork_path_pool.wait_and_get( requested_orig_obj, pt_origin, dep_mode, fallback_period_extremity, direct_path_type, request=request ) if requested_orig_obj.uri != pt_origin.uri: if pt_origin.uri in accessibles_by_crowfly.odt: pt_journey.sections[0].origin.CopyFrom(requested_orig_obj) elif _is_crowfly_needed( pt_origin.uri, fallback_durations, accessibles_by_crowfly.crowfly, fallback_dp ): crowfly_departure_dt = ( pt_journey.departure_date_time - fallback_durations[pt_origin.uri].duration ) pt_journey.sections.extend( [ _create_crowfly( pt_journey, requested_orig_obj, pt_origin, crowfly_departure_dt, pt_journey.sections[0].begin_date_time, dep_mode, ) ] ) else: # extend the journey with the fallback routing path _extend_journey(pt_journey, fallback_dp, fallback_period_extremity) pt_journey.sections.sort(SectionSorter()) pt_journey.departure_date_time = pt_journey.sections[0].begin_date_time return pt_journeys
def get_fallback_direct_path_futures(self, map_response, crowfly_stop_points, odt_stop_points): futures = [] for dep_mode, arr_mode, journey in map_response: # from departure = journey.sections[0].origin is_fallback_at_end = False fallback_extremity_dep = PeriodExtremity(journey.departure_date_time, False) # In the following cases, we don't need to compute the fallback direct path: # 1. the origin of the first section and the requested_origin are the same # 2. the origin of the first section belongs to a stop_area # 3. the origin of the first section belongs to odt stop_points if g.requested_origin.uri != departure.uri and \ departure.uri not in odt_stop_points and departure.uri not in crowfly_stop_points: futures.extend(self.get_direct_path_futures(g.fallback_direct_path_pool, g.requested_origin, departure, fallback_extremity_dep, is_fallback_at_end, [dep_mode])) # to arrival = journey.sections[-1].destination is_fallback_at_end = False # In some cases, we don't need to compute the fallback direct path # Similar reasoning as above fallback_extremity_arr = PeriodExtremity(journey.arrival_date_time, True) if g.requested_destination.uri != arrival.uri and arrival.uri not in odt_stop_points \ and arrival.uri not in crowfly_stop_points: o, d = arrival, g.requested_destination if arr_mode == 'car': o, d, is_fallback_at_end = d, o, True futures.extend(self.get_direct_path_futures(g.fallback_direct_path_pool, o, d, fallback_extremity_arr, is_fallback_at_end, [arr_mode])) return futures
def direct_path_geovelo_test(): instance = MagicMock() geovelo = Geovelo(instance=instance, service_url='http://bob.com') resp_json = direct_path_response_valid() origin = make_pt_object(type_pb2.ADDRESS, lon=2, lat=48.2, uri='refStart1') destination = make_pt_object(type_pb2.ADDRESS, lon=3, lat=48.3, uri='refEnd1') fallback_extremity = PeriodExtremity(str_to_time_stamp('20161010T152000'), False) with requests_mock.Mocker() as req: req.post( 'http://bob.com/api/v2/computedroutes?instructions=true&elevations=false&geometry=true' '&single_result=true&bike_stations=false&objects_as_ids=true&', json=resp_json) geovelo_resp = geovelo.direct_path_with_fp('bike', origin, destination, fallback_extremity, None, None) assert geovelo_resp.status_code == 200 assert geovelo_resp.response_type == response_pb2.ITINERARY_FOUND assert len(geovelo_resp.journeys) == 1 assert geovelo_resp.journeys[0].duration == 3155 # 52min35s assert len(geovelo_resp.journeys[0].sections) == 1 assert geovelo_resp.journeys[0].arrival_date_time == str_to_time_stamp( '20161010T152000') assert geovelo_resp.journeys[ 0].departure_date_time == str_to_time_stamp('20161010T142725') assert geovelo_resp.journeys[0].sections[ 0].type == response_pb2.STREET_NETWORK assert geovelo_resp.journeys[0].sections[ 0].type == response_pb2.STREET_NETWORK assert geovelo_resp.journeys[0].sections[0].duration == 3155 assert geovelo_resp.journeys[0].sections[0].length == 11393 assert geovelo_resp.journeys[0].sections[0].street_network.coordinates[ 2].lon == 2.314258 assert geovelo_resp.journeys[0].sections[0].street_network.coordinates[ 2].lat == 48.887428 assert geovelo_resp.journeys[0].sections[0].origin == origin assert geovelo_resp.journeys[0].sections[0].destination == destination assert geovelo_resp.journeys[0].sections[0].street_network.path_items[ 1].name == "Rue Jouffroy d'Abbans" assert geovelo_resp.journeys[0].sections[0].street_network.path_items[ 1].direction == 0 assert geovelo_resp.journeys[0].sections[0].street_network.path_items[ 1].length == 40 assert geovelo_resp.journeys[0].sections[0].street_network.path_items[ 1].duration == 144
def test_update_fallback_sections_ending_fallback(): journey = create_journey_with_pt_and_crowfly() origin = make_pt_object(type_pb2.ADDRESS, 9.0, 9.0, "Not Home") destination = make_pt_object(type_pb2.ADDRESS, 12.0, 12.0, "Home") fallback_dp = create_car_journey_with_leave_parking("20180618T080500", origin, destination) fallback_period_extremity = PeriodExtremity(str_to_time_stamp('20180618T080500'), True) fallback_type = StreetNetworkPathType.ENDING_FALLBACK access_point = make_pt_object(type_pb2.ACCESS_POINT, 9.0, 9.0, "access_point_toto") _update_fallback_sections(journey, fallback_dp, fallback_period_extremity, fallback_type, access_point) assert len(journey.sections) == 6 assert journey.sections[4].origin.uri == "stop_point_4" assert journey.sections[4].origin == journey.sections[3].destination assert journey.sections[4].vias[0].uri == "access_point_toto"
def direct_path_func_with_no_response_valhalla_test(): instance = MagicMock() instance.walking_speed = 1.12 valhalla = Valhalla(instance=instance, service_url='http://bob.com', costing_options={'bib': 'bom'}) origin = make_pt_object(type_pb2.ADDRESS, 2.439938, 48.572841) destination = make_pt_object(type_pb2.ADDRESS, 2.440548, 48.57307) fallback_extremity = PeriodExtremity(str_to_time_stamp('20161010T152000'), True) with requests_mock.Mocker() as req: req.post('http://bob.com/route', json={'error_code': 442}, status_code=400) valhalla_response = valhalla.direct_path_with_fp( instance, 'walking', origin, destination, fallback_extremity, MOCKED_REQUEST, None, None ) assert valhalla_response.status_code == 200 assert valhalla_response.response_type == response_pb2.NO_SOLUTION assert len(valhalla_response.journeys) == 0
def distances_durations_test(): """ Check that the response from geovelo is correctly formatted with 'distances' and 'durations' sections """ instance = MagicMock() geovelo = Geovelo(instance=instance, service_url='http://bob.com') resp_json = direct_path_response_valid() origin = make_pt_object(type_pb2.ADDRESS, lon=2, lat=48.2, uri='refStart1') destination = make_pt_object(type_pb2.ADDRESS, lon=3, lat=48.3, uri='refEnd1') fallback_extremity = PeriodExtremity(str_to_time_stamp('20161010T152000'), True) proto_resp = geovelo._get_response(resp_json, origin, destination, fallback_extremity) assert proto_resp.journeys[0].durations.total == 3155 assert proto_resp.journeys[0].durations.bike == 3155 assert proto_resp.journeys[0].distances.bike == 11393.0
def test_update_fallback_sections_beginning_fallback(): journey = create_journey_with_crowfly_and_pt() origin = make_pt_object(type_pb2.ADDRESS, 9.0, 9.0, "Home") destination = make_pt_object(type_pb2.ADDRESS, 12.0, 12.0, "Not Home") fallback_dp = create_car_journey_with_parking("20180618T050500", origin, destination) fallback_period_extremity = PeriodExtremity(str_to_time_stamp('20180618T050500'), False) fallback_type = StreetNetworkPathType.BEGINNING_FALLBACK access_point = make_pt_object(type_pb2.ACCESS_POINT, 9.0, 9.0, "access_point_toto") _update_fallback_sections(journey, fallback_dp, fallback_period_extremity, fallback_type, access_point) # Car + Park + 4 PT assert len(journey.sections) == 6 assert journey.sections[1].destination.uri == "stop_point_1" assert journey.sections[1].destination == journey.sections[2].origin assert journey.sections[1].vias[0].uri == "access_point_toto"
def get_response_func_with_unknown_exception_test(): resp_json = response_valid() origin = make_pt_object(type_pb2.ADDRESS, 2.439938, 48.572841) destination = make_pt_object(type_pb2.ADDRESS, 2.440548, 48.57307) fallback_extremity = PeriodExtremity(str_to_time_stamp('20161010T152000'), True) response = Valhalla._get_response(resp_json, 'walking', origin, destination, fallback_extremity) assert response.status_code == 200 assert response.response_type == response_pb2.ITINERARY_FOUND assert len(response.journeys) == 1 assert response.journeys[0].duration == 6 assert len(response.journeys[0].sections) == 1 assert response.journeys[0].sections[0].type == response_pb2.STREET_NETWORK assert response.journeys[0].sections[0].type == response_pb2.STREET_NETWORK assert response.journeys[0].sections[0].length == 52 assert response.journeys[0].sections[0].destination == destination
def direct_path_func_with_status_code_400_response_valhalla_test(): instance = MagicMock() instance.walking_speed = 1.12 valhalla = Valhalla(instance=instance, service_url='http://bob.com', costing_options={'bib': 'bom'}) origin = make_pt_object(type_pb2.ADDRESS, 2.439938, 48.572841) destination = make_pt_object(type_pb2.ADDRESS, 2.440548, 48.57307) fallback_extremity = PeriodExtremity(str_to_time_stamp('20161010T152000'), True) with requests_mock.Mocker() as req: with pytest.raises(TechnicalError) as excinfo: req.post('http://bob.com/route', json={'error_code': 42}, status_code=400) valhalla.direct_path_with_fp( instance, 'walking', origin, destination, fallback_extremity, MOCKED_REQUEST, None, None ) assert '500 Internal Server Error' in str(excinfo.value) assert ( str(excinfo.value.data['message']) == 'Valhalla service unavailable, impossible to query : http://bob.com/route' ) assert str(excinfo.typename) == 'TechnicalError'
def compute_transfer(pt_journey, transfer_path_pool, request, request_id): """ Launching transfer computation asynchronously once the pt_journey is finished """ logger = logging.getLogger(__name__) logger.debug("computing walking transfer in pt journey") direct_path_type = StreetNetworkPathType.DIRECT real_mode = 'walking' transfer_sections = [] for (_, _, journey) in pt_journey: for s in filter_transfer_path(journey.sections): pt_arrival = s.end_date_time fallback_extremity = PeriodExtremity(pt_arrival, False) sub_request_id = "{}_{}_{}".format(request_id, s.origin.uri, s.destination.uri) transfer_path_pool.add_async_request( s.origin, s.destination, real_mode, fallback_extremity, request, direct_path_type, sub_request_id ) transfer_sections.append(s) return transfer_sections
def complete_transfer(pt_journey, transfer_path_pool, request, transfer_sections): """ We complete the pt_journey by adding to transfer section : - path - We do not modify duration !! """ logger = logging.getLogger(__name__) logger.debug("completing walking transfer in pt journey") direct_path_type = StreetNetworkPathType.DIRECT real_mode = 'walking' for s in transfer_sections: fallback_extremity = PeriodExtremity(s.end_date_time, True) transfer_journeys = transfer_path_pool.wait_and_get( s.origin, s.destination, real_mode, fallback_extremity, direct_path_type, request ) if transfer_journeys and transfer_journeys.journeys: new_section = transfer_journeys.journeys[0].sections s.street_network.CopyFrom(new_section[0].street_network)
def _build_from(self, journey, journey_origin, crowfly_stop_points, odt_stop_points, dep_mode, fallback_direct_path_pool, origins_fallback): pt_origin = journey.sections[0].origin if journey_origin.uri != pt_origin.uri: if pt_origin.uri in odt_stop_points: journey.sections[0].origin.CopyFrom(journey_origin) elif pt_origin.uri in crowfly_stop_points or origins_fallback.is_crowfly_needed(dep_mode, pt_origin.uri): crowfly_departure_dt = journey.departure_date_time - \ origins_fallback.get_duration(dep_mode, pt_origin.uri) journey.sections.extend([create_crowfly(journey, journey_origin, pt_origin, crowfly_departure_dt, journey.sections[0].begin_date_time)]) else: # extend the journey with the fallback routing path fallback_extremity = PeriodExtremity(journey.departure_date_time, False) is_fallback_at_end = False self._extend_journey(journey, dep_mode, journey_origin, pt_origin, fallback_extremity, fallback_direct_path_pool, is_fallback_at_end) journey.sections.sort(SectionSorter()) journey.departure_date_time = journey.sections[0].begin_date_time return journey
def _get_sn_routing_matrix_with_multi_direct_path(self, origins, destinations, mode, max_duration, request, realtime_traffic, max_matrix_points): sn_routing_matrix = response_pb2.StreetNetworkRoutingMatrix() row = sn_routing_matrix.rows.add() for origin in itertools.islice(origins, int(max_matrix_points)): for destination in itertools.islice(destinations, int(max_matrix_points)): params = self.get_direct_path_params( origin, destination, mode, PeriodExtremity(datetime=request['datetime'], represents_start=request['clockwise']), request, realtime_traffic, ) r = self._call_here(self.routing_service_url, params=params) r.raise_for_status() self._create_matrix_response_with_direct_path(r.json(), row) return sn_routing_matrix
def _compute_all(self, future_manager, request, instance, krakens_call, context): """ For all krakens_call, call the kraken and aggregate the responses Note: the responses will only attach a crowfly section as a fallback. Street network will be done when calling finalise_journeys return the list of all responses """ logger = logging.getLogger(__name__) logger.debug('request datetime: %s', request['datetime']) requested_dep_modes = {mode for mode, _, _ in krakens_call} requested_arr_modes = {mode for _, mode, _ in krakens_call} if context.partial_response_is_empty: logger.debug('requesting places by uri orig: %s dest %s', request['origin'], request['destination']) context.requested_orig = PlaceByUri(future_manager=future_manager, instance=instance, uri=request['origin']) context.requested_dest = PlaceByUri(future_manager=future_manager, instance=instance, uri=request['destination']) context.requested_orig_obj = get_entry_point_or_raise( context.requested_orig, request['origin']) context.requested_dest_obj = get_entry_point_or_raise( context.requested_dest, request['destination']) context.streetnetwork_path_pool = StreetNetworkPathPool( future_manager=future_manager, instance=instance) period_extremity = PeriodExtremity(request['datetime'], request['clockwise']) for mode in requested_dep_modes: context.streetnetwork_path_pool.add_async_request( requested_orig_obj=context.requested_orig_obj, requested_dest_obj=context.requested_dest_obj, mode=mode, period_extremity=period_extremity, request=request, streetnetwork_path_type=StreetNetworkPathType.DIRECT, ) # if max_duration(time to pass in pt) is zero, there is no need to continue, # we return all direct path without pt if request['max_duration'] == 0: return [ context.streetnetwork_path_pool.wait_and_get( requested_orig_obj=context.requested_orig_obj, requested_dest_obj=context.requested_dest_obj, mode=mode, request=request, period_extremity=period_extremity, streetnetwork_path_type=StreetNetworkPathType.DIRECT, ) for mode in requested_dep_modes ] # We'd like to get the duration of a direct path to do some optimizations in ProximitiesByCrowflyPool and # FallbackDurationsPool. # Note :direct_paths_by_mode is a dict of mode vs future of a direct paths, this line is not blocking context.direct_paths_by_mode = context.streetnetwork_path_pool.get_all_direct_paths( ) context.orig_proximities_by_crowfly = ProximitiesByCrowflyPool( future_manager=future_manager, instance=instance, requested_place_obj=context.requested_orig_obj, modes=requested_dep_modes, request=request, direct_paths_by_mode=context.direct_paths_by_mode, max_nb_crowfly_by_mode=request['max_nb_crowfly_by_mode'], ) context.dest_proximities_by_crowfly = ProximitiesByCrowflyPool( future_manager=future_manager, instance=instance, requested_place_obj=context.requested_dest_obj, modes=requested_arr_modes, request=request, direct_paths_by_mode=context.direct_paths_by_mode, max_nb_crowfly_by_mode=request['max_nb_crowfly_by_mode'], ) context.orig_places_free_access = PlacesFreeAccess( future_manager=future_manager, instance=instance, requested_place_obj=context.requested_orig_obj) context.dest_places_free_access = PlacesFreeAccess( future_manager=future_manager, instance=instance, requested_place_obj=context.requested_dest_obj) context.orig_fallback_durations_pool = FallbackDurationsPool( future_manager=future_manager, instance=instance, requested_place_obj=context.requested_orig_obj, modes=requested_dep_modes, proximities_by_crowfly_pool=context. orig_proximities_by_crowfly, places_free_access=context.orig_places_free_access, direct_paths_by_mode=context.direct_paths_by_mode, request=request, direct_path_type=StreetNetworkPathType.BEGINNING_FALLBACK, ) context.dest_fallback_durations_pool = FallbackDurationsPool( future_manager=future_manager, instance=instance, requested_place_obj=context.requested_dest_obj, modes=requested_arr_modes, proximities_by_crowfly_pool=context. dest_proximities_by_crowfly, places_free_access=context.dest_places_free_access, direct_paths_by_mode=context.direct_paths_by_mode, request=request, direct_path_type=StreetNetworkPathType.ENDING_FALLBACK, ) pt_journey_pool = PtJourneyPool( future_manager=future_manager, instance=instance, requested_orig_obj=context.requested_orig_obj, requested_dest_obj=context.requested_dest_obj, streetnetwork_path_pool=context.streetnetwork_path_pool, krakens_call=krakens_call, orig_fallback_durations_pool=context.orig_fallback_durations_pool, dest_fallback_durations_pool=context.dest_fallback_durations_pool, request=request, ) pt_journey_elements = wait_and_build_crowflies( requested_orig_obj=context.requested_orig_obj, requested_dest_obj=context.requested_dest_obj, pt_journey_pool=pt_journey_pool, has_valid_direct_paths=context.streetnetwork_path_pool. has_valid_direct_paths(), orig_places_free_access=context.orig_places_free_access, dest_places_free_acces=context.dest_places_free_access, orig_fallback_durations_pool=context.orig_fallback_durations_pool, dest_fallback_durations_pool=context.dest_fallback_durations_pool, ) context.journeys_to_modes.update( self._map_journeys_to_modes(pt_journey_elements)) # At the stage, all types of journeys have been computed thus we build the final result here res = [] if context.partial_response_is_empty: for mode in requested_dep_modes: dp = context.direct_paths_by_mode.get(mode).wait_and_get() if getattr(dp, "journeys", None): res.append(dp) # pt_journeys may contain None and res must be a list of protobuf journey res.extend( (j.pt_journeys for j in pt_journey_elements if j.pt_journeys)) check_final_results_or_raise(res, context.orig_fallback_durations_pool, context.dest_fallback_durations_pool) for r in res: fill_uris(r) context.partial_response_is_empty = False return res
def _compute_all(future_manager, request, instance, krakens_call): """ For all krakens_call, call the kraken and aggregate the responses return the list of all responses """ logger = logging.getLogger(__name__) logger.debug('request datetime: %s', request['datetime']) requested_dep_modes = {mode for mode, _ in krakens_call} requested_arr_modes = {mode for _, mode in krakens_call} logger.debug('requesting places by uri orig: %s dest %s', request['origin'], request['destination']) requested_orig = PlaceByUri(future_manager=future_manager, instance=instance, uri=request['origin']) requested_dest = PlaceByUri(future_manager=future_manager, instance=instance, uri=request['destination']) requested_orig_obj = get_entry_point_or_raise(requested_orig, request['origin']) requested_dest_obj = get_entry_point_or_raise(requested_dest, request['destination']) streetnetwork_path_pool = StreetNetworkPathPool( future_manager=future_manager, instance=instance) period_extremity = PeriodExtremity(request['datetime'], request['clockwise']) # we launch direct path asynchronously for mode in requested_dep_modes: streetnetwork_path_pool.add_async_request( requested_orig_obj=requested_orig_obj, requested_dest_obj=requested_dest_obj, mode=mode, period_extremity=period_extremity, request=request, streetnetwork_path_type=StreetNetworkPathType.DIRECT) # if max_duration(time to pass in pt) is zero, there is no need to continue, # we return all direct path without pt if request['max_duration'] == 0: return [ streetnetwork_path_pool.wait_and_get( requested_orig_obj=requested_orig_obj, requested_dest_obj=requested_dest_obj, mode=mode, request=request, period_extremity=period_extremity, streetnetwork_path_type=StreetNetworkPathType.DIRECT) for mode in requested_dep_modes ] # We'd like to get the duration of a direct path to do some optimizations in ProximitiesByCrowflyPool and # FallbackDurationsPool. # Note :direct_paths_by_mode is a dict of mode vs future of a direct paths, this line is not blocking direct_paths_by_mode = streetnetwork_path_pool.get_all_direct_paths() orig_proximities_by_crowfly = ProximitiesByCrowflyPool( future_manager=future_manager, instance=instance, requested_place_obj=requested_orig_obj, modes=requested_dep_modes, request=request, direct_paths_by_mode=direct_paths_by_mode) dest_proximities_by_crowfly = ProximitiesByCrowflyPool( future_manager=future_manager, instance=instance, requested_place_obj=requested_dest_obj, modes=requested_arr_modes, request=request, direct_paths_by_mode=direct_paths_by_mode) orig_places_free_access = PlacesFreeAccess( future_manager=future_manager, instance=instance, requested_place_obj=requested_orig_obj) dest_places_free_access = PlacesFreeAccess( future_manager=future_manager, instance=instance, requested_place_obj=requested_dest_obj) orig_fallback_durations_pool = FallbackDurationsPool( future_manager=future_manager, instance=instance, requested_place_obj=requested_orig_obj, modes=requested_dep_modes, proximities_by_crowfly_pool=orig_proximities_by_crowfly, places_free_access=orig_places_free_access, direct_paths_by_mode=direct_paths_by_mode, request=request, direct_path_type=StreetNetworkPathType.BEGINNING_FALLBACK) dest_fallback_durations_pool = FallbackDurationsPool( future_manager=future_manager, instance=instance, requested_place_obj=requested_dest_obj, modes=requested_arr_modes, proximities_by_crowfly_pool=dest_proximities_by_crowfly, places_free_access=dest_places_free_access, direct_paths_by_mode=direct_paths_by_mode, request=request, direct_path_type=StreetNetworkPathType.ENDING_FALLBACK) pt_journey_pool = PtJourneyPool( future_manager=future_manager, instance=instance, requested_orig_obj=requested_orig_obj, requested_dest_obj=requested_dest_obj, streetnetwork_path_pool=streetnetwork_path_pool, krakens_call=krakens_call, orig_fallback_durations_pool=orig_fallback_durations_pool, dest_fallback_durations_pool=dest_fallback_durations_pool, request=request) completed_pt_journeys = wait_and_complete_pt_journey( future_manager=future_manager, requested_orig_obj=requested_orig_obj, requested_dest_obj=requested_dest_obj, pt_journey_pool=pt_journey_pool, streetnetwork_path_pool=streetnetwork_path_pool, orig_places_free_access=orig_places_free_access, dest_places_free_access=dest_places_free_access, orig_fallback_durations_pool=orig_fallback_durations_pool, dest_fallback_durations_pool=dest_fallback_durations_pool, request=request) # At the stage, all types of journeys have been computed thus we build the final result here res = [] for mode in requested_dep_modes: dp = direct_paths_by_mode.get(mode).wait_and_get() if getattr(dp, "journeys", None): res.append(dp) # completed_pt_journeys may contain None and res must be a list of protobuf journey res.extend((j for j in completed_pt_journeys if j)) check_final_results_or_raise(res, orig_fallback_durations_pool, dest_fallback_durations_pool) for r in res: fill_uris(r) return res
def _build_fallback( requested_obj, pt_journey, mode, streetnetwork_path_pool, obj_accessible_by_crowfly, fallback_durations_pool, request, fallback_type, ): accessibles_by_crowfly = obj_accessible_by_crowfly.wait_and_get() fallback_durations = fallback_durations_pool.wait_and_get(mode) fallback_logic = _get_fallback_logic(fallback_type) pt_obj = fallback_logic.get_pt_boundaries(pt_journey) if requested_obj.uri != pt_obj.uri: if pt_obj.uri in accessibles_by_crowfly.odt: pt_obj.CopyFrom(requested_obj) else: # extend the journey with the fallback routing path is_after_pt_sections = fallback_logic.is_after_pt_sections() pt_datetime = fallback_logic.get_pt_section_datetime(pt_journey) fallback_period_extremity = PeriodExtremity( pt_datetime, is_after_pt_sections) orig, dest = fallback_logic.route_params(requested_obj, pt_obj) fallback_dp = streetnetwork_path_pool.wait_and_get( orig, dest, mode, fallback_period_extremity, fallback_type, request=request) if not _is_crowfly_needed(pt_obj.uri, fallback_durations, accessibles_by_crowfly.crowfly, fallback_dp): _update_fallback_sections(pt_journey, fallback_dp, fallback_period_extremity, fallback_type) # update distances and durations by mode if it's a proper computed streetnetwork fallback if fallback_dp and fallback_dp.journeys: for m in all_fallback_modes - {FallbackModes.bss.name}: fb_distance = getattr( fallback_dp.journeys[0].distances, m) main_distance = getattr(pt_journey.distances, m) setattr(pt_journey.distances, m, fb_distance + main_distance) fb_duration = getattr( fallback_dp.journeys[0].durations, m) main_duration = getattr(pt_journey.durations, m) setattr(pt_journey.durations, m, fb_duration + main_duration) # if it's only a non-teleport crowfly fallback, update distances and durations by mode else: if fallback_type == StreetNetworkPathType.BEGINNING_FALLBACK: crowfly_section = pt_journey.sections[0] else: crowfly_section = pt_journey.sections[-1] if crowfly_section.duration: if hasattr(pt_journey.distances, mode): setattr( pt_journey.distances, mode, (getattr(pt_journey.distances, mode) + crowfly_section.length), ) if hasattr(pt_journey.durations, mode): setattr( pt_journey.durations, mode, (getattr(pt_journey.durations, mode) + crowfly_section.duration), ) fallback_logic.set_journey_bound_datetime(pt_journey) return pt_journey