shushus

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

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