forked from organicmaps/organicmaps
CountryInfoGetter::GetRegionInfo - extended country information (name, flag, ...)
This commit is contained in:
parent
97f58f98a4
commit
d960e0e43f
9 changed files with 129 additions and 70 deletions
|
@ -261,12 +261,14 @@ string IntermediateResult::DebugPrint() const
|
|||
|
||||
string IntermediateResult::RegionInfo::GetRegion(storage::CountryInfoGetter const * pInfo) const
|
||||
{
|
||||
storage::CountryInfo info;
|
||||
|
||||
if (!m_file.empty())
|
||||
return pInfo->GetRegionName(m_file);
|
||||
pInfo->GetRegionInfo(m_file, info);
|
||||
else if (m_valid)
|
||||
return pInfo->GetRegionName(m_point);
|
||||
else
|
||||
return string();
|
||||
pInfo->GetRegionInfo(m_point, info);
|
||||
|
||||
return info.m_name;
|
||||
}
|
||||
|
||||
} // namespace search::impl
|
||||
|
|
|
@ -142,24 +142,45 @@ namespace
|
|||
}
|
||||
};
|
||||
|
||||
class DoStoreFile2Name
|
||||
class DoStoreFile2Info
|
||||
{
|
||||
map<string, string> & m_file2name;
|
||||
public:
|
||||
DoStoreFile2Name(map<string, string> & file2name) : m_file2name(file2name) {}
|
||||
map<string, CountryInfo> & m_file2info;
|
||||
string m_lastFlag;
|
||||
|
||||
void operator() (string name, string const & file, string const &,
|
||||
public:
|
||||
DoStoreFile2Info(map<string, CountryInfo> & file2info) : m_file2info(file2info) {}
|
||||
|
||||
void operator() (string name, string file, string const & flag,
|
||||
uint32_t size, int64_t, int)
|
||||
{
|
||||
// if 'file' is empty - it's equal to name
|
||||
if (size && !file.empty())
|
||||
{
|
||||
size_t const i = file.find_first_of('_');
|
||||
if (i != string::npos)
|
||||
name = file.substr(0, i) + '_' + name;
|
||||
if (!flag.empty())
|
||||
m_lastFlag = flag;
|
||||
|
||||
if (name != file)
|
||||
m_file2name[file] = name;
|
||||
if (size)
|
||||
{
|
||||
CountryInfo info;
|
||||
|
||||
// if 'file' is empty - it's equal to 'name'
|
||||
if (!file.empty())
|
||||
{
|
||||
// make compound name: country_region
|
||||
size_t const i = file.find_first_of('_');
|
||||
if (i != string::npos)
|
||||
name = file.substr(0, i) + '_' + name;
|
||||
|
||||
// fill 'name' only when it differs with 'file'
|
||||
if (name != file)
|
||||
info.m_name.swap(name);
|
||||
}
|
||||
else
|
||||
file.swap(name);
|
||||
|
||||
// Do not use 'name' here! It was swapped!
|
||||
|
||||
ASSERT ( !m_lastFlag.empty(), () );
|
||||
info.m_flag = m_lastFlag;
|
||||
|
||||
m_file2info[file] = info;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -185,10 +206,10 @@ int64_t LoadCountries(string const & jsonBuffer, CountriesContainerT & countries
|
|||
return LoadCountriesImpl(jsonBuffer, doStore);
|
||||
}
|
||||
|
||||
void LoadCountryFile2Name(string const & jsonBuffer, map<string, string> & id2name)
|
||||
void LoadCountryFile2CountryInfo(string const & jsonBuffer, map<string, CountryInfo> & id2info)
|
||||
{
|
||||
ASSERT ( id2name.empty(), () );
|
||||
DoStoreFile2Name doStore(id2name);
|
||||
ASSERT ( id2info.empty(), () );
|
||||
DoStoreFile2Info doStore(id2info);
|
||||
LoadCountriesImpl(jsonBuffer, doStore);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "simple_tree.hpp"
|
||||
#include "country_decl.hpp"
|
||||
|
||||
#include "../defines.hpp"
|
||||
|
||||
|
@ -40,7 +41,7 @@ namespace storage
|
|||
class Country
|
||||
{
|
||||
friend class update::SizeUpdater;
|
||||
/// Name in the coutry node tree
|
||||
/// Name in the country node tree
|
||||
string m_name;
|
||||
/// Flag to display
|
||||
string m_flag;
|
||||
|
@ -70,7 +71,7 @@ namespace storage
|
|||
|
||||
/// @return version of country file or -1 if error was encountered
|
||||
int64_t LoadCountries(string const & jsonBuffer, CountriesContainerT & countries);
|
||||
void LoadCountryFile2Name(string const & jsonBuffer, map<string, string> & id2name);
|
||||
void LoadCountryFile2CountryInfo(string const & jsonBuffer, map<string, CountryInfo> & id2info);
|
||||
void LoadCountryCode2File(string const & jsonBuffer, multimap<string, string> & code2file);
|
||||
|
||||
bool SaveCountries(int64_t version, CountriesContainerT const & countries, string & jsonBuffer);
|
||||
|
|
33
storage/country_decl.hpp
Normal file
33
storage/country_decl.hpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include "../geometry/rect2d.hpp"
|
||||
|
||||
#include "../std/string.hpp"
|
||||
|
||||
|
||||
namespace storage
|
||||
{
|
||||
struct CountryDef
|
||||
{
|
||||
string m_name;
|
||||
m2::RectD m_rect;
|
||||
|
||||
CountryDef() {}
|
||||
CountryDef(string const & name, m2::RectD const & r)
|
||||
: m_name(name), m_rect(r)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct CountryInfo
|
||||
{
|
||||
/// Name (in native language) of country or region.
|
||||
/// (if empty - equals to file name of country - no additional memory)
|
||||
string m_name;
|
||||
|
||||
/// Flag of country or region.
|
||||
string m_flag;
|
||||
|
||||
bool IsNotEmpty() const { return !m_flag.empty(); }
|
||||
};
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
#include "country_info.hpp"
|
||||
#include "country_polygon.hpp"
|
||||
#include "country.hpp"
|
||||
|
||||
#include "../indexer/geometry_serialization.hpp"
|
||||
|
@ -20,7 +21,7 @@ namespace storage
|
|||
|
||||
string buffer;
|
||||
countryR.ReadAsString(buffer);
|
||||
LoadCountryFile2Name(buffer, m_id2name);
|
||||
LoadCountryFile2CountryInfo(buffer, m_id2info);
|
||||
}
|
||||
|
||||
template <class ToDo>
|
||||
|
@ -85,38 +86,33 @@ namespace storage
|
|||
return string();
|
||||
}
|
||||
|
||||
string CountryInfoGetter::GetRegionName(m2::PointD const & pt) const
|
||||
void CountryInfoGetter::GetRegionInfo(m2::PointD const & pt, CountryInfo & info) const
|
||||
{
|
||||
GetByPoint doGet(*this, pt);
|
||||
ForEachCountry(pt, doGet);
|
||||
|
||||
if (doGet.m_res != -1)
|
||||
return GetRegionName(m_countries[doGet.m_res].m_name);
|
||||
|
||||
return string();
|
||||
GetRegionInfo(m_countries[doGet.m_res].m_name, info);
|
||||
}
|
||||
|
||||
string CountryInfoGetter::GetRegionName(string const & id) const
|
||||
void CountryInfoGetter::GetRegionInfo(string const & id, CountryInfo & info) const
|
||||
{
|
||||
string name;
|
||||
map<string, CountryInfo>::const_iterator i = m_id2info.find(id);
|
||||
ASSERT ( i != m_id2info.end(), () );
|
||||
|
||||
map<string, string>::const_iterator i = m_id2name.find(id);
|
||||
if (i != m_id2name.end())
|
||||
name = i->second;
|
||||
else
|
||||
name = id;
|
||||
info = i->second;
|
||||
|
||||
if (info.m_name.empty())
|
||||
info.m_name = id;
|
||||
|
||||
/// @todo Correct replace '_' with ", " in name.
|
||||
if (id.find_first_of('_') != string::npos)
|
||||
{
|
||||
// I don't know how to do it best for UTF8, but this variant will work
|
||||
// correctly for now (utf8-names of compound countries are equal to ascii-names).
|
||||
size_t const i = info.m_name.find_first_of('_');
|
||||
ASSERT ( i != string::npos, () );
|
||||
|
||||
size_t const i = name.find_first_of('_');
|
||||
ASSERT_NOT_EQUAL ( i, string::npos, () );
|
||||
name = name.substr(0, i) + ", " + name.substr(i+1);
|
||||
// replace '_' with ", "
|
||||
info.m_name[i] = ',';
|
||||
info.m_name.insert(i+1, " ");
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include "country_polygon.hpp"
|
||||
|
||||
#include "country_decl.hpp"
|
||||
|
||||
#include "../geometry/region2d.hpp"
|
||||
|
||||
|
@ -15,7 +16,7 @@ namespace storage
|
|||
FilesContainerR m_reader;
|
||||
|
||||
vector<CountryDef> m_countries;
|
||||
map<string, string> m_id2name;
|
||||
map<string, CountryInfo> m_id2info;
|
||||
|
||||
mutable my::Cache<uint32_t, vector<m2::RegionD> > m_cache;
|
||||
|
||||
|
@ -41,7 +42,8 @@ namespace storage
|
|||
CountryInfoGetter(ModelReaderPtr polyR, ModelReaderPtr countryR);
|
||||
|
||||
string GetRegionFile(m2::PointD const & pt) const;
|
||||
string GetRegionName(m2::PointD const & pt) const;
|
||||
string GetRegionName(string const & id) const;
|
||||
|
||||
void GetRegionInfo(m2::PointD const & pt, CountryInfo & info) const;
|
||||
void GetRegionInfo(string const & id, CountryInfo & info) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,28 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include "country_decl.hpp"
|
||||
|
||||
#include "../indexer/point_to_int64.hpp"
|
||||
#include "../indexer/coding_params.hpp"
|
||||
|
||||
#include "../geometry/rect2d.hpp"
|
||||
|
||||
#include "../coding/read_write_utils.hpp"
|
||||
|
||||
|
||||
namespace storage
|
||||
{
|
||||
struct CountryDef
|
||||
{
|
||||
string m_name;
|
||||
m2::RectD m_rect;
|
||||
|
||||
CountryDef() {}
|
||||
CountryDef(string const & name, m2::RectD const & r)
|
||||
: m_name(name), m_rect(r)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <class TSource> void Read(TSource & src, CountryDef & p)
|
||||
{
|
||||
rw::Read(src, p.m_name);
|
||||
|
|
|
@ -18,6 +18,7 @@ HEADERS += \
|
|||
storage.hpp \
|
||||
country_polygon.hpp \
|
||||
country_info.hpp \
|
||||
country_decl.hpp \
|
||||
|
||||
SOURCES += \
|
||||
country.cpp \
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "../../platform/platform.hpp"
|
||||
|
||||
|
||||
using namespace storage;
|
||||
|
||||
UNIT_TEST(CountryInfo_GetByPoint_Smoke)
|
||||
{
|
||||
Platform & pl = GetPlatform();
|
||||
|
@ -16,9 +18,23 @@ UNIT_TEST(CountryInfo_GetByPoint_Smoke)
|
|||
pl.GetReader(COUNTRIES_FILE));
|
||||
|
||||
// Minsk
|
||||
TEST_EQUAL(getter.GetRegionName(
|
||||
m2::PointD(MercatorBounds::LonToX(27.5618818),
|
||||
MercatorBounds::LatToY(53.9022651))), "Belarus", ());
|
||||
CountryInfo info;
|
||||
getter.GetRegionInfo(m2::PointD(MercatorBounds::LonToX(27.5618818),
|
||||
MercatorBounds::LatToY(53.9022651)),
|
||||
info);
|
||||
|
||||
TEST_EQUAL(info.m_name, "Belarus", ());
|
||||
TEST_EQUAL(info.m_flag, "by", ());
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
bool IsEmptyName(map<string, CountryInfo> const & id2info, string const & id)
|
||||
{
|
||||
map<string, CountryInfo>::const_iterator i = id2info.find(id);
|
||||
TEST(i != id2info.end(), ());
|
||||
return i->second.m_name.empty();
|
||||
}
|
||||
}
|
||||
|
||||
UNIT_TEST(CountryInfo_ValidName_Smoke)
|
||||
|
@ -26,12 +42,12 @@ UNIT_TEST(CountryInfo_ValidName_Smoke)
|
|||
string buffer;
|
||||
ReaderPtr<Reader>(GetPlatform().GetReader(COUNTRIES_FILE)).ReadAsString(buffer);
|
||||
|
||||
map<string, string> id2name;
|
||||
storage::LoadCountryFile2Name(buffer, id2name);
|
||||
map<string, CountryInfo> id2info;
|
||||
storage::LoadCountryFile2CountryInfo(buffer, id2info);
|
||||
|
||||
TEST(id2name.count("Germany_Baden-Wurttemberg") == 1, ());
|
||||
TEST(id2name.count("France_Paris & Ile-de-France") == 1, ());
|
||||
TEST(!IsEmptyName(id2info, "Germany_Baden-Wurttemberg"), ());
|
||||
TEST(!IsEmptyName(id2info, "France_Paris & Ile-de-France"), ());
|
||||
|
||||
TEST(id2name.count("Russia_Far Eastern") == 0, ());
|
||||
TEST(id2name.count("UK_Northern Ireland") == 0, ());
|
||||
TEST(IsEmptyName(id2info, "Russia_Far Eastern"), ());
|
||||
TEST(IsEmptyName(id2info, "UK_Northern Ireland"), ());
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue