diff --git a/generator/search_index_builder.cpp b/generator/search_index_builder.cpp index c8a598d220..31a4e3b494 100644 --- a/generator/search_index_builder.cpp +++ b/generator/search_index_builder.cpp @@ -289,6 +289,40 @@ void GetUKPostcodes(string const & filename, storage::CountryId const & countryI } } +// Returns true iff feature name was indexed as postcode and should be ignored for name indexing. +bool InsertPostcodes(FeatureType & f, function const & fn) +{ + using namespace search; + + auto const & postBoxChecker = ftypes::IsPostBoxChecker::Instance(); + string const postcode = f.GetMetadata().Get(feature::Metadata::FMD_POSTCODE); + vector postcodes; + if (!postcode.empty()) + postcodes.push_back(postcode); + + bool useNameAsPostcode = false; + if (postBoxChecker(f)) + { + auto const & names = f.GetNames(); + if (names.CountLangs() == 1) + { + string defaultName; + names.GetString(StringUtf8Multilang::kDefaultCode, defaultName); + if (!defaultName.empty() && LooksLikePostcode(defaultName, false /* isPrefix */)) + { + // In UK it's common practice to set outer postcode as postcode and outer + inner as ref. + // We convert ref to name at FeatureBuilder. + postcodes.push_back(defaultName); + useNameAsPostcode = true; + } + } + } + + for (auto const & pc : postcodes) + SplitUniString(NormalizeAndSimplifyString(pc), fn, Delimiters()); + return useNameAsPostcode; +} + template class FeatureInserter { @@ -325,40 +359,8 @@ public: FeatureNameInserter inserter(index, isCountryOrState(types) ? m_synonyms : nullptr, m_keyValuePairs, hasStreetType); - auto const & postBoxChecker = ftypes::IsPostBoxChecker::Instance(); - string const postcode = f.GetMetadata().Get(feature::Metadata::FMD_POSTCODE); - vector postcodes; - if (!postcode.empty()) - postcodes.push_back(postcode); - - bool useNameAsPostcode = false; - if (postBoxChecker(types)) - { - auto const & names = f.GetNames(); - if (names.CountLangs() == 1) - { - string defaultName; - names.GetString(StringUtf8Multilang::kDefaultCode, defaultName); - if (!defaultName.empty() && LooksLikePostcode(defaultName, false /* isPrefix */)) - { - // In UK it's common practice to set outer postcode as postcode and outer + inner as ref. - // We convert ref to name at FeatureBuilder. - postcodes.push_back(defaultName); - useNameAsPostcode = true; - } - } - } - - for (auto const & pc : postcodes) - { - // See OSM TagInfo or Wiki about modern postcodes format. The - // mean number of tokens is less than two. - buffer_vector tokens; - SplitUniString(NormalizeAndSimplifyString(pc), base::MakeBackInsertFunctor(tokens), - Delimiters()); - for (auto const & token : tokens) - inserter.AddToken(kPostcodesLang, token); - } + bool const useNameAsPostcode = InsertPostcodes( + f, [&inserter](auto const & token) { inserter.AddToken(kPostcodesLang, token); }); if (!useNameAsPostcode) f.ForEachName(inserter);