[search] Fixed "relaxed" street matching.

Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
This commit is contained in:
Viktor Govako 2023-07-26 17:27:35 -03:00
parent 28e2bd2fe2
commit f52220ab61
4 changed files with 63 additions and 5 deletions

View file

@ -1220,10 +1220,12 @@ void Geocoder::ProcessStreets(BaseContext & ctx, CentersFilter const & centers,
vector<PredictionT> predictions;
StreetsMatcher::Go(ctx, streets, *m_filter, m_params, predictions);
// Iterating from best to worst predictions here. Make "Relaxed" results for the best prediction only
// to avoid dummy streets results, matched by very _common_ tokens.
// Iterating from best to worst predictions here. Make "Relaxed" results for the best probability.
for (size_t i = 0; i < predictions.size(); ++i)
CreateStreetsLayerAndMatchLowerLayers(ctx, predictions[i], centers, i == 0 /* makeRelaxed */);
{
CreateStreetsLayerAndMatchLowerLayers(ctx, predictions[i], centers,
predictions[0].SameForRelaxedMatch(predictions[i]) /* makeRelaxed */);
}
}
void Geocoder::GreedilyMatchStreetsWithSuburbs(BaseContext & ctx, CentersFilter const & centers)

View file

@ -3417,4 +3417,42 @@ UNIT_CLASS_TEST(ProcessorTest, StreetCategories)
}
}
// https://github.com/organicmaps/organicmaps/issues/4421
UNIT_CLASS_TEST(ProcessorTest, BarcelonaStreet)
{
TestStreet street({{-1, -1}, {1, 1}}, "Carrer de la Concòrdia", "default");
street.SetType({"highway", "residential"});
TestStreet highway({{-0.9, -0.9}, {0.9, -0.9}}, "C-59 Carretera de Mollet", "default");
highway.SetType({"highway", "trunk"});
highway.SetRoadNumber("C-59");
auto wonderlandId = BuildCountry("Wonderland", [&](TestMwmBuilder & builder)
{
builder.Add(street);
builder.Add(highway);
});
SetViewport(m2::RectD(-0.5, -0.5, 0.5, 0.5));
{
Rules const rules = {
ExactMatch(wonderlandId, street),
// 1 token match is discarded for _relaxed_
//ExactMatch(wonderlandId, highway),
};
TEST(OrderedResultsMatch(MakeRequest("carrer de concordia 59", "en")->Results(), rules), ());
// Add some misspellings.
TEST(OrderedResultsMatch(MakeRequest("carrer concoria 59", "en")->Results(), rules), ());
TEST(OrderedResultsMatch(MakeRequest("carer la concoria 59", "en")->Results(), rules), ());
}
{
Rules const rules = {
ExactMatch(wonderlandId, street),
ExactMatch(wonderlandId, highway),
};
TEST(OrderedResultsMatch(MakeRequest("concordia 59", "en")->Results(), rules), ());
}
}
} // namespace processor_test

View file

@ -178,7 +178,11 @@ void StreetsMatcher::Go(BaseContext const & ctx, CBV const & candidates,
//
// That's why we need all predictions here.
sort(predictions.rbegin(), predictions.rend(), base::LessBy(&Prediction::m_prob));
sort(predictions.begin(), predictions.end(), [](Prediction const & l, Prediction const & r)
{
return l.IsBetter(r);
});
while (predictions.size() > kMaxNumOfImprobablePredictions &&
predictions.back().m_prob < kTailProbability)
{

View file

@ -18,7 +18,21 @@ class StreetsMatcher
public:
struct Prediction
{
inline size_t GetNumTokens() const { return m_tokenRange.Size(); }
size_t GetNumTokens() const { return m_tokenRange.Size(); }
/// @todo Check m_withMisprints ?
/// @{
bool SameForRelaxedMatch(Prediction const & rhs) const
{
return m_prob == rhs.m_prob && GetNumTokens() == rhs.GetNumTokens();
}
bool IsBetter(Prediction const & rhs) const
{
if (m_prob == rhs.m_prob)
return GetNumTokens() > rhs.GetNumTokens();
return m_prob > rhs.m_prob;
}
/// @}
CBV m_features;
TokenRange m_tokenRange;