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-2016 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/Boundary.h>
37 #include <utils/gui/div/GLHelper.h>
38 #include <utils/common/ToString.h>
39 #include <utils/common/Command.h>
40 #include <microsim/MSNet.h>
41 #include <microsim/MSLane.h>
42 #include <microsim/MSEdge.h>
43 #include <guisim/GUINet.h>
44 #include <guisim/GUIEdge.h>
45 #include "GUITriggeredRerouter.h"
48 #include <gui/GUIGlobals.h>
55 
56 #ifdef CHECK_MEMORY_LEAKS
57 #include <foreign/nvwa/debug_new.h>
58 #endif // CHECK_MEMORY_LEAKS
59 
60 
61 // ===========================================================================
62 // FOX callback mapping
63 // ===========================================================================
64 /* -------------------------------------------------------------------------
65  * GUITriggeredRerouter::GUITriggeredRerouterPopupMenu - mapping
66  * ----------------------------------------------------------------------- */
70 
71 };
72 
73 // Object implementation
75 
76 
77 /* -------------------------------------------------------------------------
78  * GUITriggeredRerouter::GUIManip_TriggeredRerouter - mapping
79  * ----------------------------------------------------------------------- */
80 FXDEFMAP(GUITriggeredRerouter::GUIManip_TriggeredRerouter) GUIManip_TriggeredRerouterMap[] = {
85 };
86 
87 FXIMPLEMENT(GUITriggeredRerouter::GUIManip_TriggeredRerouter, GUIManipulator, GUIManip_TriggeredRerouterMap, ARRAYNUMBER(GUIManip_TriggeredRerouterMap))
88 
89 
90 // ===========================================================================
91 // method definitions
92 // ===========================================================================
93 /* -------------------------------------------------------------------------
94  * GUITriggeredRerouter::GUIManip_TriggeredRerouter - methods
95  * ----------------------------------------------------------------------- */
97  GUIMainWindow& app,
98  const std::string& name, GUITriggeredRerouter& o,
99  int /*xpos*/, int /*ypos*/)
100  : GUIManipulator(app, name, 0, 0), myParent(&app),
101  myChosenValue(0), myChosenTarget(myChosenValue, NULL, MID_OPTION),
102  myUsageProbability(o.getProbability()), myUsageProbabilityTarget(myUsageProbability),
103  myObject(&o) {
104  myChosenTarget.setTarget(this);
105  FXVerticalFrame* f1 =
106  new FXVerticalFrame(this, LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0);
107 
108  FXGroupBox* gp = new FXGroupBox(f1, "Change Probability",
109  GROUPBOX_TITLE_LEFT | FRAME_SUNKEN | FRAME_RIDGE,
110  0, 0, 0, 0, 4, 4, 1, 1, 2, 0);
111  {
112  // default
113  FXHorizontalFrame* gf1 =
114  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
115  new FXRadioButton(gf1, "Default", &myChosenTarget, FXDataTarget::ID_OPTION + 0,
116  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
117  0, 0, 0, 0, 2, 2, 0, 0);
118  }
119  {
120  // free
121  FXHorizontalFrame* gf12 =
122  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
123  new FXRadioButton(gf12, "User Given: ", &myChosenTarget, FXDataTarget::ID_OPTION + 1,
124  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y,
125  0, 0, 0, 0, 2, 2, 0, 0);
126  myUsageProbabilityDial =
127  new FXRealSpinDial(gf12, 10, this, MID_USER_DEF,
128  LAYOUT_TOP | FRAME_SUNKEN | FRAME_THICK);
129  myUsageProbabilityDial->setFormatString("%.2f");
130  myUsageProbabilityDial->setIncrements(.1, .1, .1);
131  myUsageProbabilityDial->setRange(0, 1);
132  myUsageProbabilityDial->setValue(myObject->getUserProbability());
133  }
134  {
135  // off
136  FXHorizontalFrame* gf13 =
137  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
138  new FXRadioButton(gf13, "Off", &myChosenTarget, FXDataTarget::ID_OPTION + 2,
139  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
140  0, 0, 0, 0, 2, 2, 0, 0);
141  }
142  myChosenValue = myObject->inUserMode()
143  ? myObject->getUserProbability() > 0
144  ? 1 : 2
145  : 0;
146  new FXButton(f1, "Close", NULL, this, MID_CLOSE,
147  BUTTON_INITIAL | BUTTON_DEFAULT | FRAME_RAISED | FRAME_THICK | LAYOUT_TOP | LAYOUT_LEFT | LAYOUT_CENTER_X, 0, 0, 0, 0, 30, 30, 4, 4);
148 }
149 
150 
152 
153 
154 long
156  destroy();
157  return 1;
158 }
159 
160 
161 long
165  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(true);
167  return 1;
168 }
169 
170 
171 long
172 GUITriggeredRerouter::GUIManip_TriggeredRerouter::onUpdUserDef(FXObject* sender, FXSelector, void* ptr) {
173  sender->handle(this,
174  myChosenValue != 1 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
175  ptr);
177  return 1;
178 }
179 
180 
181 long
184  switch (myChosenValue) {
185  case 0:
186  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(false);
187  break;
188  case 1:
189  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(true);
190  break;
191  case 2:
193  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(true);
194  break;
195  default:
196  throw 1;
197  }
199  return 1;
200 }
201 
202 
203 /* -------------------------------------------------------------------------
204  * GUITriggeredRerouter::GUITriggeredRerouterPopupMenu - methods
205  * ----------------------------------------------------------------------- */
207  GUIMainWindow& app, GUISUMOAbstractView& parent,
208  GUIGlObject& o)
209  : GUIGLObjectPopupMenu(app, parent, o) {}
210 
211 
213 
214 
215 long
217  FXSelector,
218  void*) {
221  return 1;
222 }
223 
224 
225 /* -------------------------------------------------------------------------
226  * GUITriggeredRerouter - methods
227  * ----------------------------------------------------------------------- */
229  const std::string& id,
230  const MSEdgeVector& edges,
231  SUMOReal prob, const std::string& aXMLFilename, bool off,
232  SUMORTree& rtree) :
233  MSTriggeredRerouter(id, edges, prob, aXMLFilename, off),
234  GUIGlObject_AbstractAdd("rerouter", GLO_TRIGGER, id) {
235  // add visualisation objects for edges which trigger the rerouter
236  for (MSEdgeVector::const_iterator it = edges.begin(); it != edges.end(); ++it) {
237  myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast<GUIEdge*>(*it), this, false));
239  myBoundary.add(myEdgeVisualizations.back()->getCenteringBoundary());
240  }
241 }
242 
243 
245  for (std::vector<GUITriggeredRerouterEdge*>::iterator it = myEdgeVisualizations.begin(); it != myEdgeVisualizations.end(); ++it) {
246  delete *it;
247  }
248  myEdgeVisualizations.clear();
249 }
250 
251 
252 void
255  if (element == SUMO_TAG_INTERVAL) {
256  // add visualisation objects for closed edges
257  const RerouteInterval& ri = myIntervals.back();
258  for (MSEdgeVector::const_iterator it = ri.closed.begin(); it != ri.closed.end(); ++it) {
259  myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast<GUIEdge*>(*it), this, true));
260  dynamic_cast<GUINet*>(GUINet::getInstance())->getVisualisationSpeedUp().addAdditionalGLObject(myEdgeVisualizations.back());
261  myBoundary.add(myEdgeVisualizations.back()->getCenteringBoundary());
262  }
263  }
264 }
265 
266 
269  GUISUMOAbstractView& parent) {
270  GUIGLObjectPopupMenu* ret = new GUITriggeredRerouterPopupMenu(app, parent, *this);
271  buildPopupHeader(ret, app);
273  buildShowManipulatorPopupEntry(ret, false);
276  buildPositionCopyEntry(ret, false);
277  return ret;
278 }
279 
280 
284  return 0;
285 }
286 
287 
288 void
290  UNUSED_PARAMETER(s);
291 }
292 
293 
294 Boundary
296  Boundary b(myBoundary);
297  b.grow(20);
298  return b;
299 }
300 
301 
302 
307  new GUIManip_TriggeredRerouter(app, getFullName(), *this, 0, 0);
308  gui->create();
309  gui->show();
310  return gui;
311 }
312 
313 
314 /* -------------------------------------------------------------------------
315  * GUITriggeredRerouterEdge - methods
316  * ----------------------------------------------------------------------- */
318  GUIGlObject("rerouter_edge", GLO_TRIGGER, parent->getID() + ":" + edge->getID()),
319  myParent(parent),
320  myEdge(edge),
321  myAmClosedEdge(closed) {
322  const std::vector<MSLane*>& lanes = edge->getLanes();
323  myFGPositions.reserve(lanes.size());
324  myFGRotations.reserve(lanes.size());
325  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
326  const PositionVector& v = (*i)->getShape();
327  const SUMOReal pos = closed ? 3 : v.length() - (SUMOReal) 6.;
328  myFGPositions.push_back((*i)->geometryPositionAtOffset(pos));
329  myFGRotations.push_back(-v.rotationDegreeAtOffset(pos));
330  myBoundary.add(myFGPositions.back());
331  }
332 }
333 
334 
336 
337 
340  GUISUMOAbstractView& parent) {
341  return myParent->getPopUpMenu(app, parent);
342 }
343 
344 
348  return 0;
349 }
350 
351 
352 void
354  const SUMOReal exaggeration = s.addSize.getExaggeration(s);
355  if (s.scale * exaggeration >= 3) {
356  glPushName(getGlID());
357  const SUMOReal prob = myParent->getProbability();
358  if (myAmClosedEdge) {
359  // draw closing symbol onto all lanes
360  const RerouteInterval* const ri =
361  myParent->getCurrentReroute(MSNet::getInstance()->getCurrentTimeStep());
362  if (ri != 0 && prob > 0) {
363  // draw only if the edge is closed at this time
364  if (std::find(ri->closed.begin(), ri->closed.end(), myEdge) != ri->closed.end()) {
365  const int noLanes = (int)myFGPositions.size();
366  for (int j = 0; j < noLanes; ++j) {
367  Position pos = myFGPositions[j];
368  SUMOReal rot = myFGRotations[j];
369  glPushMatrix();
370  glTranslated(pos.x(), pos.y(), 0);
371  glRotated(rot, 0, 0, 1);
372  glTranslated(0, -1.5, 0);
373  int noPoints = 9;
374  if (s.scale > 25) {
375  noPoints = (int)(9.0 + s.scale / 10.0);
376  if (noPoints > 36) {
377  noPoints = 36;
378  }
379  }
380  glTranslated(0, 0, getType());
381  //glScaled(exaggeration, exaggeration, 1);
382  glColor3d(0.7, 0, 0);
383  GLHelper::drawFilledCircle((SUMOReal) 1.3, noPoints);
384  glTranslated(0, 0, .1);
385  glColor3d(1, 0, 0);
386  GLHelper::drawFilledCircle((SUMOReal) 1.3, noPoints, 0, prob * 360);
387  glTranslated(0, 0, .1);
388  glColor3d(1, 1, 1);
389  glRotated(-90, 0, 0, 1);
390  glBegin(GL_TRIANGLES);
391  glVertex2d(0 - .3, -1.);
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  glEnd();
398  glPopMatrix();
399  }
400  }
401  }
402 
403  } else {
404  // draw rerouter symbol onto all lanes
405  for (int i = 0; i < (int)myFGPositions.size(); ++i) {
406  const Position& pos = myFGPositions[i];
407  SUMOReal rot = myFGRotations[i];
408  glPushMatrix();
409  glTranslated(pos.x(), pos.y(), 0);
410  glRotated(rot, 0, 0, 1);
411  glTranslated(0, 0, getType());
412  glScaled(exaggeration, exaggeration, 1);
413  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
414 
415  glBegin(GL_TRIANGLES);
416  glColor3d(1, .8f, 0);
417  // base
418  glVertex2d(0 - 1.4, 0);
419  glVertex2d(0 - 1.4, 6);
420  glVertex2d(0 + 1.4, 6);
421  glVertex2d(0 + 1.4, 0);
422  glVertex2d(0 - 1.4, 0);
423  glVertex2d(0 + 1.4, 6);
424  glEnd();
425 
426  glTranslated(0, 0, .1);
427  glColor3d(0, 0, 0);
428  pfSetPosition(0, 0);
429  pfSetScale(3.f);
430  SUMOReal w = pfdkGetStringWidth("U");
431  glRotated(180, 0, 1, 0);
432  glTranslated(-w / 2., 2, 0);
433  pfDrawString("U");
434 
435  glTranslated(w / 2., -2, 0);
436  std::string str = toString((int)(prob * 100)) + "%";
437  pfSetPosition(0, 0);
438  pfSetScale(.7f);
439  w = pfdkGetStringWidth(str.c_str());
440  glTranslated(-w / 2., 4, 0);
441  pfDrawString(str.c_str());
442  glPopMatrix();
443  }
444  }
445  glPopName();
446  }
447 }
448 
449 
450 Boundary
452  Boundary b(myBoundary);
453  b.grow(20);
454  return b;
455 }
456 
457 
458 /****************************************************************************/
459 
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
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,
const RerouteInterval * getCurrentReroute(SUMOTime time, SUMOVehicle &veh) const
Returns the rerouting definition valid for the given time and vehicle, 0 if none. ...
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[]
SUMOReal length() const
Returns the length.
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.
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:192
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
GUITriggeredRerouter * myParent
The parent rerouter to which this edge instance belongs.
void setUserUsageProbability(SUMOReal prob)
Sets the probability with which a vehicle is rerouted given by the user.
GUISUMOAbstractView * myParent
The parent window.
const std::string & getID() const
Returns the id.
Definition: Named.h:66
void setUserMode(bool val)
Sets whether the process is currently steered by the user.
GUITriggeredRerouterPopupMenuMap[]
MSEdge * myEdge
The edge for which this visualization applies.
A RT-tree for efficient storing of SUMO&#39;s GL-objects.
Definition: SUMORTree.h:74
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
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.
#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&#39;s width (temporary, used for a single view)
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:60
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.
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.
SUMOReal rotationDegreeAtOffset(SUMOReal pos) const
Returns the rotation at the given length.
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
const bool myAmClosedEdge
whether this edge instance visualizes a closed edge
SUMOReal x() const
Returns the x-position.
Definition: Position.h:63
Open the object&#39;s manipulator.
Definition: GUIAppEnum.h:255
long onCmdUserDef(FXObject *, FXSelector, void *)
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
Boundary myBoundary
The boundary of this rerouter.
long onCmdOpenManip(FXObject *, FXSelector, void *)
Called if the object&#39;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.
void buildShowManipulatorPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the manipulator window.
Reroutes vehicles passing an edge.
Boundary & grow(SUMOReal by)
extends the boundary by the given amount
Definition: Boundary.cpp:232
A MSNet extended by some values for usage within the gui.
Definition: GUINet.h:89
void add(SUMOReal x, SUMOReal y, SUMOReal z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp: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
std::vector< RerouteInterval > myIntervals
List of rerouting definition intervals.
The popup menu of a globject.
FXdouble getValue() const
Return current value.
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
GUIGlID getGlID() const
Returns the numerical id of the object.
GUIMainWindow * myApplication
The main application.
#define SUMOReal
Definition: config.h:213
SUMOReal getExaggeration(const GUIVisualizationSettings &s, SUMOReal factor=20) const
return the drawing size including exaggeration and constantSize values
Close simulation - ID.
Definition: GUIAppEnum.h:85
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:77
const std::string & getFullName() const
void myEndElement(int element)
Called when a closing tag occurs.
GUIGlObject * myObject
The object that belongs to this popup-menu.
Spinner control.
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
Boundary myBoundary
The boundary of this rerouter.
A window containing a gl-object&#39;s parameter.
GUITriggeredRerouter(const std::string &id, const MSEdgeVector &edges, SUMOReal prob, const std::string &aXMLFilename, bool off, SUMORTree &rtree)
Constructor.
PosCont myFGPositions
The positions in full-geometry mode.
SUMOReal getProbability() const
Returns the rerouting probability.
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.