Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNEDemandElementFlow.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
18// An auxiliar, asbtract class for flow elements (vehicles, person and containers)
19/****************************************************************************/
20
21#include <netedit/GNEUndoList.h>
25
27
28// ===========================================================================
29// member method definitions
30// ===========================================================================
31
33 // set default flow attributes
34 setDefaultFlowAttributes(flowElement);
35}
36
37
39 SUMOVehicleParameter(vehicleParameters) {
40 // set default flow attributes
41 setDefaultFlowAttributes(flowElement);
42}
43
44
46
47
48void
49GNEDemandElementFlow::drawFlowLabel(const Position& position, const double rotation, const double width, const double length, const double exaggeration) const {
50 // declare contour width
51 const double contourWidth = (0.05 * exaggeration);
52 // Push matrix
54 // Traslate to bot
55 glTranslated(position.x(), position.y(), GLO_PERSONFLOW + 0.1);
56 // glTranslated(position.x(), position.y(), GLO_ROUTE + getType() + 0.1 + GLO_PERSONFLOW + 0.1);
57 glRotated(rotation, 0, 0, -1);
58 glTranslated(-1 * ((width * 0.5 * exaggeration) + (0.35 * exaggeration)), 0, 0);
59 // draw external box
61 GLHelper::drawBoxLine(Position(), Position(), 0, (length * exaggeration), 0.3 * exaggeration);
62 // draw internal box
63 glTranslated(0, 0, 0.1);
65 GLHelper::drawBoxLine(Position(0, -contourWidth), Position(0, -contourWidth), 0, (length * exaggeration) - (contourWidth * 2), (0.3 * exaggeration) - contourWidth);
66 // draw stack label
67 GLHelper::drawText("Flow", Position(0, length * exaggeration * -0.5), (.1 * exaggeration), (0.6 * exaggeration), RGBColor::BLACK, 90, 0, -1);
68 // pop draw matrix
70}
71
72
73void
75 // get xph attribute
77 if (flowElement->getTagProperty().isPerson()) {
79 } else if (flowElement->getTagProperty().isContainer()) {
81 }
82 // first check that we're writting a flow
83 if (flowElement->getTagProperty().isFlow()) {
84 // write routeFlow values depending if it was set
87 }
90 }
91 if (isFlowAttributeEnabled(xph)) {
92 device.writeAttr(xph, getFlowAttribute(xph));
93 }
96 }
99 }
102 }
103 }
104}
105
106
107std::string
109 switch (key) {
110 case SUMO_ATTR_DEPART:
111 case SUMO_ATTR_BEGIN:
113 return "triggered";
115 return "containerTriggered";
117 return "now";
119 return "split";
121 return "begin";
122 } else {
123 return time2string(depart);
124 }
125 case SUMO_ATTR_END:
131 case SUMO_ATTR_PERIOD:
133 case GNE_ATTR_POISSON:
134 return toString(poissonRate);
135 case SUMO_ATTR_PROB:
137 case SUMO_ATTR_NUMBER:
139 default:
140 throw InvalidArgument("Flow doesn't have an attribute of type '" + toString(key) + "'");
141 }
142}
143
144
145double
147 switch (key) {
148 case SUMO_ATTR_DEPART:
149 case SUMO_ATTR_BEGIN:
150 return STEPS2TIME(depart);
151 default:
152 throw InvalidArgument("Flow doesn't have a double attribute of type '" + toString(key) + "'");
153 }
154}
155
156
157void
158GNEDemandElementFlow::setFlowAttribute(GNEDemandElement* flowElement, SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
159 switch (key) {
160 case SUMO_ATTR_DEPART:
161 case SUMO_ATTR_BEGIN:
162 case SUMO_ATTR_END:
163 case SUMO_ATTR_NUMBER:
167 case SUMO_ATTR_PERIOD:
168 case GNE_ATTR_POISSON:
169 case SUMO_ATTR_PROB:
170 GNEChange_Attribute::changeAttribute(flowElement, key, value, undoList);
171 break;
172 default:
173 throw InvalidArgument(flowElement->getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
174 }
175}
176
177
178bool
179GNEDemandElementFlow::isValidFlowAttribute(GNEDemandElement* flowElement, SumoXMLAttr key, const std::string& value) {
180 // declare string error
181 std::string error;
182 switch (key) {
183 case SUMO_ATTR_DEPART:
184 case SUMO_ATTR_BEGIN: {
185 SUMOTime dummyDepart;
186 DepartDefinition dummyDepartProcedure;
187 parseDepart(value, flowElement->getTagProperty().getTagStr(), id, dummyDepart, dummyDepartProcedure, error);
188 // if error is empty, given value is valid
189 return error.empty();
190 }
191 case SUMO_ATTR_END:
192 if (GNEAttributeCarrier::canParse<SUMOTime>(value)) {
193 return (GNEAttributeCarrier::parse<SUMOTime>(value) >= 0);
194 } else {
195 return false;
196 }
200 case SUMO_ATTR_PERIOD:
201 case GNE_ATTR_POISSON:
202 if (GNEAttributeCarrier::canParse<double>(value)) {
203 return (GNEAttributeCarrier::parse<double>(value) > 0);
204 } else {
205 return false;
206 }
207 case SUMO_ATTR_PROB:
208 if (GNEAttributeCarrier::canParse<double>(value)) {
209 const double prob = GNEAttributeCarrier::parse<double>(value);
210 return ((prob >= 0) && (prob <= 1));
211 } else {
212 return false;
213 }
214 case SUMO_ATTR_NUMBER:
215 if (GNEAttributeCarrier::canParse<int>(value)) {
216 return (GNEAttributeCarrier::parse<int>(value) >= 0);
217 } else {
218 return false;
219 }
220 default:
221 throw InvalidArgument("Flow doesn't have an attribute of type '" + toString(key) + "'");
222 }
223}
224
225
226void
228 switch (key) {
229 case SUMO_ATTR_END:
230 case SUMO_ATTR_NUMBER:
234 case SUMO_ATTR_PERIOD:
235 case GNE_ATTR_POISSON:
236 case SUMO_ATTR_PROB:
237 undoList->add(new GNEChange_ToggleAttribute(flowElement, key, true), true);
238 return;
239 default:
240 throw InvalidArgument(flowElement->getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
241 }
242}
243
244
245void
247 switch (key) {
248 case SUMO_ATTR_END:
249 case SUMO_ATTR_NUMBER:
253 case SUMO_ATTR_PERIOD:
254 case GNE_ATTR_POISSON:
255 case SUMO_ATTR_PROB:
256 undoList->add(new GNEChange_ToggleAttribute(flowElement, key, false), true);
257 return;
258 default:
259 throw InvalidArgument(flowElement->getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
260 }
261}
262
263
264bool
266 switch (key) {
267 case SUMO_ATTR_END:
268 return (parametersSet & VEHPARS_END_SET) != 0;
269 case SUMO_ATTR_NUMBER:
270 return (parametersSet & VEHPARS_NUMBER_SET) != 0;
274 return (parametersSet & VEHPARS_VPH_SET) != 0;
275 case SUMO_ATTR_PERIOD:
276 return (parametersSet & VEHPARS_PERIOD_SET) != 0;
277 case GNE_ATTR_POISSON:
278 return (parametersSet & VEHPARS_POISSON_SET) != 0;
279 case SUMO_ATTR_PROB:
280 return (parametersSet & VEHPARS_PROB_SET) != 0;
281 default:
282 return true;
283 }
284}
285
286
287void
288GNEDemandElementFlow::setFlowAttribute(const GNEDemandElement* flowElement, SumoXMLAttr key, const std::string& value) {
289 // declare string error
290 std::string error;
291 switch (key) {
292 case SUMO_ATTR_DEPART:
293 case SUMO_ATTR_BEGIN: {
294 parseDepart(value, flowElement->getTagProperty().getTagStr(), id, depart, departProcedure, error);
295 break;
296 }
297 case SUMO_ATTR_END:
298 repetitionEnd = string2time(value);
299 break;
303 repetitionOffset = TIME2STEPS(3600 / GNEAttributeCarrier::parse<double>(value));
304 poissonRate = GNEAttributeCarrier::parse<double>(value) / 3600;
305 break;
306 case SUMO_ATTR_PERIOD:
309 break;
310 case GNE_ATTR_POISSON:
311 poissonRate = GNEAttributeCarrier::parse<double>(value);
313 break;
314 case SUMO_ATTR_PROB:
315 repetitionProbability = GNEAttributeCarrier::parse<double>(value);
316 break;
317 case SUMO_ATTR_NUMBER:
318 repetitionNumber = GNEAttributeCarrier::parse<int>(value);
319 break;
320 default:
321 throw InvalidArgument("Flow doesn't have an attribute of type '" + toString(key) + "'");
322 }
323}
324
325
326void
327GNEDemandElementFlow::toggleFlowAttribute(const SumoXMLAttr attribute, const bool value) {
328 // modify parameters depending of given Flow attribute
329 if (value) {
330 switch (attribute) {
331 case SUMO_ATTR_END:
333 break;
334 case SUMO_ATTR_NUMBER:
336 break;
341 break;
342 case SUMO_ATTR_PERIOD:
344 break;
345 case GNE_ATTR_POISSON:
347 break;
348 case SUMO_ATTR_PROB:
350 break;
351 default:
352 break;
353 }
354 } else {
355 switch (attribute) {
356 case SUMO_ATTR_END:
357 parametersSet &= ~VEHPARS_END_SET;
358 break;
359 case SUMO_ATTR_NUMBER:
360 parametersSet &= ~VEHPARS_NUMBER_SET;
361 break;
365 parametersSet &= ~VEHPARS_VPH_SET;
366 break;
367 case SUMO_ATTR_PERIOD:
368 parametersSet &= ~VEHPARS_PERIOD_SET;
369 break;
370 case GNE_ATTR_POISSON:
371 parametersSet &= ~VEHPARS_POISSON_SET;
372 break;
373 case SUMO_ATTR_PROB:
374 parametersSet &= ~VEHPARS_PROB_SET;
375 break;
376 default:
377 break;
378 }
379 }
380}
381
382
383void
385 // first check that this demand element is a flow
386 if (flowElement->getTagProperty().isFlow()) {
387 // end
388 if ((parametersSet & VEHPARS_END_SET) == 0) {
390 }
391 // number
392 if ((parametersSet & VEHPARS_NUMBER_SET) == 0) {
394 }
395 // vehicles/person/container per hour
396 if (((parametersSet & VEHPARS_PERIOD_SET) == 0) &&
398 ((parametersSet & VEHPARS_VPH_SET) == 0)) {
400 }
401 // probability
402 if ((parametersSet & VEHPARS_PROB_SET) == 0) {
404 }
405 // poisson
406 if (repetitionOffset < 0) {
410 }
411 }
412}
413
414std::string
416 // obtain value in string format with 20 decimals precision
417 auto valueStr = toString(value, 20);
418 // now clear all zeros
419 while (valueStr.size() > 1) {
420 if (valueStr.back() == '0') {
421 valueStr.pop_back();
422 } else if (valueStr.back() == '.') {
423 valueStr.pop_back();
424 return valueStr;
425 } else {
426 return valueStr;
427 }
428 }
429 return valueStr;
430}
431
432/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
@ GLO_PERSONFLOW
a person flow
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:69
#define STEPS2TIME(x)
Definition SUMOTime.h:55
#define TIME2STEPS(x)
Definition SUMOTime.h:57
const long long int VEHPARS_END_SET
const long long int VEHPARS_PERIOD_SET
const long long int VEHPARS_POISSON_SET
const long long int VEHPARS_PROB_SET
const long long int VEHPARS_VPH_SET
const long long int VEHPARS_NUMBER_SET
DepartDefinition
Possible ways to depart.
@ BEGIN
The departure is at simulation start.
@ NOW
The vehicle is discarded if emission fails (not fully implemented yet)
@ SPLIT
The departure is triggered by a train split.
@ CONTAINER_TRIGGERED
The departure is container triggered.
@ TRIGGERED
The departure is person triggered.
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_NUMBER
@ SUMO_ATTR_DEPART
@ SUMO_ATTR_VEHSPERHOUR
@ SUMO_ATTR_BEGIN
weights: time range begin
@ GNE_ATTR_POISSON
poisson definition (used in flow)
@ SUMO_ATTR_CONTAINERSPERHOUR
@ SUMO_ATTR_PERIOD
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_PROB
@ SUMO_ATTR_PERSONSPERHOUR
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition GLHelper.cpp:654
static void popMatrix()
pop matrix
Definition GLHelper.cpp:130
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition GLHelper.cpp:295
static void pushMatrix()
push matrix
Definition GLHelper.cpp:117
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0, const int align=0, double width=-1)
Definition GLHelper.cpp:756
const std::string & getTagStr() const
get tag assigned to this object in string format
const GNETagProperties & getTagProperty() const
get tagProperty associated with this Attribute Carrier
static void changeAttribute(GNEAttributeCarrier *AC, SumoXMLAttr key, const std::string &value, GNEUndoList *undoList, const bool force=false)
change attribute
the function-object for an editing operation (abstract base)
void setDefaultFlowAttributes(const GNEDemandElement *flowElement)
set flow default attributes
void toggleFlowAttribute(const SumoXMLAttr attribute, const bool value)
toggle flow parameters (used in toggleAttribute(...) function of vehicles, persons and containers
void drawFlowLabel(const Position &position, const double rotation, const double width, const double length, const double exaggeration) const
draw flow label
void disableFlowAttribute(GNEDemandElement *flowElement, SumoXMLAttr key, GNEUndoList *undoList)
bool isFlowAttributeEnabled(SumoXMLAttr key) const
double getFlowAttributeDouble(SumoXMLAttr key) const
bool isValidFlowAttribute(GNEDemandElement *flowElement, SumoXMLAttr key, const std::string &value)
void writeFlowAttributes(const GNEDemandElement *flowElement, OutputDevice &device) const
write flow attributes
std::string adjustDecimalValue(const double value) const
adjust decimal value
void enableFlowAttribute(GNEDemandElement *flowElement, SumoXMLAttr key, GNEUndoList *undoList)
std::string getFlowAttribute(SumoXMLAttr key) const
inherited from GNEAttributeCarrier and adapted to GNEDemandElementFlow
void setFlowAttribute(GNEDemandElement *flowElement, SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
GNEDemandElementFlow(const GNEDemandElement *flowElement)
constructor
bool isContainer() const
return true if tag correspond to a container element
bool isFlow() const
return true if tag correspond to a flow element
const std::string & getTagStr() const
get Tag vinculated with this attribute Property in String Format (used to avoid multiple calls to toS...
const std::string & getDefaultValue(SumoXMLAttr attr) const
return the default value of the attribute of an element
bool isPerson() const
return true if tag correspond to a person element
void add(GNEChange *command, bool doit=false, bool merge=true)
Add new command, executing it if desired. The new command will be merged with the previous command if...
Static storage of an output device and its base (abstract) implementation.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
double x() const
Returns the x-position.
Definition Position.h:55
double y() const
Returns the y-position.
Definition Position.h:60
static const RGBColor GREY
Definition RGBColor.h:194
static const RGBColor CYAN
Definition RGBColor.h:189
static const RGBColor BLACK
Definition RGBColor.h:193
Structure representing possible vehicle parameter.
double repetitionProbability
The probability for emitting a vehicle per second.
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
long long int parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
double poissonRate
The rate for emitting vehicles with a poisson distribution.
SUMOTime repetitionEnd
The time at which the flow ends (only needed when using repetitionProbability)
static bool parseDepart(const std::string &val, const std::string &element, const std::string &id, SUMOTime &depart, DepartDefinition &dd, std::string &error, const std::string &attr="departure")
Validates a given depart value.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.