shushus

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

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