Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yuzhe/bug fix leg discontinuity multi routes #2049

Merged
merged 21 commits into from
Nov 21, 2019

Conversation

yuzheyan
Copy link
Contributor

@yuzheyan yuzheyan commented Nov 12, 2019

Issue

This PR is targeting make valhalla to handle mapmatch with disconnected edge groups. When match results have disconnected groups, the old logic return no route. This can be an issue when user input several location with small radius. The match result may only contain one matched edge group and thus a valid route is expected as output. However, when user increase the search radius, edges that previous could not be found now could be discovered and when those edges has discontinuity, no routes will be returned. This PR solves: "Why when I increase the radius, no route will be found?".

The PR put disjoint edge groups into multi-routes.

Tasklist

  • Add tests
  • Review - you must request approval to merge any PR to master
  • Add #fixes with the issue number that this PR addresses
  • Generally use squash merge to rebase and clean comments before merging
  • Update the changelog
  • Update relevant documentation

Screen Shot 2019-11-12 at 10 26 45 AM

@@ -194,7 +193,7 @@ MapMatcher::FormPath(meili::MapMatcher* matcher,
// Check if connected to prior edge
if (prior_edge.Is_Valid() &&
!matcher->graphreader().AreEdgesConnectedForward(prior_edge, edge_id)) {
disconnected_edges.emplace_back(prior_edge, edge_id);
disconnected_edges.insert({prior_edge, edge_id});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there actually a semantic difference here? sends rvalue ref to insert and the previous forwards the args to in place constructor.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yeah derp, sorry for the confusion

@yuzheyan
Copy link
Contributor Author

yuzheyan commented Nov 13, 2019 via email

Comment on lines 176 to 181
for (const auto& edge : m_temp_path_edges) {
m_temp_disjoint_edge_groups.back().emplace_back(edge);
if (m_temp_disconnected_edges.count(edge.edgeid) > 0) {
m_temp_disjoint_edge_groups.emplace_back();
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a description of what this is doing would be great for the sake of clarity. the variable names tell us a little bit but honestly not enough to really grasp what we are doing here. seems we are saying if we see the same edge id twice then we need to start a new group of edges? if that is true then i want to ask what happens when we do a map match that has a loop in the path (which is a completely reasonable thing to occur)?

@@ -28,7 +28,7 @@ class MapMatcher {
const std::vector<meili::EdgeSegment>& edge_segments,
const std::shared_ptr<sif::DynamicCost>* mode_costing,
const sif::TravelMode mode,
std::vector<std::pair<baldr::GraphId, baldr::GraphId>>& disconnected_edges,
std::unordered_map<baldr::GraphId, baldr::GraphId>& disconnected_edges,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is dubious for the reason i mentioned before. once its unordered you cant know what part of the rout eyou are talking about if the route has loops

@dnesbitt61
Copy link
Member

I have a couple of questions:

Will this return multiple routes, or a single route with multiple legs?
Is there a way to also access the portion of the input polyline where the disconnections occur?

I would like to piece the separate routes/legs back into a single route and leg with a special step and maneuver over the part of the input polyline that is unmatched. That way my navigation and reroute code remains the same. (Note that I have a custom serializer that bypasses OSRM or Valhalla serializers and outputs a custom pbf).

@yuzheyan
Copy link
Contributor Author

yuzheyan commented Nov 15, 2019 via email

// TODO - perhaps also throw exception if use_timestamps and disconnected path?
if (options.action() == Options::trace_route &&
(!m_temp_disconnected_edges.empty() || m_temp_path_edges.empty())) {
if (m_temp_path_edges.empty() && options.action() == Options::trace_route) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should try not to delete comments from the code. as you know this stuff is complicated. we need to keep comments in so that when the next person gets to the code its easier for them to understand what is going on. here we are throwing if you are doing trace route and we found no route at all.

@dnesbitt61
Copy link
Member

Testing this I am seeing an output of 2 routes but the first route has 0 legs. In trace_route_action I see 2 disjoint edge groups with 6 path edges in the first and 5 in the second. The first group never triggers a call to TripLegBuilder::Build. Is this because it is looking for a Location with type == kBreak?

@yuzheyan
Copy link
Contributor Author

yuzheyan commented Nov 18, 2019 via email

@dnesbitt61
Copy link
Member

http://localhost:8002/trace_route?json={%22shape%22:%20[{%22lat%22:%2039.660252,%22lon%22:%20-76.152962,%22time%22:%2012.979016},{%22lat%22:%2039.660278,%22lon%22:%20-76.152786,%22time%22:%2018.557921},{%22lat%22:%2039.660351,%22lon%22:%20-76.152550,%22time%22:%2026.451509},{%22lat%22:%2039.660500,%22lon%22:%20-76.152229,%22time%22:%2037.995133},{%22lat%22:%2039.660622,%22lon%22:%20-76.151993,%22time%22:%2046.779257},{%22lat%22:%2039.660679,%22lon%22:%20-76.151817,%22time%22:%2052.658214},{%22lat%22:%2039.660721,%22lon%22:%20-76.151711,%22time%22:%2056.357584},{%22lat%22:%2039.660759,%22lon%22:%20-76.151588,%22time%22:%2060.422235},{%22lat%22:%2039.660782,%22lon%22:%20-76.151421,%22time%22:%2065.745276},{%22lat%22:%2039.660801,%22lon%22:%20-76.151268,%22time%22:%2070.513987},{%22lat%22:%2039.660820,%22lon%22:%20-76.150810,%22time%22:%2084.662634},{%22lat%22:%2039.660820,%22lon%22:%20-76.150681,%22time%22:%2088.663728},{%22lat%22:%2039.660820,%22lon%22:%20-76.150452,%22time%22:%2095.724420},{%22lat%22:%2039.660820,%22lon%22:%20-76.150070,%22time%22:%20107.492341},{%22lat%22:%2039.660820,%22lon%22:%20-76.149872,%22time%22:%20113.611672},{%22lat%22:%2039.660839,%22lon%22:%20-76.149673,%22time%22:%20119.778453},{%22lat%22:%2039.660870,%22lon%22:%20-76.149559,%22time%22:%20123.520842},{%22lat%22:%2039.660919,%22lon%22:%20-76.149460,%22time%22:%20127.169235},{%22lat%22:%2039.660992,%22lon%22:%20-76.149330,%22time%22:%20132.113368},{%22lat%22:%2039.661098,%22lon%22:%20-76.149147,%22time%22:%20139.227467},{%22lat%22:%2039.661209,%22lon%22:%20-76.148972,%22time%22:%20146.224212},{%22lat%22:%2039.661320,%22lon%22:%20-76.148781,%22time%22:%20153.591163},{%22lat%22:%2039.661411,%22lon%22:%20-76.148651,%22time%22:%20159.019515},{%22lat%22:%2039.661690,%22lon%22:%20-76.148262,%22time%22:%20175.411159},{%22lat%22:%2039.661850,%22lon%22:%20-76.148003,%22time%22:%20185.670367},{%22lat%22:%2039.661819,%22lon%22:%20-76.147888,%22time%22:%20189.406572},{%22lat%22:%2039.661678,%22lon%22:%20-76.147469,%22time%22:%20203.532764},{%22lat%22:%2039.661610,%22lon%22:%20-76.147263,%22time%22:%20210.457370},{%22lat%22:%2039.661301,%22lon%22:%20-76.146378,%22time%22:%20240.435186},{%22lat%22:%2039.661228,%22lon%22:%20-76.146172,%22time%22:%20247.422054},{%22lat%22:%2039.661179,%22lon%22:%20-76.145714,%22time%22:%20261.682584},{%22lat%22:%2039.661110,%22lon%22:%20-76.145279,%22time%22:%20275.377198},{%22lat%22:%2039.660980,%22lon%22:%20-76.145020,%22time%22:%20284.926704},{%22lat%22:%2039.660839,%22lon%22:%20-76.144920,%22time%22:%20291.357266},{%22lat%22:%2039.660660,%22lon%22:%20-76.144791,%22time%22:%20299.580773},{%22lat%22:%2039.660542,%22lon%22:%20-76.144691,%22time%22:%20305.221459},{%22lat%22:%2039.660381,%22lon%22:%20-76.144623,%22time%22:%20312.206375},{%22lat%22:%2039.660198,%22lon%22:%20-76.144600,%22time%22:%20319.577694},{%22lat%22:%2039.660049,%22lon%22:%20-76.144592,%22time%22:%20325.544004},{%22lat%22:%2039.659840,%22lon%22:%20-76.144577,%22time%22:%20333.964559},{%22lat%22:%2039.659729,%22lon%22:%20-76.144577,%22time%22:%20338.397670},{%22lat%22:%2039.659359,%22lon%22:%20-76.144630,%22time%22:%20353.322674},{%22lat%22:%2039.659229,%22lon%22:%20-76.144630,%22time%22:%20358.520028},{%22lat%22:%2039.659019,%22lon%22:%20-76.144653,%22time%22:%20366.958472},{%22lat%22:%2039.658901,%22lon%22:%20-76.144638,%22time%22:%20371.720510},{%22lat%22:%2039.658760,%22lon%22:%20-76.144638,%22time%22:%20377.376325},{%22lat%22:%2039.658649,%22lon%22:%20-76.144623,%22time%22:%20381.834186},{%22lat%22:%2039.658489,%22lon%22:%20-76.144562,%22time%22:%20388.540082},{%22lat%22:%2039.658360,%22lon%22:%20-76.144478,%22time%22:%20394.397591},{%22lat%22:%2039.658169,%22lon%22:%20-76.144318,%22time%22:%20403.499627},{%22lat%22:%2039.658031,%22lon%22:%20-76.144157,%22time%22:%20410.896467},{%22lat%22:%2039.657928,%22lon%22:%20-76.144058,%22time%22:%20416.034137},{%22lat%22:%2039.657780,%22lon%22:%20-76.143837,%22time%22:%20425.096737},{%22lat%22:%2039.657711,%22lon%22:%20-76.143730,%22time%22:%20429.434592},{%22lat%22:%2039.657558,%22lon%22:%20-76.143440,%22time%22:%20440.269011},{%22lat%22:%2039.657509,%22lon%22:%20-76.143341,%22time%22:%20443.917725},{%22lat%22:%2039.657391,%22lon%22:%20-76.143044,%22time%22:%20454.248669},{%22lat%22:%2039.657310,%22lon%22:%20-76.142830,%22time%22:%20461.581496},{%22lat%22:%2039.657219,%22lon%22:%20-76.142616,%22time%22:%20469.124079},{%22lat%22:%2039.657082,%22lon%22:%20-76.142418,%22time%22:%20477.362288},{%22lat%22:%2039.656952,%22lon%22:%20-76.142319,%22time%22:%20483.393379},{%22lat%22:%2039.656799,%22lon%22:%20-76.142189,%22time%22:%20490.701913},{%22lat%22:%2039.656681,%22lon%22:%20-76.142090,%22time%22:%20496.342703},{%22lat%22:%2039.656509,%22lon%22:%20-76.141907,%22time%22:%20505.244283},{%22lat%22:%2039.656239,%22lon%22:%20-76.141632,%22time%22:%20519.013479},{%22lat%22:%2039.656090,%22lon%22:%20-76.141472,%22time%22:%20526.783855},{%22lat%22:%2039.656021,%22lon%22:%20-76.141388,%22time%22:%20530.562116},{%22lat%22:%2039.655949,%22lon%22:%20-76.141312,%22time%22:%20534.311998},{%22lat%22:%2039.655849,%22lon%22:%20-76.141190,%22time%22:%20539.787262},{%22lat%22:%2039.655750,%22lon%22:%20-76.140984,%22time%22:%20547.283073},{%22lat%22:%2039.655640,%22lon%22:%20-76.140747,%22time%22:%20555.866326},{%22lat%22:%2039.655579,%22lon%22:%20-76.140610,%22time%22:%20560.778185},{%22lat%22:%2039.655499,%22lon%22:%20-76.140411,%22time%22:%20567.688747},{%22lat%22:%2039.655449,%22lon%22:%20-76.140221,%22time%22:%20573.900832},{%22lat%22:%2039.655411,%22lon%22:%20-76.140038,%22time%22:%20579.754215},{%22lat%22:%2039.655392,%22lon%22:%20-76.139893,%22time%22:%20584.291194},{%22lat%22:%2039.655380,%22lon%22:%20-76.139709,%22time%22:%20589.962853},{%22lat%22:%2039.655380,%22lon%22:%20-76.139420,%22time%22:%20598.907444},{%22lat%22:%2039.655392,%22lon%22:%20-76.138718,%22time%22:%20620.567560},{%22lat%22:%2039.655392,%22lon%22:%20-76.138382,%22time%22:%20630.924128},{%22lat%22:%2039.655399,%22lon%22:%20-76.138229,%22time%22:%20635.641468},{%22lat%22:%2039.655418,%22lon%22:%20-76.138023,%22time%22:%20642.042383},{%22lat%22:%2039.655472,%22lon%22:%20-76.137733,%22time%22:%20651.239500},{%22lat%22:%2039.655579,%22lon%22:%20-76.137207,%22time%22:%20668.034992},{%22lat%22:%2039.655602,%22lon%22:%20-76.137062,%22time%22:%20672.641681},{%22lat%22:%2039.655602,%22lon%22:%20-76.136940,%22time%22:%20676.406410},{%22lat%22:%2039.655548,%22lon%22:%20-76.136833,%22time%22:%20680.538436},{%22lat%22:%2039.655361,%22lon%22:%20-76.136711,%22time%22:%20689.129800},{%22lat%22:%2039.655411,%22lon%22:%20-76.136581,%22time%22:%20693.597627},{%22lat%22:%2039.655460,%22lon%22:%20-76.136398,%22time%22:%20699.614712},{%22lat%22:%2039.655491,%22lon%22:%20-76.136276,%22time%22:%20703.615910},{%22lat%22:%2039.655540,%22lon%22:%20-76.136063,%22time%22:%20710.499489},{%22lat%22:%2039.655590,%22lon%22:%20-76.135834,%22time%22:%20717.838095},{%22lat%22:%2039.655640,%22lon%22:%20-76.135620,%22time%22:%20724.721674},{%22lat%22:%2039.655689,%22lon%22:%20-76.135391,%22time%22:%20732.057178},{%22lat%22:%2039.655731,%22lon%22:%20-76.135231,%22time%22:%20737.278238},{%22lat%22:%2039.655811,%22lon%22:%20-76.134941,%22time%22:%20746.781050},{%22lat%22:%2039.655880,%22lon%22:%20-76.134758,%22time%22:%20753.071470},{%22lat%22:%2039.655930,%22lon%22:%20-76.134621,%22time%22:%20757.769144},{%22lat%22:%2039.655960,%22lon%22:%20-76.134422,%22time%22:%20764.016902},{%22lat%22:%2039.655949,%22lon%22:%20-76.134216,%22time%22:%20770.403447},{%22lat%22:%2039.655918,%22lon%22:%20-76.134033,%22time%22:%20776.249508},{%22lat%22:%2039.655842,%22lon%22:%20-76.133873,%22time%22:%20782.061384},{%22lat%22:%2039.655788,%22lon%22:%20-76.133743,%22time%22:%20786.599138},{%22lat%22:%2039.655720,%22lon%22:%20-76.133591,%22time%22:%20792.051801},{%22lat%22:%2039.655659,%22lon%22:%20-76.133476,%22time%22:%20796.346784},{%22lat%22:%2039.655560,%22lon%22:%20-76.133293,%22time%22:%20803.254495},{%22lat%22:%2039.655350,%22lon%22:%20-76.132927,%22time%22:%20817.337451},{%22lat%22:%2039.655231,%22lon%22:%20-76.132729,%22time%22:%20825.128163},{%22lat%22:%2039.655121,%22lon%22:%20-76.132561,%22time%22:%20831.944846},{%22lat%22:%2039.654991,%22lon%22:%20-76.132393,%22time%22:%20839.423146},{%22lat%22:%2039.654861,%22lon%22:%20-76.132217,%22time%22:%20846.928040},{%22lat%22:%2039.654850,%22lon%22:%20-76.132210,%22time%22:%20847.444635}],%22shape_match%22:%20%22map_snap%22,%22costing%22:%20%22bicycle%22}

@yuzheyan
Copy link
Contributor Author

yuzheyan commented Nov 18, 2019 via email

@dnesbitt61
Copy link
Member

I was expecting each route would have 1 leg constructed from the path edges for each of the disjoint edge groups. I would think each would have a depart step and an arrive step. Even though you are not departing or arriving at a kBreak location you would be "arriving" at the point in the original input path where there is no map match, and would be "departing" at the point where match results start again.
This way you have directions (steps and maneuvers) for each matched section.

@kevinkreiser
Copy link
Member

@dnesbitt61 i expected that, wherever there was a break or break through type location in the route we would get multi leg but wherever there was a discontinuity it would be multi route. seems we have combined location type with discontinuity. @yuzheyan id be glad to explain more!

@dnesbitt61
Copy link
Member

I have code working on my side where there are 2 locations (short route) with a discontinuity. I am returning 2 route, using my custom code to combine the routes into 1 route with 1 leg and (finally) adding a "false" step that is the portion of the input shape that is not matched. I'm not sure it is robust enough for all conditions, but basically once the origin_iter is advanced, I have a second loop that finds the dest_iter (advances while the iter->edgeid.Is_Valid and not a kBreak). Then I just form the origin_location, destination_location using the 2 iters, have the add_path_edge code, then call TripLegBuilder::Build (with the full path_infos).

…inuity occurs and build legs on them accordingly
@dnesbitt61
Copy link
Member

The test route still seems to serialize only 1 route, though I do see 2 calls to build trip legs and there are 2 routes in the trip result. Do I have to add anything to the request to get multiple routes back? The code does work properly in my custom code that uses the pbf directly.

Also, what is the purpose of last_leg_index? These seem to be 0 in the test case I ran.

@yuzheyan
Copy link
Contributor Author

yuzheyan commented Nov 20, 2019 via email

@yuzheyan
Copy link
Contributor Author

yuzheyan commented Nov 20, 2019 via email

@dnesbitt61
Copy link
Member

My somewhat limited testing this is working for me. I have seen it create more multiple routes properly where there are disconnects.

dnesbitt61
dnesbitt61 previously approved these changes Nov 20, 2019
@kevinkreiser kevinkreiser merged commit 9e35e35 into master Nov 21, 2019
@yuzheyan yuzheyan deleted the yuzhe/bug_fix_leg_discontinuity_multi_routes branch November 22, 2019 21:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants