shushus

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

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