[search] Print street, house number for buildings in search results. Also print addresses.

This commit is contained in:
Alex Zolotarev 2016-03-17 13:28:02 +03:00 committed by Sergey Yershov
parent e6169abec1
commit b87699ccc8
10 changed files with 67 additions and 136 deletions

View file

@ -39,7 +39,7 @@ jobject ToJavaResult(Result & result, bool hasPosition, double lat, double lon)
::Framework * fr = g_framework->NativeFramework();
jni::TScopedLocalIntArrayRef ranges(env, env->NewIntArray(result.GetHighlightRangesCount() * 2));
jint * rawArr = env->GetIntArrayElements(ranges.get(), nullptr);
jint * rawArr = env->GetIntArrayElements(ranges, nullptr);
for (int i = 0; i < result.GetHighlightRangesCount(); i++)
{
auto const & range = result.GetHighlightRange(i);
@ -69,21 +69,12 @@ jobject ToJavaResult(Result & result, bool hasPosition, double lat, double lon)
return ret;
}
search::AddressInfo info;
if (result.GetResultType() == Result::RESULT_FEATURE)
{
fr->LoadSearchResultMetadata(result);
info = fr->GetFeatureAddressInfo(result.GetFeatureID());
}
else if (result.HasPoint())
info = fr->GetAddressInfoAtPoint(result.GetFeatureCenter());
jni::TScopedLocalRef featureType(env, jni::ToJavaString(env, result.GetFeatureType()));
jni::TScopedLocalRef region(env, jni::ToJavaString(env, info.FormatAddress(search::AddressInfo::SEARCH_RESULT)));
jni::TScopedLocalRef address(env, jni::ToJavaString(env, result.GetAddress()));
jni::TScopedLocalRef dist(env, jni::ToJavaString(env, distance));
jni::TScopedLocalRef cuisine(env, jni::ToJavaString(env, result.GetCuisine()));
jni::TScopedLocalRef desc(env, env->NewObject(g_descriptionClass, g_descriptionConstructor,
featureType.get(), region.get(),
featureType.get(), address.get(),
dist.get(), cuisine.get(),
result.GetStarsCount(),
static_cast<jint>(result.IsOpenNow())));

View file

@ -29,8 +29,7 @@
{
[super config:result];
self.typeLabel.text = @(result.GetFeatureType().c_str()).capitalizedString;
search::AddressInfo const info = GetFramework().GetSearchResultAddress(result);
self.locationLabel.text = @(info.FormatAddress(search::AddressInfo::SEARCH_RESULT).c_str());
self.locationLabel.text = @(result.GetAddress().c_str());
[self.locationLabel sizeToFit];
if (!forHeight)

View file

@ -1286,42 +1286,6 @@ size_t Framework::ShowSearchResults(search::Results const & results)
return count;
}
search::AddressInfo Framework::GetSearchResultAddress(search::Result const & res) const
{
search::AddressInfo info;
if (res.IsSuggest())
return info;
string const & type = res.GetFeatureType();
if (!type.empty())
info.m_types.push_back(type);
// Assign name if it's not equal with type.
string const & name = res.GetString();
if (name != type)
info.m_name = name;
info.m_city = res.GetAddress();
/// @todo Optimize here according to the fact that feature is
/// already read in many cases during search results processing.
auto const & id = res.GetFeatureID();
if (id.IsValid())
{
Index::FeaturesLoaderGuard loader(m_model.GetIndex(), id.m_mwmId);
FeatureType ft;
loader.GetFeatureByIndex(id.m_index, ft);
if (ft.GetFeatureType() == feature::GEOM_LINE ||
!ftypes::IsAddressObjectChecker::Instance()(ft))
{
return info;
}
}
info = GetAddressInfoAtPoint(res.GetFeatureCenter());
return info;
}
void Framework::FillSearchResultsMarks(search::Results const & results)
{
UserMarkControllerGuard guard(m_bmManager, UserMarkType::SEARCH_MARK);

View file

@ -399,7 +399,6 @@ public:
void ShowSearchResult(search::Result const & res);
size_t ShowSearchResults(search::Results const & results);
search::AddressInfo GetSearchResultAddress(search::Result const & res) const;
void StartInteractiveSearch(search::SearchParams const & params);
bool IsInteractiveSearchActive() const { return !m_lastInteractiveSearchParams.m_query.empty(); }

View file

@ -1,5 +1,6 @@
#include "intermediate_result.hpp"
#include "geometry_utils.hpp"
#include "reverse_geocoder.hpp"
#include "storage/country_info_getter.hpp"
@ -91,7 +92,7 @@ PreResult2::PreResult2(FeatureType const & f, PreResult1 const * p, m2::PointD c
: m_id(f.GetID()),
m_types(f),
m_str(displayName),
m_resultType(RESULT_FEATURE),
m_resultType(ftypes::IsBuildingChecker::Instance()(m_types) ? RESULT_BUILDING : RESULT_FEATURE),
m_geomType(f.GetFeatureType())
{
ASSERT(m_id.IsValid(), ());
@ -115,14 +116,6 @@ PreResult2::PreResult2(double lat, double lon)
m_region.SetParams(string(), MercatorBounds::FromLatLon(lat, lon));
}
PreResult2::PreResult2(m2::PointD const & pt, string const & str, uint32_t type)
: m_str(str), m_resultType(RESULT_BUILDING)
{
m_region.SetParams(string(), pt);
m_types.Assign(type);
}
namespace
{
class SkipRegionInfo
@ -168,40 +161,63 @@ string PreResult2::GetRegionName(storage::CountryInfoGetter const & infoGetter,
return info.m_name;
}
namespace
{
// TODO: Format street and house number according to local country's rules.
string FormatStreetAndHouse(ReverseGeocoder::Address const & addr)
{
ASSERT_GREATER_OR_EQUAL(addr.GetDistance(), 0, ());
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.
string res;
//if (addr.GetDistance() >= 0 && addr.GetDistance() < 50.0)
if (addr.GetDistance() == 0)
res = FormatStreetAndHouse(addr);
else
return region;
return res + ", " + region;
}
} // namespace
Result PreResult2::GenerateFinalResult(storage::CountryInfoGetter const & infoGetter,
CategoriesHolder const * pCat,
set<uint32_t> const * pTypes, int8_t locale) const
set<uint32_t> const * pTypes, int8_t locale,
ReverseGeocoder const & coder) const
{
ReverseGeocoder::Address addr;
coder.GetNearbyAddress(GetCenter(), addr);
// Insert exact address (street and house number) instead of empty result name.
string name;
if (m_str.empty() && addr.GetDistance() == 0)
name = FormatStreetAndHouse(addr);
else
name = m_str;
uint32_t const type = GetBestType(pTypes);
string const regionName = GetRegionName(infoGetter, type);
// TODO: GetRegionName should return City, State, Country instead of Country, State, City.
string const address = FormatFullAddress(addr, GetRegionName(infoGetter, type));
switch (m_resultType)
{
case RESULT_FEATURE:
return Result(m_id, GetCenter(), m_str, regionName, pCat->GetReadableFeatureType(type, locale)
case RESULT_BUILDING:
return Result(m_id, GetCenter(), name, address, pCat->GetReadableFeatureType(type, locale)
#ifdef DEBUG
+ ' ' + strings::to_string(static_cast<int>(m_info.m_rank))
#endif
, type, m_metadata);
case RESULT_BUILDING:
return Result(GetCenter(), m_str, regionName, pCat->GetReadableFeatureType(type, locale));
default:
ASSERT_EQUAL(m_resultType, RESULT_LATLON, ());
return Result(GetCenter(), m_str, regionName, string());
return Result(GetCenter(), m_str, address);
}
}
Result PreResult2::GeneratePointResult(storage::CountryInfoGetter const & infoGetter,
CategoriesHolder const * pCat,
set<uint32_t> const * pTypes, int8_t locale) const
{
uint32_t const type = GetBestType(pTypes);
return Result(m_id, GetCenter(), m_str, GetRegionName(infoGetter, type),
pCat->GetReadableFeatureType(type, locale));
}
// static
bool PreResult2::LessRank(PreResult2 const & r1, PreResult2 const & r2)
{

View file

@ -17,6 +17,7 @@ struct CountryInfo;
namespace search
{
class ReverseGeocoder;
namespace impl
{
/// First pass results class. Objects are creating during search in trie.
@ -60,19 +61,16 @@ public:
{
RESULT_LATLON,
RESULT_FEATURE,
RESULT_BUILDING
RESULT_BUILDING //!< Buildings are not filtered out in duplicates filter.
};
/// For RESULT_FEATURE.
/// For RESULT_FEATURE and RESULT_BUILDING.
PreResult2(FeatureType const & f, PreResult1 const * p, m2::PointD const & pivot,
string const & displayName, string const & fileName);
/// For RESULT_LATLON.
PreResult2(double lat, double lon);
/// For RESULT_BUILDING.
PreResult2(m2::PointD const & pt, string const & str, uint32_t type);
inline search::v2::RankingInfo const & GetRankingInfo() const { return m_info; }
template <typename TInfo>
@ -87,11 +85,7 @@ public:
/// @param[in] lang Current system language.
Result GenerateFinalResult(storage::CountryInfoGetter const & infoGetter,
CategoriesHolder const * pCat, set<uint32_t> const * pTypes,
int8_t locale) const;
Result GeneratePointResult(storage::CountryInfoGetter const & infoGetter,
CategoriesHolder const * pCat,
set<uint32_t> const * pTypes, int8_t locale) const;
int8_t locale, ReverseGeocoder const & coder) const;
static bool LessRank(PreResult2 const & r1, PreResult2 const & r2);
static bool LessDistance(PreResult2 const & r1, PreResult2 const & r2);

View file

@ -9,29 +9,16 @@ Result::Result(FeatureID const & id, m2::PointD const & pt, string const & str,
Metadata const & meta)
: m_id(id)
, m_center(pt)
, m_str(str)
, m_str(str.empty() ? type : str) //!< Features with empty names can be found after suggestion.
, m_address(address)
, m_type(type)
, m_featureType(featureType)
, m_metadata(meta)
{
Init(true /* metadataInitialized */);
}
Result::Result(FeatureID const & id, m2::PointD const & pt, string const & str,
string const & address, string const & type)
: m_id(id)
, m_center(pt)
, m_str(str)
, m_address(address)
, m_type(type)
{
Init(false /* metadataInitialized */);
}
Result::Result(m2::PointD const & pt, string const & str, string const & address,
string const & type)
: m_center(pt), m_str(str), m_address(address), m_type(type)
Result::Result(m2::PointD const & pt, string const & latlon, string const & address)
: m_center(pt), m_str(latlon), m_address(address)
{
}
@ -52,15 +39,6 @@ Result::Result(Result const & res, string const & suggest)
{
}
void Result::Init(bool metadataInitialized)
{
// Features with empty names can be found after suggestion.
if (m_str.empty())
m_str = m_type;
m_metadata.m_isInitialized = metadataInitialized;
}
Result::ResultType Result::GetResultType() const
{
bool const idValid = m_id.IsValid();
@ -144,9 +122,9 @@ pair<uint16_t, uint16_t> const & Result::GetHighlightRange(size_t idx) const
void Result::AppendCity(string const & name)
{
// No need to store mwm file name if we have valid city name.
if (!name.empty())
m_address = name;
// Append only if city is absent in region (mwm) name.
if (m_address.find(name) == string::npos)
m_address = name + ", " + m_address;
}
string Result::ToStringForStats() const

View file

@ -41,15 +41,10 @@ public:
/// For RESULT_FEATURE.
Result(FeatureID const & id, m2::PointD const & pt, string const & str, string const & address,
string const & type, uint32_t featureType, Metadata const & meta);
string const & type, uint32_t featureType, Metadata const & meta = {});
/// Used for generation viewport results.
Result(FeatureID const & id, m2::PointD const & pt, string const & str,
string const & address, string const & type);
/// @param[in] type Empty string - RESULT_LATLON, building address otherwise.
Result(m2::PointD const & pt, string const & str,
string const & address, string const & type);
/// For RESULT_LATLON.
Result(m2::PointD const & pt, string const & latlon, string const & address);
/// For RESULT_SUGGESTION_PURE.
Result(string const & str, string const & suggest);
@ -112,8 +107,6 @@ public:
string ToStringForStats() const;
private:
void Init(bool metadataInitialized);
FeatureID m_id;
m2::PointD m_center;
string m_str, m_address, m_type;

View file

@ -23,6 +23,7 @@
#include "indexer/feature.hpp"
#include "indexer/feature_algo.hpp"
#include "indexer/feature_covering.hpp"
#include "indexer/feature_data.hpp"
#include "indexer/feature_impl.hpp"
#include "indexer/features_vector.hpp"
#include "indexer/index.hpp"
@ -184,6 +185,7 @@ Query::Query(Index & index, CategoriesHolder const & categories, vector<Suggest>
, m_suggestsEnabled(true)
, m_viewportSearch(false)
, m_keepHouseNumberInQuery(false)
, m_reverseGeocoder(index)
{
// Initialize keywords scorer.
// Note! This order should match the indexes arrays above.
@ -513,9 +515,8 @@ void Query::FlushViewportResults(v2::Geocoder::Params const & params, Results &
{
if (IsCancelled())
break;
res.AddResultNoChecks((*(indV[i]))
.GeneratePointResult(m_infoGetter, &m_categories, &m_prefferedTypes,
m_currentLocaleCode));
res.AddResultNoChecks((*(indV[i])).GenerateFinalResult(m_infoGetter, &m_categories,
&m_prefferedTypes, m_currentLocaleCode, m_reverseGeocoder));
}
}
@ -578,14 +579,6 @@ class PreResult2Maker
m_query.GetBestMatchName(f, name);
// It's invalid for a building to have an empty name if it has a
// house number - it will be merged with other buildings in a
// MakePreResult2(). To prevent this, house number is used as a
// building name here, if the latter is empty.
auto const & checker = ftypes::IsBuildingChecker::Instance();
if (checker(f) && name.empty())
name = f.GetHouseNumber();
// country (region) name is a file name if feature isn't from World.mwm
if (m_pFV->IsWorld())
country.clear();
@ -1039,7 +1032,8 @@ public:
Result Query::MakeResult(impl::PreResult2 const & r) const
{
Result res =
r.GenerateFinalResult(m_infoGetter, &m_categories, &m_prefferedTypes, m_currentLocaleCode);
r.GenerateFinalResult(m_infoGetter, &m_categories, &m_prefferedTypes, m_currentLocaleCode,
m_reverseGeocoder);
MakeResultHighlight(res);
#ifdef FIND_LOCALITY_TEST

View file

@ -2,6 +2,7 @@
#include "search/intermediate_result.hpp"
#include "search/keyword_lang_matcher.hpp"
#include "search/mode.hpp"
#include "search/reverse_geocoder.hpp"
#include "search/search_trie.hpp"
#include "search/suggest.hpp"
#include "search/v2/geocoder.hpp"
@ -286,6 +287,8 @@ protected:
bool m_viewportSearch;
bool m_keepHouseNumberInQuery;
//@}
search::ReverseGeocoder const m_reverseGeocoder;
};
} // namespace search