aboutsummaryrefslogtreecommitdiffstats
path: root/src/querykv1/journeyroute.cpp
blob: 013ea1c8b25c4900edd08ca346ac6261db93b752 (plain) (blame)
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
// vim:set sw=2 ts=2 sts et:

#include <iostream>
#include <string_view>

#include "journeyroute.hpp"

using namespace std::string_view_literals;

void journeyRoute(const Options &options, Kv1Records &records, Kv1Index &index) {
  FILE *out = stdout;
  if (options.output_file_path != "-"sv)
    out = fopen(options.output_file_path, "wb");
  if (!out) {
    fprintf(stderr, "Open %s: %s\n", options.output_file_path, strerrordesc_np(errno));
    exit(EXIT_FAILURE);
  }

  for (auto &pujo : records.public_journeys) {
    if (pujo.key.line_planning_number == options.line_planning_number && std::to_string(pujo.key.journey_number) == options.journey_number) {
      fprintf(stderr, "Got PUJO %s/%s:\n", options.line_planning_number, options.journey_number);
      fprintf(stderr, "  Day type: %s\n", pujo.key.day_type.c_str());
      auto &pegr = *pujo.p_period_group;
      fprintf(stderr, "  PEGR Code: %s\n", pegr.key.period_group_code.c_str());
      fprintf(stderr, "  PEGR Description: %s\n", pegr.description.c_str());
      fprintf(stderr, "  SPECDAY Code: %s\n", pujo.key.specific_day_code.c_str());
      auto &timdemgrp = *pujo.p_time_demand_group;

      for (auto &pegrval : records.period_group_validities) {
        if (pegrval.key.period_group_code == pegr.key.period_group_code) {
          fprintf(stderr, "Got PEGRVAL for PEGR %s\n", pegr.key.period_group_code.c_str());
          std::cerr << "  Valid from: " << pegrval.key.valid_from << std::endl;
          std::cerr << "  Valid thru: " << pegrval.valid_thru << std::endl;
        }
      }

      struct Point {
        Kv1JourneyPatternTimingLink *jopatili = nullptr;
        Kv1TimeDemandGroupRunTime *timdemrnt = nullptr;
        double distance_since_start_of_link = 0;
        double rd_x = 0;
        double rd_y = 0;
        double total_time_s = 0;
      };
      std::vector<Point> points;

      for (size_t i = 0; i < records.time_demand_group_run_times.size(); i++) {
        Kv1TimeDemandGroupRunTime *timdemrnt = &records.time_demand_group_run_times[i];
        if (timdemrnt->key.line_planning_number   == timdemgrp.key.line_planning_number
         && timdemrnt->key.journey_pattern_code   == timdemgrp.key.journey_pattern_code
         && timdemrnt->key.time_demand_group_code == timdemgrp.key.time_demand_group_code) {
          Kv1JourneyPatternTimingLink *jopatili = timdemrnt->p_journey_pattern_timing_link;
          for (auto &pool : records.point_on_links) {
            if (pool.key.user_stop_code_begin == timdemrnt->user_stop_code_begin
             && pool.key.user_stop_code_end   == timdemrnt->user_stop_code_end
             && pool.key.transport_type       == jopatili->p_line->transport_type) {
              points.emplace_back(
                jopatili,
                timdemrnt,
                pool.distance_since_start_of_link,
                pool.p_point->location_x_ew,
                pool.p_point->location_y_ns
              );
            }
          }
        }
      }

      std::sort(points.begin(), points.end(), [](Point &a, Point &b) {
        if (a.jopatili->key.timing_link_order != b.jopatili->key.timing_link_order)
          return a.jopatili->key.timing_link_order < b.jopatili->key.timing_link_order;
        return a.distance_since_start_of_link < b.distance_since_start_of_link;
      });

      double total_time_s = 0;
      for (size_t i = 0; i < points.size(); i++) {
        Point *p = &points[i];
        p->total_time_s = total_time_s;
        if (i > 0) {
          Point *prev = &points[i - 1];
          if (p->timdemrnt != prev->timdemrnt) {
            total_time_s += prev->timdemrnt->total_drive_time_s;
            prev->total_time_s = total_time_s;
          }
        }
      }

      fputs("rd_x,rd_y,total_time_s,is_timing_stop\n", out);
      for (const auto &point : points) {
        fprintf(out, "%f,%f,%f,%d\n", point.rd_x, point.rd_y, point.total_time_s, point.jopatili->is_timing_stop);
      }
    }
  }

  if (options.output_file_path != "-"sv) fclose(out);
}