From c704245efa6a87e70961d19a0c8b4674d004840c Mon Sep 17 00:00:00 2001 From: Sergey Yershov Date: Tue, 30 Dec 2014 15:40:08 +0300 Subject: [PATCH] Refactoring OSM tags processing --- generator/osm2type.cpp | 108 +++++++++++++++----------------------- indexer/classificator.hpp | 5 ++ 2 files changed, 47 insertions(+), 66 deletions(-) diff --git a/generator/osm2type.cpp b/generator/osm2type.cpp index a31b56c766..2ad70af0ed 100644 --- a/generator/osm2type.cpp +++ b/generator/osm2type.cpp @@ -11,6 +11,7 @@ #include "../std/vector.hpp" #include "../std/bind.hpp" +#include "../std/function.hpp" #include @@ -321,33 +322,35 @@ namespace ftype } }; - class do_find_pairs + class TagProcessor { - char const * (*m_arr) [2]; - size_t m_size; + typedef struct { + char const * key; + char const * value; + function func; + } RuleT; - vector m_res; + initializer_list m_rules; public: - do_find_pairs(char const * (*arr) [2], size_t sz) - : m_arr(arr), m_size(sz) + typedef bool result_type; + + TagProcessor(initializer_list rules) + : m_rules(rules) { - m_res.resize(m_size, false); } bool operator() (string const & k, string const & v) { - for (size_t i = 0; i < m_size; ++i) - if ((k == "*" || k == m_arr[i][0]) && - (v == "*" || v == m_arr[i][1])) + for (auto e: m_rules) + if ((k == "*" || k == e.key) && + (v == "*" || v == e.value)) { - m_res[i] = true; + e.func(); } return false; } - - bool IsExist(size_t i) const { return m_res[i]; } }; } @@ -370,22 +373,19 @@ namespace ftype void add_layers(XMLElement * p) { - static char const * arr[][2] = { - { "bridge", "yes" }, - { "tunnel", "yes" }, - { "layer", "*" }, - }; + bool isLayer = false; + char const *layer = nullptr; - do_find_pairs doFind(arr, ARRAY_SIZE(arr)); - for_each_tag(p, bind(ref(doFind), _1, _2)); + TagProcessor setLayer({ + { "bridge", "yes", [&layer](){ layer = "1";}}, + { "tunnel", "yes", [&layer](){ layer = "-1";} }, + { "layer", "*", [&isLayer](){ isLayer = true;} }, + }); - if (!doFind.IsExist(2)) - { - if (doFind.IsExist(0)) - p->AddKV("layer", "1"); - if (doFind.IsExist(1)) - p->AddKV("layer", "-1"); - } + for_each_tag(p, bind(ref(setLayer), _1, _2)); + + if (!isLayer && layer) + p->AddKV("layer", layer); } //#ifdef DEBUG @@ -407,30 +407,20 @@ namespace ftype buffer_vector m_types; public: - enum Type { ENTRANCE, HIGHWAY, ADDRESS, ONEWAY, PRIVATE, LIT }; + enum EType { ENTRANCE, HIGHWAY, ADDRESS, ONEWAY, PRIVATE, LIT }; CachedTypes() { Classificator const & c = classif(); + + for (auto &e: (Classificator::Path1T[]){ {"entrance"}, {"highway"} }) + m_types.push_back(c.GetTypeByPath( {e[0]} )); - char const * arr1[][1] = { - { "entrance" }, - { "highway" } - }; - for (size_t i = 0; i < ARRAY_SIZE(arr1); ++i) - m_types.push_back(c.GetTypeByPath(vector(arr1[i], arr1[i] + 1))); - - char const * arr2[][2] = { - { "building", "address" }, - { "hwtag", "oneway" }, - { "hwtag", "private" }, - { "hwtag", "lit" }, - }; - for (size_t i = 0; i < ARRAY_SIZE(arr2); ++i) - m_types.push_back(c.GetTypeByPath(vector(arr2[i], arr2[i] + 2))); + for (auto &e: (Classificator::Path2T[]){ {"building", "address"}, {"hwtag", "oneway"}, {"hwtag", "private"}, {"hwtag", "lit"} }) + m_types.push_back(c.GetTypeByPath( {e[0], e[1]} )); } - uint32_t Get(Type t) const { return m_types[t]; } + uint32_t Get(EType t) const { return m_types[t]; } bool IsHighway(uint32_t t) const { ftype::TruncValue(t, 1); @@ -507,30 +497,16 @@ namespace ftype for (size_t i = 0; i < params.m_Types.size(); ++i) if (types.IsHighway(params.m_Types[i])) { - static char const * arr[][2] = { - { "oneway", "yes" }, - { "oneway", "1" }, - { "oneway", "-1" }, - { "access", "private" }, - { "lit", "yes" }, - }; - do_find_pairs doFind(arr, ARRAY_SIZE(arr)); - for_each_tag(p, bind(ref(doFind), _1, _2)); + TagProcessor addHighwayTypes({ + { "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;} }, + { "access", "private", [¶ms](){params.AddType(types.Get(CachedTypes::PRIVATE));} }, + { "lit", "yes", [¶ms](){params.AddType(types.Get(CachedTypes::LIT));} }, + }); - if (doFind.IsExist(3)) - params.AddType(types.Get(CachedTypes::PRIVATE)); - - if (doFind.IsExist(4)) - params.AddType(types.Get(CachedTypes::LIT)); - - if (doFind.IsExist(0) || doFind.IsExist(1) || doFind.IsExist(2)) - { - params.AddType(types.Get(CachedTypes::ONEWAY)); - - if (doFind.IsExist(2)) - params.m_reverseGeometry = true; - } + for_each_tag(p, bind(ref(addHighwayTypes), _1, _2)); break; } diff --git a/indexer/classificator.hpp b/indexer/classificator.hpp index 05e156e30c..253754bf66 100644 --- a/indexer/classificator.hpp +++ b/indexer/classificator.hpp @@ -168,6 +168,11 @@ class Classificator : private noncopyable static ClassifObject * AddV(ClassifObject * parent, string const & key, string const & value); public: + + typedef const char * Path1T[1]; + typedef const char * Path2T[2]; + typedef const char * Path3T[3]; + Classificator() : m_root("world") {} ClassifObject * Add(ClassifObject * parent, string const & key, string const & value);