[search] Support multiple semicolon separated alt/old names.

This commit is contained in:
tatiana-yan 2020-08-06 14:33:51 +03:00 committed by mpimenov
parent 42224b6b5b
commit d1f98bcf61
2 changed files with 74 additions and 13 deletions

View file

@ -38,7 +38,16 @@ template <typename Slice>
void UpdateNameScores(string const & name, uint8_t lang, Slice const & slice,
NameScores & bestScores)
{
bestScores.UpdateIfBetter(GetNameScores(name, lang, slice));
if (lang == StringUtf8Multilang::kAltNameCode || lang == StringUtf8Multilang::kOldNameCode)
{
auto const names = strings::Tokenize(name, ";");
for (auto const & n : names)
bestScores.UpdateIfBetter(GetNameScores(n, lang, slice));
}
else
{
bestScores.UpdateIfBetter(GetNameScores(name, lang, slice));
}
}
template <typename Slice>
@ -107,19 +116,32 @@ pair<NameScores, size_t> GetNameScores(FeatureType & ft, Geocoder::Params const
string name;
if (!ft.GetName(lang, name))
continue;
vector<strings::UniString> tokens;
PrepareStringForMatching(name, tokens);
UpdateNameScores(tokens, lang, slice, bestScores);
UpdateNameScores(tokens, lang, sliceNoCategories, bestScores);
if (type == Model::TYPE_STREET)
vector<vector<strings::UniString>> tokens(1);
if (lang == StringUtf8Multilang::kAltNameCode || lang == StringUtf8Multilang::kOldNameCode)
{
auto const variants = ModifyStrasse(tokens);
for (auto const & variant : variants)
auto const names = strings::Tokenize(name, ";");
tokens.resize(names.size());
for (size_t i = 0; i < names.size(); ++i)
PrepareStringForMatching(names[i], tokens[i]);
}
else
{
PrepareStringForMatching(name, tokens[0]);
}
for (auto const & t : tokens)
{
UpdateNameScores(t, lang, slice, bestScores);
UpdateNameScores(t, lang, sliceNoCategories, bestScores);
if (type == Model::TYPE_STREET)
{
UpdateNameScores(variant, lang, slice, bestScores);
UpdateNameScores(variant, lang, sliceNoCategories, bestScores);
auto const variants = ModifyStrasse(t);
for (auto const & variant : variants)
{
UpdateNameScores(variant, lang, slice, bestScores);
UpdateNameScores(variant, lang, sliceNoCategories, bestScores);
}
}
}
}
@ -772,7 +794,17 @@ void Ranker::GetBestMatchName(FeatureType & f, string & name) const
};
auto bestNameFinder = [&](int8_t lang, string const & s) {
updateScore(lang, s, true /* force */);
if (lang == StringUtf8Multilang::kAltNameCode || lang == StringUtf8Multilang::kOldNameCode)
{
auto const names = strings::Tokenize(s, ";");
for (auto const & n : names)
updateScore(lang, n, true /* force */);
}
else
{
updateScore(lang, s, true /* force */);
}
// Default name should be written in the regional language.
if (lang == StringUtf8Multilang::kDefaultCode)
{

View file

@ -3095,5 +3095,34 @@ UNIT_CLASS_TEST(ProcessorTest, JaKanaNormalizationTest)
TEST(ResultsMatch("トウキョウト", rules), ());
}
}
UNIT_CLASS_TEST(ProcessorTest, TestRankingInfo_MultipleOldNames)
{
string const countryName = "Wonderland";
StringUtf8Multilang cityName;
cityName.AddString("default", "Санкт-Петербург");
cityName.AddString("old_name", "Ленинград;Петроград");
TestCity city(m2::PointD(0.0, 0.0), cityName, 100 /* rank */);
auto worldId = BuildWorld([&](TestMwmBuilder & builder) { builder.Add(city); });
SetViewport(m2::RectD(-1, -1, 1, 1));
auto checkResult = [&](string const & query, string const & expectedName) {
auto request = MakeRequest(query, "ru");
auto const & results = request->Results();
Rules rules{ExactMatch(worldId, city)};
TEST_EQUAL(results.size(), 1, ());
TEST(ResultsMatch(results, rules), ());
TEST_EQUAL(results[0].GetRankingInfo().m_nameScore, NAME_SCORE_FULL_MATCH, (query, results));
TEST_EQUAL(results[0].GetString(), expectedName, (query, results));
};
checkResult("Санкт-Петербург", "Санкт-Петербург");
checkResult("Ленинград", "Санкт-Петербург (Ленинград)");
checkResult("Петроград", "Санкт-Петербург (Петроград)");
}
} // namespace
} // namespace search