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

house_detector.hpp « search - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: f7d47194c6b266db59ce75d3383a187de6147c8d (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#pragma once

#include "../indexer/feature_decl.hpp"
#include "../indexer/index.hpp"

#include "../geometry/point2d.hpp"

#include "../std/string.hpp"
#include "../std/queue.hpp"


namespace search
{
class FeatureLoader
{
  Index const * m_pIndex;
  Index::FeaturesLoaderGuard * m_pGuard;

  void CreateLoader(size_t mwmID);

public:
  FeatureLoader(Index const * pIndex);
  ~FeatureLoader();

  void Load(FeatureID const & id, FeatureType & f);
  void Free();

  template <class ToDo> void ForEachInRect(m2::RectD const & rect, ToDo toDo);
};

class House
{
  string m_number;
  m2::PointD m_point;
  int m_intNumber;
  string m_suffix;

  void InitHouseNumberAndSuffix();

public:
  House(string const & number, m2::PointD const & point)
    : m_number(number), m_point(point), m_intNumber(-1)
  {
    InitHouseNumberAndSuffix();
  }

  inline string const & GetNumber() const { return m_number; }
  inline int GetIntNumber() const { return m_intNumber; }
  inline m2::PointD const & GetPosition() const { return m_point; }

  struct LessHouseNumber
  {
    bool operator() (House const * h1, House const * h2) const
    {
      if (h1->m_intNumber == h2->m_intNumber)
        return h1->m_suffix < h2->m_suffix;
      return h1->m_intNumber < h2->m_intNumber;
    }
  };
};

struct HouseProjection
{
  House const * m_house;
  m2::PointD m_proj;
  double m_distance;
  /// Distance in mercator, from street beginning to projection on street
  double m_streetDistance;
  /// false - to the left, true - to the right from projection segment
  bool m_projectionSign;

  inline static bool LessDistance(HouseProjection const & r1, HouseProjection const & r2)
  {
    return r1.m_distance < r2.m_distance;
  }
};

// many features combines to street
class Street
{
  string m_name;
  string m_processedName;

public:
  void SetName(string const & name);
  string const & GetName() const { return m_name; }

  vector<m2::PointD> m_points;
  vector<HouseProjection> m_houses;
  bool m_housesReaded;
  int m_number;

  Street() : m_housesReaded(false), m_number(-1) {}

  void SortHousesProjection();

  /// Get limit rect for street with ortho offset to the left and right.
  m2::RectD GetLimitRect(double offsetMeters) const;

  inline static bool IsSameStreets(Street const * s1, Street const * s2)
  {
    return s1->m_processedName == s2->m_processedName;
  }

  inline static string GetDbgName(vector<Street *> const & streets)
  {
    return streets.front()->m_processedName;
  }
};

class HouseDetector
{
  FeatureLoader m_loader;

  map<FeatureID, Street *> m_id2st;
  map<FeatureID, House *> m_id2house;

public:
  class LessWithEpsilon
  {
    double * m_eps;
  public:
    LessWithEpsilon(double * eps) : m_eps(eps) {}
    bool operator() (m2::PointD const & p1, m2::PointD const & p2) const
    {
      if (p1.x + *m_eps < p2.x)
        return true;
      else if (p2.x + *m_eps < p1.x)
        return false;
      else
        return (p1.y + *m_eps < p2.y);
    }
  };

private:
  double m_epsMercator;
  typedef multimap<m2::PointD, Street *, LessWithEpsilon>::iterator IterT;
  multimap<m2::PointD, Street *, LessWithEpsilon> m_end2st;
  vector<vector<Street *> > m_streets;

  int m_streetNum;

  void FillQueue(queue<Street *> & q, Street const * street, bool isBeg);
  void Bfs(Street * st);

  template <class ProjectionCalcT>
  void ReadHouse(FeatureType const & f, Street * st, ProjectionCalcT & calc);

  void SetMetres2Mercator(double factor);

public:
  typedef map<FeatureID, Street *>::iterator IterM;

  HouseDetector(Index const * pIndex);

  int LoadStreets(vector<FeatureID> & ids);
  /// @return number of different joined streets.
  int MergeStreets();

  void ReadHouses(Street * st, double offsetMeters);
  void ReadAllHouses(double offsetMeters);

  void MatchAllHouses(string const & houseNumber, vector<HouseProjection> & res);
  void GetHouseForName(string const & houseNumber, vector<House const *> & res);

  void ClearCaches();
};

}