forked from organicmaps/organicmaps
Code for feature uniting is more generic now.
Define any types for unite processing in WorldMapGenerator.
This commit is contained in:
parent
7b9871b5a8
commit
ee406ece0c
7 changed files with 87 additions and 41 deletions
|
@ -68,6 +68,22 @@ void FeatureBuilder1::AddName(string const & name)
|
|||
m_Name = name;
|
||||
}
|
||||
|
||||
bool FeatureBuilder1::IsTypeExist(uint32_t t) const
|
||||
{
|
||||
return (find(m_Types.begin(), m_Types.end(), t) != m_Types.end());
|
||||
}
|
||||
|
||||
bool FeatureBuilder1::AssignType_SetDifference(vector<uint32_t> const & diffTypes)
|
||||
{
|
||||
vector<uint32_t> src;
|
||||
src.swap(m_Types);
|
||||
|
||||
sort(src.begin(), src.end());
|
||||
set_difference(src.begin(), src.end(), diffTypes.begin(), diffTypes.end(), back_inserter(m_Types));
|
||||
|
||||
return !m_Types.empty();
|
||||
}
|
||||
|
||||
void FeatureBuilder1::AddLayer(int32_t layer)
|
||||
{
|
||||
int const bound = 10;
|
||||
|
|
|
@ -20,9 +20,6 @@ class FeatureBase;
|
|||
/// Used for serialization\deserialization of features during --generate_features.
|
||||
class FeatureBuilder1
|
||||
{
|
||||
// needed for hacky coastlines merging
|
||||
friend class FeatureBuilder1Merger;
|
||||
|
||||
public:
|
||||
FeatureBuilder1();
|
||||
|
||||
|
@ -57,6 +54,9 @@ public:
|
|||
m_Types.clear();
|
||||
m_Types.push_back(type);
|
||||
}
|
||||
|
||||
bool IsTypeExist(uint32_t t) const;
|
||||
bool AssignType_SetDifference(vector<uint32_t> const & diffTypes);
|
||||
|
||||
void AddLayer(int32_t layer);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ FeatureBuilder1Merger::FeatureBuilder1Merger(FeatureBuilder1 const & fb)
|
|||
|
||||
bool FeatureBuilder1Merger::ReachedMaxPointsCount() const
|
||||
{
|
||||
return m_Geometry.size() > MAX_MERGED_POINTS_COUNT;
|
||||
return (m_Geometry.size() > MAX_MERGED_POINTS_COUNT);
|
||||
}
|
||||
|
||||
void FeatureBuilder1Merger::AppendFeature(FeatureBuilder1Merger const & fb)
|
||||
|
|
|
@ -11,7 +11,12 @@ public:
|
|||
/// but only if they have common point
|
||||
void AppendFeature(FeatureBuilder1Merger const & fb);
|
||||
|
||||
vector<uint32_t> const & Type() const { return m_Types; }
|
||||
uint32_t KeyType() const
|
||||
{
|
||||
ASSERT_EQUAL ( m_Types.size(), 1, () );
|
||||
return m_Types.front();
|
||||
}
|
||||
|
||||
bool ReachedMaxPointsCount() const;
|
||||
|
||||
m2::PointD FirstPoint() const { return m_Geometry.front(); }
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
Init();
|
||||
}
|
||||
|
||||
void operator () (feature_builder_t const & fb)
|
||||
void operator () (feature_builder_t & fb)
|
||||
{
|
||||
if (m_worldMap(fb))
|
||||
return; // we do not duplicate features in world and bucket files
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace feature
|
|||
}
|
||||
};
|
||||
|
||||
void operator () (FeatureBuilder1 const & fb)
|
||||
void operator () (FeatureBuilder1 & fb)
|
||||
{
|
||||
if (m_worldMap(fb))
|
||||
return; // do not duplicate feature in any country if it's stored in world map
|
||||
|
|
|
@ -37,7 +37,7 @@ class WorldMapGenerator
|
|||
size_t m_areasCounter;
|
||||
|
||||
typedef unordered_map<m2::PointD, FeatureBuilder1Merger> FeaturesContainerT;
|
||||
typedef map<vector<uint32_t>, FeaturesContainerT> TypesContainerT;
|
||||
typedef map<uint32_t, FeaturesContainerT> TypesContainerT;
|
||||
TypesContainerT m_features;
|
||||
|
||||
private:
|
||||
|
@ -54,8 +54,9 @@ private:
|
|||
base->second.AppendFeature(found->second);
|
||||
features.erase(found);
|
||||
++m_mergedCounter;
|
||||
|
||||
if (base->second.FirstPoint() == base->second.LastPoint())
|
||||
{ // @TODO create area feature
|
||||
{
|
||||
(*m_worldBucket)(base->second);
|
||||
features.erase(base);
|
||||
++m_areasCounter;
|
||||
|
@ -66,10 +67,9 @@ private:
|
|||
return false;
|
||||
}
|
||||
|
||||
void TryToMerge(FeatureBuilder1 const & fb)
|
||||
void TryToMerge(FeatureBuilder1Merger & fbm)
|
||||
{
|
||||
FeatureBuilder1Merger fbm(fb);
|
||||
FeaturesContainerT & container = m_features[fbm.Type()];
|
||||
FeaturesContainerT & container = m_features[fbm.KeyType()];
|
||||
FeaturesContainerT::iterator found = container.find(fbm.LastPoint());
|
||||
if (found != container.end())
|
||||
{
|
||||
|
@ -80,28 +80,31 @@ private:
|
|||
|
||||
if (fbm.FirstPoint() == fbm.LastPoint())
|
||||
{
|
||||
// @TODO create area feature
|
||||
(*m_worldBucket)(fbm);
|
||||
++m_areasCounter;
|
||||
return;
|
||||
}
|
||||
pair<FeaturesContainerT::iterator, bool> result = container.insert(make_pair(fbm.FirstPoint(), fbm));
|
||||
// if we found feature with the same starting point, emit it directly
|
||||
if (!result.second)
|
||||
else
|
||||
{
|
||||
LOG(LWARNING, ("Found features with common first point, points counts are:",
|
||||
result.first->second.GetPointsCount(), fb.GetPointsCount()));
|
||||
(*m_worldBucket)(fbm);
|
||||
pair<FeaturesContainerT::iterator, bool> result = container.insert(make_pair(fbm.FirstPoint(), fbm));
|
||||
// if we found feature with the same starting point, emit it directly
|
||||
if (!result.second)
|
||||
{
|
||||
LOG(LWARNING, ("Found features with common first point, points counts are:",
|
||||
result.first->second.GetPointsCount(), fbm.GetPointsCount()));
|
||||
(*m_worldBucket)(fbm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct FeatureTypePrinter
|
||||
{
|
||||
void operator()(uint32_t type) const
|
||||
{
|
||||
cout << classif().GetFullObjectName(type) << ".";
|
||||
}
|
||||
};
|
||||
//struct FeatureTypePrinter
|
||||
//{
|
||||
// void operator()(uint32_t type) const
|
||||
// {
|
||||
// cout << classif().GetFullObjectName(type) << ".";
|
||||
// }
|
||||
//};
|
||||
|
||||
vector<uint32_t> m_MergeTypes;
|
||||
|
||||
public:
|
||||
WorldMapGenerator(int maxWorldScale, bool mergeCoastlines,
|
||||
|
@ -111,6 +114,21 @@ public:
|
|||
{
|
||||
if (maxWorldScale >= 0)
|
||||
m_worldBucket.reset(new FeatureOutT(WORLD_FILE_NAME, featureOutInitData));
|
||||
|
||||
// fill vector with types that need to be merged
|
||||
char const * arrMerge[][2] = { {"natural", "coastline"} };
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(arrMerge); ++i)
|
||||
{
|
||||
vector<string> path(2);
|
||||
path[0] = arrMerge[i][0];
|
||||
path[1] = arrMerge[i][1];
|
||||
m_MergeTypes.push_back(classif().GetTypeByPath(path));
|
||||
|
||||
ASSERT_NOT_EQUAL ( m_MergeTypes.back(), ftype::GetEmptyValue(), () );
|
||||
}
|
||||
|
||||
sort(m_MergeTypes.begin(), m_MergeTypes.end());
|
||||
}
|
||||
|
||||
~WorldMapGenerator()
|
||||
|
@ -119,6 +137,7 @@ public:
|
|||
{
|
||||
LOG(LINFO, ("Final merging of coastlines started"));
|
||||
}
|
||||
|
||||
// try to merge all merged features with each other
|
||||
for (TypesContainerT::iterator it = m_features.begin(); it != m_features.end(); ++it)
|
||||
{
|
||||
|
@ -137,29 +156,35 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool operator()(FeatureBuilder1 const & fb)
|
||||
bool operator()(FeatureBuilder1 & fb)
|
||||
{
|
||||
if (m_worldBucket)
|
||||
{
|
||||
FeatureBase fBase = fb.GetFeatureBase();
|
||||
int minScale = feature::MinDrawableScaleForFeature(fBase);
|
||||
int const minScale = feature::MinDrawableScaleForFeature(fBase);
|
||||
CHECK_GREATER(minScale, -1, ("Non-drawable feature found!?"));
|
||||
if (m_maxWorldScale >= minScale)
|
||||
{
|
||||
FeatureTypePrinter typePrinter;
|
||||
fBase.ForEachTypeRef(typePrinter);
|
||||
cout << endl;
|
||||
if (m_mergeCoastlines)
|
||||
//FeatureTypePrinter typePrinter;
|
||||
//fBase.ForEachTypeRef(typePrinter);
|
||||
//cout << endl;
|
||||
|
||||
if (m_mergeCoastlines && fBase.GetFeatureType() == FeatureBase::FEATURE_TYPE_LINE)
|
||||
{
|
||||
// we're merging only linear features,
|
||||
// areas and points are written immediately
|
||||
if (fBase.GetFeatureType() != FeatureBase::FEATURE_TYPE_LINE)
|
||||
(*m_worldBucket)(fb);
|
||||
else
|
||||
TryToMerge(fb);
|
||||
for (size_t i = 0; i < m_MergeTypes.size(); ++i)
|
||||
{
|
||||
if (fb.IsTypeExist(m_MergeTypes[i]))
|
||||
{
|
||||
FeatureBuilder1Merger fbm(fb);
|
||||
fbm.SetType(m_MergeTypes[i]);
|
||||
TryToMerge(fbm);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fb.AssignType_SetDifference(m_MergeTypes))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
(*m_worldBucket)(fb);
|
||||
(*m_worldBucket)(fb);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue