shushus

Спринт 11. Транспортный справочник - визуализация карты маршрутов. Задание 1.

Apr 6th, 2023
1,448
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 64.14 KB | None | 0 0
  1. -----------------------------------------------------------------------
  2. domain.h
  3. -----------------------------------------------------------------------
  4. #pragma once
  5.  
  6. #include "transport_catalogue.h"
  7. #include <algorithm>
  8. #include <vector>
  9.  
  10. namespace transport_catalogue {
  11. namespace detail {
  12. namespace bus {
  13.    
  14. struct BusQueryResult{
  15.     std::string_view name;
  16.     bool not_found;
  17.     int stops_on_route;
  18.     int unique_stops;
  19.     int route_length;
  20.     double curvature;
  21. };
  22.    
  23. void show_terminal(BusQueryResult bus_info, std::ostream& output);
  24. BusQueryResult query(TransportCatalogue& catalogue, std::string_view str);
  25.    
  26. }//end namespace bus
  27.    
  28. namespace stop {
  29.    
  30. struct StopQueryResult{
  31.     std::string_view name;
  32.     bool not_found;
  33.     std::vector <std::string> buses_name;
  34. };
  35.    
  36. void show_terminal(const StopQueryResult& stop_info, std::ostream& output);
  37. StopQueryResult query(TransportCatalogue& catalogue, std::string_view stop_name);
  38.    
  39. }//end namespace stop
  40.    
  41. void execute_query(TransportCatalogue& catalogue, std::string_view str);
  42. void parse_and_execute_queries(TransportCatalogue& catalogue);
  43.    
  44. }//end namespace detail
  45. }//end namespace transport_catalogue
  46. -----------------------------------------------------------------------
  47. domain.cpp
  48. -----------------------------------------------------------------------
  49. #include "domain.h"
  50.  
  51. namespace transport_catalogue {
  52. namespace detail {
  53. namespace bus {  
  54.    
  55. void show_terminal(BusQueryResult bus_info, std::ostream& output) {
  56.     if (bus_info.not_found) {
  57.         output << "Bus " << bus_info.name << ": not found" << std::endl;
  58.     } else {
  59.         output << "Bus " << bus_info.name << ": "
  60.                << bus_info.stops_on_route << " stops on route, "
  61.                << bus_info.unique_stops << " unique stops, "
  62.                << bus_info.route_length << " route length, "
  63.                << std::setprecision(6) << bus_info.curvature
  64.                << " curvature" << std::endl;
  65.     }
  66. }
  67.    
  68. BusQueryResult query(TransportCatalogue& catalogue, std::string_view bus_name) {
  69.     BusQueryResult bus_info;
  70.     Bus* bus = catalogue.get_bus(bus_name);
  71.    
  72.     if (bus != nullptr) {                
  73.         bus_info.name = bus->name;
  74.         bus_info.not_found = false;
  75.         bus_info.stops_on_route = bus->stops.size();
  76.         bus_info.unique_stops = catalogue.get_uniq_stops(bus).size();
  77.         bus_info.route_length = bus->route_length;
  78.         bus_info.curvature = double(catalogue.get_distance_to_bus(bus)
  79.                                     /catalogue.get_length(bus));                    
  80.     } else {  
  81.         bus_info.name = bus_name;
  82.         bus_info.not_found = true;
  83.     }
  84.    
  85.     return bus_info;
  86. }
  87.    
  88. }//end namespace bus
  89.    
  90. namespace stop {  
  91.    
  92. void show_terminal(const StopQueryResult& stop_info, std::ostream& output) {
  93.     if (stop_info.not_found) {
  94.         output << "Stop " << stop_info.name << ": not found" << std::endl;
  95.        
  96.     } else {
  97.         if (stop_info.buses_name.size() == 0){
  98.             output << "Stop " << stop_info.name << ": no buses" << std::endl;
  99.         } else {
  100.             output << "Stop " << stop_info.name << ": buses ";
  101.  
  102.             for (std::string_view bus_name : stop_info.buses_name) {
  103.                  output << bus_name;
  104.                  output << " ";
  105.             }
  106.            
  107.             output << std::endl;
  108.         }
  109.     }
  110. }
  111.    
  112. StopQueryResult query(TransportCatalogue& catalogue, std::string_view stop_name) {
  113.     std::unordered_set<const Bus*> unique_buses;
  114.     StopQueryResult stop_info;
  115.     Stop* stop = catalogue.get_stop(stop_name);
  116.  
  117.     if (stop != NULL) {
  118.        
  119.         stop_info.name = stop->name;
  120.         stop_info.not_found = false;
  121.         unique_buses = catalogue.stop_get_uniq_buses(stop);
  122.        
  123.         if (unique_buses.size() > 0){
  124.             for (const Bus* bus : unique_buses) {
  125.                 stop_info.buses_name.push_back(bus->name);
  126.             }
  127.            
  128.             std::sort(stop_info.buses_name.begin(), stop_info.buses_name.end());
  129.         }  
  130.        
  131.     } else {    
  132.         stop_info.name = stop_name;
  133.         stop_info.not_found = true;
  134.     }
  135.    
  136.     return stop_info;
  137. }
  138.    
  139. }//end namespace stop
  140.    
  141. void execute_query(TransportCatalogue& catalogue, std::string_view str) {
  142.     if (str.substr(0, 3) == "Bus") {
  143.         bus::show_terminal(bus::query(catalogue, str), std::cout);
  144.        
  145.     } else if (str.substr(0, 4) == "Stop") {
  146.         stop::show_terminal(stop::query(catalogue, str), std::cout);
  147.        
  148.     } else {
  149.         std::cout << "Error query" << std::endl;
  150.     }
  151. }
  152.  
  153. void parse_and_execute_queries(TransportCatalogue& catalogue) {
  154.     std::vector<std::string> query;
  155.  
  156.     query.push_back("Bus 114");
  157.     query.push_back("Stop Морской вокзал");
  158.     query.push_back("Stop Ривьерский мост");
  159.  
  160.     for (auto& str : query) {
  161.         execute_query(catalogue, str);
  162.     }
  163. }
  164.    
  165. }//end namespace detail
  166. }//end namespace transport_catalogue
  167. -----------------------------------------------------------------------
  168. geo.h
  169. -----------------------------------------------------------------------
  170. #pragma once
  171. #include <cmath>
  172.  
  173. namespace transport_catalogue {
  174. namespace detail {
  175. namespace geo {
  176.    
  177. const int EARTH_RADIUS = 6371000;
  178. const double PI = 3.1415926535;
  179.    
  180. struct Coordinates {
  181.     double latitude;
  182.     double longitude;
  183.  
  184.     bool operator==(const Coordinates& other) const {
  185.         return latitude == other.latitude && longitude == other.longitude;
  186.     }
  187.     bool operator!=(const Coordinates& other) const {
  188.         return !(*this == other);
  189.     }
  190. };
  191.    
  192. double compute_distance(Coordinates start, Coordinates end);
  193.    
  194. }//end namespace geo
  195. }//end namespace detail
  196. }//end namespace transport_catalogue
  197. -----------------------------------------------------------------------
  198. geo.cpp
  199. -----------------------------------------------------------------------
  200. #define _USE_MATH_DEFINES
  201. #include "geo.h"
  202.  
  203. #include <cmath>
  204.  
  205. namespace transport_catalogue {
  206. namespace detail {
  207. namespace geo {
  208.    
  209. double compute_distance(Coordinates start, Coordinates end) {
  210.     using namespace std;
  211.     if (!(start == end)) {
  212.         const double dr = PI / 180.;
  213.         return acos(sin(start.latitude * dr) * sin(end.latitude * dr)
  214.                     + cos(start.latitude * dr) * cos(end.latitude * dr)
  215.                     * cos(abs(start.longitude - end.longitude) * dr)) * EARTH_RADIUS;
  216.     } else {
  217.         return 0.0;
  218.     }
  219. }
  220.    
  221. }//end namespace geo
  222. }//end namespace detail
  223. }//end namespace transport_catalogue
  224. -----------------------------------------------------------------------
  225. json.h
  226. -----------------------------------------------------------------------
  227. #pragma once
  228.  
  229. #include <iostream>
  230. #include <map>
  231. #include <string>
  232. #include <vector>
  233. #include <variant>
  234.  
  235. namespace transport_catalogue {
  236. namespace detail {
  237. namespace json {
  238.  
  239. class Node;
  240.  
  241. using Dict = std::map<std::string, Node>;
  242. using Array = std::vector<Node>;
  243.  
  244. class ParsingError : public std::runtime_error {
  245. public:
  246.     using runtime_error::runtime_error;
  247. };
  248.  
  249. class Node {
  250. public:
  251.  
  252.     using Value = std::variant<std::nullptr_t, Array, Dict, bool, int, double, std::string>;
  253.  
  254.     Node() = default;
  255.     Node(bool value);
  256.     Node(Array array);
  257.     Node(Dict map);
  258.     Node(int value);
  259.     Node(std::string value);
  260.     Node(std::nullptr_t);
  261.     Node(double value);
  262.    
  263.     const Array& as_array() const;
  264.     const Dict& as_map() const;
  265.     int as_int() const;
  266.     double as_double() const;
  267.     bool as_bool() const;
  268.     const std::string& as_string() const;
  269.  
  270.     bool is_null() const;
  271.     bool is_int() const;
  272.     bool is_double() const;
  273.     bool is_real_double() const;
  274.     bool is_bool() const;
  275.     bool is_string() const;
  276.     bool is_array() const;
  277.     bool is_map() const;
  278.  
  279.     const Value& get_value() const;
  280.        
  281. private:
  282.     Value value_;
  283. };
  284.  
  285. inline bool operator==(const Node& lhs, const Node& rhs) {
  286.     return lhs.get_value() == rhs.get_value();
  287. }  
  288. inline bool operator!=(const Node& lhs, const Node& rhs) {
  289.     return !(lhs == rhs);
  290. }
  291.    
  292. class Document {
  293. public:
  294.     Document() = default;
  295.     explicit Document(Node root);
  296.     const Node& get_root() const;
  297.  
  298. private:
  299.     Node root_;
  300. };
  301.  
  302. inline bool operator==(const Document& lhs, const Document& rhs) {
  303.     return lhs.get_root() == rhs.get_root();
  304. }
  305. inline bool operator!=(const Document& lhs, const Document& rhs) {
  306.     return !(lhs == rhs);
  307. }
  308.  
  309. Document load(std::istream& input);
  310. void print(const Document& document, std::ostream& output);
  311.  
  312. }//end namespace json
  313. }//end namespace detail
  314. }//end namespace transport_catalogue
  315. -----------------------------------------------------------------------
  316. json.cpp
  317. -----------------------------------------------------------------------
  318. #include "json.h"
  319.  
  320. using namespace std;
  321.  
  322. namespace transport_catalogue {
  323. namespace detail {
  324. namespace json {
  325. namespace {
  326.    
  327. Node load_node(istream& input);
  328.  
  329. std::string load_literal(std::istream& input) {
  330.     std::string str;
  331.    
  332.     while (std::isalpha(input.peek())) {
  333.         str.push_back(static_cast<char>(input.get()));
  334.     }
  335.     return str;
  336. }
  337.  
  338. Node load_array(std::istream& input) {
  339.     std::vector<Node> array;
  340.    
  341.     for (char ch; input >> ch && ch != ']';) {
  342.         if (ch != ',') {
  343.             input.putback(ch);
  344.         }
  345.        
  346.         array.push_back(load_node(input));
  347.     }
  348.  
  349.     if (!input) {
  350.         throw ParsingError("unable to parse array"s);
  351.     }
  352.  
  353.     return Node(array);
  354. }
  355.  
  356. Node load_null(std::istream& input) {
  357.     if (auto literal = load_literal(input); literal == "null"sv) {
  358.         return Node(nullptr);
  359.     } else {
  360.         throw ParsingError("unable to parse '"s + literal + "' as null"s);
  361.     }
  362. }
  363.  
  364. Node load_bool(std::istream& input) {
  365.     const auto str = load_literal(input);
  366.  
  367.     if (str == "true"sv) {
  368.         return Node(true);
  369.     } else if (str == "false"sv) {
  370.         return Node(false);
  371.     } else {
  372.         throw ParsingError("unable to parse '"s + str + "' as bool"s);
  373.     }
  374. }
  375.  
  376. Node load_number(std::istream& input) {
  377.     std::string number;
  378.  
  379.     auto read_char = [&number, &input] {
  380.         number += static_cast<char>(input.get());
  381.        
  382.         if (!input) {
  383.             throw ParsingError("unable to read number"s);
  384.         }
  385.     };
  386.  
  387.     auto read_digits = [&input, read_char] {
  388.        
  389.         if (!std::isdigit(input.peek())) {
  390.             throw ParsingError("digit expected"s);
  391.         } else {
  392.             while (std::isdigit(input.peek())) {
  393.                 read_char();
  394.             }  
  395.         }
  396.     };
  397.  
  398.     if (input.peek() == '-') {
  399.         read_char();
  400.     }
  401.  
  402.     if (input.peek() == '0') {
  403.         read_char();
  404.     } else {
  405.         read_digits();
  406.     }
  407.  
  408.     bool is_int = true;
  409.     if (input.peek() == '.') {
  410.         read_char();
  411.         read_digits();
  412.         is_int = false;
  413.     }
  414.  
  415.     if (int ch = input.peek(); ch == 'e' || ch == 'E') {
  416.         read_char();
  417.        
  418.         if (ch = input.peek(); ch == '+' || ch == '-') {
  419.             read_char();
  420.         }
  421.  
  422.         read_digits();
  423.         is_int = false;
  424.     }
  425.  
  426.     try {
  427.         if (is_int) {
  428.             try {
  429.                 return Node(std::stoi(number));
  430.                
  431.             } catch (...) {}
  432.         }
  433.         return Node(std::stod(number));
  434.        
  435.     } catch (...) {
  436.         throw ParsingError("unable to convert "s + number + " to number"s);
  437.     }
  438. }
  439.  
  440. Node load_string(std::istream& input) {
  441.     auto it = std::istreambuf_iterator<char>(input);
  442.     auto end = std::istreambuf_iterator<char>();
  443.     std::string str;
  444.    
  445.     while (true) {
  446.         if (it == end) {
  447.             throw ParsingError("unable to parse string");
  448.         }
  449.        
  450.         const char ch = *it;
  451.         if (ch == '"') {
  452.             ++it;
  453.             break;
  454.            
  455.         } else if (ch == '\\') {
  456.             ++it;
  457.             if (it == end) {
  458.                 throw ParsingError("unable to parse string");
  459.             }
  460.            
  461.             const char esc_ch = *(it);
  462.             switch (esc_ch) {
  463.                 case 'n':
  464.                     str.push_back('\n');
  465.                     break;
  466.                 case 't':
  467.                     str.push_back('\t');
  468.                     break;
  469.                 case 'r':
  470.                     str.push_back('\r');
  471.                     break;
  472.                 case '"':
  473.                     str.push_back('"');
  474.                     break;
  475.                 case '\\':
  476.                     str.push_back('\\');
  477.                     break;
  478.                 default:
  479.                     throw ParsingError("invalid esc \\"s + esc_ch);
  480.             }
  481.            
  482.         } else if (ch == '\n' || ch == '\r') {
  483.             throw ParsingError("invalid line end"s);
  484.         } else {
  485.             str.push_back(ch);
  486.         }
  487.        
  488.         ++it;
  489.     }
  490.    
  491.     return Node(str);
  492. }
  493.    
  494. Node load_dictionary(std::istream& input) {
  495.     Dict dictionary;
  496.  
  497.     for (char ch; input >> ch && ch != '}';) {
  498.        
  499.         if (ch == '"') {
  500.             std::string key = load_string(input).as_string();
  501.  
  502.             if (input >> ch && ch == ':') {
  503.                
  504.                 if (dictionary.find(key) != dictionary.end()) {
  505.                     throw ParsingError("duplicate key '"s + key + "'found");
  506.                 }
  507.  
  508.                 dictionary.emplace(std::move(key), load_node(input));
  509.                
  510.             } else {
  511.                 throw ParsingError(": expected. but '"s + ch + "' found"s);
  512.             }
  513.            
  514.         } else if (ch != ',') {
  515.             throw ParsingError("',' expected. but '"s + ch + "' found"s);
  516.         }
  517.     }
  518.  
  519.     if (!input) {
  520.         throw ParsingError("unable to parse dictionary"s);
  521.     } else {
  522.         return Node(dictionary);
  523.     }
  524.    
  525. }
  526.  
  527. Node load_node(std::istream& input) {
  528.     char ch;
  529.    
  530.     if (!(input >> ch)) {
  531.         throw ParsingError(""s);
  532.     } else {
  533.         switch (ch) {
  534.         case '[':
  535.             return load_array(input);
  536.         case '{':
  537.             return load_dictionary(input);
  538.         case '"':
  539.             return load_string(input);
  540.         case 't': case 'f':
  541.             input.putback(ch);
  542.             return load_bool(input);
  543.         case 'n':
  544.             input.putback(ch);
  545.             return load_null(input);
  546.         default:
  547.             input.putback(ch);
  548.             return load_number(input);
  549.         }
  550.     }
  551. }
  552.    
  553. }//end namespace
  554.    
  555. Node::Node(Array array) : value_(std::move(array)) {}    
  556. Node::Node(std::nullptr_t) : Node() {}
  557. Node::Node(bool value) : value_(value) {}
  558. Node::Node(Dict map) : value_(std::move(map)) {}
  559. Node::Node(int value) : value_(value) {}
  560. Node::Node(string value) : value_(std::move(value)) {}
  561. Node::Node(double value) : value_(value) {}
  562.    
  563. const Array& Node::as_array() const {
  564.     using namespace std::literals;
  565.    
  566.     if (!is_array()) {
  567.         throw std::logic_error("value is not an array"s);
  568.     } else {
  569.         return std::get<Array>(value_);
  570.     }
  571. }
  572.  
  573. const Dict& Node::as_map() const {
  574.     using namespace std::literals;
  575.    
  576.     if (!is_map()) {
  577.         throw std::logic_error("value is not a dictionary"s);
  578.     } else {
  579.         return std::get<Dict>(value_);  
  580.     }
  581. }
  582.  
  583. const std::string& Node::as_string() const {
  584.     using namespace std::literals;
  585.    
  586.     if (!is_string()) {
  587.         throw std::logic_error("value is not a string"s);
  588.     } else {
  589.         return std::get<std::string>(value_);        
  590.     }
  591. }
  592.    
  593. int Node::as_int() const {
  594.     using namespace std::literals;
  595.    
  596.     if (!is_int()) {
  597.         throw std::logic_error("value is not an int"s);
  598.     } else {
  599.         return std::get<int>(value_);    
  600.     }
  601. }
  602.  
  603. double Node::as_double() const {
  604.     using namespace std::literals;
  605.    
  606.     if (!is_double()) {
  607.         throw std::logic_error("value is not a double"s);
  608.     } else if (is_real_double()) {
  609.         return std::get<double>(value_);
  610.     } else {
  611.         return as_int();
  612.     }  
  613. }
  614.  
  615. bool Node::as_bool() const {
  616.     using namespace std::literals;
  617.    
  618.     if (!is_bool()) {
  619.         throw std::logic_error("value is not a bool"s);
  620.     } else {
  621.         return std::get<bool>(value_);  
  622.     }
  623. }
  624.    
  625. bool Node::is_null() const {return std::holds_alternative<std::nullptr_t>(value_);}
  626. bool Node::is_int() const {return std::holds_alternative<int>(value_);}
  627. bool Node::is_double() const {return is_real_double() || is_int();}  
  628. bool Node::is_real_double() const {return std::holds_alternative<double>(value_);}
  629. bool Node::is_bool() const {return std::holds_alternative<bool>(value_);}
  630. bool Node::is_string() const {return std::holds_alternative<std::string>(value_);}
  631. bool Node::is_array() const {return std::holds_alternative<Array>(value_);}
  632. bool Node::is_map() const {return std::holds_alternative<Dict>(value_);}
  633.  
  634. const Node::Value& Node::get_value() const {return value_;}
  635.    
  636. Document::Document(Node root) : root_(std::move(root)) {}
  637. const Node& Document::get_root() const {return root_;}
  638.    
  639. Document load(istream& input) {return Document(load_node(input));}
  640.  
  641. struct PrintContext {
  642.     std::ostream& out;
  643.     int indent_step = 4;
  644.     int indent = 0;
  645.  
  646.     void print_indent() const {
  647.         for (int i = 0; i < indent; ++i) {
  648.             out.put(' ');
  649.         }
  650.     }
  651.  
  652.     [[nodiscard]] PrintContext indented() const {
  653.         return {out,
  654.                 indent_step,
  655.                 indent_step + indent};
  656.     }
  657. };
  658.  
  659. void print_node(const Node& node, const PrintContext& context);
  660.  
  661. void print_string(const std::string& value, std::ostream& out) {
  662.     out.put('"');
  663.    
  664.     for (const char ch : value) {
  665.         switch (ch) {
  666.             case '\r':
  667.                 out << R"(\r)";
  668.                 break;
  669.             case '\n':
  670.                 out << R"(\n)";
  671.                 break;
  672.             case '"':
  673.                 out << R"(\")";
  674.                 break;
  675.             case '\\':
  676.                 out << R"(\\)";
  677.                 break;
  678.             default:
  679.                 out.put(ch);
  680.                 break;
  681.         }
  682.     }
  683.    
  684.     out.put('"');
  685. }
  686.  
  687. template <typename Value>
  688. void print_value(const Value& value, const PrintContext& context) {
  689.     context.out << value;
  690. }    
  691.  
  692. template <>
  693. void print_value<std::string>(const std::string& value, const PrintContext& context) {
  694.     print_string(value, context.out);
  695. }
  696.  
  697. void print_value(const std::nullptr_t&, const PrintContext& context) {
  698.     context.out << "null"s;
  699. }
  700.  
  701. void print_value(bool value, const PrintContext& context) {
  702.     context.out << std::boolalpha << value;
  703. }
  704.  
  705. [[maybe_unused]] void print_value(Array nodes, const PrintContext& context) {
  706.     std::ostream& out = context.out;
  707.     out << "[\n"sv;
  708.     bool first = true;
  709.     auto inner_context = context.indented();
  710.    
  711.     for (const Node& node : nodes) {
  712.         if (first) {
  713.             first = false;
  714.         } else {
  715.             out << ",\n"sv;
  716.         }
  717.  
  718.         inner_context.print_indent();
  719.         print_node(node, inner_context);
  720.     }
  721.  
  722.     out.put('\n');
  723.     context.print_indent();
  724.     out.put(']');
  725. }
  726.  
  727. [[maybe_unused]] void print_value(Dict nodes, const PrintContext& context) {
  728.     std::ostream& out = context.out;
  729.     out << "{\n"sv;
  730.     bool first = true;
  731.     auto inner_context = context.indented();
  732.    
  733.     for (const auto& [key, node] : nodes) {
  734.         if (first) {
  735.             first = false;
  736.         } else {
  737.             out << ",\n"sv;
  738.         }
  739.  
  740.         inner_context.print_indent();
  741.         print_string(key, context.out);
  742.         out << ": "sv;
  743.         print_node(node, inner_context);
  744.     }
  745.  
  746.     out.put('\n');
  747.     context.print_indent();
  748.     out.put('}');
  749. }
  750.  
  751. void print_node(const Node& node, const PrintContext& context) {
  752.     std::visit([&context](const auto& value) {
  753.             print_value(value, context);
  754.         }, node.get_value());
  755. }
  756.    
  757. void print(const Document& document, std::ostream& output) {
  758.     print_node(document.get_root(), PrintContext{output});
  759. }
  760.  
  761. }//end namespace json
  762. }//end namespace detail
  763. }//end namespace transport_catalogue
  764. -----------------------------------------------------------------------
  765. json_reader.h
  766. -----------------------------------------------------------------------
  767. #pragma once
  768. #include "json.h"
  769. #include "transport_catalogue.h"
  770. #include "domain.h"
  771. #include "map_renderer.h"
  772.  
  773. namespace transport_catalogue {
  774. namespace detail {
  775. namespace json {
  776.    
  777. using namespace transport_catalogue::detail::stop;
  778. using namespace transport_catalogue::detail::bus;
  779.    
  780. struct StatRequest {
  781.     int id;
  782.     std::string type;
  783.     std::string name;    
  784. };
  785.    
  786. void parse_node_base(const Node& root, TransportCatalogue& catalogue);
  787. //void parse_node_stat(const Node& root, std::vector<StatRequest>& stat_request);
  788. void parse_node_render(const Node& node, map_renderer::RenderSettings& render_settings);
  789. void parse_node(const Node& root, TransportCatalogue& catalogue, std::vector<StatRequest>& stat_request, map_renderer::RenderSettings& render_settings);
  790. void parse(Document& doc, TransportCatalogue& catalogue, std::vector<StatRequest>& stat_request, map_renderer::RenderSettings& render_settings);
  791.  
  792. Stop parse_node_stop(Node& node);
  793. Bus parse_node_bus(Node& node, TransportCatalogue& catalogue);
  794. std::vector<Distance> parse_node_distances(Node& node, TransportCatalogue& catalogue);
  795.    
  796. Node execute_make_node_stop(int id_request, StopQueryResult query_result);
  797. Node execute_make_node_bus(int id_request, BusQueryResult query_result);
  798. Document execute_queries(TransportCatalogue& catalogue, std::vector<StatRequest>& stat_requests);
  799.    
  800. }//end namespace json
  801. }//end namespace detail
  802. }//end namespace transport_catalogue
  803. -----------------------------------------------------------------------
  804. json_reader.cpp
  805. -----------------------------------------------------------------------
  806. #include "json_reader.h"
  807.  
  808. namespace transport_catalogue {
  809. namespace detail {
  810. namespace json {
  811.    
  812. Stop parse_node_stop(Node& node) {
  813.     Stop stop;
  814.     Dict stop_node;
  815.    
  816.     if (node.is_map()) {
  817.         stop_node = node.as_map();
  818.         stop.name = stop_node.at("name").as_string();
  819.         stop.latitude = stop_node.at("latitude").as_double();
  820.         stop.longitude = stop_node.at("longitude").as_double();
  821.     }
  822.    
  823.     return stop;
  824. }
  825.    
  826. std::vector<Distance> parse_node_distances(Node& node, TransportCatalogue& catalogue) {
  827.     std::vector<Distance> distances;
  828.     Dict stop_node;
  829.     Dict stop_road_map;
  830.     std::string begin_name;
  831.     std::string last_name;
  832.     int distance;
  833.    
  834.     if (node.is_map()) {
  835.         stop_node = node.as_map();
  836.         begin_name = stop_node.at("name").as_string();
  837.        
  838.         try {
  839.             stop_road_map = stop_node.at("road_distances").as_map();
  840.            
  841.             for (auto [key, value] : stop_road_map) {
  842.                 last_name = key;
  843.                 distance = value.as_int();
  844.                 distances.push_back({catalogue.get_stop(begin_name),
  845.                                      catalogue.get_stop(last_name), distance});
  846.             }
  847.            
  848.         } catch(...) {
  849.             std::cout << "invalide road" << std::endl;
  850.         }        
  851.     }
  852.    
  853.     return distances;
  854. }
  855.  
  856. Bus parse_node_bus(Node& node, TransportCatalogue& catalogue) {
  857.     Bus bus;
  858.     Dict bus_node;
  859.     Array bus_stops;
  860.    
  861.     if (node.is_map()) {
  862.         bus_node = node.as_map();
  863.         bus.name = bus_node.at("name").as_string();
  864.         bus.is_roundtrip = bus_node.at("is_roundtrip").as_bool();
  865.  
  866.         try {
  867.             bus_stops = bus_node.at("stops").as_array();
  868.            
  869.             for (Node stop : bus_stops) {
  870.                 bus.stops.push_back(catalogue.get_stop(stop.as_string()));
  871.             }
  872.  
  873.             if (!bus.is_roundtrip) {
  874.                 size_t size = bus.stops.size() - 1;
  875.                
  876.                 for (size_t i = size; i > 0; i--) {
  877.                     bus.stops.push_back(bus.stops[i-1]);
  878.                 }
  879.                
  880.             }
  881.            
  882.         } catch(...) {
  883.             std::cout << "base_requests: bus: stops is empty" << std::endl;
  884.         }        
  885.     }
  886.    
  887.     return bus;
  888. }
  889.    
  890. void parse_node_base(const Node& root, TransportCatalogue& catalogue){
  891.     Array base_requests;
  892.     Dict req_map;
  893.     Node req_node;
  894.    
  895.     std::vector<Node> buses;
  896.     std::vector<Node> stops;
  897.    
  898.     if (root.is_array()) {
  899.         base_requests = root.as_array();
  900.        
  901.         for (Node& node : base_requests) {            
  902.             if (node.is_map()) {
  903.                 req_map = node.as_map();
  904.                
  905.                 try {
  906.                     req_node = req_map.at("type");
  907.                    
  908.                     if (req_node.is_string()) {
  909.                        
  910.                         if (req_node.as_string() == "Bus") {
  911.                             buses.push_back(req_map);
  912.                         } else if (req_node.as_string() == "Stop") {
  913.                             stops.push_back(req_map);
  914.                         } else {
  915.                             std::cout << "base_requests are invalid";
  916.                         }
  917.                     }
  918.                    
  919.                 } catch(...) {
  920.                     std::cout << "base_requests does not have type value";
  921.                 }                
  922.             }
  923.         }  
  924.        
  925.         for (auto stop : stops) {
  926.             catalogue.add_stop(parse_node_stop(stop));
  927.         }
  928.        
  929.         for (auto stop : stops) {
  930.             catalogue.add_distance(parse_node_distances(stop, catalogue));
  931.         }
  932.        
  933.         for (auto bus : buses) {
  934.             catalogue.add_bus(parse_node_bus(bus, catalogue));
  935.         }
  936.        
  937.     } else {
  938.         std::cout << "base_requests is not an array";
  939.     }  
  940. }
  941.  
  942. /*void parce_node_stat(const Node& node, std::vector<StatRequest>& stat_request){
  943.     Array stat_requests;
  944.     Dict req_map;
  945.     StatRequest req;
  946.    
  947.     if (node.is_array()) {
  948.         stat_requests = node.as_array();
  949.        
  950.         for (Node req_node : stat_requests) {
  951.            
  952.             if (req_node.is_map()) {
  953.                 req_map = req_node.as_map();
  954.                 req.id = req_map.at("id").as_int();
  955.                 req.type = req_map.at("type").as_string();
  956.                 req.name = req_map.at("name").as_string();
  957.                 stat_request.push_back(req);
  958.             }
  959.            
  960.         }
  961.     } else {
  962.         std::cout << "base_requests is not array";
  963.     }
  964. }*/
  965.  
  966. void parce_node_render(const Node& node, map_renderer::RenderSettings& rend_set){
  967.     Dict rend_map;
  968.     Array bus_lab_offset;
  969.     Array stop_lab_offset;
  970.     Array arr_color;
  971.     Array arr_palette;
  972.     uint8_t red_;
  973.     uint8_t green_;
  974.     uint8_t blue_;
  975.     double opacity_;
  976.  
  977.     if (node.is_map()) {
  978.         rend_map = node.as_map();
  979.        
  980.         try {
  981.             rend_set.width_ = rend_map.at("width").as_double();
  982.             rend_set.height_ = rend_map.at("height").as_double();
  983.             rend_set.padding_ = rend_map.at("padding").as_double();
  984.             rend_set.line_width_ = rend_map.at("line_width").as_double();
  985.             rend_set.stop_radius_ = rend_map.at("stop_radius").as_double();
  986.             rend_set.bus_label_font_size_ = rend_map.at("bus_label_font_size").as_int();
  987.            
  988.             if (rend_map.at("bus_label_font_size").is_array()) {
  989.                 bus_lab_offset = rend_map.at("bus_label_font_size").as_array();
  990.                 rend_set.bus_label_offset_ = std::make_pair(bus_lab_offset[0].as_double(),
  991.                                                             bus_lab_offset[1].as_double());
  992.             }
  993.            
  994.             rend_set.stop_label_font_size_ = rend_map.at("stop_label_font_size").as_int();
  995.  
  996.             if (rend_map.at("stop_label_offset").is_array()) {
  997.                 stop_lab_offset = rend_map.at("stop_label_offset").as_array();
  998.                 rend_set.stop_label_offset_ = std::make_pair(stop_lab_offset[0].as_double(),
  999.                                                              stop_lab_offset[1].as_double());
  1000.             }
  1001.            
  1002.             if (rend_map.at("underlayer_color").is_string()) {
  1003.                 rend_set.underlayer_color_ = svg::Color(rend_map.at("underlayer_color").as_string());
  1004.             } else if (rend_map.at("underlayer_color").is_array()) {
  1005.                 arr_color = rend_map.at("underlayer_color").as_array();
  1006.                 red_ = arr_color[0].as_int();
  1007.                 green_ = arr_color[1].as_int();
  1008.                 blue_ = arr_color[2].as_int();
  1009.  
  1010.                 if(arr_color.size() == 4){
  1011.                     opacity_ = arr_color[3].as_double();
  1012.                     rend_set.underlayer_color_ = svg::Color(svg::Rgba(red_,
  1013.                                                                       green_,
  1014.                                                                       blue_,
  1015.                                                                       opacity_));
  1016.                 } else if (arr_color.size() == 3) {
  1017.                     rend_set.underlayer_color_ = svg::Color(svg::Rgb(red_,
  1018.                                                                      green_,
  1019.                                                                      blue_));
  1020.                 }
  1021.                
  1022.             }
  1023.  
  1024.             rend_set.underlayer_width_ = rend_map.at("underlayer_width").as_double();
  1025.  
  1026.             if (rend_map.at("color_palette").is_array()) {
  1027.                 arr_palette = rend_map.at("color_palette").as_array();
  1028.                
  1029.                 for (Node color_palette : arr_palette) {
  1030.                    
  1031.                     if (color_palette.is_string()) {
  1032.                         rend_set.color_palette_.push_back(svg::Color(color_palette.as_string()));
  1033.                     } else if (color_palette.is_array()) {
  1034.                         arr_color = color_palette.as_array();
  1035.                         red_ = arr_color[0].as_int();
  1036.                         green_ = arr_color[1].as_int();
  1037.                         blue_ = arr_color[2].as_int();
  1038.  
  1039.                         if (arr_color.size() == 4) {
  1040.                             opacity_ = arr_color[3].as_double();
  1041.                             rend_set.color_palette_.push_back(svg::Color(svg::Rgba(red_,
  1042.                                                                                    green_,
  1043.                                                                                    blue_,
  1044.                                                                                    opacity_)));
  1045.                         } else if (arr_color.size() == 3) {
  1046.                             rend_set.color_palette_.push_back(svg::Color(svg::Rgb(red_,
  1047.                                                                                   green_,
  1048.                                                                                   blue_)));
  1049.                         }
  1050.                     }
  1051.                 }
  1052.             }            
  1053.         } catch(...) {
  1054.             std::cout << "unable to parsse init settings";
  1055.         }
  1056.        
  1057.     } else {
  1058.         std::cout << "render_settings is not map";
  1059.     }
  1060. }
  1061.    
  1062. void parse_node(const Node& root, TransportCatalogue& catalogue, [[maybe_unused]] std::vector<StatRequest>& stat_request, map_renderer::RenderSettings& render_settings){
  1063.     Dict root_dictionary;
  1064.    
  1065.     if (root.is_map()) {
  1066.         root_dictionary = root.as_map();
  1067.  
  1068.         try {          
  1069.             parse_node_base(root_dictionary.at("base_requests"), catalogue);
  1070.         } catch(...) {
  1071.             std::cout << "base_requests is empty";
  1072.         }
  1073.  
  1074.         /*try {
  1075.             parce_node_stat(root_dictionary.at("stat_requests"), stat_request);
  1076.         } catch(...) {
  1077.             std::cout << "stat_requests is empty";
  1078.         }*/
  1079.  
  1080.         try {
  1081.             parce_node_render(root_dictionary.at("render_settings"), render_settings);
  1082.         } catch(...) {
  1083.             std::cout << "render_settings is empty";
  1084.         }
  1085.        
  1086.     } else {
  1087.         std::cout << "root is not map";
  1088.     }
  1089. }
  1090.    
  1091. void parse(Document& document, TransportCatalogue& catalogue, std::vector<StatRequest>& stat_request, map_renderer::RenderSettings& render_settings){  
  1092.     parse_node(document.get_root(),
  1093.                catalogue,
  1094.                stat_request,
  1095.                render_settings);
  1096. }
  1097.  
  1098. Node execute_make_node_stop(int id_request, StopQueryResult stop_info){
  1099.     Dict result;
  1100.     Array buses;
  1101.     std::string str_not_found = "not found";
  1102.    
  1103.     if (stop_info.not_found) {
  1104.         result.emplace("request_id", Node(id_request));
  1105.         result.emplace("error_message", Node(str_not_found));
  1106.     } else {
  1107.         result.emplace("request_id", Node(id_request));
  1108.        
  1109.         for (std::string bus_name : stop_info.buses_name) {
  1110.             buses.push_back(Node(bus_name));
  1111.         }
  1112.        
  1113.         result.emplace("buses", Node(buses));
  1114.     }
  1115.    
  1116.     return Node(result);
  1117. }
  1118.  
  1119. Node execute_make_node_bus(int id_request, BusQueryResult bus_info){
  1120.     Dict result;
  1121.     std::string str_not_found = "not found";
  1122.    
  1123.     if (bus_info.not_found) {
  1124.         result.emplace("request_id", Node(id_request));
  1125.         result.emplace("error_message", Node(str_not_found));
  1126.     } else {
  1127.         result.emplace("request_id", Node(id_request));        
  1128.         result.emplace("curvature", Node(bus_info.curvature));
  1129.         result.emplace("route_length", Node(bus_info.route_length));
  1130.         result.emplace("stop_count", Node(bus_info.stops_on_route));
  1131.         result.emplace("unique_stop_count", Node(bus_info.unique_stops));
  1132.     }
  1133.    
  1134.     return Node(result);
  1135. }    
  1136.    
  1137. Document execute_queries([[maybe_unused]] TransportCatalogue& catalogue, std::vector<StatRequest>& stat_requests){
  1138.     std::vector<Node> result_request;
  1139.    
  1140.     for (StatRequest req : stat_requests) {
  1141.        
  1142.         if (req.type == "Stop") {
  1143.             result_request.push_back(execute_make_node_stop(req.id, stop::query(catalogue, req.name)));
  1144.         } else if (req.type == "Bus") {
  1145.             result_request.push_back(execute_make_node_bus(req.id,bus::query(catalogue, req.name)));
  1146.         }        
  1147.     }
  1148.    
  1149.     return Document{Node(result_request)};
  1150. }
  1151.    
  1152. }//end namespace json
  1153. }//end namespace detail
  1154. }//end namespace transport_catalogue
  1155. -----------------------------------------------------------------------
  1156. main.cpp
  1157. -----------------------------------------------------------------------
  1158. #include "transport_catalogue.h"
  1159. #include "json_reader.h"
  1160. #include "domain.h"
  1161. #include "map_renderer.h"
  1162. #include "request_handler.h"
  1163.  
  1164. using namespace std;
  1165. using namespace transport_catalogue;
  1166. using namespace transport_catalogue::detail;
  1167. using namespace transport_catalogue::detail::json;
  1168.  
  1169. int main() {
  1170.  
  1171.     std::vector<StatRequest> stat_request;    
  1172.     map_renderer::RenderSettings render_settings;
  1173.     TransportCatalogue catalogue;  
  1174.     Document doc_in;
  1175.    
  1176.     doc_in = json::load(std::cin);  
  1177.     json::parse(doc_in, catalogue, stat_request, render_settings);
  1178.    
  1179.     map_renderer::MapRenderer map_render(render_settings);
  1180.    
  1181.     request_handler::RequestHandler request_handler(catalogue, map_render);
  1182.     request_handler.render_map(std::cout);
  1183. }
  1184. -----------------------------------------------------------------------
  1185. map_renderer.h
  1186. -----------------------------------------------------------------------
  1187. #pragma once
  1188. #include <iostream>
  1189. #include <optional>
  1190. #include <algorithm>
  1191. #include <cstdlib>
  1192.  
  1193. #include "domain.h"
  1194. #include "geo.h"
  1195. #include "svg.h"
  1196.  
  1197. using namespace transport_catalogue::detail;
  1198.  
  1199. namespace map_renderer {
  1200.    
  1201. inline const double EPSILON = 1e-6;
  1202.  
  1203. class SphereProjector {
  1204. public:
  1205.  
  1206.     template <typename InputIt>
  1207.     SphereProjector(InputIt points_begin,
  1208.                     InputIt points_end,
  1209.                     double max_width,
  1210.                     double max_height,
  1211.                     double padding);
  1212.  
  1213.     svg::Point operator()(geo::Coordinates coords) const;
  1214.  
  1215. private:
  1216.     double padding_;
  1217.     double min_lon_ = 0;
  1218.     double max_lat_ = 0;
  1219.     double zoom_coeff_ = 0;
  1220.    
  1221.     bool is_zero(double value);
  1222. };
  1223.    
  1224. struct RenderSettings {
  1225.     double width_;
  1226.     double height_;
  1227.     double padding_;
  1228.     double line_width_;
  1229.     double stop_radius_;
  1230.     int bus_label_font_size_;
  1231.     std::pair<double, double> bus_label_offset_;
  1232.     int stop_label_font_size_;
  1233.     std::pair<double, double>  stop_label_offset_;
  1234.     svg::Color underlayer_color_;
  1235.     double underlayer_width_;
  1236.     std::vector<svg::Color> color_palette_;
  1237. };
  1238.    
  1239. class MapRenderer {
  1240. public:
  1241.     MapRenderer(RenderSettings& render_settings);  
  1242.     SphereProjector get_sphere_projector(const std::vector<geo::Coordinates>& points) const;
  1243.    
  1244.     RenderSettings get_render_settings() const;
  1245.     int get_palette_size() const;
  1246.     svg::Color get_color(int line_number) const;
  1247.        
  1248.     void set_line_properties(svg::Polyline& polyline, int line_number) const;
  1249.  
  1250. private:
  1251.     RenderSettings& render_settings_;
  1252. };
  1253.  
  1254. template <typename InputIt>
  1255.     SphereProjector::SphereProjector(InputIt points_begin,
  1256.                                      InputIt points_end,
  1257.                                      double max_width,
  1258.                                      double max_height,
  1259.                                      double padding) : padding_(padding) {
  1260.         if (points_begin == points_end) {
  1261.             return;
  1262.         }
  1263.  
  1264.         const auto [left_it,
  1265.                     right_it] = std::minmax_element(points_begin,
  1266.                                                     points_end,
  1267.             [](auto lhs, auto rhs) {
  1268.                 return lhs.longitude < rhs.longitude;
  1269.             });
  1270.        
  1271.         min_lon_ = left_it->longitude;
  1272.         const double max_lon = right_it->longitude;
  1273.  
  1274.         const auto [bottom_it,
  1275.                     top_it] = std::minmax_element(points_begin,
  1276.                                                   points_end,
  1277.             [](auto lhs, auto rhs) {
  1278.                 return lhs.latitude < rhs.latitude;
  1279.             });
  1280.        
  1281.         const double min_lat = bottom_it->latitude;
  1282.         max_lat_ = top_it->latitude;
  1283.  
  1284.         std::optional<double> width_zoom;
  1285.         if (!is_zero(max_lon - min_lon_)) {
  1286.             width_zoom = (max_width - 2 * padding)
  1287.                          / (max_lon - min_lon_);
  1288.         }
  1289.  
  1290.         std::optional<double> height_zoom;
  1291.         if (!is_zero(max_lat_ - min_lat)) {
  1292.             height_zoom = (max_height - 2 * padding)
  1293.                           / (max_lat_ - min_lat);
  1294.         }
  1295.  
  1296.         if (width_zoom && height_zoom) {
  1297.             zoom_coeff_ = std::min(*width_zoom,
  1298.                                    *height_zoom);    
  1299.         } else if (width_zoom) {
  1300.             zoom_coeff_ = *width_zoom;
  1301.            
  1302.         } else if (height_zoom) {
  1303.             zoom_coeff_ = *height_zoom;
  1304.            
  1305.         }
  1306.     }
  1307.    
  1308. }//end namespace map_renderer
  1309. -----------------------------------------------------------------------
  1310. map_renderer.cpp
  1311. -----------------------------------------------------------------------
  1312. #include "map_renderer.h"
  1313.  
  1314. namespace map_renderer {
  1315.  
  1316. bool SphereProjector::is_zero(double value) {
  1317.     return std::abs(value) < EPSILON;
  1318. }
  1319.    
  1320. MapRenderer::MapRenderer(RenderSettings& render_settings) : render_settings_(render_settings) {}
  1321.  
  1322. svg::Point SphereProjector::operator()(geo::Coordinates coords) const {
  1323.     return {(coords.longitude - min_lon_) * zoom_coeff_ + padding_,
  1324.             (max_lat_ - coords.latitude) * zoom_coeff_ + padding_};
  1325. }
  1326.    
  1327. SphereProjector MapRenderer::get_sphere_projector(const std::vector<geo::Coordinates>& points) const {
  1328.         return SphereProjector(points.begin(),
  1329.                                points.end(),
  1330.                                render_settings_.width_,
  1331.                                render_settings_.height_,
  1332.                                render_settings_.padding_);
  1333. }
  1334.    
  1335. RenderSettings MapRenderer::get_render_settings() const{
  1336.     return render_settings_;
  1337. }
  1338.  
  1339. int MapRenderer::get_palette_size() const{
  1340.     return render_settings_.color_palette_.size();
  1341. }
  1342.    
  1343. svg::Color MapRenderer::get_color(int line_number) const {
  1344.     return render_settings_.color_palette_[line_number];
  1345. }
  1346.  
  1347. void MapRenderer::set_line_properties(svg::Polyline& polyline, [[maybe_unused]] int line_number) const {
  1348.     using namespace std::literals;
  1349.    
  1350.     polyline.set_stroke_color(get_color(line_number));  
  1351.     polyline.set_fill_color("none"s);
  1352.     polyline.set_stroke_width(render_settings_.line_width_);
  1353.     polyline.set_stroke_linecap(svg::StrokeLineCap::ROUND);
  1354.     polyline.set_stroke_linejoin(svg::StrokeLineJoin::ROUND);  
  1355. }  
  1356.    
  1357. }//end namespace map_renderer
  1358. -----------------------------------------------------------------------
  1359. request_handler.h
  1360. -----------------------------------------------------------------------
  1361. #pragma once
  1362.  
  1363. #include "transport_catalogue.h"
  1364. #include "map_renderer.h"
  1365.  
  1366. using namespace transport_catalogue;
  1367. using namespace map_renderer;
  1368.  
  1369. namespace request_handler {
  1370.  
  1371. using BusPoints = std::vector<std::pair<std::string_view, std::vector<geo::Coordinates>>>;
  1372.  
  1373. class RequestHandler {
  1374. public:
  1375.    
  1376.     RequestHandler(TransportCatalogue& db, const MapRenderer& map_renderer_);
  1377.    
  1378.     std::vector<geo::Coordinates> get_stops_coordinates() const;
  1379.     void render_map(std::ostream& out) const;
  1380.  
  1381. private:
  1382.     TransportCatalogue& db_;
  1383.     const MapRenderer& map_renderer_;
  1384. };
  1385.    
  1386. }//end namespace request_handler
  1387. -----------------------------------------------------------------------
  1388. request_handler.cpp
  1389. -----------------------------------------------------------------------
  1390. #include "request_handler.h"
  1391.  
  1392. namespace request_handler {
  1393.  
  1394. RequestHandler::RequestHandler(TransportCatalogue& db,const MapRenderer& renderer) : db_(db),
  1395.                                                                                      map_renderer_(renderer) {}
  1396.  
  1397. std::vector<geo::Coordinates> RequestHandler::get_stops_coordinates() const {
  1398.    
  1399.     std::vector<geo::Coordinates> stops_coordinates;
  1400.     auto buses = db_.get_busname_to_bus();
  1401.    
  1402.     for (auto& [busname, bus] : buses) {
  1403.         for (auto& stop : bus->stops) {
  1404.             geo::Coordinates coordinates;
  1405.             coordinates.latitude = stop->latitude;
  1406.             coordinates.longitude = stop->longitude;
  1407.            
  1408.             stops_coordinates.push_back(coordinates);
  1409.         }
  1410.     }
  1411.     return stops_coordinates;
  1412. }
  1413.  
  1414. void RequestHandler::render_map(std::ostream& out) const {
  1415.     svg::Document document;
  1416.     [[maybe_unused]] auto sphere_projector = map_renderer_.get_sphere_projector(get_stops_coordinates());
  1417.     std::vector<std::string_view> buses_name;
  1418.     std::vector<std::pair<Bus*, int>> buses_palette;
  1419.     std::vector<geo::Coordinates> stops_geo_coords;    
  1420.    
  1421.     int palette_size = 0;
  1422.     int palette_index = 0;
  1423.    
  1424.     palette_size = map_renderer_.get_palette_size();
  1425.     if (palette_size == 0) {
  1426.         std::cout << "color palette is empty";
  1427.         return;
  1428.     }
  1429.    
  1430.     auto buses = db_.get_busname_to_bus();
  1431.     if (buses.size() > 0) {
  1432.        
  1433.         for (auto& [busname, bus] : buses) {
  1434.             buses_name.push_back(busname);
  1435.         }  
  1436.  
  1437.         std::sort(buses_name.begin(), buses_name.end());
  1438.  
  1439.         for (std::string_view bus_name : buses_name) {
  1440.             Bus* bus_info = db_.get_bus(bus_name);
  1441.  
  1442.             if (bus_info) {  
  1443.  
  1444.                 if (bus_info->stops.size() > 0) {
  1445.                     buses_palette.push_back(std::make_pair(bus_info, palette_index));
  1446.                     palette_index++;
  1447.                    
  1448.                     if (palette_index == palette_size) {
  1449.                         palette_index = 0;
  1450.                     }
  1451.                 }
  1452.             }
  1453.         }
  1454.  
  1455.         if (buses_palette.size() > 0) {
  1456.            
  1457.             for (auto [bus, palette] : buses_palette) {
  1458.                
  1459.                 for (auto& stop : bus->stops) {
  1460.                     geo::Coordinates coordinates;
  1461.                     coordinates.latitude = stop->latitude;
  1462.                     coordinates.longitude = stop->longitude;
  1463.                     stops_geo_coords.push_back(coordinates);
  1464.                 }
  1465.                                
  1466.                 svg::Polyline bus_line;
  1467.                 bool bus_empty = true;                
  1468.                
  1469.                 for (auto& point : stops_geo_coords) {
  1470.                     bus_empty = false;
  1471.                     bus_line.add_point(sphere_projector(point));
  1472.                 }
  1473.                
  1474.                 if (!bus_empty) {
  1475.                     map_renderer_.set_line_properties(bus_line, palette);
  1476.                     document.add(bus_line);
  1477.                 }
  1478.                
  1479.                 stops_geo_coords.clear();
  1480.             }            
  1481.         }            
  1482.     }  
  1483.    
  1484.     document.render(out);
  1485. }
  1486.    
  1487. }//end namespace request_handler
  1488. -----------------------------------------------------------------------
  1489. svg.h
  1490. -----------------------------------------------------------------------
  1491. #pragma once
  1492. #define _USE_MATH_DEFINES
  1493.  
  1494. #include <cstdint>
  1495. #include <iostream>
  1496. #include <memory>
  1497. #include <string>
  1498. #include <vector>
  1499. #include <optional>
  1500. #include <cmath>
  1501. #include <variant>
  1502.  
  1503. namespace svg {
  1504.  
  1505. class Rgb {
  1506. public:
  1507.     Rgb() = default;
  1508.     Rgb(uint8_t red, uint8_t green, uint8_t blue);
  1509.    
  1510.     uint8_t red_ = 0;
  1511.     uint8_t green_ = 0;
  1512.     uint8_t blue_ = 0;
  1513. };
  1514. inline void print_color(std::ostream& out, Rgb& rgb);
  1515.  
  1516. class Rgba {
  1517. public:
  1518.     Rgba() = default;
  1519.     Rgba(uint8_t red, uint8_t green, uint8_t blue, double opacity);
  1520.    
  1521.     uint8_t red_ = 0;
  1522.     uint8_t green_ = 0;
  1523.     uint8_t blue_ = 0;
  1524.     double opacity_ = 1.0;
  1525. };  
  1526. inline void print_color(std::ostream& out, Rgba& rgba);
  1527.  
  1528. using Color = std::variant<std::monostate, std::string, Rgb, Rgba>;
  1529. inline const Color NoneColor{"none"};  
  1530.    
  1531. inline void print_color(std::ostream& out, std::monostate);
  1532. inline void print_color(std::ostream& out, std::string& color);
  1533. std::ostream& operator<<(std::ostream& out, const Color& color);
  1534.    
  1535. enum class StrokeLineCap {
  1536.     BUTT,
  1537.     ROUND,
  1538.     SQUARE,
  1539. };
  1540.    
  1541. inline std::ostream &operator<<(std::ostream &out, StrokeLineCap stroke_line_cap) {
  1542.     using namespace std::literals;
  1543.    
  1544.     if (stroke_line_cap == StrokeLineCap::BUTT) {
  1545.         out << "butt"sv;
  1546.     } else if (stroke_line_cap == StrokeLineCap::ROUND) {
  1547.         out << "round"sv;
  1548.     } else if (stroke_line_cap == StrokeLineCap::SQUARE) {
  1549.         out << "square"sv;
  1550.     }
  1551.     return out;
  1552. }
  1553.  
  1554. enum class StrokeLineJoin {
  1555.     ARCS,
  1556.     BEVEL,
  1557.     MITER,
  1558.     MITER_CLIP,
  1559.     ROUND,
  1560. };
  1561.    
  1562. inline std::ostream &operator<<(std::ostream &out, StrokeLineJoin stroke_line_join) {
  1563.     using namespace std::literals;
  1564.    
  1565.     if (stroke_line_join == StrokeLineJoin::ARCS) {
  1566.         out << "arcs"sv;
  1567.     } else if (stroke_line_join == StrokeLineJoin::BEVEL) {
  1568.         out << "bevel"sv;
  1569.     } else if (stroke_line_join == StrokeLineJoin::MITER) {
  1570.         out << "miter"sv;
  1571.     } else if (stroke_line_join == StrokeLineJoin::MITER_CLIP) {
  1572.         out << "miter-clip"sv;
  1573.     } else if (stroke_line_join == StrokeLineJoin::ROUND) {
  1574.         out << "round"sv;
  1575.     }
  1576.     return out;
  1577. }
  1578.    
  1579. template<typename Owner>
  1580. class PathProps {
  1581. public:
  1582.     Owner& set_fill_color(const Color& color) {
  1583.         fill_color_ = std::move(color);
  1584.         return as_owner();
  1585.     }
  1586.  
  1587.     Owner& set_stroke_color(const Color& color) {
  1588.         stroke_color_ = std::move(color);
  1589.         return as_owner();
  1590.     }
  1591.  
  1592.     Owner& set_stroke_width(double width) {
  1593.         stroke_width_ = width;
  1594.         return as_owner();
  1595.     }
  1596.  
  1597.     Owner& set_stroke_linecap(StrokeLineCap line_cap) {
  1598.         stroke_line_cap_ = line_cap;
  1599.         return as_owner();
  1600.     }
  1601.  
  1602.     Owner& set_stroke_linejoin(StrokeLineJoin line_join) {
  1603.         stroke_line_join_ = line_join;
  1604.         return as_owner();
  1605.     }
  1606.  
  1607. protected:
  1608.     ~PathProps() = default;
  1609.  
  1610.     void render_attrs(std::ostream &out) const {
  1611.         using namespace std::literals;
  1612.  
  1613.         if (fill_color_ != std::nullopt) {
  1614.             out << "fill=\""sv << *fill_color_ << "\" "sv;
  1615.         }
  1616.         if (stroke_color_ != std::nullopt) {
  1617.             out << "stroke=\""sv << *stroke_color_ << "\" "sv;
  1618.         }
  1619.         if (stroke_width_ != std::nullopt) {
  1620.             out << "stroke-width=\""sv << *stroke_width_ << "\" "sv;
  1621.         }
  1622.         if (stroke_line_cap_ != std::nullopt) {
  1623.             out << "stroke-linecap=\""sv << *stroke_line_cap_ << "\" "sv;
  1624.         }
  1625.         if (stroke_line_join_ != std::nullopt) {
  1626.             out << "stroke-linejoin=\""sv << *stroke_line_join_ << "\" "sv;
  1627.         }
  1628.     }
  1629.    
  1630. private:
  1631.     std::optional<Color> fill_color_;
  1632.     std::optional<Color> stroke_color_;
  1633.     std::optional<double> stroke_width_;
  1634.     std::optional<StrokeLineCap> stroke_line_cap_;
  1635.     std::optional<StrokeLineJoin> stroke_line_join_;
  1636.    
  1637.     Owner& as_owner() {
  1638.         return static_cast<Owner&>(*this);
  1639.     }
  1640. };
  1641.    
  1642. struct Point {
  1643.     Point() = default;
  1644.     Point(double x, double y) : x(x)
  1645.                               , y(y) {}
  1646.     double x = 0;
  1647.     double y = 0;
  1648. };
  1649.  
  1650. struct RenderContext {
  1651.     RenderContext(std::ostream& out);
  1652.     RenderContext(std::ostream& out, int indent_step, int indent = 0) : out_(out)
  1653.                                                                       , indent_step_(indent_step)
  1654.                                                                       , indent_(indent) {}
  1655.     RenderContext indented() const;
  1656.     void render_indent() const;
  1657.  
  1658.     std::ostream& out_;
  1659.     int indent_step_ = 0;
  1660.     int indent_ = 0;
  1661. };
  1662.  
  1663. class Object {
  1664. public:
  1665.     void render(const RenderContext& context) const;
  1666.     virtual ~Object() = default;
  1667.  
  1668. private:
  1669.     virtual void render_object(const RenderContext& context) const = 0;
  1670. };
  1671.  
  1672. class Circle final : public Object, public PathProps<Circle> {
  1673. public:
  1674.     Circle& set_center(Point center);
  1675.     Circle& set_radius(double radius);
  1676.  
  1677. private:
  1678.     Point center_;
  1679.     double radius_ = 1.0;
  1680.    
  1681.     void render_object(const RenderContext& context) const override;
  1682. };
  1683.  
  1684. class Polyline final : public Object, public PathProps<Polyline> {
  1685. public:
  1686.     Polyline& add_point(Point point);
  1687.    
  1688. private:
  1689.     std::vector<Point> points_;
  1690.     void render_object(const RenderContext& context) const override;
  1691. };
  1692.  
  1693. class Text final : public Object, public PathProps<Text> {
  1694. public:
  1695.     Text& set_position(Point pos);
  1696.     Text& set_offset(Point offset);
  1697.     Text& set_font_size(uint32_t size);
  1698.     Text& set_font_family(std::string font_family);
  1699.     Text& set_font_weight(std::string font_weight);
  1700.     Text& set_data(std::string data);
  1701.  
  1702. private:
  1703.     Point position_;
  1704.     Point offset_;
  1705.     std::string font_family_;
  1706.     std::string font_weight_;
  1707.     uint32_t font_size_ = 1;
  1708.     std::string data_;
  1709.      
  1710.     static std::string delete_spaces(const std::string& str);
  1711.     static std::string uniq_symbols(const std::string& str);
  1712.    
  1713.     void render_object(const RenderContext& context) const override;
  1714. };
  1715.    
  1716. class ObjectContainer {
  1717. public:
  1718.     virtual ~ObjectContainer() = default;
  1719.  
  1720.     template<typename Obj>
  1721.     void add(Obj obj);
  1722.  
  1723.     virtual void add_ptr(std::unique_ptr<Object> &&) = 0;
  1724.  
  1725. protected:
  1726.     std::vector<std::unique_ptr<Object>> objects_;
  1727. };
  1728.    
  1729. template<typename Obj>
  1730. void ObjectContainer::add(Obj obj) {
  1731.     objects_.emplace_back(std::make_unique<Obj>(std::move(obj)));
  1732. }
  1733.    
  1734. class Drawable {
  1735. public:
  1736.     virtual void draw(ObjectContainer& container) const = 0;
  1737.     virtual ~Drawable() = default;
  1738. };
  1739.    
  1740. class Document : public ObjectContainer {
  1741. public:  
  1742.     void add_ptr(std::unique_ptr<Object>&& obj) override {
  1743.         objects_.emplace_back(std::move(obj));
  1744.     }
  1745.     void render(std::ostream& out) const;
  1746.    
  1747. };
  1748.    
  1749. }//end namespace svg
  1750. -----------------------------------------------------------------------
  1751. svg.cpp
  1752. -----------------------------------------------------------------------
  1753. #include "svg.h"
  1754.  
  1755. namespace svg {
  1756.  
  1757. using namespace std::literals;
  1758. // ---------- Rgb/Rgba ------------------  
  1759.  
  1760. Rgb::Rgb(uint8_t red, uint8_t green, uint8_t blue) : red_(red)
  1761.                                                    , green_(green)
  1762.                                                    , blue_(blue) {}  
  1763.    
  1764. Rgba::Rgba(uint8_t red, uint8_t green, uint8_t blue, double opacity) : red_(red)
  1765.                                                                      , green_(green)
  1766.                                                                      , blue_(blue)
  1767.                                                                      , opacity_(opacity) {}
  1768.  
  1769. // ---------- Color ------------------
  1770.    
  1771. inline void print_color(std::ostream& out, Rgb& rgb) {
  1772.     out << "rgb("sv << static_cast<short>(rgb.red_) << ","sv
  1773.                     << static_cast<short>(rgb.green_) << ","sv
  1774.                     << static_cast<short>(rgb.blue_) << ")"sv;
  1775. }
  1776.    
  1777. inline void print_color(std::ostream& out, Rgba& rgba) {
  1778.     out << "rgba("sv << static_cast<short>(rgba.red_) << ","sv
  1779.                      << static_cast<short>(rgba.green_) << ","sv
  1780.                      << static_cast<short>(rgba.blue_) << ","sv
  1781.                      << (rgba.opacity_) << ")"sv;
  1782. }
  1783.    
  1784. inline void print_color(std::ostream& out, std::monostate) {
  1785.     out << "none"sv;
  1786. }
  1787.  
  1788. inline void print_color(std::ostream& out, std::string& color) {
  1789.     out << color;
  1790. }
  1791.    
  1792. std::ostream& operator<<(std::ostream& out, const Color& color) {
  1793.     std::visit([&out](auto value) {
  1794.             print_color(out, value);
  1795.     }, color);
  1796.    
  1797.     return out;
  1798. }
  1799.    
  1800. // ---------- Render ------------------
  1801.    
  1802. RenderContext::RenderContext(std::ostream& out) : out_(out) {}
  1803.    
  1804. RenderContext RenderContext::indented() const {
  1805.         return {out_,
  1806.                 indent_step_,
  1807.                 indent_ + indent_step_};
  1808. }
  1809.    
  1810. void RenderContext::render_indent() const {
  1811.         for (int i = 0; i < indent_; ++i) {
  1812.             out_.put(' ');
  1813.         }
  1814. }
  1815.  
  1816. void Object::render(const RenderContext& context) const {
  1817.     context.render_indent();
  1818.     render_object(context);
  1819.     context.out_ << std::endl;
  1820. }
  1821.  
  1822. // ---------- Circle ------------------
  1823.  
  1824. Circle& Circle::set_center(Point center)  {
  1825.     center_ = center;
  1826.     return *this;
  1827. }
  1828.  
  1829. Circle& Circle::set_radius(double radius)  {
  1830.     radius_ = radius;
  1831.     return *this;
  1832. }
  1833.  
  1834. void Circle::render_object(const RenderContext& context) const {
  1835.     std::ostream& out = context.out_;
  1836.  
  1837.     out << "<circle cx=\""sv << center_.x
  1838.         << "\" cy=\""sv << center_.y << "\" "sv;
  1839.     out << "r=\""sv << radius_ << "\" "sv;
  1840.    
  1841.     render_attrs(context.out_);
  1842.     out << "/>"sv;
  1843. }
  1844.  
  1845. // ---------- Polyline ------------------
  1846.    
  1847. Polyline& Polyline::add_point(Point point) {
  1848.     points_.emplace_back(point);
  1849.     return *this;
  1850. }
  1851.  
  1852. void Polyline::render_object(const RenderContext& context) const {
  1853.    
  1854.     std::ostream& out = context.out_;
  1855.     out << "<polyline points=\"";
  1856.    
  1857.     for (size_t i = 0; i < points_.size(); ++i) {
  1858.         out << points_[i].x << ","sv << points_[i].y;
  1859.  
  1860.         if (i+1 != points_.size()) {
  1861.             out << " "sv;
  1862.         }
  1863.     }
  1864.     out << "\" ";
  1865.     render_attrs(context.out_);
  1866.     out << "/>";
  1867. }
  1868.  
  1869. // ---------- Text ------------------
  1870.    
  1871. Text& Text::set_position(Point pos) {
  1872.     position_ = pos;
  1873.     return *this;
  1874. }
  1875.  
  1876. Text& Text::set_offset(Point offset) {
  1877.     offset_ = offset;
  1878.     return *this;
  1879. }
  1880.    
  1881. Text& Text::set_font_size(uint32_t size) {
  1882.     font_size_ = size;
  1883.     return *this;
  1884. }
  1885.  
  1886. Text& Text::set_font_family(std::string font_family) {
  1887.     font_family_ = std::move(font_family);
  1888.     return *this;
  1889. }
  1890.  
  1891. Text& Text::set_font_weight(std::string font_weight) {
  1892.     font_weight_ = std::move(font_weight);
  1893.     return *this;
  1894. }
  1895.  
  1896. Text& Text::set_data(std::string data) {
  1897.     data_ = std::move(data);
  1898.     return *this;
  1899. }
  1900.  
  1901. std::string Text::delete_spaces(const std::string& str) {
  1902.     if (str.empty()) {
  1903.         return {};
  1904.     } else {
  1905.        
  1906.         auto left = str.find_first_not_of(' ');
  1907.         auto right = str.find_last_not_of(' ');
  1908.         return str.substr(left, right - left + 1);  
  1909.     }
  1910. }
  1911.  
  1912. std::string Text::uniq_symbols(const std::string& str) {
  1913.    
  1914.     std::string out;
  1915.  
  1916.     for (char ch : str) {
  1917.        
  1918.         if (ch == '"') {
  1919.             out += "&quot;"sv;
  1920.             continue;
  1921.            
  1922.         } else if (ch == '`' || ch == '\'') {
  1923.             out += "&apos;"sv;
  1924.             continue;
  1925.            
  1926.         } else if (ch == '<') {
  1927.             out += "&lt;"sv;
  1928.             continue;
  1929.            
  1930.         } else if (ch == '>') {
  1931.             out += "&gt;"sv;
  1932.             continue;
  1933.            
  1934.         } else if (ch == '&') {
  1935.             out += "&amp;"sv;
  1936.             continue;
  1937.            
  1938.         } else {
  1939.            
  1940.         }
  1941.        
  1942.         out += ch;
  1943.     }
  1944.  
  1945.     return out;
  1946. }
  1947.  
  1948. void Text::render_object(const RenderContext& context) const {
  1949.    
  1950.     std::ostream& out = context.out_;
  1951.     out << "<text ";
  1952.     render_attrs(context.out_);
  1953.     out << "x=\""
  1954.         << position_.x << "\" y=\""
  1955.         << position_.y << "\" "
  1956.         << "dx=\""
  1957.         << offset_.x << "\" dy=\""
  1958.         << offset_.y << "\" "
  1959.         << "font-size=\""
  1960.         << font_size_ << "\" ";
  1961.  
  1962.     if (!font_family_.empty()) {
  1963.         out << "font-family=\"" << font_family_ << "\" ";
  1964.     }
  1965.  
  1966.     if (!font_weight_.empty()) {
  1967.         out << "font-weight=\"" << font_weight_ << "\"";
  1968.     }
  1969.  
  1970.     out << ">"sv << delete_spaces(uniq_symbols(data_)) << "</text>"sv;
  1971.  
  1972. }
  1973.  
  1974. // ---------- Document ------------------
  1975.  
  1976. void Document::render(std::ostream& out) const {
  1977.     int indent = 2;
  1978.     int indent_step = 2;
  1979.  
  1980.     RenderContext context(out, indent_step, indent);
  1981.  
  1982.     const std::string_view xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"sv;
  1983.     const std::string_view svg = "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">"sv;
  1984.  
  1985.     out << xml << "\n"sv << svg << "\n"sv;
  1986.  
  1987.     for (const auto& object : objects_) {
  1988.         object->render(context);
  1989.     }
  1990.    
  1991.     out << "</svg>"sv;
  1992. }
  1993.  
  1994. }//end namespace svg
  1995. -----------------------------------------------------------------------
  1996. transport_catalogue.h
  1997. -----------------------------------------------------------------------
  1998. #pragma once
  1999. #include <deque>
  2000. #include <string>
  2001. #include <vector>
  2002.  
  2003. #include <iomanip>
  2004. #include <iostream>
  2005.  
  2006. #include <unordered_set>
  2007. #include <unordered_map>
  2008.  
  2009. #include "geo.h"
  2010.  
  2011. namespace transport_catalogue {  
  2012.    
  2013. struct Bus;
  2014.    
  2015. struct Stop {    
  2016.     std::string name;
  2017.     double latitude;
  2018.     double longitude;
  2019.    
  2020.     std::vector<Bus*> buses;
  2021. };
  2022.  
  2023. struct Bus {
  2024.     std::string name;
  2025.     std::vector<Stop*> stops;
  2026.     bool is_roundtrip;
  2027.     size_t route_length;
  2028. };
  2029.  
  2030. struct Distance {    
  2031.     const Stop* A;
  2032.     const Stop* B;
  2033.     int distance;
  2034. };
  2035.  
  2036. struct DistanceHasher {
  2037.     std::hash<const void*> hasher;
  2038.    
  2039.     std::size_t operator()(const std::pair<const Stop*, const Stop*> pair_stops) const noexcept {
  2040.         auto hash_1 = static_cast<const void*>(pair_stops.first);
  2041.         auto hash_2 = static_cast<const void*>(pair_stops.second);
  2042.         return hasher(hash_1) * 17 + hasher(hash_2);
  2043.     }  
  2044. };
  2045.    
  2046. typedef  std::unordered_map<std::string_view, Stop*> StopMap;
  2047. typedef  std::unordered_map<std::string_view, Bus*> BusMap;
  2048. typedef  std::unordered_map<std::pair<const Stop*, const  Stop*>, int, DistanceHasher> DistanceMap;
  2049.  
  2050. class TransportCatalogue {
  2051. public:      
  2052.     void add_bus(Bus&& bus);
  2053.     void add_stop(Stop&& stop);
  2054.     void add_distance(const std::vector<Distance>& distances);
  2055.    
  2056.     Bus* get_bus(std::string_view bus_name);
  2057.     Stop* get_stop(std::string_view stop_name);
  2058.     BusMap get_busname_to_bus() const;
  2059.  
  2060.     std::unordered_set<const Bus*> stop_get_uniq_buses(Stop* stop);    
  2061.     std::unordered_set<const Stop*> get_uniq_stops(Bus* bus);
  2062.     double get_length(Bus* bus);
  2063.    
  2064.     size_t get_distance_stop(const Stop* start, const Stop* finish);
  2065.     size_t get_distance_to_bus(Bus* bus);
  2066.    
  2067. private:    
  2068.     std::deque<Stop> stops;
  2069.     StopMap stopname_to_stop;
  2070.    
  2071.     std::deque<Bus> buses;
  2072.     BusMap busname_to_bus;
  2073.    
  2074.     DistanceMap distance_to_stop;
  2075.    
  2076. };
  2077.    
  2078. }//end namespace transport_catalogue
  2079. -----------------------------------------------------------------------
  2080. transport_catalogue.cpp
  2081. -----------------------------------------------------------------------
  2082. #include "transport_catalogue.h"
  2083. #include <execution>
  2084.  
  2085. namespace transport_catalogue {  
  2086.    
  2087. void TransportCatalogue::add_stop(Stop&& stop) {
  2088.     stops.push_back(std::move(stop));
  2089.     Stop* stop_buf = &stops.back();
  2090.     stopname_to_stop.insert(transport_catalogue::StopMap::value_type(stop_buf->name, stop_buf));
  2091. }
  2092.  
  2093. void TransportCatalogue::add_bus(Bus&& bus) {
  2094.     Bus* bus_buf;
  2095.    
  2096.     buses.push_back(std::move(bus));
  2097.     bus_buf = &buses.back();
  2098.     busname_to_bus.insert(BusMap::value_type(bus_buf->name, bus_buf));
  2099.  
  2100.     for (Stop* stop : bus_buf->stops) {
  2101.          stop->buses.push_back(bus_buf);
  2102.     }
  2103.    
  2104.     bus_buf->route_length = get_distance_to_bus(bus_buf);
  2105. }
  2106.  
  2107. void TransportCatalogue::add_distance(const std::vector<Distance>& distances) {
  2108.     for (auto distance : distances){
  2109.         auto dist_pair = std::make_pair(distance.A, distance.B);
  2110.         distance_to_stop.insert(DistanceMap::value_type(dist_pair, distance.distance));
  2111.     }
  2112. }
  2113.  
  2114. Bus* TransportCatalogue::get_bus(std::string_view bus_name) {  
  2115.     if(busname_to_bus.empty()){
  2116.         return nullptr;
  2117.     }
  2118.    
  2119.     try{
  2120.         return busname_to_bus.at(bus_name);
  2121.     }
  2122.     catch(const std::out_of_range &e){
  2123.         return nullptr;
  2124.     }
  2125. }
  2126.  
  2127. Stop* TransportCatalogue::get_stop(std::string_view stop_name) {
  2128.     if(stopname_to_stop.empty()){
  2129.         return nullptr;
  2130.     }
  2131.    
  2132.     try {
  2133.         return stopname_to_stop.at(stop_name);
  2134.     } catch(const std::out_of_range &e) {
  2135.         return nullptr;
  2136.     }
  2137. }
  2138.    
  2139. BusMap TransportCatalogue::get_busname_to_bus() const {
  2140.     return busname_to_bus;
  2141. }
  2142.  
  2143. std::unordered_set<const Stop*> TransportCatalogue::get_uniq_stops(Bus* bus) {
  2144.     std::unordered_set<const Stop*> unique_stops;
  2145.    
  2146.     unique_stops.insert(bus->stops.begin(), bus->stops.end());
  2147.    
  2148.     return unique_stops;
  2149. }
  2150.  
  2151. double TransportCatalogue::get_length(Bus* bus) {
  2152.     return transform_reduce(next(bus->stops.begin()),
  2153.                             bus->stops.end(),
  2154.                             bus->stops.begin(),
  2155.                             0.0,
  2156.                             std::plus<>{},
  2157.                             [](const Stop* lhs, const Stop* rhs) {
  2158.                                 return detail::geo::compute_distance({(*lhs).latitude,
  2159.                                                         (*lhs).longitude}, {(*rhs).latitude,
  2160.                                                                               (*rhs).longitude});
  2161.                             });
  2162. }
  2163.  
  2164. std::unordered_set<const Bus*> TransportCatalogue::stop_get_uniq_buses(Stop* stop){    
  2165.     std::unordered_set<const Bus*> unique_stops;    
  2166.      
  2167.     unique_stops.insert(stop->buses.begin(), stop->buses.end());  
  2168.    
  2169.     return unique_stops;
  2170. }
  2171.  
  2172. size_t TransportCatalogue::get_distance_stop(const Stop* begin, const Stop* finish) {
  2173.     if(distance_to_stop.empty()){
  2174.         return 0;
  2175.     }
  2176.    
  2177.     try {
  2178.        
  2179.         auto dist_pair = std::make_pair(begin, finish);
  2180.         return distance_to_stop.at(dist_pair);
  2181.        
  2182.     } catch(const std::out_of_range &e) {
  2183.        
  2184.         try {
  2185.             auto dist_pair = std::make_pair(finish, begin);
  2186.             return distance_to_stop.at(dist_pair);
  2187.         } catch(const std::out_of_range &e) {
  2188.             return 0;    
  2189.         }
  2190.        
  2191.     }
  2192. }
  2193.  
  2194. size_t TransportCatalogue::get_distance_to_bus(Bus* bus) {
  2195.     size_t distance = 0;
  2196.     auto stops_size = bus->stops.size() - 1;
  2197.     for (int i = 0; i < static_cast<int>(stops_size); i++) {
  2198.         distance += get_distance_stop(bus->stops[i], bus->stops[i+1]);
  2199.     }
  2200.     return distance;
  2201. }
  2202.    
  2203. }//end namespace transport_catalogue
Advertisement
Add Comment
Please, Sign In to add comment