[search] Treat addr:interpolation as Address object. #5063
29 changed files with 155 additions and 214 deletions
|
@ -211,7 +211,6 @@ void CaptionDescription::Init(FeatureType & f, int8_t deviceLang, int const zoom
|
|||
if (m_mainText.size() > kMaxTextSize)
|
||||
m_mainText = m_mainText.substr(0, kMaxTextSize) + "...";
|
||||
|
||||
m_roadNumber = f.GetRoadNumber();
|
||||
m_houseNumber = f.GetHouseNumber();
|
||||
|
||||
ProcessZoomLevel(zoomLevel);
|
||||
|
@ -228,11 +227,6 @@ std::string const & CaptionDescription::GetAuxText() const
|
|||
return m_auxText;
|
||||
}
|
||||
|
||||
std::string const & CaptionDescription::GetRoadNumber() const
|
||||
{
|
||||
return m_roadNumber;
|
||||
}
|
||||
|
||||
bool CaptionDescription::IsNameExists() const
|
||||
{
|
||||
return !m_mainText.empty() || !m_houseNumber.empty();
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include "indexer/feature_data.hpp"
|
||||
#include "indexer/ftypes_matcher.hpp"
|
||||
#include "indexer/drawing_rule_def.hpp"
|
||||
|
||||
|
@ -31,7 +30,6 @@ struct CaptionDescription
|
|||
|
||||
std::string const & GetMainText() const;
|
||||
std::string const & GetAuxText() const;
|
||||
std::string const & GetRoadNumber() const;
|
||||
bool IsNameExists() const;
|
||||
bool IsHouseNumberInMainText() const { return m_isHouseNumberInMainText; }
|
||||
|
||||
|
@ -43,7 +41,6 @@ private:
|
|||
|
||||
std::string m_mainText;
|
||||
std::string m_auxText;
|
||||
std::string m_roadNumber;
|
||||
std::string m_houseNumber;
|
||||
bool m_isHouseNumberInMainText = false;
|
||||
};
|
||||
|
|
|
@ -210,10 +210,14 @@ bool FeatureBuilder::PreSerialize()
|
|||
if (!m_params.IsValid())
|
||||
return false;
|
||||
|
||||
// Conform serialization logic (see HeaderMask::HEADER_MASK_HAS_ADDINFO):
|
||||
// - rank (city) is stored only for Point
|
||||
// - ref (road number, address range) is stored only for Line
|
||||
// - house is stored for PointEx and Area
|
||||
switch (m_params.GetGeomType())
|
||||
{
|
||||
case GeomType::Point:
|
||||
// Store house number like HEADER_GEOM_POINT_EX.
|
||||
// Store house number like HeaderGeomType::PointEx.
|
||||
if (!m_params.house.IsEmpty())
|
||||
{
|
||||
m_params.SetGeomTypePointEx();
|
||||
|
@ -222,7 +226,6 @@ bool FeatureBuilder::PreSerialize()
|
|||
|
||||
if (!m_params.ref.empty())
|
||||
{
|
||||
|
||||
if (ftypes::IsMotorwayJunctionChecker::Instance()(GetTypes()) ||
|
||||
(m_params.name.IsEmpty() &&
|
||||
(ftypes::IsPostBoxChecker::Instance()(GetTypes()) ||
|
||||
|
@ -232,9 +235,9 @@ bool FeatureBuilder::PreSerialize()
|
|||
{
|
||||
m_params.name.AddString(StringUtf8Multilang::kDefaultCode, m_params.ref);
|
||||
}
|
||||
}
|
||||
|
||||
m_params.ref.clear();
|
||||
m_params.ref.clear();
|
||||
}
|
||||
break;
|
||||
|
||||
case GeomType::Line:
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
#include "indexer/classificator.hpp"
|
||||
#include "indexer/data_source.hpp"
|
||||
#include "indexer/feature_algo.hpp"
|
||||
#include "indexer/feature_utils.hpp"
|
||||
#include "indexer/feature_visibility.hpp"
|
||||
#include "indexer/features_vector.hpp"
|
||||
#include "indexer/ftypes_matcher.hpp"
|
||||
#include "indexer/postcodes_matcher.hpp"
|
||||
#include "indexer/road_shields_parser.hpp"
|
||||
#include "indexer/scales_patch.hpp"
|
||||
#include "indexer/search_string_utils.hpp"
|
||||
#include "indexer/trie_builder.hpp"
|
||||
|
@ -314,7 +314,7 @@ public:
|
|||
// Road number.
|
||||
if (hasStreetType)
|
||||
{
|
||||
for (auto const & shield : feature::GetRoadShieldsNames(f.GetRoadNumber()))
|
||||
for (auto const & shield : ftypes::GetRoadShieldsNames(f))
|
||||
inserter(StringUtf8Multilang::kDefaultCode, shield);
|
||||
}
|
||||
|
||||
|
|
|
@ -128,15 +128,14 @@ void ScreenBase::SetAutoPerspective(bool isAutoPerspective)
|
|||
void ScreenBase::SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect)
|
||||
{
|
||||
m2::RectD const & lRect = glbRect.GetLocalRect();
|
||||
ASSERT(!lRect.IsEmptyInterior(), (lRect));
|
||||
ASSERT(lRect.IsValid(), (lRect));
|
||||
ASSERT(!pxRect.IsEmptyInterior(), (pxRect));
|
||||
|
||||
double const hScale = lRect.SizeX() / pxRect.SizeX();
|
||||
double const vScale = lRect.SizeY() / pxRect.SizeY();
|
||||
|
||||
ASSERT_GREATER(hScale, 0.0, ());
|
||||
ASSERT_GREATER(vScale, 0.0, ());
|
||||
m_Scale = std::max(hScale, vScale);
|
||||
ASSERT_GREATER(m_Scale, 0.0, ());
|
||||
|
||||
m_Angle = glbRect.Angle();
|
||||
m_Org = glbRect.GlobalCenter();
|
||||
|
||||
|
|
|
@ -823,7 +823,7 @@ uint8_t FeatureType::GetRank()
|
|||
|
||||
uint64_t FeatureType::GetPopulation() { return feature::RankToPopulation(GetRank()); }
|
||||
|
||||
string const & FeatureType::GetRoadNumber()
|
||||
string const & FeatureType::GetRef()
|
||||
{
|
||||
ParseCommon();
|
||||
return m_params.ref;
|
||||
|
|
|
@ -157,7 +157,7 @@ public:
|
|||
|
||||
uint8_t GetRank();
|
||||
uint64_t GetPopulation();
|
||||
std::string const & GetRoadNumber();
|
||||
std::string const & GetRef();
|
||||
|
||||
feature::Metadata const & GetMetadata();
|
||||
|
||||
|
|
|
@ -1,20 +1,13 @@
|
|||
#include "indexer/feature_impl.hpp"
|
||||
|
||||
#include "base/string_utils.hpp"
|
||||
#include "base/math.hpp"
|
||||
|
||||
namespace feature
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
bool IsHouseNumber(string const & s)
|
||||
{
|
||||
return !s.empty() && strings::IsASCIIDigit(s[0]);
|
||||
}
|
||||
|
||||
uint8_t PopulationToRank(uint64_t p)
|
||||
{
|
||||
return static_cast<uint8_t>(min(0xFF, base::SignedRound(log(double(p)) / log(1.1))));
|
||||
return static_cast<uint8_t>(std::min(0xFF, base::SignedRound(log(double(p)) / log(1.1))));
|
||||
}
|
||||
|
||||
uint64_t RankToPopulation(uint8_t r)
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include "base/assert.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
namespace strings { class UniString; }
|
||||
|
@ -21,8 +20,6 @@ inline std::string GetTagForIndex(std::string const & prefix, size_t ind)
|
|||
return prefix + char('0' + ind);
|
||||
}
|
||||
|
||||
bool IsHouseNumber(std::string const & s);
|
||||
|
||||
uint8_t PopulationToRank(uint64_t p);
|
||||
uint64_t RankToPopulation(uint8_t r);
|
||||
} // namespace feature
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
#include "indexer/feature_utils.hpp"
|
||||
|
||||
#include "indexer/classificator.hpp"
|
||||
#include "indexer/feature.hpp"
|
||||
#include "indexer/feature_data.hpp"
|
||||
#include "indexer/feature_visibility.hpp"
|
||||
#include "indexer/ftypes_matcher.hpp"
|
||||
#include "indexer/road_shields_parser.hpp"
|
||||
#include "indexer/scales.hpp"
|
||||
|
||||
#include "platform/localization.hpp"
|
||||
|
@ -13,7 +11,6 @@
|
|||
#include "coding/string_utf8_multilang.hpp"
|
||||
#include "coding/transliteration.hpp"
|
||||
|
||||
#include "base/base.hpp"
|
||||
#include "base/control_flow.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
|
@ -129,6 +126,10 @@ vector<int8_t> MakeLanguagesPriorityList(int8_t deviceLang, bool preferDefault)
|
|||
if (preferDefault)
|
||||
langPriority.push_back(StrUtf8::kDefaultCode);
|
||||
|
||||
/// @DebugNote
|
||||
// Add ru lang for descriptions/rendering tests.
|
||||
//langPriority.push_back(StrUtf8::GetLangIndex("ru"));
|
||||
|
||||
auto const similarLangs = GetSimilarLanguages(deviceLang);
|
||||
langPriority.insert(langPriority.cend(), similarLangs.cbegin(), similarLangs.cend());
|
||||
langPriority.insert(langPriority.cend(), {StrUtf8::kInternationalCode, StrUtf8::kEnglishCode});
|
||||
|
@ -436,12 +437,4 @@ vector<string> GetLocalizedRecyclingTypes(TypesHolder const & types)
|
|||
auto const & isRecyclingType = ftypes::IsRecyclingTypeChecker::Instance();
|
||||
return GetLocalizedTypes(isRecyclingType, types);
|
||||
}
|
||||
|
||||
vector<string> GetRoadShieldsNames(string const & rawRoadNumber)
|
||||
{
|
||||
vector<string> names;
|
||||
for (auto && shield : ftypes::GetRoadShields(rawRoadNumber))
|
||||
names.push_back(std::move(shield.m_name));
|
||||
return names;
|
||||
}
|
||||
} // namespace feature
|
||||
|
|
|
@ -125,7 +125,4 @@ namespace feature
|
|||
|
||||
// Returns vector of recycling types localized by platform.
|
||||
std::vector<std::string> GetLocalizedRecyclingTypes(TypesHolder const & types);
|
||||
|
||||
// Returns names of feature road shields. Applicable for road features.
|
||||
std::vector<std::string> GetRoadShieldsNames(std::string const & rawRoadNumber);
|
||||
} // namespace feature
|
||||
|
|
|
@ -385,7 +385,9 @@ IsStreetOrSquareChecker::IsStreetOrSquareChecker()
|
|||
|
||||
IsAddressObjectChecker::IsAddressObjectChecker() : BaseChecker(1 /* level */)
|
||||
{
|
||||
auto const paths = {"building", "amenity", "shop", "tourism", "historic", "office", "craft"};
|
||||
base::StringIL const paths = {
|
||||
"building", "amenity", "shop", "tourism", "historic", "office", "craft", "addr:interpolation"
|
||||
};
|
||||
|
||||
Classificator const & c = classif();
|
||||
for (auto const & p : paths)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "indexer/feature_algo.hpp"
|
||||
#include "indexer/feature_utils.hpp"
|
||||
#include "indexer/ftypes_matcher.hpp"
|
||||
#include "indexer/road_shields_parser.hpp"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
|
@ -58,7 +59,7 @@ void MapObject::SetFromFeatureType(FeatureType & ft)
|
|||
|
||||
m_metadata = ft.GetMetadata();
|
||||
m_houseNumber = ft.GetHouseNumber();
|
||||
m_roadNumber = ft.GetRoadNumber();
|
||||
m_roadShields = ftypes::GetRoadShieldsNames(ft);
|
||||
m_featureID = ft.GetID();
|
||||
m_geomType = ft.GetGeomType();
|
||||
|
||||
|
@ -159,14 +160,9 @@ string MapObject::FormatCuisines() const
|
|||
return strings::JoinStrings(GetLocalizedCuisines(), kFieldsSeparator);
|
||||
}
|
||||
|
||||
vector<string> MapObject::GetRoadShields() const
|
||||
{
|
||||
return feature::GetRoadShieldsNames(m_roadNumber);
|
||||
}
|
||||
|
||||
string MapObject::FormatRoadShields() const
|
||||
{
|
||||
return strings::JoinStrings(GetRoadShields(), kFieldsSeparator);
|
||||
return strings::JoinStrings(m_roadShields, kFieldsSeparator);
|
||||
}
|
||||
|
||||
int MapObject::GetStars() const
|
||||
|
|
|
@ -87,7 +87,6 @@ public:
|
|||
/// @returns translated and formatted cuisines.
|
||||
std::string FormatCuisines() const;
|
||||
|
||||
std::vector<std::string> GetRoadShields() const;
|
||||
std::string FormatRoadShields() const;
|
||||
|
||||
std::string_view GetOpeningHours() const;
|
||||
|
@ -119,7 +118,7 @@ protected:
|
|||
|
||||
StringUtf8Multilang m_name;
|
||||
std::string m_houseNumber;
|
||||
std::string m_roadNumber;
|
||||
std::vector<std::string> m_roadShields;
|
||||
feature::TypesHolder m_types;
|
||||
feature::Metadata m_metadata;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "indexer/road_shields_parser.hpp"
|
||||
|
||||
#include "indexer/feature.hpp"
|
||||
#include "indexer/ftypes_matcher.hpp"
|
||||
|
||||
#include "base/string_utils.hpp"
|
||||
|
||||
|
@ -582,8 +583,8 @@ public:
|
|||
|
||||
RoadShieldsSetT GetRoadShields(FeatureType & f)
|
||||
{
|
||||
std::string const roadNumber = f.GetRoadNumber();
|
||||
if (roadNumber.empty())
|
||||
auto const & ref = f.GetRef();
|
||||
if (ref.empty())
|
||||
return {};
|
||||
|
||||
// Find out country name.
|
||||
|
@ -596,7 +597,7 @@ RoadShieldsSetT GetRoadShields(FeatureType & f)
|
|||
if (underlinePos != std::string::npos)
|
||||
mwmName = mwmName.substr(0, underlinePos);
|
||||
|
||||
return GetRoadShields(mwmName, roadNumber);
|
||||
return GetRoadShields(mwmName, ref);
|
||||
}
|
||||
|
||||
RoadShieldsSetT GetRoadShields(std::string const & mwmName, std::string const & roadNumber)
|
||||
|
@ -640,8 +641,19 @@ RoadShieldsSetT GetRoadShields(std::string const & rawRoadNumber)
|
|||
if (rawRoadNumber.empty())
|
||||
return {};
|
||||
|
||||
return SimpleRoadShieldParser(rawRoadNumber, SimpleRoadShieldParser::ShieldTypes())
|
||||
.GetRoadShields();
|
||||
return SimpleRoadShieldParser(rawRoadNumber, SimpleRoadShieldParser::ShieldTypes()).GetRoadShields();
|
||||
}
|
||||
|
||||
std::vector<std::string> GetRoadShieldsNames(FeatureType & ft)
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
auto const & ref = ft.GetRef();
|
||||
if (!ref.empty() && IsStreetOrSquareChecker::Instance()(ft))
|
||||
{
|
||||
for (auto && shield : GetRoadShields(ref))
|
||||
names.push_back(std::move(shield.m_name));
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
std::string DebugPrint(RoadShieldType shieldType)
|
||||
|
|
|
@ -65,6 +65,9 @@ RoadShieldsSetT GetRoadShields(std::string const & mwmName, std::string const &
|
|||
// Simple parsing without specific country styles.
|
||||
RoadShieldsSetT GetRoadShields(std::string const & rawRoadNumber);
|
||||
|
||||
// Returns names of road shields if |ft| is a "highway" feature.
|
||||
std::vector<std::string> GetRoadShieldsNames(FeatureType & ft);
|
||||
|
||||
std::string DebugPrint(RoadShieldType shieldType);
|
||||
std::string DebugPrint(RoadShield const & shield);
|
||||
} // namespace ftypes
|
||||
|
|
|
@ -91,7 +91,7 @@ static PlacePageDataHotelType convertHotelType(std::optional<ftypes::IsHotelChec
|
|||
_title = rawData.GetTitle().empty() ? nil : @(rawData.GetTitle().c_str());
|
||||
_secondaryTitle = rawData.GetSecondaryTitle().empty() ? nil : @(rawData.GetSecondaryTitle().c_str());
|
||||
_subtitle = rawData.GetSubtitle().empty() ? nil : @(rawData.GetSubtitle().c_str());
|
||||
_coordinates = rawData.GetFormattedCoordinate(true).empty() ? nil : @(rawData.GetFormattedCoordinate(true).c_str());
|
||||
_coordinates = @(rawData.GetFormattedCoordinate(true).c_str());
|
||||
_address = rawData.GetAddress().empty() ? nil : @(rawData.GetAddress().c_str());
|
||||
_isMyPosition = rawData.IsMyPosition();
|
||||
_isPopular = rawData.GetPopularity() > 0;
|
||||
|
|
|
@ -12,7 +12,6 @@ set(SRC
|
|||
bookmark_manager.cpp
|
||||
bookmark_manager.hpp
|
||||
bookmarks_search_params.hpp
|
||||
caching_address_getter.hpp
|
||||
chart_generator.cpp
|
||||
chart_generator.hpp
|
||||
elevation_info.cpp
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "search/reverse_geocoder.hpp"
|
||||
|
||||
// TODO: get rid of this class when version 8.6 will not be supported.
|
||||
// TODO: because of fast algorithm and new mwm section which were implemented for 9.0.
|
||||
// Note: this class is NOT thread-safe.
|
||||
class CachingAddressGetter
|
||||
{
|
||||
public:
|
||||
search::ReverseGeocoder::Address GetAddressAtPoint(DataSource const & dataSource,
|
||||
m2::PointD const & pt,
|
||||
double distanceThresholdMeters) const
|
||||
{
|
||||
if (pt.EqualDxDy(m_cache.m_point, kMwmPointAccuracy))
|
||||
return m_cache.m_address;
|
||||
|
||||
m_cache.m_point = pt;
|
||||
m_cache.m_address = {};
|
||||
|
||||
search::ReverseGeocoder const coder(dataSource);
|
||||
coder.GetNearbyAddress(pt, distanceThresholdMeters, m_cache.m_address);
|
||||
|
||||
return m_cache.m_address;
|
||||
}
|
||||
private:
|
||||
struct Cache
|
||||
{
|
||||
m2::PointD m_point;
|
||||
search::ReverseGeocoder::Address m_address;
|
||||
};
|
||||
|
||||
mutable Cache m_cache;
|
||||
};
|
|
@ -589,10 +589,13 @@ void Framework::FillTrackInfo(Track const & track, m2::PointD const & trackPoint
|
|||
info.SetMercator(trackPoint);
|
||||
}
|
||||
|
||||
search::ReverseGeocoder::Address Framework::GetAddressAtPoint(m2::PointD const & pt,
|
||||
double distanceThresholdMeters) const
|
||||
search::ReverseGeocoder::Address Framework::GetAddressAtPoint(m2::PointD const & pt) const
|
||||
{
|
||||
return m_addressGetter.GetAddressAtPoint(m_featuresFetcher.GetDataSource(), pt, distanceThresholdMeters);
|
||||
search::ReverseGeocoder const coder(m_featuresFetcher.GetDataSource());
|
||||
search::ReverseGeocoder::Address addr;
|
||||
/// @todo Call exact address manually here?
|
||||
coder.GetNearbyAddress(pt, 0.5 /* maxDistanceM */, addr);
|
||||
return addr;
|
||||
}
|
||||
|
||||
void Framework::FillFeatureInfo(FeatureID const & fid, place_page::Info & info) const
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include "map/api_mark_point.hpp"
|
||||
#include "map/bookmark.hpp"
|
||||
#include "map/bookmark_manager.hpp"
|
||||
#include "map/caching_address_getter.hpp"
|
||||
#include "map/features_fetcher.hpp"
|
||||
#include "map/isolines_manager.hpp"
|
||||
#include "map/mwm_url.hpp"
|
||||
|
@ -598,8 +597,7 @@ private:
|
|||
void FillDescription(FeatureType & ft, place_page::Info & info) const;
|
||||
|
||||
public:
|
||||
search::ReverseGeocoder::Address GetAddressAtPoint(m2::PointD const & pt,
|
||||
double distanceThresholdMeters = 0.5) const;
|
||||
search::ReverseGeocoder::Address GetAddressAtPoint(m2::PointD const & pt) const;
|
||||
|
||||
/// Get "best for the user" feature at given point even if it's invisible on the screen.
|
||||
/// Ignores coastlines and prefers buildings over other area features.
|
||||
|
@ -714,7 +712,6 @@ public:
|
|||
std::string const & note);
|
||||
|
||||
private:
|
||||
CachingAddressGetter m_addressGetter;
|
||||
settings::UsageStats m_usageStats;
|
||||
|
||||
public:
|
||||
|
|
|
@ -89,7 +89,8 @@ void DirectionsEngine::LoadPathAttributes(FeatureID const & featureId,
|
|||
pathSegment.m_roadNameInfo.m_junction_ref = ft->GetMetadata(feature::Metadata::FMD_JUNCTION_REF);
|
||||
pathSegment.m_roadNameInfo.m_destination_ref = ft->GetMetadata(feature::Metadata::FMD_DESTINATION_REF);
|
||||
pathSegment.m_roadNameInfo.m_destination = ft->GetMetadata(feature::Metadata::FMD_DESTINATION);
|
||||
pathSegment.m_roadNameInfo.m_ref = ft->GetRoadNumber();
|
||||
/// @todo Should make some better parsing here (@see further use in GetFullRoadName).
|
||||
pathSegment.m_roadNameInfo.m_ref = ft->GetRef();
|
||||
pathSegment.m_roadNameInfo.m_name = ft->GetName(StringUtf8Multilang::kDefaultCode);
|
||||
}
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ private:
|
|||
{
|
||||
auto const interpol = ftypes::IsAddressInterpolChecker::Instance().GetInterpolType(feature);
|
||||
if (interpol != feature::InterpolType::None)
|
||||
return house_numbers::HouseNumbersMatchRange(feature.GetRoadNumber(), queryParse, interpol);
|
||||
return house_numbers::HouseNumbersMatchRange(feature.GetRef(), queryParse, interpol);
|
||||
else
|
||||
return house_numbers::HouseNumbersMatch(strings::MakeUniString(feature.GetHouseNumber()), queryParse);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
#include "house_detector.hpp"
|
||||
|
||||
#include "search/algos.hpp"
|
||||
#include "search/common.hpp"
|
||||
|
||||
#include "indexer/classificator.hpp"
|
||||
#include "indexer/feature_impl.hpp"
|
||||
#include "indexer/search_string_utils.hpp"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
@ -12,7 +7,6 @@
|
|||
#include "coding/string_utf8_multilang.hpp"
|
||||
|
||||
#include "geometry/angles.hpp"
|
||||
#include "geometry/parametrized_segment.hpp"
|
||||
|
||||
#include "base/limited_priority_queue.hpp"
|
||||
#include "base/logging.hpp"
|
||||
|
@ -30,13 +24,14 @@
|
|||
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
|
||||
namespace search
|
||||
{
|
||||
using namespace std;
|
||||
using namespace std::placeholders;
|
||||
|
||||
using boost::make_transform_iterator;
|
||||
|
||||
namespace search
|
||||
{
|
||||
namespace
|
||||
{
|
||||
#if 0
|
||||
|
@ -1092,38 +1087,36 @@ HouseProjection const * MergedStreet::GetHousePivot(bool isOdd, bool & sign) con
|
|||
template <typename ProjectionCalculator>
|
||||
void HouseDetector::ReadHouse(FeatureType & f, Street * st, ProjectionCalculator & calc)
|
||||
{
|
||||
string const houseNumber = f.GetHouseNumber();
|
||||
string const & hn = f.GetHouseNumber();
|
||||
if (hn.empty() || !ftypes::IsBuildingChecker::Instance()(f))
|
||||
return;
|
||||
|
||||
/// @todo After new data generation we can skip IsHouseNumber check here.
|
||||
if (ftypes::IsBuildingChecker::Instance()(f) && feature::IsHouseNumber(houseNumber))
|
||||
auto const it = m_id2house.find(f.GetID());
|
||||
bool const isNew = it == m_id2house.end();
|
||||
|
||||
m2::PointD const pt =
|
||||
isNew ? f.GetLimitRect(FeatureType::BEST_GEOMETRY).Center() : it->second->GetPosition();
|
||||
|
||||
HouseProjection pr;
|
||||
if (calc.GetProjection(pt, pr) && pr.m_distMeters <= m_houseOffsetM)
|
||||
{
|
||||
auto const it = m_id2house.find(f.GetID());
|
||||
bool const isNew = it == m_id2house.end();
|
||||
pr.m_streetDistance =
|
||||
st->GetPrefixLength(pr.m_segIndex) + st->m_points[pr.m_segIndex].Length(pr.m_proj);
|
||||
|
||||
m2::PointD const pt =
|
||||
isNew ? f.GetLimitRect(FeatureType::BEST_GEOMETRY).Center() : it->second->GetPosition();
|
||||
|
||||
HouseProjection pr;
|
||||
if (calc.GetProjection(pt, pr) && pr.m_distMeters <= m_houseOffsetM)
|
||||
House * p;
|
||||
if (isNew)
|
||||
{
|
||||
pr.m_streetDistance =
|
||||
st->GetPrefixLength(pr.m_segIndex) + st->m_points[pr.m_segIndex].Length(pr.m_proj);
|
||||
|
||||
House * p;
|
||||
if (isNew)
|
||||
{
|
||||
p = new House(houseNumber, pt);
|
||||
m_id2house[f.GetID()] = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = it->second;
|
||||
ASSERT(p != 0, ());
|
||||
}
|
||||
|
||||
pr.m_house = p;
|
||||
st->m_houses.push_back(pr);
|
||||
p = new House(hn, pt);
|
||||
m_id2house[f.GetID()] = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = it->second;
|
||||
ASSERT(p != 0, ());
|
||||
}
|
||||
|
||||
pr.m_house = p;
|
||||
st->m_houses.push_back(pr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "indexer/feature_utils.hpp"
|
||||
#include "indexer/ftypes_matcher.hpp"
|
||||
#include "indexer/map_object.hpp"
|
||||
#include "indexer/road_shields_parser.hpp"
|
||||
|
||||
#include "platform/measurement_utils.hpp"
|
||||
|
||||
|
@ -292,7 +293,7 @@ void FillDetails(FeatureType & ft, Result::Details & details)
|
|||
auto const cuisines = feature::GetLocalizedCuisines(feature::TypesHolder(ft));
|
||||
details.m_cuisine = strings::JoinStrings(cuisines, osm::MapObject::kFieldsSeparator);
|
||||
|
||||
auto const roadShields = feature::GetRoadShieldsNames(ft.GetRoadNumber());
|
||||
auto const roadShields = ftypes::GetRoadShieldsNames(ft);
|
||||
details.m_roadShields = strings::JoinStrings(roadShields, osm::MapObject::kFieldsSeparator);
|
||||
|
||||
details.m_isInitialized = true;
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
#include "indexer/data_source.hpp"
|
||||
#include "indexer/feature_algo.hpp"
|
||||
#include "indexer/feature_data.hpp"
|
||||
#include "indexer/feature_utils.hpp"
|
||||
#include "indexer/ftypes_matcher.hpp"
|
||||
#include "indexer/road_shields_parser.hpp"
|
||||
#include "indexer/search_string_utils.hpp"
|
||||
|
||||
#include "coding/string_utf8_multilang.hpp"
|
||||
|
@ -170,7 +170,7 @@ NameScores GetNameScores(FeatureType & ft, Geocoder::Params const & params,
|
|||
|
||||
if (type == Model::TYPE_STREET)
|
||||
{
|
||||
for (auto const & shield : feature::GetRoadShieldsNames(ft.GetRoadNumber()))
|
||||
for (auto const & shield : ftypes::GetRoadShieldsNames(ft))
|
||||
UpdateNameScores(shield, StringUtf8Multilang::kDefaultCode, sliceNoCategories, bestScores);
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,8 @@ string FormatStreetAndHouse(ReverseGeocoder::Address const & addr)
|
|||
// 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.
|
||||
/// @todo Print "near" for not exact addresses.
|
||||
/// Add some threshold for addr:interpolation or refactor ReverseGeocoder?
|
||||
if (addr.GetDistance() != 0)
|
||||
return region;
|
||||
|
||||
|
@ -305,47 +306,6 @@ bool ResultExists(RankerResult const & p, vector<RankerResult> const & results,
|
|||
return find_if(results.begin(), results.end(), equalCmp) != results.cend();
|
||||
}
|
||||
|
||||
class LazyAddressGetter
|
||||
{
|
||||
public:
|
||||
LazyAddressGetter(ReverseGeocoder const & reverseGeocoder, m2::PointD const & center)
|
||||
: m_reverseGeocoder(reverseGeocoder), m_center(center)
|
||||
{
|
||||
}
|
||||
|
||||
ReverseGeocoder::Address const & GetNearbyAddress()
|
||||
{
|
||||
if (m_computedNearby)
|
||||
return m_address;
|
||||
m_reverseGeocoder.GetNearbyAddress(m_center, m_address);
|
||||
m_computedNearby = true;
|
||||
return m_address;
|
||||
}
|
||||
|
||||
bool GetExactAddress(ReverseGeocoder::Address & address)
|
||||
{
|
||||
if (m_computedExact)
|
||||
{
|
||||
address = m_address;
|
||||
return true;
|
||||
}
|
||||
m_reverseGeocoder.GetNearbyAddress(m_center, 0.0, m_address);
|
||||
if (m_address.IsValid())
|
||||
{
|
||||
m_computedExact = true;
|
||||
m_computedNearby = true;
|
||||
address = m_address;
|
||||
}
|
||||
return m_computedExact;
|
||||
}
|
||||
|
||||
private:
|
||||
ReverseGeocoder const & m_reverseGeocoder;
|
||||
m2::PointD const m_center;
|
||||
ReverseGeocoder::Address m_address;
|
||||
bool m_computedExact = false;
|
||||
bool m_computedNearby = false;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
class RankerResultMaker
|
||||
|
@ -453,6 +413,15 @@ private:
|
|||
return ft;
|
||||
}
|
||||
|
||||
bool GetExactAddress(FeatureType & ft, m2::PointD const & center, ReverseGeocoder::Address & addr) const
|
||||
{
|
||||
if (m_reverseGeocoder.GetExactAddress(ft, addr))
|
||||
return true;
|
||||
|
||||
m_reverseGeocoder.GetNearbyAddress(center, 0.0 /* maxDistanceM */, addr);
|
||||
return addr.IsValid();
|
||||
}
|
||||
|
||||
// For the best performance, incoming ids should be sorted by id.first (mwm file id).
|
||||
unique_ptr<FeatureType> LoadFeature(FeatureID const & id, m2::PointD & center, string & name,
|
||||
string & country)
|
||||
|
@ -475,7 +444,7 @@ private:
|
|||
if (name.empty())
|
||||
{
|
||||
ReverseGeocoder::Address addr;
|
||||
if (LazyAddressGetter(m_reverseGeocoder, center).GetExactAddress(addr))
|
||||
if (GetExactAddress(*ft, center, addr))
|
||||
{
|
||||
unique_ptr<FeatureType> streetFeature;
|
||||
|
||||
|
@ -721,7 +690,13 @@ Result Ranker::MakeResult(RankerResult const & rankerResult, bool needAddress, b
|
|||
|
||||
// Format full address only for suitable results.
|
||||
if (ftypes::IsAddressObjectChecker::Instance()(rankerResult.GetTypes()))
|
||||
address = FormatFullAddress(LazyAddressGetter(m_reverseGeocoder, rankerResult.GetCenter()).GetNearbyAddress(), address);
|
||||
{
|
||||
ReverseGeocoder::Address addr;
|
||||
if (!(rankerResult.GetID().IsValid() && m_reverseGeocoder.GetExactAddress(rankerResult.GetID(), addr)))
|
||||
m_reverseGeocoder.GetNearbyAddress(rankerResult.GetCenter(), addr);
|
||||
|
||||
address = FormatFullAddress(addr, address);
|
||||
}
|
||||
|
||||
res.SetAddress(std::move(address));
|
||||
}
|
||||
|
@ -991,4 +966,5 @@ string Ranker::GetLocalizedRegionInfoForResult(RankerResult const & result) cons
|
|||
|
||||
return m_regionInfoGetter.GetLocalizedFullName(id);
|
||||
}
|
||||
|
||||
} // namespace search
|
||||
|
|
|
@ -77,6 +77,20 @@ string Join(string const & s, Args &&... args)
|
|||
return s;
|
||||
return s + ", " + tail;
|
||||
}
|
||||
|
||||
ReverseGeocoder::Building FromFeatureImpl(FeatureType & ft, std::string const & hn, double distMeters)
|
||||
{
|
||||
return { ft.GetID(), distMeters, hn, feature::GetCenter(ft) };
|
||||
}
|
||||
|
||||
std::string const & GetHouseNumber(FeatureType & ft)
|
||||
{
|
||||
std::string const & hn = ft.GetHouseNumber();
|
||||
if (hn.empty() && ftypes::IsAddressInterpolChecker::Instance()(ft))
|
||||
return ft.GetRef();
|
||||
return hn;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ReverseGeocoder::ReverseGeocoder(DataSource const & dataSource) : m_dataSource(dataSource) {}
|
||||
|
@ -217,11 +231,10 @@ bool ReverseGeocoder::GetOriginalStreetByHouse(FeatureType & house, FeatureID &
|
|||
|
||||
void ReverseGeocoder::GetNearbyAddress(m2::PointD const & center, Address & addr) const
|
||||
{
|
||||
return GetNearbyAddress(center, kLookupRadiusM, addr);
|
||||
GetNearbyAddress(center, kLookupRadiusM, addr);
|
||||
}
|
||||
|
||||
void ReverseGeocoder::GetNearbyAddress(m2::PointD const & center, double maxDistanceM,
|
||||
Address & addr) const
|
||||
void ReverseGeocoder::GetNearbyAddress(m2::PointD const & center, double maxDistanceM, Address & addr) const
|
||||
{
|
||||
vector<Building> buildings;
|
||||
GetNearbyBuildings(center, maxDistanceM, buildings);
|
||||
|
@ -241,11 +254,12 @@ void ReverseGeocoder::GetNearbyAddress(m2::PointD const & center, double maxDist
|
|||
|
||||
bool ReverseGeocoder::GetExactAddress(FeatureType & ft, Address & addr) const
|
||||
{
|
||||
if (ft.GetHouseNumber().empty())
|
||||
std::string const & hn = GetHouseNumber(ft);
|
||||
if (hn.empty())
|
||||
return false;
|
||||
|
||||
HouseTable table(m_dataSource);
|
||||
return GetNearbyAddress(table, FromFeature(ft, 0.0 /* distMeters */), false /* ignoreEdits */,
|
||||
addr);
|
||||
return GetNearbyAddress(table, FromFeatureImpl(ft, hn, 0.0 /* distMeters */), false /* ignoreEdits */, addr);
|
||||
}
|
||||
|
||||
bool ReverseGeocoder::GetExactAddress(FeatureID const & fid, Address & addr) const
|
||||
|
@ -311,10 +325,15 @@ bool ReverseGeocoder::GetNearbyAddress(HouseTable & table, Building const & bld,
|
|||
void ReverseGeocoder::GetNearbyBuildings(m2::PointD const & center, double radius,
|
||||
vector<Building> & buildings) const
|
||||
{
|
||||
auto const addBuilding = [&](FeatureType & ft) {
|
||||
auto const addBuilding = [&](FeatureType & ft)
|
||||
{
|
||||
std::string const & hn = GetHouseNumber(ft);
|
||||
if (hn.empty())
|
||||
return;
|
||||
|
||||
auto const distance = feature::GetMinDistanceMeters(ft, center);
|
||||
if (!ft.GetHouseNumber().empty() && distance <= radius)
|
||||
buildings.push_back(FromFeature(ft, distance));
|
||||
if (distance <= radius)
|
||||
buildings.push_back(FromFeatureImpl(ft, hn, distance));
|
||||
};
|
||||
|
||||
auto const stop = [&]() { return buildings.size() >= kMaxNumTriesToApproxAddress; };
|
||||
|
@ -371,7 +390,7 @@ string ReverseGeocoder::GetLocalizedRegionAddress(RegionAddress const & addr,
|
|||
// static
|
||||
ReverseGeocoder::Building ReverseGeocoder::FromFeature(FeatureType & ft, double distMeters)
|
||||
{
|
||||
return { ft.GetID(), distMeters, ft.GetHouseNumber(), feature::GetCenter(ft) };
|
||||
return FromFeatureImpl(ft, ft.GetHouseNumber(), distMeters);
|
||||
}
|
||||
|
||||
std::optional<HouseToStreetTable::Result> ReverseGeocoder::HouseTable::Get(FeatureID const & fid)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "indexer/feature.hpp"
|
||||
#include "indexer/feature_algo.hpp"
|
||||
#include "indexer/road_shields_parser.hpp"
|
||||
#include "indexer/search_string_utils.hpp"
|
||||
|
||||
#include "base/control_flow.hpp"
|
||||
|
@ -151,10 +152,6 @@ bool Matcher::Matches(strings::UniString const & query, Sample::Result const & g
|
|||
bool Matcher::Matches(strings::UniString const & query, Sample::Result const & golden,
|
||||
FeatureType & ft)
|
||||
{
|
||||
static double constexpr kToleranceMeters = 50;
|
||||
|
||||
auto const houseNumber = ft.GetHouseNumber();
|
||||
|
||||
auto const queryTokens = NormalizeAndTokenizeAsUtf8(ToUtf8(query));
|
||||
|
||||
bool nameMatches = false;
|
||||
|
@ -166,7 +163,14 @@ bool Matcher::Matches(strings::UniString const & query, Sample::Result const & g
|
|||
{
|
||||
if (ft.GetGeomType() == feature::GeomType::Line)
|
||||
{
|
||||
nameMatches = StreetMatches(ft.GetRoadNumber(), queryTokens);
|
||||
for (auto const & name : ftypes::GetRoadShieldsNames(ft))
|
||||
{
|
||||
if (StreetMatches(name, queryTokens))
|
||||
{
|
||||
nameMatches = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -195,10 +199,11 @@ bool Matcher::Matches(strings::UniString const & query, Sample::Result const & g
|
|||
});
|
||||
|
||||
bool houseNumberMatches = true;
|
||||
if (!golden.m_houseNumber.empty() && !houseNumber.empty())
|
||||
houseNumberMatches = golden.m_houseNumber == houseNumber;
|
||||
std::string const & hn = ft.GetHouseNumber();
|
||||
if (!golden.m_houseNumber.empty() && !hn.empty())
|
||||
houseNumberMatches = golden.m_houseNumber == hn;
|
||||
|
||||
return (nameMatches && houseNumberMatches &&
|
||||
feature::GetMinDistanceMeters(ft, golden.m_pos) < kToleranceMeters);
|
||||
/// @todo Where are 50 meters came from?
|
||||
return (nameMatches && houseNumberMatches && feature::GetMinDistanceMeters(ft, golden.m_pos) < 50.0);
|
||||
}
|
||||
} // namespace search
|
||||
|
|
|
@ -215,12 +215,9 @@ m2::RectD GenerateNearbyViewport(m2::PointD const & point)
|
|||
|
||||
bool GetBuildingInfo(FeatureType & ft, search::ReverseGeocoder const & coder, string & street)
|
||||
{
|
||||
auto const houseNumber = ft.GetHouseNumber();
|
||||
if (houseNumber.empty() ||
|
||||
!search::house_numbers::LooksLikeHouseNumber(houseNumber, false /* prefix */))
|
||||
{
|
||||
std::string const & hn = ft.GetHouseNumber();
|
||||
if (hn.empty() || !search::house_numbers::LooksLikeHouseNumber(hn, false /* prefix */))
|
||||
return false;
|
||||
}
|
||||
|
||||
street = coder.GetFeatureStreetName(ft);
|
||||
if (street.empty())
|
||||
|
@ -323,9 +320,8 @@ optional<Sample> GenerateRequest(
|
|||
}
|
||||
}
|
||||
|
||||
auto const house = ft.GetHouseNumber();
|
||||
auto const featureCenter = feature::GetCenter(ft);
|
||||
auto const address = ModifyAddress(street, house, lang);
|
||||
auto const address = ModifyAddress(std::move(street), ft.GetHouseNumber(), lang);
|
||||
auto query = address;
|
||||
if (!cafeStr.empty())
|
||||
query = FLAGS_add_cafe_address ? CombineRandomly(cafeStr, address) : cafeStr;
|
||||
|
|
Reference in a new issue