-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmap_renderer.h
125 lines (106 loc) · 3.9 KB
/
map_renderer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#pragma once
#include <algorithm>
#include <deque>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <vector>
#include "domain.h"
#include "geo.h"
#include "svg.h"
#include "transport_catalogue.h"
inline const double EPSILON = 1e-6;
struct RenderSettings {
double width_ = 300.0;
double height_ = 200.0;
double padding_ = 50.0;
double line_width_ = 14.0;
double stop_radius_ = 5.0;
int bus_label_font_size_ = 20;
std::vector<double> bus_label_offset_ = { 7.0, 15.0 };
int stop_label_font_size_ = 20;
std::vector<double> stop_label_offset_ = { 7.0, -3.0 };
svg::Color underlayer_color_ = svg::Rgba{ 255, 255, 255, 0.85 };
double underlayer_width_ = 3.0;
std::vector<svg::Color> color_palette_ = { "green", svg::Rgb{255, 160, 0}, "red" };
};//*/
class MapRenderer {
public:
std::ostream& Draw(std::ostream& out, transport_catalogue::TransportCatalogue& tc);
void SetRenderSettings(const RenderSettings& rc);
RenderSettings GetRenderSettings();
private:
void GetBuses(transport_catalogue::TransportCatalogue& tc);
void GetStops(transport_catalogue::TransportCatalogue& tc);
std::ostream& DrawRoutes(std::ostream& out);
private:
RenderSettings render_settings_;
std::set<std::string> stop_names_;
std::vector<domain::Stop*> stops_;
std::set<std::string> bus_names_;
std::vector<domain::Bus*> buses_;
};
class SphereProjector {
public:
// points_begin è points_end çàäàþò íà÷àëî è êîíåö èíòåðâàëà ýëåìåíòîâ geo::Coordinates
template <typename PointInputIt>
SphereProjector(PointInputIt points_begin, PointInputIt points_end,
double max_width, double max_height, double padding);
// Ïðîåöèðóåò øèðîòó è äîëãîòó â êîîðäèíàòû âíóòðè SVG-èçîáðàæåíèÿ
svg::Point operator()(geo::Coordinates coords) const {
return {
(coords.lng - min_lon_) * zoom_coeff_ + padding_,
(max_lat_ - coords.lat) * zoom_coeff_ + padding_
};
}
private:
double padding_ = 0;
double min_lon_ = 0;
double max_lat_ = 0;
double zoom_coeff_ = 0;
};
template <typename PointInputIt>
SphereProjector::SphereProjector(PointInputIt points_begin, PointInputIt points_end,
double max_width, double max_height, double padding)
: padding_(padding)
{
// Åñëè òî÷êè ïîâåðõíîñòè ñôåðû íå çàäàíû, âû÷èñëÿòü íå÷åãî
if (points_begin == points_end) {
return;
}
// Íàõîäèì òî÷êè ñ ìèíèìàëüíîé è ìàêñèìàëüíîé äîëãîòîé
const auto [left_it, right_it] = std::minmax_element(
points_begin, points_end,
[](auto lhs, auto rhs) { return lhs.lng < rhs.lng; });
min_lon_ = left_it->lng;
const double max_lon = right_it->lng;
// Íàõîäèì òî÷êè ñ ìèíèìàëüíîé è ìàêñèìàëüíîé øèðîòîé
const auto [bottom_it, top_it] = std::minmax_element(
points_begin, points_end,
[](auto lhs, auto rhs) { return lhs.lat < rhs.lat; });
const double min_lat = bottom_it->lat;
max_lat_ = top_it->lat;
// Âû÷èñëÿåì êîýôôèöèåíò ìàñøòàáèðîâàíèÿ âäîëü êîîðäèíàòû x
std::optional<double> width_zoom;
if (!(std::abs(max_lon - min_lon_) < EPSILON)) {
width_zoom = (max_width - 2 * padding) / (max_lon - min_lon_);
}
// Âû÷èñëÿåì êîýôôèöèåíò ìàñøòàáèðîâàíèÿ âäîëü êîîðäèíàòû y
std::optional<double> height_zoom;
if (!(std::abs(max_lat_ - min_lat) < EPSILON)) {
height_zoom = (max_height - 2 * padding) / (max_lat_ - min_lat);
}
if (width_zoom && height_zoom) {
// Êîýôôèöèåíòû ìàñøòàáèðîâàíèÿ ïî øèðèíå è âûñîòå íåíóëåâûå, áåð¸ì ìèíèìàëüíûé èç íèõ
zoom_coeff_ = std::min(*width_zoom, *height_zoom);
}
else if (width_zoom) {
// Êîýôôèöèåíò ìàñøòàáèðîâàíèÿ ïî øèðèíå íåíóëåâîé, èñïîëüçóåì åãî
zoom_coeff_ = *width_zoom;
}
else if (height_zoom) {
// Êîýôôèöèåíò ìàñøòàáèðîâàíèÿ ïî âûñîòå íåíóëåâîé, èñïîëüçóåì åãî
zoom_coeff_ = *height_zoom;
}
}