Welcome to mirror list, hosted at ThFree Co, Russian Federation.

reverse_geocoder.hpp « search - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: fe71871946cc05a088a5c65db9c94bce9b60b6eb (plain)
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
#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 DataSourceBase;

namespace search
{

class ReverseGeocoder
{
  DataSourceBase 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(DataSourceBase 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.
  //@{
  void GetNearbyStreets(MwmSet::MwmId const & id, m2::PointD const & center,
                        vector<Street> & streets) const;
  void GetNearbyStreets(FeatureType & ft, 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;

  /// @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 const & ft, Address & addr) const;

private:

  /// Helper class to incapsulate house 2 street table reloading.
  class HouseTable
  {
    DataSourceBase const & m_dataSource;
    unique_ptr<search::HouseToStreetTable> m_table;
    MwmSet::MwmHandle m_handle;
  public:
    explicit HouseTable(DataSourceBase 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 const & ft, double distMeters);
  static m2::RectD GetLookupRect(m2::PointD const & center, double radiusM);
};

} // namespace search