Work on forward/backward ref's support
This commit is contained in:
parent
37774a331a
commit
895f072425
@ -74,28 +74,28 @@ Feature: Car - route relations
|
||||
| c,d | eastbound,eastbound | I 80 $east; CO 93 $east,I 80 $east; CO 93 $east |
|
||||
|
||||
|
||||
# Scenario: Forward/backward assignment on non-divided roads with role direction tag
|
||||
# Given the node map
|
||||
# """
|
||||
# a----------------b
|
||||
# """
|
||||
#
|
||||
# And the ways
|
||||
# | nodes | name | highway | ref | oneway |
|
||||
# | ab | mainroad | motorway | I 80 | no |
|
||||
#
|
||||
# And the relations
|
||||
# | type | direction | way:forward | route | ref | network |
|
||||
# | route | west | ab | road | 80 | US:I |
|
||||
#
|
||||
# And the relations
|
||||
# | type | direction | way:backward | route | ref | network |
|
||||
# | route | east | ab | road | 80 | US:I |
|
||||
#
|
||||
# When I route I should get
|
||||
# | waypoints | route | ref |
|
||||
# | b,a | mainroad,mainroad | I 80 $west,I 80 $west |
|
||||
# | a,b | mainroad,mainroad | I 80 $east,I 80 $east |
|
||||
Scenario: Forward/backward assignment on non-divided roads with role direction tag
|
||||
Given the node map
|
||||
"""
|
||||
a----------------b
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | name | highway | ref | oneway |
|
||||
| ab | mainroad | motorway | I 80 | no |
|
||||
|
||||
And the relations
|
||||
| type | direction | way:forward | route | ref | network |
|
||||
| route | west | ab | road | 80 | US:I |
|
||||
|
||||
And the relations
|
||||
| type | direction | way:backward | route | ref | network |
|
||||
| route | east | ab | road | 80 | US:I |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | ref |
|
||||
| a,b | mainroad,mainroad | I 80 $west,I 80 $west |
|
||||
| b,a | mainroad,mainroad | I 80 $east,I 80 $east |
|
||||
|
||||
|
||||
Scenario: Conflict between role and direction
|
||||
|
@ -47,7 +47,8 @@ struct ExtractionWay
|
||||
duration = -1;
|
||||
weight = -1;
|
||||
name.clear();
|
||||
ref.clear();
|
||||
forward_ref.clear();
|
||||
backward_ref.clear();
|
||||
pronunciation.clear();
|
||||
destinations.clear();
|
||||
exits.clear();
|
||||
@ -67,8 +68,10 @@ struct ExtractionWay
|
||||
// wrappers to allow assigning nil (nullptr) to string values
|
||||
void SetName(const char *value) { detail::maybeSetString(name, value); }
|
||||
const char *GetName() const { return name.c_str(); }
|
||||
void SetRef(const char *value) { detail::maybeSetString(ref, value); }
|
||||
const char *GetRef() const { return ref.c_str(); }
|
||||
void SetForwardRef(const char *value) { detail::maybeSetString(forward_ref, value); }
|
||||
const char *GetForwardRef() const { return forward_ref.c_str(); }
|
||||
void SetBackwardRef(const char *value) { detail::maybeSetString(backward_ref, value); }
|
||||
const char *GetBackwardRef() const { return backward_ref.c_str(); }
|
||||
void SetDestinations(const char *value) { detail::maybeSetString(destinations, value); }
|
||||
const char *GetDestinations() const { return destinations.c_str(); }
|
||||
void SetExits(const char *value) { detail::maybeSetString(exits, value); }
|
||||
@ -101,7 +104,8 @@ struct ExtractionWay
|
||||
// weight of the whole way in both directions
|
||||
double weight;
|
||||
std::string name;
|
||||
std::string ref;
|
||||
std::string forward_ref;
|
||||
std::string backward_ref;
|
||||
std::string pronunciation;
|
||||
std::string destinations;
|
||||
std::string exits;
|
||||
|
@ -63,7 +63,8 @@ class ExtractorCallbacks
|
||||
// actually maps to name ids
|
||||
using MapKey = std::tuple<std::string, std::string, std::string, std::string, std::string>;
|
||||
using MapVal = unsigned;
|
||||
std::unordered_map<MapKey, MapVal> string_map;
|
||||
using StringMap = std::unordered_map<MapKey, MapVal>;
|
||||
StringMap string_map;
|
||||
ExtractionContainers &external_memory;
|
||||
std::unordered_map<std::string, ClassData> &classes_map;
|
||||
guidance::LaneDescriptionMap &lane_description_map;
|
||||
|
@ -402,35 +402,7 @@ function process_way(profile, way, result, relations)
|
||||
|
||||
WayHandlers.run(profile, way, result, data, handlers, relations)
|
||||
|
||||
local parsed_rel_list = {}
|
||||
local rel_id_list = relations:get_relations(way)
|
||||
for i, rel_id in ipairs(rel_id_list) do
|
||||
local rel = relations:relation(rel_id)
|
||||
parsed_rel_list[i] = Relations.parse_route_relation(rel, way, relations)
|
||||
end
|
||||
|
||||
-- now process relations data
|
||||
local matched_refs = nil;
|
||||
if result.ref then
|
||||
local match_res = Relations.match_to_ref(parsed_rel_list, result.ref)
|
||||
|
||||
local ref = ''
|
||||
for _, m in pairs(match_res) do
|
||||
if ref ~= '' then
|
||||
ref = ref .. '; '
|
||||
end
|
||||
|
||||
if m.dir then
|
||||
ref = ref .. m.ref .. ' $' .. m.dir
|
||||
else
|
||||
ref = ref .. m.ref
|
||||
end
|
||||
end
|
||||
|
||||
-- print(result.name, ref)
|
||||
|
||||
result.ref = ref
|
||||
end
|
||||
Relations.process_way_refs(way, relations, result)
|
||||
end
|
||||
|
||||
function process_turn(profile, turn)
|
||||
|
@ -41,7 +41,7 @@ function Relations.match_to_ref(relations, ref)
|
||||
local result_match = {}
|
||||
local order = {}
|
||||
for i, r in ipairs(references) do
|
||||
result_match[r] = false
|
||||
result_match[r] = { forward = nil, backward = nil }
|
||||
order[i] = r
|
||||
end
|
||||
|
||||
@ -81,7 +81,19 @@ function Relations.match_to_ref(relations, ref)
|
||||
find_best(ref_scores)
|
||||
|
||||
if best_ref then
|
||||
result_match[best_ref] = direction
|
||||
local result_direction = result_match[best_ref]
|
||||
|
||||
local is_forward = rel["route_forward"]
|
||||
if is_forward == nil then
|
||||
result_direction.forward = direction
|
||||
result_direction.backward = direction
|
||||
elseif is_forward == true then
|
||||
result_direction.forward = direction
|
||||
else
|
||||
result_direction.backward = direction
|
||||
end
|
||||
|
||||
result_match[best_ref] = result_direction
|
||||
end
|
||||
end
|
||||
|
||||
@ -182,7 +194,6 @@ function Relations.parse_route_relation(rel, way, relations)
|
||||
local super_dir = get_direction_from_superrel(rel, relations)
|
||||
|
||||
-- check if there are data error
|
||||
|
||||
if (result_direction ~= nil) and (super_dir ~= nil) and (result_direction ~= super_dir) then
|
||||
print('ERROR: conflicting relation directions found for way ' .. way:id() ..
|
||||
' relation direction is ' .. result_direction .. ' superrelation direction is ' .. super_dir)
|
||||
@ -192,11 +203,59 @@ function Relations.parse_route_relation(rel, way, relations)
|
||||
end
|
||||
|
||||
result['route_direction'] = result_direction
|
||||
add_extra_data(m)
|
||||
|
||||
if role == 'forward' then
|
||||
result['route_forward'] = true
|
||||
elseif role == 'backward' then
|
||||
result['route_forward'] = false
|
||||
else
|
||||
result['route_forward'] = nil
|
||||
end
|
||||
|
||||
add_extra_data(m)
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
function Relations.process_way_refs(way, relations, result)
|
||||
local parsed_rel_list = {}
|
||||
local rel_id_list = relations:get_relations(way)
|
||||
for i, rel_id in ipairs(rel_id_list) do
|
||||
local rel = relations:relation(rel_id)
|
||||
parsed_rel_list[i] = Relations.parse_route_relation(rel, way, relations)
|
||||
end
|
||||
|
||||
-- now process relations data
|
||||
local matched_refs = nil;
|
||||
if result.ref then
|
||||
local match_res = Relations.match_to_ref(parsed_rel_list, result.ref)
|
||||
|
||||
function gen_ref(is_forward)
|
||||
local ref = ''
|
||||
for _, m in pairs(match_res) do
|
||||
if ref ~= '' then
|
||||
ref = ref .. '; '
|
||||
end
|
||||
|
||||
local dir = m.dir.forward
|
||||
if is_forward == false then
|
||||
dir = m.dir.backward
|
||||
end
|
||||
|
||||
if dir then
|
||||
ref = ref .. m.ref .. ' $' .. dir
|
||||
else
|
||||
ref = ref .. m.ref
|
||||
end
|
||||
end
|
||||
|
||||
return ref
|
||||
end
|
||||
|
||||
result.forward_ref = gen_ref(true)
|
||||
result.backward_ref = gen_ref(false)
|
||||
end
|
||||
end
|
||||
|
||||
return Relations
|
@ -318,12 +318,15 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
road_classification.SetNumberOfLanes(std::max(road_deduced_num_lanes, // len(turn:lanes)
|
||||
road_classification.GetNumberOfLanes()));
|
||||
|
||||
const auto GetNameID = [this, &parsed_way](bool is_forward) -> NameID {
|
||||
const std::string &ref = is_forward ? parsed_way.forward_ref : parsed_way.backward_ref;
|
||||
// Get the unique identifier for the street name, destination, and ref
|
||||
const auto name_iterator = string_map.find(MapKey(parsed_way.name,
|
||||
parsed_way.destinations,
|
||||
parsed_way.ref,
|
||||
ref,
|
||||
parsed_way.pronunciation,
|
||||
parsed_way.exits));
|
||||
|
||||
NameID name_id = EMPTY_NAMEID;
|
||||
if (string_map.end() == name_iterator)
|
||||
{
|
||||
@ -347,9 +350,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
std::back_inserter(external_memory.name_char_data));
|
||||
external_memory.name_offsets.push_back(external_memory.name_char_data.size());
|
||||
|
||||
std::copy(parsed_way.ref.begin(),
|
||||
parsed_way.ref.end(),
|
||||
std::back_inserter(external_memory.name_char_data));
|
||||
std::copy(ref.begin(), ref.end(), std::back_inserter(external_memory.name_char_data));
|
||||
external_memory.name_offsets.push_back(external_memory.name_char_data.size());
|
||||
|
||||
std::copy(parsed_way.exits.begin(),
|
||||
@ -359,7 +360,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
|
||||
auto k = MapKey{parsed_way.name,
|
||||
parsed_way.destinations,
|
||||
parsed_way.ref,
|
||||
ref,
|
||||
parsed_way.pronunciation,
|
||||
parsed_way.exits};
|
||||
auto v = MapVal{name_id};
|
||||
@ -370,6 +371,12 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
name_id = name_iterator->second;
|
||||
}
|
||||
|
||||
return name_id;
|
||||
};
|
||||
|
||||
const NameID forward_name_id = GetNameID(true);
|
||||
const NameID backward_name_id = GetNameID(false);
|
||||
|
||||
const bool in_forward_direction =
|
||||
(parsed_way.forward_speed > 0 || parsed_way.forward_rate > 0 || parsed_way.duration > 0 ||
|
||||
parsed_way.weight > 0) &&
|
||||
@ -386,12 +393,13 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
(force_split_edges || (parsed_way.forward_rate != parsed_way.backward_rate) ||
|
||||
(parsed_way.forward_speed != parsed_way.backward_speed) ||
|
||||
(parsed_way.forward_travel_mode != parsed_way.backward_travel_mode) ||
|
||||
(turn_lane_id_forward != turn_lane_id_backward) || (forward_classes != backward_classes));
|
||||
(turn_lane_id_forward != turn_lane_id_backward) || (forward_classes != backward_classes) ||
|
||||
(parsed_way.forward_ref != parsed_way.backward_ref));
|
||||
|
||||
if (in_forward_direction)
|
||||
{ // add (forward) segments or (forward,backward) for non-split edges in backward direction
|
||||
const auto annotation_data_id = external_memory.all_edges_annotation_data_list.size();
|
||||
external_memory.all_edges_annotation_data_list.push_back({name_id,
|
||||
external_memory.all_edges_annotation_data_list.push_back({forward_name_id,
|
||||
turn_lane_id_forward,
|
||||
forward_classes,
|
||||
parsed_way.forward_travel_mode,
|
||||
@ -424,7 +432,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
if (in_backward_direction && (!in_forward_direction || split_edge))
|
||||
{ // add (backward) segments for split edges or not in forward direction
|
||||
const auto annotation_data_id = external_memory.all_edges_annotation_data_list.size();
|
||||
external_memory.all_edges_annotation_data_list.push_back({name_id,
|
||||
external_memory.all_edges_annotation_data_list.push_back({backward_name_id,
|
||||
turn_lane_id_backward,
|
||||
backward_classes,
|
||||
parsed_way.backward_travel_mode,
|
||||
|
@ -369,8 +369,16 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
&ExtractionWay::backward_rate,
|
||||
"name",
|
||||
sol::property(&ExtractionWay::GetName, &ExtractionWay::SetName),
|
||||
"ref",
|
||||
sol::property(&ExtractionWay::GetRef, &ExtractionWay::SetRef),
|
||||
"ref", // backward compatibility
|
||||
sol::property(&ExtractionWay::GetForwardRef,
|
||||
[](ExtractionWay &way, const char *ref) {
|
||||
way.SetForwardRef(ref);
|
||||
way.SetBackwardRef(ref);
|
||||
}),
|
||||
"forward_ref",
|
||||
sol::property(&ExtractionWay::GetForwardRef, &ExtractionWay::SetForwardRef),
|
||||
"backward_ref",
|
||||
sol::property(&ExtractionWay::GetBackwardRef, &ExtractionWay::SetBackwardRef),
|
||||
"pronunciation",
|
||||
sol::property(&ExtractionWay::GetPronunciation, &ExtractionWay::SetPronunciation),
|
||||
"destinations",
|
||||
|
Loading…
Reference in New Issue
Block a user