diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 38a27f2726..fc5013464a 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -152,7 +152,7 @@ jobs: submodules: recursive token: ${{ steps.ci-core-app-token.outputs.token }} - name: Restore ccache - uses: hendrikmuhs/ccache-action@v1.2 + uses: hendrikmuhs/ccache-action@v1.2.11 with: key: ${{matrix.os.docker_image}}-ci max-size: 2000M diff --git a/source/jormungandr/jormungandr/street_network/geovelo.py b/source/jormungandr/jormungandr/street_network/geovelo.py index 59eb8646fd..b1a7bb0ddb 100644 --- a/source/jormungandr/jormungandr/street_network/geovelo.py +++ b/source/jormungandr/jormungandr/street_network/geovelo.py @@ -128,15 +128,15 @@ def _make_request_arguments_bike_details(cls, bike_speed_mps): 'averageSpeed': bike_speed, # in km/h, BEGINNER sets it to 13 } - def sort_by_mode(self, points): - def key_func(point): + def sort_places_by_physical_mode_and_distance(self, points): + def priority_by_mode(point): if len(point.stop_point.physical_modes) == 0: return float('inf') return min( (self.mode_weight.get(mode.uri, float('inf')) for mode in point.stop_point.physical_modes) ) - return sorted(points, key=key_func) + return sorted(points, key=lambda point: (priority_by_mode(point), point.distance)) @classmethod def _make_request_arguments_isochrone(cls, origins, destinations, bike_speed_mps=3.33): @@ -456,6 +456,6 @@ def get_truncated_places_isochrone(self, places_isochrone): def filter_places_isochrone(self, places_isochrone): result = (p for p in places_isochrone if self.is_reached_by_physical_mode(p)) - ordered_isochrone = self.sort_by_mode(result) + ordered_isochrone = self.sort_places_by_physical_mode_and_distance(result) return self.get_truncated_places_isochrone(ordered_isochrone) diff --git a/source/jormungandr/jormungandr/street_network/tests/geovelo_test.py b/source/jormungandr/jormungandr/street_network/tests/geovelo_test.py index 518a294375..51c083bf93 100644 --- a/source/jormungandr/jormungandr/street_network/tests/geovelo_test.py +++ b/source/jormungandr/jormungandr/street_network/tests/geovelo_test.py @@ -451,7 +451,7 @@ def sort_by_mode_test(): modes=["walking", "bike", "car"], timeout=56, ) - points = geovelo.sort_by_mode(points) + points = geovelo.sort_places_by_physical_mode_and_distance(points) assert points[0].uri == 'ref_Train' assert points[1].uri == 'ref_Rapid' assert points[2].uri == 'ref_Metro' @@ -619,6 +619,89 @@ def filter_places_isochrone_modes_multiple_modes_test(): assert mode in geovelo.mode_weight +def filter_places_isochrone_modes_distance_test(): + points = [ + make_pt_object_with_sp_mode( + lon=3, + lat=48.3, + uri='ref_bus_LocalTrain_d_14', + mode_uris=['physical_mode:Bus', 'physical_mode:LocalTrain'], + distance=14, + ), + make_pt_object_with_sp_mode( + lon=3, + lat=48.3, + uri='ref_bus_LocalTrain_d_12', + mode_uris=['physical_mode:Bus', 'physical_mode:LocalTrain'], + distance=12, + ), + make_pt_object_with_sp_mode( + lon=3, + lat=48.3, + uri='ref_bus_LocalTrain_d_15', + mode_uris=['physical_mode:Bus', 'physical_mode:LocalTrain'], + distance=15, + ), + make_pt_object_with_sp_mode( + lon=4, lat=48.4, uri='ref_Train_d_5', mode_uris=['physical_mode:Train'], distance=5 + ), + make_pt_object_with_sp_mode( + lon=4, lat=48.4, uri='ref_Train_d_17', mode_uris=['physical_mode:Train'], distance=17 + ), + make_pt_object_with_sp_mode( + lon=4, lat=48.4, uri='ref_Train_d_7', mode_uris=['physical_mode:Train'], distance=7 + ), + make_pt_object_with_sp_mode( + lon=6, + lat=48.6, + uri='ref_car_rapid_d_15', + mode_uris=['physical_mode:Car', 'physical_mode:RapidTransit'], + distance=15, + ), + make_pt_object_with_sp_mode( + lon=6, + lat=48.6, + uri='ref_car_rapid_d_3', + mode_uris=['physical_mode:Car', 'physical_mode:RapidTransit'], + distance=3, + ), + make_pt_object_with_sp_mode( + lon=6, + lat=48.6, + uri='ref_car_rapid_d_16', + mode_uris=['physical_mode:Car', 'physical_mode:RapidTransit'], + distance=16, + ), + ] + geovelo = Geovelo( + instance=None, + service_url=MOCKED_SERVICE_URL, + id=u"tata-é$~#@\"*!'`§èû", + modes=["walking", "bike", "car"], + timeout=56, + mode_weight={"physical_mode:Train": 2, "physical_mode:RapidTransit": 2, "physical_mode:LocalTrain": 1}, + ) + points = geovelo.filter_places_isochrone(points) + result = [ + "ref_bus_LocalTrain_d_12", + "ref_bus_LocalTrain_d_14", + "ref_bus_LocalTrain_d_15", + "ref_car_rapid_d_3", + "ref_Train_d_5", + "ref_Train_d_7", + "ref_car_rapid_d_15", + "ref_car_rapid_d_16", + "ref_Train_d_17", + ] + assert len(points) == len(result) + for index, uri in enumerate(result): + assert points[index].uri == uri + # Default mode_weight + assert len(list(geovelo.mode_weight.keys())) == 3 + for mode in ['physical_mode:Train', 'physical_mode:RapidTransit', 'physical_mode:LocalTrain']: + assert mode in geovelo.mode_weight + + def is_reached_by_physical_mode_test(): place = make_pt_object_with_sp_mode(lon=3, lat=48.3, uri='ref_Bus', mode_uris=['physical_mode:Bus']) geovelo = Geovelo( diff --git a/source/jormungandr/jormungandr/street_network/tests/streetnetwork_test_utils.py b/source/jormungandr/jormungandr/street_network/tests/streetnetwork_test_utils.py index 9d22b38da3..ffe815ac20 100644 --- a/source/jormungandr/jormungandr/street_network/tests/streetnetwork_test_utils.py +++ b/source/jormungandr/jormungandr/street_network/tests/streetnetwork_test_utils.py @@ -58,8 +58,9 @@ def make_pt_object(embedded_type, lon, lat, uri=None): return pt_object -def make_pt_object_with_sp_mode(lon, lat, uri, mode_uris=None): +def make_pt_object_with_sp_mode(lon, lat, uri, mode_uris=None, distance=0): pt_object = type_pb2.PtObject() + pt_object.distance = distance pt_object.embedded_type = type_pb2.STOP_POINT if uri: pt_object.uri = uri