shushus

Спринт 15. Итоговый проект: двухстадийность в транспортном справочнике. Задание 1.

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