[generator] Fix bug with skipping types for inner boundary relations

(Should skip only boundaries, not all types).
This commit is contained in:
vng 2012-05-31 02:18:37 +03:00 committed by Alex Zolotarev
parent ae5e7ded22
commit a65a9d2775
5 changed files with 44 additions and 10 deletions

View file

@ -366,4 +366,10 @@ namespace ftype
} while (true);
}
uint32_t GetBoundaryType2()
{
char const * arr[] = { "boundary", "administrative" };
return classif().GetTypeByPath(vector<string>(arr, arr + 2));
}
}

View file

@ -9,4 +9,7 @@ namespace ftype
{
/// Get the types, name and layer for feature with the tree of tags.
void GetNameAndType(XMLElement * p, FeatureParams & params);
/// @return 'boundary-administrative' type.
uint32_t GetBoundaryType2();
}

View file

@ -16,6 +16,7 @@
#include "../std/set.hpp"
#include "../std/vector.hpp"
/// @param TEmitter Feature accumulating policy
/// @param THolder Nodes, ways, relations holder
template <class TEmitter, class THolder>
@ -218,17 +219,27 @@ protected:
typedef unordered_map<uint64_t, RelationValue> RelationCacheT;
RelationCacheT m_typeCache;
bool IsAcceptTypes(RelationElement const & rel) const
bool IsAcceptBoundaryTypes(RelationElement const & rel) const
{
string role;
VERIFY ( rel.FindWay(m_featureID, role), (m_featureID) );
// Do not accumulate border types (boundary-administrative-*) for inner polygons.
// Do not accumulate boundary types (boundary-administrative-*) for inner polygons.
// Example: Minsk city border (admin_level=8) is inner for Minsk area border (admin_level=4).
return (role != "inner");
}
uint32_t const m_boundaryType;
uint32_t GetSkipBoundaryType(RelationElement const * rel) const
{
return ((rel == 0 || IsAcceptBoundaryTypes(*rel)) ? 0 : m_boundaryType);
}
public:
type_processor() : m_boundaryType(ftype::GetBoundaryType2())
{
}
~type_processor()
{
for (typename RelationCacheT::iterator i = m_typeCache.begin(); i != m_typeCache.end(); ++i)
@ -248,9 +259,7 @@ protected:
typename RelationCacheT::const_iterator i = m_typeCache.find(id);
if (i != m_typeCache.end())
{
if (i->second.m_e == 0 || IsAcceptTypes(*(i->second.m_e)))
m_val->AddTypes(i->second.m_p);
m_val->AddTypes(i->second.m_p, GetSkipBoundaryType(i->second.m_e));
return -1; // continue process relations
}
return 0; // read relation from file (see next operator)
@ -277,8 +286,7 @@ protected:
ftype::GetNameAndType(&e, val.m_p);
if (val.m_p.IsValid())
{
if (!isBoundary || IsAcceptTypes(rel))
m_val->AddTypes(val.m_p);
m_val->AddTypes(val.m_p, GetSkipBoundaryType(isBoundary ? &rel : 0));
if (isBoundary)
{

View file

@ -96,9 +96,22 @@ uint8_t FeatureParams::GetTypeMask() const
return h;
}
void FeatureParams::AddTypes(FeatureParams const & rhs)
void FeatureParams::AddTypes(FeatureParams const & rhs, uint32_t skipType2)
{
m_Types.insert(m_Types.end(), rhs.m_Types.begin(), rhs.m_Types.end());
if (skipType2 == 0)
{
m_Types.insert(m_Types.end(), rhs.m_Types.begin(), rhs.m_Types.end());
}
else
{
for (size_t i = 0; i < rhs.m_Types.size(); ++i)
{
uint32_t t = rhs.m_Types[i];
ftype::TruncValue(t, 2);
if (t != skipType2)
m_Types.push_back(t);
}
}
}
void FeatureParams::FinishAddingTypes()

View file

@ -205,7 +205,11 @@ public:
uint8_t GetTypeMask() const;
inline void AddType(uint32_t t) { m_Types.push_back(t); }
void AddTypes(FeatureParams const & rhs);
/// @param skipType2 Do not accumulate this type if skipType2 != 0.
/// '2' means 2-level type in classificator tree (also skip child types).
void AddTypes(FeatureParams const & rhs, uint32_t skipType2);
template <class TIter> void AssignTypes(TIter b, TIter e)
{
m_Types.assign(b, e);