Naming priority for poi objects was changed

This commit is contained in:
Arsentiy Milchakov 2016-11-02 12:43:23 +03:00 committed by Ilya Grechuhin
parent 36e7c13457
commit 7bd2eed6a4
9 changed files with 490 additions and 203 deletions

View file

@ -36,7 +36,7 @@ JNIEXPORT void JNICALL
Java_com_mapswithme_maps_bookmarks_data_BookmarkManager_nativeShowBookmarkOnMap(
JNIEnv * env, jobject thiz, jint c, jint b)
{
BookmarkAndCategory bnc = BookmarkAndCategory(b,c);
BookmarkAndCategory bnc = BookmarkAndCategory(b, c);
frm()->ShowBookmark(bnc);
}

View file

@ -79,30 +79,48 @@ void FilterRulesByRuntimeSelector(FeatureType const & f, int zoomLevel, drule::K
});
}
class KeyFunctor
class Aggregator
{
public:
KeyFunctor(FeatureType const & f,
feature::EGeomType type,
Aggregator(FeatureType const & f,
feature::EGeomType const type,
int const zoomLevel,
int const keyCount,
CaptionDescription & descr)
int const keyCount)
: m_pointStyleFound(false)
, m_lineStyleFound(false)
, m_iconFound(false)
, m_captionWithoutOffsetFound(false)
, m_auxCaptionFound(false)
, m_mainTextType(drule::text_type_name)
, m_descrInit(false)
, m_f(f)
, m_geomType(type)
, m_zoomLevel(zoomLevel)
, m_descr(descr)
{
m_rules.reserve(keyCount);
Init();
}
void AggregateKeys(drule::KeysT const & keys)
{
for (auto const & key : keys)
ProcessKey(key);
}
void AggregateStyleFlags(drule::KeysT const & keys, bool const nameExists)
{
for (auto const & key : keys)
{
bool const isNonEmptyCaption = IsTypeOf(key, Caption) && nameExists;
m_pointStyleFound |= (IsTypeOf(key, Symbol | Circle) || isNonEmptyCaption);
m_lineStyleFound |= IsTypeOf(key, Line);
}
}
bool m_pointStyleFound;
bool m_lineStyleFound;
bool m_auxCaptionFound;
drule::text_type_t m_mainTextType;
buffer_vector<Stylist::TRuleWrapper, 8> m_rules;
private:
void ProcessKey(drule::Key const & key)
{
double depth = key.m_priority;
@ -117,36 +135,23 @@ public:
if (IsTypeOf(key, Caption | Symbol | Circle | PathText))
{
depth += m_priorityModifier;
if (m_geomType == feature::GEOM_POINT) ++depth;
if (m_geomType == feature::GEOM_POINT)
++depth;
}
else if (IsTypeOf(key, Area))
depth -= m_priorityModifier;
drule::BaseRule const * const dRule = drule::rules().Find(key);
m_rules.push_back(make_pair(dRule, depth));
if (dRule->GetCaption(0) != nullptr)
{
InitCaptionDescription();
m_mainTextType = dRule->GetCaptionTextType(0);
depth -= m_priorityModifier;
}
bool const isNonEmptyCaption = IsTypeOf(key, Caption) && IsNameExists();
m_pointStyleFound |= (IsTypeOf(key, Symbol | Circle) || isNonEmptyCaption);
m_lineStyleFound |= IsTypeOf(key, Line);
drule::BaseRule const * const dRule = drule::rules().Find(key);
m_rules.emplace_back(make_pair(dRule, depth));
if (dRule->GetCaption(0) != nullptr)
m_mainTextType = dRule->GetCaptionTextType(0);
m_auxCaptionFound |= (dRule->GetCaption(1) != nullptr);
}
bool m_pointStyleFound;
bool m_lineStyleFound;
bool m_iconFound;
bool m_captionWithoutOffsetFound;
bool m_auxCaptionFound;
buffer_vector<Stylist::TRuleWrapper, 8> m_rules;
drule::text_type_t m_mainTextType;
bool m_descrInit;
private:
void Init()
{
m_depthLayer = m_f.GetLayer();
@ -162,28 +167,11 @@ private:
}
}
void InitCaptionDescription()
{
if (!m_descrInit)
{
m_descr.Init(m_f, m_zoomLevel);
m_descrInit = true;
}
}
inline bool IsNameExists() const
{
ASSERT(m_descrInit, ());
return m_descr.IsNameExists();
}
private:
FeatureType const & m_f;
feature::EGeomType m_geomType;
int const m_zoomLevel;
double m_priorityModifier;
int m_depthLayer;
CaptionDescription & m_descr;
};
const uint8_t CoastlineFlag = 1;
@ -196,41 +184,21 @@ const uint8_t PointStyleFlag = 1 << 3;
// ==================================== //
void CaptionDescription::Init(FeatureType const & f,
int const zoomLevel)
int const zoomLevel,
feature::EGeomType const type,
drule::text_type_t const mainTextType,
bool const auxCaptionExists)
{
f.GetPreferredNames(m_mainText, m_auxText);
if (auxCaptionExists || type == feature::GEOM_LINE)
f.GetPreferredNames(m_mainText, m_auxText);
else
f.GetReadableName(m_mainText);
m_roadNumber = f.GetRoadNumber();
m_houseNumber = f.GetHouseNumber();
SwapCaptions(zoomLevel);
DiscardLongCaption(zoomLevel);
}
void CaptionDescription::FormatCaptions(FeatureType const & f,
feature::EGeomType type,
drule::text_type_t mainTextType,
bool auxCaptionExists)
{
if (!auxCaptionExists && !m_auxText.empty() && type != feature::GEOM_LINE)
{
m_mainText.swap(m_auxText);
m_auxText.clear();
}
if (mainTextType == drule::text_type_housenumber)
{
m_mainText.swap(m_houseNumber);
m_houseNumber.clear();
}
else if (mainTextType == drule::text_type_name)
{
if (!m_houseNumber.empty())
{
if (m_mainText.empty() || m_houseNumber.find(m_mainText) != string::npos)
m_houseNumber.swap(m_mainText);
}
}
ProcessZoomLevel(zoomLevel);
ProcessMainTextType(mainTextType);
}
string const & CaptionDescription::GetMainText() const
@ -262,21 +230,34 @@ bool CaptionDescription::IsNameExists() const
return !m_mainText.empty() || !m_houseNumber.empty();
}
void CaptionDescription::SwapCaptions(int const zoomLevel)
void CaptionDescription::ProcessZoomLevel(int const zoomLevel)
{
if (zoomLevel <= scales::GetUpperWorldScale() && !m_auxText.empty())
{
m_mainText.swap(m_auxText);
m_auxText.clear();
}
}
void CaptionDescription::DiscardLongCaption(int const zoomLevel)
{
if (zoomLevel < 5 && m_mainText.size() > 50)
m_mainText.clear();
}
void CaptionDescription::ProcessMainTextType(drule::text_type_t const & mainTextType)
{
if (mainTextType == drule::text_type_housenumber)
{
m_mainText.swap(m_houseNumber);
m_houseNumber.clear();
}
else if (mainTextType == drule::text_type_name)
{
if (!m_houseNumber.empty())
{
if (m_mainText.empty() || m_houseNumber.find(m_mainText) != string::npos)
m_houseNumber.swap(m_mainText);
}
}
}
// ==================================== //
Stylist::Stylist()
@ -385,21 +366,20 @@ bool InitStylist(FeatureType const & f, int const zoomLevel, bool buildings3d, S
return false;
}
Aggregator aggregator(f, mainGeomType, zoomLevel, keys.size());
aggregator.AggregateKeys(keys);
CaptionDescription & descr = s.GetCaptionDescriptionImpl();
descr.Init(f, zoomLevel, mainGeomType, aggregator.m_mainTextType, aggregator.m_auxCaptionFound);
KeyFunctor keyFunctor(f, mainGeomType, zoomLevel, keys.size(), descr);
for (auto const & key : keys)
keyFunctor.ProcessKey(key);
aggregator.AggregateStyleFlags(keys, descr.IsNameExists());
if (keyFunctor.m_pointStyleFound)
if (aggregator.m_pointStyleFound)
s.RaisePointStyleFlag();
if (keyFunctor.m_lineStyleFound)
if (aggregator.m_lineStyleFound)
s.RaiseLineStyleFlag();
s.m_rules.swap(keyFunctor.m_rules);
if (keyFunctor.m_descrInit)
descr.FormatCaptions(f, mainGeomType, keyFunctor.m_mainTextType, keyFunctor.m_auxCaptionFound);
s.m_rules.swap(aggregator.m_rules);
return true;
}
@ -413,14 +393,11 @@ double GetFeaturePriority(FeatureType const & f, int const zoomLevel)
feature::EGeomType const mainGeomType = feature::EGeomType(geomType.first);
CaptionDescription descr;
KeyFunctor keyFunctor(f, mainGeomType, zoomLevel, keys.size(), descr);
for (auto const & key : keys)
keyFunctor.ProcessKey(key);
Aggregator aggregator(f, mainGeomType, zoomLevel, keys.size());
aggregator.AggregateKeys(keys);
double maxPriority = kMinPriority;
for (auto const & rule : keyFunctor.m_rules)
for (auto const & rule : aggregator.m_rules)
{
if (rule.second > maxPriority)
maxPriority = rule.second;

View file

@ -18,12 +18,10 @@ namespace df
struct CaptionDescription
{
void Init(FeatureType const & f,
int const zoomLevel);
void FormatCaptions(FeatureType const & f,
feature::EGeomType type,
drule::text_type_t mainTextType,
bool auxCaptionExists);
int const zoomLevel,
feature::EGeomType const type,
drule::text_type_t const mainTextType,
bool const auxCaptionExists);
string const & GetMainText() const;
string const & GetAuxText() const;
@ -32,10 +30,11 @@ struct CaptionDescription
bool IsNameExists() const;
private:
void SwapCaptions(int const zoomLevel);
void DiscardLongCaption(int const zoomLevel);
/// Clear aux name on high zoom and clear long main name on low zoom.
void ProcessZoomLevel(int const zoomLevel);
/// Try to use house number as name of the object.
void ProcessMainTextType(drule::text_type_t const & mainTextType);
private:
string m_mainText;
string m_auxText;
string m_roadNumber;

View file

@ -106,8 +106,7 @@ bool GetPopulation(FeatureType const & ft, uint32_t & population)
// Feature tag value evaluator for tag 'name'
bool GetName(FeatureType const & ft, string & name)
{
string intName;
ft.GetPreferredNames(name, intName);
ft.GetReadableName(name);
return true;
}

View file

@ -8,6 +8,8 @@
#include "indexer/feature_visibility.hpp"
#include "indexer/osm_editor.hpp"
#include "platform/preferred_languages.hpp"
#include "geometry/distance.hpp"
#include "geometry/robust_orientation.hpp"
@ -487,13 +489,19 @@ FeatureType::geom_stat_t FeatureType::GetTrianglesSize(int scale) const
return geom_stat_t(sz, m_triangles.size());
}
void FeatureType::GetPreferredNames(string & defaultName, string & intName) const
void FeatureType::GetPreferredNames(string & primary, string & secondary) const
{
if (!HasName())
return;
auto const mwmInfo = GetID().m_mwmId.GetInfo();
if (!mwmInfo)
return;
ParseCommon();
::GetPreferredNames(GetID(), GetNames(), defaultName, intName);
auto const deviceLang = StringUtf8Multilang::GetLangIndex(languages::GetCurrentNorm());
::GetPreferredNames(mwmInfo->GetRegionData(), GetNames(), deviceLang, primary, secondary);
}
void FeatureType::GetReadableName(string & name) const
@ -501,8 +509,14 @@ void FeatureType::GetReadableName(string & name) const
if (!HasName())
return;
auto const mwmInfo = GetID().m_mwmId.GetInfo();
if (!mwmInfo)
return;
ParseCommon();
::GetReadableName(GetID(), GetNames(), name);
auto const deviceLang = StringUtf8Multilang::GetLangIndex(languages::GetCurrentNorm());
::GetReadableName(mwmInfo->GetRegionData(), GetNames(), deviceLang, name);
}
string FeatureType::GetHouseNumber() const

View file

@ -7,8 +7,6 @@
#include "geometry/point2d.hpp"
#include "platform/preferred_languages.hpp"
#include "coding/multilang_utf8_string.hpp"
#include "base/base.hpp"
@ -17,15 +15,12 @@
namespace
{
void GetMwmLangName(FeatureID const & id, StringUtf8Multilang const & src, string & out)
using StrUtf8 = StringUtf8Multilang;
void GetMwmLangName(feature::RegionData const & regionData, StringUtf8Multilang const & src, string & out)
{
auto const mwmInfo = id.m_mwmId.GetInfo();
if (!mwmInfo)
return;
vector<int8_t> mwmLangCodes;
mwmInfo->GetRegionData().GetLanguages(mwmLangCodes);
regionData.GetLanguages(mwmLangCodes);
for (auto const code : mwmLangCodes)
{
@ -34,22 +29,9 @@ void GetMwmLangName(FeatureID const & id, StringUtf8Multilang const & src, strin
}
}
void GetNames(FeatureID const & id, StringUtf8Multilang const & src, string & primary,
string & secondary)
void GetBestName(StringUtf8Multilang const & src, vector<int8_t> const & priorityList, string & out)
{
primary.clear();
secondary.clear();
if (src.IsEmpty())
return;
vector<int8_t> primaryCodes = {StringUtf8Multilang::kDefaultCode};
vector<int8_t> secondaryCodes = {StringUtf8Multilang::GetLangIndex(languages::GetCurrentNorm()),
StringUtf8Multilang::kInternationalCode,
StringUtf8Multilang::kEnglishCode};
auto primaryIndex = primaryCodes.size();
auto secondaryIndex = secondaryCodes.size();
auto bestIndex = priorityList.size();
auto const findAndSet = [](vector<int8_t> const & langs, int8_t const code, string const & name,
size_t & bestIndex, string & outName)
@ -64,23 +46,19 @@ void GetNames(FeatureID const & id, StringUtf8Multilang const & src, string & pr
src.ForEach([&](int8_t code, string const & name)
{
if (primaryIndex != 0)
findAndSet(primaryCodes, code, name, primaryIndex, primary);
if (bestIndex == 0)
return false;
if (secondaryIndex != 0)
findAndSet(secondaryCodes, code, name, secondaryIndex, secondary);
findAndSet(priorityList, code, name, bestIndex, out);
return true;
});
if (primary.empty())
GetMwmLangName(id, src, primary);
if (secondaryIndex < secondaryCodes.size() &&
secondaryCodes[secondaryIndex] == StringUtf8Multilang::kInternationalCode)
// There are many "junk" names in Arabian island.
if (bestIndex < priorityList.size() &&
priorityList[bestIndex] == StrUtf8::kInternationalCode)
{
// There are many "junk" names in Arabian island.
secondary = secondary.substr(0, secondary.find_first_of(','));
out = out.substr(0, out.find_first_of(','));
}
}
} // namespace
@ -225,41 +203,54 @@ int GetFeatureViewportScale(TypesHolder const & types)
return impl::GetFeatureEstimator().GetViewportScale(types);
}
void GetPreferredNames(FeatureID const & id, StringUtf8Multilang const & src, string & primary,
string & secondary)
void GetPreferredNames(RegionData const & regionData, StringUtf8Multilang const & src,
int8_t const deviceLang, string & primary, string & secondary)
{
// Primary name using priority:
// - default name;
// - country language name.
// Secondary name using priority:
// - device language name;
// - international name;
// - english name.
GetNames(id, src, primary, secondary);
primary.clear();
secondary.clear();
if (src.IsEmpty())
return;
vector<int8_t> const primaryCodes = {deviceLang,
StrUtf8::kInternationalCode,
StrUtf8::kEnglishCode};
vector<int8_t> secondaryCodes = {StrUtf8::kDefaultCode,
StrUtf8::kInternationalCode};
vector<int8_t> mwmLangCodes;
regionData.GetLanguages(mwmLangCodes);
secondaryCodes.insert(secondaryCodes.end(), mwmLangCodes.begin(), mwmLangCodes.end());
secondaryCodes.push_back(StrUtf8::kEnglishCode);
GetBestName(src, primaryCodes, primary);
GetBestName(src, secondaryCodes, secondary);
if (primary.empty())
{
primary.swap(secondary);
}
else
{
// Filter out similar intName.
if (!secondary.empty() && primary.find(secondary) != string::npos)
secondary.clear();
}
primary.swap(secondary);
else if (!secondary.empty() && primary.find(secondary) != string::npos)
secondary.clear();
}
void GetReadableName(FeatureID const & id, StringUtf8Multilang const & src, string & out)
void GetReadableName(RegionData const & regionData, StringUtf8Multilang const & src,
int8_t const deviceLang, string & out)
{
// Names using priority:
// - device language name;
// - international name;
// - english name;
// - default name;
// - country language name.
// Secondary name is preffered to display on the map and place page.
string primary, secondary;
GetNames(id, src, primary, secondary);
out = secondary.empty() ? primary : secondary;
out.clear();
if (src.IsEmpty())
return;
vector<int8_t> codes;
// If MWM contains user's language.
if (regionData.HasLanguage(deviceLang))
codes = {deviceLang, StrUtf8::kDefaultCode, StrUtf8::kInternationalCode, StrUtf8::kEnglishCode};
else
codes = {deviceLang, StrUtf8::kInternationalCode, StrUtf8::kEnglishCode, StrUtf8::kDefaultCode};
GetBestName(src, codes, out);
if (out.empty())
GetMwmLangName(regionData, src, out);
}
} // namespace feature

View file

@ -10,11 +10,37 @@ class StringUtf8Multilang;
namespace feature
{
class TypesHolder;
class RegionData;
/// Get viewport scale to show given feature. Used in search.
int GetFeatureViewportScale(TypesHolder const & types);
void GetPreferredNames(FeatureID const & id, StringUtf8Multilang const & src, string & primary,
string & secondary);
void GetReadableName(FeatureID const & id, StringUtf8Multilang const & src, string & out);
/// Primary name using priority:
/// - device language name;
/// - international name;
/// - english name.
/// Secondary name using priority:
/// - default name;
/// - international name;
/// - country language name;
/// - english name.
/// In case when primary name is empty it will be propagated from secondary and secondary will be
/// cleared. In case when primary name contains secondary name then secondary will be cleared.
void GetPreferredNames(RegionData const & regionData, StringUtf8Multilang const & src,
int8_t const deviceLang, string & primary, string & secondary);
/// When MWM contains user's language, the priority is the following:
/// - device language name;
/// - default name;
/// - international name;
/// - english name;
/// - country language name.
/// When MWM does not contain user's language, the priority is the following:
/// - device language name;
/// - international name;
/// - english name;
/// - default name;
/// - country language name.
void GetReadableName(RegionData const & regionData, StringUtf8Multilang const & src,
int8_t const deviceLang, string & out);
} // namespace feature

View file

@ -1,39 +1,314 @@
#include "testing/testing.hpp"
#include "indexer/feature_utils.hpp"
#include "indexer/features_vector.hpp"
#include "indexer/index.hpp"
#include "indexer/mwm_set.hpp"
#include "platform/local_country_file.hpp"
#include "platform/preferred_languages.hpp"
using namespace platform;
namespace
{
UNIT_TEST(GetFeatureNames)
using StrUtf8 = StringUtf8Multilang;
UNIT_TEST(GetPrefferedNames)
{
LocalCountryFile localFile = LocalCountryFile::MakeForTesting("minsk-pass");
feature::RegionData regionData;
regionData.SetLanguages({"de", "ko"});
Index index;
auto result = index.RegisterMap(localFile);
TEST_EQUAL(result.second, MwmSet::RegResult::Success, ());
int8_t deviceLang = StrUtf8::GetLangIndex("ru");
string primary, secondary;
auto const & id = result.first;
MwmSet::MwmHandle handle = index.GetMwmHandleById(id);
TEST(handle.IsAlive(), ());
auto const * value = handle.GetValue<MwmValue>();
FeaturesVector fv(value->m_cont, value->GetHeader(), value->m_table.get());
string primary, secondary, readable;
fv.ForEach([&](FeatureType & ft, uint32_t /* index */)
{
ft.GetPreferredNames(primary, secondary);
if (!secondary.empty())
{
ft.GetReadableName(readable);
TEST_EQUAL(secondary, readable, ());
}
});
StrUtf8 src;
src.AddString("fr", "fr name");
feature::GetPreferredNames(regionData, src, deviceLang, primary, secondary);
TEST_EQUAL(primary, "", ());
TEST_EQUAL(secondary, "", ());
}
{
StrUtf8 src;
src.AddString("default", "default name");
feature::GetPreferredNames(regionData, src, deviceLang, primary, secondary);
TEST_EQUAL(primary, "default name", ());
TEST_EQUAL(secondary, "", ());
}
{
StrUtf8 src;
src.AddString("default", "default name");
src.AddString("en", "en name");
feature::GetPreferredNames(regionData, src, deviceLang, primary, secondary);
TEST_EQUAL(primary, "en name", ());
TEST_EQUAL(secondary, "default name", ());
}
{
StrUtf8 src;
src.AddString("default", "default name");
src.AddString("en", "en name");
src.AddString("ru", "ru name");
feature::GetPreferredNames(regionData, src, deviceLang, primary, secondary);
TEST_EQUAL(primary, "ru name", ());
TEST_EQUAL(secondary, "default name", ());
}
{
StrUtf8 src;
src.AddString("default", "same name");
src.AddString("en", "en name");
src.AddString("ru", "same name");
src.AddString("int_name", "int name");
feature::GetPreferredNames(regionData, src, deviceLang, primary, secondary);
TEST_EQUAL(primary, "same name", ());
TEST_EQUAL(secondary, "", ());
}
{
StrUtf8 src;
src.AddString("default", "default name");
src.AddString("en", "en name");
src.AddString("ru", "ru name");
src.AddString("int_name", "int name");
src.AddString("de", "de name");
feature::GetPreferredNames(regionData, src, deviceLang, primary, secondary);
TEST_EQUAL(primary, "ru name", ());
TEST_EQUAL(secondary, "default name", ());
}
{
StrUtf8 src;
src.AddString("default", "default name");
src.AddString("en", "en name");
src.AddString("ru", "ru name");
src.AddString("int_name", "int name");
src.AddString("de", "de name");
src.AddString("ko", "ko name");
feature::GetPreferredNames(regionData, src, deviceLang, primary, secondary);
TEST_EQUAL(primary, "ru name", ());
TEST_EQUAL(secondary, "default name", ());
}
{
StrUtf8 src;
src.AddString("default", "default name");
src.AddString("en", "en name");
src.AddString("int_name", "int name");
src.AddString("de", "de name");
src.AddString("ko", "ko name");
feature::GetPreferredNames(regionData, src, deviceLang, primary, secondary);
TEST_EQUAL(primary, "int name", ());
TEST_EQUAL(secondary, "default name", ());
}
{
StrUtf8 src;
src.AddString("en", "en name");
src.AddString("int_name", "int name");
src.AddString("de", "de name");
src.AddString("ko", "ko name");
feature::GetPreferredNames(regionData, src, deviceLang, primary, secondary);
TEST_EQUAL(primary, "int name", ());
TEST_EQUAL(secondary, "", ());
}
{
StrUtf8 src;
src.AddString("en", "en name");
src.AddString("de", "de name");
src.AddString("ko", "ko name");
feature::GetPreferredNames(regionData, src, deviceLang, primary, secondary);
TEST_EQUAL(primary, "en name", ());
TEST_EQUAL(secondary, "de name", ());
}
{
StrUtf8 src;
src.AddString("en", "en name");
src.AddString("ko", "ko name");
feature::GetPreferredNames(regionData, src, deviceLang, primary, secondary);
TEST_EQUAL(primary, "en name", ());
TEST_EQUAL(secondary, "ko name", ());
}
{
StrUtf8 src;
src.AddString("en", "en name");
feature::GetPreferredNames(regionData, src, deviceLang, primary, secondary);
TEST_EQUAL(primary, "en name", ());
TEST_EQUAL(secondary, "", ());
}
}
UNIT_TEST(GetReadableName)
{
feature::RegionData regionData;
regionData.SetLanguages({"de", "ko"});
int8_t deviceLang = StrUtf8::GetLangIndex("ru");
string name;
{
StrUtf8 src;
src.AddString("fr", "fr name");
feature::GetReadableName(regionData, src, deviceLang, name);
TEST_EQUAL(name, "", ());
}
{
StrUtf8 src;
src.AddString("ko", "ko name");
feature::GetReadableName(regionData, src, deviceLang, name);
TEST_EQUAL(name, "ko name", ());
}
{
StrUtf8 src;
src.AddString("ko", "ko name");
src.AddString("de", "de name");
feature::GetReadableName(regionData, src, deviceLang, name);
TEST_EQUAL(name, "de name", ());
}
{
StrUtf8 src;
src.AddString("ko", "ko name");
src.AddString("de", "de name");
src.AddString("default", "default name");
feature::GetReadableName(regionData, src, deviceLang, name);
TEST_EQUAL(name, "default name", ());
}
{
StrUtf8 src;
src.AddString("ko", "ko name");
src.AddString("de", "de name");
src.AddString("default", "default name");
src.AddString("en", "en name");
feature::GetReadableName(regionData, src, deviceLang, name);
TEST_EQUAL(name, "en name", ());
}
{
StrUtf8 src;
src.AddString("ko", "ko name");
src.AddString("de", "de name");
src.AddString("default", "default name");
src.AddString("en", "en name");
src.AddString("int_name", "int name");
feature::GetReadableName(regionData, src, deviceLang, name);
TEST_EQUAL(name, "int name", ());
}
{
StrUtf8 src;
src.AddString("ko", "ko name");
src.AddString("de", "de name");
src.AddString("default", "default name");
src.AddString("en", "en name");
src.AddString("int_name", "int name");
src.AddString("ru", "ru name");
feature::GetReadableName(regionData, src, deviceLang, name);
TEST_EQUAL(name, "ru name", ());
}
deviceLang = StrUtf8::GetLangIndex("de");
{
StrUtf8 src;
src.AddString("ko", "ko name");
src.AddString("de", "de name");
src.AddString("default", "default name");
src.AddString("en", "en name");
src.AddString("int_name", "int name");
feature::GetReadableName(regionData, src, deviceLang, name);
TEST_EQUAL(name, "de name", ());
}
{
StrUtf8 src;
src.AddString("ko", "ko name");
src.AddString("default", "default name");
src.AddString("en", "en name");
src.AddString("int_name", "int name");
feature::GetReadableName(regionData, src, deviceLang, name);
TEST_EQUAL(name, "default name", ());
}
{
StrUtf8 src;
src.AddString("ko", "ko name");
src.AddString("en", "en name");
src.AddString("int_name", "int name");
feature::GetReadableName(regionData, src, deviceLang, name);
TEST_EQUAL(name, "int name", ());
}
{
StrUtf8 src;
src.AddString("ko", "ko name");
src.AddString("en", "en name");
feature::GetReadableName(regionData, src, deviceLang, name);
TEST_EQUAL(name, "en name", ());
}
{
StrUtf8 src;
src.AddString("ko", "ko name");
feature::GetReadableName(regionData, src, deviceLang, name);
TEST_EQUAL(name, "ko name", ());
}
}
} // namespace

View file

@ -4,6 +4,7 @@
#include "indexer/osm_editor.hpp"
#include "platform/measurement_utils.hpp"
#include "platform/preferred_languages.hpp"
namespace place_page
{
@ -49,7 +50,12 @@ string Info::GetTitle() const
return m_customName;
string name;
feature::GetReadableName(GetID(), m_name, name);
auto const deviceLang = StringUtf8Multilang::GetLangIndex(languages::GetCurrentNorm());
auto const mwmInfo = GetID().m_mwmId.GetInfo();
if (mwmInfo)
feature::GetReadableName(mwmInfo->GetRegionData(), m_name, deviceLang, name);
return name;
}