SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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-sim.org/
12 // Copyright (C) 2001-2013 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 std::vector<MSEdge*>& 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 (std::vector<MSEdge*>::const_iterator it = edges.begin(); it != edges.end(); ++it) {
238  myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast<GUIEdge*>(*it), this, false));
239  }
240  // add visualisation objects for closed edges
241  for (std::vector<RerouteInterval>::const_iterator it_interval = myIntervals.begin();
242  it_interval != myIntervals.end(); ++it_interval) {
243  const std::vector<MSEdge*>& closed = it_interval->closed;
244  for (std::vector<MSEdge*>::const_iterator it = closed.begin(); it != closed.end(); ++it) {
245  myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast<GUIEdge*>(*it), this, true));
246  }
247  }
248  // register with rtree and rerouter boundary
249  for (std::vector<GUITriggeredRerouterEdge*>::iterator it = myEdgeVisualizations.begin(); it != myEdgeVisualizations.end(); ++it) {
250  rtree.addAdditionalGLObject(*it);
251  myBoundary.add((*it)->getCenteringBoundary());
252  }
253 }
254 
255 
257  for (std::vector<GUITriggeredRerouterEdge*>::iterator it = myEdgeVisualizations.begin(); it != myEdgeVisualizations.end(); ++it) {
258  delete *it;
259  }
260  myEdgeVisualizations.clear();
261 }
262 
263 
266  GUISUMOAbstractView& parent) {
267  GUIGLObjectPopupMenu* ret = new GUITriggeredRerouterPopupMenu(app, parent, *this);
268  buildPopupHeader(ret, app);
270  buildShowManipulatorPopupEntry(ret, false);
273  buildPositionCopyEntry(ret, false);
274  return ret;
275 }
276 
277 
281  return 0;
282 }
283 
284 
285 void
287  UNUSED_PARAMETER(s);
288 }
289 
290 
291 Boundary
293  Boundary b(myBoundary);
294  b.grow(20);
295  return b;
296 }
297 
298 
299 
304  new GUIManip_TriggeredRerouter(app, getFullName(), *this, 0, 0);
305  gui->create();
306  gui->show();
307  return gui;
308 }
309 
310 
311 /* -------------------------------------------------------------------------
312  * GUITriggeredRerouterEdge - methods
313  * ----------------------------------------------------------------------- */
315  GUIGlObject("rerouter_edge", GLO_TRIGGER, parent->getID() + ":" + edge->getID()),
316  myParent(parent),
317  myEdge(edge),
318  myAmClosedEdge(closed) {
319  const std::vector<MSLane*>& lanes = edge->getLanes();
320  myFGPositions.reserve(lanes.size());
321  myFGRotations.reserve(lanes.size());
322  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
323  const PositionVector& v = (*i)->getShape();
324  const SUMOReal pos = closed ? 3 : v.length() - (SUMOReal) 6.;
325  myFGPositions.push_back((*i)->geometryPositionAtOffset(pos));
326  myFGRotations.push_back(-v.rotationDegreeAtOffset(pos));
327  myBoundary.add(myFGPositions.back());
328  }
329 }
330 
331 
333 
334 
337  GUISUMOAbstractView& parent) {
338  return myParent->getPopUpMenu(app, parent);
339 }
340 
341 
345  return 0;
346 }
347 
348 
349 void
351  if (s.scale * s.addExaggeration >= 3) {
352  glPushName(getGlID());
353  const SUMOReal prob = myParent->getProbability();
354  if (myAmClosedEdge) {
355  // draw closing symbol onto all lanes
356  if (myParent->hasCurrentReroute(MSNet::getInstance()->getCurrentTimeStep()) && prob > 0) {
357  const RerouteInterval& ri =
358  myParent->getCurrentReroute(MSNet::getInstance()->getCurrentTimeStep());
359  // draw only if the edge is closed at this time
360  if (std::find(ri.closed.begin(), ri.closed.end(), myEdge) != ri.closed.end()) {
361  const size_t noLanes = myFGPositions.size();
362  for (size_t j = 0; j < noLanes; ++j) {
363  Position pos = myFGPositions[j];
364  SUMOReal rot = myFGRotations[j];
365  glPushMatrix();
366  glTranslated(pos.x(), pos.y(), 0);
367  glRotated(rot, 0, 0, 1);
368  glTranslated(0, -1.5, 0);
369  int noPoints = 9;
370  if (s.scale > 25) {
371  noPoints = (int)(9.0 + s.scale / 10.0);
372  if (noPoints > 36) {
373  noPoints = 36;
374  }
375  }
376  glTranslated(0, 0, getType());
377  //glScaled(s.addExaggeration, s.addExaggeration, 1);
378  glColor3d(0.7, 0, 0);
379  GLHelper::drawFilledCircle((SUMOReal) 1.3, noPoints);
380  glTranslated(0, 0, .1);
381  glColor3d(1, 0, 0);
382  GLHelper::drawFilledCircle((SUMOReal) 1.3, noPoints, 0, prob * 360);
383  glTranslated(0, 0, .1);
384  glColor3d(1, 1, 1);
385  glRotated(-90, 0, 0, 1);
386  glBegin(GL_TRIANGLES);
387  glVertex2d(0 - .3, -1.);
388  glVertex2d(0 - .3, 1.);
389  glVertex2d(0 + .3, 1.);
390  glVertex2d(0 + .3, -1.);
391  glVertex2d(0 - .3, -1.);
392  glVertex2d(0 + .3, 1.);
393  glEnd();
394  glPopMatrix();
395  }
396  }
397  }
398 
399  } else {
400  // draw rerouter symbol onto all lanes
401  for (size_t i = 0; i < myFGPositions.size(); ++i) {
402  const Position& pos = myFGPositions[i];
403  SUMOReal rot = myFGRotations[i];
404  glPushMatrix();
405  glTranslated(pos.x(), pos.y(), 0);
406  glRotated(rot, 0, 0, 1);
407  glTranslated(0, 0, getType());
408  glScaled(s.addExaggeration, s.addExaggeration, 1);
409  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
410 
411  glBegin(GL_TRIANGLES);
412  glColor3d(1, .8f, 0);
413  // base
414  glVertex2d(0 - 1.4, 0);
415  glVertex2d(0 - 1.4, 6);
416  glVertex2d(0 + 1.4, 6);
417  glVertex2d(0 + 1.4, 0);
418  glVertex2d(0 - 1.4, 0);
419  glVertex2d(0 + 1.4, 6);
420  glEnd();
421 
422  glTranslated(0, 0, .1);
423  glColor3d(0, 0, 0);
424  pfSetPosition(0, 0);
425  pfSetScale(3.f);
426  SUMOReal w = pfdkGetStringWidth("U");
427  glRotated(180, 0, 1, 0);
428  glTranslated(-w / 2., 2, 0);
429  pfDrawString("U");
430 
431  glTranslated(w / 2., -2, 0);
432  std::string str = toString((int)(prob * 100)) + "%";
433  pfSetPosition(0, 0);
434  pfSetScale(.7f);
435  w = pfdkGetStringWidth(str.c_str());
436  glTranslated(-w / 2., 4, 0);
437  pfDrawString(str.c_str());
438  glPopMatrix();
439  }
440  }
441  glPopName();
442  }
443 }
444 
445 
446 Boundary
448  Boundary b(myBoundary);
449  b.grow(20);
450  return b;
451 }
452 
453 
454 /****************************************************************************/
455 
int pfDrawString(const char *c)
Definition: polyfonts.c:1070
long onCmdClose(FXObject *, FXSelector, void *)
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...
std::vector< MSEdge * > closed
The list of closed edges.
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
std::vector< GUITriggeredRerouterEdge * > myEdgeVisualizations
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:167
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:476
GUITriggeredRerouter(const std::string &id, const std::vector< MSEdge * > &edges, SUMOReal prob, const std::string &aXMLFilename, bool off, SUMORTree &rtree)
Constructor.
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:150
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.
Close simulation - ID.
Definition: GUIAppEnum.h:81
GUITriggeredRerouterPopupMenuMap[]
SUMOTime getCurrentTimeStep() const
Returns the current simulation step (in s)
Definition: MSNet.cpp:500
A RT-tree for efficient storing of SUMO&#39;s GL-objects.
Definition: SUMORTree.h:61
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:36
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
FXDEFMAP(GUIDialog_AppSettings) GUIDialog_AppSettingsMap[]
SUMOReal scale
information about a lane&#39;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:196
A road/street connecting two junctions (gui-version)
Definition: GUIEdge.h:61
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
float addExaggeration
The additional structures exaggeration (upscale)
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.
long onCmdUserDef(FXObject *, FXSelector, void *)
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:51
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.
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
void pfSetScale(SUMOReal s)
Definition: polyfonts.c:461
void addAdditionalGLObject(GUIGlObject *o)
Adds an additional object (detector/shape/trigger) for visualisation.
Definition: SUMORTree.h:117
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:1109
#define SUMOReal
Definition: config.h:221
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&#39;s parameter.
PosCont myFGPositions
The positions in full-geometry mode.
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
Open the object&#39;s manipulator.
Definition: GUIAppEnum.h:231