Skip to content

Commit

Permalink
Allow setting avoidIndoor route modifier for bus stops with walking…
Browse files Browse the repository at this point in the history
… directions.
  • Loading branch information
ondrasej committed Jan 17, 2024
1 parent 7c4b20c commit 0848622
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 0 deletions.
10 changes: 10 additions & 0 deletions python/cfr/json/cfr_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,15 @@ class BreakRule(TypedDict):
breakRequests: list[BreakRequest]


class RouteModifiers(TypedDict, total=False):
"""Represents the route modifiers in the JSON CFR request."""

avoidTolls: bool
avoidHighways: bool
avoidFerries: bool
avoidIndoor: bool


class Vehicle(TypedDict, total=False):
"""Represents a vehicle in the JSON CFR request."""

Expand All @@ -147,6 +156,7 @@ class Vehicle(TypedDict, total=False):

travelMode: int
travelDurationMultiple: float
routeModifiers: RouteModifiers

routeDurationLimit: DurationLimit

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
}
},
"travelDurationMultiple": 1.1,
"routeModifiers": {"avoidIndoor": true},
"travelMode": 2
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@
}
},
"travelDurationMultiple": 1.1,
"routeModifiers": {"avoidIndoor": true},
"travelMode": 2
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@
}
},
"travelDurationMultiple": 1.1,
"routeModifiers": {"avoidIndoor": true},
"travelMode": 2
},
{
Expand Down
3 changes: 3 additions & 0 deletions python/cfr/testdata/small/expected_local_request.json
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@
},
"travelDurationMultiple": 1.1,
"travelMode": 2,
"routeModifiers": {"avoidIndoor": true},
"fixedCost": 10000,
"costPerHour": 300,
"costPerKilometer": 60,
Expand Down Expand Up @@ -249,6 +250,7 @@
},
"travelDurationMultiple": 1.1,
"travelMode": 2,
"routeModifiers": {"avoidIndoor": true},
"fixedCost": 10000,
"costPerHour": 300,
"costPerKilometer": 60,
Expand Down Expand Up @@ -287,6 +289,7 @@
},
"travelDurationMultiple": 1.1,
"travelMode": 2,
"routeModifiers": {"avoidIndoor": true},
"fixedCost": 10000,
"costPerHour": 300,
"costPerKilometer": 60,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@
},
"travelDurationMultiple": 1.1,
"travelMode": 2,
"routeModifiers": {"avoidIndoor": true},
"startTags": ["P001"],
"endTags": ["P001"]
},
Expand All @@ -200,6 +201,7 @@
}
},
"travelDurationMultiple": 1.1,
"routeModifiers": {"avoidIndoor": true},
"travelMode": 2,
"startTags": ["P001"],
"endTags": ["P001"]
Expand All @@ -222,6 +224,7 @@
}
},
"travelDurationMultiple": 1.1,
"routeModifiers": {"avoidIndoor": true},
"travelMode": 2,
"startTags": ["P001"],
"endTags": ["P001"]
Expand All @@ -244,6 +247,7 @@
}
},
"travelDurationMultiple": 1.1,
"routeModifiers": {"avoidIndoor": true},
"travelMode": 2,
"startTags": ["P001"],
"endTags": ["P001"]
Expand Down
1 change: 1 addition & 0 deletions python/cfr/testdata/small/parking.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"tag": "P001",
"travel_mode": 2,
"travel_duration_multiple": 1.1,
"avoid_indoor": true,
"delivery_load_limits": { "ore": 2 },
"max_round_duration": "1800s"
},
Expand Down
11 changes: 11 additions & 0 deletions python/cfr/two_step_routing/two_step_routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ class ParkingLocation:
optimized routes from the parking lot to the final delivery locations.
Overrides `Vehicle.travel_duration_multiple` for vehicles used in the
local route optimization plan.
avoid_indoor: The value of the `routeModifiers.avoidIndoor` option used in
local delivery routes from this parking location. When `None`, the option
will not be set. This option can be set to True only for when walking
directions are used, i.e. when `travel_mode` == 2.
delivery_load_limits: The load limits applied when delivering shipments from
the parking location. This is equivalent to Vehicle.loadLimits, and it
restricts the number of shipments that can be delivered without returning
Expand Down Expand Up @@ -185,6 +189,8 @@ class ParkingLocation:
travel_mode: int = 1
travel_duration_multiple: float = 1.0

avoid_indoor: bool | None = None

delivery_load_limits: Mapping[str, int] | None = None

max_round_duration: cfr_json.DurationString | None = None
Expand All @@ -210,6 +216,9 @@ def __post_init__(self, coordinates: cfr_json.LatLng | None):
self, "waypoint", {"location": {"latLng": coordinates}}
)

if self.avoid_indoor and self.travel_mode != 2:
raise ValueError("`avoid_indoor` can be True only when travel_mode == 2.")

@functools.cached_property
def waypoint_for_local_model(self) -> cfr_json.Waypoint:
"""Returns a waypoint for the parking to be used in local models.
Expand Down Expand Up @@ -1295,6 +1304,8 @@ def _make_local_model_vehicle(
"startTags": [parking.tag],
"endTags": [parking.tag],
}
if parking.avoid_indoor is not None:
vehicle["routeModifiers"] = {"avoidIndoor": parking.avoid_indoor}
if parking.max_round_duration is not None:
vehicle["routeDurationLimit"] = {
"maxDuration": parking.max_round_duration,
Expand Down
21 changes: 21 additions & 0 deletions python/cfr/two_step_routing/two_step_routing_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,27 @@ def test_initialize_from_nothing(self):
tag="P003",
)

def test_avoid_indoor_valid_travel_mode(self):
for travel_mode, avoid_indoor in ((2, True), (2, False), (1, False)):
with self.subTest(travel_mode=travel_mode, avoid_indoor=avoid_indoor):
parking = two_step_routing.ParkingLocation(
tag="P002",
coordinates={"latitude": 48.877, "longitude": 2.3299},
travel_mode=travel_mode,
avoid_indoor=avoid_indoor,
)
self.assertEqual(parking.travel_mode, travel_mode)
self.assertEqual(parking.avoid_indoor, avoid_indoor)

def test_avoid_indoor_invalid_travel_mode(self):
with self.assertRaisesRegex(ValueError, "travel_mode"):
two_step_routing.ParkingLocation(
tag="P002",
coordinates={"latitude": 48.877, "longitude": 2.3299},
travel_mode=1,
avoid_indoor=True,
)


class LoadParkingFromJsonTest(unittest.TestCase):
"""Tests for load_parking_from_json."""
Expand Down

0 comments on commit 0848622

Please sign in to comment.