Skip to content

Commit 521636c

Browse files
deniskoronchikTheMarex
authored andcommitted
Work on forward/backward ref's support
1 parent 6172dff commit 521636c

File tree

7 files changed

+168
-116
lines changed

7 files changed

+168
-116
lines changed

features/car/route_relations.feature

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -74,28 +74,28 @@ Feature: Car - route relations
7474
| c,d | eastbound,eastbound | I 80 $east; CO 93 $east,I 80 $east; CO 93 $east |
7575

7676

77-
# Scenario: Forward/backward assignment on non-divided roads with role direction tag
78-
# Given the node map
79-
# """
80-
# a----------------b
81-
# """
82-
#
83-
# And the ways
84-
# | nodes | name | highway | ref | oneway |
85-
# | ab | mainroad | motorway | I 80 | no |
86-
#
87-
# And the relations
88-
# | type | direction | way:forward | route | ref | network |
89-
# | route | west | ab | road | 80 | US:I |
90-
#
91-
# And the relations
92-
# | type | direction | way:backward | route | ref | network |
93-
# | route | east | ab | road | 80 | US:I |
94-
#
95-
# When I route I should get
96-
# | waypoints | route | ref |
97-
# | b,a | mainroad,mainroad | I 80 $west,I 80 $west |
98-
# | a,b | mainroad,mainroad | I 80 $east,I 80 $east |
77+
Scenario: Forward/backward assignment on non-divided roads with role direction tag
78+
Given the node map
79+
"""
80+
a----------------b
81+
"""
82+
83+
And the ways
84+
| nodes | name | highway | ref | oneway |
85+
| ab | mainroad | motorway | I 80 | no |
86+
87+
And the relations
88+
| type | direction | way:forward | route | ref | network |
89+
| route | west | ab | road | 80 | US:I |
90+
91+
And the relations
92+
| type | direction | way:backward | route | ref | network |
93+
| route | east | ab | road | 80 | US:I |
94+
95+
When I route I should get
96+
| waypoints | route | ref |
97+
| a,b | mainroad,mainroad | I 80 $west,I 80 $west |
98+
| b,a | mainroad,mainroad | I 80 $east,I 80 $east |
9999

100100

101101
Scenario: Conflict between role and direction

include/extractor/extraction_way.hpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ struct ExtractionWay
4747
duration = -1;
4848
weight = -1;
4949
name.clear();
50-
ref.clear();
50+
forward_ref.clear();
51+
backward_ref.clear();
5152
pronunciation.clear();
5253
destinations.clear();
5354
exits.clear();
@@ -67,8 +68,10 @@ struct ExtractionWay
6768
// wrappers to allow assigning nil (nullptr) to string values
6869
void SetName(const char *value) { detail::maybeSetString(name, value); }
6970
const char *GetName() const { return name.c_str(); }
70-
void SetRef(const char *value) { detail::maybeSetString(ref, value); }
71-
const char *GetRef() const { return ref.c_str(); }
71+
void SetForwardRef(const char *value) { detail::maybeSetString(forward_ref, value); }
72+
const char *GetForwardRef() const { return forward_ref.c_str(); }
73+
void SetBackwardRef(const char *value) { detail::maybeSetString(backward_ref, value); }
74+
const char *GetBackwardRef() const { return backward_ref.c_str(); }
7275
void SetDestinations(const char *value) { detail::maybeSetString(destinations, value); }
7376
const char *GetDestinations() const { return destinations.c_str(); }
7477
void SetExits(const char *value) { detail::maybeSetString(exits, value); }
@@ -101,7 +104,8 @@ struct ExtractionWay
101104
// weight of the whole way in both directions
102105
double weight;
103106
std::string name;
104-
std::string ref;
107+
std::string forward_ref;
108+
std::string backward_ref;
105109
std::string pronunciation;
106110
std::string destinations;
107111
std::string exits;

include/extractor/extractor_callbacks.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ class ExtractorCallbacks
6363
// actually maps to name ids
6464
using MapKey = std::tuple<std::string, std::string, std::string, std::string, std::string>;
6565
using MapVal = unsigned;
66-
std::unordered_map<MapKey, MapVal> string_map;
66+
using StringMap = std::unordered_map<MapKey, MapVal>;
67+
StringMap string_map;
6768
ExtractionContainers &external_memory;
6869
std::unordered_map<std::string, ClassData> &classes_map;
6970
guidance::LaneDescriptionMap &lane_description_map;

profiles/car.lua

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -403,35 +403,7 @@ function process_way(profile, way, result, relations)
403403

404404
WayHandlers.run(profile, way, result, data, handlers, relations)
405405

406-
local parsed_rel_list = {}
407-
local rel_id_list = relations:get_relations(way)
408-
for i, rel_id in ipairs(rel_id_list) do
409-
local rel = relations:relation(rel_id)
410-
parsed_rel_list[i] = Relations.parse_route_relation(rel, way, relations)
411-
end
412-
413-
-- now process relations data
414-
local matched_refs = nil;
415-
if result.ref then
416-
local match_res = Relations.match_to_ref(parsed_rel_list, result.ref)
417-
418-
local ref = ''
419-
for _, m in pairs(match_res) do
420-
if ref ~= '' then
421-
ref = ref .. '; '
422-
end
423-
424-
if m.dir then
425-
ref = ref .. m.ref .. ' $' .. m.dir
426-
else
427-
ref = ref .. m.ref
428-
end
429-
end
430-
431-
-- print(result.name, ref)
432-
433-
result.ref = ref
434-
end
406+
Relations.process_way_refs(way, relations, result)
435407
end
436408

437409
function process_turn(profile, turn)

profiles/lib/relations.lua

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function Relations.match_to_ref(relations, ref)
4141
local result_match = {}
4242
local order = {}
4343
for i, r in ipairs(references) do
44-
result_match[r] = false
44+
result_match[r] = { forward = nil, backward = nil }
4545
order[i] = r
4646
end
4747

@@ -81,7 +81,19 @@ function Relations.match_to_ref(relations, ref)
8181
find_best(ref_scores)
8282

8383
if best_ref then
84-
result_match[best_ref] = direction
84+
local result_direction = result_match[best_ref]
85+
86+
local is_forward = rel["route_forward"]
87+
if is_forward == nil then
88+
result_direction.forward = direction
89+
result_direction.backward = direction
90+
elseif is_forward == true then
91+
result_direction.forward = direction
92+
else
93+
result_direction.backward = direction
94+
end
95+
96+
result_match[best_ref] = result_direction
8597
end
8698
end
8799

@@ -182,7 +194,6 @@ function Relations.parse_route_relation(rel, way, relations)
182194
local super_dir = get_direction_from_superrel(rel, relations)
183195

184196
-- check if there are data error
185-
186197
if (result_direction ~= nil) and (super_dir ~= nil) and (result_direction ~= super_dir) then
187198
print('ERROR: conflicting relation directions found for way ' .. way:id() ..
188199
' relation direction is ' .. result_direction .. ' superrelation direction is ' .. super_dir)
@@ -192,11 +203,59 @@ function Relations.parse_route_relation(rel, way, relations)
192203
end
193204

194205
result['route_direction'] = result_direction
206+
207+
if role == 'forward' then
208+
result['route_forward'] = true
209+
elseif role == 'backward' then
210+
result['route_forward'] = false
211+
else
212+
result['route_forward'] = nil
213+
end
214+
195215
add_extra_data(m)
196216
end
197217

198-
199218
return result
200219
end
201220

221+
function Relations.process_way_refs(way, relations, result)
222+
local parsed_rel_list = {}
223+
local rel_id_list = relations:get_relations(way)
224+
for i, rel_id in ipairs(rel_id_list) do
225+
local rel = relations:relation(rel_id)
226+
parsed_rel_list[i] = Relations.parse_route_relation(rel, way, relations)
227+
end
228+
229+
-- now process relations data
230+
local matched_refs = nil;
231+
if result.ref then
232+
local match_res = Relations.match_to_ref(parsed_rel_list, result.ref)
233+
234+
function gen_ref(is_forward)
235+
local ref = ''
236+
for _, m in pairs(match_res) do
237+
if ref ~= '' then
238+
ref = ref .. '; '
239+
end
240+
241+
local dir = m.dir.forward
242+
if is_forward == false then
243+
dir = m.dir.backward
244+
end
245+
246+
if dir then
247+
ref = ref .. m.ref .. ' $' .. dir
248+
else
249+
ref = ref .. m.ref
250+
end
251+
end
252+
253+
return ref
254+
end
255+
256+
result.forward_ref = gen_ref(true)
257+
result.backward_ref = gen_ref(false)
258+
end
259+
end
260+
202261
return Relations

src/extractor/extractor_callbacks.cpp

Lines changed: 62 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -318,57 +318,64 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
318318
road_classification.SetNumberOfLanes(std::max(road_deduced_num_lanes, // len(turn:lanes)
319319
road_classification.GetNumberOfLanes()));
320320

321-
// Get the unique identifier for the street name, destination, and ref
322-
const auto name_iterator = string_map.find(MapKey(parsed_way.name,
323-
parsed_way.destinations,
324-
parsed_way.ref,
325-
parsed_way.pronunciation,
326-
parsed_way.exits));
327-
NameID name_id = EMPTY_NAMEID;
328-
if (string_map.end() == name_iterator)
329-
{
330-
// name_offsets has a sentinel element with the total name data size
331-
// take the sentinels index as the name id of the new name data pack
332-
// (name [name_id], destination [+1], pronunciation [+2], ref [+3], exits [+4])
333-
name_id = external_memory.name_offsets.size() - 1;
334-
335-
std::copy(parsed_way.name.begin(),
336-
parsed_way.name.end(),
337-
std::back_inserter(external_memory.name_char_data));
338-
external_memory.name_offsets.push_back(external_memory.name_char_data.size());
339-
340-
std::copy(parsed_way.destinations.begin(),
341-
parsed_way.destinations.end(),
342-
std::back_inserter(external_memory.name_char_data));
343-
external_memory.name_offsets.push_back(external_memory.name_char_data.size());
344-
345-
std::copy(parsed_way.pronunciation.begin(),
346-
parsed_way.pronunciation.end(),
347-
std::back_inserter(external_memory.name_char_data));
348-
external_memory.name_offsets.push_back(external_memory.name_char_data.size());
349-
350-
std::copy(parsed_way.ref.begin(),
351-
parsed_way.ref.end(),
352-
std::back_inserter(external_memory.name_char_data));
353-
external_memory.name_offsets.push_back(external_memory.name_char_data.size());
354-
355-
std::copy(parsed_way.exits.begin(),
356-
parsed_way.exits.end(),
357-
std::back_inserter(external_memory.name_char_data));
358-
external_memory.name_offsets.push_back(external_memory.name_char_data.size());
359-
360-
auto k = MapKey{parsed_way.name,
361-
parsed_way.destinations,
362-
parsed_way.ref,
363-
parsed_way.pronunciation,
364-
parsed_way.exits};
365-
auto v = MapVal{name_id};
366-
string_map.emplace(std::move(k), std::move(v));
367-
}
368-
else
369-
{
370-
name_id = name_iterator->second;
371-
}
321+
const auto GetNameID = [this, &parsed_way](bool is_forward) -> NameID {
322+
const std::string &ref = is_forward ? parsed_way.forward_ref : parsed_way.backward_ref;
323+
// Get the unique identifier for the street name, destination, and ref
324+
const auto name_iterator = string_map.find(MapKey(parsed_way.name,
325+
parsed_way.destinations,
326+
ref,
327+
parsed_way.pronunciation,
328+
parsed_way.exits));
329+
330+
NameID name_id = EMPTY_NAMEID;
331+
if (string_map.end() == name_iterator)
332+
{
333+
// name_offsets has a sentinel element with the total name data size
334+
// take the sentinels index as the name id of the new name data pack
335+
// (name [name_id], destination [+1], pronunciation [+2], ref [+3], exits [+4])
336+
name_id = external_memory.name_offsets.size() - 1;
337+
338+
std::copy(parsed_way.name.begin(),
339+
parsed_way.name.end(),
340+
std::back_inserter(external_memory.name_char_data));
341+
external_memory.name_offsets.push_back(external_memory.name_char_data.size());
342+
343+
std::copy(parsed_way.destinations.begin(),
344+
parsed_way.destinations.end(),
345+
std::back_inserter(external_memory.name_char_data));
346+
external_memory.name_offsets.push_back(external_memory.name_char_data.size());
347+
348+
std::copy(parsed_way.pronunciation.begin(),
349+
parsed_way.pronunciation.end(),
350+
std::back_inserter(external_memory.name_char_data));
351+
external_memory.name_offsets.push_back(external_memory.name_char_data.size());
352+
353+
std::copy(ref.begin(), ref.end(), std::back_inserter(external_memory.name_char_data));
354+
external_memory.name_offsets.push_back(external_memory.name_char_data.size());
355+
356+
std::copy(parsed_way.exits.begin(),
357+
parsed_way.exits.end(),
358+
std::back_inserter(external_memory.name_char_data));
359+
external_memory.name_offsets.push_back(external_memory.name_char_data.size());
360+
361+
auto k = MapKey{parsed_way.name,
362+
parsed_way.destinations,
363+
ref,
364+
parsed_way.pronunciation,
365+
parsed_way.exits};
366+
auto v = MapVal{name_id};
367+
string_map.emplace(std::move(k), std::move(v));
368+
}
369+
else
370+
{
371+
name_id = name_iterator->second;
372+
}
373+
374+
return name_id;
375+
};
376+
377+
const NameID forward_name_id = GetNameID(true);
378+
const NameID backward_name_id = GetNameID(false);
372379

373380
const bool in_forward_direction =
374381
(parsed_way.forward_speed > 0 || parsed_way.forward_rate > 0 || parsed_way.duration > 0 ||
@@ -386,12 +393,13 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
386393
(force_split_edges || (parsed_way.forward_rate != parsed_way.backward_rate) ||
387394
(parsed_way.forward_speed != parsed_way.backward_speed) ||
388395
(parsed_way.forward_travel_mode != parsed_way.backward_travel_mode) ||
389-
(turn_lane_id_forward != turn_lane_id_backward) || (forward_classes != backward_classes));
396+
(turn_lane_id_forward != turn_lane_id_backward) || (forward_classes != backward_classes) ||
397+
(parsed_way.forward_ref != parsed_way.backward_ref));
390398

391399
if (in_forward_direction)
392400
{ // add (forward) segments or (forward,backward) for non-split edges in backward direction
393401
const auto annotation_data_id = external_memory.all_edges_annotation_data_list.size();
394-
external_memory.all_edges_annotation_data_list.push_back({name_id,
402+
external_memory.all_edges_annotation_data_list.push_back({forward_name_id,
395403
turn_lane_id_forward,
396404
forward_classes,
397405
parsed_way.forward_travel_mode,
@@ -424,7 +432,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
424432
if (in_backward_direction && (!in_forward_direction || split_edge))
425433
{ // add (backward) segments for split edges or not in forward direction
426434
const auto annotation_data_id = external_memory.all_edges_annotation_data_list.size();
427-
external_memory.all_edges_annotation_data_list.push_back({name_id,
435+
external_memory.all_edges_annotation_data_list.push_back({backward_name_id,
428436
turn_lane_id_backward,
429437
backward_classes,
430438
parsed_way.backward_travel_mode,

src/extractor/scripting_environment_lua.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,16 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
369369
&ExtractionWay::backward_rate,
370370
"name",
371371
sol::property(&ExtractionWay::GetName, &ExtractionWay::SetName),
372-
"ref",
373-
sol::property(&ExtractionWay::GetRef, &ExtractionWay::SetRef),
372+
"ref", // backward compatibility
373+
sol::property(&ExtractionWay::GetForwardRef,
374+
[](ExtractionWay &way, const char *ref) {
375+
way.SetForwardRef(ref);
376+
way.SetBackwardRef(ref);
377+
}),
378+
"forward_ref",
379+
sol::property(&ExtractionWay::GetForwardRef, &ExtractionWay::SetForwardRef),
380+
"backward_ref",
381+
sol::property(&ExtractionWay::GetBackwardRef, &ExtractionWay::SetBackwardRef),
374382
"pronunciation",
375383
sol::property(&ExtractionWay::GetPronunciation, &ExtractionWay::SetPronunciation),
376384
"destinations",

0 commit comments

Comments
 (0)