Added more locality types to IsLocalityChecker.

This commit is contained in:
Denis Koronchik 2014-06-27 20:00:17 +03:00 committed by Alex Zolotarev
parent 30d2be0a4b
commit 181957e344
3 changed files with 72 additions and 29 deletions

View file

@ -73,57 +73,83 @@ IsLocalityChecker::IsLocalityChecker()
{
Classificator const & c = classif();
// Note! The order should be equal with constants in Type enum (add other villages to the end).
char const * arr[][2] = {
{ "place", "country" },
{ "place", "state" },
{ "place", "city" },
{ "place", "town" }
{ "place", "town" },
{ "place", "village" },
{ "place", "hamlet" }
};
for (size_t i = 0; i < ARRAY_SIZE(arr); ++i)
m_types.push_back(c.GetTypeByPath(vector<string>(arr[i], arr[i] + 2)));
}
Type IsLocalityChecker::GetLocalityType(feature::TypesHolder const & types) const
Type IsLocalityChecker::GetType(feature::TypesHolder const & types) const
{
for (size_t i = 0; i < types.Size(); ++i)
{
uint32_t t = types[i];
ftype::TruncValue(t, 2);
if (t == m_types[0])
return COUNTRY;
if (t == m_types[1])
return STATE;
for (int j = 2; j < m_types.size(); ++j)
size_t j = COUNTRY;
for (; j < LOCALITY_COUNT; ++j)
if (t == m_types[j])
return CITY;
return static_cast<Type>(j);
for (; j < m_types.size(); ++j)
if (t == m_types[j])
return VILLAGE;
}
return NONE;
}
Type IsLocalityChecker::GetLocalityType(const FeatureType & f) const
Type IsLocalityChecker::GetType(const FeatureType & f) const
{
feature::TypesHolder types(f);
return GetLocalityType(types);
return GetType(types);
}
double GetLocationRadius(FeatureType const & ft)
IsLocalityChecker const & IsLocalityChecker::Instance()
{
static IsLocalityChecker inst;
return inst;
}
uint32_t GetPopulation(FeatureType const & ft)
{
uint32_t population = ft.GetPopulation();
if (population < 10)
{
static IsLocalityChecker checker;
if (checker.GetLocalityType(ft) == CITY)
switch (IsLocalityChecker::Instance().GetType(ft))
{
case CITY:
case TOWN:
population = 10000;
/// @todo: process all cases of locality types
break;
case VILLAGE:
population = 100;
break;
default:
population = 0;
}
}
return pow((double)population, 0.277778) * 550;
return population;
}
double GetRadiusByPopulation(uint32_t p)
{
return pow(static_cast<double>(p), 0.277778) * 550.0;
}
uint32_t GetPopulationByRadius(double r)
{
return my::rounds(pow(r / 550.0, 3.6));
}
}

View file

@ -36,19 +36,26 @@ public:
IsBuildingChecker();
};
/// Type of locality (do not change values - they have detalization order)
/// COUNTRY < STATE < CITY
enum Type { NONE = -1, COUNTRY = 0, STATE, CITY };
/// Type of locality (do not change values and order - they have detalization order)
/// COUNTRY < STATE < CITY < ...
enum Type { NONE = -1, COUNTRY = 0, STATE, CITY, TOWN, VILLAGE, LOCALITY_COUNT };
class IsLocalityChecker : public BaseChecker
{
public:
IsLocalityChecker();
Type GetLocalityType(feature::TypesHolder const & types) const;
Type GetLocalityType(FeatureType const & f) const;
Type GetType(feature::TypesHolder const & types) const;
Type GetType(FeatureType const & f) const;
static IsLocalityChecker const & Instance();
};
/// Get city radius (meters)
double GetLocationRadius(FeatureType const & ft);
/// @name Get city radius and population.
/// @param r Radius in meters.
//@{
uint32_t GetPopulation(FeatureType const & ft);
double GetRadiusByPopulation(uint32_t p);
uint32_t GetPopulationByRadius(double r);
//@}
}

View file

@ -724,8 +724,16 @@ void Query::SearchViewportPoints(Results & res)
ftypes::Type Query::GetLocalityIndex(feature::TypesHolder const & types) const
{
static ftypes::IsLocalityChecker checker;
return checker.GetLocalityType(types);
using namespace ftypes;
// Inner logic of SearchAddress expects COUNTRY, STATE and CITY only.
Type const type = IsLocalityChecker::Instance().GetType(types);
switch (type)
{
case TOWN: return CITY;
case VILLAGE: return NONE;
default: return type;
}
}
void Query::RemoveStringPrefix(string const & str, string & res) const
@ -1703,14 +1711,16 @@ namespace impl
FeatureType f;
m_vector.Get(v.m_featureId, f);
using namespace ftypes;
// check, if feature is locality
ftypes::Type const index = m_query.GetLocalityIndex(feature::TypesHolder(f));
if (index != ftypes::NONE)
Type const index = m_query.GetLocalityIndex(feature::TypesHolder(f));
if (index != NONE)
{
Locality * loc = PushLocality(Locality(v, index));
if (loc)
{
loc->m_radius = ftypes::GetLocationRadius(f);
loc->m_radius = GetRadiusByPopulation(GetPopulation(f));
// m_lang name should exist if we matched feature in search index for this language.
VERIFY(f.GetName(m_lang, loc->m_name), ());