forked from organicmaps/organicmaps
[search] Fix index build for categories which are deeper than 3 levels
This commit is contained in:
parent
ac5a2c6ae9
commit
8d63d1a507
3 changed files with 170 additions and 5 deletions
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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";
|
||||
|
|
Loading…
Add table
Reference in a new issue