Eclipse SUMO - Simulation of Urban MObility
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>
24 #include <utils/gui/div/GLHelper.h>
25 
26 #include "GNEDemandElementFlow.h"
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 
48 void
49 GNEDemandElementFlow::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 
73 void
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 
107 std::string
109  switch (key) {
110  case SUMO_ATTR_DEPART:
111  case SUMO_ATTR_BEGIN:
113  return "triggered";
115  return "containerTriggered";
116  } else if (departProcedure == DepartDefinition::NOW) {
117  return "now";
119  return "split";
121  return "begin";
122  } else {
123  return time2string(depart);
124  }
125  case SUMO_ATTR_END:
126  return time2string(repetitionEnd);
131  case SUMO_ATTR_PERIOD:
133  case GNE_ATTR_POISSON:
134  return toString(poissonRate);
135  case SUMO_ATTR_PROB:
137  case SUMO_ATTR_NUMBER:
138  return toString(repetitionNumber);
139  default:
140  throw InvalidArgument("Flow doesn't have an attribute of type '" + toString(key) + "'");
141  }
142 }
143 
144 
145 double
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 
157 void
158 GNEDemandElementFlow::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 
178 bool
179 GNEDemandElementFlow::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 
226 void
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, parametersSet), true);
238  return;
239  default:
240  throw InvalidArgument(flowElement->getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
241  }
242 }
243 
244 
245 void
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, parametersSet), true);
257  return;
258  default:
259  throw InvalidArgument(flowElement->getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
260  }
261 }
262 
263 
264 bool
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 
287 void
288 GNEDemandElementFlow::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:
307  repetitionOffset = string2time(value);
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 
326 void
327 GNEDemandElementFlow::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:
358  break;
359  case SUMO_ATTR_NUMBER:
361  break;
366  break;
367  case SUMO_ATTR_PERIOD:
369  break;
370  case GNE_ATTR_POISSON:
372  break;
373  case SUMO_ATTR_PROB:
375  break;
376  default:
377  break;
378  }
379  }
380 }
381 
382 
383 void
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) &&
397  ((parametersSet & VEHPARS_POISSON_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 
414 std::string
415 GNEDemandElementFlow::adjustDecimalValue(const double value) const {
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:35
@ 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 int VEHPARS_PROB_SET
const int VEHPARS_VPH_SET
const int VEHPARS_END_SET
const int VEHPARS_POISSON_SET
const int VEHPARS_NUMBER_SET
const int VEHPARS_PERIOD_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.
Definition: OutputDevice.h:61
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
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.
int parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
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.