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

borders.hpp « indexer - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: bc6f02ffa49fbf894530c4a26ad646366bdc4321 (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
#pragma once

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

#include <cstdint>
#include <map>
#include <string>
#include <utility>
#include <vector>

namespace indexer
{
// Stores region borders for countries, states, cities, city districts in reverse geocoder.
// Used to check exact object region after getting regions short list from regions geo index.
// Each region may have several outer borders. It may be islands or separated parts like
// Kaliningrad region which is part of Russia or Alaska which is part of US.
// Each outer border may have several inner borders e.g. Vatican and San Marino are
// located inside Italy but are not parts of it.
class Borders
{
public:
  bool IsPointInside(uint64_t id, m2::PointD const & point) const
  {
    auto const range = m_borders.equal_range(id);

    for (auto it = range.first; it != range.second; ++it)
    {
      if (it->second.IsPointInside(point))
        return true;
    }
    return false;
  }

  // Throws Reader::Exception in case of data reading errors.
  void Deserialize(std::string const & filename);

  template <typename BordersVec>
  void DeserializeFromVec(BordersVec const & vec)
  {
    vec.ForEach([this](uint64_t id, std::vector<m2::PointD> const & outer,
                       std::vector<std::vector<m2::PointD>> const & inners) {
      auto it = m_borders.insert(std::make_pair(id, Border()));
      it->second.m_outer = m2::RegionD(outer);
      for (auto const & inner : inners)
        it->second.m_inners.push_back(m2::RegionD(inner));
    });
  }

private:
  struct Border
  {
    Border() = default;

    bool IsPointInside(m2::PointD const & point) const;

    m2::RegionD m_outer;
    std::vector<m2::RegionD> m_inners;
  };

  std::multimap<uint64_t, Border> m_borders;
};
}  // namespace indexer