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:
authorMaksim Andrianov <maksimandrianov1@gmail.com>2019-05-19 02:46:08 +0300
committermpimenov <mpimenov@users.noreply.github.com>2019-05-21 12:56:48 +0300
commit91dda74d7ec612c7ae78be491ee2f44c0dc2d73b (patch)
tree351d4a05df3ba425e7aca787b325e578ec4f133d /generator
parent066e3de6aa90638fffb05fed1cacc58bfb748d22 (diff)
[generator] Refactored Polygonizer.
Diffstat (limited to 'generator')
-rw-r--r--generator/emitter_coastline.cpp2
-rw-r--r--generator/emitter_simple.cpp2
-rw-r--r--generator/feature_builder.hpp39
-rw-r--r--generator/feature_generator.cpp6
-rw-r--r--generator/feature_generator.hpp8
-rw-r--r--generator/feature_processing_layers.cpp6
-rw-r--r--generator/generator_tests/coasts_test.cpp2
-rw-r--r--generator/generator_tests/popularity_builder_tests.cpp2
-rw-r--r--generator/generator_tests_support/test_mwm_builder.cpp2
-rw-r--r--generator/geo_objects/geo_objects.cpp4
-rw-r--r--generator/locality_sorter.cpp6
-rw-r--r--generator/polygonizer.hpp264
-rw-r--r--generator/regions/regions.cpp2
-rw-r--r--generator/world_map_generator.hpp2
14 files changed, 126 insertions, 221 deletions
diff --git a/generator/emitter_coastline.cpp b/generator/emitter_coastline.cpp
index e81c2d06a1..6cc745b48d 100644
--- a/generator/emitter_coastline.cpp
+++ b/generator/emitter_coastline.cpp
@@ -47,7 +47,7 @@ bool EmitterCoastline::Finish()
m_generator->GetFeatures(features);
for (auto & feature : features)
{
- collector(feature);
+ collector.Collect(feature);
++totalFeatures;
totalPoints += feature.GetPointsCount();
diff --git a/generator/emitter_simple.cpp b/generator/emitter_simple.cpp
index 9d7a5eac43..0eb14d6bc5 100644
--- a/generator/emitter_simple.cpp
+++ b/generator/emitter_simple.cpp
@@ -11,7 +11,7 @@ EmitterSimple::EmitterSimple(feature::GenerateInfo const & info) :
void EmitterSimple::GetNames(std::vector<std::string> & names) const
{
- names = m_regionGenerator->Parent().Names();
+ names = m_regionGenerator->Parent().GetNames();
}
void EmitterSimple::Process(FeatureBuilder1 & fb)
diff --git a/generator/feature_builder.hpp b/generator/feature_builder.hpp
index 4299c3f432..e9dfcdd331 100644
--- a/generator/feature_builder.hpp
+++ b/generator/feature_builder.hpp
@@ -127,16 +127,18 @@ public:
private:
template <class ToDo> class ToDoWrapper
{
- ToDo & m_toDo;
public:
- ToDoWrapper(ToDo & toDo) : m_toDo(toDo) {}
+ ToDoWrapper(ToDo && toDo) : m_toDo(std::forward<ToDo>(toDo)) {}
bool operator() (m2::PointD const & p) { return m_toDo(p); }
void EndRegion() {}
+
+ private:
+ ToDo && m_toDo;
};
public:
template <class ToDo>
- void ForEachGeometryPointEx(ToDo & toDo) const
+ void ForEachGeometryPointEx(ToDo && toDo) const
{
if (m_params.GetGeomType() == feature::GeomType::Point)
toDo(m_center);
@@ -153,13 +155,38 @@ public:
}
template <class ToDo>
- void ForEachGeometryPoint(ToDo & toDo) const
+ void ForEachGeometryPoint(ToDo && toDo) const
{
- ToDoWrapper<ToDo> wrapper(toDo);
- ForEachGeometryPointEx(wrapper);
+ ToDoWrapper<ToDo> wrapper(std::forward<ToDo>(toDo));
+ ForEachGeometryPointEx(std::move(wrapper));
}
//@}
+ template <class ToDo>
+ bool AnyOfGeometryPointEx(ToDo && toDo) const
+ {
+ if (m_params.GetGeomType() == feature::GeomType::Point)
+ return toDo(m_center);
+ else
+ {
+ for (PointSeq const & points : m_polygons)
+ {
+ for (auto const & pt : points)
+ if (toDo(pt))
+ return true;
+ toDo.EndRegion();
+ }
+ return false;
+ }
+ }
+
+ template <class ToDo>
+ bool AnyOfGeometryPoint(ToDo && toDo) const
+ {
+ ToDoWrapper<ToDo> wrapper(std::forward<ToDo>(toDo));
+ return AnyOfGeometryPointEx(std::move(wrapper));
+ }
+
bool PreSerialize();
bool PreSerializeAndRemoveUselessNames();
diff --git a/generator/feature_generator.cpp b/generator/feature_generator.cpp
index 82f54fe406..deba8d226a 100644
--- a/generator/feature_generator.cpp
+++ b/generator/feature_generator.cpp
@@ -92,7 +92,7 @@ uint32_t FeaturesCollector::WriteFeatureBase(std::vector<char> const & bytes, Fe
return m_featureID++;
}
-uint32_t FeaturesCollector::operator()(FeatureBuilder1 const & fb)
+uint32_t FeaturesCollector::Collect(FeatureBuilder1 const & fb)
{
FeatureBuilder1::Buffer bytes;
fb.Serialize(bytes);
@@ -112,9 +112,9 @@ FeaturesAndRawGeometryCollector::~FeaturesAndRawGeometryCollector()
LOG(LINFO, ("Write", m_rawGeometryCounter, "geometries into", m_rawGeometryFileStream.GetName()));
}
-uint32_t FeaturesAndRawGeometryCollector::operator()(FeatureBuilder1 const & fb)
+uint32_t FeaturesAndRawGeometryCollector::Collect(FeatureBuilder1 const & fb)
{
- uint32_t const featureId = FeaturesCollector::operator()(fb);
+ uint32_t const featureId = FeaturesCollector::Collect(fb);
FeatureBuilder1::Geometry const & geom = fb.GetGeometry();
if (geom.empty())
return featureId;
diff --git a/generator/feature_generator.hpp b/generator/feature_generator.hpp
index d0e874c06d..358eef32db 100644
--- a/generator/feature_generator.hpp
+++ b/generator/feature_generator.hpp
@@ -29,10 +29,10 @@ public:
/// and |kInvalidFeatureId| if not.
/// \note See implementation operator() in derived class for cases when |f| cannot be
/// serialized.
- virtual uint32_t operator()(FeatureBuilder1 const & f);
- virtual uint32_t operator()(FeatureBuilder1 & f)
+ virtual uint32_t Collect(FeatureBuilder1 const & f);
+ virtual uint32_t Collect(FeatureBuilder1 & f)
{
- return (*this)(const_cast<FeatureBuilder1 const &>(f));
+ return Collect(const_cast<FeatureBuilder1 const &>(f));
}
virtual void Finish() {}
@@ -65,7 +65,7 @@ public:
std::string const & rawGeometryFileName);
~FeaturesAndRawGeometryCollector() override;
- uint32_t operator()(FeatureBuilder1 const & f) override;
+ uint32_t Collect(FeatureBuilder1 const & f) override;
};
uint32_t CheckedFilePosCast(FileWriter const & f);
diff --git a/generator/feature_processing_layers.cpp b/generator/feature_processing_layers.cpp
index ac215171fc..388225239e 100644
--- a/generator/feature_processing_layers.cpp
+++ b/generator/feature_processing_layers.cpp
@@ -336,8 +336,8 @@ EmitCoastsLayer::~EmitCoastsLayer()
m_countryMapper->Map(fb);
emitter.Finish();
- fb.AddName("default", emitter.m_currentNames);
- (*m_collector)(fb);
+ fb.AddName("default", emitter.GetCurrentNames());
+ m_collector->Collect(fb);
});
}
@@ -369,7 +369,7 @@ CountryMapper::Polygonizer & CountryMapper::Parent()
std::vector<std::string> const & CountryMapper::GetNames() const
{
- return m_countries->Parent().Names();
+ return m_countries->Parent().GetNames();
}
WorldMapper::WorldMapper(std::string const & worldFilename, std::string const & rawGeometryFilename,
diff --git a/generator/generator_tests/coasts_test.cpp b/generator/generator_tests/coasts_test.cpp
index 3dfa742e78..30b7513c61 100644
--- a/generator/generator_tests/coasts_test.cpp
+++ b/generator/generator_tests/coasts_test.cpp
@@ -99,7 +99,7 @@ public:
void operator()(FeatureBuilder1 const & fb1, uint64_t)
{
if (HasID(fb1))
- m_collector(fb1);
+ m_collector.Collect(fb1);
}
private:
diff --git a/generator/generator_tests/popularity_builder_tests.cpp b/generator/generator_tests/popularity_builder_tests.cpp
index e69d9e73a2..26a025ca0b 100644
--- a/generator/generator_tests/popularity_builder_tests.cpp
+++ b/generator/generator_tests/popularity_builder_tests.cpp
@@ -242,7 +242,7 @@ public:
{
feature::FeaturesCollector collector(filename);
for (auto const & feature : m_testSet)
- collector(feature);
+ collector.Collect(feature);
}
PopularityBuilder builder(filename);
diff --git a/generator/generator_tests_support/test_mwm_builder.cpp b/generator/generator_tests_support/test_mwm_builder.cpp
index 924347026e..1f8c806e82 100644
--- a/generator/generator_tests_support/test_mwm_builder.cpp
+++ b/generator/generator_tests_support/test_mwm_builder.cpp
@@ -104,7 +104,7 @@ bool TestMwmBuilder::Add(FeatureBuilder1 & fb)
return false;
}
- (*m_collector)(fb);
+ m_collector->Collect(fb);
return true;
}
diff --git a/generator/geo_objects/geo_objects.cpp b/generator/geo_objects/geo_objects.cpp
index e315400d1a..c6083eb894 100644
--- a/generator/geo_objects/geo_objects.cpp
+++ b/generator/geo_objects/geo_objects.cpp
@@ -144,7 +144,7 @@ void FilterAddresslessByCountryAndRepackMwm(std::string const & pathInGeoObjects
{
if (GeoObjectsFilter::HasHouse(fb))
{
- collector(fb);
+ collector.Collect(fb);
return;
}
@@ -158,7 +158,7 @@ void FilterAddresslessByCountryAndRepackMwm(std::string const & pathInGeoObjects
auto countryName = FromJSON<std::string>(country);
auto pos = includeCountries.find(countryName);
if (pos != std::string::npos)
- collector(fb);
+ collector.Collect(fb);
};
feature::ForEachFromDatRawFormat(pathInGeoObjectsTmpMwm, filteringCollector);
diff --git a/generator/locality_sorter.cpp b/generator/locality_sorter.cpp
index 533be70db0..1709466c1c 100644
--- a/generator/locality_sorter.cpp
+++ b/generator/locality_sorter.cpp
@@ -44,7 +44,7 @@ public:
}
// FeaturesCollector overrides:
- uint32_t operator()(FeatureBuilder1 & fb) override
+ uint32_t Collect(FeatureBuilder1 & fb) override
{
if (fb.IsArea())
{
@@ -101,7 +101,7 @@ public:
m_writer.Finish();
}
- uint32_t operator()(FeatureBuilder1 & fb1) override
+ uint32_t Collect(FeatureBuilder1 & fb1) override
{
auto & fb2 = static_cast<FeatureBuilder2 &>(fb1);
@@ -217,7 +217,7 @@ bool GenerateLocalityDataImpl(FeaturesCollector & collector, NeedSerialize const
ReadFromSourceRawFormat(src, f);
// Emit object.
if (needSerialize(f))
- collector(f);
+ collector.Collect(f);
}
collector.Finish();
diff --git a/generator/polygonizer.hpp b/generator/polygonizer.hpp
index c6e84f8719..15cc53700b 100644
--- a/generator/polygonizer.hpp
+++ b/generator/polygonizer.hpp
@@ -3,220 +3,98 @@
#include "generator/borders_loader.hpp"
#include "generator/feature_builder.hpp"
#include "generator/generate_info.hpp"
-#include "generator/osm_source.hpp"
-
-#include "indexer/feature_visibility.hpp"
-#include "indexer/cell_id.hpp"
#include "geometry/rect2d.hpp"
+#include "geometry/mercator.hpp"
-#include "coding/file_writer.hpp"
-
-#include "base/base.hpp"
-#include "base/buffer_vector.hpp"
-#include "base/macros.hpp"
-
+#include <memory>
#include <string>
-
-#ifndef PARALLEL_POLYGONIZER
-#define PARALLEL_POLYGONIZER 1
-#endif
-
-#if PARALLEL_POLYGONIZER
-#include <QtCore/QSemaphore>
-#include <QtCore/QThreadPool>
-#include <QtCore/QMutex>
-#include <QtCore/QMutexLocker>
-#endif
+#include <vector>
namespace feature
{
- // Groups features according to country polygons
- template <class FeatureOutT>
- class Polygonizer
+// Groups features according to country polygons
+template <class FeatureOut>
+class Polygonizer
+{
+public:
+ Polygonizer(feature::GenerateInfo const & info)
+ : m_info(info)
{
- feature::GenerateInfo const & m_info;
-
- vector<FeatureOutT*> m_Buckets;
- vector<std::string> m_Names;
- borders::CountriesContainer m_countries;
-
-#if PARALLEL_POLYGONIZER
- QThreadPool m_ThreadPool;
- QSemaphore m_ThreadPoolSemaphore;
- QMutex m_EmitFeatureMutex;
-#endif
-
- public:
- Polygonizer(feature::GenerateInfo const & info)
- : m_info(info)
-#if PARALLEL_POLYGONIZER
- , m_ThreadPoolSemaphore(m_ThreadPool.maxThreadCount() * 8)
-#endif
+ if (info.m_splitByPolygons)
{
-#if PARALLEL_POLYGONIZER
- LOG(LINFO, ("Polygonizer thread pool threads:", m_ThreadPool.maxThreadCount()));
-#endif
-
- if (info.m_splitByPolygons)
- {
- CHECK(borders::LoadCountriesList(info.m_targetDir, m_countries),
+ CHECK(borders::LoadCountriesList(info.m_targetDir, m_countries),
("Error loading country polygons files"));
- }
- else
- {
- // Insert fake country polygon equal to whole world to
- // create only one output file which contains all features
- m_countries.Add(borders::CountryPolygons(info.m_fileName), MercatorBounds::FullRect());
- }
- }
- ~Polygonizer()
- {
- Finish();
- for_each(m_Buckets.begin(), m_Buckets.end(), base::DeleteFunctor());
- }
-
- struct PointChecker
- {
- borders::RegionsContainer const & m_regions;
- bool m_belongs;
-
- PointChecker(borders::RegionsContainer const & regions)
- : m_regions(regions), m_belongs(false) {}
-
- bool operator()(m2::PointD const & pt)
- {
- m_regions.ForEachInRect(m2::RectD(pt, pt),
- std::bind<void>(std::ref(*this), std::placeholders::_1, std::cref(pt)));
- return !m_belongs;
- }
-
- void operator() (borders::Region const & rgn, borders::Region::Value const & point)
- {
- if (!m_belongs)
- m_belongs = rgn.Contains(point);
- }
- };
-
- class InsertCountriesPtr
- {
- typedef buffer_vector<borders::CountryPolygons const *, 32> vec_type;
- vec_type & m_vec;
-
- public:
- InsertCountriesPtr(vec_type & vec) : m_vec(vec) {}
- void operator() (borders::CountryPolygons const & c)
- {
- m_vec.push_back(&c);
- }
- };
-
- void operator()(FeatureBuilder1 & fb)
- {
- buffer_vector<borders::CountryPolygons const *, 32> vec;
- m_countries.ForEachInRect(fb.GetLimitRect(), InsertCountriesPtr(vec));
-
- switch (vec.size())
- {
- case 0:
- break;
- case 1:
- EmitFeature(vec[0], fb);
- break;
- default:
- {
-#if PARALLEL_POLYGONIZER
- m_ThreadPoolSemaphore.acquire();
- m_ThreadPool.start(new PolygonizerTask(this, vec, fb));
-#else
- PolygonizerTask task(this, vec, fb);
- task.RunBase();
-#endif
- }
- }
}
-
- std::string m_currentNames;
-
- void Start()
+ else
{
- m_currentNames.clear();
+ // Insert fake country polygon equal to whole world to
+ // create only one output file which contains all features
+ m_countries.Add(borders::CountryPolygons(info.m_fileName), MercatorBounds::FullRect());
}
+ }
- void Finish()
- {
-#if PARALLEL_POLYGONIZER
- m_ThreadPool.waitForDone();
-#endif
- }
-
- void EmitFeature(borders::CountryPolygons const * country, FeatureBuilder1 const & fb)
- {
-#if PARALLEL_POLYGONIZER
- QMutexLocker mutexLocker(&m_EmitFeatureMutex);
- UNUSED_VALUE(mutexLocker);
-#endif
- if (country->m_index == -1)
- {
- m_Names.push_back(country->m_name);
- m_Buckets.push_back(new FeatureOutT(m_info.GetTmpFileName(country->m_name)));
- country->m_index = static_cast<int>(m_Buckets.size())-1;
- }
+ ~Polygonizer()
+ {
+ Finish();
+ }
- if (!m_currentNames.empty())
- m_currentNames += ';';
- m_currentNames += country->m_name;
+ void operator()(FeatureBuilder1 & fb)
+ {
+ m_countries.ForEachInRect(fb.GetLimitRect(), [&](auto const & countryPolygons) {
+ auto const need = fb.AnyOfGeometryPoint([&](auto const & point) {
+ auto const & regions = countryPolygons.m_regions;
+ return regions.AnyOfInRect(m2::RectD(point, point), [&](auto const & rgn) {
+ return rgn.Contains(point);
+ });
+ return true;
+ });
+
+ if (need)
+ EmitFeature(countryPolygons, fb);
+ });
+ }
+
+ void Start()
+ {
+ m_currentNames.clear();
+ }
- auto & bucket = *(m_Buckets[country->m_index]);
- bucket(fb);
- }
+ void Finish()
+ {
+ }
- vector<std::string> const & Names() const
+ void EmitFeature(borders::CountryPolygons const & countryPolygons, FeatureBuilder1 const & fb)
+ {
+ if (countryPolygons.m_index == -1)
{
- return m_Names;
+ m_Names.push_back(countryPolygons.m_name);
+ m_Buckets.emplace_back(new FeatureOut(m_info.GetTmpFileName(countryPolygons.m_name)));
+ countryPolygons.m_index = static_cast<int>(m_Buckets.size())-1;
}
- private:
- friend class PolygonizerTask;
-
- class PolygonizerTask
-#if PARALLEL_POLYGONIZER
- : public QRunnable
-#endif
- {
- public:
- PolygonizerTask(Polygonizer * pPolygonizer,
- buffer_vector<borders::CountryPolygons const *, 32> const & countries,
- FeatureBuilder1 const & fb)
- : m_pPolygonizer(pPolygonizer), m_Countries(countries), m_fb(fb)
- {
- }
-
- void RunBase()
- {
- for (size_t i = 0; i < m_Countries.size(); ++i)
- {
- PointChecker doCheck(m_Countries[i]->m_regions);
- m_fb.ForEachGeometryPoint(doCheck);
-
- if (doCheck.m_belongs)
- m_pPolygonizer->EmitFeature(m_Countries[i], m_fb);
- }
- }
+ if (!m_currentNames.empty())
+ m_currentNames += ';';
-#if PARALLEL_POLYGONIZER
- void run()
- {
- RunBase();
+ m_currentNames += countryPolygons.m_name;
+ m_Buckets[countryPolygons.m_index]->Collect(fb);
+ }
- m_pPolygonizer->m_ThreadPoolSemaphore.release();
- }
-#endif
+ std::vector<std::string> const & GetNames() const
+ {
+ return m_Names;
+ }
- private:
- Polygonizer * m_pPolygonizer;
- buffer_vector<borders::CountryPolygons const *, 32> m_Countries;
- FeatureBuilder1 m_fb;
- };
- };
+ std::string const & GetCurrentNames() const
+ {
+ return m_currentNames;
+ }
+
+private:
+ feature::GenerateInfo const & m_info;
+ std::vector<std::unique_ptr<FeatureOut>> m_Buckets;
+ std::vector<std::string> m_Names;
+ borders::CountriesContainer m_countries;
+ std::string m_currentNames;
+};
} // namespace feature
diff --git a/generator/regions/regions.cpp b/generator/regions/regions.cpp
index 74866524fe..1e93a97c55 100644
--- a/generator/regions/regions.cpp
+++ b/generator/regions/regions.cpp
@@ -158,7 +158,7 @@ private:
}
CHECK(fb.IsArea(), ());
- collector(fb);
+ collector.Collect(fb);
};
feature::ForEachFromDatRawFormat(m_pathInRegionsTmpMwm, toDo);
diff --git a/generator/world_map_generator.hpp b/generator/world_map_generator.hpp
index 149c78464e..1d6b29c4a0 100644
--- a/generator/world_map_generator.hpp
+++ b/generator/world_map_generator.hpp
@@ -243,7 +243,7 @@ class WorldMapGenerator
return (scales::GetUpperWorldScale() >= fb.GetMinFeatureDrawScale());
}
- void PushSure(FeatureBuilder1 const & fb) { m_output(fb); }
+ void PushSure(FeatureBuilder1 const & fb) { m_output.Collect(fb); }
};
EmitterImpl m_worldBucket;