From afa1b6e023be533421c0e1510035c7e2d96cf7ad Mon Sep 17 00:00:00 2001 From: Sergey Yershov Date: Fri, 23 Jan 2015 16:59:59 +0300 Subject: [PATCH] Fix crash while running generator_tool on whole planet --- generator/osm2type.cpp | 70 ++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 37 deletions(-) diff --git a/generator/osm2type.cpp b/generator/osm2type.cpp index 3f3cd469fc..8972468c9f 100644 --- a/generator/osm2type.cpp +++ b/generator/osm2type.cpp @@ -297,31 +297,37 @@ namespace ftype } }; - template< typename FuncT = void()> class TagProcessor { - typedef struct { + template + struct Rule{ char const * key; char const * value; function func; - } RuleT; - - initializer_list m_rules; + }; + XMLElement * m_element; public: - TagProcessor(initializer_list rules) : m_rules(rules) {} + TagProcessor(XMLElement *elem) : m_element(elem) {} - bool operator() (string & k, string & v) const + + template< typename FuncT = void()> + void ApplyRules(initializer_list> const &rules) const { - for (auto const & e: m_rules) - if ((k == "*" || k == e.key) && (v == "*" || v == e.value)) - apply(e.func, k, v); - return false; + for (auto & e : m_element->childs) + { + if (e.tagKey == XMLElement::ET_TAG) + { + for (auto const & rule: rules) + if ((e.k == "*" || e.k == rule.key) && (e.v == "*" || e.v == rule.value)) + call(rule.func, e.k, e.v); + } + } } protected: - static void apply(function const & f, string & k, string & v) { f(); } - static void apply(function const & f, string & k, string & v) { f(k, v); } + static void call(function const & f, string & k, string & v) { f(); } + static void call(function const & f, string & k, string & v) { f(k, v); } }; } @@ -330,38 +336,24 @@ namespace ftype return for_each_tag(p, do_find_obj(parent, isKey)); } - size_t process_common_params(XMLElement * p, FeatureParams & params) + size_t ProcessCommonParams(XMLElement * p, FeatureParams & params) { size_t count; for_each_tag(p, do_find_name(count, params)); return count; } - void process_synonims(XMLElement * p) - { - /// Process synonym tags to match existing classificator types. - /// @todo We are planning to rewrite classificator <-> tags matching. - TagProcessor replaceSynonyms({ - { "atm", "yes", [](string &k, string &v){ k.swap(v); k = "amenity"; }}, - { "restaurant", "yes", [](string &k, string &v){ k.swap(v); k = "amenity"; }}, - { "hotel", "yes", [](string &k, string &v){ k.swap(v); k = "tourism"; }}, - }); - for_each_tag(p, bind(ref(replaceSynonyms), _1, _2)); - } - - void add_layers(XMLElement * p) + void AddLayers(XMLElement * p) { bool isLayer = false; char const *layer = nullptr; - TagProcessor<> setLayer({ + TagProcessor(p).ApplyRules({ { "bridge", "yes", [&layer](){ layer = "1";}}, { "tunnel", "yes", [&layer](){ layer = "-1";} }, { "layer", "*", [&isLayer](){ isLayer = true;} }, }); - for_each_tag(p, bind(ref(setLayer), _1, _2)); - if (!isLayer && layer) p->AddKV("layer", layer); } @@ -408,11 +400,18 @@ namespace ftype void GetNameAndType(XMLElement * p, FeatureParams & params) { - process_synonims(p); - add_layers(p); + /// Process synonym tags to match existing classificator types. + /// @todo We are planning to rewrite classificator <-> tags matching. + TagProcessor(p).ApplyRules({ + { "atm", "yes", [](string &k, string &v){ k.swap(v); k = "amenity"; }}, + { "restaurant", "yes", [](string &k, string &v){ k.swap(v); k = "amenity"; }}, + { "hotel", "yes", [](string &k, string &v){ k.swap(v); k = "tourism"; }}, + }); + + AddLayers(p); // maybe an empty feature - if (process_common_params(p, params) == 0) + if (ProcessCommonParams(p, params) == 0) return; set skipRootKeys; @@ -475,8 +474,7 @@ namespace ftype for (size_t i = 0; i < params.m_Types.size(); ++i) if (types.IsHighway(params.m_Types[i])) { - - TagProcessor<> addHighwayTypes({ + TagProcessor(p).ApplyRules({ { "oneway", "yes", [¶ms](){params.AddType(types.Get(CachedTypes::ONEWAY));} }, { "oneway", "1", [¶ms](){params.AddType(types.Get(CachedTypes::ONEWAY));} }, { "oneway", "-1", [¶ms](){params.AddType(types.Get(CachedTypes::ONEWAY)); params.m_reverseGeometry = true;} }, @@ -484,8 +482,6 @@ namespace ftype { "lit", "yes", [¶ms](){params.AddType(types.Get(CachedTypes::LIT));} }, }); - for_each_tag(p, bind(ref(addHighwayTypes), _1, _2)); - break; }