[search] Fix index build for categories which are deeper than 3 levels

This commit is contained in:
tatiana-yan 2018-06-08 19:40:07 +03:00 committed by mpimenov
parent ac5a2c6ae9
commit 8d63d1a507
3 changed files with 170 additions and 5 deletions

View file

@ -106,13 +106,24 @@ void GetCategoryTypes(CategoriesHolder const & categories, pair<int, int> const
for (uint32_t t : types)
{
// Leave only 2 levels of types - for example, do not distinguish:
// highway-primary-bridge and highway-primary-tunnel
// or amenity-parking-fee and amenity-parking-underground-fee.
ftype::TruncValue(t, 2);
// Truncate |t| up to 2 levels and choose the best category match to find explicit category if
// any and not distinguish types like highway-primary-bridge and highway-primary-tunnel or
// amenity-parking-fee and amenity-parking-underground-fee if we do not have such explicit
// categories.
bool found = false;
for (uint8_t level = ftype::GetLevel(t); level >= 2; --level)
{
ftype::TruncValue(t, level);
if (categories.IsTypeExist(t))
{
found = true;
break;
}
}
// Only categorized types will be added to index.
if (!categories.IsTypeExist(t))
if (!found)
continue;
// There are some special non-drawable types we plan to search on.

View file

@ -57,6 +57,20 @@ public:
return id;
}
void DeregisterMap(std::string const & name)
{
auto const file = platform::CountryFile(name);
auto it = find_if(
m_files.begin(), m_files.end(),
[&file](platform::LocalCountryFile const & f) { return f.GetCountryFile() == file; });
if (it == m_files.end())
return;
m_index.DeregisterMap(file);
Cleanup(*it);
m_files.erase(it);
}
template <typename BuildFn>
MwmSet::MwmId BuildWorld(BuildFn && fn)
{

View file

@ -64,6 +64,30 @@ public:
~AlcoShop() override = default;
};
class SubwayStation : public TestPOI
{
public:
SubwayStation(m2::PointD const & center, string const & name, string const & lang)
: TestPOI(center, name, lang)
{
SetTypes({{"railway", "station", "subway"}});
}
~SubwayStation() override = default;
};
class SubwayStationMoscow : public TestPOI
{
public:
SubwayStationMoscow(m2::PointD const & center, string const & name, string const & lang)
: TestPOI(center, name, lang)
{
SetTypes({{"railway", "station", "subway", "moscow"}});
}
~SubwayStationMoscow() override = default;
};
UNIT_CLASS_TEST(SmokeTest, Smoke)
{
char const kCountryName[] = "BuzzTown";
@ -96,6 +120,122 @@ UNIT_CLASS_TEST(SmokeTest, Smoke)
}
}
UNIT_CLASS_TEST(SmokeTest, DeepCategoryTest)
{
char const kCountryName[] = "Wonderland";
SubwayStation redStation(m2::PointD(0, 0), "red", "en");
SubwayStationMoscow blueStation(m2::PointD(1, 1), "blue", "en");
auto id = BuildMwm(kCountryName, feature::DataHeader::country, [&](TestMwmBuilder & builder) {
builder.Add(redStation);
builder.Add(blueStation);
});
SetViewport(m2::RectD(m2::PointD(0, 0), m2::PointD(1, 1)));
{
TRules rules = {ExactMatch(id, redStation), ExactMatch(id, blueStation)};
TEST(ResultsMatch("Subway ", rules), ());
}
}
UNIT_CLASS_TEST(SmokeTest, CategoriesTest)
{
// todo(@t.yan): fix some or delete category.
vector<vector<string>> const invisibleTags = {{"amenity", "driving_school"},
{"military", "bunker"},
{"waterway", "canal"},
{"waterway", "river"},
{"waterway", "riverbank"},
{"waterway", "stream"},
{"landuse", "basin"},
{"place", "county"},
{"place", "islet"},
{"power", "pole"},
{"highway", "footway"},
{"highway", "living_street"},
{"highway", "motorway"},
{"highway", "motorway_link"},
{"highway", "path"},
{"highway", "pedestrian"},
{"highway", "primary"},
{"highway", "primary_link"},
{"highway", "raceway"},
{"highway", "residential"},
{"highway", "road"},
{"highway", "secondary"},
{"highway", "secondary_link"},
{"highway", "service"},
{"highway", "steps"},
{"area:highway", "steps"},
{"highway", "tertiary"},
{"highway", "tertiary_link"},
{"highway", "track"},
{"highway", "traffic_signals"},
{"highway", "trunk"},
{"highway", "trunk_link"},
{"highway", "unclassified"},
{"man_made", "surveillance"},
{"man_made", "tower"},
{"man_made", "water_tower"},
{"man_made", "water_well"},
{"natural", "pond"},
{"natural", "tree"},
{"natural", "wood"}};
set<uint32_t> invisibleTypes;
for (auto const & tags : invisibleTags)
invisibleTypes.insert(classif().GetTypeByPath(tags));
// todo(@t.yan): fix some or delete category.
vector<vector<string>> const badTags = {{"building"},
{"building", "address"},
{"entrance"},
{"internet_access"},
{"internet_access", "wlan"},
{"office"},
{"shop"},
{"shop", "butcher"},
{"shop", "florist"},
{"shop", "greengrocer"},
{"shop", "optician"},
{"place", "continent"},
{"place", "region"},
{"event", "fc2018_city"},
{"sponsored", "holiday"},
{"railway", "level_crossing"},
{"highway", "rest_area"}};
set<uint32_t> badTypes;
for (auto const & tags : badTags)
badTypes.insert(classif().GetTypeByPath(tags));
auto const & holder = GetDefaultCategories();
auto testCategory = [&](uint32_t type, CategoriesHolder::Category const &) {
if (invisibleTypes.find(type) != invisibleTypes.end())
return;
if (badTypes.find(type) != badTypes.end())
return;
string const countryName = "Wonderland";
TestPOI poi(m2::PointD(1.0, 1.0), "poi", "en");
poi.SetTypes({strings::Tokenize(classif().GetFullObjectName(type), "|")});
auto id = BuildMwm(countryName, feature::DataHeader::country,
[&](TestMwmBuilder & builder) { builder.Add(poi); });
SetViewport(m2::RectD(m2::PointD(0.0, 0.0), m2::PointD(2.0, 2.0)));
{
TRules rules = {ExactMatch(id, poi)};
auto const query = holder.GetReadableFeatureType(type, CategoriesHolder::kEnglishCode) + " ";
TEST(ResultsMatch(query, rules), ());
}
DeregisterMap(countryName);
};
holder.ForEachTypeAndCategory(testCategory);
}
UNIT_CLASS_TEST(SmokeTest, NotPrefixFreeNames)
{
char const kCountryName[] = "ATown";