forked from organicmaps/organicmaps
Parallel implementation of Polygonizer.
This commit is contained in:
parent
1c0f5a6553
commit
a482c51fbc
2 changed files with 71 additions and 21 deletions
|
@ -308,6 +308,7 @@ bool GenerateImpl(GenerateInfo & info)
|
|||
FeaturePolygonizerType bucketer(info);
|
||||
TParser<FeaturePolygonizerType, holder_t> parser(bucketer, holder);
|
||||
ParseXMLFromStdIn(parser);
|
||||
bucketer.Finish();
|
||||
info.bucketNames = bucketer.Names();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,23 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../base/base.hpp"
|
||||
|
||||
#include "kml_parser.hpp"
|
||||
#include "world_map_generator.hpp"
|
||||
#include "../../indexer/feature.hpp"
|
||||
#include "../../indexer/feature_visibility.hpp"
|
||||
#include "../../indexer/cell_id.hpp"
|
||||
|
||||
#include "../../coding/file_writer.hpp"
|
||||
|
||||
#include "../../geometry/rect2d.hpp"
|
||||
|
||||
#include "../../coding/file_writer.hpp"
|
||||
#include "../../base/base.hpp"
|
||||
#include "../../base/buffer_vector.hpp"
|
||||
|
||||
#include "../../base/macros.hpp"
|
||||
#include "../../std/scoped_ptr.hpp"
|
||||
#include "../../std/string.hpp"
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#ifndef PARALLEL_POLYGONIZER
|
||||
#define PARALLEL_POLYGONIZER 1
|
||||
#endif
|
||||
|
||||
#include "kml_parser.hpp"
|
||||
#include "world_map_generator.hpp"
|
||||
#if PARALLEL_POLYGONIZER
|
||||
#include <QSemaphore>
|
||||
#include <QThreadPool>
|
||||
#include <QMutex>
|
||||
#include <QMutexLocker>
|
||||
#endif
|
||||
|
||||
namespace feature
|
||||
{
|
||||
|
@ -29,6 +33,9 @@ namespace feature
|
|||
template <class TInfo>
|
||||
Polygonizer(TInfo & info) : m_FeatureOutInitData(info.datFilePrefix, info.datFileSuffix),
|
||||
m_worldMap(info.maxScaleForWorldFeatures, info.mergeCoastlines, m_FeatureOutInitData)
|
||||
#if PARALLEL_POLYGONIZER
|
||||
, m_ThreadPoolSemaphore(m_ThreadPool.maxThreadCount() * 4)
|
||||
#endif
|
||||
{
|
||||
CHECK(kml::LoadCountriesList(info.datFilePrefix, m_countries, info.simplifyCountriesLevel),
|
||||
("Error loading country polygons files"));
|
||||
|
@ -41,6 +48,7 @@ namespace feature
|
|||
}
|
||||
~Polygonizer()
|
||||
{
|
||||
Finish();
|
||||
for_each(m_Buckets.begin(), m_Buckets.end(), DeleteFunctor());
|
||||
}
|
||||
|
||||
|
@ -90,22 +98,29 @@ namespace feature
|
|||
EmitFeature(vec[0], fb);
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < vec.size(); ++i)
|
||||
this->operator()(vec[i], fb);
|
||||
#if PARALLEL_POLYGONIZER
|
||||
m_ThreadPoolSemaphore.acquire();
|
||||
m_ThreadPool.start(new PolygonizerTask(this, vec, fb));
|
||||
#else
|
||||
PolygonizerTask task(this, vec, fb);
|
||||
task.run();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void operator() (kml::CountryPolygons const * country, FeatureBuilder1 const & fb)
|
||||
void Finish()
|
||||
{
|
||||
PointChecker doCheck(country->m_regions);
|
||||
fb.ForEachTruePointRef(doCheck);
|
||||
|
||||
if (doCheck.m_belongs)
|
||||
EmitFeature(country, fb);
|
||||
#if PARALLEL_POLYGONIZER
|
||||
m_ThreadPool.waitForDone();
|
||||
#endif
|
||||
}
|
||||
|
||||
void EmitFeature(kml::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);
|
||||
|
@ -126,9 +141,43 @@ namespace feature
|
|||
|
||||
vector<FeatureOutT*> m_Buckets;
|
||||
vector<string> m_Names;
|
||||
|
||||
kml::CountriesContainerT m_countries;
|
||||
|
||||
WorldMapGenerator<FeatureOutT> m_worldMap;
|
||||
|
||||
#if PARALLEL_POLYGONIZER
|
||||
QThreadPool m_ThreadPool;
|
||||
QSemaphore m_ThreadPoolSemaphore;
|
||||
QMutex m_EmitFeatureMutex;
|
||||
|
||||
friend class PolygonizerTask;
|
||||
|
||||
class PolygonizerTask : public QRunnable
|
||||
{
|
||||
public:
|
||||
PolygonizerTask(Polygonizer * pPolygonizer,
|
||||
buffer_vector<kml::CountryPolygons const *, 32> const & countries,
|
||||
FeatureBuilder1 const & fb)
|
||||
: m_pPolygonizer(pPolygonizer), m_Countries(countries), m_FB(fb) {}
|
||||
|
||||
void run()
|
||||
{
|
||||
for (size_t i = 0; i < m_Countries.size(); ++i)
|
||||
{
|
||||
PointChecker doCheck(m_Countries[i]->m_regions);
|
||||
m_FB.ForEachTruePointRef(doCheck);
|
||||
|
||||
if (doCheck.m_belongs)
|
||||
m_pPolygonizer->EmitFeature(m_Countries[i], m_FB);
|
||||
}
|
||||
|
||||
m_pPolygonizer->m_ThreadPoolSemaphore.release();
|
||||
}
|
||||
|
||||
private:
|
||||
Polygonizer * m_pPolygonizer;
|
||||
buffer_vector<kml::CountryPolygons const *, 32> m_Countries;
|
||||
FeatureBuilder1 m_FB;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue