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

traffic_info.hpp « traffic - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 0dd75cb946328315461a94f2ef7b431a7fe7eb75 (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
170
171
172
173
#pragma once

#include "traffic/speed_groups.hpp"

#include "indexer/mwm_set.hpp"

#include "std/cstdint.hpp"
#include "std/map.hpp"
#include "std/shared_ptr.hpp"
#include "std/vector.hpp"

namespace platform
{
class HttpClient;
}

namespace traffic
{
// This class is responsible for providing the real-time
// information about road traffic for one mwm file.

class TrafficInfo
{
public:
  static uint8_t const kLatestKeysVersion;
  static uint8_t const kLatestValuesVersion;

  enum class Availability
  {
    IsAvailable,
    NoData,
    ExpiredData,
    ExpiredApp,
    Unknown
  };

  struct RoadSegmentId
  {
    // m_dir can be kForwardDirection or kReverseDirection.
    static uint8_t constexpr kForwardDirection = 0;
    static uint8_t constexpr kReverseDirection = 1;

    RoadSegmentId();

    RoadSegmentId(uint32_t fid, uint16_t idx, uint8_t dir);

    bool operator==(RoadSegmentId const & o) const
    {
      return m_fid == o.m_fid && m_idx == o.m_idx && m_dir == o.m_dir;
    }

    bool operator<(RoadSegmentId const & o) const
    {
      if (m_fid != o.m_fid)
        return m_fid < o.m_fid;
      if (m_idx != o.m_idx)
        return m_idx < o.m_idx;
      return m_dir < o.m_dir;
    }

    uint32_t GetFid() const { return m_fid; }
    uint16_t GetIdx() const { return m_idx; }
    uint8_t GetDir() const { return m_dir; }

    // The ordinal number of feature this segment belongs to.
    uint32_t m_fid;

    // The ordinal number of this segment in the list of
    // its feature's segments.
    uint16_t m_idx : 15;

    // The direction of the segment.
    uint8_t m_dir : 1;
  };

  // todo(@m) unordered_map?
  using Coloring = map<RoadSegmentId, SpeedGroup>;

  TrafficInfo() = default;

  TrafficInfo(MwmSet::MwmId const & mwmId, int64_t currentDataVersion);

  static TrafficInfo BuildForTesting(Coloring && coloring);
  void SetTrafficKeysForTesting(vector<RoadSegmentId> const & keys);

  // Fetches the latest traffic data from the server and updates the coloring and ETag.
  // Construct the url by passing an MwmId.
  // The ETag or entity tag is part of HTTP, the protocol for the World Wide Web.
  // It is one of several mechanisms that HTTP provides for web cache validation,
  // which allows a client to make conditional requests.
  // *NOTE* This method must not be called on the UI thread.
  bool ReceiveTrafficData(string & etag);

  // Returns the latest known speed group by a feature segment's id
  // or SpeedGroup::Unknown if there is no information about the segment.
  SpeedGroup GetSpeedGroup(RoadSegmentId const & id) const;

  MwmSet::MwmId const & GetMwmId() const { return m_mwmId; }
  Coloring const & GetColoring() const { return m_coloring; }
  Availability GetAvailability() const { return m_availability; }

  // Extracts RoadSegmentIds from mwm and stores them in a sorted order.
  static void ExtractTrafficKeys(string const & mwmPath, vector<RoadSegmentId> & result);

  // Adds the unknown values to the partially known coloring map |knownColors|
  // so that the keys of the resulting map are exactly |keys|.
  static void CombineColorings(vector<TrafficInfo::RoadSegmentId> const & keys,
                               TrafficInfo::Coloring const & knownColors,
                               TrafficInfo::Coloring & result);

  // Serializes the keys of the coloring map to |result|.
  // The keys are road segments ids which do not change during
  // an mwm's lifetime so there's no point in downloading them every time.
  // todo(@m) Document the format.
  static void SerializeTrafficKeys(vector<RoadSegmentId> const & keys, vector<uint8_t> & result);

  static void DeserializeTrafficKeys(vector<uint8_t> const & data, vector<RoadSegmentId> & result);

  static void SerializeTrafficValues(vector<SpeedGroup> const & values, vector<uint8_t> & result);

  static void DeserializeTrafficValues(vector<uint8_t> const & data, vector<SpeedGroup> & result);

private:
  enum class ServerDataStatus
  {
    New,
    NotChanged,
    NotFound,
    Error,
  };

  friend void UnitTest_TrafficInfo_UpdateTrafficData();

  // todo(@m) A temporary method. Remove it once the keys are added
  // to the generator and the data is regenerated.
  bool ReceiveTrafficKeys();

  // Tries to read the values of the Coloring map from server into |values|.
  // Returns result of communicating with server as ServerDataStatus.
  // Otherwise, returns false and does not change m_coloring.
  ServerDataStatus ReceiveTrafficValues(string & etag, vector<SpeedGroup> & values);

  // Updates the coloring and changes the availability status if needed.
  bool UpdateTrafficData(vector<SpeedGroup> const & values);

  ServerDataStatus ProcessFailure(platform::HttpClient const & request, uint64_t const mwmVersion);

  // The mapping from feature segments to speed groups (see speed_groups.hpp).
  Coloring m_coloring;

  // The keys of the coloring map. The values are downloaded periodically
  // and combined with the keys to form m_coloring.
  // *NOTE* The values must be received in the exact same order that the
  // keys are saved in.
  vector<RoadSegmentId> m_keys;

  MwmSet::MwmId m_mwmId;
  Availability m_availability = Availability::Unknown;
  int64_t m_currentDataVersion = 0;
};

class TrafficObserver
{
public:
  virtual ~TrafficObserver() = default;

  virtual void OnTrafficInfoClear() = 0;
  virtual void OnTrafficInfoAdded(traffic::TrafficInfo && info) = 0;
  virtual void OnTrafficInfoRemoved(MwmSet::MwmId const & mwmId) = 0;
};

string DebugPrint(TrafficInfo::RoadSegmentId const & id);
}  // namespace traffic