From 39d18547b95d7dc0bccef93400891e3b80fbf733 Mon Sep 17 00:00:00 2001 From: vng Date: Fri, 23 Sep 2011 18:14:55 +0300 Subject: [PATCH] Different cell coding depth for wmw when indexing. --- indexer/feature_covering.cpp | 27 ++++++++++++++++--- indexer/feature_covering.hpp | 8 ++++-- indexer/index.cpp | 22 +++++++++++++++ indexer/index.hpp | 47 ++++++++++++++++++++++----------- indexer/scale_index_builder.hpp | 4 +-- 5 files changed, 85 insertions(+), 23 deletions(-) diff --git a/indexer/feature_covering.cpp b/indexer/feature_covering.cpp index 66c4054770..01b8436791 100644 --- a/indexer/feature_covering.cpp +++ b/indexer/feature_covering.cpp @@ -2,9 +2,13 @@ #include "cell_coverer.hpp" #include "cell_id.hpp" #include "feature.hpp" +#include "scales.hpp" + #include "../geometry/covering_utils.hpp" + #include "../base/base.hpp" #include "../base/stl_add.hpp" + #include "../std/algorithm.hpp" #include "../std/bind.hpp" #include "../std/vector.hpp" @@ -119,16 +123,16 @@ vector CoverFeature(FeatureType const & f, int cellDepth, uint64_t cell return res; } -IntervalsT SortAndMergeIntervals(IntervalsT v) +void SortAndMergeIntervals(IntervalsT v, IntervalsT & res) { #ifdef DEBUG + ASSERT ( res.empty(), () ); for (size_t i = 0; i < v.size(); ++i) ASSERT_LESS(v[i].first, v[i].second, (i)); #endif sort(v.begin(), v.end()); - IntervalsT res; res.reserve(v.size()); for (size_t i = 0; i < v.size(); ++i) { @@ -137,7 +141,12 @@ IntervalsT SortAndMergeIntervals(IntervalsT v) else res.back().second = max(res.back().second, v[i].second); } +} +IntervalsT SortAndMergeIntervals(IntervalsT const & v) +{ + IntervalsT res; + SortAndMergeIntervals(v, res); return res; } @@ -153,7 +162,7 @@ void AppendLowerLevels(RectId id, int cellDepth, IntervalsT & intervals) } } -IntervalsT CoverViewportAndAppendLowerLevels(m2::RectD const & r, int cellDepth) +void CoverViewportAndAppendLowerLevels(m2::RectD const & r, int cellDepth, IntervalsT & res) { vector ids; CoverRect(r.minX(), r.minY(), r.maxX(), r.maxY(), 8, ids); @@ -164,7 +173,7 @@ IntervalsT CoverViewportAndAppendLowerLevels(m2::RectD const & r, int cellDepth) for (size_t i = 0; i < ids.size(); ++i) AppendLowerLevels(ids[i], cellDepth, intervals); - return SortAndMergeIntervals(intervals); + SortAndMergeIntervals(intervals, res); } RectId GetRectIdAsIs(m2::RectD const & r) @@ -178,4 +187,14 @@ RectId GetRectIdAsIs(m2::RectD const & r) MercatorBounds::ClampY(r.maxY() - eps)); } +int GetCodingDepth(pair const & scalesR) +{ + ASSERT_LESS_OR_EQUAL ( scalesR.first, scalesR.second, () ); + + int const delta = scales::GetUpperScale() - scalesR.second; + ASSERT_GREATER_OR_EQUAL ( delta, 0, () ); + + return (RectId::DEPTH_LEVELS - delta); +} + } diff --git a/indexer/feature_covering.hpp b/indexer/feature_covering.hpp index 955052bd83..8b03e98b73 100644 --- a/indexer/feature_covering.hpp +++ b/indexer/feature_covering.hpp @@ -22,10 +22,14 @@ namespace covering void AppendLowerLevels(RectId id, int cellDepth, IntervalsT & intervals); // Cover viewport with RectIds and append their RectIds as well. - IntervalsT CoverViewportAndAppendLowerLevels(m2::RectD const & rect, int cellDepth); + void CoverViewportAndAppendLowerLevels(m2::RectD const & rect, int cellDepth, + IntervalsT & intervals); // Given a vector of intervals [a, b), sort them and merge overlapping intervals. - IntervalsT SortAndMergeIntervals(IntervalsT intervals); + IntervalsT SortAndMergeIntervals(IntervalsT const & intervals); RectId GetRectIdAsIs(m2::RectD const & r); + + // Calculate cell coding depth according to max visual scale for mwm. + int GetCodingDepth(pair const & scalesR); } diff --git a/indexer/index.cpp b/indexer/index.cpp index f19d7e367d..6087e8cd02 100644 --- a/indexer/index.cpp +++ b/indexer/index.cpp @@ -35,3 +35,25 @@ Index::~Index() { Cleanup(); } + +using namespace covering; + +void Index::GetCovering(m2::RectD const & rect, int mode, int cellDepth, IntervalsT & res) +{ + ASSERT ( res.empty(), () ); + + switch (mode) + { + case 0: + CoverViewportAndAppendLowerLevels(rect, cellDepth, res); + break; + + case 1: + AppendLowerLevels(GetRectIdAsIs(rect), cellDepth, res); + break; + + case 2: + res.push_back(IntervalsT::value_type(0, static_cast((1ULL << 63) - 1))); + break; + } +} diff --git a/indexer/index.hpp b/indexer/index.hpp index ebb13eb5d7..0fc0d5673e 100644 --- a/indexer/index.hpp +++ b/indexer/index.hpp @@ -21,7 +21,10 @@ public: IndexFactory m_factory; MwmValue(string const & name); - feature::DataHeader const & GetHeader() const { return m_factory.GetHeader(); } + inline feature::DataHeader const & GetHeader() const + { + return m_factory.GetHeader(); + } }; class Index : public MwmSet @@ -48,25 +51,19 @@ public: template void ForEachInRect(F & f, m2::RectD const & rect, uint32_t scale) const { - ForEachInIntervals(f, covering::CoverViewportAndAppendLowerLevels(rect, RectId::DEPTH_LEVELS), - rect, scale); + ForEachInIntervals(f, 0, rect, scale); } template void ForEachInRect_TileDrawing(F & f, m2::RectD const & rect, uint32_t scale) const { - covering::IntervalsT intervals; - covering::AppendLowerLevels(covering::GetRectIdAsIs(rect), RectId::DEPTH_LEVELS, intervals); - ForEachInIntervals(f, intervals, rect, scale); + ForEachInIntervals(f, 1, rect, scale); } template void ForEachInScale(F & f, uint32_t scale) const { - covering::IntervalsT intervals; - intervals.push_back(covering::IntervalsT::value_type( - 0, static_cast((1ULL << 63) - 1))); - ForEachInIntervals(f, intervals, m2::RectD::GetInfiniteRect(), scale); + ForEachInIntervals(f, 2, m2::RectD::GetInfiniteRect(), scale); } private: @@ -92,13 +89,22 @@ private: } }; + /// @param[in] mode\n + /// - 0 - cover viewport with low lovels;\n + /// - 1 - cover append low levels only;\n + /// - 2 - make full cover\n + static void GetCovering(m2::RectD const & rect, + int mode, int cellDepth, + covering::IntervalsT & res); template - void ForEachInIntervals(F & f, covering::IntervalsT const & intervals, - m2::RectD const & rect, uint32_t scale) const + void ForEachInIntervals(F & f, int mode, m2::RectD const & rect, uint32_t scale) const { vector mwm; GetMwmInfo(mwm); + + covering::IntervalsT intervals[2]; + for (MwmId id = 0; id < mwm.size(); ++id) { if ((mwm[id].m_minScale <= scale && scale <= mwm[id].m_maxScale) && @@ -108,15 +114,26 @@ private: MwmValue * pValue = lock.GetValue(); if (pValue) { - FeaturesVector fv(pValue->m_cont, pValue->GetHeader()); + feature::DataHeader const & header = pValue->GetHeader(); + + // prepare needed covering + int const cellDepth = covering::GetCodingDepth(header.GetScaleRange()); + int const ind = (cellDepth == RectId::DEPTH_LEVELS ? 0 : 1); + + if (intervals[ind].empty()) + GetCovering(rect, mode, cellDepth, intervals[ind]); + + // prepare features reading + FeaturesVector fv(pValue->m_cont, header); ScaleIndex index(pValue->m_cont.GetReader(INDEX_FILE_TAG), pValue->m_factory); + // iterate through intervals unordered_set offsets; ReadFeatureFunctor f1(fv, f, offsets); - for (size_t i = 0; i < intervals.size(); ++i) + for (size_t i = 0; i < intervals[ind].size(); ++i) { - index.ForEachInIntervalAndScale(f1, intervals[i].first, intervals[i].second, scale); + index.ForEachInIntervalAndScale(f1, intervals[ind][i].first, intervals[ind][i].second, scale); } } } diff --git a/indexer/scale_index_builder.hpp b/indexer/scale_index_builder.hpp index bd8a0346ad..a28530d959 100644 --- a/indexer/scale_index_builder.hpp +++ b/indexer/scale_index_builder.hpp @@ -71,8 +71,8 @@ public: { if (FeatureShouldBeIndexed(f)) { - /// @todo Use m_mwmScaleRange to make better covering. - vector const cells = covering::CoverFeature(f, RectId::DEPTH_LEVELS, 250); + vector const cells = covering::CoverFeature(f, + covering::GetCodingDepth(m_mwmScaleRange), 250); for (vector::const_iterator it = cells.begin(); it != cells.end(); ++it) m_Sorter.Add(CellFeaturePair(*it, offset));