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

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

#include "routing/maxspeeds_serialization.hpp"

#include "indexer/data_source.hpp"

#include "platform/measurement_utils.hpp"

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

#include "defines.hpp"

#include <algorithm>

namespace routing
{
bool Maxspeeds::IsEmpty() const
{
  return m_forwardMaxspeedsTable.size() == 0 && m_bidirectionalMaxspeeds.empty();
}

Maxspeed Maxspeeds::GetMaxspeed(uint32_t fid) const
{
  if (IsEmpty())
    return Maxspeed();

  // Forward only maxspeeds.
  if (HasForwardMaxspeed(fid))
  {
    auto const r = m_forwardMaxspeedsTable.rank(fid);
    CHECK_LESS(r, m_forwardMaxspeeds.Size(), ());
    uint8_t const forwardMaxspeedMacro = m_forwardMaxspeeds.Get(r);
    CHECK(GetMaxspeedConverter().IsValidMacro(forwardMaxspeedMacro), ());
    auto const forwardMaxspeed =
        GetMaxspeedConverter().MacroToSpeed(static_cast<SpeedMacro>(forwardMaxspeedMacro));
    return {forwardMaxspeed.GetUnits(), forwardMaxspeed.GetSpeed(), kInvalidSpeed};
  }

  // Bidirectional maxspeeds.
  auto const range = std::equal_range(
      m_bidirectionalMaxspeeds.cbegin(), m_bidirectionalMaxspeeds.cend(),
      FeatureMaxspeed(fid, measurement_utils::Units::Metric, kInvalidSpeed, kInvalidSpeed),
      IsFeatureIdLess);

  if (range.second == range.first)
    return Maxspeed(); // No maxspeed for |fid| is set. Returns an invalid Maxspeed instance.

  CHECK_EQUAL(range.second - range.first, 1, ());
  return range.first->GetMaxspeed();
}

bool Maxspeeds::HasForwardMaxspeed(uint32_t fid) const
{
  return fid < m_forwardMaxspeedsTable.size() ? m_forwardMaxspeedsTable[fid] : false;
}

bool Maxspeeds::HasBidirectionalMaxspeed(uint32_t fid) const
{
  return std::binary_search(
      m_bidirectionalMaxspeeds.cbegin(), m_bidirectionalMaxspeeds.cend(),
      FeatureMaxspeed(fid, measurement_utils::Units::Metric, kInvalidSpeed, kInvalidSpeed),
      IsFeatureIdLess);
}

void LoadMaxspeeds(FilesContainerR::TReader const & reader, Maxspeeds & maxspeeds)
{
  ReaderSource<FilesContainerR::TReader> src(reader);
  MaxspeedsSerializer::Deserialize(src, maxspeeds);
}

std::unique_ptr<Maxspeeds> LoadMaxspeeds(DataSource const & dataSource,
                                         MwmSet::MwmHandle const & handle)
{
  auto maxspeeds = std::make_unique<Maxspeeds>();
  auto const value = handle.GetValue<MwmValue>();
  CHECK(value, ());
  auto const & mwmValue = *value;
  if (!mwmValue.m_cont.IsExist(MAXSPEEDS_FILE_TAG))
    return maxspeeds;

  try
  {
    LoadMaxspeeds(mwmValue.m_cont.GetReader(MAXSPEEDS_FILE_TAG), *maxspeeds);
  }
  catch (Reader::OpenException const & e)
  {
    LOG(LERROR, ("File", mwmValue.GetCountryFileName(), "Error while reading", MAXSPEEDS_FILE_TAG,
        "section.", e.Msg()));
    return std::make_unique<Maxspeeds>();
  }

  return maxspeeds;
}
}  // namespace routing