diff --git a/indexer/categories_holder.hpp b/indexer/categories_holder.hpp index ab62ca0d21..e756aab61e 100644 --- a/indexer/categories_holder.hpp +++ b/indexer/categories_holder.hpp @@ -34,11 +34,12 @@ public: private: typedef strings::UniString StringT; - typedef multimap > ContainerT; - typedef ContainerT::const_iterator IteratorT; + typedef multimap > Type2CategoryContT; + typedef multimap Name2CatContT; + typedef Type2CategoryContT::const_iterator IteratorT; - multimap > m_type2cat; - multimap m_name2type; + Type2CategoryContT m_type2cat; + Name2CatContT m_name2type; public: CategoriesHolder() {} @@ -65,7 +66,7 @@ public: template void ForEachTypeByName(StringT const & name, ToDo toDo) const { - typedef typename multimap::const_iterator IterT; + typedef typename Name2CatContT::const_iterator IterT; pair range = m_name2type.equal_range(name); while (range.first != range.second) diff --git a/indexer/search_index_builder.cpp b/indexer/search_index_builder.cpp index 16cc651df8..42aa6cd47a 100644 --- a/indexer/search_index_builder.cpp +++ b/indexer/search_index_builder.cpp @@ -336,6 +336,8 @@ public: if (types.Empty()) return; + Classificator const & c = classif(); + // add names of categories of the feature for (size_t i = 0; i < types.Size(); ++i) { @@ -354,7 +356,8 @@ public: if (my::between_s(m_scales.first, m_scales.second, r.first) || my::between_s(m_scales.first, m_scales.second, r.second)) { - inserter.AddToken(search::CATEGORIES_LANG, search::FeatureTypeToString(type)); + inserter.AddToken(search::CATEGORIES_LANG, + search::FeatureTypeToString(c.GetIndexForType(type))); } } } diff --git a/map/framework.cpp b/map/framework.cpp index b058cfaf73..07a1c6b994 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -66,11 +66,11 @@ void Framework::AddMap(string const & file) //threads::MutexGuard lock(m_modelSyn); int const version = m_model.AddMap(file); + if (m_lowestMapVersion > version) + m_lowestMapVersion = version; // Now we do force delete of old (April 2011) maps. - //if (m_lowestMapVersion == -1 || (version != -1 && m_lowestMapVersion > version)) - // m_lowestMapVersion = version; - if (version == 0) + if (version == feature::DataHeader::v1) { LOG(LINFO, ("Deleting old map:", file)); RemoveMap(file); @@ -78,10 +78,10 @@ void Framework::AddMap(string const & file) } } -void Framework::RemoveMap(string const & datFile) +void Framework::RemoveMap(string const & file) { //threads::MutexGuard lock(m_modelSyn); - m_model.RemoveMap(datFile); + m_model.RemoveMap(file); } void Framework::StartLocation() @@ -183,7 +183,7 @@ Framework::Framework() m_width(0), m_height(0), m_informationDisplay(this), - //m_lowestMapVersion(-1), + m_lowestMapVersion(numeric_limits::max()), m_benchmarkEngine(0) { // Checking whether we should enable benchmark. @@ -226,27 +226,27 @@ Framework::Framework() m_model.InitClassificator(); - // To avoid possible races - init search engine once in constructor. - (void)GetSearchEngine(); - // Get all available maps. vector maps; GetResourcesMaps(maps); #ifndef OMIM_OS_ANDROID - // On Android, local maps are added and removed when - // external storage is connected/disconnected. + // On Android, local maps are added and removed when external storage is connected/disconnected. GetLocalMaps(maps); #endif - // Remove duplicate maps if they're both present in resources and in WritableDir + // Remove duplicate maps if they're both present in resources and in WritableDir. sort(maps.begin(), maps.end()); maps.erase(unique(maps.begin(), maps.end()), maps.end()); + // Add founded maps to index. for_each(maps.begin(), maps.end(), bind(&Framework::AddMap, this, _1)); // Init storage with needed callback. m_storage.Init(bind(&Framework::UpdateAfterDownload, this, _1)); + // To avoid possible races - init search engine once in constructor. + (void)GetSearchEngine(); + LOG(LDEBUG, ("Storage initialized")); } @@ -358,6 +358,8 @@ void Framework::AddLocalMaps() GetLocalMaps(maps); for_each(maps.begin(), maps.end(), bind(&Framework::AddMap, this, _1)); + + m_pSearchEngine->SupportOldFormat(m_lowestMapVersion < feature::DataHeader::v3); } void Framework::RemoveLocalMaps() @@ -1283,11 +1285,14 @@ search::Engine * Framework::GetSearchEngine() const try { - m_pSearchEngine.reset(new search::Engine(&m_model.GetIndex(), - pl.GetReader(SEARCH_CATEGORIES_FILE_NAME), - pl.GetReader(PACKED_POLYGONS_FILE), - pl.GetReader(COUNTRIES_FILE), - languages::CurrentLanguage())); + m_pSearchEngine.reset(new search::Engine( + &m_model.GetIndex(), + pl.GetReader(SEARCH_CATEGORIES_FILE_NAME), + pl.GetReader(PACKED_POLYGONS_FILE), + pl.GetReader(COUNTRIES_FILE), + languages::CurrentLanguage())); + + m_pSearchEngine->SupportOldFormat(m_lowestMapVersion < feature::DataHeader::v3); } catch (RootException const & e) { @@ -1449,36 +1454,6 @@ void Framework::SetupMeasurementSystem() Invalidate(); } -/* -// 0 - old April version which we should delete -#define MAXIMUM_VERSION_TO_DELETE 0 - -bool Framework::NeedToDeleteOldMaps() const -{ - return m_lowestMapVersion == MAXIMUM_VERSION_TO_DELETE; -} - -void Framework::DeleteOldMaps() -{ - Platform & p = GetPlatform(); - vector maps; - p.GetFilesByExt(p.WritableDir(), DATA_FILE_EXTENSION, maps); - for (vector::iterator it = maps.begin(); it != maps.end(); ++it) - { - feature::DataHeader header; - LoadMapHeader(p.GetReader(*it), header); - if (header.GetVersion() <= MAXIMUM_VERSION_TO_DELETE) - { - LOG(LINFO, ("Deleting old map", *it)); - RemoveMap(*it); - FileWriter::DeleteFileX(p.WritablePathForFile(*it)); - InvalidateRect(header.GetBounds()); - } - } - m_lowestMapVersion = MAXIMUM_VERSION_TO_DELETE + 1; -} -*/ - string Framework::GetCountryCode(m2::PointD const & pt) const { return GetSearchEngine()->GetCountryCode(pt); diff --git a/map/framework.hpp b/map/framework.hpp index d8f9ac4572..7641276527 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -125,10 +125,9 @@ protected: return 0.0; } - /// Stores lowest loaded map version - /// Holds -1 if no maps were added + /// Stores lowest loaded map version or MAX_INT if no maps added. /// @see feature::DataHeader::Version - //int m_lowestMapVersion; + int m_lowestMapVersion; void DrawAdditionalInfo(shared_ptr const & e); @@ -136,21 +135,13 @@ protected: void ClearAllCaches(); + void AddMap(string const & file); + void RemoveMap(string const & file); + public: Framework(); virtual ~Framework(); - /* - /// @name Used on iPhone for upgrade from April 1.0.1 version - //@{ - /// @return true if client should display delete old maps dialog before using downloader - bool NeedToDeleteOldMaps() const; - void DeleteOldMaps(); - //@} - */ - - void AddMap(string const & file); - void RemoveMap(string const & datFile); bool IsCategoryExist(string const & name); /// @name Process storage connecting/disconnecting. //@{ diff --git a/search/search_engine.cpp b/search/search_engine.cpp index 4e828dfdcf..aafedb49a4 100644 --- a/search/search_engine.cpp +++ b/search/search_engine.cpp @@ -94,6 +94,11 @@ Engine::~Engine() { } +void Engine::SupportOldFormat(bool b) +{ + m_pQuery->SupportOldFormat(b); +} + namespace { m2::PointD GetViewportXY(double lat, double lon) diff --git a/search/search_engine.hpp b/search/search_engine.hpp index 8de965c350..6fc0643377 100644 --- a/search/search_engine.hpp +++ b/search/search_engine.hpp @@ -36,6 +36,8 @@ public: string const & lang); ~Engine(); + void SupportOldFormat(bool b); + void PrepareSearch(m2::RectD const & viewport, bool hasPt, double lat, double lon); bool Search(SearchParams const & params, m2::RectD const & viewport); diff --git a/search/search_query.cpp b/search/search_query.cpp index af5acf86c6..3b2c0547dd 100644 --- a/search/search_query.cpp +++ b/search/search_query.cpp @@ -213,8 +213,8 @@ void Query::UpdateViewportOffsets(MWMVectorT const & mwmInfo, m2::RectD const & Index::MwmLock mwmLock(*m_pIndex, mwmId); if (MwmValue * pMwm = mwmLock.GetValue()) { - feature::DataHeader const & header = pMwm->GetHeader(); - if (header.GetType() == feature::DataHeader::country) + FHeaderT const & header = pMwm->GetHeader(); + if (header.GetType() == FHeaderT::country) { pair const scaleR = header.GetScaleRange(); int const scale = min(max(viewScale + SCALE_SEARCH_DEPTH, scaleR.first), scaleR.second); @@ -653,21 +653,184 @@ public: namespace { + typedef vector TokensVectorT; -typedef vector TokensVectorT; - -class DoInsertTypeNames -{ - TokensVectorT & m_tokens; - -public: - DoInsertTypeNames(TokensVectorT & tokens) : m_tokens(tokens) {} - void operator() (uint32_t t) + class DoInsertTypeNames { - m_tokens.push_back(FeatureTypeToString(t)); - } -}; + Classificator const & m_c; + TokensVectorT & m_tokens; + bool m_supportOldFormat; + static int GetOldTypeFromIndex(size_t index) + { + // "building" has old type value = 70 + ASSERT_NOT_EQUAL(index, 70, ()); + + switch (index) + { + case 156: return 4099; + case 98: return 4163; + case 374: return 4419; + case 188: return 4227; + case 100: return 6147; + case 107: return 4547; + case 96: return 5059; + case 60: return 6275; + case 66: return 5251; + case 161: return 4120; + case 160: return 4376; + case 159: return 4568; + case 16: return 4233; + case 178: return 5654; + case 227: return 4483; + case 111: return 5398; + case 256: return 5526; + case 702: return 263446; + case 146: return 4186; + case 155: return 4890; + case 141: return 4570; + case 158: return 4762; + case 38: return 5891; + case 63: return 4291; + case 270: return 4355; + case 327: return 4675; + case 704: return 4611; + case 242: return 4739; + case 223: return 4803; + case 174: return 4931; + case 137: return 5123; + case 186: return 5187; + case 250: return 5315; + case 104: return 4299; + case 113: return 5379; + case 206: return 4867; + case 184: return 5443; + case 125: return 5507; + case 170: return 5571; + case 25: return 5763; + case 118: return 5827; + case 76: return 6019; + case 116: return 6083; + case 108: return 6211; + case 35: return 6339; + case 180: return 6403; + case 121: return 6595; + case 243: return 6659; + case 150: return 6723; + case 175: return 6851; + case 600: return 4180; + case 348: return 4244; + case 179: return 4116; + case 77: return 4884; + case 387: return 262164; + case 214: return 4308; + case 289: return 4756; + case 264: return 4692; + case 93: return 4500; + case 240: return 4564; + case 127: return 4820; + case 29: return 4436; + case 20: return 4948; + case 18: return 4628; + case 293: return 4372; + case 22: return 4571; + case 3: return 4699; + case 51: return 4635; + case 89: return 4123; + case 307: return 5705; + case 15: return 5321; + case 6: return 4809; + case 58: return 6089; + case 26: return 5513; + case 187: return 5577; + case 1: return 5769; + case 12: return 5897; + case 244: return 5961; + case 8: return 6153; + case 318: return 6217; + case 2: return 6025; + case 30: return 5833; + case 7: return 6281; + case 65: return 6409; + case 221: return 6473; + case 54: return 4937; + case 69: return 5385; + case 4: return 6537; + case 200: return 5257; + case 195: return 5129; + case 120: return 5193; + case 56: return 5904; + case 5: return 6864; + case 169: return 4171; + case 61: return 5707; + case 575: return 5968; + case 563: return 5456; + case 13: return 6992; + case 10: return 4811; + case 109: return 4236; + case 67: return 4556; + case 276: return 4442; + case 103: return 4506; + case 183: return 4440; + case 632: return 4162; + case 135: return 4098; + case 205: return 5004; + case 87: return 4684; + case 164: return 4940; + case 201: return 4300; + case 68: return 4620; + case 101: return 5068; + case 0: return 70; + case 737: return 4102; + case 703: return 5955; + case 705: return 6531; + case 706: return 5635; + case 707: return 5699; + case 708: return 4995; + case 715: return 4298; + case 717: return 4362; + case 716: return 4490; + case 718: return 4234; + case 719: return 4106; + case 722: return 4240; + case 723: return 6480; + case 725: return 4312; + case 726: return 4248; + case 727: return 4184; + case 728: return 4504; + case 732: return 4698; + case 733: return 4378; + case 734: return 4634; + case 166: return 4250; + case 288: return 4314; + case 274: return 4122; + } + return -1; + } + + public: + DoInsertTypeNames(TokensVectorT & tokens, bool supportOldFormat) + : m_c(classif()), m_tokens(tokens), m_supportOldFormat(supportOldFormat) + { + } + void operator() (uint32_t t) + { + uint32_t const index = m_c.GetIndexForType(t); + m_tokens.push_back(FeatureTypeToString(index)); + + // v2-version MWM has raw classificator types in search index prefix, so + // do the hack: add synonyms for old convention if needed. + if (m_supportOldFormat) + { + int const type = GetOldTypeFromIndex(index); + if (type >= 0) + { + ASSERT ( type == 70 || type > 4000, (type)); + m_tokens.push_back(FeatureTypeToString(static_cast(type))); + } + } + } + }; } // namespace search::impl Query::Params::Params(Query const & q, bool isLocalities/* = false*/) @@ -686,10 +849,10 @@ Query::Params::Params(Query const & q, bool isLocalities/* = false*/) if (q.m_pCategories && !isLocalities) { for (size_t i = 0; i < tokensCount; ++i) - q.m_pCategories->ForEachTypeByName(q.m_tokens[i], DoInsertTypeNames(m_tokens[i])); + q.m_pCategories->ForEachTypeByName(q.m_tokens[i], DoInsertTypeNames(m_tokens[i], q.m_supportOldFormat)); if (!q.m_prefix.empty()) - q.m_pCategories->ForEachTypeByName(q.m_prefix, DoInsertTypeNames(m_prefixTokens)); + q.m_pCategories->ForEachTypeByName(q.m_prefix, DoInsertTypeNames(m_prefixTokens, q.m_supportOldFormat)); } FillLanguages(q); @@ -1021,7 +1184,7 @@ void Query::SearchAddress() MwmValue * pMwm = mwmLock.GetValue(); if (pMwm && pMwm->m_cont.IsReaderExist(SEARCH_INDEX_FILE_TAG) && - pMwm->GetHeader().GetType() == feature::DataHeader::world) + pMwm->GetHeader().GetType() == FHeaderT::world) { impl::Locality city; impl::Region region; @@ -1532,10 +1695,10 @@ void Query::SearchInMWM(Index::MwmLock const & mwmLock, Params const & params, i { if (pMwm->m_cont.IsReaderExist(SEARCH_INDEX_FILE_TAG)) { - feature::DataHeader const & header = pMwm->GetHeader(); + FHeaderT const & header = pMwm->GetHeader(); /// @todo do not process World.mwm here - do it in SearchLocality - bool const isWorld = (header.GetType() == feature::DataHeader::world); + bool const isWorld = (header.GetType() == FHeaderT::world); if (isWorld && !m_worldSearch) return; diff --git a/search/search_query.hpp b/search/search_query.hpp index 122c525036..ed97763c51 100644 --- a/search/search_query.hpp +++ b/search/search_query.hpp @@ -64,6 +64,8 @@ public: size_t resultsNeeded = 10); ~Query(); + inline void SupportOldFormat(bool b) { m_supportOldFormat = b; } + void Init(); void SetViewport(m2::RectD viewport[], size_t count); @@ -139,6 +141,7 @@ private: typedef vector MWMVectorT; typedef vector > OffsetsVectorT; + typedef feature::DataHeader FHeaderT; void SetViewportByIndex(MWMVectorT const & mwmInfo, m2::RectD const & viewport, size_t idx); void UpdateViewportOffsets(MWMVectorT const & mwmInfo, m2::RectD const & rect, @@ -212,6 +215,7 @@ private: KeywordLangMatcher m_keywordsScorer; OffsetsVectorT m_offsetsInViewport[RECTSCOUNT]; + bool m_supportOldFormat; template class CompareT {