diff options
author | vng <viktor.govako@gmail.com> | 2012-07-24 23:53:40 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 01:41:23 +0300 |
commit | b323f502461df546528d4b2ff932b2af531d8bc0 (patch) | |
tree | 1a53d35469de478004835d9e20e9ee6a57abdce1 /map/address_finder.cpp | |
parent | ee3f59fcd1edb15a80611dc577b71d04fc4010a1 (diff) |
Fix address getting: different distance for POI, streets, buildings; do not mix up meters and degrees.
Diffstat (limited to 'map/address_finder.cpp')
-rw-r--r-- | map/address_finder.cpp | 138 |
1 files changed, 92 insertions, 46 deletions
diff --git a/map/address_finder.cpp b/map/address_finder.cpp index 2551f8b649..70a3c21ecb 100644 --- a/map/address_finder.cpp +++ b/map/address_finder.cpp @@ -27,6 +27,7 @@ namespace void Swap(FeatureInfoT & rhs) { swap(m_dist, rhs.m_dist); + swap(m_pt, rhs.m_pt); m_name.swap(rhs.m_name); m_house.swap(rhs.m_house); swap(m_types, rhs.m_types); @@ -53,6 +54,7 @@ namespace class DoGetFeatureInfoBase { protected: + virtual bool IsInclude(double dist, feature::TypesHolder const & types) const = 0; virtual double GetResultDistance(double d, feature::TypesHolder const & types) const = 0; virtual double NeedProcess(feature::TypesHolder const & types) const { @@ -78,8 +80,8 @@ namespace } public: - DoGetFeatureInfoBase(m2::PointD const & pt, double eps, int scale) - : m_pt(pt), m_scale(scale), m_eps(eps) + DoGetFeatureInfoBase(m2::PointD const & pt, int scale) + : m_pt(pt), m_scale(scale) { m_coastType = classif().GetCoastType(); } @@ -92,7 +94,7 @@ namespace double const d = f.GetDistance(m_pt, m_scale); ASSERT_GREATER_OR_EQUAL(d, 0.0, ()); - if (d <= m_eps) + if (IsInclude(d, types)) { string name, house; f.GetPrefferedNames(name, house /*dummy parameter*/); @@ -119,13 +121,16 @@ namespace protected: int m_scale; - double m_eps; vector<FeatureInfoT> m_cont; }; class DoGetFeatureTypes : public DoGetFeatureInfoBase { protected: + virtual bool IsInclude(double dist, feature::TypesHolder const & types) const + { + return (dist <= m_eps); + } virtual double GetResultDistance(double d, feature::TypesHolder const & types) const { return (d + GetCompareEpsilonImpl(types.GetGeoType(), m_eps)); @@ -133,7 +138,7 @@ namespace public: DoGetFeatureTypes(m2::PointD const & pt, double eps, int scale) - : DoGetFeatureInfoBase(pt, eps, scale) + : DoGetFeatureInfoBase(pt, scale), m_eps(eps) { } @@ -147,6 +152,9 @@ namespace for (size_t j = 0; j < m_cont[i].m_types.Size(); ++j) types.push_back(c.GetFullObjectName(m_cont[i].m_types[j])); } + + private: + double m_eps; }; } @@ -173,7 +181,7 @@ void Framework::GetFeatureTypes(m2::PointD pt, vector<string> & types) const namespace { - class DoGetAddressInfo : public DoGetFeatureInfoBase + class DoGetAddressBase : public DoGetFeatureInfoBase { public: class TypeChecker @@ -282,48 +290,46 @@ namespace } }; + protected: TypeChecker const & m_checker; - bool m_doLocalities; + public: + DoGetAddressBase(m2::PointD const & pt, int scale, TypeChecker const & checker) + : DoGetFeatureInfoBase(pt, scale), m_checker(checker) + { + } + }; + + class DoGetAddressInfo : public DoGetAddressBase + { protected: - virtual double GetResultDistance(double d, feature::TypesHolder const & types) const + virtual bool IsInclude(double dist, feature::TypesHolder const & types) const { - if (!m_doLocalities) - return (d + GetCompareEpsilonImpl(types.GetGeoType(), 5.0 * MercatorBounds::degreeInMetres)); - else - { - // This routine is needed for quality of locality prediction. - // Hamlet may be the nearest point, but it's a part of a City. So use the divide factor - // for distance, according to feature type. - return (d / m_checker.GetLocalityDivideFactor(types)); - } + return (dist <= m_arrEps[types.GetGeoType()]); } - virtual double NeedProcess(feature::TypesHolder const & types) const + + virtual double GetResultDistance(double d, feature::TypesHolder const & types) const { - if (m_doLocalities) - { - return (types.GetGeoType() == feature::GEOM_POINT && m_checker.IsLocality(types)); - } - else - { - // we need features with texts for address lookup - pair<int, int> const r = feature::GetDrawableScaleRangeForText(types); - return my::between_s(r.first, r.second, m_scale); - } + return (d + GetCompareEpsilonImpl(types.GetGeoType(), 5.0 * MercatorBounds::degreeInMetres)); } - public: - DoGetAddressInfo(m2::PointD const & pt, double eps, int scale, - TypeChecker const & checker) - : DoGetFeatureInfoBase(pt, eps, scale), - m_checker(checker), m_doLocalities(false) + virtual double NeedProcess(feature::TypesHolder const & types) const { + // we need features with texts for address lookup + pair<int, int> const r = feature::GetDrawableScaleRangeForText(types); + return my::between_s(r.first, r.second, m_scale); } - void PrepareForLocalities() + public: + DoGetAddressInfo(m2::PointD const & pt, int scale, TypeChecker const & checker, + double (&arrRadius) [3]) + : DoGetAddressBase(pt, scale, checker) { - m_doLocalities = true; - m_cont.clear(); + for (size_t i = 0; i < 3; ++i) + { + m2::RectD const r = MercatorBounds::RectByCenterXYAndSizeInMeters(pt, arrRadius[i]); + m_arrEps[i] = (r.SizeX() + r.SizeY()) / 2.0; + } } void FillAddress(search::Engine const * eng, Framework::AddressInfo & info) @@ -363,6 +369,39 @@ namespace } } + private: + double m_arrEps[3]; + }; + + class DoGetLocality : public DoGetAddressBase + { + protected: + virtual bool IsInclude(double dist, feature::TypesHolder const & types) const + { + return (dist <= m_eps); + } + + virtual double GetResultDistance(double d, feature::TypesHolder const & types) const + { + // This routine is needed for quality of locality prediction. + // Hamlet may be the nearest point, but it's a part of a City. So use the divide factor + // for distance, according to feature type. + return (d / m_checker.GetLocalityDivideFactor(types)); + } + + virtual double NeedProcess(feature::TypesHolder const & types) const + { + return (types.GetGeoType() == feature::GEOM_POINT && m_checker.IsLocality(types)); + } + + public: + DoGetLocality(m2::PointD const & pt, int scale, TypeChecker const & checker, + m2::RectD const & rect) + : DoGetAddressBase(pt, scale, checker) + { + m_eps = max(rect.SizeX(), rect.SizeY()); + } + void FillLocality(Framework::AddressInfo & info, Framework const & fm) { SortResults(); @@ -377,6 +416,9 @@ namespace } } } + + private: + double m_eps; }; } @@ -392,17 +434,22 @@ void Framework::GetAddressInfo(m2::PointD const & pt, AddressInfo & info) const } int scale = scales::GetUpperScale(); - double const addressR = 200.0; - double const localityR = 20000.0; + double addressR[] = { + 15.0, // radius to search point POI's + 100.0, // radius to search street names + 5.0 // radius to search building numbers (POI's) + }; + double const localityR = 20000.0; // radius to search localities - static DoGetAddressInfo::TypeChecker checker; + static DoGetAddressBase::TypeChecker checker; // first of all - get an address { - DoGetAddressInfo getAddress(pt, addressR, scale, checker); + // pass maximum value for all addressR + m2::RectD const rect = MercatorBounds::RectByCenterXYAndSizeInMeters(pt, addressR[1]); + DoGetAddressInfo getAddress(pt, scale, checker, addressR); - m_model.ForEachFeature( - MercatorBounds::RectByCenterXYAndSizeInMeters(pt, addressR), getAddress, scale); + m_model.ForEachFeature(rect, getAddress, scale); getAddress.FillAddress(GetSearchEngine(), info); } @@ -412,11 +459,10 @@ void Framework::GetAddressInfo(m2::PointD const & pt, AddressInfo & info) const scale = checker.GetLocalitySearchScale(); LOG(LDEBUG, ("Locality scale = ", scale)); - DoGetAddressInfo getLocality(pt, localityR, scale, checker); - getLocality.PrepareForLocalities(); + m2::RectD const rect = MercatorBounds::RectByCenterXYAndSizeInMeters(pt, localityR); + DoGetLocality getLocality(pt, scale, checker, rect); - m_model.ForEachFeature( - MercatorBounds::RectByCenterXYAndSizeInMeters(pt, localityR), getLocality, scale); + m_model.ForEachFeature(rect, getLocality, scale); getLocality.FillLocality(info, *this); } |