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,
50 const double length, const double exaggeration) const {
51 // declare contour width
52 const double contourWidth = (0.05 * exaggeration);
53 // Push matrix
55 // Traslate to bot
56 glTranslated(position.x(), position.y(), GLO_VEHICLELABELS);
57 // glTranslated(position.x(), position.y(), GLO_ROUTE + getType() + 0.1 + GLO_PERSONFLOW + 0.1);
58 glRotated(rotation, 0, 0, -1);
59 glTranslated(-1 * ((width * 0.5 * exaggeration) + (0.35 * exaggeration)) - 0.05, 0, 0);
60 // draw external box
62 GLHelper::drawBoxLine(Position(), Position(), 0, (length * exaggeration), 0.3 * exaggeration);
63 // draw internal box
64 glTranslated(0, 0, 0.1);
66 GLHelper::drawBoxLine(Position(0, -contourWidth), Position(0, -contourWidth), 0, (length * exaggeration) - (contourWidth * 2), (0.3 * exaggeration) - contourWidth);
67 // draw stack label
68 GLHelper::drawText("Flow", Position(0, length * exaggeration * -0.5), (.1 * exaggeration), (0.6 * exaggeration), RGBColor::BLACK, 90, 0, -1);
69 // pop draw matrix
71}
72
73
74void
76 // get xph attribute
78 if (flowElement->getTagProperty().isPerson()) {
80 } else if (flowElement->getTagProperty().isContainer()) {
82 }
83 // first check that we're writting a flow
84 if (flowElement->getTagProperty().isFlow()) {
85 // write routeFlow values depending if it was set
88 }
91 }
92 if (isFlowAttributeEnabled(xph)) {
93 device.writeAttr(xph, getFlowAttribute(flowElement, xph));
94 }
97 }
99 device.writeAttr(SUMO_ATTR_PERIOD, "exp(" + getFlowAttribute(flowElement, GNE_ATTR_POISSON) + ")");
100 }
103 }
104 }
105}
106
107
108std::string
110 switch (key) {
111 case SUMO_ATTR_DEPART:
112 case SUMO_ATTR_BEGIN:
114 return "triggered";
116 return "containerTriggered";
118 return "now";
120 return "split";
122 return "begin";
123 } else {
124 return time2string(depart);
125 }
126 case SUMO_ATTR_END:
132 case SUMO_ATTR_PERIOD:
134 case GNE_ATTR_POISSON:
135 return toString(poissonRate);
136 case SUMO_ATTR_PROB:
138 case SUMO_ATTR_NUMBER:
144 } else {
145 return toString(SUMO_ATTR_END);
146 }
149 } else {
150 return "invalid terminate";
151 }
162 return toString(SUMO_ATTR_PROB);
165 } else {
166 return "invalid flow spacing";
167 }
168 default:
169 return flowElement->getCommonAttribute(key);
170 }
171}
172
173
174double
176 switch (key) {
177 case SUMO_ATTR_DEPART:
178 case SUMO_ATTR_BEGIN:
179 return STEPS2TIME(depart);
180 default:
181 throw InvalidArgument("Flow doesn't have a double attribute of type '" + toString(key) + "'");
182 }
183}
184
185
186void
187GNEDemandElementFlow::setFlowAttribute(GNEDemandElement* flowElement, SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
188 switch (key) {
189 case SUMO_ATTR_DEPART:
190 case SUMO_ATTR_BEGIN:
191 case SUMO_ATTR_END:
192 case SUMO_ATTR_NUMBER:
196 case SUMO_ATTR_PERIOD:
197 case GNE_ATTR_POISSON:
198 case SUMO_ATTR_PROB:
201 GNEChange_Attribute::changeAttribute(flowElement, key, value, undoList);
202 break;
203 default:
204 return flowElement->setCommonAttribute(key, value, undoList);
205 break;
206 }
207}
208
209
210bool
211GNEDemandElementFlow::isValidFlowAttribute(GNEDemandElement* flowElement, SumoXMLAttr key, const std::string& value) {
212 // declare string error
213 std::string error;
214 switch (key) {
215 case SUMO_ATTR_DEPART:
216 case SUMO_ATTR_BEGIN: {
217 SUMOTime dummyDepart;
218 DepartDefinition dummyDepartProcedure;
219 parseDepart(value, flowElement->getTagProperty().getTagStr(), id, dummyDepart, dummyDepartProcedure, error);
220 // if error is empty, given value is valid
221 return error.empty();
222 }
223 case SUMO_ATTR_END:
224 if (GNEAttributeCarrier::canParse<SUMOTime>(value)) {
225 return (GNEAttributeCarrier::parse<SUMOTime>(value) >= 0);
226 } else {
227 return false;
228 }
232 case SUMO_ATTR_PERIOD:
233 case GNE_ATTR_POISSON:
234 if (GNEAttributeCarrier::canParse<double>(value)) {
235 return (GNEAttributeCarrier::parse<double>(value) > 0);
236 } else {
237 return false;
238 }
239 case SUMO_ATTR_PROB:
240 if (GNEAttributeCarrier::canParse<double>(value)) {
241 const double prob = GNEAttributeCarrier::parse<double>(value);
242 return ((prob >= 0) && (prob <= 1));
243 } else {
244 return false;
245 }
246 case SUMO_ATTR_NUMBER:
247 if (GNEAttributeCarrier::canParse<int>(value)) {
248 return (GNEAttributeCarrier::parse<int>(value) >= 0);
249 } else {
250 return false;
251 }
254 const auto& flowValues = flowElement->getTagProperty().getAttributeProperties(key).getDiscreteValues();
255 if (std::find(flowValues.begin(), flowValues.end(), value) != flowValues.end()) {
256 return true;
257 } else {
258 return false;
259 }
260 }
261 default:
262 return flowElement->isCommonValid(key, value);
263 }
264}
265
266
267void
269 switch (key) {
270 case SUMO_ATTR_END:
271 case SUMO_ATTR_NUMBER:
275 case SUMO_ATTR_PERIOD:
276 case GNE_ATTR_POISSON:
277 case SUMO_ATTR_PROB:
278 undoList->add(new GNEChange_ToggleAttribute(flowElement, key, true), true);
279 return;
280 default:
281 throw InvalidArgument(flowElement->getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
282 }
283}
284
285
286void
288 switch (key) {
289 case SUMO_ATTR_END:
290 case SUMO_ATTR_NUMBER:
294 case SUMO_ATTR_PERIOD:
295 case GNE_ATTR_POISSON:
296 case SUMO_ATTR_PROB:
297 undoList->add(new GNEChange_ToggleAttribute(flowElement, key, false), true);
298 return;
299 default:
300 throw InvalidArgument(flowElement->getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
301 }
302}
303
304
305bool
307 switch (key) {
308 case SUMO_ATTR_END:
309 return (parametersSet & VEHPARS_END_SET) != 0;
310 case SUMO_ATTR_NUMBER:
311 return (parametersSet & VEHPARS_NUMBER_SET) != 0;
315 return (parametersSet & VEHPARS_VPH_SET) != 0;
316 case SUMO_ATTR_PERIOD:
317 return (parametersSet & VEHPARS_PERIOD_SET) != 0;
318 case GNE_ATTR_POISSON:
319 return (parametersSet & VEHPARS_POISSON_SET) != 0;
320 case SUMO_ATTR_PROB:
321 return (parametersSet & VEHPARS_PROB_SET) != 0;
324 default:
325 return true;
326 }
327}
328
329
330void
331GNEDemandElementFlow::setFlowAttribute(GNEDemandElement* flowElement, SumoXMLAttr key, const std::string& value) {
332 // declare string error
333 std::string error;
334 switch (key) {
335 case SUMO_ATTR_DEPART:
336 case SUMO_ATTR_BEGIN: {
337 parseDepart(value, flowElement->getTagProperty().getTagStr(), id, depart, departProcedure, error);
338 break;
339 }
340 case SUMO_ATTR_END:
341 repetitionEnd = string2time(value);
342 break;
346 repetitionOffset = TIME2STEPS(3600 / GNEAttributeCarrier::parse<double>(value));
347 poissonRate = GNEAttributeCarrier::parse<double>(value) / 3600;
348 break;
349 case SUMO_ATTR_PERIOD:
352 break;
353 case GNE_ATTR_POISSON:
354 poissonRate = GNEAttributeCarrier::parse<double>(value);
356 break;
357 case SUMO_ATTR_PROB:
358 repetitionProbability = GNEAttributeCarrier::parse<double>(value);
359 break;
360 case SUMO_ATTR_NUMBER:
361 repetitionNumber = GNEAttributeCarrier::parse<int>(value);
362 break;
364 if (value == (toString(SUMO_ATTR_END) + "-" + toString(SUMO_ATTR_NUMBER))) {
367 // in this special case, disable other spacing
372 } else {
373 // if previously end-number was enabled, enable perHour
376 }
377 if (value == toString(SUMO_ATTR_END)) {
380 } else if (value == toString(SUMO_ATTR_NUMBER)) {
383 }
384 }
385 break;
387 if ((value == toString(SUMO_ATTR_VEHSPERHOUR)) ||
394 } else if (value == toString(SUMO_ATTR_PERIOD)) {
399 } else if (value == toString(GNE_ATTR_POISSON)) {
404 } else if (value == toString(SUMO_ATTR_PROB)) {
409 }
410 break;
411 default:
412 flowElement->setCommonAttribute(key, value);
413 break;
414 }
415}
416
417
418void
419GNEDemandElementFlow::toggleFlowAttribute(const SumoXMLAttr attribute, const bool value) {
420 // modify parameters depending of given Flow attribute
421 if (value) {
422 switch (attribute) {
423 case SUMO_ATTR_END:
425 break;
426 case SUMO_ATTR_NUMBER:
428 break;
433 break;
434 case SUMO_ATTR_PERIOD:
436 break;
437 case GNE_ATTR_POISSON:
439 break;
440 case SUMO_ATTR_PROB:
442 break;
443 default:
444 break;
445 }
446 } else {
447 switch (attribute) {
448 case SUMO_ATTR_END:
449 parametersSet &= ~VEHPARS_END_SET;
450 break;
451 case SUMO_ATTR_NUMBER:
452 parametersSet &= ~VEHPARS_NUMBER_SET;
453 break;
457 parametersSet &= ~VEHPARS_VPH_SET;
458 break;
459 case SUMO_ATTR_PERIOD:
460 parametersSet &= ~VEHPARS_PERIOD_SET;
461 break;
462 case GNE_ATTR_POISSON:
463 parametersSet &= ~VEHPARS_POISSON_SET;
464 break;
465 case SUMO_ATTR_PROB:
466 parametersSet &= ~VEHPARS_PROB_SET;
467 break;
468 default:
469 break;
470 }
471 }
472}
473
474
475void
477 // first check that this demand element is a flow
478 if (flowElement->getTagProperty().isFlow()) {
479 // end
480 if ((parametersSet & VEHPARS_END_SET) == 0) {
482 }
483 // number
484 if ((parametersSet & VEHPARS_NUMBER_SET) == 0) {
486 }
487 // vehicles/person/container per hour
488 if (((parametersSet & VEHPARS_PERIOD_SET) == 0) &&
490 ((parametersSet & VEHPARS_VPH_SET) == 0)) {
492 }
493 // probability
494 if ((parametersSet & VEHPARS_PROB_SET) == 0) {
496 }
497 // poisson
498 if (repetitionOffset < 0) {
502 }
503 }
504}
505
506std::string
508 // obtain value in string format with 20 decimals precision
509 auto valueStr = toString(value, 20);
510 // now clear all zeros
511 while (valueStr.size() > 1) {
512 if (valueStr.back() == '0') {
513 valueStr.pop_back();
514 } else if (valueStr.back() == '.') {
515 valueStr.pop_back();
516 return valueStr;
517 } else {
518 return valueStr;
519 }
520 }
521 return valueStr;
522}
523
524/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
@ GLO_VEHICLELABELS
stack and flow labels (used in netedit)
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
@ GNE_ATTR_FLOW_SPACING
flow spacing
@ GNE_ATTR_FLOW_TERMINATE
flow terminating
@ 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:649
static void popMatrix()
pop matrix
Definition GLHelper.cpp:131
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition GLHelper.cpp:296
static void pushMatrix()
push matrix
Definition GLHelper.cpp:118
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:751
void setCommonAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
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
bool isCommonValid(SumoXMLAttr key, const std::string &value)
std::string getCommonAttribute(SumoXMLAttr key) const
const std::vector< std::string > & getDiscreteValues() const
get discrete values
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 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
std::string getFlowAttribute(const GNEDemandElement *flowElement, SumoXMLAttr key) const
inherited from GNEAttributeCarrier and adapted to GNEDemandElementFlow
void disableFlowAttribute(GNEDemandElement *flowElement, SumoXMLAttr key, GNEUndoList *undoList)
bool isFlowAttributeEnabled(SumoXMLAttr key) const
double getFlowAttributeDouble(SumoXMLAttr key) const
GNEDemandElementFlow(GNEDemandElement *flowElement)
constructor
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)
void setFlowAttribute(GNEDemandElement *flowElement, SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
void setDefaultFlowAttributes(GNEDemandElement *flowElement)
set flow default attributes
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 GNEAttributeProperties & getAttributeProperties(SumoXMLAttr attr) const
get attribute propety associated with the given Sumo XML Attribute (throw error if doesn't exist)
const std::string & getDefaultValue(SumoXMLAttr attr) const
return the default value of the attribute of an element
bool hasAttribute(SumoXMLAttr attr) const
check if current TagProperties owns the attribute "attr"
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.