[search] Refactored emitting final search results.

This commit is contained in:
vng 2014-07-24 20:15:16 +03:00 committed by Alex Zolotarev
parent 3909bc8adc
commit 4dda2e079c
14 changed files with 149 additions and 135 deletions

View file

@ -251,34 +251,27 @@ Java_com_mapswithme_maps_SearchActivity_nativeGetResult(
env->ReleaseIntArrayElements(ranges, narr, 0);
jclass klass = env->FindClass("com/mapswithme/maps/SearchActivity$SearchAdapter$SearchResult");
ASSERT ( klass, () );
ASSERT(klass, ());
if (res->GetResultType() != search::Result::RESULT_SUGGESTION)
if (!res->IsSuggest())
{
jmethodID methodID = env->GetMethodID(
klass, "<init>",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;D[I)V");
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[I)V");
ASSERT ( methodID, () );
string distance;
double azimut = -1.0;
if (hasPosition)
{
if (!g_framework->NativeFramework()->GetDistanceAndAzimut(
res->GetFeatureCenter(), lat, lon, north, distance, azimut))
{
// do not show the arrow for far away features
azimut = -1.0;
}
double dummy;
(void) g_framework->NativeFramework()->GetDistanceAndAzimut(res->GetFeatureCenter(), lat, lon, north, distance, dummy);
}
return env->NewObject(klass, methodID,
jni::ToJavaString(env, res->GetString()),
jni::ToJavaString(env, res->GetRegionString()),
jni::ToJavaString(env, res->GetFeatureType()),
jni::ToJavaString(env, res->GetRegionFlag()),
jni::ToJavaString(env, distance.c_str()),
static_cast<jdouble>(azimut),
static_cast<jintArray>(ranges));
}
else

View file

@ -496,8 +496,7 @@ public class SearchActivity extends MapsWithMeBaseListActivity implements Locati
// Called from native code
@SuppressWarnings("unused")
public SearchResult(String name, String country, String amenity,
String flag, String distance, double azimut,
int[] highlightRanges)
String distance, int[] highlightRanges)
{
mName = name;
mCountry = country;

View file

@ -66,6 +66,12 @@ namespace feature
TypesHolder(EGeomType geoType = GEOM_UNDEFINED) : m_size(0), m_geoType(geoType) {}
TypesHolder(FeatureBase const & f);
void Assign(uint32_t type)
{
m_types[0] = type;
m_size = 1;
}
/// Accumulation function.
inline void operator() (uint32_t t) { m_types[m_size++] = t; }

View file

@ -42,6 +42,8 @@ class IsBuildingChecker : public BaseChecker
{
public:
IsBuildingChecker();
uint32_t GetMainType() const { return m_types[0]; }
};
/// Type of locality (do not change values and order - they have detalization order)

View file

@ -274,8 +274,8 @@ __weak SearchView * selfPointer;
- (void)recalculateDistances
{
LocationManager * locationManager = [MapsAppDelegate theApp].m_locationManager;
double north = -1.0;
double azimut = -1.0;
[locationManager getNorthRad:north];
double lat, lon;
if ([locationManager getLat:lat Lon:lon])
@ -284,9 +284,10 @@ __weak SearchView * selfPointer;
for (NSInteger position = 0; position < [wrapper count]; position++)
{
search::Result const & result = [wrapper resultWithPosition:position];
string distance;
if (result.GetResultType() != search::Result::RESULT_SUGGESTION)
if (result.HasPoint())
{
string distance;
double azimut = -1.0;
GetFramework().GetDistanceAndAzimut(result.GetFeatureCenter(), lat, lon, north, distance, azimut);
wrapper.distances[@(position)] = [NSString stringWithUTF8String:distance.c_str()];
}

View file

@ -1430,26 +1430,36 @@ size_t Framework::ShowAllSearchResults()
m2::PointD const center = viewport.Center();
double minDistance = numeric_limits<double>::max();
size_t minInd;
int minInd = -1;
for (size_t i = 0; i < count; ++i)
{
double const dist = center.SquareLength(results.GetResult(i).GetFeatureCenter());
if (dist < minDistance)
Result const & r = results.GetResult(i);
if (r.HasPoint())
{
minDistance = dist;
minInd = i;
double const dist = center.SquareLength(r.GetFeatureCenter());
if (dist < minDistance)
{
minDistance = dist;
minInd = static_cast<int>(i);
}
}
}
m2::PointD const pt = results.GetResult(minInd).GetFeatureCenter();
if (!viewport.IsPointInside(pt))
if (minInd != -1)
{
viewport.SetSizesToIncludePoint(pt);
m2::PointD const pt = results.GetResult(minInd).GetFeatureCenter();
if (!viewport.IsPointInside(pt))
{
viewport.SetSizesToIncludePoint(pt);
ShowRectFixedAR(viewport);
StopLocationFollow();
ShowRectFixedAR(viewport);
StopLocationFollow();
}
else
minInd = -1;
}
else
if (minInd == -1)
Invalidate();
return count;
@ -1468,7 +1478,7 @@ void Framework::FillSearchResultsMarks(search::Results const & results)
using namespace search;
Result const & r = results.GetResult(i);
if (!r.IsSuggest())
if (r.HasPoint())
{
AddressInfo info;
info.MakeFrom(r);

View file

@ -183,17 +183,17 @@ void SearchPanel::OnSearchPanelItemClicked(int row, int)
{
ASSERT_EQUAL(m_results.size(), static_cast<size_t>(m_pTable->rowCount()), ());
if (m_results[row].GetResultType() != ResultT::RESULT_SUGGESTION)
{
// center viewport on clicked item
m_pDrawWidget->ShowSearchResult(m_results[row]);
}
else
if (m_results[row].IsSuggest())
{
// insert suggestion into the search bar
string const suggestion = m_results[row].GetSuggestionString();
m_pEditor->setText(QString::fromUtf8(suggestion.c_str()));
}
else
{
// center viewport on clicked item
m_pDrawWidget->ShowSearchResult(m_results[row]);
}
}
void SearchPanel::hideEvent(QHideEvent *)

View file

@ -2,7 +2,6 @@
#include "search_common.hpp"
#include "algos.hpp"
#include "../indexer/ftypes_matcher.hpp"
#include "../indexer/feature_impl.hpp"
#include "../indexer/classificator.hpp"
@ -803,15 +802,18 @@ HouseProjection const * MergedStreet::GetHousePivot(bool isOdd, bool & sign) con
return 0;
}
uint32_t HouseDetector::GetBuildingType() const
{
return m_buildingChecker.GetMainType();
}
template <class ProjectionCalcT>
void HouseDetector::ReadHouse(FeatureType const & f, Street * st, ProjectionCalcT & calc)
{
static ftypes::IsBuildingChecker const checker;
string const houseNumber = f.GetHouseNumber();
/// @todo After new data generation we can skip IsHouseNumber check here.
if (checker(f) && feature::IsHouseNumber(houseNumber))
if (m_buildingChecker(f) && feature::IsHouseNumber(houseNumber))
{
HouseMapT::iterator const it = m_id2house.find(f.GetID());
bool const isNew = it == m_id2house.end();

View file

@ -3,6 +3,7 @@
#include "../indexer/feature_decl.hpp"
#include "../indexer/index.hpp"
#include "../indexer/ftypes_matcher.hpp"
#include "../geometry/point2d.hpp"
@ -237,6 +238,8 @@ class HouseDetector
int m_streetNum;
double m_houseOffsetM;
ftypes::IsBuildingChecker m_buildingChecker;
typedef pair<Street *, bool> StreetPtr;
StreetPtr FindConnection(Street const * st, bool beg) const;
void MergeStreets(Street * st);
@ -252,6 +255,8 @@ class HouseDetector
public:
HouseDetector(Index const * pIndex);
uint32_t GetBuildingType() const;
int LoadStreets(vector<FeatureID> const & ids);
/// @return number of different joined streets.
int MergeStreets();

View file

@ -171,15 +171,19 @@ PreResult2::PreResult2(FeatureType const & f, PreResult1 const * p,
CalcParams(viewport, pos);
}
PreResult2::PreResult2(m2::RectD const & viewport, m2::PointD const & pos, double lat, double lon)
PreResult2::PreResult2(double lat, double lon)
: m_str("(" + MeasurementUtils::FormatLatLon(lat, lon) + ")"),
m_resultType(RESULT_LATLON),
m_rank(255),
m_geomType(feature::GEOM_UNDEFINED)
m_resultType(RESULT_LATLON)
{
m2::PointD const fCenter(MercatorBounds::FromLatLon(lat, lon));
m_region.SetParams(string(), fCenter);
CalcParams(viewport, pos);
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
@ -218,7 +222,7 @@ Result PreResult2::GenerateFinalResult(
uint32_t const type = GetBestType();
static SkipRegionInfo checker;
static SkipRegionInfo const checker;
if (!checker.IsContinent(type))
{
m_region.GetRegion(pInfo, info);
@ -230,15 +234,18 @@ Result PreResult2::GenerateFinalResult(
switch (m_resultType)
{
case RESULT_FEATURE:
return Result(m_id, GetCenter(), m_str, info.m_name, info.m_flag, GetFeatureType(pCat, pTypes, lang)
return Result(m_id, GetCenter(), m_str, info.m_name, GetFeatureType(pCat, pTypes, lang)
#ifdef DEBUG
+ ' ' + strings::to_string(static_cast<int>(m_rank))
#endif
, type, m_distance);
, type);
case RESULT_BUILDING:
return Result(GetCenter(), m_str, info.m_name, GetFeatureType(pCat, pTypes, lang));
default:
ASSERT_EQUAL(m_resultType, RESULT_LATLON, ());
return Result(GetCenter(), m_str, info.m_name, info.m_flag, m_distance);
return Result(GetCenter(), m_str, info.m_name, string());
}
}

View file

@ -69,17 +69,20 @@ public:
enum ResultType
{
RESULT_LATLON,
RESULT_FEATURE
RESULT_FEATURE,
RESULT_BUILDING
};
// For RESULT_FEATURE.
/// For RESULT_FEATURE.
PreResult2(FeatureType const & f, PreResult1 const * p,
m2::RectD const & viewport, m2::PointD const & pos,
string const & displayName, string const & fileName);
// For RESULT_LATLON.
PreResult2(m2::RectD const & viewport, m2::PointD const & pos,
double lat, double lon);
/// For RESULT_LATLON.
PreResult2(double lat, double lon);
/// For RESULT_BUILDING.
PreResult2(m2::PointD const & pt, string const & str, uint32_t type);
/// @param[in] pInfo Need to get region for result.
/// @param[in] pCat Categories need to display readable type string.

View file

@ -5,19 +5,15 @@
namespace search
{
Result::Result(FeatureID const & id, m2::PointD const & fCenter,
Result::Result(FeatureID const & id, m2::PointD const & pt,
string const & str, string const & region,
string const & flag, string const & type,
uint32_t featureType, double distance)
: m_id(id), m_center(fCenter), m_str(str), m_region(region),
m_flag(flag), m_type(type), m_featureType(featureType), m_distance(distance)
string const & type, uint32_t featureType)
: m_id(id), m_center(pt), m_str(str), m_region(region),
m_type(type), m_featureType(featureType)
{
// Features with empty names can be found after suggestion.
if (m_str.empty())
{
//m_str = "-";
m_str = type;
}
}
Result::Result(m2::PointD const & pt, string const & str, string const & type)
@ -25,11 +21,9 @@ Result::Result(m2::PointD const & pt, string const & str, string const & type)
{
}
Result::Result(m2::PointD const & fCenter,
string const & str, string const & region,
string const & flag, double distance)
: m_center(fCenter), m_str(str), m_region(region),
m_flag(flag), m_featureType(0), m_distance(distance)
Result::Result(m2::PointD const & pt, string const & str,
string const & region, string const & type)
: m_center(pt), m_str(str), m_region(region), m_type(type)
{
}
@ -38,14 +32,21 @@ Result::Result(string const & str, string const & suggest)
{
}
Result::Result(Result const & res, string const & suggest)
: m_center(res.m_center), m_str(res.m_str), m_region(res.m_region),
m_featureType(res.m_featureType), m_suggestionStr(suggest),
m_hightlightRanges(res.m_hightlightRanges)
{
}
Result::ResultType Result::GetResultType() const
{
bool const idValid = m_id.IsValid();
if (!m_suggestionStr.empty())
return RESULT_SUGGESTION;
if (m_id.IsValid())
return RESULT_FEATURE;
else
return RESULT_LATLON;
return (idValid ? RESULT_SUGGEST_FROM_FEATURE : RESULT_SUGGEST_PURE);
return (idValid ? RESULT_FEATURE : RESULT_LATLON);
}
bool Result::IsSuggest() const
@ -53,21 +54,20 @@ bool Result::IsSuggest() const
return !m_suggestionStr.empty();
}
bool Result::HasPoint() const
{
return (GetResultType() != RESULT_SUGGEST_PURE);
}
FeatureID Result::GetFeatureID() const
{
ASSERT_EQUAL(GetResultType(), RESULT_FEATURE, ());
return m_id;
}
double Result::GetDistance() const
{
ASSERT(!IsSuggest(), ());
return m_distance;
}
m2::PointD Result::GetFeatureCenter() const
{
ASSERT(!IsSuggest(), ());
ASSERT(HasPoint(), ());
return m_center;
}
@ -82,8 +82,11 @@ bool Result::operator== (Result const & r) const
ResultType const type = GetResultType();
if (type == r.GetResultType())
{
if (type == RESULT_SUGGESTION)
return m_suggestionStr == r.m_suggestionStr;
if (IsSuggest())
{
ASSERT(r.IsSuggest(), ());
return (m_suggestionStr == r.m_suggestionStr);
}
else
{
// This function is used to filter duplicate results in cases:
@ -133,15 +136,18 @@ bool Results::AddResultCheckExisting(Result const & r)
size_t Results::GetSuggestsCount() const
{
size_t suggestsCount = 0;
size_t res = 0;
for (size_t i = 0; i < GetCount(); i++)
{
if (m_vec[i].GetResultType() == search::Result::RESULT_SUGGESTION)
suggestsCount++;
if (m_vec[i].IsSuggest())
++res;
else
{
// Suggests always go first, so we can exit here.
break;
}
}
return suggestsCount;
return res;
}
////////////////////////////////////////////////////////////////////////////////////
@ -150,26 +156,23 @@ size_t Results::GetSuggestsCount() const
void AddressInfo::MakeFrom(Result const & res)
{
ASSERT_NOT_EQUAL(res.GetResultType(), Result::RESULT_SUGGESTION, ());
ASSERT_NOT_EQUAL(res.GetResultType(), Result::RESULT_SUGGEST_PURE, ());
// push the feature type (may be empty for coordinates result)
string const type = res.GetFeatureType();
string const & type = res.GetFeatureType();
if (!type.empty())
m_types.push_back(type);
// assign name if it's not equal with type
string name = res.GetString();
string const & name = res.GetString();
if (name != type)
m_name.swap(name);
m_name = name;
}
void AddressInfo::SetPinName(string const & name)
bool AddressInfo::IsEmptyName() const
{
m_name = name;
return m_name.empty() && m_house.empty();
}
bool AddressInfo::IsEmptyName() const { return m_name.empty() && m_house.empty(); }
string AddressInfo::GetPinName() const
{
if (IsEmptyName() && !m_types.empty())

View file

@ -20,36 +20,37 @@ public:
{
RESULT_FEATURE,
RESULT_LATLON,
RESULT_SUGGESTION,
RESULT_POI_SUGGEST
RESULT_SUGGEST_PURE,
RESULT_SUGGEST_FROM_FEATURE
};
/// For RESULT_FEATURE.
Result(FeatureID const & id, m2::PointD const & fCenter,
Result(FeatureID const & id, m2::PointD const & pt,
string const & str, string const & region,
string const & flag, string const & type,
uint32_t featureType, double distance);
string const & type, uint32_t featureType);
/// Used for point-like results on the map.
Result(m2::PointD const & pt, string const & str, string const & type);
/// For RESULT_LATLON.
Result(m2::PointD const & fCenter,
string const & str, string const & region,
string const & flag, double distance);
/// @param[in] type Pass 0 - for RESULT_LATLON or building type for building address.
Result(m2::PointD const & pt, string const & str,
string const & region, string const & type);
/// For RESULT_SUGGESTION.
/// For RESULT_SUGGESTION_PURE.
Result(string const & str, string const & suggest);
/// For RESULT_SUGGESTION_FROM_FEATURE.
Result(Result const & res, string const & suggest);
/// Strings that is displayed in the GUI.
//@{
char const * GetString() const { return m_str.c_str(); }
char const * GetRegionString() const { return m_region.c_str(); }
char const * GetRegionFlag() const { return m_flag.empty() ? 0 : m_flag.c_str(); }
char const * GetFeatureType() const { return m_type.c_str(); }
//@}
bool IsSuggest() const;
bool HasPoint() const;
/// Type of the result.
ResultType GetResultType() const;
@ -59,15 +60,11 @@ public:
FeatureID GetFeatureID() const;
/// Center point of a feature.
/// @precondition GetResultType() != RESULT_SUGGESTION
/// @precondition HasPoint() == true
m2::PointD GetFeatureCenter() const;
/// Distance from the current position or -1 if location is not detected.
/// @precondition GetResultType() != RESULT_SUGGESTION
double GetDistance() const;
/// String to write in the search box.
/// @precondition GetResultType() == RESULT_SUGGESTION
/// @precondition IsSuggest() == true
char const * GetSuggestionString() const;
bool operator== (Result const & r) const;
@ -81,9 +78,8 @@ public:
private:
FeatureID m_id;
m2::PointD m_center;
string m_str, m_region, m_flag, m_type;
string m_str, m_region, m_type;
uint32_t m_featureType;
double m_distance;
string m_suggestionStr;
buffer_vector<pair<uint16_t, uint16_t>, 4> m_hightlightRanges;
};
@ -154,7 +150,6 @@ struct AddressInfo
void MakeFrom(search::Result const & res);
void SetPinName(string const & name);
string GetPinName() const; // Caroline
string GetPinType() const; // shop

View file

@ -389,7 +389,7 @@ void Query::SearchCoordinates(string const & query, Results & res) const
if (MatchLatLonDegree(query, lat, lon))
{
//double const precision = 5.0 * max(0.0001, min(latPrec, lonPrec)); // Min 55 meters
res.AddResult(MakeResult(impl::PreResult2(GetViewport(), m_position, lat, lon)));
res.AddResult(MakeResult(impl::PreResult2(lat, lon)));
}
}
@ -711,19 +711,9 @@ void Query::FlushHouses(Results & res, bool allMWMs, vector<FeatureID> const & s
for (size_t i = 0; i < count; ++i)
{
House const * h = houses[i].m_house;
storage::CountryInfo ci;
m_pInfoGetter->GetRegionInfo(h->GetPosition(), ci);
Result r(h->GetPosition(), h->GetNumber() + ", " + houses[i].m_street->GetName(),
ci.m_name, string(), IsValidPosition() ? h->GetPosition().Length(m_position) : -1.0);
MakeResultHighlight(r);
#ifdef FIND_LOCALITY_TEST
string city;
m_locality.GetLocalityCreateCache(r.GetFeatureCenter(), city);
r.AppendCity(city);
#endif
(res.*addFn)(r);
(res.*addFn)(MakeResult(impl::PreResult2(h->GetPosition(),
h->GetNumber() + ", " + houses[i].m_street->GetName(),
m_houseDetector.GetBuildingType())));
}
}
}
@ -889,14 +879,12 @@ template <class T> void Query::ProcessSuggestions(vector<T> & vec, Results & res
GetSuggestion(r.GetName(), suggest);
if (!suggest.empty() && added < MAX_SUGGESTS_COUNT)
{
Result rr(r.GetName(), suggest);
MakeResultHighlight(rr);
Result rr(MakeResult(r), suggest);
if (res.AddResultCheckExisting(rr))
{
++added;
i = vec.erase(i);
continue;
}
i = vec.erase(i);
continue;
}
}
++i;