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:
authorSergey Yershov <yershov@corp.mail.ru>2015-07-28 15:15:06 +0300
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:58:23 +0300
commit3cef8ffe6ab5b0860a2ff599321ddfb5f525a45d (patch)
treef69390091e2416da1e9c9a2c01f5c14b3c739f08 /generator/world_map_generator.hpp
parent1dc564769c8a6f7a0f0a2f620fed77f47c9dc8a1 (diff)
Review fixes
Diffstat (limited to 'generator/world_map_generator.hpp')
-rw-r--r--generator/world_map_generator.hpp246
1 files changed, 130 insertions, 116 deletions
diff --git a/generator/world_map_generator.hpp b/generator/world_map_generator.hpp
index 8a4e5bd515..45dce6171c 100644
--- a/generator/world_map_generator.hpp
+++ b/generator/world_map_generator.hpp
@@ -13,6 +13,113 @@
#include "defines.hpp"
+namespace
+{
+class WaterBoundaryChecker
+{
+ uint32_t m_boundaryType;
+ deque<m2::RegionD> m_waterRegions;
+
+ m4::Tree<size_t> m_tree;
+ size_t m_totalFeatures = 0;
+ size_t m_totalBorders = 0;
+ size_t m_skippedBorders = 0;
+ size_t m_selectedPolygons = 0;
+
+public:
+ WaterBoundaryChecker(feature::GenerateInfo const & info)
+ {
+ m_boundaryType = classif().GetTypeByPath({"boundary", "administrative"});
+ LoadWaterGeometry(
+ info.GetIntermediateFileName(WORLD_COASTS_FILE_NAME, RAW_GEOM_FILE_EXTENSION));
+ }
+
+ ~WaterBoundaryChecker()
+ {
+ LOG(LINFO, ("Features checked:", m_totalFeatures, "borders checked:", m_totalBorders,
+ "borders skipped:", m_skippedBorders, "selected polygons:", m_selectedPolygons));
+ }
+
+ void LoadWaterGeometry(string const & rawGeometryFileName)
+ {
+ LOG(LINFO, ("Loading water geometry:", rawGeometryFileName));
+ FileReader reader(rawGeometryFileName);
+ ReaderSource<FileReader> file(reader);
+
+ size_t total = 0;
+ while (true)
+ {
+ uint64_t numGeometries = 0;
+ file.Read(&numGeometries, sizeof(numGeometries));
+
+ if (numGeometries == 0)
+ break;
+
+ ++total;
+
+ vector<m2::PointD> points;
+ for (size_t i = 0; i < numGeometries; ++i)
+ {
+ uint64_t numPoints = 0;
+ file.Read(&numPoints, sizeof(numPoints));
+ points.resize(numPoints);
+ file.Read(points.data(), sizeof(m2::PointD) * numPoints);
+ m_waterRegions.push_back(m2::RegionD());
+ m_waterRegions.back().Assign(points.begin(), points.end());
+ m_tree.Add(m_waterRegions.size() - 1, m_waterRegions.back().GetRect());
+ }
+ }
+ LOG(LINFO, ("Load", total, "water geometries"));
+ }
+
+ bool IsWaterBoundaries(FeatureBuilder1 const & fb)
+ {
+ ++m_totalFeatures;
+
+ if (fb.FindType(m_boundaryType, 2) == ftype::GetEmptyValue())
+ return false;
+
+ ++m_totalBorders;
+
+ array<m2::PointD, 3> pts = {{{0, 0}, {0, 0}, {0, 0}}};
+ array<size_t, 3> hits = {{0, 0, 0}};
+
+ // For check we select first, last and middle point in line.
+ auto const & line = fb.GetGeometry().front();
+ pts[0] = line.front();
+ pts[1] = *(line.cbegin() + line.size() / 2);
+ pts[2] = line.back();
+
+ double constexpr kExtension = 0.01;
+
+ for (size_t i = 0; i < pts.size(); ++i)
+ {
+ m2::PointD const & p = pts[i];
+ m2::RectD r(p.x - kExtension, p.y - kExtension, p.x + kExtension, p.y + kExtension);
+ m_tree.ForEachInRect(r, [&](size_t index)
+ {
+ ++m_selectedPolygons;
+ hits[i] += m_waterRegions[index].Contains(pts[i]) ? 1 : 0;
+ });
+ }
+
+ size_t const state = (hits[0] & 0x01) + (hits[1] & 0x01) + (hits[2] & 0x01);
+
+ // whole border on water
+ if (state == 3)
+ {
+ LOG(LINFO, ("Boundary", (state == 3 ? "deleted" : "kept"), "hits:", hits,
+ DebugPrint(fb.GetParams()), fb.GetOsmIdsString()));
+ ++m_skippedBorders;
+ return true;
+ }
+
+ // state == 0 whole border on land, else partial intersection
+ return false;
+ }
+};
+}
+
/// Process FeatureBuilder1 for world map. Main functions:
/// - check for visibility in world map
/// - merge linear features
@@ -22,69 +129,25 @@ class WorldMapGenerator
class EmitterImpl : public FeatureEmitterIFace
{
FeatureOutT m_output;
- uint32_t m_boundaryType;
- deque<m2::RegionD> m_waterRegions;
-
- m4::Tree<size_t> m_tree;
map<uint32_t, size_t> m_mapTypes;
- size_t m_totalFeatures = 0;
- size_t m_totalBorders = 0;
- size_t m_skippedBorders = 0;
- size_t m_selectedPolygons = 0;
public:
explicit EmitterImpl(feature::GenerateInfo const & info)
: m_output(info.GetTmpFileName(WORLD_FILE_NAME))
{
- m_boundaryType = classif().GetTypeByPath({"boundary", "administrative"});
- LoadWaterGeometry(info.GetIntermediateFileName(WORLD_COASTS_FILE_NAME, RAW_GEOM_FILE_EXTENSION));
LOG(LINFO, ("Output World file:", info.GetTmpFileName(WORLD_FILE_NAME)));
}
~EmitterImpl() override
{
Classificator const & c = classif();
-
- LOG(LINFO, ("Features checked:", m_totalFeatures, "borders checked:", m_totalBorders, "borders skipped:", m_skippedBorders, "selected polygons:", m_selectedPolygons));
+
stringstream ss;
for (auto const & p : m_mapTypes)
ss << c.GetReadableObjectName(p.first) << " : " << p.second << endl;
LOG(LINFO, ("World types:\n", ss.str()));
}
- void LoadWaterGeometry(string const & rawGeometryFileName)
- {
- LOG(LINFO, ("Loading water geometry:", rawGeometryFileName));
- FileReader reader(rawGeometryFileName);
- ReaderSource<FileReader> file(reader);
-
- size_t total = 0;
- while (true)
- {
- uint64_t numGeometries = 0;
- file.Read(&numGeometries, sizeof(numGeometries));
-
- if (numGeometries == 0)
- break;
-
- ++total;
-
- vector<m2::PointD> points;
- for (size_t i = 0; i < numGeometries; ++i)
- {
- uint64_t numPoints = 0;
- file.Read(&numPoints, sizeof(numPoints));
- points.resize(numPoints);
- file.Read(points.data(), sizeof(m2::PointD) * numPoints);
- m_waterRegions.push_back(m2::RegionD());
- m_waterRegions.back().Assign(points.begin(), points.end());
- m_tree.Add(m_waterRegions.size() - 1, m_waterRegions.back().GetRect());
- }
- }
-
- LOG(LINFO, ("Load", total, "water geometries"));
- }
-
/// This function is called after merging linear features.
void operator()(FeatureBuilder1 const & fb) override
{
@@ -100,51 +163,6 @@ class WorldMapGenerator
++m_mapTypes[type];
}
- bool IsWaterBoundaries(FeatureBuilder1 const & fb)
- {
- ++m_totalFeatures;
-
- if (fb.FindType(m_boundaryType, 2) == ftype::GetEmptyValue())
- return false;
-
- ++m_totalBorders;
-
- array<m2::PointD, 3> pts = {m2::PointD{0, 0}, {0, 0}, {0, 0}};
- array<size_t, 3> hits = {0, 0, 0};
-
- // For check we select first, last and middle point in line.
- auto const & line = fb.GetGeometry().front();
- pts[0] = line.front();
- pts[1] = *(line.cbegin() + line.size() / 2);
- pts[2] = line.back();
-
- double constexpr kExtension = 0.01;
-
- for (size_t i = 0; i < pts.size(); ++i)
- {
- m2::RectD r(pts[i].x - kExtension, pts[i].y - kExtension, pts[i].x + kExtension, pts[i].y + kExtension);
- m_tree.ForEachInRect(r, [&](size_t index)
- {
- ++m_selectedPolygons;
- hits[i] += m_waterRegions[index].Contains(pts[i]) ? 1 : 0;
- });
- }
-
- size_t const state = (hits[0] & 0x01) + (hits[1] & 0x01) + (hits[2] & 0x01);
-
- // whole border on water
- if (state == 3)
- {
- LOG(LINFO, ("Boundary", (state == 3 ? "deleted" : "kept"), "hits:", hits,
- DebugPrint(fb.GetParams()), fb.GetOsmIdsString()));
- ++m_skippedBorders;
- return true;
- }
-
- // state == 0 whole border on land, else partial intersection
- return false;
- }
-
bool NeedPushToWorld(FeatureBuilder1 const & fb) const
{
// GetMinFeatureDrawScale also checks suitable size for AREA features
@@ -157,12 +175,13 @@ class WorldMapGenerator
EmitterImpl m_worldBucket;
FeatureTypesProcessor m_typesCorrector;
FeatureMergeProcessor m_merger;
+ WaterBoundaryChecker m_boundaryChecker;
public:
- template <class TInfo>
- explicit WorldMapGenerator(TInfo const & info)
+ explicit WorldMapGenerator(feature::GenerateInfo const & info)
: m_worldBucket(info),
- m_merger(POINT_COORD_BITS - (scales::GetUpperScale() - scales::GetUpperWorldScale()) / 2)
+ m_merger(POINT_COORD_BITS - (scales::GetUpperScale() - scales::GetUpperWorldScale()) / 2),
+ m_boundaryChecker(info)
{
// Do not strip last types for given tags,
// for example, do not cut 'admin_level' in 'boundary-administrative-XXX'.
@@ -200,25 +219,24 @@ public:
void operator()(FeatureBuilder1 fb)
{
- if (m_worldBucket.NeedPushToWorld(fb))
- {
- m_worldBucket.CalcStatistics(fb);
- // skip visible water boundary
- if (m_worldBucket.IsWaterBoundaries(fb))
- return;
+ if (!m_worldBucket.NeedPushToWorld(fb))
+ return;
- if (fb.GetGeomType() == feature::GEOM_LINE)
- {
- MergedFeatureBuilder1 * p = m_typesCorrector(fb);
- if (p)
- m_merger(p);
- }
- else
- {
- if (feature::PreprocessForWorldMap(fb))
- m_worldBucket.PushSure(fb);
- }
+ m_worldBucket.CalcStatistics(fb);
+ // skip visible water boundary
+ if (m_boundaryChecker.IsWaterBoundaries(fb))
+ return;
+
+ if (fb.GetGeomType() == feature::GEOM_LINE)
+ {
+ MergedFeatureBuilder1 * p = m_typesCorrector(fb);
+ if (p)
+ m_merger(p);
+ return;
}
+
+ if (feature::PreprocessForWorldMap(fb))
+ m_worldBucket.PushSure(fb);
}
void DoMerge() { m_merger.DoMerge(m_worldBucket); }
@@ -230,11 +248,7 @@ class CountryMapGenerator
FeatureOutT m_bucket;
public:
- template <class TInfo>
- explicit CountryMapGenerator(TInfo const & info)
- : m_bucket(info)
- {
- }
+ explicit CountryMapGenerator(feature::GenerateInfo const & info) : m_bucket(info) {}
void operator()(FeatureBuilder1 fb)
{
@@ -242,5 +256,5 @@ public:
m_bucket(fb);
}
- FeatureOutT const & Parent() const { return m_bucket; }
+ inline FeatureOutT const & Parent() const { return m_bucket; }
};