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

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

#include "kml/serdes.hpp"
#include "kml/type_utils.hpp"
#include "kml/types.hpp"

#include "routing/base/followed_polyline.hpp"
#include "routing/route.hpp"
#include "routing/routing_callbacks.hpp"
#include "routing/routing_quality/utils.hpp"

#include "coding/file_name_utils.hpp"
#include "coding/file_reader.hpp"
#include "coding/file_writer.hpp"

#include "platform/platform.hpp"

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

#include <cstdint>
#include <utility>
#include <vector>

using namespace std;

namespace
{
vector<m2::PointD> GetTrackPoints(routing::Route && route)
{
  CHECK(route.IsValid(), ());
  auto const & segments = route.GetRouteSegments();
  auto const size = segments.size();
  vector<m2::PointD> result;
  result.reserve(size);

  for (size_t i = 0; i < size;)
  {
    size_t j = i + 1;
    size_t consecutiveNumber = 1;
    /// Check number of consecutive junctions with the same point.
    while (j < size && segments[j].GetJunction().GetPoint() == segments[i].GetJunction().GetPoint())
    {
      ++j;
      ++consecutiveNumber;
    }

    ///             S3  S4
    ///             ⥀  ⥀
    ///             *   |
    ///             ⋀   S5
    ///             |   |
    ///             S2  ⋁
    ///             |   *
    /// —— S1 ——> *      —— S6 ——> *

    /// If there is 3 or more consecutive point than it's an intermediate point
    /// which is the start and the end of the subroute simultaneously.
    if (consecutiveNumber >= 3)
    {
      /// —— S1 ——> *
      ///           |
      ///           S2
      ///           |
      ///           ⋁
      ///           *

      /// Check if there are two perpendicular fake segments and get rid from both of them.
      if (!result.empty() && result.back() == segments[j].GetJunction().GetPoint())
      {
        result.pop_back();
        ++j;
      }
    }
    else
    {
      result.emplace_back(segments[i].GetJunction().GetPoint());
    }

    i = j;
  }

  return result;
}
}  // namespace

namespace track_generator_tool
{
void GenerateTracks(string const & inputDir, string const & outputDir, routing::VehicleType type)
{
  CHECK(!inputDir.empty(), ());
  CHECK(!outputDir.empty(), ());
  CHECK_LESS(type, routing::VehicleType::Count, ());

  Platform::FilesList files;
  Platform::GetFilesByExt(inputDir, ".kml", files);
  CHECK(!files.empty(), ("Input directory doesn't contain kmls."));

  for (auto const & file : files)
  {
    LOG(LINFO, ("Start generating tracks for file", file));
    kml::FileData data;
    try
    {
      kml::DeserializerKml des(data);
      FileReader r(base::JoinPath(inputDir, file));
      des.Deserialize(r);
    }
    catch (FileReader::Exception const & ex)
    {
      CHECK(false, ("Can't convert file", file, "\nException:", ex.what()));
    }
    catch (kml::DeserializerKml::DeserializeException const & ex)
    {
      CHECK(false, ("Can't deserialize file", file, "\nException:", ex.what()));
    }

    CHECK(!data.m_tracksData.empty(), ("No tracks in file", file));
    for (auto & track : data.m_tracksData)
    {
      auto waypoints = track.m_points;
      auto result = routing_quality::GetRoute(move(waypoints), type);
      if (result.m_code != routing::RouterResultCode::NoError)
      {
        LOG(LINFO, ("Can't convert track", track.m_id, "from file", file));
        continue;
      }

      track.m_points = GetTrackPoints(move(result.m_route));
    }

    try
    {
      kml::SerializerKml ser(data);
      FileWriter sink(base::JoinPath(outputDir, file));
      ser.Serialize(sink);
    }
    catch (FileWriter::Exception const & ex)
    {
      CHECK(false, ("Can't save file", file, "\nException:", ex.what()));
    }
    catch (kml::SerializerKml::SerializeException const & ex)
    {
      CHECK(false, ("Can't serialize file", file, "\nException:", ex.what()));
    }

    LOG(LINFO, ("Finished generating tracks for file", file));
  }
}
}  // namespace track_generator_tool