forked from organicmaps/organicmaps
[editor] Correctly set nearby streets for created features, minor refactoring.
This commit is contained in:
parent
7847d189c7
commit
23b92892e7
8 changed files with 61 additions and 49 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue