diff options
author | vng <viktor.govako@gmail.com> | 2011-05-09 02:53:49 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 01:17:06 +0300 |
commit | 2400357a3db3f7eaf00e8c75d7603168f441fd80 (patch) | |
tree | 4597cb81b97faf0e1d92185128d5b0bfd58c5046 /generator | |
parent | 4ec7dff6c7b847264eb0091b89fe86df1eea95d2 (diff) |
Refactoring of feature structure:
- multilanguage names
- separate house numbers
- point feature rank
- refs for linear features
Diffstat (limited to 'generator')
-rw-r--r-- | generator/feature_merger.cpp | 5 | ||||
-rw-r--r-- | generator/feature_merger.hpp | 5 | ||||
-rw-r--r-- | generator/generator_tests/feature_bucketer_test.cpp | 1 | ||||
-rw-r--r-- | generator/osm2type.cpp | 83 | ||||
-rw-r--r-- | generator/osm2type.hpp | 9 | ||||
-rw-r--r-- | generator/osm_element.hpp | 69 | ||||
-rw-r--r-- | generator/statistics.cpp | 8 | ||||
-rw-r--r-- | generator/statistics.hpp | 2 | ||||
-rw-r--r-- | generator/world_map_generator.hpp | 2 |
9 files changed, 96 insertions, 88 deletions
diff --git a/generator/feature_merger.cpp b/generator/feature_merger.cpp index 547ef882c0..5cdb681e73 100644 --- a/generator/feature_merger.cpp +++ b/generator/feature_merger.cpp @@ -17,10 +17,11 @@ bool FeatureBuilder1Merger::ReachedMaxPointsCount() const void FeatureBuilder1Merger::AppendFeature(FeatureBuilder1Merger const & fb) { // check that both features are of linear type - CHECK(fb.m_bLinear && m_bLinear, ("Not linear feature")); + CHECK(fb.m_Params.GetGeomType() == feature::GEOM_LINE && + m_Params.GetGeomType() == feature::GEOM_LINE, ("Not linear feature")); // check that classificator types are the same - CHECK_EQUAL(fb.m_Types, m_Types, ("Not equal types")); + //CHECK_EQUAL(fb.m_Types, m_Types, ("Not equal types")); // check last-first points equality //CHECK_EQUAL(m_Geometry.back(), fb.m_Geometry.front(), ("End and Start point are no equal")); diff --git a/generator/feature_merger.hpp b/generator/feature_merger.hpp index 0bede7358c..0662309097 100644 --- a/generator/feature_merger.hpp +++ b/generator/feature_merger.hpp @@ -16,14 +16,13 @@ public: if (m_Geometry.size() < 3) return false; - m_bArea = true; + m_Params.SetGeomType(feature::GEOM_AREA); return true; } uint32_t KeyType() const { - ASSERT_EQUAL ( m_Types.size(), 1, () ); - return m_Types.front(); + return m_Params.KeyType(); } bool ReachedMaxPointsCount() const; diff --git a/generator/generator_tests/feature_bucketer_test.cpp b/generator/generator_tests/feature_bucketer_test.cpp index 648a83e26e..4cdbf527aa 100644 --- a/generator/generator_tests/feature_bucketer_test.cpp +++ b/generator/generator_tests/feature_bucketer_test.cpp @@ -60,6 +60,7 @@ UNIT_TEST(FeatureBucketerSmokeTest) fb.AddPoint(m2::PointD(10, 10)); fb.AddPoint(m2::PointD(20, 20)); fb.SetType(0); + fb.SetLinear(); bucketer(fb); FeatureType f; diff --git a/generator/osm2type.cpp b/generator/osm2type.cpp index 864b2fe876..dc630f81c5 100644 --- a/generator/osm2type.cpp +++ b/generator/osm2type.cpp @@ -450,7 +450,8 @@ namespace ftype { string const & k = p->childs[i].attrs["k"]; string const & v = p->childs[i].attrs["v"]; - if (is_skip_tag(k, v)) continue; + if (k.empty() || is_skip_tag(k, v)) + continue; // this means "no" //if (get_mark_value(k, v) == -1) @@ -485,33 +486,70 @@ namespace ftype { class do_find_name { size_t & m_count; - string & m_name; - string & m_addr; - int32_t & m_layer; + FeatureParams & m_params; + + class get_lang + { + bool m_ok; + string & m_lang; + + public: + get_lang(string & lang) : m_ok(false), m_lang(lang) {} + + void operator() (string const & s) + { + if (m_ok) + m_lang = s; + else if (s == "name") + { + m_ok = true; + m_lang = "def"; + } + } + }; public: typedef bool result_type; - do_find_name(size_t & count, string & name, string & addr, int32_t & layer) - : m_count(count), m_name(name), m_addr(addr), m_layer(layer) + do_find_name(size_t & count, FeatureParams & params) + : m_count(count), m_params(params) { m_count = 0; - m_layer = 0; } bool operator() (string const & k, string const & v) { ++m_count; - // do not call is_name_tag(k), but exactly "name" tag - if (m_name.empty() && k == "name") - m_name = v; + if (v.empty()) return false; - // add house number - if (m_addr.empty() && k == "addr:housenumber") - m_addr = v; + // get names + string lang; + utils::TokenizeString(k, "\t :", get_lang(lang)); + if (!lang.empty()) + m_params.name.AddString(lang, v); - if (k == "layer" && m_layer == 0) - m_layer = atoi(v.c_str()); + // get layer + if (k == "layer" && m_params.layer == 0) + m_params.layer = atoi(v.c_str()); + + // get reference (we process road numbers only) + if (k == "ref") + m_params.ref = v; + + // get house number + if ((m_params.house.IsEmpty() && k == "addr:housenumber") || + (k == "addr:housename")) + { + m_params.house.Set(v); + } + + // get population rank + if (k == "population") + { + int n; + if (utils::to_int(v, n)) + m_params.rank = static_cast<uint8_t>(log(double(n)) / log(1.1)); + } return false; } @@ -565,13 +603,10 @@ namespace ftype { return for_each_tag(p, do_find_obj(parent, isKey)); } - size_t find_name_and_count(XMLElement * p, string & name, int32_t & layer) + size_t process_common_params(XMLElement * p, FeatureParams & params) { size_t count; - string addr; - for_each_tag(p, do_find_name(count, name, addr, layer)); - - if (name.empty()) name = addr; + for_each_tag(p, do_find_name(count, params)); return count; } @@ -589,7 +624,7 @@ namespace ftype { // }; //#endif - bool GetNameAndType(XMLElement * p, vector<uint32_t> & types, string & name, int32_t & layer) + bool GetNameAndType(XMLElement * p, FeatureParams & params) { //#ifdef DEBUG // // code to set a breakpoint @@ -600,7 +635,7 @@ namespace ftype { //#endif // maybe an empty feature - if (find_name_and_count(p, name, layer) == 0) + if (process_common_params(p, params) == 0) return false; set<string> skipRootKeys; @@ -639,7 +674,7 @@ namespace ftype { // use features only with drawing rules if (feature::IsDrawableAny(t)) - types.push_back(t); + params.AddType(t); } if (pRoot) @@ -652,6 +687,6 @@ namespace ftype { } while (true); - return !types.empty(); + return params.IsValid(); } } diff --git a/generator/osm2type.hpp b/generator/osm2type.hpp index 6a2449c29d..fa399ba6ef 100644 --- a/generator/osm2type.hpp +++ b/generator/osm2type.hpp @@ -1,9 +1,6 @@ #pragma once -#include "../base/base.hpp" - -#include "../std/string.hpp" -#include "../std/vector.hpp" +#include "../indexer/feature_data.hpp" #include "../base/start_mem_debug.hpp" @@ -13,8 +10,8 @@ namespace ftype { void ParseOSMTypes(char const * fPath, int scale); - /// Get the types, name and layer fot feature with the tree of tags. - bool GetNameAndType(XMLElement * p, vector<uint32_t> & types, string & name, int32_t & layer); + /// Get the types, name and layer for feature with the tree of tags. + bool GetNameAndType(XMLElement * p, FeatureParams & params); } #include "../base/stop_mem_debug.hpp" diff --git a/generator/osm_element.hpp b/generator/osm_element.hpp index 70e34e7e69..06b8b1c25c 100644 --- a/generator/osm_element.hpp +++ b/generator/osm_element.hpp @@ -28,9 +28,6 @@ protected: TEmitter & m_emitter; THolder & m_holder; - /// max possible number of types per feature - static const size_t max_number_of_types = 16; - SecondPassParserBase(TEmitter & emitter, THolder & holder) : m_emitter(emitter), m_holder(holder) { @@ -189,25 +186,6 @@ protected: list<vector<m2::PointD> > & GetHoles() { return m_holes.m_holes; } }; - /// Feature description struct. - struct value_t - { - typedef vector<uint32_t> types_t; - types_t types; ///< 1-n types, not empty - string name; ///< 1-1 name, @todo 1-n names - int32_t layer; ///< layer - - value_t() - { - types.reserve(max_number_of_types); - } - bool IsValid() const { return !types.empty(); } - void Add(value_t const & v) - { - types.insert(types.end(), v.types.begin(), v.types.end()); - } - }; - /// Feature types processor. class type_processor { @@ -229,14 +207,14 @@ protected: uint64_t m_featureID; /// @param[out] Feature value as result. - value_t * m_val; + FeatureParams * m_val; /// Cache: relation id -> feature value (for fast feature parsing) - unordered_map<uint64_t, value_t> m_typeCache; + unordered_map<uint64_t, FeatureParams> m_typeCache; public: /// Start process new feature. - void Reset(uint64_t fID, value_t * val) + void Reset(uint64_t fID, FeatureParams * val) { m_featureID = fID; m_val = val; @@ -245,10 +223,10 @@ protected: /// 1. "initial relation" process int operator() (uint64_t id) { - typename unordered_map<uint64_t, value_t>::const_iterator i = m_typeCache.find(id); + typename unordered_map<uint64_t, FeatureParams>::const_iterator i = m_typeCache.find(id); if (i != m_typeCache.end()) { - m_val->Add(i->second); + m_val->AddTypes(i->second); return -1; // continue process relations } return 0; // read relation from file (see next operator) @@ -268,14 +246,14 @@ protected: else { // process types of relation and add them to m_val - value_t val; - if (ftype::GetNameAndType(&e, val.types, val.name, val.layer)) + FeatureParams val; + if (ftype::GetNameAndType(&e, val)) { m_typeCache[id] = val; - m_val->Add(val); + m_val->AddTypes(val); } else - m_typeCache[id] = value_t(); + m_typeCache[id] = FeatureParams(); } // continue process relations @@ -294,13 +272,13 @@ protected: ft.SetAreaAddHoles(processor.GetHoles()); } - bool ParseType(XMLElement * p, uint64_t & id, value_t & fValue) + bool ParseType(XMLElement * p, uint64_t & id, FeatureParams & fValue) { VERIFY ( utils::to_uint64(p->attrs["id"], id), ("Unknown element with invalid id : ", p->attrs["id"]) ); // try to get type from element tags - ftype::GetNameAndType(p, fValue.types, fValue.name, fValue.layer); + ftype::GetNameAndType(p, fValue); // try to get type from relations tags m_typeProcessor.Reset(id, &fValue); @@ -316,9 +294,7 @@ protected: m_holder.ForEachRelationByWayCached(id, m_typeProcessor); } - // remove duplicating types - sort(fValue.types.begin(), fValue.types.end()); - fValue.types.erase(unique(fValue.types.begin(), fValue.types.end()), fValue.types.end()); + fValue.FinishAddingTypes(); // unrecognized feature by classificator return fValue.IsValid(); @@ -421,12 +397,12 @@ protected: virtual void EmitElement(XMLElement * p) { uint64_t id; - typename base_type::value_t fValue; + FeatureParams fValue; if (!ParseType(p, id, fValue)) return; // check, if we can make united feature - for (typename base_type::value_t::types_t::iterator i = fValue.types.begin(); i != fValue.types.end(); ++i) + for (typename FeatureParams::types_t::iterator i = fValue.types.begin(); i != fValue.types.end(); ++i) if (feature::NeedUnite(*i)) { typename base_type::feature_builder_t ft; @@ -452,21 +428,18 @@ class SecondPassParserUsual : public SecondPassParserBase<TEmitter, THolder> { typedef SecondPassParserBase<TEmitter, THolder> base_type; - typedef typename base_type::value_t type_t; typedef typename base_type::feature_builder_t feature_t; - void InitFeature(type_t const & fValue, feature_t & ft) + void InitFeature(FeatureParams const & fValue, feature_t & ft) { - ft.AddName(fValue.name); - ft.AddTypes(fValue.types.begin(), fValue.types.end()); - ft.AddLayer(fValue.layer); + ft.SetParams(fValue); } protected: virtual void EmitElement(XMLElement * p) { uint64_t id; - type_t fValue; + FeatureParams fValue; if (!ParseType(p, id, fValue)) return; @@ -475,7 +448,7 @@ protected: if (p->name == "node") { - if (!feature::IsDrawableLike(fValue.types, feature::fpoint)) + if (!feature::IsDrawableLike(fValue.m_Types, feature::fpoint)) return; m2::PointD pt; @@ -491,8 +464,8 @@ protected: // __debugbreak(); //#endif - bool const isLine = feature::IsDrawableLike(fValue.types, feature::fline); - bool const isArea = feature::IsDrawableLike(fValue.types, feature::farea); + bool const isLine = feature::IsDrawableLike(fValue.m_Types, feature::fline); + bool const isArea = feature::IsDrawableLike(fValue.m_Types, feature::farea); if (!isLine && !isArea) return; @@ -533,7 +506,7 @@ protected: // __debugbreak(); //#endif - if (!feature::IsDrawableLike(fValue.types, feature::farea)) + if (!feature::IsDrawableLike(fValue.m_Types, feature::farea)) return; // check, if this is our processable relation diff --git a/generator/statistics.cpp b/generator/statistics.cpp index 84c99ea74a..0d9da58ad7 100644 --- a/generator/statistics.cpp +++ b/generator/statistics.cpp @@ -13,6 +13,8 @@ #include "../base/start_mem_debug.hpp" +using namespace feature; + namespace stats { void FileContainerStatistic(string const & fName) @@ -88,12 +90,12 @@ namespace stats cout << prefix << ": size = " << info.m_size << "; count = " << info.m_count << endl; } - string GetKey(FeatureBase::FeatureType type) + string GetKey(EGeomType type) { switch (type) { - case FeatureBase::FEATURE_TYPE_LINE: return "Line"; - case FeatureBase::FEATURE_TYPE_AREA: return "Area"; + case GEOM_LINE: return "Line"; + case GEOM_AREA: return "Area"; default: return "Point"; } } diff --git a/generator/statistics.hpp b/generator/statistics.hpp index a4a73c03c1..2f4956fd20 100644 --- a/generator/statistics.hpp +++ b/generator/statistics.hpp @@ -51,7 +51,7 @@ namespace stats struct MapInfo { - set<GeneralInfoKey<FeatureBase::FeatureType> > m_byGeomType; + set<GeneralInfoKey<feature::EGeomType> > m_byGeomType; set<GeneralInfoKey<TypeTag> > m_byClassifType; set<GeneralInfoKey<uint32_t> > m_byPointsCount, m_byTrgCount; diff --git a/generator/world_map_generator.hpp b/generator/world_map_generator.hpp index 75928828b1..9838de9ec3 100644 --- a/generator/world_map_generator.hpp +++ b/generator/world_map_generator.hpp @@ -194,7 +194,7 @@ public: if (m_maxWorldScale >= minScale) { - if (m_mergeCoastlines && fBase.GetFeatureType() == FeatureBase::FEATURE_TYPE_LINE) + if (m_mergeCoastlines && fBase.GetFeatureType() == feature::GEOM_LINE) { for (size_t i = 0; i < m_MergeTypes.size(); ++i) { |