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:
-rw-r--r--generator/feature_generator.cpp1
-rw-r--r--generator/osm_decl.cpp28
-rw-r--r--generator/osm_decl.hpp1
-rw-r--r--generator/osm_element.hpp60
-rw-r--r--indexer/feature_visibility.cpp41
-rw-r--r--indexer/feature_visibility.hpp7
6 files changed, 101 insertions, 37 deletions
diff --git a/generator/feature_generator.cpp b/generator/feature_generator.cpp
index 74c9f51792..94c0608979 100644
--- a/generator/feature_generator.cpp
+++ b/generator/feature_generator.cpp
@@ -314,6 +314,7 @@ public:
{
if (m_coasts)
{
+ CHECK ( fb.GetGeomType() != feature::GEOM_POINT, () );
if (fb.HasType(m_coastType))
{
// leave only coastline type
diff --git a/generator/osm_decl.cpp b/generator/osm_decl.cpp
index c0d345d400..de1e71eb13 100644
--- a/generator/osm_decl.cpp
+++ b/generator/osm_decl.cpp
@@ -35,13 +35,27 @@ string RelationElement::GetType() const
return ((i != tags.end()) ? i->second : string());
}
-bool RelationElement::FindWay(uint64_t id, string & role) const
+namespace
{
- for (size_t i = 0; i < ways.size(); ++i)
- if (ways[i].first == id)
- {
- role = ways[i].second;
- return true;
- }
+ bool FindRoleImpl(vector<pair<uint64_t, string> > const & cnt,
+ uint64_t id, string & role)
+ {
+ for (size_t i = 0; i < cnt.size(); ++i)
+ if (cnt[i].first == id)
+ {
+ role = cnt[i].second;
+ return true;
+ }
return false;
+ }
+}
+
+bool RelationElement::FindWay(uint64_t id, string & role) const
+{
+ return FindRoleImpl(ways, id, role);
+}
+
+bool RelationElement::FindNode(uint64_t id, string & role) const
+{
+ return FindRoleImpl(nodes, id, role);
}
diff --git a/generator/osm_decl.hpp b/generator/osm_decl.hpp
index 6c63948ccc..1bd3ba7e81 100644
--- a/generator/osm_decl.hpp
+++ b/generator/osm_decl.hpp
@@ -93,6 +93,7 @@ struct RelationElement
string GetType() const;
bool FindWay(uint64_t id, string & role) const;
+ bool FindNode(uint64_t id, string & role) const;
template <class ToDo> void ForEachWay(ToDo & toDo) const
{
diff --git a/generator/osm_element.hpp b/generator/osm_element.hpp
index e48ef776f7..5db33a2360 100644
--- a/generator/osm_element.hpp
+++ b/generator/osm_element.hpp
@@ -222,7 +222,12 @@ protected:
bool IsAcceptBoundaryTypes(RelationElement const & rel) const
{
string role;
- VERIFY ( rel.FindWay(m_featureID, role), (m_featureID) );
+ if (!rel.FindWay(m_featureID, role))
+ {
+ // This case is possible when we found the relation by node (just skip it).
+ CHECK ( rel.FindNode(m_featureID, role), (m_featureID) );
+ return false;
+ }
// 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).
@@ -359,6 +364,8 @@ class SecondPassParserUsual : public SecondPassParserBase<TEmitter, THolder>
protected:
virtual void EmitElement(XMLElement * p)
{
+ using namespace feature;
+
uint64_t id;
FeatureParams fValue;
if (!base_type::ParseType(p, id, fValue))
@@ -369,7 +376,7 @@ protected:
if (p->name == "node")
{
- if (!feature::IsDrawableLike(fValue.m_Types, feature::FEATURE_TYPE_POINT))
+ if (!feature::RemoveNoDrawableTypes(fValue.m_Types, FEATURE_TYPE_POINT))
return;
m2::PointD pt;
@@ -380,13 +387,7 @@ protected:
}
else if (p->name == "way")
{
- bool const isLine = feature::IsDrawableLike(fValue.m_Types, feature::FEATURE_TYPE_LINE) ||
- // this is important fix: we need to process all coastlines even without linear drawing rules
- (m_coastType != 0 && fValue.IsTypeExist(m_coastType));
-
- bool const isArea = feature::IsDrawableLike(fValue.m_Types, feature::FEATURE_TYPE_AREA);
-
- if (!isLine && !isArea)
+ if (!feature::RemoveNoDrawableTypes(fValue.m_Types, FEATURE_TYPE_LINE_AREA))
return;
// geometry of feature
@@ -395,8 +396,7 @@ protected:
if (p->childs[i].name == "nd")
{
uint64_t nodeID;
- VERIFY ( strings::to_uint64(p->childs[i].attrs["ref"], nodeID),
- ("Bad node ref in way : ", p->childs[i].attrs["ref"]) );
+ CHECK ( strings::to_uint64(p->childs[i].attrs["ref"], nodeID), (p->childs[i].attrs["ref"]) );
m2::PointD pt;
if (!base_type::GetPoint(nodeID, pt))
@@ -410,13 +410,25 @@ protected:
if (count < 2)
return;
- if (isLine)
- ft.SetLinear();
-
- // Get the tesselation for an area object (only if it has area drawing rules,
- // otherwise it will stay a linear object).
- if (isArea && count > 2 && ft.IsGeometryClosed())
+ // Try to set area feature (linear types are also suitable for this)
+ if (feature::IsDrawableLike(fValue.m_Types, FEATURE_TYPE_AREA) &&
+ (count > 2) && ft.IsGeometryClosed())
+ {
base_type::FinishAreaFeature(id, ft);
+ }
+ else
+ {
+ // Try to set linear feature:
+ // - it's a coastline, OR
+ // - has linear types (remove others)
+ if ((m_coastType != 0 && fValue.IsTypeExist(m_coastType)) ||
+ feature::RemoveNoDrawableTypes(fValue.m_Types, FEATURE_TYPE_LINE))
+ {
+ ft.SetLinear();
+ }
+ else
+ return;
+ }
}
else if (p->name == "relation")
{
@@ -438,16 +450,13 @@ protected:
}
// 2. Relation should have visible area types.
- if (!feature::IsDrawableLike(fValue.m_Types, feature::FEATURE_TYPE_AREA))
- {
- LOG(LWARNING, ("Polygon relation without area types:", id));
+ if (!feature::IsDrawableLike(fValue.m_Types, FEATURE_TYPE_AREA))
return;
- }
typename base_type::holes_accumulator holes(this);
typename base_type::way_map_t wayMap;
- // 2. Iterate ways to get 'outer' and 'inner' geometries
+ // 3. Iterate ways to get 'outer' and 'inner' geometries
for (size_t i = 0; i < p->childs.size(); ++i)
{
if (p->childs[i].name == "member" &&
@@ -455,8 +464,7 @@ protected:
{
string const & role = p->childs[i].attrs["role"];
uint64_t wayID;
- VERIFY ( strings::to_uint64(p->childs[i].attrs["ref"], wayID),
- ("Bad way ref in relation : ", p->childs[i].attrs["ref"]) );
+ CHECK ( strings::to_uint64(p->childs[i].attrs["ref"], wayID), (p->childs[i].attrs["ref"]) );
if (role == "outer")
{
@@ -466,10 +474,6 @@ protected:
{
holes(wayID);
}
- else if (role.empty())
- {
- LOG(LWARNING, ("Way", wayID, "in relation", id, "with empty role"));
- }
}
}
diff --git a/indexer/feature_visibility.cpp b/indexer/feature_visibility.cpp
index ee96d55a33..db0c5cc953 100644
--- a/indexer/feature_visibility.cpp
+++ b/indexer/feature_visibility.cpp
@@ -254,6 +254,47 @@ bool IsDrawableForIndex(FeatureBase const & f, int level)
return false;
}
+namespace
+{
+ class CheckNonDrawableType
+ {
+ Classificator & m_c;
+ FeatureGeoType m_arr[3];
+ size_t m_count;
+
+ public:
+ CheckNonDrawableType(FeatureGeoType ft)
+ : m_c(classif()), m_count(0)
+ {
+ if (ft < FEATURE_TYPE_LINE_AREA)
+ m_arr[m_count++] = ft;
+ else
+ {
+ ASSERT_EQUAL ( ft, FEATURE_TYPE_LINE_AREA, () );
+ m_arr[m_count++] = FEATURE_TYPE_LINE;
+ m_arr[m_count++] = FEATURE_TYPE_AREA;
+ }
+ }
+
+ bool operator() (uint32_t t)
+ {
+ for (size_t i = 0; i < m_count; ++i)
+ {
+ IsDrawableLikeChecker doCheck(m_arr[i]);
+ if (m_c.ProcessObjects(t, doCheck))
+ return false;
+ }
+ return true;
+ }
+ };
+}
+
+bool RemoveNoDrawableTypes(vector<uint32_t> & types, FeatureGeoType ft)
+{
+ types.erase(remove_if(types.begin(), types.end(), CheckNonDrawableType(ft)), types.end());
+ return !types.empty();
+}
+
int GetMinDrawableScale(FeatureBase const & f)
{
int const upBound = scales::GetUpperScale();
diff --git a/indexer/feature_visibility.hpp b/indexer/feature_visibility.hpp
index b4ba4c5f77..6f3fea925c 100644
--- a/indexer/feature_visibility.hpp
+++ b/indexer/feature_visibility.hpp
@@ -19,13 +19,16 @@ namespace feature
enum FeatureGeoType {
FEATURE_TYPE_POINT = 0,
FEATURE_TYPE_LINE = 1,
- FEATURE_TYPE_AREA = 2
+ FEATURE_TYPE_AREA = 2,
+ FEATURE_TYPE_LINE_AREA = 3
};
bool IsDrawableAny(uint32_t type);
- bool IsDrawableLike(vector<uint32_t> const & type, FeatureGeoType ft);
+ bool IsDrawableLike(vector<uint32_t> const & types, FeatureGeoType ft);
bool IsDrawableForIndex(FeatureBase const & f, int level);
+ bool RemoveNoDrawableTypes(vector<uint32_t> & types, FeatureGeoType ft);
+
int GetMinDrawableScale(FeatureBase const & f);
/// @return [-1, -1] if no any text exists