1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
#pragma once
#include "search/house_to_street_table.hpp"
#include "indexer/feature_decl.hpp"
#include "base/string_utils.hpp"
#include "std/string.hpp"
#include "std/utility.hpp"
#include "std/vector.hpp"
class FeatureType;
class DataSource;
namespace search
{
class MwmContext;
class ReverseGeocoder
{
DataSource const & m_dataSource;
struct Object
{
FeatureID m_id;
double m_distanceMeters;
string m_name;
Object() : m_distanceMeters(-1.0) {}
Object(FeatureID const & id, double dist, string const & name)
: m_id(id), m_distanceMeters(dist), m_name(name)
{
}
inline bool IsValid() const { return m_id.IsValid(); }
};
friend string DebugPrint(Object const & obj);
public:
/// All "Nearby" functions work in this lookup radius.
static int constexpr kLookupRadiusM = 500;
explicit ReverseGeocoder(DataSource const & dataSource);
using Street = Object;
struct Building : public Object
{
m2::PointD m_center;
// To investigate possible errors.
// There are no houses in (0, 0) coordinates.
Building() : m_center(0, 0) {}
Building(FeatureID const & id, double dist, string const & number, m2::PointD const & center)
: Object(id, dist, number), m_center(center)
{
}
};
static size_t GetMatchedStreetIndex(strings::UniString const & keyName,
vector<Street> const & streets);
struct Address
{
Building m_building;
Street m_street;
string const & GetHouseNumber() const { return m_building.m_name; }
string const & GetStreetName() const { return m_street.m_name; }
double GetDistance() const { return m_building.m_distanceMeters; }
};
friend string DebugPrint(Address const & addr);
/// @return Sorted by distance streets vector for the specified MwmId.
static void GetNearbyStreets(search::MwmContext & context, m2::PointD const & center,
vector<Street> & streets);
void GetNearbyStreets(MwmSet::MwmId const & id, m2::PointD const & center,
vector<Street> & streets) const;
void GetNearbyStreets(FeatureType & ft, vector<Street> & streets) const;
void GetNearbyOriginalStreets(MwmSet::MwmId const & id, m2::PointD const & center,
vector<Street> & streets) const;
/// @returns [a lot of] nearby feature's streets and an index of a feature's street.
/// Returns a value greater than vector size when there are no Street the feature belongs to.
/// @note returned vector can contain duplicated street segments.
pair<vector<Street>, uint32_t> GetNearbyFeatureStreets(FeatureType & ft) const;
/// Same as GetNearbyFeatureStreets but returns streets from MWM only.
pair<vector<Street>, uint32_t> GetNearbyOriginalFeatureStreets(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;
/// @param addr (out) the exact address of a feature.
/// @returns false if can't extruct address or ft have no house number.
bool GetExactAddress(FeatureType & ft, Address & addr) const;
private:
/// Helper class to incapsulate house 2 street table reloading.
class HouseTable
{
DataSource const & m_dataSource;
unique_ptr<search::HouseToStreetTable> m_table;
MwmSet::MwmHandle m_handle;
public:
explicit HouseTable(DataSource const & dataSource) : m_dataSource(dataSource) {}
bool Get(FeatureID const & fid, uint32_t & streetIndex);
};
bool GetNearbyAddress(HouseTable & table, Building const & bld, Address & addr) const;
/// @return Sorted by distance houses vector with valid house number.
void GetNearbyBuildings(m2::PointD const & center, vector<Building> & buildings) const;
static Building FromFeature(FeatureType & ft, double distMeters);
};
} // namespace search
|