SUMO - Simulation of Urban MObility
GUITriggeredRerouter.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // Reroutes vehicles passing an edge (gui version)
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
12 // Copyright (C) 2001-2015 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <string>
36 #include <utils/geom/Line.h>
37 #include <utils/geom/Boundary.h>
38 #include <utils/gui/div/GLHelper.h>
39 #include <utils/common/ToString.h>
40 #include <utils/common/Command.h>
41 #include <microsim/MSNet.h>
42 #include <microsim/MSLane.h>
43 #include <microsim/MSEdge.h>
44 #include <guisim/GUINet.h>
45 #include <guisim/GUIEdge.h>
46 #include "GUITriggeredRerouter.h"
49 #include <gui/GUIGlobals.h>
56 
57 #ifdef CHECK_MEMORY_LEAKS
58 #include <foreign/nvwa/debug_new.h>
59 #endif // CHECK_MEMORY_LEAKS
60 
61 
62 // ===========================================================================
63 // FOX callback mapping
64 // ===========================================================================
65 /* -------------------------------------------------------------------------
66  * GUITriggeredRerouter::GUITriggeredRerouterPopupMenu - mapping
67  * ----------------------------------------------------------------------- */
71 
72 };
73 
74 // Object implementation
76 
77 
78 /* -------------------------------------------------------------------------
79  * GUITriggeredRerouter::GUIManip_TriggeredRerouter - mapping
80  * ----------------------------------------------------------------------- */
81 FXDEFMAP(GUITriggeredRerouter::GUIManip_TriggeredRerouter) GUIManip_TriggeredRerouterMap[] = {
86 };
87 
88 FXIMPLEMENT(GUITriggeredRerouter::GUIManip_TriggeredRerouter, GUIManipulator, GUIManip_TriggeredRerouterMap, ARRAYNUMBER(GUIManip_TriggeredRerouterMap))
89 
90 
91 // ===========================================================================
92 // method definitions
93 // ===========================================================================
94 /* -------------------------------------------------------------------------
95  * GUITriggeredRerouter::GUIManip_TriggeredRerouter - methods
96  * ----------------------------------------------------------------------- */
98  GUIMainWindow& app,
99  const std::string& name, GUITriggeredRerouter& o,
100  int /*xpos*/, int /*ypos*/)
101  : GUIManipulator(app, name, 0, 0), myParent(&app),
102  myChosenValue(0), myChosenTarget(myChosenValue, NULL, MID_OPTION),
103  myUsageProbability(o.getProbability()), myUsageProbabilityTarget(myUsageProbability),
104  myObject(&o) {
105  myChosenTarget.setTarget(this);
106  FXVerticalFrame* f1 =
107  new FXVerticalFrame(this, LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0);
108 
109  FXGroupBox* gp = new FXGroupBox(f1, "Change Probability",
110  GROUPBOX_TITLE_LEFT | FRAME_SUNKEN | FRAME_RIDGE,
111  0, 0, 0, 0, 4, 4, 1, 1, 2, 0);
112  {
113  // default
114  FXHorizontalFrame* gf1 =
115  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
116  new FXRadioButton(gf1, "Default", &myChosenTarget, FXDataTarget::ID_OPTION + 0,
117  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
118  0, 0, 0, 0, 2, 2, 0, 0);
119  }
120  {
121  // free
122  FXHorizontalFrame* gf12 =
123  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
124  new FXRadioButton(gf12, "User Given: ", &myChosenTarget, FXDataTarget::ID_OPTION + 1,
125  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y,
126  0, 0, 0, 0, 2, 2, 0, 0);
127  myUsageProbabilityDial =
128  new FXRealSpinDial(gf12, 10, this, MID_USER_DEF,
129  LAYOUT_TOP | FRAME_SUNKEN | FRAME_THICK);
130  myUsageProbabilityDial->setFormatString("%.2f");
131  myUsageProbabilityDial->setIncrements(.1, .1, .1);
132  myUsageProbabilityDial->setRange(0, 1);
133  myUsageProbabilityDial->setValue(myObject->getUserProbability());
134  }
135  {
136  // off
137  FXHorizontalFrame* gf13 =
138  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
139  new FXRadioButton(gf13, "Off", &myChosenTarget, FXDataTarget::ID_OPTION + 2,
140  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
141  0, 0, 0, 0, 2, 2, 0, 0);
142  }
143  myChosenValue = myObject->inUserMode()
144  ? myObject->getUserProbability() > 0
145  ? 1 : 2
146  : 0;
147  new FXButton(f1, "Close", NULL, this, MID_CLOSE,
148  BUTTON_INITIAL | BUTTON_DEFAULT | FRAME_RAISED | FRAME_THICK | LAYOUT_TOP | LAYOUT_LEFT | LAYOUT_CENTER_X, 0, 0, 0, 0, 30, 30, 4, 4);
149 }
150 
151 
153 
154 
155 long
157  destroy();
158  return 1;
159 }
160 
161 
162 long
164  myUsageProbability = (SUMOReal)(myUsageProbabilityDial->getValue());
165  static_cast<GUITriggeredRerouter*>(myObject)->setUserUsageProbability(myUsageProbability);
166  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(true);
167  myParent->updateChildren();
168  return 1;
169 }
170 
171 
172 long
174  sender->handle(this,
175  myChosenValue != 1 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
176  ptr);
177  myParent->updateChildren();
178  return 1;
179 }
180 
181 
182 long
184  static_cast<GUITriggeredRerouter*>(myObject)->setUserUsageProbability(myUsageProbability);
185  switch (myChosenValue) {
186  case 0:
187  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(false);
188  break;
189  case 1:
190  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(true);
191  break;
192  case 2:
193  static_cast<GUITriggeredRerouter*>(myObject)->setUserUsageProbability(0);
194  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(true);
195  break;
196  default:
197  throw 1;
198  }
199  myParent->updateChildren();
200  return 1;
201 }
202 
203 
204 /* -------------------------------------------------------------------------
205  * GUITriggeredRerouter::GUITriggeredRerouterPopupMenu - methods
206  * ----------------------------------------------------------------------- */
208  GUIMainWindow& app, GUISUMOAbstractView& parent,
209  GUIGlObject& o)
210  : GUIGLObjectPopupMenu(app, parent, o) {}
211 
212 
214 
215 
216 long
218  FXSelector,
219  void*) {
220  static_cast<GUITriggeredRerouter*>(myObject)->openManipulator(
221  *myApplication, *myParent);
222  return 1;
223 }
224 
225 
226 /* -------------------------------------------------------------------------
227  * GUITriggeredRerouter - methods
228  * ----------------------------------------------------------------------- */
230  const std::string& id,
231  const MSEdgeVector& edges,
232  SUMOReal prob, const std::string& aXMLFilename, bool off,
233  SUMORTree& rtree) :
234  MSTriggeredRerouter(id, edges, prob, aXMLFilename, off),
235  GUIGlObject_AbstractAdd("rerouter", GLO_TRIGGER, id) {
236  // add visualisation objects for edges which trigger the rerouter
237  for (MSEdgeVector::const_iterator it = edges.begin(); it != edges.end(); ++it) {
238  myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast<GUIEdge*>(*it), this, false));
240  myBoundary.add(myEdgeVisualizations.back()->getCenteringBoundary());
241  }
242 }
243 
244 
246  for (std::vector<GUITriggeredRerouterEdge*>::iterator it = myEdgeVisualizations.begin(); it != myEdgeVisualizations.end(); ++it) {
247  delete *it;
248  }
249  myEdgeVisualizations.clear();
250 }
251 
252 
253 void
256  if (element == SUMO_TAG_INTERVAL) {
257  // add visualisation objects for closed edges
258  const RerouteInterval& ri = myIntervals.back();
259  for (MSEdgeVector::const_iterator it = ri.closed.begin(); it != ri.closed.end(); ++it) {
260  myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast<GUIEdge*>(*it), this, true));
261  dynamic_cast<GUINet*>(GUINet::getInstance())->getVisualisationSpeedUp().addAdditionalGLObject(myEdgeVisualizations.back());
262  myBoundary.add(myEdgeVisualizations.back()->getCenteringBoundary());
263  }
264  }
265 }
266 
267 
270  GUISUMOAbstractView& parent) {
271  GUIGLObjectPopupMenu* ret = new GUITriggeredRerouterPopupMenu(app, parent, *this);
272  buildPopupHeader(ret, app);
274  buildShowManipulatorPopupEntry(ret, false);
277  buildPositionCopyEntry(ret, false);
278  return ret;
279 }
280 
281 
285  return 0;
286 }
287 
288 
289 void
291  UNUSED_PARAMETER(s);
292 }
293 
294 
295 Boundary
297  Boundary b(myBoundary);
298  b.grow(20);
299  return b;
300 }
301 
302 
303 
308  new GUIManip_TriggeredRerouter(app, getFullName(), *this, 0, 0);
309  gui->create();
310  gui->show();
311  return gui;
312 }
313 
314 
315 /* -------------------------------------------------------------------------
316  * GUITriggeredRerouterEdge - methods
317  * ----------------------------------------------------------------------- */
319  GUIGlObject("rerouter_edge", GLO_TRIGGER, parent->getID() + ":" + edge->getID()),
320  myParent(parent),
321  myEdge(edge),
322  myAmClosedEdge(closed) {
323  const std::vector<MSLane*>& lanes = edge->getLanes();
324  myFGPositions.reserve(lanes.size());
325  myFGRotations.reserve(lanes.size());
326  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
327  const PositionVector& v = (*i)->getShape();
328  const SUMOReal pos = closed ? 3 : v.length() - (SUMOReal) 6.;
329  myFGPositions.push_back((*i)->geometryPositionAtOffset(pos));
330  myFGRotations.push_back(-v.rotationDegreeAtOffset(pos));
331  myBoundary.add(myFGPositions.back());
332  }
333 }
334 
335 
337 
338 
341  GUISUMOAbstractView& parent) {
342  return myParent->getPopUpMenu(app, parent);
343 }
344 
345 
349  return 0;
350 }
351 
352 
353 void
355  const SUMOReal exaggeration = s.addSize.getExaggeration(s);
356  if (s.scale * exaggeration >= 3) {
357  glPushName(getGlID());
358  const SUMOReal prob = myParent->getProbability();
359  if (myAmClosedEdge) {
360  // draw closing symbol onto all lanes
361  const RerouteInterval* const ri =
362  myParent->getCurrentReroute(MSNet::getInstance()->getCurrentTimeStep());
363  if (ri != 0 && prob > 0) {
364  // draw only if the edge is closed at this time
365  if (std::find(ri->closed.begin(), ri->closed.end(), myEdge) != ri->closed.end()) {
366  const size_t noLanes = myFGPositions.size();
367  for (size_t j = 0; j < noLanes; ++j) {
368  Position pos = myFGPositions[j];
369  SUMOReal rot = myFGRotations[j];
370  glPushMatrix();
371  glTranslated(pos.x(), pos.y(), 0);
372  glRotated(rot, 0, 0, 1);
373  glTranslated(0, -1.5, 0);
374  int noPoints = 9;
375  if (s.scale > 25) {
376  noPoints = (int)(9.0 + s.scale / 10.0);
377  if (noPoints > 36) {
378  noPoints = 36;
379  }
380  }
381  glTranslated(0, 0, getType());
382  //glScaled(exaggeration, exaggeration, 1);
383  glColor3d(0.7, 0, 0);
384  GLHelper::drawFilledCircle((SUMOReal) 1.3, noPoints);
385  glTranslated(0, 0, .1);
386  glColor3d(1, 0, 0);
387  GLHelper::drawFilledCircle((SUMOReal) 1.3, noPoints, 0, prob * 360);
388  glTranslated(0, 0, .1);
389  glColor3d(1, 1, 1);
390  glRotated(-90, 0, 0, 1);
391  glBegin(GL_TRIANGLES);
392  glVertex2d(0 - .3, -1.);
393  glVertex2d(0 - .3, 1.);
394  glVertex2d(0 + .3, 1.);
395  glVertex2d(0 + .3, -1.);
396  glVertex2d(0 - .3, -1.);
397  glVertex2d(0 + .3, 1.);
398  glEnd();
399  glPopMatrix();
400  }
401  }
402  }
403 
404  } else {
405  // draw rerouter symbol onto all lanes
406  for (size_t i = 0; i < myFGPositions.size(); ++i) {
407  const Position& pos = myFGPositions[i];
408  SUMOReal rot = myFGRotations[i];
409  glPushMatrix();
410  glTranslated(pos.x(), pos.y(), 0);
411  glRotated(rot, 0, 0, 1);
412  glTranslated(0, 0, getType());
413  glScaled(exaggeration, exaggeration, 1);
414  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
415 
416  glBegin(GL_TRIANGLES);
417  glColor3d(1, .8f, 0);
418  // base
419  glVertex2d(0 - 1.4, 0);
420  glVertex2d(0 - 1.4, 6);
421  glVertex2d(0 + 1.4, 6);
422  glVertex2d(0 + 1.4, 0);
423  glVertex2d(0 - 1.4, 0);
424  glVertex2d(0 + 1.4, 6);
425  glEnd();
426 
427  glTranslated(0, 0, .1);
428  glColor3d(0, 0, 0);
429  pfSetPosition(0, 0);
430  pfSetScale(3.f);
431  SUMOReal w = pfdkGetStringWidth("U");
432  glRotated(180, 0, 1, 0);
433  glTranslated(-w / 2., 2, 0);
434  pfDrawString("U");
435 
436  glTranslated(w / 2., -2, 0);
437  std::string str = toString((int)(prob * 100)) + "%";
438  pfSetPosition(0, 0);
439  pfSetScale(.7f);
440  w = pfdkGetStringWidth(str.c_str());
441  glTranslated(-w / 2., 4, 0);
442  pfDrawString(str.c_str());
443  glPopMatrix();
444  }
445  }
446  glPopName();
447  }
448 }
449 
450 
451 Boundary
453  Boundary b(myBoundary);
454  b.grow(20);
455  return b;
456 }
457 
458 
459 /****************************************************************************/
460 
int pfDrawString(const char *c)
Definition: polyfonts.c:1074
long onCmdClose(FXObject *, FXSelector, void *)
MSEdgeVector closed
The list of closed edges.
a lane speed trigger,
GUITriggeredRerouterEdge(GUIEdge *edge, GUITriggeredRerouter *parent, bool closed)
Reroutes vehicles passing an edge One rerouter can be active on multiple edges. To reduce drawing loa...
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
std::vector< GUITriggeredRerouterEdge * > myEdgeVisualizations
FXDEFMAP(GUITriggeredRerouter::GUIManip_TriggeredRerouter) GUIManip_TriggeredRerouterMap[]
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:186
GUIManipulator * openManipulator(GUIMainWindow &app, GUISUMOAbstractView &parent)
Stores the information about how to visualize structures.
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
void pfSetPosition(SUMOReal x, SUMOReal y)
Definition: polyfonts.c:480
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
void setUserUsageProbability(SUMOReal prob)
Sets the probability with which a vehicle is rerouted given by the user.
void setUserMode(bool val)
Sets whether the process is currently steered by the user.
GUITriggeredRerouterPopupMenuMap[]
A RT-tree for efficient storing of SUMO's GL-objects.
Definition: SUMORTree.h:74
SUMOReal x() const
Returns the x-position.
Definition: Position.h:63
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to copy the cursor position if geo projection is used, also builds an entry for copying the geo-position.
GUIGlID getGlID() const
Returns the numerical id of the object.
Definition: GUIGlObject.h:115
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
SUMOReal scale
information about a lane's width (temporary, used for a single view)
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
static void drawFilledCircle(SUMOReal width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:344
A road/street connecting two junctions (gui-version)
Definition: GUIEdge.h:61
virtual void myEndElement(int element)
Called when a closing tag occurs.
GUIVisualizationSizeSettings addSize
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
Definition: GUIGlObject.h:159
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
A list of positions.
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Open the object's manipulator.
Definition: GUIAppEnum.h:237
long onCmdUserDef(FXObject *, FXSelector, void *)
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
Boundary myBoundary
The boundary of this rerouter.
long onCmdOpenManip(FXObject *, FXSelector, void *)
Called if the object's manipulator shall be shown.
long onUpdUserDef(FXObject *, FXSelector, void *)
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
long onCmdChangeOption(FXObject *, FXSelector, void *)
RotCont myFGRotations
The rotations in full-geometry mode.
SUMOReal length() const
Returns the length.
SUMOReal rotationDegreeAtOffset(SUMOReal pos) const
Returns the rotation at the given length.
void buildShowManipulatorPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the manipulator window.
Reroutes vehicles passing an edge.
void add(SUMOReal x, SUMOReal y)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:76
Boundary & grow(SUMOReal by)
extends the boundary by the given amount
Definition: Boundary.cpp:200
A MSNet extended by some values for usage within the gui.
Definition: GUINet.h:90
void pfSetScale(SUMOReal s)
Definition: polyfonts.c:465
void addAdditionalGLObject(GUIGlObject *o)
Adds an additional object (detector/shape/trigger) for visualisation.
Definition: SUMORTree.h:129
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
std::vector< RerouteInterval > myIntervals
List of rerouting definition intervals.
The popup menu of a globject.
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
void buildSelectionPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to (de)select the object.
SUMOReal pfdkGetStringWidth(const char *c)
Definition: polyfonts.c:1113
#define SUMOReal
Definition: config.h:218
Close simulation - ID.
Definition: GUIAppEnum.h:83
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:78
void myEndElement(int element)
Called when a closing tag occurs.
Spinner control.
Boundary myBoundary
The boundary of this rerouter.
const std::string & getFullName() const
Returns the full name appearing in the tool tip.
Definition: GUIGlObject.h:107
A window containing a gl-object's parameter.
GUITriggeredRerouter(const std::string &id, const MSEdgeVector &edges, SUMOReal prob, const std::string &aXMLFilename, bool off, SUMORTree &rtree)
Constructor.
SUMOReal getExaggeration(const GUIVisualizationSettings &s) const
return the drawing size including exaggeration and constantSize values
PosCont myFGPositions
The positions in full-geometry mode.
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.