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

restriction_writer.cpp « generator - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1c7f119dccbf71130c42aa5e19e4888380e9c1ea (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
#include "generator/restriction_writer.hpp"

#include "generator/intermediate_elements.hpp"
#include "generator/restriction_collector.hpp"

#include "routing/restrictions_serialization.hpp"

#include "base/geo_object_id.hpp"
#include "base/logging.hpp"

#include <algorithm>
#include <fstream>
#include <string>
#include <utility>
#include <vector>

namespace
{
using namespace routing;

std::vector<std::pair<std::string, Restriction::Type>> const kRestrictionTypes =
  {{"no_right_turn", Restriction::Type::No},  {"no_left_turn", Restriction::Type::No},
   {"no_u_turn", Restriction::Type::No}, {"no_straight_on", Restriction::Type::No},
   {"no_entry", Restriction::Type::No}, {"no_exit", Restriction::Type::No},
   {"only_right_turn", Restriction::Type::Only}, {"only_left_turn", Restriction::Type::Only},
   {"only_straight_on", Restriction::Type::Only}};

/// \brief Converts restriction type form string to RestrictionCollector::Type.
/// \returns true if conversion was successful and false otherwise.
bool TagToType(std::string const & tag, Restriction::Type & type)
{
  auto const it = std::find_if(kRestrictionTypes.cbegin(), kRestrictionTypes.cend(),
                          [&tag](std::pair<std::string, Restriction::Type> const & v) {
    return v.first == tag;
  });
  if (it == kRestrictionTypes.cend())
    return false; // Unsupported restriction type.

  type = it->second;
  return true;
}
}  // namespace

namespace routing
{
RestrictionWriter::RestrictionWriter(std::string const & fullPath)
{
  Open(fullPath);
}

void RestrictionWriter::Open(std::string const & fullPath)
{
  LOG(LINFO, ("Saving road restrictions in osm id terms to", fullPath));
  m_stream.open(fullPath, std::ofstream::out);

  if (!IsOpened())
    LOG(LINFO, ("Cannot open file", fullPath));
}

void RestrictionWriter::CollectRelation(RelationElement const & relationElement)
{
  if (!IsOpened())
  {
    LOG(LWARNING, ("Tried to write to a closed restrictions writer"));
    return;
  }

  if (relationElement.GetType() != "restriction")
    return;

  // Note. For the time being only line-point-line road restriction is supported.
  if (relationElement.nodes.size() != 1 || relationElement.ways.size() != 2)
    return;  // Unsupported restriction. For example line-line-line.

  // Extracting osm ids of lines and points of the restriction.
  auto const findTag = [](std::vector<std::pair<uint64_t, std::string>> const & members,
                          std::string const & tag) {
    auto const it = std::find_if(
        members.cbegin(), members.cend(),
        [&tag](std::pair<uint64_t, std::string> const & p) { return p.second == tag; });
    return it;
  };

  auto const fromIt = findTag(relationElement.ways, "from");
  if (fromIt == relationElement.ways.cend())
    return;

  auto const toIt = findTag(relationElement.ways, "to");
  if (toIt == relationElement.ways.cend())
    return;

  if (findTag(relationElement.nodes, "via") == relationElement.nodes.cend())
    return;

  // Extracting type of restriction.
  auto const tagIt = relationElement.tags.find("restriction");
  if (tagIt == relationElement.tags.end())
    return;

  Restriction::Type type = Restriction::Type::No;
  if (!TagToType(tagIt->second, type))
    return;

  // Adding restriction.
  m_stream << ToString(type) << "," << fromIt->first << ", " << toIt->first << '\n';
}

bool RestrictionWriter::IsOpened() const { return m_stream && m_stream.is_open(); }
}  // namespace routing