shushus

Спринт 13. Итоговый проект.

May 2nd, 2023
1,348
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 103.43 KB | None | 0 0
  1. -----------------------------------------------------------------------
  2. graph.h
  3. -----------------------------------------------------------------------
  4. #pragma once
  5.  
  6. #include "ranges.h"
  7.  
  8. #include <cstdlib>
  9. #include <vector>
  10.  
  11. namespace graph {
  12.  
  13. using VertexId = size_t;
  14. using EdgeId = size_t;
  15.  
  16. template <typename Weight>
  17. struct Edge {
  18.     VertexId from;
  19.     VertexId to;
  20.     Weight weight;
  21. };
  22.  
  23. template <typename Weight>
  24. class DirectedWeightedGraph {
  25. private:
  26.     using IncidenceList = std::vector<EdgeId>;
  27.     using IncidentEdgesRange = ranges::Range<typename IncidenceList::const_iterator>;
  28.  
  29. public:
  30.     DirectedWeightedGraph() = default;
  31.     explicit DirectedWeightedGraph(size_t vertex_count);
  32.     EdgeId add_edge(const Edge<Weight>& edge);
  33.  
  34.     size_t get_vertex_count() const;
  35.     size_t get_edge_count() const;
  36.     const Edge<Weight>& get_edge(EdgeId edge_id) const;
  37.     IncidentEdgesRange get_incident_edges(VertexId vertex) const;
  38.  
  39. private:
  40.     std::vector<Edge<Weight>> edges_;
  41.     std::vector<IncidenceList> incidence_lists_;
  42. };
  43.  
  44. template <typename Weight>
  45. DirectedWeightedGraph<Weight>::DirectedWeightedGraph(size_t vertex_count) : incidence_lists_(vertex_count) {}
  46.  
  47. template <typename Weight>
  48. EdgeId DirectedWeightedGraph<Weight>::add_edge(const Edge<Weight>& edge) {
  49.     edges_.push_back(edge);
  50.    
  51.     const EdgeId id = edges_.size() - 1;
  52.    
  53.     incidence_lists_.at(edge.from).push_back(id);
  54.    
  55.     return id;
  56. }
  57.  
  58. template <typename Weight>
  59. size_t DirectedWeightedGraph<Weight>::get_vertex_count() const {return incidence_lists_.size();}
  60.  
  61. template <typename Weight>
  62. size_t DirectedWeightedGraph<Weight>::get_edge_count() const {return edges_.size();}
  63.  
  64. template <typename Weight>
  65. const Edge<Weight>& DirectedWeightedGraph<Weight>::get_edge(EdgeId edge_id) const {return edges_.at(edge_id);}
  66.  
  67. template <typename Weight>
  68. typename DirectedWeightedGraph<Weight>::IncidentEdgesRange DirectedWeightedGraph<Weight>::get_incident_edges(VertexId vertex) const {
  69.     return ranges::as_range(incidence_lists_.at(vertex));
  70. }
  71.  
  72. }//end namespace graph
  73. -----------------------------------------------------------------------
  74. ranges.h
  75. -----------------------------------------------------------------------
  76. #pragma once
  77.  
  78. #include <iterator>
  79. #include <string_view>
  80. #include <unordered_map>
  81. #include <unordered_set>
  82.  
  83. namespace ranges {
  84.  
  85. template <typename It>
  86. class Range {
  87. public:
  88.     using ValueType = typename std::iterator_traits<It>::value_type;
  89.  
  90.     Range(It begin, It end) : begin_(begin)
  91.                             , end_(end) {}
  92.                            
  93.     It begin() const {return begin_;}
  94.     It end() const {return end_;}
  95.  
  96. private:
  97.     It begin_;
  98.     It end_;
  99. };
  100.  
  101. template <typename C>
  102. auto as_range(const C& container) {return Range{container.begin(), container.end()};}
  103.  
  104. }//end namespace ranges
  105. -----------------------------------------------------------------------
  106. router.h
  107. -----------------------------------------------------------------------
  108. #pragma once
  109.  
  110. #include "graph.h"
  111.  
  112. #include <algorithm>
  113. #include <cassert>
  114. #include <cstdint>
  115. #include <iterator>
  116. #include <optional>
  117. #include <stdexcept>
  118. #include <unordered_map>
  119. #include <utility>
  120. #include <vector>
  121.  
  122. namespace graph {
  123.  
  124. template <typename Weight>
  125. class Router {
  126. using Graph = DirectedWeightedGraph<Weight>;
  127.  
  128. public:
  129.     explicit Router(const Graph& graph);
  130.  
  131.     struct RouteInfo {
  132.         Weight weight;
  133.         std::vector<EdgeId> edges;
  134.     };
  135.    
  136.     void build() {
  137.         initialize_routes_internal_data(graph_);
  138.         const size_t vertex_count = graph_.get_vertex_count();
  139.        
  140.         for (VertexId vertex_through = 0; vertex_through < vertex_count; ++vertex_through) {
  141.             relax_routes_internal_data_through_vertex(vertex_count, vertex_through);
  142.         }
  143.     }
  144.    
  145.     std::optional<RouteInfo> build_route(VertexId from, VertexId to) const;
  146.  
  147. private:
  148.     struct RouteInternalData {
  149.         Weight weight;
  150.         std::optional<EdgeId> prev_edge;
  151.     };
  152.    
  153.     using RoutesInternalData = std::vector<std::vector<std::optional<RouteInternalData>>>;
  154.  
  155.     void initialize_routes_internal_data(const Graph& graph) {
  156.         const size_t vertex_count = graph.get_vertex_count();
  157.        
  158.         for (VertexId vertex = 0; vertex < vertex_count; ++vertex) {
  159.             routes_internal_data_[vertex][vertex] = RouteInternalData{ZERO_WEIGHT, std::nullopt};
  160.            
  161.             for (const EdgeId edge_id : graph.get_incident_edges(vertex)) {
  162.                 const auto& edge = graph.get_edge(edge_id);
  163.                
  164.                 if (edge.weight < ZERO_WEIGHT) {
  165.                     throw std::domain_error("Edges' weights should be non-negative");
  166.                 }
  167.                
  168.                 auto& route_internal_data = routes_internal_data_[vertex][edge.to];
  169.                 if (!route_internal_data || route_internal_data->weight > edge.weight) {
  170.                     route_internal_data = RouteInternalData{edge.weight, edge_id};
  171.                 }
  172.             }
  173.         }
  174.     }
  175.  
  176.     void relax_route(VertexId vertex_from, VertexId vertex_to,
  177.                      const RouteInternalData& route_from,
  178.                      const RouteInternalData& route_to) {
  179.                      
  180.         auto& route_relaxing = routes_internal_data_[vertex_from][vertex_to];
  181.         const Weight candidate_weight = route_from.weight + route_to.weight;
  182.        
  183.         if (!route_relaxing || candidate_weight < route_relaxing->weight) {
  184.             route_relaxing = {candidate_weight,
  185.                               route_to.prev_edge ? route_to.prev_edge : route_from.prev_edge};
  186.         }
  187.     }
  188.  
  189.     void relax_routes_internal_data_through_vertex(size_t vertex_count, VertexId vertex_through) {
  190.    
  191.         for (VertexId vertex_from = 0; vertex_from < vertex_count; ++vertex_from) {
  192.        
  193.             if (const auto& route_from = routes_internal_data_[vertex_from][vertex_through]) {
  194.            
  195.                 for (VertexId vertex_to = 0; vertex_to < vertex_count; ++vertex_to) {
  196.                
  197.                     if (const auto& route_to = routes_internal_data_[vertex_through][vertex_to]) {
  198.                         relax_route(vertex_from, vertex_to, *route_from, *route_to);
  199.                     }
  200.                 }
  201.             }
  202.         }
  203.     }
  204.  
  205.     static constexpr Weight ZERO_WEIGHT{};
  206.     const Graph& graph_;
  207.     RoutesInternalData routes_internal_data_;
  208. };
  209.  
  210. template <typename Weight>
  211. Router<Weight>::Router(const Graph& graph) : graph_(graph)
  212.                                            , routes_internal_data_(graph.get_vertex_count()
  213.                                            , std::vector<std::optional<RouteInternalData>>(graph.get_vertex_count())) {
  214.     initialize_routes_internal_data(graph);
  215.  
  216.     const size_t vertex_count = graph.get_vertex_count();
  217.     for (VertexId vertex_through = 0; vertex_through < vertex_count; ++vertex_through) {
  218.         relax_routes_internal_data_through_vertex(vertex_count, vertex_through);
  219.     }
  220. }
  221.  
  222. template <typename Weight>
  223. std::optional<typename Router<Weight>::RouteInfo> Router<Weight>::build_route(VertexId from,
  224.                                                                               VertexId to) const {
  225.     const auto& route_internal_data = routes_internal_data_.at(from).at(to);
  226.    
  227.     if (!route_internal_data) {
  228.         return std::nullopt;
  229.     }
  230.    
  231.     const Weight weight = route_internal_data->weight;
  232.     std::vector<EdgeId> edges;
  233.     for (std::optional<EdgeId> edge_id = route_internal_data->prev_edge;
  234.          edge_id;
  235.          edge_id = routes_internal_data_[from][graph_.get_edge(*edge_id).from]->prev_edge) {
  236.        
  237.         edges.push_back(*edge_id);
  238.     }
  239.    
  240.     std::reverse(edges.begin(), edges.end());
  241.  
  242.     return RouteInfo{weight, std::move(edges)};
  243. }
  244.  
  245. }//end namespace graph
  246. -----------------------------------------------------------------------
  247. domain.cpp
  248. -----------------------------------------------------------------------
  249.  
  250. empty
  251.  
  252. -----------------------------------------------------------------------
  253. domain.h
  254. -----------------------------------------------------------------------
  255. #pragma once
  256.  
  257. #include <algorithm>
  258. #include <vector>
  259. #include <string>
  260. #include <variant>
  261.  
  262. #include "geo.h"
  263. #include "graph.h"
  264.  
  265. namespace domain {
  266.  
  267. struct StatRequest {
  268.     int id;
  269.     std::string type;
  270.     std::string name;    
  271.     std::string from;
  272.     std::string to;
  273. };
  274.    
  275. struct Bus;
  276.    
  277. struct Stop {    
  278.     std::string name;
  279.     double latitude;
  280.     double longitude;
  281.    
  282.     std::vector<Bus*> buses;
  283. };
  284.  
  285. struct Bus {
  286.     std::string name;
  287.     std::vector<Stop*> stops;
  288.     bool is_roundtrip;
  289.     size_t route_length;
  290. };
  291.  
  292. struct Distance {    
  293.     const Stop* start;
  294.     const Stop* end;
  295.     int distance;
  296. };  
  297.  
  298. struct BusQueryResult {
  299.     std::string_view name;
  300.     bool not_found;
  301.     int stops_on_route;
  302.     int unique_stops;
  303.     int route_length;
  304.     double curvature;
  305. };    
  306.    
  307. struct StopQueryResult {
  308.     std::string_view name;
  309.     bool not_found;
  310.     std::vector<std::string> buses_name;
  311. };
  312.    
  313. struct StopEdge {
  314.     std::string_view name;
  315.     double time = 0;
  316. };
  317.  
  318. struct BusEdge {
  319.     std::string_view bus_name;
  320.     size_t span_count = 0;
  321.     double time = 0;
  322. };
  323.  
  324. struct RoutingSettings {
  325.     double bus_wait_time = 0;
  326.     double bus_velocity = 0;
  327. };
  328.  
  329. struct RouterByStop {
  330.     graph::VertexId bus_wait_start;
  331.     graph::VertexId bus_wait_end;
  332. };
  333.  
  334. struct RouteInfo {
  335.     double total_time = 0.;
  336.     std::vector<std::variant<StopEdge, BusEdge>> edges;
  337. };
  338.  
  339. }//end namespace domain
  340. -----------------------------------------------------------------------
  341. geo.cpp
  342. -----------------------------------------------------------------------
  343. #define _USE_MATH_DEFINES
  344. #include "geo.h"
  345.  
  346. #include <cmath>
  347.  
  348. namespace geo {
  349.    
  350. double compute_distance(Coordinates start, Coordinates end) {
  351.     using namespace std;
  352.    
  353.     if (!(start == end)) {
  354.         const double dr = PI / 180.;
  355.         return acos(sin(start.latitude * dr) * sin(end.latitude * dr)
  356.                     + cos(start.latitude * dr) * cos(end.latitude * dr)
  357.                     * cos(abs(start.longitude - end.longitude) * dr)) * EARTH_RADIUS;
  358.     } else {
  359.         return 0.0;
  360.     }
  361. }
  362.    
  363. }//end namespace geo
  364. -----------------------------------------------------------------------
  365. geo.h
  366. -----------------------------------------------------------------------
  367. #pragma once
  368. #include <cmath>
  369.  
  370. namespace geo {
  371.    
  372. const int EARTH_RADIUS = 6371000;
  373. const double PI = 3.1415926535;
  374.    
  375. struct Coordinates {
  376.     double latitude;
  377.     double longitude;
  378.  
  379.     bool operator==(const Coordinates& other) const {
  380.         return latitude == other.latitude && longitude == other.longitude;
  381.     }
  382.     bool operator!=(const Coordinates& other) const {
  383.         return !(*this == other);
  384.     }
  385. };
  386.    
  387. double compute_distance(Coordinates start, Coordinates end);
  388.    
  389. }//end namespace geo
  390. -----------------------------------------------------------------------
  391. json.cpp
  392. -----------------------------------------------------------------------
  393. #include "json.h"
  394.  
  395. using namespace std;
  396.  
  397. namespace transport_catalogue {
  398. namespace detail {
  399. namespace json {
  400. namespace {
  401.    
  402. Node load_node(istream& input);
  403.  
  404. std::string load_literal(std::istream& input) {
  405.     std::string str;
  406.    
  407.     while (std::isalpha(input.peek())) {
  408.         str.push_back(static_cast<char>(input.get()));
  409.     }
  410.     return str;
  411. }
  412.  
  413. Node load_array(std::istream& input) {
  414.     std::vector<Node> array;
  415.    
  416.     for (char ch; input >> ch && ch != ']';) {
  417.         if (ch != ',') {
  418.             input.putback(ch);
  419.         }
  420.        
  421.         array.push_back(load_node(input));
  422.     }
  423.  
  424.     if (!input) {
  425.         throw ParsingError("unable to parse array"s);
  426.     }
  427.  
  428.     return Node(array);
  429. }
  430.  
  431. Node load_null(std::istream& input) {
  432.     if (auto literal = load_literal(input); literal == "null"sv) {
  433.         return Node(nullptr);
  434.     } else {
  435.         throw ParsingError("unable to parse '"s + literal + "' as null"s);
  436.     }
  437. }
  438.  
  439. Node load_bool(std::istream& input) {
  440.     const auto str = load_literal(input);
  441.  
  442.     if (str == "true"sv) {
  443.         return Node(true);
  444.     } else if (str == "false"sv) {
  445.         return Node(false);
  446.     } else {
  447.         throw ParsingError("unable to parse '"s + str + "' as bool"s);
  448.     }
  449. }
  450.  
  451. Node load_number(std::istream& input) {
  452.     std::string number;
  453.  
  454.     auto read_char = [&number, &input] {
  455.         number += static_cast<char>(input.get());
  456.        
  457.         if (!input) {
  458.             throw ParsingError("unable to read number"s);
  459.         }
  460.     };
  461.  
  462.     auto read_digits = [&input, read_char] {
  463.        
  464.         if (!std::isdigit(input.peek())) {
  465.             throw ParsingError("digit expected"s);
  466.         } else {
  467.             while (std::isdigit(input.peek())) {
  468.                 read_char();
  469.             }  
  470.         }
  471.     };
  472.  
  473.     if (input.peek() == '-') {
  474.         read_char();
  475.     }
  476.  
  477.     if (input.peek() == '0') {
  478.         read_char();
  479.     } else {
  480.         read_digits();
  481.     }
  482.  
  483.     bool is_int = true;
  484.     if (input.peek() == '.') {
  485.         read_char();
  486.         read_digits();
  487.         is_int = false;
  488.     }
  489.  
  490.     if (int ch = input.peek(); ch == 'e' || ch == 'E') {
  491.         read_char();
  492.        
  493.         if (ch = input.peek(); ch == '+' || ch == '-') {
  494.             read_char();
  495.         }
  496.  
  497.         read_digits();
  498.         is_int = false;
  499.     }
  500.  
  501.     try {
  502.         if (is_int) {
  503.             try {
  504.                 return Node(std::stoi(number));
  505.                
  506.             } catch (...) {}
  507.         }
  508.         return Node(std::stod(number));
  509.        
  510.     } catch (...) {
  511.         throw ParsingError("unable to convert "s + number + " to number"s);
  512.     }
  513. }
  514.  
  515. Node load_string(std::istream& input) {
  516.     auto it = std::istreambuf_iterator<char>(input);
  517.     auto end = std::istreambuf_iterator<char>();
  518.     std::string str;
  519.    
  520.     while (true) {
  521.         if (it == end) {
  522.             throw ParsingError("unable to parse string");
  523.         }
  524.        
  525.         const char ch = *it;
  526.         if (ch == '"') {
  527.             ++it;
  528.             break;
  529.            
  530.         } else if (ch == '\\') {
  531.             ++it;
  532.             if (it == end) {
  533.                 throw ParsingError("unable to parse string");
  534.             }
  535.            
  536.             const char esc_ch = *(it);
  537.             switch (esc_ch) {
  538.                 case 'n':
  539.                     str.push_back('\n');
  540.                     break;
  541.                 case 't':
  542.                     str.push_back('\t');
  543.                     break;
  544.                 case 'r':
  545.                     str.push_back('\r');
  546.                     break;
  547.                 case '"':
  548.                     str.push_back('"');
  549.                     break;
  550.                 case '\\':
  551.                     str.push_back('\\');
  552.                     break;
  553.                 default:
  554.                     throw ParsingError("invalid esc \\"s + esc_ch);
  555.             }
  556.            
  557.         } else if (ch == '\n' || ch == '\r') {
  558.             throw ParsingError("invalid line end"s);
  559.         } else {
  560.             str.push_back(ch);
  561.         }
  562.        
  563.         ++it;
  564.     }
  565.    
  566.     return Node(str);
  567. }
  568.    
  569. Node load_dictionary(std::istream& input) {
  570.     Dict dictionary;
  571.  
  572.     for (char ch; input >> ch && ch != '}';) {
  573.        
  574.         if (ch == '"') {
  575.             std::string key = load_string(input).as_string();
  576.  
  577.             if (input >> ch && ch == ':') {
  578.                
  579.                 if (dictionary.find(key) != dictionary.end()) {
  580.                     throw ParsingError("duplicate key '"s + key + "'found");
  581.                 }
  582.  
  583.                 dictionary.emplace(std::move(key), load_node(input));
  584.                
  585.             } else {
  586.                 throw ParsingError(": expected. but '"s + ch + "' found"s);
  587.             }
  588.            
  589.         } else if (ch != ',') {
  590.             throw ParsingError("',' expected. but '"s + ch + "' found"s);
  591.         }
  592.     }
  593.  
  594.     if (!input) {
  595.         throw ParsingError("unable to parse dictionary"s);
  596.     } else {
  597.         return Node(dictionary);
  598.     }
  599.    
  600. }
  601.  
  602. Node load_node(std::istream& input) {
  603.     char ch;
  604.    
  605.     if (!(input >> ch)) {
  606.         throw ParsingError(""s);
  607.     } else {
  608.         switch (ch) {
  609.         case '[':
  610.             return load_array(input);
  611.         case '{':
  612.             return load_dictionary(input);
  613.         case '"':
  614.             return load_string(input);
  615.         case 't': case 'f':
  616.             input.putback(ch);
  617.             return load_bool(input);
  618.         case 'n':
  619.             input.putback(ch);
  620.             return load_null(input);
  621.         default:
  622.             input.putback(ch);
  623.             return load_number(input);
  624.         }
  625.     }
  626. }
  627.    
  628. }//end namespace
  629.    
  630. Node::Node(Array array) : value_(std::move(array)) {}    
  631. Node::Node(std::nullptr_t) : Node() {}
  632. Node::Node(bool value) : value_(value) {}
  633. Node::Node(Dict dict) : value_(std::move(dict)) {}
  634. Node::Node(int value) : value_(value) {}
  635. Node::Node(string value) : value_(std::move(value)) {}
  636. Node::Node(double value) : value_(value) {}
  637.    
  638. const Array& Node::as_array() const {
  639.     using namespace std::literals;
  640.    
  641.     if (!is_array()) {
  642.         throw std::logic_error("value is not an array"s);
  643.     } else {
  644.         return std::get<Array>(value_);
  645.     }
  646. }
  647.  
  648. const Dict& Node::as_dict() const {
  649.     using namespace std::literals;
  650.    
  651.     if (!is_dict()) {
  652.         throw std::logic_error("value is not a dictionary"s);
  653.     } else {
  654.         return std::get<Dict>(value_);  
  655.     }
  656. }
  657.  
  658. const std::string& Node::as_string() const {
  659.     using namespace std::literals;
  660.    
  661.     if (!is_string()) {
  662.         throw std::logic_error("value is not a string"s);
  663.     } else {
  664.         return std::get<std::string>(value_);        
  665.     }
  666. }
  667.    
  668. int Node::as_int() const {
  669.     using namespace std::literals;
  670.    
  671.     if (!is_int()) {
  672.         throw std::logic_error("value is not an int"s);
  673.     } else {
  674.         return std::get<int>(value_);    
  675.     }
  676. }
  677.  
  678. double Node::as_double() const {
  679.     using namespace std::literals;
  680.    
  681.     if (!is_double()) {
  682.         throw std::logic_error("value is not a double"s);
  683.     } else if (is_real_double()) {
  684.         return std::get<double>(value_);
  685.     } else {
  686.         return as_int();
  687.     }  
  688. }
  689.  
  690. bool Node::as_bool() const {
  691.     using namespace std::literals;
  692.    
  693.     if (!is_bool()) {
  694.         throw std::logic_error("value is not a bool"s);
  695.     } else {
  696.         return std::get<bool>(value_);  
  697.     }
  698. }
  699.    
  700. bool Node::is_null() const {return std::holds_alternative<std::nullptr_t>(value_);}
  701. bool Node::is_int() const {return std::holds_alternative<int>(value_);}
  702. bool Node::is_double() const {return is_real_double() || is_int();}  
  703. bool Node::is_real_double() const {return std::holds_alternative<double>(value_);}
  704. bool Node::is_bool() const {return std::holds_alternative<bool>(value_);}
  705. bool Node::is_string() const {return std::holds_alternative<std::string>(value_);}
  706. bool Node::is_array() const {return std::holds_alternative<Array>(value_);}
  707. bool Node::is_dict() const {return std::holds_alternative<Dict>(value_);}
  708.  
  709. const Node::Value& Node::get_value() const {return value_;}
  710.    
  711. Document::Document(Node root) : root_(std::move(root)) {}
  712. const Node& Document::get_root() const {return root_;}
  713.    
  714. Document load(istream& input) {return Document(load_node(input));}
  715.  
  716. struct PrintContext {
  717.     std::ostream& out;
  718.     int indent_step = 4;
  719.     int indent = 0;
  720.  
  721.     void print_indent() const {
  722.         for (int i = 0; i < indent; ++i) {
  723.             out.put(' ');
  724.         }
  725.     }
  726.  
  727.     [[nodiscard]] PrintContext indented() const {
  728.         return {out,
  729.                 indent_step,
  730.                 indent_step + indent};
  731.     }
  732. };
  733.  
  734. void print_node(const Node& node, const PrintContext& context);
  735.  
  736. void print_string(const std::string& value, std::ostream& out) {
  737.     out.put('"');
  738.    
  739.     for (const char ch : value) {
  740.         switch (ch) {
  741.             case '\r':
  742.                 out << R"(\r)";
  743.                 break;
  744.             case '\n':
  745.                 out << R"(\n)";
  746.                 break;
  747.             case '"':
  748.                 out << R"(\")";
  749.                 break;
  750.             case '\\':
  751.                 out << R"(\\)";
  752.                 break;
  753.             default:
  754.                 out.put(ch);
  755.                 break;
  756.         }
  757.     }
  758.    
  759.     out.put('"');
  760. }
  761.  
  762. template <typename Value>
  763. void print_value(const Value& value, const PrintContext& context) {
  764.     context.out << value;
  765. }    
  766.  
  767. template <>
  768. void print_value<std::string>(const std::string& value, const PrintContext& context) {
  769.     print_string(value, context.out);
  770. }
  771.  
  772. void print_value(const std::nullptr_t&, const PrintContext& context) {
  773.     context.out << "null"s;
  774. }
  775.  
  776. void print_value(bool value, const PrintContext& context) {
  777.     context.out << std::boolalpha << value;
  778. }
  779.  
  780. [[maybe_unused]] void print_value(Array nodes, const PrintContext& context) {
  781.     std::ostream& out = context.out;
  782.     out << "[\n"sv;
  783.     bool first = true;
  784.     auto inner_context = context.indented();
  785.    
  786.     for (const Node& node : nodes) {
  787.         if (first) {
  788.             first = false;
  789.         } else {
  790.             out << ",\n"sv;
  791.         }
  792.  
  793.         inner_context.print_indent();
  794.         print_node(node, inner_context);
  795.     }
  796.  
  797.     out.put('\n');
  798.     context.print_indent();
  799.     out.put(']');
  800. }
  801.  
  802. [[maybe_unused]] void print_value(Dict nodes, const PrintContext& context) {
  803.     std::ostream& out = context.out;
  804.     out << "{\n"sv;
  805.     bool first = true;
  806.     auto inner_context = context.indented();
  807.    
  808.     for (const auto& [key, node] : nodes) {
  809.         if (first) {
  810.             first = false;
  811.         } else {
  812.             out << ",\n"sv;
  813.         }
  814.  
  815.         inner_context.print_indent();
  816.         print_string(key, context.out);
  817.         out << ": "sv;
  818.         print_node(node, inner_context);
  819.     }
  820.  
  821.     out.put('\n');
  822.     context.print_indent();
  823.     out.put('}');
  824. }
  825.  
  826. void print_node(const Node& node, const PrintContext& context) {
  827.     std::visit([&context](const auto& value) {
  828.             print_value(value, context);
  829.         }, node.get_value());
  830. }
  831.    
  832. void print(const Document& document, std::ostream& output) {
  833.     print_node(document.get_root(), PrintContext{output});
  834. }
  835.  
  836. }//end namespace json
  837. }//end namespace detail
  838. }//end namespace transport_catalogue
  839. -----------------------------------------------------------------------
  840. json.h
  841. -----------------------------------------------------------------------
  842. #pragma once
  843.  
  844. #include <iostream>
  845. #include <map>
  846. #include <string>
  847. #include <vector>
  848. #include <variant>
  849.  
  850. namespace transport_catalogue {
  851. namespace detail {
  852. namespace json {
  853.  
  854. class Node;
  855.  
  856. using Dict = std::map<std::string, Node>;
  857. using Array = std::vector<Node>;
  858.  
  859. class ParsingError : public std::runtime_error {
  860. public:
  861.     using runtime_error::runtime_error;
  862. };
  863.  
  864. class Node final : private std::variant<std::nullptr_t, Array, Dict, bool, int, double, std::string> {
  865. public:
  866.    
  867.     using variant::variant;
  868.     using Value = variant;
  869.  
  870.     Node() = default;
  871.     Node(bool value);
  872.     Node(Array array);
  873.     Node(Dict dict);
  874.     Node(int value);
  875.     Node(std::string value);
  876.     Node(std::nullptr_t);
  877.     Node(double value);
  878.    
  879.     const Array& as_array() const;
  880.     const Dict& as_dict() const;
  881.     int as_int() const;
  882.     double as_double() const;
  883.     bool as_bool() const;
  884.     const std::string& as_string() const;
  885.  
  886.     bool is_null() const;
  887.     bool is_int() const;
  888.     bool is_double() const;
  889.     bool is_real_double() const;
  890.     bool is_bool() const;
  891.     bool is_string() const;
  892.     bool is_array() const;
  893.     bool is_dict() const;
  894.  
  895.     const Value& get_value() const;
  896.        
  897. private:
  898.     Value value_;
  899. };
  900.  
  901. inline bool operator==(const Node& lhs, const Node& rhs) {
  902.     return lhs.get_value() == rhs.get_value();
  903. }  
  904. inline bool operator!=(const Node& lhs, const Node& rhs) {
  905.     return !(lhs == rhs);
  906. }
  907.    
  908. class Document {
  909. public:
  910.     Document() = default;
  911.     explicit Document(Node root);
  912.     const Node& get_root() const;
  913.  
  914. private:
  915.     Node root_;
  916. };
  917.  
  918. inline bool operator==(const Document& lhs, const Document& rhs) {
  919.     return lhs.get_root() == rhs.get_root();
  920. }
  921. inline bool operator!=(const Document& lhs, const Document& rhs) {
  922.     return !(lhs == rhs);
  923. }
  924.  
  925. Document load(std::istream& input);
  926. void print(const Document& document, std::ostream& output);
  927.  
  928. }//end namespace json
  929. }//end namespace detail
  930. }//end namespace transport_catalogue
  931. -----------------------------------------------------------------------
  932. json_builder.cpp
  933. -----------------------------------------------------------------------
  934. #include "json_builder.h"
  935.  
  936. namespace transport_catalogue {
  937. namespace detail {
  938. namespace json {
  939. namespace builder {
  940.  
  941. BaseContext::BaseContext(Builder& builder) : builder_(builder) {}
  942.  
  943. KeyContext BaseContext::key(const std::string& key) {return builder_.key(key);}
  944. Builder& BaseContext::value(const Node::Value& value) {return builder_.value(value);}
  945.  
  946. DictionaryContext BaseContext::start_dict() {return DictionaryContext(builder_.start_dict());}
  947. Builder& BaseContext::end_dict() {return builder_.end_dict();}
  948.  
  949. ArrayContext BaseContext::start_array() {return ArrayContext(builder_.start_array());}
  950. Builder& BaseContext::end_array() {return builder_.end_array();}
  951.  
  952. KeyContext::KeyContext(Builder& builder) : BaseContext(builder) {}
  953.  
  954. DictionaryContext KeyContext::value(const Node::Value& value) {return BaseContext::value(std::move(value));}
  955.  
  956. DictionaryContext::DictionaryContext(Builder& builder) : BaseContext(builder) {}
  957.  
  958. ArrayContext::ArrayContext(Builder& builder) : BaseContext(builder) {}
  959.  
  960. ArrayContext ArrayContext::value(const Node::Value& value) {return BaseContext::value(std::move(value));}
  961.  
  962. Node Builder::make_node(const Node::Value& value_) {
  963.     Node node;
  964.  
  965.     if (std::holds_alternative<bool>(value_)) {
  966.         bool bol = std::get<bool>(value_);
  967.         node = Node(bol);
  968.  
  969.     } else if (std::holds_alternative<int>(value_)) {
  970.         int intt = std::get<int>(value_);
  971.         node = Node(intt);
  972.  
  973.     } else if (std::holds_alternative<double>(value_)) {
  974.         double doble = std::get<double>(value_);
  975.         node = Node(doble);
  976.  
  977.     } else if (std::holds_alternative<std::string>(value_)) {
  978.         std::string str = std::get<std::string>(value_);
  979.         node = Node(std::move(str));
  980.  
  981.     } else if (std::holds_alternative<Array>(value_)) {
  982.         Array arr = std::get<Array>(value_);
  983.         node = Node(std::move(arr));
  984.  
  985.     } else if (std::holds_alternative<Dict>(value_)) {
  986.         Dict dictionary = std::get<Dict>(value_);
  987.         node = Node(std::move(dictionary));
  988.  
  989.     } else {
  990.         node = Node();
  991.     }
  992.  
  993.     return node;
  994. }
  995.  
  996. void Builder::add_node(const Node& node) {
  997.     if (nodes_stack_.empty()) {
  998.  
  999.         if (!root_.is_null()) {
  1000.             throw std::logic_error("root has been added");
  1001.         }
  1002.  
  1003.         root_ = node;
  1004.         return;
  1005.  
  1006.     } else {
  1007.  
  1008.         if (!nodes_stack_.back()->is_array()
  1009.             && !nodes_stack_.back()->is_string()) {
  1010.  
  1011.             throw std::logic_error("unable to create node");
  1012.         }
  1013.  
  1014.         if (nodes_stack_.back()->is_array()) {
  1015.             Array arr = nodes_stack_.back()->as_array();
  1016.             arr.emplace_back(node);
  1017.  
  1018.             nodes_stack_.pop_back();
  1019.             auto arr_ptr = std::make_unique<Node>(arr);
  1020.             nodes_stack_.emplace_back(std::move(arr_ptr));
  1021.  
  1022.             return;
  1023.         }
  1024.  
  1025.         if (nodes_stack_.back()->is_string()) {
  1026.             std::string str = nodes_stack_.back()->as_string();
  1027.             nodes_stack_.pop_back();
  1028.  
  1029.             if (nodes_stack_.back()->is_dict()) {
  1030.                 Dict dictionary = nodes_stack_.back()->as_dict();
  1031.                 dictionary.emplace(std::move(str), node);
  1032.  
  1033.                 nodes_stack_.pop_back();
  1034.                 auto dictionary_ptr = std::make_unique<Node>(dictionary);
  1035.                 nodes_stack_.emplace_back(std::move(dictionary_ptr));
  1036.             }
  1037.  
  1038.             return;
  1039.         }
  1040.     }
  1041. }
  1042.  
  1043. KeyContext Builder::key(const std::string& key_) {
  1044.     if (nodes_stack_.empty()) {
  1045.         throw std::logic_error("unable to create key");
  1046.     }
  1047.  
  1048.     auto key_ptr = std::make_unique<Node>(key_);
  1049.  
  1050.     if (nodes_stack_.back()->is_dict()) {
  1051.         nodes_stack_.emplace_back(std::move(key_ptr));
  1052.     }
  1053.  
  1054.     return KeyContext(*this);
  1055. }
  1056.  
  1057. Builder& Builder::value(const Node::Value& value_) {
  1058.     add_node(make_node(value_));
  1059.  
  1060.     return *this;
  1061. }
  1062.  
  1063. DictionaryContext Builder::start_dict() {
  1064.     nodes_stack_.emplace_back(std::move(std::make_unique<Node>(Dict())));
  1065.  
  1066.     return DictionaryContext(*this);
  1067. }
  1068.  
  1069. Builder& Builder::end_dict() {
  1070.     if (nodes_stack_.empty()) {
  1071.         throw std::logic_error("unable to close as without opening");
  1072.     }
  1073.  
  1074.     Node node = *nodes_stack_.back();
  1075.  
  1076.     if (!node.is_dict()) {
  1077.         throw std::logic_error("object isn't dictionary");
  1078.     }
  1079.  
  1080.     nodes_stack_.pop_back();
  1081.     add_node(node);
  1082.  
  1083.     return *this;
  1084. }
  1085.  
  1086. ArrayContext Builder::start_array() {
  1087.     nodes_stack_.emplace_back(std::move(std::make_unique<Node>(Array())));
  1088.  
  1089.     return ArrayContext(*this);
  1090. }
  1091.  
  1092. Builder& Builder::end_array() {
  1093.     if (nodes_stack_.empty()) {
  1094.         throw std::logic_error("unable to close without opening");
  1095.     }
  1096.  
  1097.     Node node = *nodes_stack_.back();
  1098.  
  1099.     if (!node.is_array()) {
  1100.         throw std::logic_error("object isn't array");
  1101.     }
  1102.  
  1103.     nodes_stack_.pop_back();
  1104.     add_node(node);
  1105.  
  1106.     return *this;
  1107. }
  1108.  
  1109. Node Builder::build() {
  1110.     if (root_.is_null()) {
  1111.         throw std::logic_error("empty json");
  1112.     }
  1113.  
  1114.     if (!nodes_stack_.empty()) {
  1115.         throw std::logic_error("invalid json");
  1116.     }
  1117.  
  1118.     return root_;
  1119. }
  1120.  
  1121. }//end namespace builder
  1122. }//end namespace json
  1123. }//end namespace detail
  1124. }//end namespace transport_catalogue
  1125. -----------------------------------------------------------------------
  1126. json_builder.h
  1127. -----------------------------------------------------------------------
  1128. #pragma once
  1129.  
  1130. #include "json.h"
  1131. #include <stack>
  1132. #include <string>
  1133. #include <memory>
  1134.  
  1135. namespace transport_catalogue {
  1136. namespace detail {
  1137. namespace json {
  1138. namespace builder {
  1139.  
  1140. class KeyContext;
  1141. class DictionaryContext;
  1142. class ArrayContext;
  1143.  
  1144. class Builder {
  1145. public:
  1146.     Node make_node(const Node::Value& value_);
  1147.     void add_node(const Node& node);
  1148.  
  1149.     KeyContext key(const std::string& key_);
  1150.     Builder& value(const Node::Value& value);
  1151.    
  1152.     DictionaryContext start_dict();
  1153.     Builder& end_dict();
  1154.    
  1155.     ArrayContext start_array();
  1156.     Builder& end_array();
  1157.  
  1158.     Node build();
  1159.  
  1160. private:
  1161.     Node root_;
  1162.     std::vector<std::unique_ptr<Node>> nodes_stack_;
  1163. };
  1164.  
  1165. class BaseContext {
  1166. public:
  1167.     BaseContext(Builder& builder);
  1168.  
  1169.     KeyContext key(const std::string& key);
  1170.     Builder& value(const Node::Value& value);
  1171.    
  1172.     DictionaryContext start_dict();
  1173.     Builder& end_dict();
  1174.    
  1175.     ArrayContext start_array();
  1176.     Builder& end_array();
  1177.  
  1178. protected:
  1179.     Builder& builder_;
  1180. };
  1181.  
  1182. class KeyContext : public BaseContext {
  1183. public:
  1184.     KeyContext(Builder& builder);
  1185.  
  1186.     KeyContext key(const std::string& key) = delete;
  1187.  
  1188.     BaseContext end_dict() = delete;
  1189.     BaseContext end_array() = delete;
  1190.  
  1191.     DictionaryContext value(const Node::Value& value);
  1192. };
  1193.  
  1194. class DictionaryContext : public BaseContext {
  1195. public:
  1196.     DictionaryContext(Builder& builder);
  1197.  
  1198.     DictionaryContext start_dict() = delete;
  1199.  
  1200.     ArrayContext start_array() = delete;
  1201.     Builder& end_array() = delete;
  1202.  
  1203.     Builder& value(const Node::Value& value) = delete;
  1204. };
  1205.  
  1206. class ArrayContext : public BaseContext {
  1207. public:
  1208.     ArrayContext(Builder& builder);
  1209.  
  1210.     KeyContext key(const std::string& key) = delete;
  1211.  
  1212.     Builder& end_dict() = delete;
  1213.  
  1214.     ArrayContext value(const Node::Value& value);
  1215. };
  1216.  
  1217. }//end namespace builder
  1218. }//end namespace json
  1219. }//end namespace detail
  1220. }//end namespace transport_catalogue
  1221. -----------------------------------------------------------------------
  1222. json_reader.cpp
  1223. -----------------------------------------------------------------------
  1224. #include "json_reader.h"
  1225.  
  1226. namespace transport_catalogue {
  1227. namespace detail {
  1228. namespace json {
  1229.    
  1230. JSONReader::JSONReader(Document doc) : document_(std::move(doc)) {}
  1231. JSONReader::JSONReader(std::istream& input) : document_(json::load(input)) {}    
  1232.    
  1233. Stop JSONReader::parse_node_stop(Node& node) {
  1234.     Stop stop;
  1235.     Dict stop_node;
  1236.    
  1237.     if (node.is_dict()) {
  1238.         stop_node = node.as_dict();
  1239.         stop.name = stop_node.at("name").as_string();
  1240.         stop.latitude = stop_node.at("latitude").as_double();
  1241.         stop.longitude = stop_node.at("longitude").as_double();
  1242.     }
  1243.    
  1244.     return stop;
  1245. }
  1246.    
  1247. std::vector<Distance> JSONReader::parse_node_distances(Node& node, TransportCatalogue& catalogue) {
  1248.     std::vector<Distance> distances;
  1249.     Dict stop_node;
  1250.     Dict stop_road_map;
  1251.     std::string begin_name;
  1252.     std::string last_name;
  1253.     int distance;
  1254.    
  1255.     if (node.is_dict()) {
  1256.         stop_node = node.as_dict();
  1257.         begin_name = stop_node.at("name").as_string();
  1258.        
  1259.         try {
  1260.             stop_road_map = stop_node.at("road_distances").as_dict();
  1261.            
  1262.             for (auto [key, value] : stop_road_map) {
  1263.                 last_name = key;
  1264.                 distance = value.as_int();
  1265.                 distances.push_back({catalogue.get_stop(begin_name),
  1266.                                      catalogue.get_stop(last_name), distance});
  1267.             }
  1268.            
  1269.         } catch(...) {
  1270.             std::cout << "invalide road" << std::endl;
  1271.         }        
  1272.     }
  1273.    
  1274.     return distances;
  1275. }
  1276.  
  1277. Bus JSONReader::parse_node_bus(Node& node, TransportCatalogue& catalogue) {
  1278.     Bus bus;
  1279.     Dict bus_node;
  1280.     Array bus_stops;
  1281.    
  1282.     if (node.is_dict()) {
  1283.         bus_node = node.as_dict();
  1284.         bus.name = bus_node.at("name").as_string();
  1285.         bus.is_roundtrip = bus_node.at("is_roundtrip").as_bool();
  1286.  
  1287.         try {
  1288.             bus_stops = bus_node.at("stops").as_array();
  1289.            
  1290.             for (Node stop : bus_stops) {
  1291.                 bus.stops.push_back(catalogue.get_stop(stop.as_string()));
  1292.             }
  1293.  
  1294.             if (!bus.is_roundtrip) {
  1295.                 size_t size = bus.stops.size() - 1;
  1296.                
  1297.                 for (size_t i = size; i > 0; i--) {
  1298.                     bus.stops.push_back(bus.stops[i-1]);
  1299.                 }
  1300.                
  1301.             }
  1302.            
  1303.         } catch(...) {
  1304.             std::cout << "base_requests: bus: stops is empty" << std::endl;
  1305.         }        
  1306.     }
  1307.    
  1308.     return bus;
  1309. }
  1310.    
  1311. void JSONReader::parse_node_base(const Node& root, TransportCatalogue& catalogue){
  1312.     Array base_requests;
  1313.     Dict req_map;
  1314.     Node req_node;
  1315.    
  1316.     std::vector<Node> buses;
  1317.     std::vector<Node> stops;
  1318.    
  1319.     if (root.is_array()) {
  1320.         base_requests = root.as_array();
  1321.        
  1322.         for (Node& node : base_requests) {            
  1323.             if (node.is_dict()) {
  1324.                 req_map = node.as_dict();
  1325.                
  1326.                 try {
  1327.                     req_node = req_map.at("type");
  1328.                    
  1329.                     if (req_node.is_string()) {
  1330.                        
  1331.                         if (req_node.as_string() == "Bus") {
  1332.                             buses.push_back(req_map);
  1333.                         } else if (req_node.as_string() == "Stop") {
  1334.                             stops.push_back(req_map);
  1335.                         } else {
  1336.                             std::cout << "base_requests are invalid";
  1337.                         }
  1338.                     }
  1339.                    
  1340.                 } catch(...) {
  1341.                     std::cout << "base_requests does not have type value";
  1342.                 }                
  1343.             }
  1344.         }  
  1345.        
  1346.         for (auto stop : stops) {
  1347.             catalogue.add_stop(parse_node_stop(stop));
  1348.         }
  1349.        
  1350.         for (auto stop : stops) {
  1351.             catalogue.add_distance(parse_node_distances(stop, catalogue));
  1352.         }
  1353.        
  1354.         for (auto bus : buses) {
  1355.             catalogue.add_bus(parse_node_bus(bus, catalogue));
  1356.         }
  1357.        
  1358.     } else {
  1359.         std::cout << "base_requests is not an array";
  1360.     }  
  1361. }
  1362.  
  1363. void JSONReader::parse_node_stat(const Node& node, std::vector<StatRequest>& stat_request){
  1364.     Array stat_requests;
  1365.     Dict req_map;
  1366.     StatRequest req;
  1367.    
  1368.     if (node.is_array()) {
  1369.         stat_requests = node.as_array();
  1370.        
  1371.         for (Node req_node : stat_requests) {
  1372.            
  1373.             if (req_node.is_dict()) {
  1374.                 req_map = req_node.as_dict();
  1375.                 req.id = req_map.at("id").as_int();
  1376.                 req.type = req_map.at("type").as_string();              
  1377.  
  1378.                 if ((req.type == "Bus") || (req.type == "Stop")) {
  1379.                     req.name = req_map.at("name").as_string();
  1380.                     req.from ="";
  1381.                     req.to = "";
  1382.                 } else {
  1383.                     req.name = "";
  1384.                     if(req.type == "Route"){
  1385.                         req.from = req_map.at("from").as_string();
  1386.                         req.to = req_map.at("to").as_string();
  1387.                     }
  1388.                     else{
  1389.                         req.from ="";
  1390.                         req.to = "";
  1391.                     }
  1392.                 }
  1393.                
  1394.                 stat_request.push_back(req);                
  1395.             }  
  1396.         }
  1397.        
  1398.     } else {
  1399.         std::cout << "base_requests is not array";
  1400.     }
  1401. }
  1402.  
  1403. void JSONReader::parse_node_render(const Node& node, map_renderer::RenderSettings& rend_set){
  1404.     Dict rend_map;
  1405.     Array bus_lab_offset;
  1406.     Array stop_lab_offset;
  1407.     Array arr_color;
  1408.     Array arr_palette;
  1409.     uint8_t red_;
  1410.     uint8_t green_;
  1411.     uint8_t blue_;
  1412.     double opacity_;
  1413.  
  1414.     if (node.is_dict()) {
  1415.         rend_map = node.as_dict();
  1416.        
  1417.         try {
  1418.             rend_set.width_ = rend_map.at("width").as_double();
  1419.             rend_set.height_ = rend_map.at("height").as_double();
  1420.             rend_set.padding_ = rend_map.at("padding").as_double();
  1421.             rend_set.line_width_ = rend_map.at("line_width").as_double();
  1422.             rend_set.stop_radius_ = rend_map.at("stop_radius").as_double();
  1423.            
  1424.             rend_set.bus_label_font_size_ = rend_map.at("bus_label_font_size").as_int();
  1425.            
  1426.             if (rend_map.at("bus_label_offset").is_array()) {
  1427.                 bus_lab_offset = rend_map.at("bus_label_offset").as_array();
  1428.                 rend_set.bus_label_offset_ = std::make_pair(bus_lab_offset[0].as_double(),
  1429.                                                             bus_lab_offset[1].as_double());
  1430.             }
  1431.            
  1432.             rend_set.stop_label_font_size_ = rend_map.at("stop_label_font_size").as_int();
  1433.  
  1434.             if (rend_map.at("stop_label_offset").is_array()) {
  1435.                 stop_lab_offset = rend_map.at("stop_label_offset").as_array();
  1436.                 rend_set.stop_label_offset_ = std::make_pair(stop_lab_offset[0].as_double(),
  1437.                                                              stop_lab_offset[1].as_double());
  1438.             }
  1439.            
  1440.             if (rend_map.at("underlayer_color").is_string()) {
  1441.                 rend_set.underlayer_color_ = svg::Color(rend_map.at("underlayer_color").as_string());
  1442.             } else if (rend_map.at("underlayer_color").is_array()) {
  1443.                 arr_color = rend_map.at("underlayer_color").as_array();
  1444.                 red_ = arr_color[0].as_int();
  1445.                 green_ = arr_color[1].as_int();
  1446.                 blue_ = arr_color[2].as_int();
  1447.  
  1448.                 if(arr_color.size() == 4){
  1449.                     opacity_ = arr_color[3].as_double();
  1450.                     rend_set.underlayer_color_ = svg::Color(svg::Rgba(red_,
  1451.                                                                       green_,
  1452.                                                                       blue_,
  1453.                                                                       opacity_));
  1454.                 } else if (arr_color.size() == 3) {
  1455.                     rend_set.underlayer_color_ = svg::Color(svg::Rgb(red_,
  1456.                                                                      green_,
  1457.                                                                      blue_));
  1458.                 }
  1459.                
  1460.             }
  1461.  
  1462.             rend_set.underlayer_width_ = rend_map.at("underlayer_width").as_double();
  1463.  
  1464.             if (rend_map.at("color_palette").is_array()) {
  1465.                 arr_palette = rend_map.at("color_palette").as_array();
  1466.                
  1467.                 for (Node color_palette : arr_palette) {
  1468.                    
  1469.                     if (color_palette.is_string()) {
  1470.                         rend_set.color_palette_.push_back(svg::Color(color_palette.as_string()));
  1471.                     } else if (color_palette.is_array()) {
  1472.                         arr_color = color_palette.as_array();
  1473.                         red_ = arr_color[0].as_int();
  1474.                         green_ = arr_color[1].as_int();
  1475.                         blue_ = arr_color[2].as_int();
  1476.  
  1477.                         if (arr_color.size() == 4) {
  1478.                             opacity_ = arr_color[3].as_double();
  1479.                             rend_set.color_palette_.push_back(svg::Color(svg::Rgba(red_,
  1480.                                                                                    green_,
  1481.                                                                                    blue_,
  1482.                                                                                    opacity_)));
  1483.                         } else if (arr_color.size() == 3) {
  1484.                             rend_set.color_palette_.push_back(svg::Color(svg::Rgb(red_,
  1485.                                                                                   green_,
  1486.                                                                                   blue_)));
  1487.                         }
  1488.                     }
  1489.                 }
  1490.             }            
  1491.         } catch(...) {
  1492.             std::cout << "unable to parsse init settings";
  1493.         }
  1494.        
  1495.     } else {
  1496.         std::cout << "render_settings is not map";
  1497.     }
  1498. }
  1499.    
  1500. void JSONReader::parse_node_routing(const Node& node, router::RoutingSettings& route_set) {
  1501.     Dict route;
  1502.    
  1503.     if (node.is_dict()) {
  1504.         route = node.as_dict();
  1505.  
  1506.         try {
  1507.  
  1508.             route_set.bus_wait_time = route.at("bus_wait_time").as_double();
  1509.             route_set.bus_velocity = route.at("bus_velocity").as_double();
  1510.            
  1511.         } catch(...) {
  1512.             std::cout << "unable to parse routing settings";
  1513.         }
  1514.        
  1515.     } else {
  1516.         std::cout << "routing settings is not map";
  1517.     }
  1518.  
  1519. }
  1520.    
  1521. void JSONReader::parse_node(const Node& root,
  1522.                             TransportCatalogue& catalogue,
  1523.                             std::vector<StatRequest>& stat_request,
  1524.                             map_renderer::RenderSettings& render_settings,
  1525.                             router::RoutingSettings& routing_settings){
  1526.     Dict root_dictionary;
  1527.    
  1528.     if (root.is_dict()) {
  1529.         root_dictionary = root.as_dict();
  1530.        
  1531.         try {          
  1532.             parse_node_base(root_dictionary.at("base_requests"), catalogue);
  1533.         } catch(...) {
  1534.             std::cout << "base_requests is empty";
  1535.         }
  1536.        
  1537.         try {
  1538.             parse_node_stat(root_dictionary.at("stat_requests"), stat_request);
  1539.         } catch(...) {
  1540.             std::cout << "stat_requests is empty";
  1541.         }
  1542.        
  1543.         try {
  1544.             parse_node_render(root_dictionary.at("render_settings"), render_settings);
  1545.         } catch(...) {
  1546.             std::cout << "render_settings is empty";
  1547.         }
  1548.        
  1549.         try {
  1550.             parse_node_routing(root_dictionary.at("routing_settings"), routing_settings);
  1551.         } catch(...) {
  1552.             std::cout << "routing_settings is empty";
  1553.         }
  1554.        
  1555.     } else {
  1556.         std::cout << "root is not map";
  1557.     }
  1558. }
  1559.    
  1560. void JSONReader::parse(TransportCatalogue& catalogue, std::vector<StatRequest>& stat_request, map_renderer::RenderSettings& render_settings, router::RoutingSettings& routing_settings) {  
  1561.     parse_node(document_.get_root(),
  1562.                catalogue,
  1563.                stat_request,
  1564.                render_settings,
  1565.                routing_settings);
  1566. }
  1567.    
  1568. }//end namespace json
  1569. }//end namespace detail
  1570. }//end namespace transport_catalogue
  1571. -----------------------------------------------------------------------
  1572. main.cpp
  1573. -----------------------------------------------------------------------
  1574. #include "json_reader.h"
  1575. #include "map_renderer.h"
  1576. #include "request_handler.h"
  1577.  
  1578. using namespace std;
  1579. using namespace transport_catalogue;
  1580. using namespace map_renderer;
  1581. using namespace request_handler;
  1582. using namespace transport_catalogue::detail::json;
  1583. using namespace transport_catalogue::detail::router;
  1584.  
  1585. int main() {
  1586.     vector<StatRequest> stat_request;
  1587.     RenderSettings render_settings;
  1588.     TransportCatalogue catalogue;  
  1589.     RoutingSettings routing_settings;
  1590.      
  1591.     JSONReader json_reader;
  1592.     RequestHandler request_handler;
  1593.        
  1594.     json_reader = JSONReader(cin);    
  1595.     json_reader.parse(catalogue, stat_request, render_settings, routing_settings);
  1596.    
  1597.     request_handler = RequestHandler();    
  1598.     request_handler.execute_queries(catalogue, stat_request, render_settings, routing_settings);
  1599.     transport_catalogue::detail::json::print(request_handler.get_document(), cout);
  1600. }
  1601. -----------------------------------------------------------------------
  1602. json_reader.h
  1603. -----------------------------------------------------------------------
  1604. #pragma once
  1605. #include "json.h"
  1606. #include "transport_catalogue.h"
  1607. #include "map_renderer.h"
  1608. #include "transport_router.h"
  1609.  
  1610. namespace transport_catalogue {
  1611. namespace detail {
  1612. namespace json {
  1613.    
  1614. class JSONReader{
  1615. public:
  1616.     JSONReader() = default;    
  1617.     JSONReader(Document doc);
  1618.     JSONReader(std::istream& input);
  1619.    
  1620.     void parse_node_base(const Node& root, TransportCatalogue& catalogue);
  1621.     void parse_node_stat(const Node& root, std::vector<StatRequest>& stat_request);
  1622.     void parse_node_render(const Node& node, map_renderer::RenderSettings& render_settings);
  1623.     void parse_node_routing(const Node& node, router::RoutingSettings& route_set);
  1624.    
  1625.     void parse_node(const Node& root,
  1626.                     TransportCatalogue& catalogue,
  1627.                     std::vector<StatRequest>& stat_request,
  1628.                     map_renderer::RenderSettings& render_settings,
  1629.                     router::RoutingSettings& routing_settings);
  1630.    
  1631.     void parse(TransportCatalogue& catalogue,
  1632.                std::vector<StatRequest>& stat_request,
  1633.                map_renderer::RenderSettings& render_settings,
  1634.                router::RoutingSettings& routing_settings);
  1635.    
  1636.     Stop parse_node_stop(Node& node);
  1637.     Bus parse_node_bus(Node& node, TransportCatalogue& catalogue);
  1638.     std::vector<Distance> parse_node_distances(Node& node, TransportCatalogue& catalogue);
  1639.    
  1640.     const Document& get_document() const;
  1641.    
  1642. private:
  1643.     Document document_;
  1644. };
  1645.    
  1646. }//end namespace json
  1647. }//end namespace detail
  1648. }//end namespace transport_catalogue
  1649. -----------------------------------------------------------------------
  1650. map_renderer.cpp
  1651. -----------------------------------------------------------------------
  1652. #include "map_renderer.h"
  1653.  
  1654. namespace map_renderer {
  1655.  
  1656. bool SphereProjector::is_zero(double value) {
  1657.     return std::abs(value) < EPSILON;
  1658. }
  1659.    
  1660. MapRenderer::MapRenderer(RenderSettings& render_settings) : render_settings_(render_settings) {}
  1661.  
  1662. svg::Point SphereProjector::operator()(geo::Coordinates coords) const {
  1663.     return {(coords.longitude - min_lon_) * zoom_coeff_ + padding_,
  1664.             (max_lat_ - coords.latitude) * zoom_coeff_ + padding_};
  1665. }
  1666.    
  1667. SphereProjector MapRenderer::get_sphere_projector(const std::vector<geo::Coordinates>& points) const {
  1668.         return SphereProjector(points.begin(),
  1669.                                points.end(),
  1670.                                render_settings_.width_,
  1671.                                render_settings_.height_,
  1672.                                render_settings_.padding_);
  1673. }
  1674.  
  1675. void MapRenderer::init_sphere_projector(std::vector<geo::Coordinates> points){
  1676.     sphere_projector = SphereProjector(points.begin(),
  1677.                                points.end(),
  1678.                                render_settings_.width_,
  1679.                                render_settings_.height_,
  1680.                                render_settings_.padding_);
  1681. }
  1682.    
  1683. RenderSettings MapRenderer::get_render_settings() const{
  1684.     return render_settings_;
  1685. }
  1686.  
  1687. int MapRenderer::get_palette_size() const{
  1688.     return render_settings_.color_palette_.size();
  1689. }
  1690.    
  1691. svg::Color MapRenderer::get_color(int line_number) const {
  1692.     return render_settings_.color_palette_[line_number];
  1693. }
  1694.  
  1695. void MapRenderer::set_line_properties(svg::Polyline& polyline,
  1696.                                       [[maybe_unused]] int line_number) const {
  1697.     using namespace std::literals;
  1698.    
  1699.     polyline.set_stroke_color(get_color(line_number));  
  1700.     polyline.set_fill_color("none"s);
  1701.     polyline.set_stroke_width(render_settings_.line_width_);
  1702.     polyline.set_stroke_linecap(svg::StrokeLineCap::ROUND);
  1703.     polyline.set_stroke_linejoin(svg::StrokeLineJoin::ROUND);  
  1704. }
  1705.    
  1706. void MapRenderer::set_route_text_common_properties(svg::Text& text,
  1707.                                                    const std::string& name,
  1708.                                                    svg::Point position) const {
  1709.     using namespace std::literals;
  1710.  
  1711.     text.set_position(position);
  1712.     text.set_offset({render_settings_.bus_label_offset_.first,
  1713.                      render_settings_.bus_label_offset_.second});
  1714.     text.set_font_size(render_settings_.bus_label_font_size_);
  1715.     text.set_font_family("Verdana");
  1716.     text.set_font_weight("bold");
  1717.     text.set_data(name);  
  1718. }
  1719.    
  1720. void MapRenderer::set_route_text_additional_properties(svg::Text& text,
  1721.                                                        const std::string& name,
  1722.                                                        svg::Point position) const {
  1723.     set_route_text_common_properties(text,
  1724.                                      name,
  1725.                                      position);
  1726.    
  1727.     text.set_fill_color(render_settings_.underlayer_color_);
  1728.     text.set_stroke_color(render_settings_.underlayer_color_);
  1729.     text.set_stroke_width(render_settings_.underlayer_width_);
  1730.     text.set_stroke_linejoin(svg::StrokeLineJoin::ROUND);
  1731.     text.set_stroke_linecap(svg::StrokeLineCap::ROUND);
  1732. }
  1733.  
  1734. void MapRenderer::set_route_text_color_properties(svg::Text& text,
  1735.                                                   const std::string& name,
  1736.                                                   int palette,
  1737.                                                   svg::Point position) const {
  1738.     set_route_text_common_properties(text,
  1739.                                      name,
  1740.                                      position);
  1741.    
  1742.     text.set_fill_color(get_color(palette));
  1743. }
  1744.    
  1745. void MapRenderer::set_stops_circles_properties(svg::Circle& circle,
  1746.                                                svg::Point position) const {
  1747.     using namespace std::literals;
  1748.    
  1749.     circle.set_center(position);
  1750.     circle.set_radius(render_settings_.stop_radius_);
  1751.     circle.set_fill_color("white");
  1752. }
  1753.    
  1754. void MapRenderer::set_stops_text_common_properties(svg::Text& text,
  1755.                                                    const std::string& name,
  1756.                                                    svg::Point position) const {
  1757.     using namespace std::literals;
  1758.  
  1759.     text.set_position(position);
  1760.     text.set_offset({render_settings_.stop_label_offset_.first,
  1761.                      render_settings_.stop_label_offset_.second});
  1762.     text.set_font_size(render_settings_.stop_label_font_size_);
  1763.     text.set_font_family("Verdana");
  1764.     text.set_data(name);
  1765. }
  1766.  
  1767. void MapRenderer::set_stops_text_additional_properties(svg::Text& text,
  1768.                                                        const std::string& name,
  1769.                                                        svg::Point position) const {
  1770.     using namespace std::literals;
  1771.     set_stops_text_common_properties(text,
  1772.                                      name,
  1773.                                      position);
  1774.  
  1775.     text.set_fill_color(render_settings_.underlayer_color_);
  1776.     text.set_stroke_color(render_settings_.underlayer_color_);
  1777.     text.set_stroke_width(render_settings_.underlayer_width_);
  1778.     text.set_stroke_linejoin(svg::StrokeLineJoin::ROUND);
  1779.     text.set_stroke_linecap(svg::StrokeLineCap::ROUND);
  1780. }
  1781.  
  1782. void MapRenderer::set_stops_text_color_properties(svg::Text& text,
  1783.                                                   const std::string& name,
  1784.                                                   svg::Point position) const {
  1785.     using namespace std::literals;
  1786.  
  1787.     set_stops_text_common_properties(text,
  1788.                                      name,
  1789.                                      position);
  1790.     text.set_fill_color("black");
  1791. }
  1792.    
  1793. void MapRenderer::add_line(std::vector<std::pair<Bus*, int>>& buses_palette) {    
  1794.     std::vector<geo::Coordinates> stops_geo_coords;
  1795.    
  1796.     for (auto [bus, palette] : buses_palette) {
  1797.        
  1798.         for (Stop* stop : bus->stops) {
  1799.             geo::Coordinates coordinates;
  1800.             coordinates.latitude = stop->latitude;
  1801.             coordinates.longitude = stop->longitude;
  1802.            
  1803.             stops_geo_coords.push_back(coordinates);
  1804.         }
  1805.        
  1806.         svg::Polyline bus_line;
  1807.         bool bus_empty = true;  
  1808.        
  1809.         for (auto& coord : stops_geo_coords) {
  1810.             bus_empty = false;
  1811.             bus_line.add_point(sphere_projector(coord));
  1812.         }
  1813.        
  1814.         if (!bus_empty) {
  1815.             set_line_properties(bus_line,
  1816.                                 palette);
  1817.             map_svg.add(bus_line);  
  1818.         }
  1819.        
  1820.         stops_geo_coords.clear();
  1821.     }
  1822. }
  1823.    
  1824. void MapRenderer::add_buses_name(std::vector<std::pair<Bus*, int>>& buses_palette){    
  1825.     std::vector<geo::Coordinates> stops_geo_coords;
  1826.     bool bus_empty = true;
  1827.    
  1828.     for (auto [bus, palette] : buses_palette) {  
  1829.        
  1830.         for (Stop* stop : bus->stops) {
  1831.             geo::Coordinates coordinates;
  1832.             coordinates.latitude = stop->latitude;
  1833.             coordinates.longitude = stop->longitude;
  1834.            
  1835.             stops_geo_coords.push_back(coordinates);
  1836.            
  1837.             if(bus_empty) bus_empty = false;
  1838.         }
  1839.        
  1840.         svg::Text route_name_roundtrip;
  1841.         svg::Text route_title_roundtrip;
  1842.         svg::Text route_name_notroundtrip;
  1843.         svg::Text route_title_notroundtrip;
  1844.        
  1845.         if (!bus_empty) {
  1846.            
  1847.             if (bus->is_roundtrip) {
  1848.                 set_route_text_additional_properties(route_name_roundtrip,
  1849.                                                      std::string(bus->name),
  1850.                                                      sphere_projector(stops_geo_coords[0]));
  1851.                 map_svg.add(route_name_roundtrip);
  1852.                
  1853.                 set_route_text_color_properties(route_title_roundtrip,
  1854.                                                 std::string(bus->name),
  1855.                                                 palette,
  1856.                                                 sphere_projector(stops_geo_coords[0]));
  1857.                 map_svg.add(route_title_roundtrip);
  1858.                
  1859.             } else {
  1860.                 set_route_text_additional_properties(route_name_roundtrip,
  1861.                                                      std::string(bus->name),
  1862.                                                      sphere_projector(stops_geo_coords[0]));
  1863.                 map_svg.add(route_name_roundtrip);
  1864.                
  1865.                 set_route_text_color_properties(route_title_roundtrip,
  1866.                                                 std::string(bus->name),
  1867.                                                 palette,
  1868.                                                 sphere_projector(stops_geo_coords[0]));
  1869.                 map_svg.add(route_title_roundtrip);
  1870.                
  1871.                 if (stops_geo_coords[0] != stops_geo_coords[stops_geo_coords.size()/2]) {
  1872.                     set_route_text_additional_properties(route_name_notroundtrip,
  1873.                                                          std::string(bus->name),
  1874.                                                          sphere_projector(stops_geo_coords[stops_geo_coords.size()/2]));
  1875.                     map_svg.add(route_name_notroundtrip);
  1876.                    
  1877.                     set_route_text_color_properties(route_title_notroundtrip,
  1878.                                                     std::string(bus->name),
  1879.                                                     palette,
  1880.                                                     sphere_projector(stops_geo_coords[stops_geo_coords.size()/2]));
  1881.                     map_svg.add(route_title_notroundtrip);
  1882.                 }
  1883.             }
  1884.         }
  1885.        
  1886.         bus_empty = false;
  1887.         stops_geo_coords.clear();
  1888.     }
  1889. }
  1890.    
  1891. void MapRenderer::add_stops_circle(std::vector<Stop*>& stops){
  1892.     std::vector<geo::Coordinates> stops_geo_coords;      
  1893.     svg::Circle icon;
  1894.    
  1895.     for (Stop* stop_info : stops) {
  1896.        
  1897.         if (stop_info) {
  1898.             geo::Coordinates coordinates;
  1899.             coordinates.latitude = stop_info->latitude;
  1900.             coordinates.longitude = stop_info->longitude;
  1901.  
  1902.             set_stops_circles_properties(icon,
  1903.                                          sphere_projector(coordinates));
  1904.             map_svg.add(icon);  
  1905.         }
  1906.     }
  1907. }
  1908.  
  1909. void MapRenderer::add_stops_name(std::vector<Stop*>& stops){    
  1910.     std::vector<geo::Coordinates> stops_geo_coords;    
  1911.    
  1912.     svg::Text svg_stop_name;
  1913.     svg::Text svg_stop_name_title;
  1914.    
  1915.     for (Stop* stop_info : stops) {
  1916.        
  1917.         if (stop_info) {
  1918.             geo::Coordinates coordinates;
  1919.             coordinates.latitude = stop_info->latitude;
  1920.             coordinates.longitude = stop_info->longitude;            
  1921.            
  1922.             set_stops_text_additional_properties(svg_stop_name,
  1923.                                                  stop_info->name,
  1924.                                                  sphere_projector(coordinates));
  1925.             map_svg.add(svg_stop_name);
  1926.            
  1927.             set_stops_text_color_properties(svg_stop_name_title,
  1928.                                             stop_info->name,
  1929.                                             sphere_projector(coordinates));
  1930.             map_svg.add(svg_stop_name_title);
  1931.         }
  1932.     }
  1933. }
  1934.  
  1935. void MapRenderer::get_stream_map(std::ostream& stream_) {
  1936.     map_svg.render(stream_);
  1937. }
  1938.    
  1939. }//end namespace map_renderer
  1940. -----------------------------------------------------------------------
  1941. map_renderer.h
  1942. -----------------------------------------------------------------------
  1943. #pragma once
  1944. #include <iostream>
  1945. #include <optional>
  1946. #include <algorithm>
  1947. #include <cstdlib>
  1948.  
  1949. #include "domain.h"
  1950. #include "geo.h"
  1951. #include "svg.h"
  1952.  
  1953. using namespace domain;
  1954.  
  1955. namespace map_renderer {
  1956.    
  1957. inline const double EPSILON = 1e-6;
  1958.  
  1959. class SphereProjector {
  1960. public:
  1961.     SphereProjector() = default;
  1962.    
  1963.     template <typename InputIt>
  1964.     SphereProjector(InputIt points_begin,
  1965.                     InputIt points_end,
  1966.                     double max_width,
  1967.                     double max_height,
  1968.                     double padding);
  1969.  
  1970.     svg::Point operator()(geo::Coordinates coords) const;
  1971.  
  1972. private:
  1973.     double padding_;
  1974.     double min_lon_ = 0;
  1975.     double max_lat_ = 0;
  1976.     double zoom_coeff_ = 0;
  1977.    
  1978.     bool is_zero(double value);
  1979. };
  1980.    
  1981. struct RenderSettings {
  1982.     double width_;
  1983.     double height_;
  1984.     double padding_;
  1985.     double line_width_;
  1986.     double stop_radius_;
  1987.     int bus_label_font_size_;
  1988.     std::pair<double, double> bus_label_offset_;
  1989.     int stop_label_font_size_;
  1990.     std::pair<double, double> stop_label_offset_;
  1991.     svg::Color underlayer_color_;
  1992.     double underlayer_width_;
  1993.     std::vector<svg::Color> color_palette_;
  1994. };
  1995.    
  1996. class MapRenderer {
  1997.  
  1998. public:
  1999.     MapRenderer(RenderSettings& render_settings);  
  2000.    
  2001.     SphereProjector get_sphere_projector(const std::vector<geo::Coordinates>& points) const;
  2002.     void init_sphere_projector(std::vector<geo::Coordinates> points);
  2003.    
  2004.     RenderSettings get_render_settings() const;
  2005.     int get_palette_size() const;
  2006.     svg::Color get_color(int line_number) const;
  2007.        
  2008.     void set_line_properties(svg::Polyline& polyline, int line_number) const;
  2009.    
  2010.     void set_route_text_common_properties(svg::Text &text, const std::string& name, svg::Point position) const;
  2011.     void set_route_text_additional_properties(svg::Text& text, const std::string& name, svg::Point position) const;
  2012.     void set_route_text_color_properties(svg::Text& text, const std::string& name, int palette, svg::Point position) const;
  2013.    
  2014.     void set_stops_circles_properties(svg::Circle& circle, svg::Point position) const;
  2015.    
  2016.     void set_stops_text_common_properties(svg::Text& text, const std::string& name, svg::Point position) const;
  2017.     void set_stops_text_additional_properties(svg::Text& text, const std::string& name, svg::Point position) const;
  2018.     void set_stops_text_color_properties(svg::Text& text, const std::string& name, svg::Point position) const;
  2019.    
  2020.     void add_line(std::vector<std::pair<Bus*, int>>& buses_palette);
  2021.     void add_buses_name(std::vector<std::pair<Bus*, int>>& buses_palette);
  2022.     void add_stops_circle(std::vector<Stop*>& stops_name);
  2023.     void add_stops_name(std::vector<Stop*>& stops_name);    
  2024.    
  2025.     void get_stream_map(std::ostream& stream_);
  2026.    
  2027. private:
  2028.     SphereProjector sphere_projector;
  2029.     RenderSettings& render_settings_;
  2030.     svg::Document map_svg;
  2031. };
  2032.  
  2033. template <typename InputIt>
  2034.     SphereProjector::SphereProjector(InputIt points_begin,
  2035.                                      InputIt points_end,
  2036.                                      double max_width,
  2037.                                      double max_height,
  2038.                                      double padding) : padding_(padding) {
  2039.         if (points_begin == points_end) {
  2040.             return;
  2041.         }
  2042.  
  2043.         const auto [left_it,
  2044.                     right_it] = std::minmax_element(points_begin,
  2045.                                                     points_end,
  2046.             [](auto lhs, auto rhs) {
  2047.                 return lhs.longitude < rhs.longitude;
  2048.             });
  2049.        
  2050.         min_lon_ = left_it->longitude;
  2051.         const double max_lon = right_it->longitude;
  2052.  
  2053.         const auto [bottom_it,
  2054.                     top_it] = std::minmax_element(points_begin,
  2055.                                                   points_end,
  2056.             [](auto lhs, auto rhs) {
  2057.                 return lhs.latitude < rhs.latitude;
  2058.             });
  2059.        
  2060.         const double min_lat = bottom_it->latitude;
  2061.         max_lat_ = top_it->latitude;
  2062.  
  2063.         std::optional<double> width_zoom;
  2064.         if (!is_zero(max_lon - min_lon_)) {
  2065.             width_zoom = (max_width - 2 * padding)
  2066.                          / (max_lon - min_lon_);
  2067.         }
  2068.  
  2069.         std::optional<double> height_zoom;
  2070.         if (!is_zero(max_lat_ - min_lat)) {
  2071.             height_zoom = (max_height - 2 * padding)
  2072.                           / (max_lat_ - min_lat);
  2073.         }
  2074.  
  2075.         if (width_zoom && height_zoom) {
  2076.             zoom_coeff_ = std::min(*width_zoom,
  2077.                                    *height_zoom);    
  2078.         } else if (width_zoom) {
  2079.             zoom_coeff_ = *width_zoom;
  2080.            
  2081.         } else if (height_zoom) {
  2082.             zoom_coeff_ = *height_zoom;
  2083.            
  2084.         }
  2085.     }
  2086.    
  2087. }//end namespace map_renderer
  2088. -----------------------------------------------------------------------
  2089. request_handler.cpp
  2090. -----------------------------------------------------------------------
  2091. #include "request_handler.h"
  2092.  
  2093. namespace request_handler {
  2094.  
  2095. struct EdgeInfoGetter {
  2096.    
  2097.     Node operator()(const StopEdge& edge_info) {
  2098.         using namespace std::literals;
  2099.  
  2100.         return Builder{}.start_dict()
  2101.                         .key("type").value("Wait")
  2102.                         .key("stop_name").value(std::string(edge_info.name))
  2103.                         .key("time").value(edge_info.time)
  2104.                         .end_dict()
  2105.                         .build();
  2106.     }
  2107.  
  2108.     Node operator()(const BusEdge& edge_info) {
  2109.         using namespace std::literals;
  2110.    
  2111.         return Builder{}.start_dict()
  2112.                         .key("type").value("Bus")
  2113.                         .key("bus").value(std::string(edge_info.bus_name))
  2114.                         .key("span_count").value(static_cast<int>(edge_info.span_count))
  2115.                         .key("time").value(edge_info.time)
  2116.                         .end_dict()
  2117.                         .build();
  2118.     }
  2119. };
  2120.  
  2121. Node RequestHandler::execute_make_node_stop(int id_request, const StopQueryResult& stop_info) {
  2122.     Node result;
  2123.     Array buses;
  2124.     Builder builder;
  2125.  
  2126.     std::string str_not_found = "not found";
  2127.  
  2128.     if (stop_info.not_found) {
  2129.         builder.start_dict()
  2130.                .key("request_id").value(id_request)
  2131.                .key("error_message").value(str_not_found)
  2132.                .end_dict();
  2133.        
  2134.         result = builder.build();
  2135.        
  2136.     } else {
  2137.         builder.start_dict()
  2138.                .key("request_id").value(id_request)
  2139.                .key("buses").start_array();
  2140.  
  2141.         for (std::string bus_name : stop_info.buses_name) {
  2142.             builder.value(bus_name);
  2143.         }
  2144.  
  2145.         builder.end_array().end_dict();
  2146.        
  2147.         result = builder.build();
  2148.     }
  2149.  
  2150.     return result;
  2151. }
  2152.  
  2153. Node RequestHandler::execute_make_node_bus(int id_request, const BusQueryResult& bus_info) {
  2154.     Node result;
  2155.     std::string str_not_found = "not found";
  2156.  
  2157.     if (bus_info.not_found) {
  2158.         result = Builder{}.start_dict()
  2159.                           .key("request_id").value(id_request)
  2160.                           .key("error_message").value(str_not_found)
  2161.                           .end_dict()
  2162.                           .build();
  2163.     } else {
  2164.         result = Builder{}.start_dict()
  2165.                           .key("request_id").value(id_request)
  2166.                           .key("curvature").value(bus_info.curvature)
  2167.                           .key("route_length").value(bus_info.route_length)
  2168.                           .key("stop_count").value(bus_info.stops_on_route)
  2169.                           .key("unique_stop_count").value(bus_info.unique_stops)
  2170.                           .end_dict()
  2171.                           .build();
  2172.     }
  2173.  
  2174.     return result;
  2175. }
  2176.  
  2177. Node RequestHandler::execute_make_node_map(int id_request,
  2178.                                            TransportCatalogue& catalogue_,
  2179.                                            RenderSettings render_settings) {
  2180.     Node result;
  2181.  
  2182.     std::ostringstream map_stream;
  2183.     std::string map_str;
  2184.  
  2185.     MapRenderer map_catalogue(render_settings);
  2186.    
  2187.     map_catalogue.init_sphere_projector(get_stops_coordinates(catalogue_));
  2188.    
  2189.     execute_render_map(map_catalogue, catalogue_);
  2190.     map_catalogue.get_stream_map(map_stream);
  2191.     map_str = map_stream.str();
  2192.  
  2193.     result = Builder{}.start_dict()
  2194.                       .key("request_id").value(id_request)
  2195.                       .key("map").value(map_str)
  2196.                       .end_dict()
  2197.                       .build();
  2198.  
  2199.     return result;
  2200. }
  2201.  
  2202. Node RequestHandler::execute_make_node_route(StatRequest& request,
  2203.                                              TransportCatalogue& catalogue,
  2204.                                              TransportRouter& routing) {
  2205.     const auto& route_info = get_route_info(request.from, request.to, catalogue, routing);
  2206.  
  2207.     if (!route_info) {
  2208.         return Builder{}.start_dict()
  2209.                         .key("request_id").value(request.id)
  2210.                         .key("error_message").value("not found")
  2211.                         .end_dict()
  2212.                         .build();
  2213.     }
  2214.  
  2215.     Array items;
  2216.     for (const auto& item : route_info->edges) {
  2217.         items.emplace_back(std::visit(EdgeInfoGetter{}, item));
  2218.     }
  2219.  
  2220.     return Builder{}.start_dict()
  2221.                     .key("request_id").value(request.id)
  2222.                     .key("total_time").value(route_info->total_time)
  2223.                     .key("items").value(items)
  2224.                     .end_dict()
  2225.                     .build();
  2226. }
  2227.  
  2228. void RequestHandler::execute_queries(TransportCatalogue& catalogue,
  2229.                                      std::vector<StatRequest>& stat_requests,
  2230.                                      RenderSettings& render_settings,
  2231.                                      RoutingSettings& routing_settings) {
  2232.  
  2233.     std::vector<Node> result_request;
  2234.     TransportRouter routing;
  2235.  
  2236.     routing.set_routing_settings(routing_settings);
  2237.     routing.build_router(catalogue);
  2238.  
  2239.     for (StatRequest req : stat_requests) {
  2240.  
  2241.         if (req.type == "Stop") {
  2242.             result_request.push_back(execute_make_node_stop(req.id, stop_query(catalogue, req.name)));
  2243.            
  2244.         } else if (req.type == "Bus") {
  2245.             result_request.push_back(execute_make_node_bus(req.id, bus_query(catalogue, req.name)));
  2246.            
  2247.         } else if (req.type == "Map") {
  2248.             result_request.push_back(execute_make_node_map(req.id, catalogue, render_settings));
  2249.            
  2250.         }  else if (req.type == "Route") {
  2251.             result_request.push_back(execute_make_node_route(req, catalogue, routing));
  2252.         }
  2253.     }
  2254.  
  2255.     doc_out = Document{Node(result_request)};
  2256. }
  2257.  
  2258. void RequestHandler::execute_render_map(MapRenderer& map_catalogue, TransportCatalogue& catalogue) const {
  2259.     std::vector<std::pair<Bus*, int>> buses_palette;
  2260.     std::vector<Stop*> stops_sort;
  2261.     int palette_size = 0;
  2262.     int palette_index = 0;
  2263.  
  2264.     palette_size = map_catalogue.get_palette_size();
  2265.    
  2266.     if (palette_size == 0) {
  2267.         std::cout << "color palette is empty";
  2268.         return;
  2269.     }
  2270.  
  2271.     auto buses = catalogue.get_busname_to_bus();
  2272.     if (buses.size() > 0) {
  2273.  
  2274.         for (std::string_view bus_name : get_sort_buses_names(catalogue)) {
  2275.             Bus* bus_info = catalogue.get_bus(bus_name);
  2276.  
  2277.             if (bus_info) {
  2278.                 if (bus_info->stops.size() > 0) {
  2279.                     buses_palette.push_back(std::make_pair(bus_info, palette_index));
  2280.                     palette_index++;
  2281.  
  2282.                     if (palette_index == palette_size) {
  2283.                         palette_index = 0;
  2284.                     }
  2285.                 }
  2286.             }
  2287.         }
  2288.  
  2289.         if (buses_palette.size() > 0) {
  2290.             map_catalogue.add_line(buses_palette);
  2291.             map_catalogue.add_buses_name(buses_palette);
  2292.         }
  2293.     }
  2294.  
  2295.     auto stops = catalogue.get_stopname_to_stop();
  2296.     if (stops.size() > 0) {
  2297.         std::vector<std::string_view> stops_name;
  2298.  
  2299.         for (auto& [stop_name, stop] : stops) {
  2300.  
  2301.             if (stop->buses.size() > 0) {
  2302.                 stops_name.push_back(stop_name);
  2303.             }
  2304.         }
  2305.  
  2306.         std::sort(stops_name.begin(), stops_name.end());
  2307.  
  2308.         for (std::string_view stop_name : stops_name) {
  2309.             Stop* stop = catalogue.get_stop(stop_name);
  2310.             if (stop) {
  2311.                 stops_sort.push_back(stop);
  2312.             }
  2313.         }
  2314.  
  2315.         if (stops_sort.size() > 0) {
  2316.             map_catalogue.add_stops_circle(stops_sort);
  2317.             map_catalogue.add_stops_name(stops_sort);
  2318.         }
  2319.     }
  2320. }
  2321.  
  2322. std::optional<RouteInfo> RequestHandler::get_route_info(std::string_view start,
  2323.                                                         std::string_view end,
  2324.                                                         TransportCatalogue& catalogue,
  2325.                                                         TransportRouter& routing) const {
  2326.  
  2327.     return routing.get_route_info(routing.get_router_by_stop(catalogue.get_stop(start))->bus_wait_start,
  2328.                                   routing.get_router_by_stop(catalogue.get_stop(end))->bus_wait_start);
  2329. }
  2330.  
  2331. std::vector<geo::Coordinates> RequestHandler::get_stops_coordinates(TransportCatalogue& catalogue_) const {
  2332.  
  2333.     std::vector<geo::Coordinates> stops_coordinates;
  2334.     auto buses = catalogue_.get_busname_to_bus();
  2335.  
  2336.     for (auto& [busname, bus] : buses) {
  2337.        
  2338.         for (auto& stop : bus->stops) {
  2339.             geo::Coordinates coordinates;
  2340.             coordinates.latitude = stop->latitude;
  2341.             coordinates.longitude = stop->longitude;
  2342.  
  2343.             stops_coordinates.push_back(coordinates);
  2344.         }
  2345.     }
  2346.     return stops_coordinates;
  2347. }
  2348.  
  2349. std::vector<std::string_view> RequestHandler::get_sort_buses_names(TransportCatalogue& catalogue_) const {
  2350.     std::vector<std::string_view> buses_names;
  2351.  
  2352.     auto buses = catalogue_.get_busname_to_bus();
  2353.     if (buses.size() > 0) {
  2354.  
  2355.         for (auto& [busname, bus] : buses) {
  2356.             buses_names.push_back(busname);
  2357.         }
  2358.  
  2359.         std::sort(buses_names.begin(), buses_names.end());
  2360.  
  2361.         return buses_names;
  2362.  
  2363.     } else {
  2364.         return {};
  2365.     }
  2366. }
  2367.  
  2368. BusQueryResult RequestHandler::bus_query(TransportCatalogue& catalogue, std::string_view bus_name) {
  2369.     BusQueryResult bus_info;
  2370.     Bus* bus = catalogue.get_bus(bus_name);
  2371.  
  2372.     if (bus != nullptr) {
  2373.         bus_info.name = bus->name;
  2374.         bus_info.not_found = false;
  2375.         bus_info.stops_on_route = static_cast<int>(bus->stops.size());
  2376.         bus_info.unique_stops = static_cast<int>(catalogue.get_uniq_stops(bus).size());
  2377.         bus_info.route_length = static_cast<int>(bus->route_length);
  2378.         bus_info.curvature = double(catalogue.get_distance_to_bus(bus)
  2379.                                    /catalogue.get_length(bus));
  2380.     } else {
  2381.         bus_info.name = bus_name;
  2382.         bus_info.not_found = true;
  2383.     }
  2384.  
  2385.     return bus_info;
  2386. }
  2387.  
  2388. StopQueryResult RequestHandler::stop_query(TransportCatalogue& catalogue, std::string_view stop_name) {
  2389.     std::unordered_set<const Bus*> unique_buses;
  2390.     StopQueryResult stop_info;
  2391.     Stop* stop = catalogue.get_stop(stop_name);
  2392.  
  2393.     if (stop != NULL) {
  2394.  
  2395.         stop_info.name = stop->name;
  2396.         stop_info.not_found = false;
  2397.         unique_buses = catalogue.stop_get_uniq_buses(stop);
  2398.  
  2399.         if (unique_buses.size() > 0) {
  2400.            
  2401.             for (const Bus* bus : unique_buses) {
  2402.                 stop_info.buses_name.push_back(bus->name);
  2403.             }
  2404.  
  2405.             std::sort(stop_info.buses_name.begin(), stop_info.buses_name.end());
  2406.         }
  2407.        
  2408.     } else {
  2409.         stop_info.name = stop_name;
  2410.         stop_info.not_found = true;
  2411.     }
  2412.  
  2413.     return stop_info;
  2414. }
  2415.  
  2416. const Document& RequestHandler::get_document() {
  2417.     return doc_out;
  2418. }
  2419.  
  2420. }//end namespace request_handler
  2421. -----------------------------------------------------------------------
  2422. request_handler.h
  2423. -----------------------------------------------------------------------
  2424. #pragma once
  2425.  
  2426. #include "transport_catalogue.h"
  2427. #include "map_renderer.h"
  2428. #include "json_builder.h"
  2429. #include "transport_router.h"
  2430.  
  2431. using namespace transport_catalogue;
  2432. using namespace map_renderer;
  2433. using namespace transport_catalogue::detail::json;
  2434. using namespace transport_catalogue::detail::json::builder;
  2435. using namespace transport_catalogue::detail::router;
  2436.  
  2437. namespace request_handler {
  2438.  
  2439. class RequestHandler {
  2440. public:
  2441.            
  2442.     RequestHandler() = default;
  2443.    
  2444.     std::optional<RouteInfo> get_route_info(std::string_view start,
  2445.                                             std::string_view end,
  2446.                                             TransportCatalogue& catalogue,
  2447.                                             TransportRouter& routing) const;
  2448.    
  2449.     std::vector<geo::Coordinates> get_stops_coordinates(TransportCatalogue& catalogue_) const;
  2450.     std::vector<std::string_view> get_sort_buses_names(TransportCatalogue& catalogue_) const;
  2451.    
  2452.     BusQueryResult bus_query(TransportCatalogue& catalogue, std::string_view str);
  2453.     StopQueryResult stop_query(TransportCatalogue& catalogue, std::string_view stop_name);
  2454.    
  2455.     Node execute_make_node_stop(int id_request, const StopQueryResult& query_result);
  2456.     Node execute_make_node_bus(int id_request, const BusQueryResult& query_result);
  2457.     Node execute_make_node_map(int id_request, TransportCatalogue& catalogue, RenderSettings render_settings);
  2458.     Node execute_make_node_route(StatRequest& request, TransportCatalogue& catalogue, TransportRouter& routing);
  2459.    
  2460.     void execute_queries(TransportCatalogue& catalogue,
  2461.                          std::vector<StatRequest>& stat_requests,
  2462.                          RenderSettings& render_settings,
  2463.                          RoutingSettings& route_settings);
  2464.    
  2465.     void execute_render_map(MapRenderer& map_catalogue, TransportCatalogue& catalogue_) const;
  2466.        
  2467.     const Document& get_document();
  2468.  
  2469. private:
  2470.     Document doc_out;
  2471. };
  2472.    
  2473. }//end namespace request_handler
  2474. -----------------------------------------------------------------------
  2475. svg.cpp
  2476. -----------------------------------------------------------------------
  2477. #include "svg.h"
  2478.  
  2479. namespace svg {
  2480.  
  2481. using namespace std::literals;
  2482.  
  2483. Rgb::Rgb(uint8_t red, uint8_t green, uint8_t blue) : red_(red)
  2484.                                                    , green_(green)
  2485.                                                    , blue_(blue) {}  
  2486.    
  2487. Rgba::Rgba(uint8_t red, uint8_t green, uint8_t blue, double opacity) : red_(red)
  2488.                                                                      , green_(green)
  2489.                                                                      , blue_(blue)
  2490.                                                                      , opacity_(opacity) {}
  2491.    
  2492. inline void print_color(std::ostream& out, Rgb& rgb) {
  2493.     out << "rgb("sv << static_cast<short>(rgb.red_) << ","sv
  2494.                     << static_cast<short>(rgb.green_) << ","sv
  2495.                     << static_cast<short>(rgb.blue_) << ")"sv;
  2496. }
  2497.    
  2498. inline void print_color(std::ostream& out, Rgba& rgba) {
  2499.     out << "rgba("sv << static_cast<short>(rgba.red_) << ","sv
  2500.                      << static_cast<short>(rgba.green_) << ","sv
  2501.                      << static_cast<short>(rgba.blue_) << ","sv
  2502.                      << (rgba.opacity_) << ")"sv;
  2503. }
  2504.    
  2505. inline void print_color(std::ostream& out, std::monostate) {
  2506.     out << "none"sv;
  2507. }
  2508.  
  2509. inline void print_color(std::ostream& out, std::string& color) {
  2510.     out << color;
  2511. }
  2512.    
  2513. std::ostream& operator<<(std::ostream& out, const Color& color) {
  2514.     std::visit([&out](auto value) {
  2515.             print_color(out, value);
  2516.     }, color);
  2517.    
  2518.     return out;
  2519. }
  2520.    
  2521. RenderContext::RenderContext(std::ostream& out) : out_(out) {}
  2522.    
  2523. RenderContext RenderContext::indented() const {
  2524.         return {out_,
  2525.                 indent_step_,
  2526.                 indent_ + indent_step_};
  2527. }
  2528.    
  2529. void RenderContext::render_indent() const {
  2530.         for (int i = 0; i < indent_; ++i) {
  2531.             out_.put(' ');
  2532.         }
  2533. }
  2534.  
  2535. void Object::render(const RenderContext& context) const {
  2536.     context.render_indent();
  2537.     render_object(context);
  2538.     context.out_ << std::endl;
  2539. }
  2540.  
  2541. Circle& Circle::set_center(Point center)  {
  2542.     center_ = center;
  2543.     return *this;
  2544. }
  2545.  
  2546. Circle& Circle::set_radius(double radius)  {
  2547.     radius_ = radius;
  2548.     return *this;
  2549. }
  2550.  
  2551. void Circle::render_object(const RenderContext& context) const {
  2552.     std::ostream& out = context.out_;
  2553.  
  2554.     out << "<circle cx=\""sv << center_.x
  2555.         << "\" cy=\""sv << center_.y << "\" "sv;
  2556.     out << "r=\""sv << radius_ << "\" "sv;
  2557.    
  2558.     render_attrs(context.out_);
  2559.     out << "/>"sv;
  2560. }
  2561.    
  2562. Polyline& Polyline::add_point(Point point) {
  2563.     points_.emplace_back(point);
  2564.     return *this;
  2565. }
  2566.  
  2567. void Polyline::render_object(const RenderContext& context) const {
  2568.    
  2569.     std::ostream& out = context.out_;
  2570.     out << "<polyline points=\"";
  2571.    
  2572.     for (size_t i = 0; i < points_.size(); ++i) {
  2573.         out << points_[i].x << ","sv << points_[i].y;
  2574.  
  2575.         if (i+1 != points_.size()) {
  2576.             out << " "sv;
  2577.         }
  2578.     }
  2579.     out << "\" ";
  2580.     render_attrs(context.out_);
  2581.     out << "/>";
  2582. }
  2583.    
  2584. Text& Text::set_position(Point pos) {
  2585.     position_ = pos;
  2586.     return *this;
  2587. }
  2588.  
  2589. Text& Text::set_offset(Point offset) {
  2590.     offset_ = offset;
  2591.     return *this;
  2592. }
  2593.    
  2594. Text& Text::set_font_size(uint32_t size) {
  2595.     font_size_ = size;
  2596.     return *this;
  2597. }
  2598.  
  2599. Text& Text::set_font_family(std::string font_family) {
  2600.     font_family_ = std::move(font_family);
  2601.     return *this;
  2602. }
  2603.  
  2604. Text& Text::set_font_weight(std::string font_weight) {
  2605.     font_weight_ = std::move(font_weight);
  2606.     return *this;
  2607. }
  2608.  
  2609. Text& Text::set_data(std::string data) {
  2610.     data_ = std::move(data);
  2611.     return *this;
  2612. }
  2613.  
  2614. std::string Text::delete_spaces(const std::string& str) {
  2615.     if (str.empty()) {
  2616.         return {};
  2617.     } else {
  2618.        
  2619.         auto left = str.find_first_not_of(' ');
  2620.         auto right = str.find_last_not_of(' ');
  2621.         return str.substr(left, right - left + 1);  
  2622.     }
  2623. }
  2624.  
  2625. std::string Text::uniq_symbols(const std::string& str) {
  2626.    
  2627.     std::string out;
  2628.  
  2629.     for (char ch : str) {
  2630.        
  2631.         if (ch == '"') {
  2632.             out += "&quot;"sv;
  2633.             continue;
  2634.            
  2635.         } else if (ch == '`' || ch == '\'') {
  2636.             out += "&apos;"sv;
  2637.             continue;
  2638.            
  2639.         } else if (ch == '<') {
  2640.             out += "&lt;"sv;
  2641.             continue;
  2642.            
  2643.         } else if (ch == '>') {
  2644.             out += "&gt;"sv;
  2645.             continue;
  2646.            
  2647.         } else if (ch == '&') {
  2648.             out += "&amp;"sv;
  2649.             continue;
  2650.            
  2651.         } else {
  2652.            
  2653.         }
  2654.        
  2655.         out += ch;
  2656.     }
  2657.  
  2658.     return out;
  2659. }
  2660.  
  2661. void Text::render_object(const RenderContext& context) const {
  2662.    
  2663.     std::ostream& out = context.out_;
  2664.     out << "<text ";
  2665.     render_attrs(context.out_);
  2666.     out << "x=\""
  2667.         << position_.x << "\" y=\""
  2668.         << position_.y << "\" "
  2669.         << "dx=\""
  2670.         << offset_.x << "\" dy=\""
  2671.         << offset_.y << "\" "
  2672.         << "font-size=\""
  2673.         << font_size_ << "\" ";
  2674.  
  2675.     if (!font_family_.empty()) {
  2676.         out << "font-family=\"" << font_family_ << "\" ";
  2677.     }
  2678.  
  2679.     if (!font_weight_.empty()) {
  2680.         out << "font-weight=\"" << font_weight_ << "\"";
  2681.     }
  2682.  
  2683.     out << ">"sv << delete_spaces(uniq_symbols(data_)) << "</text>"sv;
  2684.  
  2685. }
  2686.  
  2687. void Document::render(std::ostream& out) const{
  2688.     int indent = 2;
  2689.     int indent_step = 2;
  2690.  
  2691.     RenderContext context(out, indent_step, indent);
  2692.  
  2693.     const std::string_view xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"sv;
  2694.     const std::string_view svg = "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">"sv;
  2695.  
  2696.     out << xml << "\n"sv << svg << "\n"sv;
  2697.  
  2698.     for (const auto& object : objects_) {
  2699.         object->render(context);
  2700.     }
  2701.    
  2702.     out << "</svg>"sv;
  2703. }
  2704.  
  2705. }//end namespace svg
  2706. -----------------------------------------------------------------------
  2707. svg.h
  2708. -----------------------------------------------------------------------
  2709. #pragma once
  2710. #define _USE_MATH_DEFINES
  2711.  
  2712. #include <cstdint>
  2713. #include <iostream>
  2714. #include <memory>
  2715. #include <string>
  2716. #include <vector>
  2717. #include <optional>
  2718. #include <cmath>
  2719. #include <variant>
  2720.  
  2721. namespace svg {
  2722.  
  2723. class Rgb {
  2724. public:
  2725.     Rgb() = default;
  2726.     Rgb(uint8_t red, uint8_t green, uint8_t blue);
  2727.    
  2728.     uint8_t red_ = 0;
  2729.     uint8_t green_ = 0;
  2730.     uint8_t blue_ = 0;
  2731. };
  2732. inline void print_color(std::ostream& out, Rgb& rgb);
  2733.  
  2734. class Rgba {
  2735. public:
  2736.     Rgba() = default;
  2737.     Rgba(uint8_t red, uint8_t green, uint8_t blue, double opacity);
  2738.    
  2739.     uint8_t red_ = 0;
  2740.     uint8_t green_ = 0;
  2741.     uint8_t blue_ = 0;
  2742.     double opacity_ = 1.0;
  2743. };  
  2744. inline void print_color(std::ostream& out, Rgba& rgba);
  2745.  
  2746. using Color = std::variant<std::monostate, std::string, Rgb, Rgba>;
  2747. inline const Color NoneColor{"none"};  
  2748.    
  2749. inline void print_color(std::ostream& out, std::monostate);
  2750. inline void print_color(std::ostream& out, std::string& color);
  2751. std::ostream& operator<<(std::ostream& out, const Color& color);
  2752.    
  2753. enum class StrokeLineCap {
  2754.     BUTT,
  2755.     ROUND,
  2756.     SQUARE,
  2757. };
  2758.    
  2759. inline std::ostream &operator<<(std::ostream &out, StrokeLineCap stroke_line_cap) {
  2760.     using namespace std::literals;
  2761.    
  2762.     if (stroke_line_cap == StrokeLineCap::BUTT) {
  2763.         out << "butt"sv;
  2764.     } else if (stroke_line_cap == StrokeLineCap::ROUND) {
  2765.         out << "round"sv;
  2766.     } else if (stroke_line_cap == StrokeLineCap::SQUARE) {
  2767.         out << "square"sv;
  2768.     }
  2769.     return out;
  2770. }
  2771.  
  2772. enum class StrokeLineJoin {
  2773.     ARCS,
  2774.     BEVEL,
  2775.     MITER,
  2776.     MITER_CLIP,
  2777.     ROUND,
  2778. };
  2779.    
  2780. inline std::ostream &operator<<(std::ostream &out, StrokeLineJoin stroke_line_join) {
  2781.     using namespace std::literals;
  2782.    
  2783.     if (stroke_line_join == StrokeLineJoin::ARCS) {
  2784.         out << "arcs"sv;
  2785.     } else if (stroke_line_join == StrokeLineJoin::BEVEL) {
  2786.         out << "bevel"sv;
  2787.     } else if (stroke_line_join == StrokeLineJoin::MITER) {
  2788.         out << "miter"sv;
  2789.     } else if (stroke_line_join == StrokeLineJoin::MITER_CLIP) {
  2790.         out << "miter-clip"sv;
  2791.     } else if (stroke_line_join == StrokeLineJoin::ROUND) {
  2792.         out << "round"sv;
  2793.     }
  2794.     return out;
  2795. }
  2796.    
  2797. template<typename Owner>
  2798. class PathProps {
  2799. public:
  2800.     Owner& set_fill_color(const Color& color) {
  2801.         fill_color_ = std::move(color);
  2802.         return as_owner();
  2803.     }
  2804.  
  2805.     Owner& set_stroke_color(const Color& color) {
  2806.         stroke_color_ = std::move(color);
  2807.         return as_owner();
  2808.     }
  2809.  
  2810.     Owner& set_stroke_width(double width) {
  2811.         stroke_width_ = width;
  2812.         return as_owner();
  2813.     }
  2814.  
  2815.     Owner& set_stroke_linecap(StrokeLineCap line_cap) {
  2816.         stroke_line_cap_ = line_cap;
  2817.         return as_owner();
  2818.     }
  2819.  
  2820.     Owner& set_stroke_linejoin(StrokeLineJoin line_join) {
  2821.         stroke_line_join_ = line_join;
  2822.         return as_owner();
  2823.     }
  2824.  
  2825. protected:
  2826.     ~PathProps() = default;
  2827.  
  2828.     void render_attrs(std::ostream &out) const {
  2829.         using namespace std::literals;
  2830.  
  2831.         if (fill_color_ != std::nullopt) {
  2832.             out << "fill=\""sv << *fill_color_ << "\" "sv;
  2833.         }
  2834.         if (stroke_color_ != std::nullopt) {
  2835.             out << "stroke=\""sv << *stroke_color_ << "\" "sv;
  2836.         }
  2837.         if (stroke_width_ != std::nullopt) {
  2838.             out << "stroke-width=\""sv << *stroke_width_ << "\" "sv;
  2839.         }
  2840.         if (stroke_line_cap_ != std::nullopt) {
  2841.             out << "stroke-linecap=\""sv << *stroke_line_cap_ << "\" "sv;
  2842.         }
  2843.         if (stroke_line_join_ != std::nullopt) {
  2844.             out << "stroke-linejoin=\""sv << *stroke_line_join_ << "\" "sv;
  2845.         }
  2846.     }
  2847.    
  2848. private:
  2849.     std::optional<Color> fill_color_;
  2850.     std::optional<Color> stroke_color_;
  2851.     std::optional<double> stroke_width_;
  2852.     std::optional<StrokeLineCap> stroke_line_cap_;
  2853.     std::optional<StrokeLineJoin> stroke_line_join_;
  2854.    
  2855.     Owner& as_owner() {
  2856.         return static_cast<Owner&>(*this);
  2857.     }
  2858. };
  2859.    
  2860. struct Point {
  2861.     Point() = default;
  2862.     Point(double x, double y) : x(x)
  2863.                               , y(y) {}
  2864.     double x = 0;
  2865.     double y = 0;
  2866. };
  2867.  
  2868. struct RenderContext {
  2869.     RenderContext(std::ostream& out);
  2870.     RenderContext(std::ostream& out, int indent_step, int indent = 0) : out_(out)
  2871.                                                                       , indent_step_(indent_step)
  2872.                                                                       , indent_(indent) {}
  2873.     RenderContext indented() const;
  2874.     void render_indent() const;
  2875.  
  2876.     std::ostream& out_;
  2877.     int indent_step_ = 0;
  2878.     int indent_ = 0;
  2879. };
  2880.  
  2881. class Object {
  2882. public:
  2883.     void render(const RenderContext& context) const;
  2884.     virtual ~Object() = default;
  2885.  
  2886. private:
  2887.     virtual void render_object(const RenderContext& context) const = 0;
  2888. };
  2889.  
  2890. class Circle final : public Object, public PathProps<Circle> {
  2891. public:
  2892.     Circle& set_center(Point center);
  2893.     Circle& set_radius(double radius);
  2894.  
  2895. private:
  2896.     Point center_;
  2897.     double radius_ = 1.0;
  2898.    
  2899.     void render_object(const RenderContext& context) const override;
  2900. };
  2901.  
  2902. class Polyline final : public Object, public PathProps<Polyline> {
  2903. public:
  2904.     Polyline& add_point(Point point);
  2905.    
  2906. private:
  2907.     std::vector<Point> points_;
  2908.     void render_object(const RenderContext& context) const override;
  2909. };
  2910.  
  2911. class Text final : public Object, public PathProps<Text> {
  2912. public:
  2913.     Text& set_position(Point pos);
  2914.     Text& set_offset(Point offset);
  2915.     Text& set_font_size(uint32_t size);
  2916.     Text& set_font_family(std::string font_family);
  2917.     Text& set_font_weight(std::string font_weight);
  2918.     Text& set_data(std::string data);
  2919.  
  2920. private:
  2921.     Point position_;
  2922.     Point offset_;
  2923.     std::string font_family_;
  2924.     std::string font_weight_;
  2925.     uint32_t font_size_ = 1;
  2926.     std::string data_;
  2927.      
  2928.     static std::string delete_spaces(const std::string& str);
  2929.     static std::string uniq_symbols(const std::string& str);
  2930.    
  2931.     void render_object(const RenderContext& context) const override;
  2932. };
  2933.  
  2934. class ObjectContainer {
  2935. public:
  2936.     virtual ~ObjectContainer() = default;
  2937.  
  2938.     template<typename Obj>
  2939.     void add(Obj obj);
  2940.  
  2941.     virtual void add_ptr(std::unique_ptr<Object> &&) = 0;
  2942.  
  2943. protected:
  2944.     std::vector<std::unique_ptr<Object>> objects_;
  2945. };
  2946.    
  2947. template<typename Obj>
  2948. void ObjectContainer::add(Obj obj) {
  2949.     objects_.emplace_back(std::make_unique<Obj>(std::move(obj)));
  2950. }
  2951.    
  2952. class Drawable {
  2953. public:
  2954.     virtual void draw(ObjectContainer& container) const = 0;
  2955.     virtual ~Drawable() = default;
  2956. };
  2957.    
  2958. class Document : public ObjectContainer {
  2959. public:
  2960.    
  2961.     void add_ptr(std::unique_ptr<Object>&& obj) override {
  2962.         objects_.emplace_back(std::move(obj));
  2963.     }
  2964.    
  2965.     void render(std::ostream& out) const;
  2966.    
  2967. };
  2968.    
  2969. }//end namespace svg
  2970. -----------------------------------------------------------------------
  2971. transport_catalogue.cpp
  2972. -----------------------------------------------------------------------
  2973. #include "transport_catalogue.h"
  2974. #include <execution>
  2975.  
  2976. namespace transport_catalogue {  
  2977.    
  2978. void TransportCatalogue::add_stop(Stop&& stop) {
  2979.     stops.push_back(std::move(stop));
  2980.     Stop* stop_buf = &stops.back();
  2981.     stopname_to_stop.insert(transport_catalogue::StopMap::value_type(stop_buf->name, stop_buf));
  2982. }
  2983.  
  2984. void TransportCatalogue::add_bus(Bus&& bus) {
  2985.     Bus* bus_buf;
  2986.    
  2987.     buses.push_back(std::move(bus));
  2988.     bus_buf = &buses.back();
  2989.     busname_to_bus.insert(BusMap::value_type(bus_buf->name, bus_buf));
  2990.  
  2991.     for (Stop* stop : bus_buf->stops) {
  2992.          stop->buses.push_back(bus_buf);
  2993.     }
  2994.    
  2995.     bus_buf->route_length = get_distance_to_bus(bus_buf);
  2996. }
  2997.  
  2998. void TransportCatalogue::add_distance(const std::vector<Distance>& distances) {
  2999.    
  3000.     for (auto distance : distances) {
  3001.         auto dist_pair = std::make_pair(distance.start, distance.end);
  3002.         distance_to_stop.insert(DistanceMap::value_type(dist_pair, distance.distance));
  3003.     }
  3004. }
  3005.  
  3006. Bus* TransportCatalogue::get_bus(std::string_view bus_name) {
  3007.     if (busname_to_bus.empty()) {
  3008.         return nullptr;
  3009.     }
  3010.    
  3011.     if (busname_to_bus.count(bus_name)) {
  3012.         return busname_to_bus.at(bus_name);
  3013.     } else {
  3014.         return nullptr;
  3015.     }
  3016. }
  3017.    
  3018. Stop* TransportCatalogue::get_stop(std::string_view stop_name) {
  3019.     if (stopname_to_stop.empty()) {
  3020.         return nullptr;
  3021.     }
  3022.    
  3023.     if (stopname_to_stop.count(stop_name)) {
  3024.         return stopname_to_stop.at(stop_name);
  3025.     } else {
  3026.         return nullptr;
  3027.     }
  3028. }
  3029.    
  3030. BusMap TransportCatalogue::get_busname_to_bus() const {
  3031.     return busname_to_bus;
  3032. }
  3033.    
  3034. StopMap TransportCatalogue::get_stopname_to_stop() const {
  3035.     return stopname_to_stop;
  3036. }
  3037.  
  3038. std::unordered_set<const Stop*> TransportCatalogue::get_uniq_stops(Bus* bus) {
  3039.     std::unordered_set<const Stop*> unique_stops;  
  3040.     unique_stops.insert(bus->stops.begin(), bus->stops.end());
  3041.    
  3042.     return unique_stops;
  3043. }
  3044.    
  3045. double TransportCatalogue::get_length(Bus* bus) {
  3046.     return transform_reduce(next(bus->stops.begin()),
  3047.                             bus->stops.end(),
  3048.                             bus->stops.begin(),
  3049.                             0.0,
  3050.                             std::plus<>{},
  3051.                             [](const Stop* lhs, const Stop* rhs) {
  3052.                                 return geo::compute_distance({(*lhs).latitude,
  3053.                                                               (*lhs).longitude}, {(*rhs).latitude,
  3054.                                                                                   (*rhs).longitude});
  3055.                             });
  3056. }
  3057.  
  3058. std::unordered_set<const Bus*> TransportCatalogue::stop_get_uniq_buses(Stop* stop){    
  3059.     std::unordered_set<const Bus*> unique_stops;          
  3060.     unique_stops.insert(stop->buses.begin(), stop->buses.end());  
  3061.    
  3062.     return unique_stops;
  3063. }
  3064.  
  3065. size_t TransportCatalogue::get_distance_stop(const Stop* begin, const Stop* finish) const {
  3066.    
  3067.     if (distance_to_stop.empty()) {
  3068.         return 0;
  3069.        
  3070.     } else {
  3071.        
  3072.         if (const auto& stop_ptr_pair = std::make_pair(begin, finish);
  3073.             distance_to_stop.count(stop_ptr_pair)) {
  3074.            
  3075.             return distance_to_stop.at(stop_ptr_pair);
  3076.  
  3077.         } else if (const auto& stop_ptr_pair = std::make_pair(finish, begin);
  3078.                    distance_to_stop.count(stop_ptr_pair)) {
  3079.            
  3080.             return distance_to_stop.at(stop_ptr_pair);
  3081.            
  3082.         } else {
  3083.            
  3084.             return 0;
  3085.         }
  3086.     }
  3087. }
  3088.  
  3089. size_t TransportCatalogue::get_distance_to_bus(Bus* bus) {
  3090.     size_t distance = 0;
  3091.     auto stops_size = bus->stops.size() - 1;
  3092.    
  3093.     for (int i = 0; i < static_cast<int>(stops_size); i++) {
  3094.         distance += get_distance_stop(bus->stops[i], bus->stops[i+1]);
  3095.     }
  3096.    
  3097.     return distance;
  3098. }
  3099.    
  3100. }//end namespace transport_catalogue
  3101. -----------------------------------------------------------------------
  3102. transport_catalogue.h
  3103. -----------------------------------------------------------------------
  3104. #pragma once
  3105. #include <deque>
  3106. #include <string>
  3107. #include <vector>
  3108. #include <iomanip>
  3109. #include <iostream>
  3110. #include <unordered_set>
  3111. #include <unordered_map>
  3112.  
  3113. #include "domain.h"
  3114.  
  3115. using namespace domain;
  3116.  
  3117. namespace transport_catalogue {  
  3118.  
  3119. struct DistanceHasher {
  3120.     std::hash<const void*> hasher;
  3121.    
  3122.     std::size_t operator()(const std::pair<const Stop*, const Stop*> pair_stops) const noexcept {
  3123.         auto hash_1 = static_cast<const void*>(pair_stops.first);
  3124.         auto hash_2 = static_cast<const void*>(pair_stops.second);
  3125.         return hasher(hash_1) * 17 + hasher(hash_2);
  3126.     }  
  3127. };
  3128.    
  3129. typedef  std::unordered_map<std::string_view, Stop*> StopMap;
  3130. typedef  std::unordered_map<std::string_view, Bus*> BusMap;
  3131. typedef  std::unordered_map<std::pair<const Stop*, const  Stop*>, int, DistanceHasher> DistanceMap;
  3132.  
  3133. class TransportCatalogue {
  3134. public:      
  3135.     void add_bus(Bus&& bus);
  3136.     void add_stop(Stop&& stop);
  3137.     void add_distance(const std::vector<Distance>& distances);
  3138.    
  3139.     Bus* get_bus(std::string_view bus_name);
  3140.     Stop* get_stop(std::string_view stop_name);
  3141.     BusMap get_busname_to_bus() const;
  3142.     StopMap get_stopname_to_stop() const;
  3143.    
  3144.     std::unordered_set<const Bus*> stop_get_uniq_buses(Stop* stop);    
  3145.     std::unordered_set<const Stop*> get_uniq_stops(Bus* bus);
  3146.     double get_length(Bus* bus);
  3147.    
  3148.     size_t get_distance_stop(const Stop* start, const Stop* finish) const;
  3149.     size_t get_distance_to_bus(Bus* bus);
  3150.    
  3151. private:    
  3152.     std::deque<Stop> stops;
  3153.     StopMap stopname_to_stop;
  3154.    
  3155.     std::deque<Bus> buses;
  3156.     BusMap busname_to_bus;
  3157.    
  3158.     DistanceMap distance_to_stop;
  3159.    
  3160. };
  3161.    
  3162. }//end namespace transport_catalogue
  3163. -----------------------------------------------------------------------
  3164. transport_router.cpp
  3165. -----------------------------------------------------------------------
  3166. #include "transport_router.h"
  3167.  
  3168. namespace transport_catalogue {
  3169. namespace detail {
  3170. namespace router {
  3171.  
  3172. void TransportRouter::set_routing_settings(RoutingSettings routing_settings) {routing_settings_ = std::move(routing_settings);}
  3173. const RoutingSettings& TransportRouter::get_routing_settings() const {return routing_settings_;}
  3174.  
  3175. void TransportRouter::build_router(TransportCatalogue& transport_catalogue) {
  3176.     set_graph(transport_catalogue);
  3177.     router_ = std::make_unique<Router<double>>(*graph_);
  3178.     router_->build();
  3179. }
  3180.  
  3181. const DirectedWeightedGraph<double>& TransportRouter::get_graph() const {return *graph_;}
  3182. const Router<double>& TransportRouter::get_router() const {return *router_;}
  3183. const std::variant<StopEdge, BusEdge>& TransportRouter::get_edge(EdgeId id) const {return edge_id_to_edge_.at(id);}
  3184.  
  3185. std::optional<RouterByStop> TransportRouter::get_router_by_stop(Stop* stop) const {
  3186.     if (stop_to_router_.count(stop)) {
  3187.         return stop_to_router_.at(stop);
  3188.     } else {
  3189.         return std::nullopt;
  3190.     }
  3191. }
  3192.  
  3193. std::optional<RouteInfo> TransportRouter::get_route_info(VertexId start, graph::VertexId end) const {
  3194.     const auto& route_info = router_->build_route(start, end);
  3195.     if (route_info) {
  3196.         RouteInfo result;
  3197.         result.total_time = route_info->weight;
  3198.        
  3199.         for (const auto edge : route_info->edges) {
  3200.             result.edges.emplace_back(get_edge(edge));
  3201.         }
  3202.        
  3203.         return result;
  3204.        
  3205.     } else {
  3206.         return std::nullopt;
  3207.     }
  3208. }  
  3209.    
  3210. const std::unordered_map<Stop*, RouterByStop>& TransportRouter::get_stop_to_vertex() const {return stop_to_router_;}
  3211. const std::unordered_map<EdgeId, std::variant<StopEdge, BusEdge>>& TransportRouter::get_edge_id_to_edge() const {return edge_id_to_edge_;}
  3212.    
  3213. std::deque<Stop*> TransportRouter::get_stops_ptr(TransportCatalogue& transport_catalogue) {
  3214.     std::deque<Stop*> stops_ptr;  
  3215.    
  3216.     for (auto [_, stop_ptr] : transport_catalogue.get_stopname_to_stop()) {
  3217.         stops_ptr.push_back(stop_ptr);
  3218.     }
  3219.  
  3220.     return stops_ptr;
  3221. }
  3222.    
  3223. std::deque<Bus*> TransportRouter::get_bus_ptr(TransportCatalogue& transport_catalogue) {
  3224.     std::deque<Bus*> buses_ptr;  
  3225.    
  3226.     for (auto [_, bus_ptr] : transport_catalogue.get_busname_to_bus()) {
  3227.         buses_ptr.push_back(bus_ptr);
  3228.     }
  3229.  
  3230.     return buses_ptr;
  3231. }
  3232.    
  3233. void TransportRouter::set_stops(const std::deque<Stop*>& stops) {
  3234.     size_t i = 0;
  3235.    
  3236.     for (const auto stop : stops) {
  3237.         VertexId first = i++;
  3238.         VertexId second = i++;
  3239.        
  3240.         stop_to_router_[stop] = RouterByStop{first, second};
  3241.     }
  3242. }
  3243.  
  3244. void TransportRouter::add_edge_to_stop() {  
  3245.    
  3246.     for (const auto [stop, num] : stop_to_router_) {
  3247.         EdgeId id = graph_->add_edge(Edge<double>{num.bus_wait_start,
  3248.                                                  num.bus_wait_end,
  3249.                                                  routing_settings_.bus_wait_time});
  3250.        
  3251.         edge_id_to_edge_[id] = StopEdge{stop->name, routing_settings_.bus_wait_time};
  3252.     }
  3253. }
  3254.  
  3255. void TransportRouter::add_edge_to_bus(TransportCatalogue& transport_catalogue) {
  3256.  
  3257.     for (auto bus : get_bus_ptr(transport_catalogue)) {        
  3258.         parse_bus_to_edges(bus->stops.begin(),
  3259.                            bus->stops.end(),
  3260.                            transport_catalogue,
  3261.                            bus);
  3262.        
  3263.         if (!bus->is_roundtrip) {
  3264.             parse_bus_to_edges(bus->stops.rbegin(),
  3265.                                bus->stops.rend(),
  3266.                                transport_catalogue,
  3267.                                bus);
  3268.         }
  3269.     }
  3270. }
  3271.  
  3272. void TransportRouter::set_graph(TransportCatalogue& transport_catalogue) {
  3273.     const auto stops_ptr_size = get_stops_ptr(transport_catalogue).size();  
  3274.    
  3275.     graph_ = std::make_unique<DirectedWeightedGraph<double>>(2 * stops_ptr_size);    
  3276.    
  3277.     set_stops(get_stops_ptr(transport_catalogue));    
  3278.     add_edge_to_stop();
  3279.     add_edge_to_bus(transport_catalogue);
  3280. }
  3281.  
  3282. Edge<double> TransportRouter::make_edge_to_bus(Stop* start, Stop* end, const double distance) const {
  3283.     Edge<double> result;
  3284.    
  3285.     result.from = stop_to_router_.at(start).bus_wait_end;
  3286.     result.to = stop_to_router_.at(end).bus_wait_start;
  3287.     result.weight = distance * 1.0 / (routing_settings_.bus_velocity * KILOMETER / HOUR);
  3288.    
  3289.     return result;
  3290. }
  3291.  
  3292. }//end namespace router
  3293. }//end namespace detail
  3294. }//end namespace transport_catalogue
  3295. -----------------------------------------------------------------------
  3296. transport_router.h
  3297. -----------------------------------------------------------------------
  3298. #pragma once
  3299.  
  3300. #include "transport_catalogue.h"
  3301. #include "router.h"
  3302. #include "domain.h"
  3303.  
  3304. #include <deque>
  3305. #include <unordered_map>
  3306. #include <iostream>
  3307.  
  3308. namespace transport_catalogue {
  3309. namespace detail {
  3310. namespace router {
  3311.  
  3312. using namespace domain;
  3313. using namespace graph;
  3314.    
  3315. static const uint16_t KILOMETER = 1000;
  3316. static const uint16_t HOUR = 60;    
  3317.  
  3318. class TransportRouter {
  3319. public:
  3320.     void set_routing_settings(RoutingSettings routing_settings);
  3321.     const RoutingSettings& get_routing_settings() const;
  3322.  
  3323.     void build_router(TransportCatalogue& transport_catalogue);
  3324.  
  3325.     const DirectedWeightedGraph<double>& get_graph() const;
  3326.     const Router<double>& get_router() const;
  3327.     const std::variant<StopEdge, BusEdge>& get_edge(EdgeId id) const;
  3328.    
  3329.     std::optional<RouterByStop> get_router_by_stop(Stop* stop) const;
  3330.     std::optional<RouteInfo> get_route_info(VertexId start, VertexId end) const;
  3331.  
  3332.     const std::unordered_map<Stop*, RouterByStop>& get_stop_to_vertex() const;
  3333.     const std::unordered_map<EdgeId, std::variant<StopEdge, BusEdge>>& get_edge_id_to_edge() const;
  3334.    
  3335.     std::deque<Stop*> get_stops_ptr(TransportCatalogue& transport_catalogue);
  3336.     std::deque<Bus*> get_bus_ptr(TransportCatalogue& transport_catalogue);
  3337.        
  3338.     void add_edge_to_stop();
  3339.     void add_edge_to_bus(TransportCatalogue& transport_catalogue);
  3340.    
  3341.     void set_stops(const std::deque<Stop*>& stops);
  3342.     void set_graph(TransportCatalogue& transport_catalogue);
  3343.  
  3344.     Edge<double> make_edge_to_bus(Stop* start, Stop* end, const double distance) const;
  3345.  
  3346.     template <typename Iterator>
  3347.     void parse_bus_to_edges(Iterator first,
  3348.                             Iterator last,
  3349.                             const TransportCatalogue& transport_catalogue,
  3350.                             const Bus* bus);
  3351.    
  3352. private:    
  3353.     std::unordered_map<Stop*, RouterByStop> stop_to_router_;
  3354.     std::unordered_map<EdgeId, std::variant<StopEdge, BusEdge>> edge_id_to_edge_;
  3355.    
  3356.     std::unique_ptr<DirectedWeightedGraph<double>> graph_;
  3357.     std::unique_ptr<Router<double>> router_;
  3358.    
  3359.     RoutingSettings routing_settings_;
  3360. };
  3361.  
  3362. template <typename Iterator>
  3363. void TransportRouter::parse_bus_to_edges(Iterator first,
  3364.                                          Iterator last,
  3365.                                          const TransportCatalogue& transport_catalogue,
  3366.                                          const Bus* bus) {
  3367.    
  3368.     for (auto it = first; it != last; ++it) {
  3369.         size_t distance = 0;
  3370.         size_t span = 0;
  3371.  
  3372.         for (auto it2 = std::next(it); it2 != last; ++it2) {
  3373.             distance += transport_catalogue.get_distance_stop(*prev(it2), *it2);
  3374.             ++span;
  3375.  
  3376.             EdgeId id = graph_->add_edge(make_edge_to_bus(*it, *it2, distance));
  3377.            
  3378.             edge_id_to_edge_[id] = BusEdge{bus->name, span, graph_->get_edge(id).weight};
  3379.         }
  3380.     }
  3381. }
  3382.  
  3383. }//end namespace router
  3384. }//end namespace detail
  3385. }//end namespace transport_catalogue
Advertisement
Add Comment
Please, Sign In to add comment