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:
Diffstat (limited to 'indexer')
-rw-r--r--indexer/altitude_loader.cpp2
-rw-r--r--indexer/altitude_loader.hpp4
-rw-r--r--indexer/data_source.cpp244
-rw-r--r--indexer/data_source.hpp281
-rw-r--r--indexer/data_source_helpers.cpp2
-rw-r--r--indexer/data_source_helpers.hpp4
-rw-r--r--indexer/feature_source.hpp10
-rw-r--r--indexer/indexer_tests/data_source_test.cpp6
-rw-r--r--indexer/indexer_tests/features_vector_test.cpp2
-rw-r--r--indexer/indexer_tests/index_builder_test.cpp2
-rw-r--r--indexer/indexer_tests/rank_table_test.cpp2
-rw-r--r--indexer/indexer_tests/scale_index_reading_tests.cpp2
-rw-r--r--indexer/mwm_set.hpp6
13 files changed, 298 insertions, 269 deletions
diff --git a/indexer/altitude_loader.cpp b/indexer/altitude_loader.cpp
index 8e54d52034..a1387a1f8e 100644
--- a/indexer/altitude_loader.cpp
+++ b/indexer/altitude_loader.cpp
@@ -31,7 +31,7 @@ void LoadAndMap(size_t dataSize, ReaderSource<FilesContainerR::TReader> & src, T
namespace feature
{
-AltitudeLoader::AltitudeLoader(DataSourceBase const & dataSource, MwmSet::MwmId const & mwmId)
+AltitudeLoader::AltitudeLoader(DataSource const & dataSource, MwmSet::MwmId const & mwmId)
: m_handle(dataSource.GetMwmHandleById(mwmId))
{
if (!m_handle.IsAlive())
diff --git a/indexer/altitude_loader.hpp b/indexer/altitude_loader.hpp
index ceb089e7e2..3ef738abd0 100644
--- a/indexer/altitude_loader.hpp
+++ b/indexer/altitude_loader.hpp
@@ -10,14 +10,14 @@
#include "3party/succinct/rs_bit_vector.hpp"
-class DataSourceBase;
+class DataSource;
namespace feature
{
class AltitudeLoader
{
public:
- AltitudeLoader(DataSourceBase const & dataSource, MwmSet::MwmId const & mwmId);
+ AltitudeLoader(DataSource const & dataSource, MwmSet::MwmId const & mwmId);
/// \returns altitude of feature with |featureId|. All items of the returned vector are valid
/// or the returned vector is empty.
diff --git a/indexer/data_source.cpp b/indexer/data_source.cpp
index bb6b7ea3ed..fffe4650d7 100644
--- a/indexer/data_source.cpp
+++ b/indexer/data_source.cpp
@@ -2,15 +2,172 @@
#include "base/logging.hpp"
+#include <limits>
+#include <type_traits>
+
using platform::CountryFile;
using platform::LocalCountryFile;
using namespace std;
-//////////////////////////////////////////////////////////////////////////////////
-// DataSourceBase implementation
-//////////////////////////////////////////////////////////////////////////////////
+namespace
+{
+template <typename Element>
+class ReadMWMFunctor
+{
+public:
+ using Fn = function<void(Element &)>;
+
+ ReadMWMFunctor(Fn const & fn, FeatureSourceFactory const & factory) : m_fn(fn), m_factory(factory)
+ {
+ }
+
+ template <typename T>
+ enable_if_t<is_same<T, FeatureID const>::value> ProcessElement(FeatureSource & src,
+ uint32_t index) const
+ {
+ if (FeatureStatus::Deleted == src.GetFeatureStatus(index))
+ return;
+
+ m_fn(src.GetFeatureId(index));
+ }
+
+ template <typename T>
+ enable_if_t<is_same<T, FeatureType>::value> ProcessElement(FeatureSource & src,
+ uint32_t index) const
+ {
+ FeatureType feature;
+ switch (src.GetFeatureStatus(index))
+ {
+ case FeatureStatus::Created: CHECK(false, ("Created features index should be generated."));
+ case FeatureStatus::Deleted:
+ case FeatureStatus::Obsolete: return;
+ case FeatureStatus::Modified:
+ {
+ VERIFY(src.GetModifiedFeature(index, feature), ());
+ break;
+ }
+ case FeatureStatus::Untouched:
+ {
+ src.GetOriginalFeature(index, feature);
+ break;
+ }
+ }
+ m_fn(feature);
+ }
+
+ // Reads features visible at |scale| covered by |cov| from mwm and applies |m_fn| to it.
+ // Feature reading process consists of two steps: untouched (original) features reading and
+ // touched (created, edited etc.) features reading.
+ void operator()(MwmSet::MwmHandle const & handle, covering::CoveringGetter & cov, int scale) const
+ {
+ auto src = m_factory(handle);
+
+ MwmValue const * pValue = handle.GetValue<MwmValue>();
+ if (pValue)
+ {
+ // Untouched (original) features reading. Applies covering |cov| to geometry index, gets
+ // feature ids from it, gets untouched features by ids from |src| and applies |m_fn| by
+ // ProcessElement.
+ feature::DataHeader const & header = pValue->GetHeader();
+ CheckUniqueIndexes checkUnique(header.GetFormat() >= version::Format::v5);
+
+ // In case of WorldCoasts we should pass correct scale in ForEachInIntervalAndScale.
+ auto const lastScale = header.GetLastScale();
+ if (scale > lastScale)
+ scale = lastScale;
+
+ // Use last coding scale for covering (see index_builder.cpp).
+ covering::Intervals const & intervals = cov.Get<RectId::DEPTH_LEVELS>(lastScale);
+ ScaleIndex<ModelReaderPtr> index(pValue->m_cont.GetReader(INDEX_FILE_TAG), pValue->m_factory);
+
+ // iterate through intervals
+ for (auto const & i : intervals)
+ {
+ index.ForEachInIntervalAndScale(i.first, i.second, scale, [&](uint32_t index) {
+ if (!checkUnique(index))
+ return;
+ ProcessElement<Element>(*src, index);
+ });
+ }
+ }
+ // Check created features container.
+ // Need to do it on a per-mwm basis, because Drape relies on features in a sorted order.
+ // Touched (created, edited) features reading.
+ src->ForEachInRectAndScale(cov.GetRect(), scale, m_fn);
+ }
+
+private:
+ Fn m_fn;
+ FeatureSourceFactory const & m_factory;
+};
+} // namespace
+
+//------------------------- DataSource::FeaturesLoaderGuard ----------------------
+
+string DataSource::FeaturesLoaderGuard::GetCountryFileName() const
+{
+ if (!m_handle.IsAlive())
+ return string();
+
+ return m_handle.GetValue<MwmValue>()->GetCountryFileName();
+}
+
+bool DataSource::FeaturesLoaderGuard::IsWorld() const
+{
+ if (!m_handle.IsAlive())
+ return false;
+
+ return m_handle.GetValue<MwmValue>()->GetHeader().GetType() == feature::DataHeader::world;
+}
+
+unique_ptr<FeatureType> DataSource::FeaturesLoaderGuard::GetOriginalFeatureByIndex(
+ uint32_t index) const
+{
+ auto feature = make_unique<FeatureType>();
+ if (GetOriginalFeatureByIndex(index, *feature))
+ return feature;
+
+ return {};
+}
-unique_ptr<MwmInfo> DataSourceBase::CreateInfo(platform::LocalCountryFile const & localFile) const
+unique_ptr<FeatureType> DataSource::FeaturesLoaderGuard::GetOriginalOrEditedFeatureByIndex(
+ uint32_t index) const
+{
+ auto feature = make_unique<FeatureType>();
+ if (!m_handle.IsAlive())
+ return {};
+
+ ASSERT_NOT_EQUAL(m_source->GetFeatureStatus(index), FeatureStatus::Created, ());
+ if (GetFeatureByIndex(index, *feature))
+ return feature;
+
+ return {};
+}
+
+/// Everyone, except Editor core, should use this method.
+WARN_UNUSED_RESULT bool DataSource::FeaturesLoaderGuard::GetFeatureByIndex(uint32_t index,
+ FeatureType & ft) const
+{
+ if (!m_handle.IsAlive())
+ return false;
+
+ ASSERT_NOT_EQUAL(FeatureStatus::Deleted, m_source->GetFeatureStatus(index),
+ ("Deleted feature was cached. It should not be here. Please review your code."));
+ if (m_source->GetModifiedFeature(index, ft))
+ return true;
+ return GetOriginalFeatureByIndex(index, ft);
+}
+
+/// Editor core only method, to get 'untouched', original version of feature.
+WARN_UNUSED_RESULT bool DataSource::FeaturesLoaderGuard::GetOriginalFeatureByIndex(
+ uint32_t index, FeatureType & ft) const
+{
+ return m_handle.IsAlive() ? m_source->GetOriginalFeature(index, ft) : false;
+}
+
+//---------------- DataSource -----------------------------------------------
+
+unique_ptr<MwmInfo> DataSource::CreateInfo(platform::LocalCountryFile const & localFile) const
{
MwmValue value(localFile);
@@ -32,7 +189,7 @@ unique_ptr<MwmInfo> DataSourceBase::CreateInfo(platform::LocalCountryFile const
return unique_ptr<MwmInfo>(move(info));
}
-unique_ptr<MwmSet::MwmValueBase> DataSourceBase::CreateValue(MwmInfo & info) const
+unique_ptr<MwmSet::MwmValueBase> DataSource::CreateValue(MwmInfo & info) const
{
// Create a section with rank table if it does not exist.
platform::LocalCountryFile const & localFile = info.GetLocalFile();
@@ -42,15 +199,15 @@ unique_ptr<MwmSet::MwmValueBase> DataSourceBase::CreateValue(MwmInfo & info) con
return unique_ptr<MwmSet::MwmValueBase>(move(p));
}
-pair<MwmSet::MwmId, MwmSet::RegResult> DataSourceBase::RegisterMap(LocalCountryFile const & localFile)
+pair<MwmSet::MwmId, MwmSet::RegResult> DataSource::RegisterMap(LocalCountryFile const & localFile)
{
return Register(localFile);
}
-bool DataSourceBase::DeregisterMap(CountryFile const & countryFile) { return Deregister(countryFile); }
+bool DataSource::DeregisterMap(CountryFile const & countryFile) { return Deregister(countryFile); }
-void DataSourceBase::ForEachInIntervals(ReaderCallback const & fn, covering::CoveringMode mode,
- m2::RectD const & rect, int scale) const
+void DataSource::ForEachInIntervals(ReaderCallback const & fn, covering::CoveringMode mode,
+ m2::RectD const & rect, int scale) const
{
vector<shared_ptr<MwmInfo>> mwms;
GetMwmsInfo(mwms);
@@ -80,3 +237,72 @@ void DataSourceBase::ForEachInIntervals(ReaderCallback const & fn, covering::Cov
if (worldID[1].IsAlive())
fn(GetMwmHandleById(worldID[1]), cov, scale);
}
+
+void DataSource::ForEachFeatureIDInRect(FeatureIdCallback const & f, m2::RectD const & rect,
+ int scale) const
+{
+ ReadMWMFunctor<FeatureID const> readFunctor(f, *m_factory);
+ ForEachInIntervals(readFunctor, covering::LowLevelsOnly, rect, scale);
+}
+
+void DataSource::ForEachInRect(FeatureCallback const & f, m2::RectD const & rect, int scale) const
+{
+ ReadMWMFunctor<FeatureType> readFunctor(f, *m_factory);
+ ForEachInIntervals(readFunctor, covering::ViewportWithLowLevels, rect, scale);
+}
+
+void DataSource::ForEachInScale(FeatureCallback const & f, int scale) const
+{
+ ReadMWMFunctor<FeatureType> readFunctor(f, *m_factory);
+ ForEachInIntervals(readFunctor, covering::FullCover, m2::RectD::GetInfiniteRect(), scale);
+}
+
+void DataSource::ForEachInRectForMWM(FeatureCallback const & f, m2::RectD const & rect, int scale,
+ MwmId const & id) const
+{
+ MwmHandle const handle = GetMwmHandleById(id);
+ if (handle.IsAlive())
+ {
+ covering::CoveringGetter cov(rect, covering::ViewportWithLowLevels);
+ ReadMWMFunctor<FeatureType> readFunctor(f, *m_factory);
+ readFunctor(handle, cov, scale);
+ }
+}
+
+void DataSource::ReadFeatures(FeatureConstCallback const & fn,
+ vector<FeatureID> const & features) const
+{
+ ASSERT(is_sorted(features.begin(), features.end()), ());
+
+ auto fidIter = features.begin();
+ auto const endIter = features.end();
+ while (fidIter != endIter)
+ {
+ MwmId const & id = fidIter->m_mwmId;
+ MwmHandle const handle = GetMwmHandleById(id);
+ if (handle.IsAlive())
+ {
+ // Prepare features reading.
+ auto src = (*m_factory)(handle);
+ do
+ {
+ auto const fts = src->GetFeatureStatus(fidIter->m_index);
+ ASSERT_NOT_EQUAL(
+ FeatureStatus::Deleted, fts,
+ ("Deleted feature was cached. It should not be here. Please review your code."));
+ FeatureType featureType;
+ if (fts == FeatureStatus::Modified || fts == FeatureStatus::Created)
+ VERIFY(src->GetModifiedFeature(fidIter->m_index, featureType), ());
+ else
+ src->GetOriginalFeature(fidIter->m_index, featureType);
+ fn(featureType);
+ } while (++fidIter != endIter && id == fidIter->m_mwmId);
+ }
+ else
+ {
+ // Skip unregistered mwm files.
+ while (++fidIter != endIter && id == fidIter->m_mwmId)
+ ;
+ }
+ }
+}
diff --git a/indexer/data_source.hpp b/indexer/data_source.hpp
index 8e8edfb2d0..484f1efa23 100644
--- a/indexer/data_source.hpp
+++ b/indexer/data_source.hpp
@@ -17,109 +17,50 @@
#include <algorithm>
#include <cstdint>
#include <functional>
-#include <limits>
#include <memory>
-#include <type_traits>
#include <utility>
#include <vector>
#include "defines.hpp"
-template <typename FeatureSource, typename Element>
-class ReadMWMFunctor final
+class DataSource : public MwmSet
{
public:
- using Fn = std::function<void(Element &)>;
-
- explicit ReadMWMFunctor(Fn const & fn) : m_fn(fn) {}
-
- template <typename T>
- std::enable_if_t<std::is_same<T, FeatureID const>::value> ProcessElement(FeatureSource & src,
- uint32_t index) const
- {
- if (FeatureStatus::Deleted == src.GetFeatureStatus(index))
- return;
-
- m_fn(src.GetFeatureId(index));
- }
+ using FeatureConstCallback = std::function<void(FeatureType const &)>;
+ using FeatureCallback = std::function<void(FeatureType &)>;
+ using FeatureIdCallback = std::function<void(FeatureID const &)>;
- template <typename T>
- std::enable_if_t<std::is_same<T, FeatureType>::value> ProcessElement(FeatureSource & src,
- uint32_t index) const
+ explicit DataSource(std::unique_ptr<FeatureSourceFactory> factory) : m_factory(std::move(factory))
{
- FeatureType feature;
- switch (src.GetFeatureStatus(index))
- {
- case FeatureStatus::Created: CHECK(false, ("Created features index should be generated."));
- case FeatureStatus::Deleted:
- case FeatureStatus::Obsolete: return;
- case FeatureStatus::Modified:
- {
- VERIFY(src.GetModifiedFeature(index, feature), ());
- break;
- }
- case FeatureStatus::Untouched:
- {
- src.GetOriginalFeature(index, feature);
- break;
- }
- }
- m_fn(feature);
}
+ ~DataSource() override = default;
- // Reads features visible at |scale| covered by |cov| from mwm and applies |m_fn| to it.
- // Feature reading process consists of two steps: untouched (original) features reading and
- // touched (created, edited etc.) features reading.
- void operator()(MwmSet::MwmHandle const & handle, covering::CoveringGetter & cov, int scale) const
+ /// Guard for loading features from particular MWM by demand.
+ /// @note This guard is suitable when mwm is loaded.
+ class FeaturesLoaderGuard
{
- FeatureSource src(handle);
-
- MwmValue const * pValue = handle.GetValue<MwmValue>();
- if (pValue)
+ public:
+ FeaturesLoaderGuard(DataSource const & dataSource, MwmId const & id,
+ FeatureSourceFactory const & factory)
+ : m_handle(dataSource.GetMwmHandleById(id)), m_source(factory(m_handle))
{
- // Untouched (original) features reading. Applies covering |cov| to geometry index, gets
- // feature ids from it, gets untouched features by ids from |src| and applies |m_fn| by
- // ProcessElement.
- feature::DataHeader const & header = pValue->GetHeader();
- CheckUniqueIndexes checkUnique(header.GetFormat() >= version::Format::v5);
-
- // In case of WorldCoasts we should pass correct scale in ForEachInIntervalAndScale.
- auto const lastScale = header.GetLastScale();
- if (scale > lastScale)
- scale = lastScale;
-
- // Use last coding scale for covering (see index_builder.cpp).
- covering::Intervals const & intervals = cov.Get<RectId::DEPTH_LEVELS>(lastScale);
- ScaleIndex<ModelReaderPtr> index(pValue->m_cont.GetReader(INDEX_FILE_TAG), pValue->m_factory);
-
- // iterate through intervals
- for (auto const & i : intervals)
- {
- index.ForEachInIntervalAndScale(i.first, i.second, scale, [&](uint32_t index) {
- if (!checkUnique(index))
- return;
- ProcessElement<Element>(src, index);
- });
- }
}
- // Check created features container.
- // Need to do it on a per-mwm basis, because Drape relies on features in a sorted order.
- // Touched (created, edited) features reading.
- src.ForEachInRectAndScale(cov.GetRect(), scale, m_fn);
- }
-
-private:
- Fn m_fn;
-};
-class DataSourceBase : public MwmSet
-{
-public:
- using FeatureConstCallback = std::function<void(FeatureType const &)>;
- using FeatureCallback = std::function<void(FeatureType &)>;
- using FeatureIdCallback = std::function<void(FeatureID const &)>;
+ MwmSet::MwmId const & GetId() const { return m_handle.GetId(); }
+ std::string GetCountryFileName() const;
+ bool IsWorld() const;
+ std::unique_ptr<FeatureType> GetOriginalFeatureByIndex(uint32_t index) const;
+ std::unique_ptr<FeatureType> GetOriginalOrEditedFeatureByIndex(uint32_t index) const;
+ /// Everyone, except Editor core, should use this method.
+ WARN_UNUSED_RESULT bool GetFeatureByIndex(uint32_t index, FeatureType & ft) const;
+ /// Editor core only method, to get 'untouched', original version of feature.
+ WARN_UNUSED_RESULT bool GetOriginalFeatureByIndex(uint32_t index, FeatureType & ft) const;
+ size_t GetNumFeatures() const { return m_source->GetNumFeatures(); }
- ~DataSourceBase() override = default;
+ private:
+ MwmHandle m_handle;
+ std::unique_ptr<FeatureSource> m_source;
+ };
/// Registers a new map.
std::pair<MwmId, RegResult> RegisterMap(platform::LocalCountryFile const & localFile);
@@ -131,16 +72,13 @@ public:
/// now, returns false.
bool DeregisterMap(platform::CountryFile const & countryFile);
- virtual void ForEachFeatureIDInRect(FeatureIdCallback const & f, m2::RectD const & rect,
- int scale) const = 0;
- virtual void ForEachInRect(FeatureCallback const & f, m2::RectD const & rect,
- int scale) const = 0;
- virtual void ForEachInScale(FeatureCallback const & f, int scale) const = 0;
- virtual void ForEachInRectForMWM(FeatureCallback const & f, m2::RectD const & rect, int scale,
- MwmId const & id) const = 0;
+ void ForEachFeatureIDInRect(FeatureIdCallback const & f, m2::RectD const & rect, int scale) const;
+ void ForEachInRect(FeatureCallback const & f, m2::RectD const & rect, int scale) const;
+ void ForEachInScale(FeatureCallback const & f, int scale) const;
+ void ForEachInRectForMWM(FeatureCallback const & f, m2::RectD const & rect, int scale,
+ MwmId const & id) const;
// "features" must be sorted using FeatureID::operator< as predicate.
- virtual void ReadFeatures(FeatureConstCallback const & fn,
- std::vector<FeatureID> const & features) const = 0;
+ void ReadFeatures(FeatureConstCallback const & fn, std::vector<FeatureID> const & features) const;
void ReadFeature(FeatureConstCallback const & fn, FeatureID const & feature) const
{
@@ -157,157 +95,8 @@ protected:
/// MwmSet overrides:
std::unique_ptr<MwmInfo> CreateInfo(platform::LocalCountryFile const & localFile) const override;
std::unique_ptr<MwmValueBase> CreateValue(MwmInfo & info) const override;
-};
-template <typename FeatureSource>
-class DataSourceImpl : public DataSourceBase
-{
-public:
- void ForEachFeatureIDInRect(FeatureIdCallback const & f, m2::RectD const & rect,
- int scale) const override
- {
- ReadMWMFunctor<FeatureSource, FeatureID const> readFunctor(f);
- ForEachInIntervals(readFunctor, covering::LowLevelsOnly, rect, scale);
- }
-
- void ForEachInRect(FeatureCallback const & f, m2::RectD const & rect, int scale) const override
- {
- ReadMWMFunctor<FeatureSource, FeatureType> readFunctor(f);
- ForEachInIntervals(readFunctor, covering::ViewportWithLowLevels, rect, scale);
- }
-
- void ForEachInScale(FeatureCallback const & f, int scale) const override
- {
- ReadMWMFunctor<FeatureSource, FeatureType> readFunctor(f);
- ForEachInIntervals(readFunctor, covering::FullCover, m2::RectD::GetInfiniteRect(), scale);
- }
-
- void ForEachInRectForMWM(FeatureCallback const & f, m2::RectD const & rect, int scale,
- MwmId const & id) const override
- {
- MwmHandle const handle = GetMwmHandleById(id);
- if (handle.IsAlive())
- {
- covering::CoveringGetter cov(rect, covering::ViewportWithLowLevels);
- ReadMWMFunctor<FeatureSource, FeatureType> readFunctor(f);
- readFunctor(handle, cov, scale);
- }
- }
-
- void ReadFeatures(FeatureConstCallback const & fn,
- std::vector<FeatureID> const & features) const override
- {
- ASSERT(std::is_sorted(features.begin(), features.end()), ());
-
- auto fidIter = features.begin();
- auto const endIter = features.end();
- while (fidIter != endIter)
- {
- MwmId const & id = fidIter->m_mwmId;
- MwmHandle const handle = GetMwmHandleById(id);
- if (handle.IsAlive())
- {
- // Prepare features reading.
- FeatureSource src(handle);
- do
- {
- auto const fts = src.GetFeatureStatus(fidIter->m_index);
- ASSERT_NOT_EQUAL(
- FeatureStatus::Deleted, fts,
- ("Deleted feature was cached. It should not be here. Please review your code."));
- FeatureType featureType;
- if (fts == FeatureStatus::Modified || fts == FeatureStatus::Created)
- VERIFY(src.GetModifiedFeature(fidIter->m_index, featureType), ());
- else
- src.GetOriginalFeature(fidIter->m_index, featureType);
- fn(featureType);
- } while (++fidIter != endIter && id == fidIter->m_mwmId);
- }
- else
- {
- // Skip unregistered mwm files.
- while (++fidIter != endIter && id == fidIter->m_mwmId)
- ;
- }
- }
- }
-
- /// Guard for loading features from particular MWM by demand.
- /// @note This guard is suitable when mwm is loaded.
- class FeaturesLoaderGuard
- {
- public:
- FeaturesLoaderGuard(DataSourceBase const & dataSource, MwmId const & id)
- : m_handle(dataSource.GetMwmHandleById(id)), m_source(m_handle)
- {
- }
-
- MwmSet::MwmId const & GetId() const { return m_handle.GetId(); }
-
- std::string GetCountryFileName() const
- {
- if (!m_handle.IsAlive())
- return string();
-
- return m_handle.GetValue<MwmValue>()->GetCountryFileName();
- }
-
- bool IsWorld() const
- {
- if (!m_handle.IsAlive())
- return false;
-
- return m_handle.GetValue<MwmValue>()->GetHeader().GetType() == feature::DataHeader::world;
- }
-
- std::unique_ptr<FeatureType> GetOriginalFeatureByIndex(uint32_t index) const
- {
- auto feature = make_unique<FeatureType>();
- if (GetOriginalFeatureByIndex(index, *feature))
- return feature;
-
- return {};
- }
-
- std::unique_ptr<FeatureType> GetOriginalOrEditedFeatureByIndex(uint32_t index) const
- {
- auto feature = make_unique<FeatureType>();
- if (!m_handle.IsAlive())
- return {};
-
- ASSERT_NOT_EQUAL(m_source.GetFeatureStatus(index), FeatureStatus::Created, ());
- if (GetFeatureByIndex(index, *feature))
- return feature;
-
- return {};
- }
-
- /// Everyone, except Editor core, should use this method.
- WARN_UNUSED_RESULT bool GetFeatureByIndex(uint32_t index, FeatureType & ft) const
- {
- if (!m_handle.IsAlive())
- return false;
-
- ASSERT_NOT_EQUAL(
- FeatureStatus::Deleted, m_source.GetFeatureStatus(index),
- ("Deleted feature was cached. It should not be here. Please review your code."));
- if (m_source.GetModifiedFeature(index, ft))
- return true;
- return GetOriginalFeatureByIndex(index, ft);
- }
-
- /// Editor core only method, to get 'untouched', original version of feature.
- WARN_UNUSED_RESULT bool GetOriginalFeatureByIndex(uint32_t index, FeatureType & ft) const
- {
- return m_handle.IsAlive() ? m_source.GetOriginalFeature(index, ft) : false;
- }
-
- size_t GetNumFeatures() const { return m_source.GetNumFeatures(); }
-
- private:
- MwmHandle m_handle;
- FeatureSource m_source;
- };
+private:
+ std::unique_ptr<FeatureSourceFactory> m_factory;
};
-using DataSource = DataSourceImpl<FeatureSource>;
diff --git a/indexer/data_source_helpers.cpp b/indexer/data_source_helpers.cpp
index 210a0af1e9..f17f22072f 100644
--- a/indexer/data_source_helpers.cpp
+++ b/indexer/data_source_helpers.cpp
@@ -6,7 +6,7 @@
namespace indexer
{
-void ForEachFeatureAtPoint(DataSourceBase const & dataSource, function<void(FeatureType &)> && fn,
+void ForEachFeatureAtPoint(DataSource const & dataSource, function<void(FeatureType &)> && fn,
m2::PointD const & mercator, double toleranceInMeters)
{
double constexpr kSelectRectWidthInMeters = 1.1;
diff --git a/indexer/data_source_helpers.hpp b/indexer/data_source_helpers.hpp
index f7dc7a4582..f638e5e5a7 100644
--- a/indexer/data_source_helpers.hpp
+++ b/indexer/data_source_helpers.hpp
@@ -4,11 +4,11 @@
#include "std/function.hpp"
-class DataSourceBase;
+class DataSource;
class FeatureType;
namespace indexer
{
-void ForEachFeatureAtPoint(DataSourceBase const & dataSource, function<void(FeatureType &)> && fn,
+void ForEachFeatureAtPoint(DataSource const & dataSource, function<void(FeatureType &)> && fn,
m2::PointD const & mercator, double toleranceInMeters = 0.0);
}
diff --git a/indexer/feature_source.hpp b/indexer/feature_source.hpp
index 19bc3d6fb4..96f56e8725 100644
--- a/indexer/feature_source.hpp
+++ b/indexer/feature_source.hpp
@@ -50,3 +50,13 @@ protected:
MwmSet::MwmHandle const & m_handle;
std::unique_ptr<FeaturesVector> m_vector;
}; // class FeatureSource
+
+class FeatureSourceFactory
+{
+public:
+ virtual ~FeatureSourceFactory() = default;
+ virtual std::unique_ptr<FeatureSource> operator()(MwmSet::MwmHandle const & handle) const
+ {
+ return std::make_unique<FeatureSource>(handle);
+ }
+};
diff --git a/indexer/indexer_tests/data_source_test.cpp b/indexer/indexer_tests/data_source_test.cpp
index c5b64905da..6bf21c0024 100644
--- a/indexer/indexer_tests/data_source_test.cpp
+++ b/indexer/indexer_tests/data_source_test.cpp
@@ -2,6 +2,7 @@
#include "indexer/data_header.hpp"
#include "indexer/data_source.hpp"
+#include "indexer/feature_source.hpp"
#include "indexer/mwm_set.hpp"
#include "coding/file_name_utils.hpp"
@@ -28,7 +29,10 @@ namespace
class DataSourceTest : public MwmSet::Observer
{
public:
- DataSourceTest() { TEST(m_dataSource.AddObserver(*this), ()); }
+ DataSourceTest() : m_dataSource(make_unique<FeatureSourceFactory>())
+ {
+ TEST(m_dataSource.AddObserver(*this), ());
+ }
~DataSourceTest() override { TEST(m_dataSource.RemoveObserver(*this), ()); }
diff --git a/indexer/indexer_tests/features_vector_test.cpp b/indexer/indexer_tests/features_vector_test.cpp
index ed0fdb80e6..1599d939cb 100644
--- a/indexer/indexer_tests/features_vector_test.cpp
+++ b/indexer/indexer_tests/features_vector_test.cpp
@@ -50,7 +50,7 @@ UNIT_TEST(FeaturesVectorTest_ParseMetadata)
LocalCountryFile localFile = LocalCountryFile::MakeForTesting(kCountryName);
- DataSource dataSource;
+ DataSource dataSource(make_unique<FeatureSourceFactory>());
auto result = dataSource.RegisterMap(localFile);
TEST_EQUAL(result.second, MwmSet::RegResult::Success, ());
diff --git a/indexer/indexer_tests/index_builder_test.cpp b/indexer/indexer_tests/index_builder_test.cpp
index aa60d56f1a..1be95727a2 100644
--- a/indexer/indexer_tests/index_builder_test.cpp
+++ b/indexer/indexer_tests/index_builder_test.cpp
@@ -52,7 +52,7 @@ UNIT_TEST(BuildIndexTest)
{
// Check that index actually works.
- DataSource dataSource;
+ DataSource dataSource(make_unique<FeatureSourceFactory>());
UNUSED_VALUE(dataSource.Register(platform::LocalCountryFile::MakeForTesting("build_index_test")));
// Make sure that index is actually parsed.
diff --git a/indexer/indexer_tests/rank_table_test.cpp b/indexer/indexer_tests/rank_table_test.cpp
index 54f9a78b62..2436eb514c 100644
--- a/indexer/indexer_tests/rank_table_test.cpp
+++ b/indexer/indexer_tests/rank_table_test.cpp
@@ -97,7 +97,7 @@ UNIT_TEST(RankTableBuilder_EndToEnd)
search::RankTableBuilder::Create(ranks, wcont);
}
- DataSource dataSource;
+ DataSource dataSource(make_unique<FeatureSourceFactory>());
auto regResult = dataSource.RegisterMap(localFile);
TEST_EQUAL(regResult.second, MwmSet::RegResult::Success, ());
diff --git a/indexer/indexer_tests/scale_index_reading_tests.cpp b/indexer/indexer_tests/scale_index_reading_tests.cpp
index 4718f14445..0693f084ac 100644
--- a/indexer/indexer_tests/scale_index_reading_tests.cpp
+++ b/indexer/indexer_tests/scale_index_reading_tests.cpp
@@ -54,7 +54,7 @@ public:
[&](uint32_t index) { indices.push_back(index); });
}
- DataSource::FeaturesLoaderGuard loader(m_dataSource, id);
+ DataSource::FeaturesLoaderGuard loader(m_dataSource, id, FeatureSourceFactory());
Names names;
for (auto const & index : indices)
diff --git a/indexer/mwm_set.hpp b/indexer/mwm_set.hpp
index 9e193f31e7..62d708734f 100644
--- a/indexer/mwm_set.hpp
+++ b/indexer/mwm_set.hpp
@@ -29,7 +29,7 @@
class MwmInfo
{
public:
- friend class DataSourceBase;
+ friend class DataSource;
friend class MwmSet;
enum MwmTypeT
@@ -91,7 +91,7 @@ protected:
class MwmInfoEx : public MwmInfo
{
private:
- friend class DataSourceBase;
+ friend class DataSource;
friend class MwmValue;
// weak_ptr is needed here to access offsets table in already
@@ -315,7 +315,7 @@ public:
MwmHandle GetMwmHandleById(MwmId const & id);
/// Now this function looks like workaround, but it allows to avoid ugly const_cast everywhere..
- /// Client code usually holds const reference to DataSourceBase, but implementation is non-const.
+ /// Client code usually holds const reference to DataSource, but implementation is non-const.
/// @todo Actually, we need to define, is this behaviour (getting Handle) const or non-const.
MwmHandle GetMwmHandleById(MwmId const & id) const
{