[editor] Correctly set nearby streets for created features, minor refactoring.

This commit is contained in:
Alex Zolotarev 2016-03-07 07:33:06 +03:00 committed by Sergey Yershov
parent 7847d189c7
commit 23b92892e7
8 changed files with 61 additions and 49 deletions

View file

@ -84,9 +84,9 @@ void EditableMapObject::SetType(uint32_t featureType)
void EditableMapObject::SetID(FeatureID const & fid) { m_featureID = fid; }
void EditableMapObject::SetStreet(string const & street) { m_street = street; }
void EditableMapObject::SetNearbyStreets(vector<string> const & streets)
void EditableMapObject::SetNearbyStreets(vector<string> && streets)
{
m_nearbyStreets = streets;
m_nearbyStreets = move(streets);
}
void EditableMapObject::SetHouseNumber(string const & houseNumber)
{

View file

@ -70,7 +70,7 @@ public:
void SetID(FeatureID const & fid);
// void SetTypes(feature::TypesHolder const & types);
void SetStreet(string const & street);
void SetNearbyStreets(vector<string> const & streets);
void SetNearbyStreets(vector<string> && streets);
void SetHouseNumber(string const & houseNumber);
void SetPostcode(string const & postcode);
void SetPhone(string const & phone);

View file

@ -31,7 +31,7 @@ public:
using TMwmIdByMapNameFn = function<MwmSet::MwmId(string const & /*map*/)>;
using TInvalidateFn = function<void()>;
using TFeatureLoaderFn = function<unique_ptr<FeatureType> (FeatureID const & /*fid*/)>;
using TFeatureOriginalStreetFn = function<string(FeatureType const & /*ft*/)>;
using TFeatureOriginalStreetFn = function<string(FeatureType & /*ft*/)>;
using TForEachFeaturesNearByFn =
function<void(TFeatureTypeFn && /*fn*/, m2::PointD const & /*mercator*/)>;
enum class UploadResult

View file

@ -511,34 +511,6 @@ vector<string> Framework::GetPrintableFeatureTypes(FeatureType const & ft) const
return results;
}
vector<string> Framework::GetNearbyFeatureStreets(FeatureID const & fid) const
{
return GetNearbyFeatureStreets(*GetFeatureByID(fid));
}
vector<string> Framework::GetNearbyFeatureStreets(FeatureType const & ft) const
{
search::ReverseGeocoder const coder(m_model.GetIndex());
// Need to filter out duplicate street names.
auto const streets = coder.GetNearbyFeatureStreets(ft);
// Reasonable number of different nearby street names to display in UI.
size_t const kMinNumberOfNearbyStreets = 8;
vector<string> results;
// Feature's street from OSM data, if exists, always goes first.
if (streets.second < streets.first.size())
results.push_back(streets.first[streets.second].m_name);
for (auto const & street : streets.first)
{
auto const e = results.end();
if (e == find(results.begin(), e, street.m_name))
{
results.push_back(street.m_name);
if (results.size() >= kMinNumberOfNearbyStreets)
break;
}
}
return results;
}
/*
void Framework::GetLocality(m2::PointD const & pt, search::AddressInfo & info) const
{

View file

@ -374,7 +374,7 @@ Framework::Framework()
feature->ParseEverything();
return feature;
});
editor.SetFeatureOriginalStreetFn([this](FeatureType const & ft) -> string
editor.SetFeatureOriginalStreetFn([this](FeatureType & ft) -> string
{
search::ReverseGeocoder const coder(m_model.GetIndex());
auto const streets = coder.GetNearbyFeatureStreets(ft);
@ -2327,6 +2327,27 @@ bool Framework::ParseEditorDebugCommand(search::SearchParams const & params)
return false;
}
namespace
{
vector<string> FilterNearbyStreets(vector<search::ReverseGeocoder::Street> const & streets)
{
vector<string> results;
// Reasonable number of different nearby street names to display in UI.
constexpr size_t kMaxNumberOfNearbyStreetsToDisplay = 8;
for (auto const & street : streets)
{
auto const e = results.end();
if (e == find(results.begin(), e, street.m_name))
{
results.push_back(street.m_name);
if (results.size() >= kMaxNumberOfNearbyStreetsToDisplay)
break;
}
}
return results;
}
} // namespace
bool Framework::CreateMapObject(m2::PointD const & mercator, uint32_t const featureType,
osm::EditableMapObject & emo) const
{
@ -2334,6 +2355,11 @@ bool Framework::CreateMapObject(m2::PointD const & mercator, uint32_t const feat
platform::CountryFile(m_infoGetter->GetRegionCountryId(mercator)));
if (!mwmId.IsAlive())
return false;
search::ReverseGeocoder const coder(m_model.GetIndex());
vector<search::ReverseGeocoder::Street> streets;
coder.GetNearbyStreets(mwmId, mercator, streets);
emo.SetNearbyStreets(FilterNearbyStreets(streets));
return osm::Editor::Instance().CreatePoint(featureType, mercator, mwmId, emo);
}
@ -2341,14 +2367,34 @@ bool Framework::GetEditableMapObject(FeatureID const & fid, osm::EditableMapObje
{
if (!fid.IsValid())
return false;
// TODO(AlexZ): Move this code to the Editor.
auto feature = GetFeatureByID(fid);
FeatureType & ft = *feature;
emo.SetFromFeatureType(ft);
emo.SetHouseNumber(ft.GetHouseNumber());
emo.SetStreet(GetFeatureAddressInfo(ft).m_street);
emo.SetNearbyStreets(GetNearbyFeatureStreets(ft));
emo.SetEditableProperties(osm::Editor::Instance().GetEditableProperties(ft));
osm::Editor & editor = osm::Editor::Instance();
emo.SetEditableProperties(editor.GetEditableProperties(ft));
string street;
if (editor.GetEditedFeatureStreet(fid, street))
{
// Exact feature's street is taken directy from the Editor.
// Fill only nearby streets.
search::ReverseGeocoder const coder(m_model.GetIndex());
vector<search::ReverseGeocoder::Street> streets;
coder.GetNearbyStreets(fid.m_mwmId, feature::GetCenter(*feature), streets);
emo.SetNearbyStreets(FilterNearbyStreets(streets));
}
else
{
// Get exact feature's street address (if any) from mwm, together with all nearby streets.
search::ReverseGeocoder const coder(m_model.GetIndex());
auto const streets = coder.GetNearbyFeatureStreets(ft);
if (streets.second < streets.first.size())
street = streets.first[streets.second].m_name;
emo.SetNearbyStreets(FilterNearbyStreets(streets.first));
}
emo.SetStreet(street);
return true;
}

View file

@ -489,11 +489,6 @@ public:
search::AddressInfo GetFeatureAddressInfo(FeatureType & ft) const;
search::AddressInfo GetFeatureAddressInfo(FeatureID const & fid) const;
vector<string> GetPrintableFeatureTypes(FeatureType const & ft) const;
/// If feature does not have explicit street in OSM data, first value can be a closest named street.
/// If it does have explicit street name in OSM, it goes first in the returned vector.
/// @returns empty vector if no named streets were found around feature.
vector<string> GetNearbyFeatureStreets(FeatureType const & ft) const;
vector<string> GetNearbyFeatureStreets(FeatureID const & fid) const;
/// Get "best for the user" feature at given point even if it's invisible on the screen.
/// @returns nullptr if no feature was found at the given mercator point.
unique_ptr<FeatureType> GetFeatureAtPoint(m2::PointD const & mercator) const;

View file

@ -39,8 +39,7 @@ void ReverseGeocoder::GetNearbyStreets(MwmSet::MwmId const & id, m2::PointD cons
}
string name;
static int8_t const lang = StringUtf8Multilang::GetLangIndex("default");
if (!ft.GetName(lang, name))
if (!ft.GetName(StringUtf8Multilang::kDefaultCode, name))
return;
ASSERT(!name.empty(), ());
@ -100,11 +99,11 @@ size_t ReverseGeocoder::GetMatchedStreetIndex(string const & keyName,
}
pair<vector<ReverseGeocoder::Street>, uint32_t>
ReverseGeocoder::GetNearbyFeatureStreets(FeatureType const & ft) const
ReverseGeocoder::GetNearbyFeatureStreets(FeatureType & ft) const
{
pair<vector<ReverseGeocoder::Street>, uint32_t> result;
GetNearbyStreets(const_cast<FeatureType &>(ft), result.first);
GetNearbyStreets(ft, result.first);
HouseTable table(m_index);
if (!table.Get(ft.GetID(), result.second))

View file

@ -75,9 +75,9 @@ public:
void GetNearbyStreets(FeatureType & ft, vector<Street> & streets) const;
//@}
/// @todo Leave const reference for now to support client's legacy code.
/// It's better to use honest non-const reference when feature can be modified in any way.
pair<vector<Street>, uint32_t> GetNearbyFeatureStreets(FeatureType const & ft) const;
/// @returns [a lot of] nearby feature's streets and feature's street index, if valid ( < vector.size()).
/// @note returned vector can contain duplicated street segments.
pair<vector<Street>, uint32_t> GetNearbyFeatureStreets(FeatureType & ft) const;
/// @return The nearest exact address where building has house number and valid street match.
void GetNearbyAddress(m2::PointD const & center, Address & addr) const;