Line data Source code
1 : #include "data/SUMO/Routes.hpp"
2 :
3 : #include <spdlog/spdlog.h>
4 :
5 : #include <filesystem>
6 : #include <fstream>
7 : #include <iostream>
8 : #include <memory>
9 : #include <stdexcept>
10 :
11 : #include "rapidxml.hpp"
12 : #include "utils/xml.hpp"
13 :
14 : using namespace std;
15 : using namespace SUMO;
16 : using namespace rapidxml;
17 : using namespace utils::stringify;
18 :
19 : namespace fs = std::filesystem;
20 :
21 : namespace xml = utils::xml;
22 :
23 0 : Routes::VehicleFlow::VehicleFlow(
24 : ID id_,
25 : Route route_
26 0 : ):
27 : id(id_),
28 0 : route(route_) {}
29 :
30 : // clang-format off
31 0 : void Routes::VehicleFlow::setColor (color::rgb<float> color_ ) { color = color_ ; }
32 0 : void Routes::VehicleFlow::setFromTaz (TAZ::ID fromTaz_ ) { fromTaz = fromTaz_ ; }
33 0 : void Routes::VehicleFlow::setToTaz (TAZ::ID toTaz_ ) { toTaz = toTaz_ ; }
34 0 : void Routes::VehicleFlow::setDepartPos (DepartPos departPos_ ) { departPos = departPos_ ; }
35 0 : void Routes::VehicleFlow::setDepartSpeed (DepartSpeed departSpeed_) { departSpeed = departSpeed_ ; }
36 : // clang-format on
37 :
38 0 : void Routes::VehicleFlow::toXML(xml_node<> &vehicleFlowEl) const {
39 0 : xml_document<> &doc = *vehicleFlowEl.document();
40 :
41 : // clang-format off
42 0 : xml::add_attribute(vehicleFlowEl, "id", id );
43 0 : if(color .has_value()) xml::add_attribute(vehicleFlowEl, "color" , color .value());
44 0 : if(fromTaz .has_value()) xml::add_attribute(vehicleFlowEl, "fromTaz" , fromTaz .value());
45 0 : if(toTaz .has_value()) xml::add_attribute(vehicleFlowEl, "toTaz" , toTaz .value());
46 0 : if(departPos .has_value()) xml::add_attribute(vehicleFlowEl, "departPos" , departPos .value());
47 0 : if(departSpeed .has_value()) xml::add_attribute(vehicleFlowEl, "departSpeed" , departSpeed .value());
48 : // clang-format on
49 :
50 0 : xml_node<> &routeEl = *doc.allocate_node(node_element, "route");
51 0 : vehicleFlowEl.append_node(&routeEl);
52 :
53 0 : xml::add_attribute(routeEl, "edges", route);
54 0 : }
55 :
56 0 : Routes::Vehicle::Vehicle(
57 : ID id_,
58 : Route route_,
59 : Time depart_
60 0 : ):
61 : VehicleFlow(id_, route_),
62 0 : depart(depart_) {}
63 :
64 0 : void Routes::Vehicle::toXML(xml_node<> &vehicleEl) const {
65 0 : VehicleFlow::toXML(vehicleEl);
66 :
67 0 : xml::add_attribute(vehicleEl, "depart", depart);
68 0 : }
69 :
70 0 : void Routes::Vehicle::addToXML(xml_node<> &routesEl) const {
71 0 : xml_document<> &doc = *routesEl.document();
72 :
73 0 : xml_node<> &vehicleEl = *doc.allocate_node(node_element, "vehicle");
74 0 : routesEl.append_node(&vehicleEl);
75 :
76 0 : toXML(vehicleEl);
77 0 : }
78 :
79 0 : bool Routes::Vehicle::operator<(const Vehicle &other) const {
80 0 : return (depart < other.depart || (!(depart > other.depart) && id < other.id));
81 : }
82 :
83 0 : Routes::Flow::PolicyVehsPerHour::PolicyVehsPerHour(double vehsPerHour_):
84 0 : vehsPerHour(vehsPerHour_) {}
85 :
86 0 : Routes::Flow::Flow(
87 : ID id_,
88 : Route route_,
89 : Time begin_,
90 : Time end_,
91 : shared_ptr<Policy> policy_
92 0 : ):
93 : VehicleFlow(id_, route_),
94 : begin(begin_),
95 : end(end_),
96 0 : policy(policy_) {}
97 :
98 0 : void Routes::Flow::toXML(xml_node<> &flowEl) const {
99 0 : VehicleFlow::toXML(flowEl);
100 :
101 : // clang-format off
102 0 : xml::add_attribute(flowEl, "begin" , begin);
103 0 : xml::add_attribute(flowEl, "end" , end );
104 : // clang-format on
105 :
106 0 : policy->saveToXML(flowEl);
107 0 : }
108 :
109 0 : void Routes::Flow::addToXML(xml_node<> &routesEl) const {
110 0 : xml_document<> &doc = *routesEl.document();
111 :
112 0 : xml_node<> &flowEl = *doc.allocate_node(node_element, "flow");
113 0 : routesEl.append_node(&flowEl);
114 :
115 0 : toXML(flowEl);
116 0 : }
117 :
118 0 : Routes::Vehicle &Routes::createVehicle(
119 : ID id,
120 : Route route,
121 : Time depart
122 : ) {
123 0 : shared_ptr<Vehicle> vehicle(new Vehicle(id, route, depart));
124 0 : vehicles.emplace(vehicle);
125 0 : return *vehicle;
126 : }
127 :
128 0 : Routes::Flow &Routes::createFlow(
129 : SUMO::ID id,
130 : Route route,
131 : SUMO::Time begin,
132 : SUMO::Time end,
133 : shared_ptr<Flow::Policy> policy
134 : ) {
135 0 : shared_ptr<Flow> flow(new Flow(id, route, begin, end, policy));
136 0 : flows.emplace_back(flow);
137 0 : return *flow;
138 : }
139 :
140 0 : void Routes::saveToFile(const string &filePath) const {
141 0 : xml_document<> doc;
142 0 : xml_node<> &routesEl = *doc.allocate_node(node_element, "routes");
143 0 : doc.append_node(&routesEl);
144 :
145 0 : for(const shared_ptr<Flow> &flow: flows) {
146 0 : flow->addToXML(routesEl);
147 : }
148 :
149 0 : for(const shared_ptr<Vehicle> &vehicle: vehicles) {
150 0 : vehicle->addToXML(routesEl);
151 : }
152 :
153 0 : ofstream os;
154 0 : os.exceptions(ios_base::failbit | ios_base::badbit);
155 0 : fs::path p = fs::path(filePath).parent_path();
156 0 : if(!fs::is_directory(p)) {
157 0 : spdlog::info("Creating directory {}", p.string());
158 0 : if(!fs::create_directory(p)) {
159 0 : throw ios_base::failure("Could not create directory " + p.string());
160 : }
161 : }
162 0 : try {
163 0 : os.open(filePath);
164 0 : } catch(const ios_base::failure &ex) {
165 0 : throw ios_base::failure("Could not open file " + filePath);
166 : }
167 :
168 0 : os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
169 0 : os << doc;
170 0 : }
171 :
172 0 : void Routes::Flow::PolicyVehsPerHour::saveToXML(xml_node<> &flowEl) const {
173 0 : xml::add_attribute(flowEl, "vehsPerHour", vehsPerHour);
174 0 : }
175 :
176 0 : void Routes::Flow::PolicyPeriod::saveToXML(xml_node<> &flowEl) const {
177 0 : if(f.has_value()) {
178 0 : xml::add_attribute(flowEl, "period", f.value());
179 0 : return;
180 0 : } else if(s.has_value()) {
181 0 : xml::add_attribute(flowEl, "period", s.value());
182 0 : return;
183 : }
184 0 : throw runtime_error("PolicyPeriod::saveToXML: either f or s must be set, but neither were set.");
185 : }
186 :
187 0 : void Routes::Flow::PolicyProbability::saveToXML(xml_node<> &flowEl) const {
188 0 : xml::add_attribute(flowEl, "probability", probability);
189 0 : }
|