forked from organicmaps/organicmaps
[generator] Skip features with empty names that have caption-only drawing rules.
This commit is contained in:
parent
855a3205d3
commit
69c162c00a
6 changed files with 91 additions and 68 deletions
|
@ -136,7 +136,9 @@ bool FeatureBuilder1::RemoveInvalidTypes()
|
|||
if (!m_params.FinishAddingTypes())
|
||||
return false;
|
||||
|
||||
return feature::RemoveNoDrawableTypes(m_params.m_Types, m_params.GetGeomType());
|
||||
return feature::RemoveNoDrawableTypes(m_params.m_Types,
|
||||
m_params.GetGeomType(),
|
||||
m_params.name.IsEmpty());
|
||||
}
|
||||
|
||||
bool FeatureBuilder1::FormatFullAddress(string & res) const
|
||||
|
|
|
@ -45,7 +45,7 @@ UNIT_TEST(FBuilder_ManyTypes)
|
|||
params.FinishAddingTypes();
|
||||
params.AddHouseNumber("75");
|
||||
params.AddHouseName("Best House");
|
||||
params.name.AddString(0, "Name");
|
||||
params.AddName("default", "Name");
|
||||
|
||||
fb1.SetParams(params);
|
||||
fb1.SetCenter(m2::PointD(0, 0));
|
||||
|
@ -125,8 +125,8 @@ UNIT_TEST(FBuilder_RemoveUselessNames)
|
|||
AddTypes(params, arr2);
|
||||
params.FinishAddingTypes();
|
||||
|
||||
params.name.AddString(0, "Name");
|
||||
params.name.AddString(8, "Имя");
|
||||
params.AddName("default", "Name");
|
||||
params.AddName("ru", "Имя");
|
||||
|
||||
FeatureBuilder1 fb1;
|
||||
fb1.SetParams(params);
|
||||
|
@ -145,3 +145,34 @@ UNIT_TEST(FBuilder_RemoveUselessNames)
|
|||
|
||||
TEST(fb1.CheckValid(), ());
|
||||
}
|
||||
|
||||
UNIT_TEST(FBuilder_WithoutName)
|
||||
{
|
||||
classificator::Load();
|
||||
char const * arr1[][1] = { { "amenity" } };
|
||||
|
||||
{
|
||||
FeatureParams params;
|
||||
AddTypes(params, arr1);
|
||||
params.AddName("default", "Name");
|
||||
|
||||
FeatureBuilder1 fb;
|
||||
fb.SetParams(params);
|
||||
fb.SetCenter(m2::PointD(0, 0));
|
||||
|
||||
TEST(fb.PreSerialize(), ());
|
||||
TEST(fb.RemoveInvalidTypes(), ());
|
||||
}
|
||||
|
||||
{
|
||||
FeatureParams params;
|
||||
AddTypes(params, arr1);
|
||||
|
||||
FeatureBuilder1 fb;
|
||||
fb.SetParams(params);
|
||||
fb.SetCenter(m2::PointD(0, 0));
|
||||
|
||||
TEST(fb.PreSerialize(), ());
|
||||
TEST(!fb.RemoveInvalidTypes(), ());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,9 +38,9 @@ ClassifObject * ClassifObject::Add(string const & s)
|
|||
|
||||
ClassifObject * ClassifObject::Find(string const & s)
|
||||
{
|
||||
for (iter_t i = m_objs.begin(); i != m_objs.end(); ++i)
|
||||
if ((*i).m_name == s)
|
||||
return &(*i);
|
||||
for (auto & obj : m_objs)
|
||||
if (obj.m_name == s)
|
||||
return &obj;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ void ClassifObject::AddDrawRule(drule::Key const & k)
|
|||
|
||||
ClassifObjectPtr ClassifObject::BinaryFind(string const & s) const
|
||||
{
|
||||
const_iter_t i = lower_bound(m_objs.begin(), m_objs.end(), s, less_name_t());
|
||||
auto i = lower_bound(m_objs.begin(), m_objs.end(), s, less_name_t());
|
||||
if ((i == m_objs.end()) || ((*i).m_name != s))
|
||||
return ClassifObjectPtr(0, 0);
|
||||
else
|
||||
|
@ -293,10 +293,10 @@ bool ClassifObject::IsDrawable(int scale) const
|
|||
|
||||
bool ClassifObject::IsDrawableAny() const
|
||||
{
|
||||
return (m_visibility != visible_mask_t() && !m_drawRule.empty());
|
||||
return (m_visibility != TVisibleMask() && !m_drawRule.empty());
|
||||
}
|
||||
|
||||
bool ClassifObject::IsDrawableLike(feature::EGeomType ft) const
|
||||
bool ClassifObject::IsDrawableLike(feature::EGeomType ft, bool emptyName) const
|
||||
{
|
||||
ASSERT(ft >= 0 && ft <= 2, ());
|
||||
|
||||
|
@ -310,12 +310,14 @@ bool ClassifObject::IsDrawableLike(feature::EGeomType ft) const
|
|||
{0, 1, 0, 0, 0, 0, 0, 0} // farea (!!! key difference with GetSuitable !!!)
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < m_drawRule.size(); ++i)
|
||||
for (auto const & k : m_drawRule)
|
||||
{
|
||||
ASSERT ( m_drawRule[i].m_type < drule::count_of_rules, () );
|
||||
if (visible[ft][m_drawRule[i].m_type] == 1)
|
||||
ASSERT_LESS(k.m_type, drule::count_of_rules, ());
|
||||
|
||||
// In case when feature name is empty we donn't take into account caption drawing rules.
|
||||
if ((visible[ft][k.m_type] == 1) &&
|
||||
(!emptyName || (k.m_type != drule::caption && k.m_type != drule::pathtext)))
|
||||
{
|
||||
/// @todo Check if rule's scale is reachable according to m_visibility (see GetSuitable algorithm).
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ public:
|
|||
|
||||
bool IsDrawable(int scale) const;
|
||||
bool IsDrawableAny() const;
|
||||
bool IsDrawableLike(feature::EGeomType ft) const;
|
||||
bool IsDrawableLike(feature::EGeomType ft, bool emptyName = false) const;
|
||||
|
||||
pair<int, int> GetDrawScaleRange() const;
|
||||
|
||||
|
@ -110,10 +110,8 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
typedef bitset<scales::UPPER_STYLE_SCALE+1> visible_mask_t;
|
||||
visible_mask_t GetVisibilityMask() const { return m_visibility; }
|
||||
void SetVisibilityMask(visible_mask_t mask) { m_visibility = mask; }
|
||||
void SetVisibilityOnScale(const bool isVisible, const int scale) { m_visibility[scale] = isVisible; }
|
||||
typedef bitset<scales::UPPER_STYLE_SCALE+1> TVisibleMask;
|
||||
void SetVisibilityOnScale(bool isVisible, int scale) { m_visibility[scale] = isVisible; }
|
||||
|
||||
/// @name Policies for classificator tree serialization.
|
||||
//@{
|
||||
|
@ -146,10 +144,7 @@ private:
|
|||
string m_name;
|
||||
vector<drule::Key> m_drawRule;
|
||||
vector<ClassifObject> m_objs;
|
||||
visible_mask_t m_visibility;
|
||||
|
||||
typedef vector<ClassifObject>::iterator iter_t;
|
||||
typedef vector<ClassifObject>::const_iterator const_iter_t;
|
||||
TVisibleMask m_visibility;
|
||||
};
|
||||
|
||||
inline void swap(ClassifObject & r1, ClassifObject & r2)
|
||||
|
|
|
@ -147,8 +147,8 @@ void GetDrawRule(vector<uint32_t> const & types, int level, int geoType,
|
|||
|
||||
DrawRuleGetter doRules(level, EGeomType(geoType), keys);
|
||||
|
||||
for (size_t i = 0; i < types.size(); ++i)
|
||||
(void)c.ProcessObjects(types[i], doRules);
|
||||
for (uint32_t t : types)
|
||||
(void)c.ProcessObjects(t, doRules);
|
||||
}
|
||||
|
||||
namespace
|
||||
|
@ -176,17 +176,21 @@ namespace
|
|||
|
||||
class IsDrawableLikeChecker
|
||||
{
|
||||
EGeomType m_type;
|
||||
EGeomType m_geomType;
|
||||
bool m_emptyName;
|
||||
|
||||
public:
|
||||
IsDrawableLikeChecker(EGeomType type) : m_type(type) {}
|
||||
IsDrawableLikeChecker(EGeomType geomType, bool emptyName = false)
|
||||
: m_geomType(geomType), m_emptyName(emptyName)
|
||||
{
|
||||
}
|
||||
|
||||
typedef bool ResultType;
|
||||
|
||||
void operator() (ClassifObject const *) {}
|
||||
bool operator() (ClassifObject const * p, bool & res)
|
||||
{
|
||||
if (p->IsDrawableLike(m_type))
|
||||
if (p->IsDrawableLike(m_geomType, m_emptyName))
|
||||
{
|
||||
res = true;
|
||||
return true;
|
||||
|
@ -218,11 +222,11 @@ namespace
|
|||
drule::KeysT keys;
|
||||
p->GetSuitable(m_scale, m_ft, keys);
|
||||
|
||||
for (size_t i = 0; i < keys.size(); ++i)
|
||||
for (auto const & k : keys)
|
||||
{
|
||||
if ((m_arr[0] && keys[i].m_type == drule::caption) ||
|
||||
(m_arr[1] && keys[i].m_type == drule::pathtext) ||
|
||||
(m_arr[2] && keys[i].m_type == drule::symbol))
|
||||
if ((m_arr[0] && k.m_type == drule::caption) ||
|
||||
(m_arr[1] && k.m_type == drule::pathtext) ||
|
||||
(m_arr[2] && k.m_type == drule::symbol))
|
||||
{
|
||||
res = true;
|
||||
return true;
|
||||
|
@ -259,13 +263,13 @@ bool IsDrawableAny(uint32_t type)
|
|||
return (TypeAlwaysExists(type) || classif().GetObject(type)->IsDrawableAny());
|
||||
}
|
||||
|
||||
bool IsDrawableLike(vector<uint32_t> const & types, EGeomType ft)
|
||||
bool IsDrawableLike(vector<uint32_t> const & types, EGeomType geomType)
|
||||
{
|
||||
Classificator const & c = classif();
|
||||
|
||||
IsDrawableLikeChecker doCheck(ft);
|
||||
for (size_t i = 0; i < types.size(); ++i)
|
||||
if (c.ProcessObjects(types[i], doCheck))
|
||||
IsDrawableLikeChecker doCheck(geomType);
|
||||
for (uint32_t t : types)
|
||||
if (c.ProcessObjects(t, doCheck))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -302,42 +306,31 @@ bool IsDrawableForIndexClassifOnly(FeatureBase const & f, int level)
|
|||
return false;
|
||||
}
|
||||
|
||||
namespace
|
||||
bool RemoveNoDrawableTypes(vector<uint32_t> & types, EGeomType geomType, bool emptyName)
|
||||
{
|
||||
class IsNonDrawableType
|
||||
Classificator const & c = classif();
|
||||
|
||||
types.erase(remove_if(types.begin(), types.end(), [&] (uint32_t t)
|
||||
{
|
||||
Classificator & m_c;
|
||||
EGeomType m_type;
|
||||
if (TypeAlwaysExists(t, geomType))
|
||||
return false;
|
||||
|
||||
public:
|
||||
IsNonDrawableType(EGeomType ft) : m_c(classif()), m_type(ft) {}
|
||||
IsDrawableLikeChecker doCheck(geomType, emptyName);
|
||||
if (c.ProcessObjects(t, doCheck))
|
||||
return false;
|
||||
|
||||
bool operator() (uint32_t t) const
|
||||
{
|
||||
if (TypeAlwaysExists(t, m_type))
|
||||
return false;
|
||||
// IsDrawableLikeChecker checks only unique area styles,
|
||||
// so we need to take into account point styles too.
|
||||
if (geomType == GEOM_AREA)
|
||||
{
|
||||
IsDrawableLikeChecker doCheck(GEOM_POINT, emptyName);
|
||||
if (c.ProcessObjects(t, doCheck))
|
||||
return false;
|
||||
}
|
||||
|
||||
IsDrawableLikeChecker doCheck(m_type);
|
||||
if (m_c.ProcessObjects(t, doCheck))
|
||||
return false;
|
||||
return true;
|
||||
}), types.end());
|
||||
|
||||
// IsDrawableLikeChecker checks only unique area styles,
|
||||
// so we need to take into account point styles too.
|
||||
if (m_type == GEOM_AREA)
|
||||
{
|
||||
IsDrawableLikeChecker doCheck(GEOM_POINT);
|
||||
if (m_c.ProcessObjects(t, doCheck))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
bool RemoveNoDrawableTypes(vector<uint32_t> & types, EGeomType ft)
|
||||
{
|
||||
types.erase(remove_if(types.begin(), types.end(), IsNonDrawableType(ft)), types.end());
|
||||
return !types.empty();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,9 +28,9 @@ namespace feature
|
|||
bool IsDrawableForIndexGeometryOnly(FeatureBase const & f, int level);
|
||||
|
||||
/// For FEATURE_TYPE_AREA need to have at least one area-filling type.
|
||||
bool IsDrawableLike(vector<uint32_t> const & types, EGeomType ft);
|
||||
bool IsDrawableLike(vector<uint32_t> const & types, EGeomType geomType);
|
||||
/// For FEATURE_TYPE_AREA removes line-drawing only types.
|
||||
bool RemoveNoDrawableTypes(vector<uint32_t> & types, EGeomType ft);
|
||||
bool RemoveNoDrawableTypes(vector<uint32_t> & types, EGeomType geomType, bool emptyName = false);
|
||||
//@}
|
||||
|
||||
int GetMinDrawableScale(FeatureBase const & f);
|
||||
|
|
Loading…
Add table
Reference in a new issue