From fc9a89ea8b36a2284602492416749a3118121f6d Mon Sep 17 00:00:00 2001 From: Denis Koronchik Date: Tue, 3 Oct 2017 19:38:33 +0300 Subject: [PATCH] Support some cases for supperrelations in car.lua --- profiles/car.lua | 2 +- profiles/lib/relations.lua | 70 ++++++++++++++++++--- src/extractor/scripting_environment_lua.cpp | 42 ++++++------- 3 files changed, 81 insertions(+), 33 deletions(-) diff --git a/profiles/car.lua b/profiles/car.lua index 2193af261..a6d369a72 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -406,7 +406,7 @@ function process_way(profile, way, result, relations) 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) + parsed_rel_list[i] = Relations.parse_route_relation(rel, way, relations) end -- now process relations data diff --git a/profiles/lib/relations.lua b/profiles/lib/relations.lua index a1474bad5..ec492679e 100644 --- a/profiles/lib/relations.lua +++ b/profiles/lib/relations.lua @@ -7,6 +7,10 @@ Utils = require('lib/utils') Relations = {} +function is_direction(role) + return (role == 'north' or role == 'south' or role == 'west' or role == 'east') +end + -- match ref values to relations data function Relations.match_to_ref(relations, ref) @@ -91,37 +95,71 @@ function Relations.match_to_ref(relations, ref) return result end -function Relations.parse_route_relation(relation, obj) - local t = relation:get_value_by_key("type") - local role = relation:get_role(obj) +function get_direction_from_superrel(rel, relations) + local result = nil + local result_id = nil + local rel_id_list = relations:get_relations(rel) + + function set_result(direction, current_rel) + if (result ~= nil) and (direction ~= nil) then + print('WARNING: relation ' .. rel:id() .. ' is a part of more then one supperrelations ' .. result_id .. ' and ' .. current_rel:id()) + else + result = direction + result_id = current_rel:id() + end + end + + for i, rel_id in ipairs(rel_id_list) do + local parent_rel = relations:relation(rel_id) + if parent_rel:get_value_by_key('type') == 'route' then + local role = parent_rel:get_role(rel) + + if is_direction(role) then + set_result(role, parent_rel) + else + local dir = parent_rel:get_value_by_key('direction') + if is_direction(dir) then + set_result(dir, parent_rel) + end + end + end + -- TODO: support forward/backward + end + + return result +end + +function Relations.parse_route_relation(rel, way, relations) + local t = rel:get_value_by_key("type") + local role = rel:get_role(way) local result = {} function add_extra_data(m) - local name = relation:get_value_by_key("name") + local name = rel:get_value_by_key("name") if name then result['route_name'] = name end - local ref = relation:get_value_by_key("ref") + local ref = rel:get_value_by_key("ref") if ref then result['route_ref'] = ref end end if t == 'route' then - local route = relation:get_value_by_key("route") + local route = rel:get_value_by_key("route") if route == 'road' then -- process case, where directions set as role - if role == 'north' or role == 'south' or role == 'west' or role == 'east' then + if is_direction(role) then result['route_direction'] = role add_extra_data(m) end end - local direction = relation:get_value_by_key('direction') + local direction = rel:get_value_by_key('direction') if direction then direction = string.lower(direction) - if direction == 'north' or direction == 'south' or direction == 'west' or direction == 'east' then + if is_direction(direction) then if role == 'forward' then result['route_direction'] = direction add_extra_data(m) @@ -130,6 +168,20 @@ function Relations.parse_route_relation(relation, obj) end end + -- process superrelations + local super_dir = get_direction_from_superrel(rel, relations) + + -- check if there are data error + local dir = result['route_direction'] + if (dir ~= nil) and (super_dir ~= nil) and (dir ~= super_dir) then + print('ERROR: conflicting relation directions found for way ' .. way:id() .. + ' relation direction is ' .. dir .. ' superrelation direction is ' .. super_dir) + end + + if (dir == nil) and (super_dir ~= nil) then + result['route_direction'] = super_dir + end + return result end diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index 0117b380c..0f135d788 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -417,24 +417,23 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) sol::property([](const ExtractionWay &way) { return way.is_left_hand_driving; }, [](ExtractionWay &way, bool flag) { way.is_left_hand_driving = flag; })); - auto getTypedRefBySol = [](const sol::object & obj) -> ExtractionRelation::OsmIDTyped - { + auto getTypedRefBySol = [](const sol::object &obj) -> ExtractionRelation::OsmIDTyped { if (obj.is()) { - osmium::Way * way = obj.as(); - return { way->id(), osmium::item_type::way }; + osmium::Way *way = obj.as(); + return {way->id(), osmium::item_type::way}; } - if (obj.is()) + if (obj.is()) { - osmium::Relation * rel = obj.as(); - return { rel->id(), osmium::item_type::relation }; + ExtractionRelation *rel = obj.as(); + return rel->id; } if (obj.is()) { - osmium::Node * node = obj.as(); - return { node->id(), osmium::item_type::node }; + osmium::Node *node = obj.as(); + return {node->id(), osmium::item_type::node}; } return ExtractionRelation::OsmIDTyped(0, osmium::item_type::undefined); @@ -449,27 +448,25 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) context.state.new_usertype( "ExtractionRelation", + "id", + [](ExtractionRelation &rel) { return rel.id.GetID(); }, "get_value_by_key", - [](ExtractionRelation &rel, const char * key) -> const char * { return rel.GetAttr(key); }, + [](ExtractionRelation &rel, const char *key) -> const char * { return rel.GetAttr(key); }, "get_role", - [&getTypedRefBySol](ExtractionRelation &rel, const sol::object & obj) -> const char * - { + [&getTypedRefBySol](ExtractionRelation &rel, const sol::object &obj) -> const char * { return rel.GetRole(getTypedRefBySol(obj)); }); context.state.new_usertype( "ExtractionRelationContainer", "get_relations", - [&getTypedRefBySol](ExtractionRelationContainer &cont, const sol::object & obj) - -> const ExtractionRelationContainer::RelationIDList & - { - return cont.GetRelations(getTypedRefBySol(obj)); - }, + [&getTypedRefBySol](ExtractionRelationContainer &cont, const sol::object &obj) + -> const ExtractionRelationContainer::RelationIDList & { + return cont.GetRelations(getTypedRefBySol(obj)); + }, "relation", - [](ExtractionRelationContainer &cont, const ExtractionRelation::OsmIDTyped & rel_id) -> const ExtractionRelation & - { - return cont.GetRelationData(rel_id); - }); + [](ExtractionRelationContainer &cont, const ExtractionRelation::OsmIDTyped &rel_id) + -> const ExtractionRelation & { return cont.GetRelationData(rel_id); }); context.state.new_usertype("ExtractionSegment", "source", @@ -717,7 +714,7 @@ LuaScriptingContext &Sol2ScriptingEnvironment::GetSol2Context() auto &ref = script_contexts.local(initialized); if (!initialized) { - ref = std::make_unique(location_dependent_data); + ref = std::make_unique(); InitContext(*ref); } @@ -1037,7 +1034,6 @@ void LuaScriptingContext::ProcessWay(const osmium::Way &way, case 1: case 0: way_function(way, result); - result.is_left_hand_driving = properties.left_hand_driving; break; } }