adjusted to in/out. only emit one of them for depart/arrive

This commit is contained in:
Moritz Kobitzsch 2016-05-12 11:16:52 +02:00 committed by Patrick Niklaus
parent 4d9aa65e78
commit 9c8bf820de
No known key found for this signature in database
GPG Key ID: E426891B5F978B1B
10 changed files with 161 additions and 105 deletions

View File

@ -18,7 +18,7 @@ Feature: Intersections Data
When I route I should get
| waypoints | route | turns | intersections |
| a,c | through,through | depart,arrive | true:90 true:270 false:0,true:90 true:180 false:270;true:90 true:270 false:0 |
| a,c | through,through | depart,arrive | true:90 true:270,true:90 true:180 false:270;true:90 true:270 |
Scenario: Passing Three Way North
Given the node map
@ -33,7 +33,7 @@ Feature: Intersections Data
When I route I should get
| waypoints | route | turns | intersections |
| a,c | through,through | depart,arrive | true:90 true:270 false:0,true:0 true:90 false:270;true:90 true:270 false:0 |
| a,c | through,through | depart,arrive | true:90 true:270,true:0 true:90 false:270;true:90 true:270 |
Scenario: Passing Oneway Street In
Given the node map
@ -48,7 +48,7 @@ Feature: Intersections Data
When I route I should get
| waypoints | route | turns | intersections |
| a,c | through,through | depart,arrive | true:90 true:270 false:0,false:0 true:90 false:270;true:90 true:270 false:0 |
| a,c | through,through | depart,arrive | true:90 true:270,false:0 true:90 false:270;true:90 true:270 |
Scenario: Passing Oneway Street Out
Given the node map
@ -63,7 +63,7 @@ Feature: Intersections Data
When I route I should get
| waypoints | route | turns | intersections |
| a,c | through,through | depart,arrive | true:90 true:270 false:0,true:0 true:90 false:270;true:90 true:270 false:0 |
| a,c | through,through | depart,arrive | true:90 true:270,true:0 true:90 false:270;true:90 true:270 |
Scenario: Passing Two Intersections
Given the node map
@ -81,7 +81,7 @@ Feature: Intersections Data
When I route I should get
| waypoints | route | turns | intersections |
| a,d | through,through | depart,arrive | true:90 true:270 false:0,true:0 true:90 false:270,true:90 true:180 false:270;true:90 true:270 false:0 |
| a,d | through,through | depart,arrive | true:90 true:270,true:0 true:90 false:270,true:90 true:180 false:270;true:90 true:270 |
Scenario: Passing Two Intersections, Collapsing
Given the node map
@ -99,8 +99,8 @@ Feature: Intersections Data
When I route I should get
| waypoints | route | turns | intersections |
| a,d | through,through | depart,arrive | true:90 true:270 false:0,true:0 true:90 false:270,true:90 true:180 false:270;true:90 true:270 false:0 |
| f,a | corner,throughbridge,through | depart,end of road left,arrive | true:0 true:180;true:90 false:180 true:270,true:0 false:90 true:270;true:90 true:270 false:0 |
| a,d | through,through | depart,arrive | true:90 true:270,true:0 true:90 false:270,true:90 true:180 false:270;true:90 true:270 |
| f,a | corner,throughbridge,through | depart,end of road left,arrive | true:0 true:180;true:90 false:180 true:270,true:0 false:90 true:270;true:90 true:270 |
Scenario: Roundabouts
Given the node map
@ -126,9 +126,9 @@ Feature: Intersections Data
When I route I should get
| waypoints | route | turns | intersections |
| e,f | ea,fb,fb | depart,abcda-exit-1,arrive | true:0 true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 true:270 false:0 |
| e,f | ea,fb,fb | depart,abcda-exit-1,arrive | true:0 true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 true:270 |
| e,g | ea,gc,gc | depart,abcda-exit-2,arrive | true:0 true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330;true:0 true:180 |
| e,h | ea,hd,hd | depart,abcda-exit-3,arrive | true:0 true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330,true:90 false:210 true:330;true:90 true:270 false:0 |
| e,2 | ea,abcda,abcda | depart,abcda-exit-undefined,arrive | true:0 true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:146 false:326 false:0 |
| 1,g | abcda,gc,gc | depart,abcda-exit-2,arrive | false:34 true:214 false:0;false:34 true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:0 true:180 |
| 1,3 | abcda,abcda | depart,arrive | false:34 true:214 false:0,false:30 true:150 true:270,true:30 true:180 false:330;true:34 false:214 false:0 |
| e,h | ea,hd,hd | depart,abcda-exit-3,arrive | true:0 true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330,true:90 false:210 true:330;true:90 true:270 |
| e,2 | ea,abcda,abcda | depart,abcda-exit-undefined,arrive | true:0 true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:146 false:326 |
| 1,g | abcda,gc,gc | depart,abcda-exit-2,arrive | false:34 true:214;false:34 true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:0 true:180 |
| 1,3 | abcda,abcda | depart,arrive | false:34 true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:34 false:214 |

View File

@ -138,7 +138,9 @@ module.exports = function () {
};
this.bearingList = (instructions) => {
return this.extractInstructionList(instructions, s => s.intersections[0].bearings[s.intersections[0].bearing_after]);
return this.extractInstructionList(instructions, s => (typeof s.intersections[0].out !== 'undefined')
? s.intersections[0].bearings[s.intersections[0].out]
: 0);
};
this.annotationList = (instructions) => {
@ -187,8 +189,8 @@ module.exports = function () {
for( i = 1; i < intersection.bearings.length; ++i )
string = string + ' ' + intersection.entry[i]+':'+intersection.bearings[i];
return string;
}).join(',')
}).join(';')
}).join(',');
}).join(';');
};
this.modeList = (instructions) => {

View File

@ -88,13 +88,12 @@ getIntersection(const guidance::Intersection &intersection, bool locate_before,
const auto &available_bearings = intersection.bearing_class.getAvailableBearings();
for (std::size_t i = 0; i < available_bearings.size(); ++i)
{
bearings.values.push_back(std::to_string(available_bearings[i]));
bearings.values.push_back(available_bearings[i]);
entry.values.push_back(intersection.entry_class.allowsEntry(i) ? "true" : "false");
}
result.values["location"] = detail::coordinateToLonLat(intersection.location);
bool requires_correction = false;
if (locate_before || (!available_bearings.empty() && available_bearings.front()==0))
if (locate_before)
{
// bearings are oriented in the direction of driving. For the in-bearing, we actually need
// to
@ -104,31 +103,15 @@ getIntersection(const guidance::Intersection &intersection, bool locate_before,
const auto rotated_bearing_before = (intersection.bearing_before >= 180.0)
? (intersection.bearing_before - 180.0)
: (intersection.bearing_before + 180.0);
result.values["bearing_before"] =
result.values["in"] =
intersection.bearing_class.findMatchingBearing(rotated_bearing_before);
}
else
{
result.values["bearing_before"] = available_bearings.size();
requires_correction = true;
}
if (locate_after || (!available_bearings.empty() && available_bearings.front()==0))
if (locate_after)
{
result.values["bearing_after"] =
result.values["out"] =
intersection.bearing_class.findMatchingBearing(intersection.bearing_after);
}
else
{
result.values["bearing_after"] = available_bearings.size();
requires_correction = true;
}
if (requires_correction)
{
bearings.values.push_back("0");
entry.values.push_back("false");
}
result.values["bearings"] = bearings;
result.values["entry"] = entry;

View File

@ -45,7 +45,6 @@ void fillInDepart(Intersection &intersection, const LegGeometry &leg_geometry)
intersection.bearing_before = 0;
intersection.bearing_after =
util::coordinate_calculation::bearing(turn_coordinate, post_turn_coordinate);
std::cout << "Depart: " << intersection.bearing_before << " " << intersection.bearing_after << std::endl;
}
void fillInArrive(Intersection &intersection, const LegGeometry &leg_geometry)
@ -57,7 +56,6 @@ void fillInArrive(Intersection &intersection, const LegGeometry &leg_geometry)
intersection.bearing_before =
util::coordinate_calculation::bearing(pre_turn_coordinate, turn_coordinate);
intersection.bearing_after = 0;
std::cout << "Arrive: " << intersection.bearing_before << " " << intersection.bearing_after << std::endl;
}
} // namespace

View File

@ -201,6 +201,7 @@ void closeOffRoundabout(const bool on_roundabout,
// index back to the entering location and prepare the current silent set of instructions for
// removal.
std::vector<std::size_t> intermediate_steps;
BOOST_ASSERT(!steps[step_index].intersections.empty());
const auto exit_bearing = steps[step_index].intersections.back().bearing_after;
if (step_index > 1)
{
@ -245,6 +246,7 @@ void closeOffRoundabout(const bool on_roundabout,
// % 360;
// All other cases are handled by first rotating both bearings to an
// entry_bearing of 0.
BOOST_ASSERT(!propagation_step.intersections.empty());
const double angle = [](const double entry_bearing, const double exit_bearing) {
const double offset = 360 - entry_bearing;
const double rotated_exit = [](double bearing, const double offset) {
@ -254,7 +256,7 @@ void closeOffRoundabout(const bool on_roundabout,
const auto angle = 540 - rotated_exit;
return angle > 360 ? angle - 360 : angle;
}(propagation_step.intersections.back().bearing_before, exit_bearing);
}(propagation_step.intersections.front().bearing_before, exit_bearing);
propagation_step.maneuver.instruction.direction_modifier =
::osrm::util::guidance::getTurnDirection(angle);
@ -335,12 +337,12 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
return angularDeviation(bearing_in, bearing_out) > 170;
};
BOOST_ASSERT(!one_back_step.intersections.empty() && !current_step.intersections.empty());
const auto isCollapsableInstruction = [](const TurnInstruction instruction) {
return instruction.type == TurnType::NewName ||
(instruction.type == TurnType::Turn &&
instruction.direction_modifier == DirectionModifier::Straight);
};
// Very Short New Name
if (isCollapsableInstruction(one_back_step.maneuver.instruction))
{
@ -679,7 +681,6 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
[](const std::size_t val) { return val - 1; });
steps.front().maneuver = {TurnInstruction::NO_TURN(), WaypointType::Depart, 0};
std::cout << "Removed coordinate: " << std::endl;
}
// and update the leg geometry indices for the removed entry
@ -706,6 +707,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
geometry.segment_distances.pop_back();
next_to_last_step.maneuver = {TurnInstruction::NO_TURN(), WaypointType::Arrive, 0};
BOOST_ASSERT(!next_to_last_step.intersections.empty());
next_to_last_step.intersections.front().bearing_after = 0;
steps.pop_back();
@ -761,6 +763,7 @@ std::vector<RouteStep> assignRelativeLocations(std::vector<RouteStep> steps,
: extractor::guidance::DirectionModifier::UTurn;
steps.front().maneuver.instruction.direction_modifier = initial_modifier;
BOOST_ASSERT(!steps.front().intersections.empty());
steps.front().intersections.front().bearing_before = 0;
steps.front().intersections.front().bearing_after =
util::coordinate_calculation::bearing(leg_geometry.locations[0], leg_geometry.locations[1]);
@ -781,6 +784,7 @@ std::vector<RouteStep> assignRelativeLocations(std::vector<RouteStep> steps,
steps.back().maneuver.instruction.direction_modifier = final_modifier;
BOOST_ASSERT(steps.back().intersections.size() == 1);
BOOST_ASSERT(!steps.back().intersections.empty());
steps.back().intersections.front().bearing_before = util::coordinate_calculation::bearing(
leg_geometry.locations[leg_geometry.locations.size() - 2],
leg_geometry.locations[leg_geometry.locations.size() - 1]);

View File

@ -48,6 +48,7 @@
#include <thread>
#include <unordered_map>
#include <vector>
#include <type_traits>
namespace osrm
{
@ -644,8 +645,10 @@ void Extractor::WriteIntersectionClassificationData(
file_out_stream.write( reinterpret_cast<const char*>(&bearings[0]), sizeof(bearings[0]) * bearings.size() );
}
static_assert(std::is_trivially_copyable<util::guidance::EntryClass>::value,
"EntryClass Serialization requires trivial copyable entry classes");
// FIXME
// This should be here, but g++4.8 does not have it...
// static_assert(std::is_trivially_copyable<util::guidance::EntryClass>::value,
// "EntryClass Serialization requires trivial copyable entry classes");
util::serializeVector(file_out_stream, entry_classes);
TIMER_STOP(write_edges);

View File

@ -54,11 +54,7 @@ classifyIntersection(NodeID nid,
std::sort(turns.begin(), turns.end(),
[](const TurnPossibility left, const TurnPossibility right) {
return util::guidance::BearingClass::getDiscreteBearing(left.bearing) <
util::guidance::BearingClass::getDiscreteBearing(right.bearing) ||
(util::guidance::BearingClass::getDiscreteBearing(left.bearing) ==
util::guidance::BearingClass::getDiscreteBearing(right.bearing) &&
left.bearing < right.bearing);
return left.bearing < right.bearing;
});
util::guidance::EntryClass entry_class;
@ -85,6 +81,12 @@ classifyIntersection(NodeID nid,
std::size_t number = 0;
if (canBeDiscretized)
{
if(util::guidance::BearingClass::getDiscreteBearing(turns.back().bearing) <
util::guidance::BearingClass::getDiscreteBearing(turns.front().bearing))
{
turns.insert(turns.begin(), turns.back());
turns.pop_back();
}
for (const auto turn : turns)
{
if (turn.entry_allowed)

View File

@ -589,9 +589,12 @@ int Storage::Run()
shared_layout_ptr->SetBlockSize<BearingClassID>(SharedDataLayout::BEARING_CLASSID,
bearing_class_id_table.size());
if (!bearing_class_id_table.empty())
{
auto bearing_id_ptr = shared_layout_ptr->GetBlockPtr<BearingClassID, true>(
shared_memory_ptr, SharedDataLayout::BEARING_CLASSID);
std::copy(bearing_class_id_table.begin(), bearing_class_id_table.end(), bearing_id_ptr);
}
unsigned bearing_blocks = 0;
intersection_stream.read((char *)&bearing_blocks, sizeof(unsigned));
@ -603,19 +606,19 @@ int Storage::Run()
shared_layout_ptr->SetBlockSize<typename util::RangeTable<16, true>::BlockT>(
SharedDataLayout::BEARING_BLOCKS, bearing_blocks);
unsigned *bearing_offsets_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
shared_memory_ptr, SharedDataLayout::BEARING_OFFSETS);
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::BEARING_OFFSETS) > 0)
{
unsigned *bearing_offsets_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
shared_memory_ptr, SharedDataLayout::BEARING_OFFSETS);
intersection_stream.read(
reinterpret_cast<char *>(bearing_offsets_ptr),
shared_layout_ptr->GetBlockSize(SharedDataLayout::BEARING_OFFSETS));
}
unsigned *bearing_blocks_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
shared_memory_ptr, SharedDataLayout::BEARING_BLOCKS);
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::BEARING_BLOCKS) > 0)
{
unsigned *bearing_blocks_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
shared_memory_ptr, SharedDataLayout::BEARING_BLOCKS);
intersection_stream.read(
reinterpret_cast<char *>(bearing_blocks_ptr),
shared_layout_ptr->GetBlockSize(SharedDataLayout::BEARING_BLOCKS));
@ -629,9 +632,12 @@ int Storage::Run()
sizeof(bearing_class_table[0]) * num_bearings);
shared_layout_ptr->SetBlockSize<DiscreteBearing>(SharedDataLayout::BEARING_VALUES,
num_bearings);
if (!bearing_class_table.empty())
{
auto bearing_class_ptr = shared_layout_ptr->GetBlockPtr<DiscreteBearing, true>(
shared_memory_ptr, SharedDataLayout::BEARING_VALUES);
std::copy(bearing_class_table.begin(), bearing_class_table.end(), bearing_class_ptr);
}
if (!static_cast<bool>(intersection_stream))
throw util::exception("Failed to read from " + config.names_data_path.string());
@ -642,10 +648,13 @@ int Storage::Run()
shared_layout_ptr->SetBlockSize<util::guidance::EntryClass>(SharedDataLayout::ENTRY_CLASS,
entry_class_table.size());
if (!entry_class_table.empty())
{
auto entry_class_ptr = shared_layout_ptr->GetBlockPtr<util::guidance::EntryClass, true>(
shared_memory_ptr, SharedDataLayout::ENTRY_CLASS);
std::copy(entry_class_table.begin(), entry_class_table.end(), entry_class_ptr);
}
}
data_timestamp_ptr->layout = layout_region;
data_timestamp_ptr->data = data_region;

View File

@ -56,29 +56,36 @@ BOOST_AUTO_TEST_CASE(test_route_same_coordinates_fixture)
{{"distance", 0.},
{"duration", 0.},
{"summary", ""},
{"steps", json::Array{{json::Object{{{"duration", 0.},
{"steps",
json::Array{{{json::Object{{{"duration", 0.},
{"distance", 0.},
{"geometry", "yw_jGupkl@??"},
{"name", "Boulevard du Larvotto"},
{"mode", "driving"},
{"maneuver", json::Object{{
{"type", "depart"},
{"location", location},
{"bearing_before", 0.},
{"bearing_after", 0.},
}}}}},
}}},
{"intersections",
json::Array{{json::Object{
{{"location", location},
{"bearings", json::Array{{0, 180}}},
{"entry", json::Array{{"true", "true"}}},
{"out", 0}}}}}}}}},
json::Object{{{"duration", 0.},
{"distance", 0.},
{"geometry", "yw_jGupkl@"},
{"name", "Boulevard du Larvotto"},
{"mode", "driving"},
{"maneuver", json::Object{{
{"type", "arrive"},
{"location", location},
{"bearing_before", 0.},
{"bearing_after", 0.},
}}}}}}}}}}}}}}}}}}}};
{"maneuver", json::Object{{{"type", "arrive"}}}},
{"intersections",
json::Array{{json::Object{
{{"location", location},
{"bearings", json::Array{{0, 180}}},
{"entry", json::Array{{"true", "true"}}},
{"in", 1}}}}}}
}}}}}}}}}}}}}}}}};
CHECK_EQUAL_JSON(reference, result);
}
@ -161,6 +168,8 @@ BOOST_AUTO_TEST_CASE(test_route_same_coordinates)
const auto &steps = leg_object.values.at("steps").get<json::Array>().values;
BOOST_CHECK(!steps.empty());
std::size_t step_count = 0;
for (const auto &step : steps)
{
const auto &step_object = step.get<json::Object>();
@ -185,25 +194,47 @@ BOOST_AUTO_TEST_CASE(test_route_same_coordinates)
const auto &maneuver = step_object.values.at("maneuver").get<json::Object>().values;
const auto location = maneuver.at("location").get<json::Array>().values;
const auto type = maneuver.at("type").get<json::String>().value;
BOOST_CHECK(!type.empty());
const auto &intersections =
step_object.values.at("intersections").get<json::Array>().values;
for (auto &intersection : intersections)
{
const auto &intersection_object = intersection.get<json::Object>().values;
const auto location = intersection_object.at("location").get<json::Array>().values;
const auto longitude = location[0].get<json::Number>().value;
const auto latitude = location[1].get<json::Number>().value;
BOOST_CHECK(longitude >= -180. && longitude <= 180.);
BOOST_CHECK(latitude >= -90. && latitude <= 90.);
const auto bearing_before = maneuver.at("bearing_before").get<json::Number>().value;
const auto bearing_after = maneuver.at("bearing_after").get<json::Number>().value;
BOOST_CHECK(bearing_before >= 0. && bearing_before <= 360.);
BOOST_CHECK(bearing_after >= 0. && bearing_after <= 360.);
const auto &bearings = intersection_object.at("bearings").get<json::Array>().values;
BOOST_CHECK(!bearings.empty());
const auto &entries = intersection_object.at("entry").get<json::Array>().values;
BOOST_CHECK(bearings.size() == entries.size());
const auto type = maneuver.at("type").get<json::String>().value;
BOOST_CHECK(!type.empty());
for( const auto bearing : bearings )
BOOST_CHECK( 0. <= bearing.get<json::Number>().value && bearing.get<json::Number>().value <= 360. );
if( step_count > 0 )
{
const auto in = intersection_object.at("in").get<json::Number>().value;
BOOST_CHECK(in < bearings.size());
}
if( step_count + 1 < steps.size() )
{
const auto out = intersection_object.at("out").get<json::Number>().value;
BOOST_CHECK(out < bearings.size());
}
}
// modifier is optional
// TODO(daniel-j-h):
// exit is optional
// TODO(daniel-j-h):
++step_count;
}
}
}

View File

@ -3,9 +3,12 @@
// implements all data storage when shared memory _IS_ used
#include "extractor/guidance/turn_instruction.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "contractor/query_edge.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/typedefs.hpp"
namespace osrm
{
@ -171,6 +174,27 @@ class MockDataFacade final : public engine::datafacade::BaseDataFacade
std::size_t GetCoreSize() const override { return 0; }
std::string GetTimestamp() const override { return ""; }
bool GetContinueStraightDefault() const override { return true; }
BearingClassID GetBearingClassID(const NodeID /*id*/) const override { return 0; };
EntryClassID GetEntryClassID(const EdgeID /*id*/) const override { return 0; }
util::guidance::BearingClass GetBearingClass(const BearingClassID /*bearing_class_id*/) const override
{
util::guidance::BearingClass result;
result.add(0);
result.add(90);
result.add(180);
result.add(270);
return result;
}
util::guidance::EntryClass GetEntryClass(const EntryClassID /*entry_class_id*/) const override
{
util::guidance::EntryClass result;
result.activate(1);
result.activate(2);
result.activate(3);
return result;
}
};
} // ns test
} // ns osrm