diff --git a/indexer/editable_map_object.cpp b/indexer/editable_map_object.cpp index 51323430e8..9f01c3f77d 100644 --- a/indexer/editable_map_object.cpp +++ b/indexer/editable_map_object.cpp @@ -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 const & streets) +void EditableMapObject::SetNearbyStreets(vector && streets) { - m_nearbyStreets = streets; + m_nearbyStreets = move(streets); } void EditableMapObject::SetHouseNumber(string const & houseNumber) { diff --git a/indexer/editable_map_object.hpp b/indexer/editable_map_object.hpp index 526c08af73..d5bdc92a14 100644 --- a/indexer/editable_map_object.hpp +++ b/indexer/editable_map_object.hpp @@ -70,7 +70,7 @@ public: void SetID(FeatureID const & fid); // void SetTypes(feature::TypesHolder const & types); void SetStreet(string const & street); - void SetNearbyStreets(vector const & streets); + void SetNearbyStreets(vector && streets); void SetHouseNumber(string const & houseNumber); void SetPostcode(string const & postcode); void SetPhone(string const & phone); diff --git a/indexer/osm_editor.hpp b/indexer/osm_editor.hpp index 736136fab4..8f5bd315e0 100644 --- a/indexer/osm_editor.hpp +++ b/indexer/osm_editor.hpp @@ -31,7 +31,7 @@ public: using TMwmIdByMapNameFn = function; using TInvalidateFn = function; using TFeatureLoaderFn = function (FeatureID const & /*fid*/)>; - using TFeatureOriginalStreetFn = function; + using TFeatureOriginalStreetFn = function; using TForEachFeaturesNearByFn = function; enum class UploadResult diff --git a/map/address_finder.cpp b/map/address_finder.cpp index 9d9081b3c9..e9c39284fb 100644 --- a/map/address_finder.cpp +++ b/map/address_finder.cpp @@ -511,34 +511,6 @@ vector Framework::GetPrintableFeatureTypes(FeatureType const & ft) const return results; } -vector Framework::GetNearbyFeatureStreets(FeatureID const & fid) const -{ - return GetNearbyFeatureStreets(*GetFeatureByID(fid)); -} - -vector 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 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 { diff --git a/map/framework.cpp b/map/framework.cpp index fe8dfe9818..4d1c7fe734 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -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 FilterNearbyStreets(vector const & streets) +{ + vector 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 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 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; } diff --git a/map/framework.hpp b/map/framework.hpp index 1aee5ce77d..ff30300a05 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -489,11 +489,6 @@ public: search::AddressInfo GetFeatureAddressInfo(FeatureType & ft) const; search::AddressInfo GetFeatureAddressInfo(FeatureID const & fid) const; vector 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 GetNearbyFeatureStreets(FeatureType const & ft) const; - vector 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 GetFeatureAtPoint(m2::PointD const & mercator) const; diff --git a/search/reverse_geocoder.cpp b/search/reverse_geocoder.cpp index 5f2666f596..450c2a14de 100644 --- a/search/reverse_geocoder.cpp +++ b/search/reverse_geocoder.cpp @@ -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, uint32_t> -ReverseGeocoder::GetNearbyFeatureStreets(FeatureType const & ft) const +ReverseGeocoder::GetNearbyFeatureStreets(FeatureType & ft) const { pair, uint32_t> result; - GetNearbyStreets(const_cast(ft), result.first); + GetNearbyStreets(ft, result.first); HouseTable table(m_index); if (!table.Get(ft.GetID(), result.second)) diff --git a/search/reverse_geocoder.hpp b/search/reverse_geocoder.hpp index cfa8465c2b..2eb4c21f38 100644 --- a/search/reverse_geocoder.hpp +++ b/search/reverse_geocoder.hpp @@ -75,9 +75,9 @@ public: void GetNearbyStreets(FeatureType & ft, vector & 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, 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, 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;