Skip to content

Commit

Permalink
Merge branch 'master' into nn-matrix-pbf
Browse files Browse the repository at this point in the history
  • Loading branch information
nilsnolde committed Jul 4, 2023
2 parents 44a0369 + 1e97599 commit 49b4429
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* **Enhancement**
* UPDATED: French translations, thanks to @xlqian [#4159](https://github.com/valhalla/valhalla/pull/4159)
* ADDED: CI runs a spell check on the PR to detect spelling mistakes [#4179](https://github.com/valhalla/valhalla/pull/4179)
* ADDED: `preferred_side_cutoff` parameter for locations [#4182](https://github.com/valhalla/valhalla/pull/4182)
* ADDED: PBF output for matrix endpoint [#4121](https://github.com/valhalla/valhalla/pull/4121)

## Release Date: 2023-05-11 Valhalla 3.4.0
Expand Down
10 changes: 6 additions & 4 deletions docs/docs/api/turn-by-turn/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ To build a route, you need to specify two `break` locations. In addition, you ca
| `preferred_side` | If the location is not offset from the road centerline or is closest to an intersection this option has no effect. Otherwise the determined side of street is used to determine whether or not the location should be visited from the `same`, `opposite` or `either` side of the road with respect to the side of the road the given locale drives on. In Germany (driving on the right side of the road), passing a value of `same` will only allow you to leave from or arrive at a location such that the location will be on your right. In Australia (driving on the left side of the road), passing a value of `same` will force the location to be on your left. A value of `opposite` will enforce arriving/departing from a location on the opposite side of the road from that which you would be driving on while a value of `either` will make no attempt limit the side of street that is available for the route. |
| `display_lat` | Latitude of the map location in degrees. If provided the `lat` and `lon` parameters will be treated as the routing location and the `display_lat` and `display_lon` will be used to determine the side of street. Both `display_lat` and `display_lon` must be provided and valid to achieve the desired effect. |
| `display_lon` | Longitude of the map location in degrees. If provided the `lat` and `lon` parameters will be treated as the routing location and the `display_lat` and `display_lon` will be used to determine the side of street. Both `display_lat` and `display_lon` must be provided and valid to achieve the desired effect. |
| `search_cutoff` | The cutoff at which we will assume the input is too far away from civilisation to be worth correlating to the nearest graph elements |
| `node_snap_tolerance` | During edge correlation this is the tolerance used to determine whether or not to snap to the intersection rather than along the street, if the snap location is within this distance from the intersection the intersection is used instead. The default is 5 meters |
| `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 |
| `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 |
| `search_cutoff` | The cutoff at which we will assume the input is too far away from civilisation to be worth correlating to the nearest graph elements. The default is 35 km. |
| `node_snap_tolerance` | During edge correlation this is the tolerance used to determine whether or not to snap to the intersection rather than along the street, if the snap location is within this distance from the intersection the intersection is used instead. The default is 5 meters. |
| `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. |
| `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. |
| `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. |
| `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></ul>Road classes from highest to lowest are: motorway, trunk, primary, secondary, tertiary, unclassified, residential, service_other.

Optionally, you can include the following location information without impacting the routing. This information is carried through the request and returned as a convenience.
Expand Down Expand Up @@ -315,6 +316,7 @@ Directions options should be specified at the top level of the JSON object.
| `id` | Name your route request. If `id` is specified, the naming will be sent thru to the response. |
| `linear_references` | When present and `true`, the successful `route` response will include a key `linear_references`. Its value is an array of base64-encoded [OpenLR location references][openlr], one for each graph edge of the road network matched by the input trace. |
| `prioritize_bidirectional` | Prioritize `bidirectional a*` when `date_time.type = depart_at/current`. By default `time_dependent_forward a*` is used in these cases, but `bidirectional a*` is much faster. Currently it does not update the time (and speeds) when searching for the route path, but the ETA on that route is recalculated based on the time-dependent speeds |
| `roundabout_exits` | A boolean indicating whether exit instructions at roundabouts should be added to the output or not. Default is true. |

[openlr]: https://www.openlr-association.com/fileadmin/user_upload/openlr-whitepaper_v1.5.pdf

Expand Down
3 changes: 3 additions & 0 deletions proto/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ message Location {
int32 preferred_layer = 28;
}
float waiting_secs = 29; // waiting period before a new leg starts, e.g. for servicing/loading goods
oneof has_street_side_cutoff {
RoadClass street_side_cutoff = 30;
}

// This information will be ignored if provided in the request. Instead it will be filled in as the request is handled
Correlation correlation = 90;
Expand Down
5 changes: 4 additions & 1 deletion src/baldr/location.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ Location::Location(const midgard::PointLL& latlng,
unsigned int min_inbound_reach,
unsigned long radius,
const PreferredSide& side,
valhalla::RoadClass street_side_cutoff,
const SearchFilter& search_filter,
std::optional<int8_t> preferred_layer)
: latlng_(latlng), stoptype_(stoptype), min_outbound_reach_(min_outbound_reach),
min_inbound_reach_(min_inbound_reach), radius_(radius), preferred_side_(side),
node_snap_tolerance_(5), heading_tolerance_(60), search_cutoff_(35000),
street_side_tolerance_(5), street_side_max_distance_(1000), search_filter_(search_filter),
street_side_tolerance_(5), street_side_max_distance_(1000),
street_side_cutoff_(street_side_cutoff), search_filter_(search_filter),
preferred_layer_(std::move(preferred_layer)) {
}

Expand All @@ -43,6 +45,7 @@ bool Location::operator==(const Location& o) const {
node_snap_tolerance_ == o.node_snap_tolerance_ &&
street_side_tolerance_ == o.street_side_tolerance_ &&
street_side_max_distance_ == o.street_side_max_distance_ &&
street_side_cutoff_ == o.street_side_cutoff_ &&
min_outbound_reach_ == o.min_outbound_reach_ && min_inbound_reach_ == o.min_inbound_reach_ &&
radius_ == o.radius_ && preferred_side_ == o.preferred_side_ &&
display_latlng_ == o.display_latlng_ && preferred_layer_ == o.preferred_layer_;
Expand Down
11 changes: 10 additions & 1 deletion src/loki/search.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,23 @@ bool side_filter(const PathLocation::PathEdge& edge, const Location& location, G
location.preferred_side_ == Location::PreferredSide::EITHER)
return false;

// need the driving side for this edge
// need this for further checking of driving side and road class
graph_tile_ptr tile;
auto* opp = reader.GetOpposingEdge(edge.id, tile);
if (!opp)
return false;

// nothing to filter if it is a minor road
// since motorway = 0 and service = 7, higher number means smaller road class
uint32_t road_class = static_cast<uint32_t>(opp->classification());
if (road_class > location.street_side_cutoff_)
return false;

// need the driving side for this edge
auto* node = reader.GetEndNode(opp, tile);
if (!node)
return false;

// if its on the right side and you drive on the right OR if its not on the right and you dont drive
// on the right THEN its the same side that you drive on
bool same = node->drive_on_right() == (edge.sos == PathLocation::SideOfStreet::RIGHT);
Expand Down
7 changes: 7 additions & 0 deletions src/worker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,13 @@ void parse_location(valhalla::Location* location,
if (street_side_max_distance) {
location->set_street_side_max_distance(*street_side_max_distance);
}
auto street_side_cutoff = rapidjson::get_optional<std::string>(r_loc, "/street_side_cutoff");
if (street_side_cutoff) {
valhalla::RoadClass cutoff_street_side;
if (RoadClass_Enum_Parse(*street_side_cutoff, &cutoff_street_side)) {
location->set_street_side_cutoff(cutoff_street_side);
}
}

boost::optional<bool> exclude_closures;
// is it json?
Expand Down
18 changes: 18 additions & 0 deletions test/gurka/test_search_filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class SearchFilter : public ::testing::Test {
static void SetUpTestSuite() {
constexpr double gridsize = 100;

// remark: without admin database, left-side driving is the
// default driving side.
const std::string ascii_map = R"(
B---------C
| 2 8 |
Expand Down Expand Up @@ -91,6 +93,22 @@ TEST_F(SearchFilter, PreferredSide) {
gurka::assert::osrm::expect_steps(result, {"AB", "AD", "CD", "BC"});
gurka::assert::raw::expect_path(result, {"AB", "AD", "CD", "BC"});
}
TEST_F(SearchFilter, StreetSideCutoff) {
auto from = "7";
auto to = "8";

const std::string& request =
(boost::format(
R"({"locations":[{"lat":%s,"lon":%s},{"lat":%s,"lon":%s,"preferred_side":"same","street_side_cutoff":"primary"}],"costing":"auto"})") %
std::to_string(map.nodes.at(from).lat()) % std::to_string(map.nodes.at(from).lng()) %
std::to_string(map.nodes.at(to).lat()) % std::to_string(map.nodes.at(to).lng()))
.str();
auto result = gurka::do_action(valhalla::Options::route, map, request);

// should take the short way in the north
gurka::assert::osrm::expect_steps(result, {"AB", "BC"});
gurka::assert::raw::expect_path(result, {"AB", "BC"});
}
TEST_F(SearchFilter, MaxRoadClass) {
auto from = "1";
auto to = "2";
Expand Down
4 changes: 3 additions & 1 deletion valhalla/baldr/location.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ struct Location {
* Optional filters supplied in the request.
*
* NOTE: this struct must be kept in sync with the protobuf defined
* valhalla::Location::SearchFilter in tripcommon.proto.
* valhalla::Location::SearchFilter in common.proto.
*/
struct SearchFilter {
public:
Expand Down Expand Up @@ -71,6 +71,7 @@ struct Location {
unsigned int min_inbound_reach = 0,
unsigned long radius = 0,
const PreferredSide& side = PreferredSide::EITHER,
valhalla::RoadClass street_side_cutoff = valhalla::RoadClass::kServiceOther,
const SearchFilter& search_filter = SearchFilter(),
std::optional<int8_t> preferred_layer = {});

Expand Down Expand Up @@ -109,6 +110,7 @@ struct Location {
float search_cutoff_;
float street_side_tolerance_;
float street_side_max_distance_;
valhalla::RoadClass street_side_cutoff_;
SearchFilter search_filter_;

// coordinates of the location as used for altering the side of street
Expand Down
7 changes: 6 additions & 1 deletion valhalla/baldr/pathlocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ struct PathLocation : public Location {
l->set_search_cutoff(pl.radius_ > pl.search_cutoff_ ? pl.radius_ : pl.search_cutoff_);
l->set_street_side_tolerance(pl.street_side_tolerance_);
l->set_street_side_max_distance(pl.street_side_max_distance_);
l->set_street_side_cutoff(pl.street_side_cutoff_);
l->mutable_search_filter()->set_min_road_class(pl.search_filter_.min_road_class_);
l->mutable_search_filter()->set_max_road_class(pl.search_filter_.max_road_class_);
l->mutable_search_filter()->set_exclude_tunnel(pl.search_filter_.exclude_tunnel_);
Expand Down Expand Up @@ -192,7 +193,8 @@ struct PathLocation : public Location {

SearchFilter search_filter = SearchFilter();
Location l({loc.ll().lng(), loc.ll().lat()}, fromPBF(loc.type()), loc.minimum_reachability(),
loc.minimum_reachability(), loc.radius(), side, search_filter);
loc.minimum_reachability(), loc.radius(), side, valhalla::RoadClass::kServiceOther,
search_filter);

l.name_ = loc.name();
l.street_ = loc.street();
Expand All @@ -218,6 +220,9 @@ struct PathLocation : public Location {
if (loc.has_street_side_max_distance_case()) {
l.street_side_max_distance_ = loc.street_side_max_distance();
}
if (loc.has_street_side_cutoff_case()) {
l.street_side_cutoff_ = loc.street_side_cutoff();
}
if (loc.has_search_filter()) {
l.search_filter_.min_road_class_ = loc.search_filter().min_road_class();
l.search_filter_.max_road_class_ = loc.search_filter().max_road_class();
Expand Down

0 comments on commit 49b4429

Please sign in to comment.