Create logic for different search result address ordering (TODO: place page order)

This commit is contained in:
zyphlar 2024-07-11 19:24:53 -07:00
parent fecccafba4
commit 3d682e80a0
No known key found for this signature in database
GPG key ID: 4601DE80976978B6
6 changed files with 85 additions and 53 deletions

View file

@ -229,8 +229,8 @@ uint32_t RankerResult::GetBestType(vector<uint32_t> const * preferredTypes /* =
return m_types.GetBestType();
}
// RankerResult::RegionInfo ------------------------------------------------------------------------
bool RankerResult::RegionInfo::GetCountryId(storage::CountryInfoGetter const & infoGetter,
// RegionInfo ------------------------------------------------------------------------
bool RegionInfo::GetCountryId(storage::CountryInfoGetter const & infoGetter,
storage::CountryId & countryId) const
{
if (!m_countryId.empty())

View file

@ -95,6 +95,21 @@ private:
#endif
};
struct RegionInfo
{
storage::CountryId m_countryId;
m2::PointD m_point;
void SetParams(storage::CountryId const & countryId, m2::PointD const & point)
{
m_countryId = countryId;
m_point = point;
}
bool GetCountryId(storage::CountryInfoGetter const & infoGetter,
storage::CountryId & countryId) const;
};
// Second result class. Objects are created during reading of features.
// Read and fill needed info for ranking and getting final results.
class RankerResult
@ -141,6 +156,7 @@ public:
bool GetCountryId(storage::CountryInfoGetter const & infoGetter, uint32_t ftype,
storage::CountryId & countryId) const;
RegionInfo const & GetRegion() const { return m_region; }
bool IsEqualBasic(RankerResult const & r) const;
bool IsEqualCommon(RankerResult const & r) const;
@ -157,21 +173,6 @@ private:
friend class RankerResultMaker;
friend class Ranker;
struct RegionInfo
{
storage::CountryId m_countryId;
m2::PointD m_point;
void SetParams(storage::CountryId const & countryId, m2::PointD const & point)
{
m_countryId = countryId;
m_point = point;
}
bool GetCountryId(storage::CountryInfoGetter const & infoGetter,
storage::CountryId & countryId) const;
};
RegionInfo m_region;
feature::TypesHolder m_types;
std::string m_str;

View file

@ -299,23 +299,6 @@ ftypes::LocalityType GetLocalityIndex(feature::TypesHolder const & types)
UNREACHABLE();
}
// TODO: Format street and house number according to local country's rules.
string FormatStreetAndHouse(ReverseGeocoder::Address const & addr)
{
return addr.GetStreetName() + ", " + addr.GetHouseNumber();
}
// TODO: Share common formatting code for search results and place page.
string FormatFullAddress(ReverseGeocoder::Address const & addr, string const & region)
{
/// @todo Print "near" for not exact addresses.
/// Add some threshold for addr:interpolation or refactor ReverseGeocoder?
if (addr.GetDistance() != 0)
return region;
return FormatStreetAndHouse(addr) + (region.empty() ? "" : ", ") + region;
}
} // namespace
class RankerResultMaker
@ -494,7 +477,8 @@ private:
{
string streetName;
m_ranker.GetBestMatchName(*streetFeature, streetName);
name = streetName + ", " + addr.GetHouseNumber();
LOG(LDEBUG, ("WAB LoadFeature", streetName, addr.GetHouseNumber()));
name = streetName + ", " + addr.GetHouseNumber(); /// @todo consider using partialAddress logic below
}
}
}
@ -719,25 +703,79 @@ void Ranker::Finish(bool cancelled)
m_emitter.Finish(cancelled);
}
/// This is one of the final steps in finishing a result and displaying an address in the GUI
/// So it returns a full string like "City, Street Name, 123, Province, Country"
/// @todo Share common formatting code for search results and place page.
Result Ranker::MakeResult(RankerResult const & rankerResult, bool needAddress, bool needHighlighting) const
{
// If we don't want to bother with addresses at all, just use the ranker result which is "Main St, 123"
Result res(rankerResult.GetCenter(), rankerResult.m_str);
if (needAddress)
{
string address = GetLocalizedRegionInfoForResult(rankerResult);
string partialAddress = "";
string fullAddress = "";
ReverseGeocoder::Address addr;
string_view city;
string region = GetLocalizedRegionInfoForResult(rankerResult);
// Format full address only for suitable results.
if (ftypes::IsAddressObjectChecker::Instance()(rankerResult.GetTypes()))
{
ReverseGeocoder::Address addr;
if (ftypes::IsAddressObjectChecker::Instance()(rankerResult.GetTypes())) {
if (!(rankerResult.GetID().IsValid() && m_reverseGeocoder.GetExactAddress(rankerResult.GetID(), addr)))
m_reverseGeocoder.GetNearbyAddress(rankerResult.GetCenter(), addr);
address = FormatFullAddress(addr, address);
}
res.SetAddress(std::move(address));
// Get city when possible
if (ftypes::IsLocalityChecker::Instance().GetType(rankerResult.GetTypes()) == ftypes::LocalityType::None)
{
m_localities.GetLocality(res.GetFeatureCenter(), [&](LocalityItem const & item)
{
item.GetReadableName(city);
});
}
/// @todo Print "near" for not exact addresses.
/// Add some threshold for addr:interpolation or refactor ReverseGeocoder?
if (rankerResult.GetRegion().m_countryId.starts_with("US_")) {
// US partial is 123 Main St
if (addr.IsValid() && addr.GetDistance() == 0) partialAddress += addr.GetHouseNumber() + " " + addr.GetStreetName();
// US full is 123 Main St, Chicago, Illinois, USA
if (addr.IsValid() && addr.GetDistance() == 0) fullAddress += addr.GetHouseNumber() + " " + addr.GetStreetName();
if (!city.empty()) {
if(!fullAddress.empty()) fullAddress += ", ";
fullAddress.append(city);
}
if (!region.empty())
{
if(!fullAddress.empty()) fullAddress += ", ";
fullAddress += region;
}
}
else
{
// OM default partial is Main St, 123
if (addr.IsValid() && addr.GetDistance() == 0) partialAddress += addr.GetStreetName() + ", " + addr.GetHouseNumber();
// OM default full is Chicago, Main St, 123, Illinois, USA
if (!city.empty()) fullAddress.append(city);
if (addr.IsValid() && addr.GetDistance() == 0)
{
if(!fullAddress.empty()) fullAddress += ", ";
fullAddress += addr.GetStreetName() + ", " + addr.GetHouseNumber();
}
if (!region.empty())
{
if(!fullAddress.empty()) fullAddress += ", ";
fullAddress += region;
}
}
if(!partialAddress.empty()) res.SetString(std::move(partialAddress));
res.SetAddress(std::move(fullAddress));
}
switch (rankerResult.GetResultType())
@ -750,16 +788,6 @@ Result Ranker::MakeResult(RankerResult const & rankerResult, bool needAddress, b
case RankerResult::Type::Postcode: res.SetType(Result::Type::Postcode); break;
}
if (needAddress && ftypes::IsLocalityChecker::Instance().GetType(rankerResult.GetTypes()) == ftypes::LocalityType::None)
{
m_localities.GetLocality(res.GetFeatureCenter(), [&](LocalityItem const & item)
{
string_view city;
if (item.GetReadableName(city))
res.PrependCity(city);
});
}
if (needHighlighting)
HighlightResult(m_params.m_query.m_tokens, m_params.m_query.m_prefix, res);
@ -768,7 +796,7 @@ Result Ranker::MakeResult(RankerResult const & rankerResult, bool needAddress, b
#ifdef SEARCH_USE_PROVENANCE
res.SetProvenance(std::move(rankerResult.m_provenance));
#endif
LOG(LDEBUG, ("WAB MakeResult", res));
return res;
}

View file

@ -237,6 +237,7 @@ string DebugPrint(Result const & result)
ostringstream os;
os << "Result [";
os << "name: " << result.GetString();
os << ", addr: " << result.GetAddress();
os << ", type: " << readableType;
os << ", info: " << DebugPrint(result.GetRankingInfo());

View file

@ -61,6 +61,7 @@ public:
Result(m2::PointD const & pt, std::string const & name) : m_center(pt), m_str(name) {}
void FromFeature(FeatureID const & id, uint32_t mainType, uint32_t matchedType, Details const & details);
void SetString(std::string && str) { m_str = std::move(str); }
void SetAddress(std::string && address) { m_address = std::move(address); }
void SetType(Result::Type type) { m_resultType = type; }

View file

@ -331,6 +331,7 @@ string ReverseGeocoder::GetLocalizedRegionAddress(RegionAddress const & addr,
addrStr = nameGetter.GetLocalizedFullName(addr.m_countryId);
}
LOG(LWARNING, ("WAB LocalizedRegionAddress", addrStr));
return addrStr;
}