diff options
author | vng <viktor.govako@gmail.com> | 2011-12-22 19:51:22 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 01:30:58 +0300 |
commit | 4679671ca0cdcf845ab1e05e70e4f8d0fe1aab07 (patch) | |
tree | 7e3786c6d491cb15256f021559a79f9909244da4 /storage | |
parent | 591df2661b12ebe7fc377048f77355953ab0177d (diff) |
[search] Add cache of regions to CountryInfoGetter.
Diffstat (limited to 'storage')
-rw-r--r-- | storage/country_info.cpp | 39 | ||||
-rw-r--r-- | storage/country_info.hpp | 8 |
2 files changed, 38 insertions, 9 deletions
diff --git a/storage/country_info.cpp b/storage/country_info.cpp index 7eaf7a5198..ea5fd4f577 100644 --- a/storage/country_info.cpp +++ b/storage/country_info.cpp @@ -13,7 +13,7 @@ namespace storage { CountryInfoGetter::CountryInfoGetter(ModelReaderPtr polyR, ModelReaderPtr countryR) - : m_reader(polyR) + : m_reader(polyR), m_cache(2) { ReaderSource<ModelReaderPtr> src(m_reader.GetReader(PACKED_POLYGONS_INFO_TAG)); rw::Read(src, m_countries); @@ -34,16 +34,11 @@ namespace storage bool CountryInfoGetter::GetByPoint::operator() (size_t id) { - ReaderSource<ModelReaderPtr> src(m_info.m_reader.GetReader(strings::to_string(id))); + vector<m2::RegionD> const & rgnV = m_info.GetRegions(id); - uint32_t const count = ReadVarUint<uint32_t>(src); - for (size_t i = 0; i < count; ++i) + for (size_t i = 0; i < rgnV.size(); ++i) { - vector<m2::PointD> points; - serial::LoadOuterPath(src, serial::CodingParams(), points); - - m2::RegionD rgn(points.begin(), points.end()); - if (rgn.Contains(m_pt)) + if (rgnV[i].Contains(m_pt)) { m_res = id; return false; @@ -53,6 +48,32 @@ namespace storage return true; } + vector<m2::RegionD> const & CountryInfoGetter::GetRegions(size_t id) const + { + bool isFound = false; + vector<m2::RegionD> & rgnV = m_cache.Find(id, isFound); + + if (!isFound) + { + rgnV.clear(); + + // load regions from file + ReaderSource<ModelReaderPtr> src(m_reader.GetReader(strings::to_string(id))); + + uint32_t const count = ReadVarUint<uint32_t>(src); + for (size_t i = 0; i < count; ++i) + { + vector<m2::PointD> points; + serial::LoadOuterPath(src, serial::CodingParams(), points); + + rgnV.push_back(m2::RegionD()); + rgnV.back().Assign(points.begin(), points.end()); + } + } + + return rgnV; + } + string CountryInfoGetter::GetRegionFile(m2::PointD const & pt) const { GetByPoint doGet(*this, pt); diff --git a/storage/country_info.hpp b/storage/country_info.hpp index 4c4a3fd41e..6923040b8e 100644 --- a/storage/country_info.hpp +++ b/storage/country_info.hpp @@ -1,8 +1,12 @@ #pragma once #include "country_polygon.hpp" +#include "../geometry/region2d.hpp" + #include "../coding/file_container.hpp" +#include "../base/cache.hpp" + namespace storage { @@ -13,6 +17,10 @@ namespace storage vector<CountryDef> m_countries; map<string, string> m_id2name; + mutable my::Cache<uint32_t, vector<m2::RegionD> > m_cache; + + vector<m2::RegionD> const & GetRegions(size_t id) const; + template <class ToDo> void ForEachCountry(m2::PointD const & pt, ToDo & toDo) const; |