Skip to content

Commit a9071e3

Browse files
ADMUKHEazarzadrika.mukherjeejohannes-nojanusz-anue
authored
Hard avoids highway ferry (valhalla#4524)
Co-authored-by: amaury.zarzelli <[email protected]> Co-authored-by: adrika.mukherjee <[email protected]> Co-authored-by: Johannes Nonnenmacher <[email protected]> Co-authored-by: Janusz <[email protected]>
1 parent 329c4e6 commit a9071e3

29 files changed

+571
-38
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@
226226
* ADDED: "has_transit_tiles" & "osm_changeset" to verbose status response [#4062](https://github.com/valhalla/valhalla/pull/4062)
227227
* ADDED: time awareness to CostMatrix for e.g. traffic support [#4071](https://github.com/valhalla/valhalla/pull/4071)
228228
* UPDATED: transifex translations [#4102](https://github.com/valhalla/valhalla/pull/4102)
229+
* ADDED: costing parameters to exclude certain edges `exclude_tolls`, `exclude_bridges`, `exclude_tunnels`, `exclude_highways`, `exclude_ferries`. They need to be enabled in the config with `service_limits.allow_hard_exclusions`. Also added location search filters `exclude_ferry` and `exclude_toll` to complement these changes. [#4524](https://github.com/valhalla/valhalla/pull/4524)
229230

230231
## Release Date: 2023-01-03 Valhalla 3.3.0
231232
* **Removed**

docs/docs/api/turn-by-turn/api-reference.md

+15-4
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ To build a route, you need to specify two `break` locations. In addition, you ca
4646
| `street_side_tolerance` | If your input coordinate is less than this tolerance away from the edge centerline then we set your side of street to none otherwise your side of street will be left or right depending on direction of travel. The default is 5 meters. |
4747
| `street_side_max_distance` | The max distance in meters that the input coordinates or display ll can be from the edge centerline for them to be used for determining the side of street. Beyond this distance the side of street is set to none. The default is 1000 meters. |
4848
| `street_side_cutoff` | Disables the `preferred_side` when set to `same` or `opposite` if the edge has a road class less than that provided by `street_side_cutoff`. The road class must be one of the following strings: motorway, trunk, primary, secondary, tertiary, unclassified, residential, service_other. The default value is `service_other` so that `preferred_side` will not be disabled for any edges. |
49-
| `search_filter` | A set of optional filters to exclude candidate edges based on their attribution. The following exclusion filters are supported: <ul><li>`exclude_tunnel` (boolean, defaults to `false`): whether to exclude roads marked as tunnels</li><li>`exclude_bridge` (boolean, defaults to `false`): whether to exclude roads marked as bridges</li><li>`exclude_ramp` (boolean, defaults to `false`): whether to exclude link roads marked as ramps, note that some turn channels are also marked as ramps</li><li>`exclude_closures` (boolean, defaults to `true`): whether to exclude roads considered closed due to live traffic closure. **Note:** This option cannot be set if `costing_options.<costing>.ignore_closures` is also specified. An error is returned if both options are specified. **Note 2:** Ignoring closures at destination and source locations does NOT work for date_time type `0/1` & `2` respectively</li><li>`min_road_class` (string, defaults to `"service_other"`): lowest road class allowed</li><li>`max_road_class` (string, defaults to `"motorway"`): highest road class allowed</li><li>**BETA** `level` (float): if specified, will only consider edges that are on or traverse the passed floor level. It will set `search_cutoff` to a default value of 300 meters if no cutoff value is passed. Additionally, if a `search_cutoff` is passed, it will be clamped to 1000 meters.</li></ul>Road classes from highest to lowest are: motorway, trunk, primary, secondary, tertiary, unclassified, residential, service_other. |
49+
| `search_filter` | A set of optional filters to exclude candidate edges based on their attribution. The following exclusion filters are supported: <ul><li>`exclude_tunnel` (boolean, defaults to `false`): whether to exclude roads marked as tunnels</li><li>`exclude_bridge` (boolean, defaults to `false`): whether to exclude roads marked as bridges</li><li>`exclude_toll` (boolean, defaults to `false`): whether to exclude toll</li><li>`exclude_ferry` (boolean, defaults to `false`): whether to exclude ferry</li><li>`exclude_ramp` (boolean, defaults to `false`): whether to exclude link roads marked as ramps, note that some turn channels are also marked as ramps</li><li>`exclude_closures` (boolean, defaults to `true`): whether to exclude roads considered closed due to live traffic closure. <br>**Note:** This option cannot be set if `costing_options.<costing>.ignore_closures` is also specified. An error is returned if both options are specified. <br>**Note 2:** Ignoring closures at destination and source locations does NOT work for date_time type `0/1` & `2` respectively</li><li>`min_road_class` (string, defaults to `"service_other"`): lowest road class allowed</li><li>`max_road_class` (string, defaults to `"motorway"`): highest road class allowed</li><li>**BETA** `level` (float): if specified, will only consider edges that are on or traverse the passed floor level. It will set `search_cutoff` to a default value of 300 meters if no cutoff value is passed. Additionally, if a `search_cutoff` is passed, it will be clamped to 1000 meters.</li></ul>Road classes from highest to lowest are: motorway, trunk, primary, secondary, tertiary, unclassified, residential, service_other. |
5050
| `preferred_layer` | The layer on which edges should be considered. If provided, edges whose layer does not match the provided value will be discarded from the candidate search. |
5151

5252
Optionally, you can include the following location information without impacting the routing. This information is carried through the request and returned as a convenience.
@@ -90,7 +90,7 @@ Costing methods can have several options that can be adjusted to develop the rou
9090
* Penalty options are fixed costs in seconds that are only added to the path cost. Penalties can influence the route path determination but do not add to the estimated time along the path. For example, add a `toll_booth_penalty` to create route paths that tend to avoid toll booths. Penalties must be in the range of 0.0 seconds to 43200.0 seconds (12 hours), otherwise a default value will be assigned.
9191
* Factor options are used to multiply the cost along an edge or road section in a way that influences the path to favor or avoid a particular attribute. Factor options do not impact estimated time along the path, though. Factors must be in the range 0.1 to 100000.0, where factors of 1.0 have no influence on cost. Anything outside of this range will be assigned a default value. Use a factor less than 1.0 to attempt to favor paths containing preferred attributes, and a value greater than 1.0 to avoid paths with undesirable attributes. Avoidance factors are more effective than favor factors at influencing a path. A factor's impact also depends on the length of road containing the specified attribute, as longer roads have more impact on the costing than very short roads. For this reason, penalty options tend to be better at influencing paths.
9292

93-
A special costing option is `shortest`, which, when `true`, will solely use distance as cost and disregard all other costs, penalties and factors. It's available for all costing models except `multimodal` & `bikeshare`.
93+
A special costing option is `shortest`, which, when `true`, will solely use distance as cost and disregard all other costs, penalties and factors. It's available for all costing models except `multimodal` & `bikeshare`.
9494

9595
Another special case is `disable_hierarchy_pruning` costing option. As the name indicates, `disable_hierarchy_pruning = true` will disable hierarchies in routing algorithms, which allows us to find the actual optimal route even in edge cases. For example, together with `shortest = true` they can find the actual shortest route. When `disable_hierarchy_pruning` is `true` and arc distances between source and target are not above the max limit, the actual optimal route will be calculated at the expense of performance. Note that if arc distances between locations exceed the max limit, `disable_hierarchy_pruning` is `true` will not be applied. This costing option is available for all motorized costing models, i.e `auto`, `motorcycle`, `motor_scooter`, `bus`, `truck` & `taxi`. For `bicycle` and `pedestrian` hierarchies are always disabled by default.
9696

@@ -234,7 +234,7 @@ These options are available for pedestrian costing methods.
234234
| `use_living_streets` | This value indicates the willingness to take living streets. This is a range of values between 0 and 1. Values near 0 attempt to avoid living streets and values near 1 will favor living streets. The default value is 0.6. Note that sometimes living streets are required to complete a route so values of 0 are not guaranteed to avoid living streets entirely. |
235235
| `use_tracks` | This value indicates the willingness to take track roads. This is a range of values between 0 and 1. Values near 0 attempt to avoid tracks and values near 1 will favor tracks a little bit. The default value is 0.5. Note that sometimes tracks are required to complete a route so values of 0 are not guaranteed to avoid tracks entirely. |
236236
| `use_hills` | This is a range of values from 0 to 1, where 0 attempts to avoid hills and steep grades even if it means a longer (time and distance) path, while 1 indicates the pedestrian does not fear hills and steeper grades. Based on the `use_hills` factor, penalties are applied to roads based on elevation change and grade. These penalties help the path avoid hilly roads in favor of flatter roads or less steep grades where available. Note that it is not always possible to find alternate paths to avoid hills (for example when route locations are in mountainous areas). The default value is 0.5. |
237-
| `use_lit` | This value is a range of values from 0 to 1, where 0 indicates indifference towards lit streets, and 1 indicates that unlit streets should be avoided. Note that even with values near 1, there is no guarantee the returned route will include lit segments. The default value is 0. |
237+
| `use_lit` | This value is a range of values from 0 to 1, where 0 indicates indifference towards lit streets, and 1 indicates that unlit streets should be avoided. Note that even with values near 1, there is no guarantee the returned route will include lit segments. The default value is 0. |
238238
| `service_penalty` | A penalty applied for transition to generic service road. The default penalty is 0. |
239239
| `service_factor` | A factor that modifies (multiplies) the cost when generic service roads are encountered. The default `service_factor` is 1. |
240240
| `destination_only_penalty` | A penalty applied when entering an road which is only allowed to enter if necessary to reach the [destination](https://wiki.openstreetmap.org/wiki/Tag:vehicle%3Ddestination) |
@@ -259,6 +259,17 @@ These options are available for transit costing when the multimodal costing mode
259259
| `use_transfers` |User's desire to favor transfers. Range of values from 0 (try to avoid transfers) to 1 (totally comfortable with transfers).|
260260
| `filters` | A way to filter for one or more ~~`stops`~~ (TODO: need to re-enable), `routes`, or `operators`. Filters must contain a list of so-called Onestop IDs, which is (supposed to be) a unique identifier for GTFS data, and an `action`. The OneStop ID is simply the feeds's directory name and the object's GTFS ID separated by an underscore, i.e. a route with `route_id: AUR` in `routes.txt` from the feed `NYC` would have the OneStop ID `NYC_AUR`, similar with operators/agencies. <ul><li>`ids`: any number of Onestop IDs</li><li>`action`: either `exclude` to exclude all of the `ids` listed in the filter or `include` to include only the `ids` listed in the filter</li></ul>
261261

262+
##### Hard exclusions -> **EXPERIMENTAL**
263+
264+
The following options are available for all costing methods. Those options are not available by default, the server config must have `service_limits.allow_hard_exclusions` set to true in order to allow them. If not allowed and any of the hard excludes is set to true, the server will return a warning and ignore the hard excludes.
265+
266+
| Vehicle Options | Description |
267+
| :-------------------------- | :----------- |
268+
| `exclude_bridges` | This value indicates whether or not the path may include bridges. If `exclude_bridges` is set to true it is allowed to start and end with bridges, but is not allowed to have them in the middle of the route path, otherwise they are allowed. If set to true, it is highly plausible that no path will be found. Default false. |
269+
| `exclude_tunnels` | This value indicates whether or not the path may include tunnels. If `exclude_tunnels` is set to true it is allowed to start and end with tunnels, but is not allowed to have them in the middle of the route path, otherwise they are allowed. If set to true, it is highly plausible that no path will be found. Default false. |
270+
| `exclude_tolls` | This value indicates whether or not the path may include tolls. If `exclude_tolls` is set to true it is allowed to start and end with tolls, but is not allowed to have them in the middle of the route path, otherwise they are allowed. If set to true, it is highly plausible that no path will be found. Default false. |
271+
| `exclude_highways` | This value indicates whether or not the path may include highways. If `exclude_highways` is set to true it is allowed to start and end with highways, but is not allowed to have them in the middle of the route path, otherwise they are allowed. If set to true, it is highly plausible that no path will be found. Default false. |
272+
| `exclude_ferries` | This value indicates whether or not the path may include ferries. If `exclude_ferries` is set to true it is allowed to start and end with ferries, but is not allowed to have them in the middle of the route path, otherwise they are allowed. If set to true, it is highly plausible that no path will be found. Default false. |
262273

263274
##### Sample JSON payloads for multimodal requests with transit
264275

@@ -371,7 +382,7 @@ Basic trip information includes:
371382
| `units` | The specified units of length are returned, either kilometers or miles. |
372383
| `language` | The language of the narration instructions. If the user specified a language in the directions options and the specified language was supported - this returned value will be equal to the specified value. Otherwise, this value will be the default (en-US) language. |
373384
| `locations` | Location information is returned in the same form as it is entered with additional fields to indicate the side of the street. |
374-
| `warnings` (optional) | This array may contain warning objects informing about deprecated request parameters, clamped values etc. |
385+
| `warnings` (optional) | This array may contain warning objects informing about deprecated request parameters, clamped values etc. |
375386

376387
The summary JSON object includes:
377388

proto/common.proto

+3-1
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,11 @@ message SearchFilter {
6161
oneof has_exclude_closures {
6262
bool exclude_closures = 6;// whether to exclude roads marked as closed due to traffic [default = true]
6363
}
64+
bool exclude_toll = 7; // whether to exclude toll routes from loki results [default = false]
65+
bool exclude_ferry = 8; // whether to exclude ferry routes from loki results [default = false]
6466

6567
oneof has_level {
66-
float level = 7; // level to filter edges by
68+
float level = 9; // level to filter edges by
6769
}
6870
}
6971

proto/options.proto

+5
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,11 @@ message Costing {
317317
float hgv_no_access_penalty = 85;
318318
}
319319
float use_truck_route = 86;
320+
bool exclude_bridges = 87;
321+
bool exclude_tunnels = 88;
322+
bool exclude_tolls = 89;
323+
bool exclude_highways = 90;
324+
bool exclude_ferries = 91;
320325
}
321326

322327
oneof has_options {

scripts/valhalla_build_config

+2
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ config = {
273273
'max_alternates': 2,
274274
'max_exclude_polygons_length': 10000,
275275
'max_distance_disable_hierarchy_culling': 0,
276+
'allow_hard_exclusions': False,
276277
},
277278
'statsd': {
278279
'host': Optional(str),
@@ -549,6 +550,7 @@ help_text = {
549550
'max_alternates': 'Maximum number of alternate routes to allow in a request',
550551
'max_exclude_polygons_length': 'Maximum total perimeter of all exclude_polygons in meters',
551552
'max_distance_disable_hierarchy_culling': 'Maximum search distance allowed with hierarchy culling disabled',
553+
'allow_hard_exclusions': 'Whether hard exclusions, such as exclude_bridges, exclude_tunnels, exclude_tolls, exclude_highways or exclude_ferries are allowed on this server',
552554
},
553555
'statsd': {
554556
'host': 'The statsd host address',

src/baldr/location.cc

+5-2
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@ Location::SearchFilter::SearchFilter(valhalla::RoadClass min_road_class,
1111
valhalla::RoadClass max_road_class,
1212
bool exclude_tunnel,
1313
bool exclude_bridge,
14+
bool exclude_toll,
1415
bool exclude_ramp,
16+
bool exclude_ferry,
1517
bool exclude_closures,
1618
float level)
1719
: min_road_class_(min_road_class), max_road_class_(max_road_class),
18-
exclude_tunnel_(exclude_tunnel), exclude_bridge_(exclude_bridge), exclude_ramp_(exclude_ramp),
19-
exclude_closures_(exclude_closures), level_(level) {
20+
exclude_tunnel_(exclude_tunnel), exclude_bridge_(exclude_bridge), exclude_toll_(exclude_toll),
21+
exclude_ramp_(exclude_ramp), exclude_ferry_(exclude_ferry), exclude_closures_(exclude_closures),
22+
level_(level) {
2023
}
2124

2225
// TODO: get defaults from config singleton

src/loki/search.cc

+2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ bool search_filter(const DirectedEdge* edge,
3636
// road class is outside of the min to max range.
3737
return (road_class > min_road_class || road_class < max_road_class) ||
3838
(filter.exclude_tunnel_ && edge->tunnel()) || (filter.exclude_bridge_ && edge->bridge()) ||
39+
(filter.exclude_toll_ && edge->toll()) ||
3940
(filter.exclude_ramp_ && (edge->use() == Use::kRamp)) ||
41+
(filter.exclude_ferry_ && (edge->use() == Use::kFerry || edge->use() == Use::kRailFerry)) ||
4042
(filter.exclude_closures_ && (costing.flow_mask() & kCurrentFlowMask) &&
4143
tile->IsClosed(edge)) ||
4244
(filter.level_ != kMaxLevel && !tile->edgeinfo(edge).includes_level(filter.level_));

0 commit comments

Comments
 (0)