Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvng <viktor.govako@gmail.com>2011-05-09 02:53:49 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 01:17:06 +0300
commit2400357a3db3f7eaf00e8c75d7603168f441fd80 (patch)
tree4597cb81b97faf0e1d92185128d5b0bfd58c5046 /generator
parent4ec7dff6c7b847264eb0091b89fe86df1eea95d2 (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.cpp5
-rw-r--r--generator/feature_merger.hpp5
-rw-r--r--generator/generator_tests/feature_bucketer_test.cpp1
-rw-r--r--generator/osm2type.cpp83
-rw-r--r--generator/osm2type.hpp9
-rw-r--r--generator/osm_element.hpp69
-rw-r--r--generator/statistics.cpp8
-rw-r--r--generator/statistics.hpp2
-rw-r--r--generator/world_map_generator.hpp2
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)
{