diff --git a/source/jormungandr/jormungandr/scenarios/helper_classes/helper_utils.py b/source/jormungandr/jormungandr/scenarios/helper_classes/helper_utils.py index c7960183de..5d23b88291 100644 --- a/source/jormungandr/jormungandr/scenarios/helper_classes/helper_utils.py +++ b/source/jormungandr/jormungandr/scenarios/helper_classes/helper_utils.py @@ -205,16 +205,21 @@ def _make_bike_park(begin_date_time, duration): return bike_park_section -def _make_bike_park_street_network(origin, begin_date_time, destination, end_date_time, duration): +def _make_bike_park_street_network(origin, begin_date_time, destination, end_date_time, duration, length): bike_park_to_sp_section = response_pb2.Section() bike_park_to_sp_section.id = "Street_network_section_2" bike_park_to_sp_section.origin.CopyFrom(origin) bike_park_to_sp_section.destination.CopyFrom(destination) bike_park_to_sp_section.type = response_pb2.STREET_NETWORK bike_park_to_sp_section.street_network.mode = response_pb2.Walking + bike_park_to_sp_section.street_network.street_information.extend( + [response_pb2.StreetInformation(geojson_offset=0, cycle_path_type=0, length=length)] + ) + bike_park_to_sp_section.street_network.duration = duration bike_park_to_sp_section.begin_date_time = begin_date_time bike_park_to_sp_section.end_date_time = end_date_time + duration bike_park_to_sp_section.duration = duration + bike_park_to_sp_section.street_network.length = length return bike_park_to_sp_section @@ -423,13 +428,12 @@ def _update_journey(journey, park_section, street_mode_section, to_replace, new_ journey.arrival_date_time += park_section.duration + street_mode_section.duration journey.sections.remove(to_replace) journey.sections.extend([street_mode_section, park_section]) - journey.sections.extend(new_fallbacks) journey.nb_sections += 2 -def walking_time(cord1, cord2, walking_speed): +def _get_walking_information(cord1, cord2, walking_speed): """ - Calculate the walking time between two coordinates. + Calculate the walking time and the distance between two coordinates. Args: cord1 (tuple): The (latitude, longitude) of the starting point. @@ -438,9 +442,10 @@ def walking_time(cord1, cord2, walking_speed): Returns: float: The walking time in secondes. + float: The distance in meters. """ distance = crowfly_distance_between(cord1, cord2) - return get_manhattan_duration(distance, walking_speed) + return get_manhattan_duration(distance, walking_speed), round(distance) def _get_place(kwargs, uri): @@ -503,7 +508,7 @@ def _update_fallback_with_bike_mode( # We have to create the link between the fallback and the pt part manually here if fallback_type == StreetNetworkPathType.BEGINNING_FALLBACK and "bike" in kwargs["origin_mode"]: address = _get_place(kwargs, fallback_sections[-1].destination.uri) - walktime = walking_time( + walktime, walking_distance = _get_walking_information( address.address.coord, journey.sections[0].destination.stop_point.coord, kwargs["instance"].walking_speed, @@ -513,12 +518,14 @@ def _update_fallback_with_bike_mode( s.begin_date_time += kwargs["additional_time"] + walktime s.end_date_time += kwargs["additional_time"] + walktime park_section = _make_bike_park(fallback_sections[-1].end_date_time, kwargs["additional_time"]) + journey.durations.walking += walktime street_mode_section = _make_bike_park_street_network( fallback_sections[-1].destination, park_section.end_date_time, journey.sections[0].destination, (fallback_sections[-1].end_date_time + park_section.duration) - journey.sections[0].end_date_time, walktime, + walking_distance, ) street_mode_section.street_network.coordinates.extend( [journey.sections[0].destination.stop_point.coord, fallback_sections[-1].destination.address.coord] @@ -528,13 +535,13 @@ def _update_fallback_with_bike_mode( section_to_replace = journey.sections[0] journey.sections.remove(section_to_replace) fallback_sections[-1].destination.CopyFrom(journey.sections[0].origin) - journey.sections.extend(fallback_sections) elif fallback_type == StreetNetworkPathType.ENDING_FALLBACK and "bike" in kwargs["destination_mode"]: - walktime = walking_time( - journey.sections[-1].origin.stop_point.coord, + walktime, walking_distance = _get_walking_information( + journey.sectiowalking_distancens[-1].origin.stop_point.coord, fallback_sections[0].origin.address.coord, kwargs["instance"].walking_speed, ) + journey.durations.walking += walktime address = _get_place(kwargs, fallback_sections[0].origin.uri) fallback_sections[0].origin.CopyFrom(address) street_mode_section = _make_bike_park_street_network( @@ -544,6 +551,7 @@ def _update_fallback_with_bike_mode( (fallback_sections[0].begin_date_time + kwargs["additional_time"]) - journey.sections[-1].begin_date_time, walktime, + walking_distance, ) park_section = _make_bike_park(street_mode_section.begin_date_time, kwargs["additional_time"]) fallback_sections[0].begin_date_time += kwargs["additional_time"] @@ -555,21 +563,20 @@ def _update_fallback_with_bike_mode( section_to_replace = journey.sections[-1] journey.sections.remove(section_to_replace) fallback_sections[0].origin.CopyFrom(journey.sections[-1].destination) - journey.sections.extend(fallback_sections) add_poi_access_point_in_sections(fallback_type, via_poi_access, fallback_sections) if isinstance(via_pt_access, type_pb2.PtObject) and via_pt_access.embedded_type == type_pb2.ACCESS_POINT: if fallback_type == StreetNetworkPathType.BEGINNING_FALLBACK: - journey.sections[-1].vias.add().CopyFrom(via_pt_access.access_point) + fallback_sections[-1].vias.add().CopyFrom(via_pt_access.access_point) target_section = next((s for s in journey.sections if s.id == "Street_network_section_2"), None) if target_section: - target_section.vias.extend(journey.sections[-1].vias) - target_section.street_network.path_items.extend( - [journey.sections[-1].street_network.path_items[-1]] - ) + target_section.vias.extend(fallback_sections[-1].vias) + target_section.street_network.path_items.extend(fallback_sections[-1].street_network.path_items) + else: - journey.sections[0].vias.add().CopyFrom(via_pt_access.access_point) + fallback_sections[0].vias.add().CopyFrom(via_pt_access.access_point) + journey.sections.extend(fallback_sections) journey.sections.sort(key=cmp_to_key(SectionSorter())) @@ -821,9 +828,7 @@ def _build_fallback( fallback_dp_copy, fallback_type, requested_obj, via_poi_access, language ) - if request["park_mode"] == [ParkMode.on_street.name] and ( - request["origin_mode"] == ["bike"] or request["destination_mode"] == ["bike"] - ): + if request["park_mode"] == [ParkMode.on_street.name]: _update_fallback_with_bike_mode( pt_journey, fallback_dp_copy, diff --git a/source/jormungandr/tests/routing_tests_experimental.py b/source/jormungandr/tests/routing_tests_experimental.py index 182cbceaa5..02f8355e9f 100644 --- a/source/jormungandr/tests/routing_tests_experimental.py +++ b/source/jormungandr/tests/routing_tests_experimental.py @@ -1563,3 +1563,101 @@ def test_bike_with_parking_penalty_first_section_and_access_points(self): assert journey['sections'][2]['type'] == 'street_network' assert journey['sections'][2]['mode'] == 'walking' assert len(journey['sections'][2]['vias']) >= 1 + + def test_bike_with_parking_penalty_multiple_first_section_mode(self): + query = ( + sub_query + + "&datetime=20120614T075000" + + "&from=2.36893;48.88413" + + "&to=2.28928;48.84710" + + "&first_section_mode[]=bike" + + "&bike_speed=0.1" + + "&park_mode[]=on_street" + + "&_access_points=true" + + "&first_section_mode[]=walking" + ) + + response = self.query_region(query) + check_best(response) + + journeys = get_not_null(response, 'journeys') + assert len(journeys) > 0 + for journey in journeys: + if len(journey['sections']) > 1: + assert journey['sections'][0]['mode'] in ['bike', 'walking'] + assert journey['sections'][1]['type'] == 'park' + assert journey['sections'][2]['type'] == 'street_network' + assert journey['sections'][2]['mode'] == 'walking' + assert len(journey['sections'][2]['vias']) >= 1 + + def test_bike_with_parking_penalty_multiple_first_section_mode_and_access_points(self): + query = ( + sub_query + + "&datetime=20120614T075000" + + "&from=2.36893;48.88413" + + "&to=2.28928;48.84710" + + "&first_section_mode[]=bike" + + "&bike_speed=0.1" + + "&park_mode[]=on_street" + + "&_access_points=true" + + "&first_section_mode[]=walking" + ) + + response = self.query_region(query) + check_best(response) + + journeys = get_not_null(response, 'journeys') + assert len(journeys) > 0 + for journey in journeys: + if len(journey['sections']) > 1: + assert journey['sections'][0]['mode'] in ['bike', 'walking'] + assert journey['sections'][1]['type'] == 'park' + assert journey['sections'][2]['type'] == 'street_network' + assert journey['sections'][2]['mode'] == 'walking' + assert len(journey['sections'][2]['vias']) >= 1 + + def test_bike_with_parking_penalty_multiple_first_section_mode_park_mode_none(self): + query = ( + sub_query + + "&datetime=20120614T075000" + + "&from=2.36893;48.88413" + + "&to=2.28928;48.84710" + + "&first_section_mode[]=bike" + + "&bike_speed=0.1" + + "&park_mode[]=none" + + "&_access_points=true" + + "&first_section_mode[]=walking" + ) + + response = self.query_region(query) + check_best(response) + + journeys = get_not_null(response, 'journeys') + assert len(journeys) > 0 + for journey in journeys: + if len(journey['sections']) > 1: + assert journey['sections'][0]['mode'] in ['bike', 'walking'] + assert journey['sections'][1]['type'] != 'park' + + def test_bike_with_parking_penalty_multiple_first_section_mode_park_mode_park_and_ride(self): + query = ( + sub_query + + "&datetime=20120614T075000" + + "&from=2.36893;48.88413" + + "&to=2.28928;48.84710" + + "&first_section_mode[]=bike" + + "&bike_speed=0.1" + + "&park_mode[]=park_and_ride" + + "&_access_points=true" + + "&first_section_mode[]=walking" + ) + + response = self.query_region(query) + check_best(response) + + journeys = get_not_null(response, 'journeys') + assert len(journeys) > 0 + for journey in journeys: + if len(journey['sections']) > 1: + assert journey['sections'][0]['mode'] in ['bike', 'walking'] + assert journey['sections'][1]['type'] != 'park'