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-2017 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 
57 // ===========================================================================
58 // FOX callback mapping
59 // ===========================================================================
60 /* -------------------------------------------------------------------------
61  * GUITriggeredRerouter::GUITriggeredRerouterPopupMenu - mapping
62  * ----------------------------------------------------------------------- */
66 
67 };
68 
69 // Object implementation
71 
72 
73 /* -------------------------------------------------------------------------
74  * GUITriggeredRerouter::GUIManip_TriggeredRerouter - mapping
75  * ----------------------------------------------------------------------- */
76 FXDEFMAP(GUITriggeredRerouter::GUIManip_TriggeredRerouter) GUIManip_TriggeredRerouterMap[] = {
81 };
82 
83 FXIMPLEMENT(GUITriggeredRerouter::GUIManip_TriggeredRerouter, GUIManipulator, GUIManip_TriggeredRerouterMap, ARRAYNUMBER(GUIManip_TriggeredRerouterMap))
84 
85 
86 // ===========================================================================
87 // method definitions
88 // ===========================================================================
89 /* -------------------------------------------------------------------------
90  * GUITriggeredRerouter::GUIManip_TriggeredRerouter - methods
91  * ----------------------------------------------------------------------- */
93  GUIMainWindow& app,
94  const std::string& name, GUITriggeredRerouter& o,
95  int /*xpos*/, int /*ypos*/)
96  : GUIManipulator(app, name, 0, 0), myParent(&app),
97  myChosenValue(0), myChosenTarget(myChosenValue, NULL, MID_OPTION),
98  myUsageProbability(o.getProbability()), myUsageProbabilityTarget(myUsageProbability),
99  myObject(&o) {
100  myChosenTarget.setTarget(this);
101  FXVerticalFrame* f1 =
102  new FXVerticalFrame(this, LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0);
103 
104  FXGroupBox* gp = new FXGroupBox(f1, "Change Probability",
105  GROUPBOX_TITLE_LEFT | FRAME_SUNKEN | FRAME_RIDGE,
106  0, 0, 0, 0, 4, 4, 1, 1, 2, 0);
107  {
108  // default
109  FXHorizontalFrame* gf1 =
110  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
111  new FXRadioButton(gf1, "Default", &myChosenTarget, FXDataTarget::ID_OPTION + 0,
112  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
113  0, 0, 0, 0, 2, 2, 0, 0);
114  }
115  {
116  // free
117  FXHorizontalFrame* gf12 =
118  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
119  new FXRadioButton(gf12, "User Given: ", &myChosenTarget, FXDataTarget::ID_OPTION + 1,
120  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y,
121  0, 0, 0, 0, 2, 2, 0, 0);
122  myUsageProbabilityDial =
123  new FXRealSpinDial(gf12, 10, this, MID_USER_DEF,
124  LAYOUT_TOP | FRAME_SUNKEN | FRAME_THICK);
125  myUsageProbabilityDial->setFormatString("%.2f");
126  myUsageProbabilityDial->setIncrements(.1, .1, .1);
127  myUsageProbabilityDial->setRange(0, 1);
128  myUsageProbabilityDial->setValue(myObject->getUserProbability());
129  }
130  {
131  // off
132  FXHorizontalFrame* gf13 =
133  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
134  new FXRadioButton(gf13, "Off", &myChosenTarget, FXDataTarget::ID_OPTION + 2,
135  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
136  0, 0, 0, 0, 2, 2, 0, 0);
137  }
138  myChosenValue = myObject->inUserMode()
139  ? myObject->getUserProbability() > 0
140  ? 1 : 2
141  : 0;
142  new FXButton(f1, "Close", NULL, this, MID_CLOSE,
143  BUTTON_INITIAL | BUTTON_DEFAULT | FRAME_RAISED | FRAME_THICK | LAYOUT_TOP | LAYOUT_LEFT | LAYOUT_CENTER_X, 0, 0, 0, 0, 30, 30, 4, 4);
144 }
145 
146 
148 
149 
150 long
152  destroy();
153  return 1;
154 }
155 
156 
157 long
161  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(true);
163  return 1;
164 }
165 
166 
167 long
168 GUITriggeredRerouter::GUIManip_TriggeredRerouter::onUpdUserDef(FXObject* sender, FXSelector, void* ptr) {
169  sender->handle(this,
170  myChosenValue != 1 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
171  ptr);
173  return 1;
174 }
175 
176 
177 long
180  switch (myChosenValue) {
181  case 0:
182  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(false);
183  break;
184  case 1:
185  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(true);
186  break;
187  case 2:
189  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(true);
190  break;
191  default:
192  throw 1;
193  }
195  return 1;
196 }
197 
198 
199 /* -------------------------------------------------------------------------
200  * GUITriggeredRerouter::GUITriggeredRerouterPopupMenu - methods
201  * ----------------------------------------------------------------------- */
203  GUIMainWindow& app, GUISUMOAbstractView& parent,
204  GUIGlObject& o)
205  : GUIGLObjectPopupMenu(app, parent, o) {}
206 
207 
209 
210 
211 long
213  FXSelector,
214  void*) {
217  return 1;
218 }
219 
220 
221 /* -------------------------------------------------------------------------
222  * GUITriggeredRerouter - methods
223  * ----------------------------------------------------------------------- */
225  const std::string& id,
226  const MSEdgeVector& edges,
227  double prob, const std::string& aXMLFilename, bool off,
228  SUMORTree& rtree) :
229  MSTriggeredRerouter(id, edges, prob, aXMLFilename, off),
230  GUIGlObject_AbstractAdd("rerouter", GLO_TRIGGER, id) {
231  // add visualisation objects for edges which trigger the rerouter
232  for (MSEdgeVector::const_iterator it = edges.begin(); it != edges.end(); ++it) {
233  myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast<GUIEdge*>(*it), this, false));
235  myBoundary.add(myEdgeVisualizations.back()->getCenteringBoundary());
236  }
237 }
238 
239 
241  for (std::vector<GUITriggeredRerouterEdge*>::iterator it = myEdgeVisualizations.begin(); it != myEdgeVisualizations.end(); ++it) {
242  delete *it;
243  }
244  myEdgeVisualizations.clear();
245 }
246 
247 
248 void
251  if (element == SUMO_TAG_INTERVAL) {
252  // add visualisation objects for closed edges
253  const RerouteInterval& ri = myIntervals.back();
254  for (MSEdgeVector::const_iterator it = ri.closed.begin(); it != ri.closed.end(); ++it) {
255  myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast<GUIEdge*>(*it), this, true));
256  dynamic_cast<GUINet*>(GUINet::getInstance())->getVisualisationSpeedUp().addAdditionalGLObject(myEdgeVisualizations.back());
257  myBoundary.add(myEdgeVisualizations.back()->getCenteringBoundary());
258  }
259  }
260 }
261 
262 
265  GUISUMOAbstractView& parent) {
266  GUIGLObjectPopupMenu* ret = new GUITriggeredRerouterPopupMenu(app, parent, *this);
267  buildPopupHeader(ret, app);
269  buildShowManipulatorPopupEntry(ret, false);
272  buildPositionCopyEntry(ret, false);
273  return ret;
274 }
275 
276 
280  return 0;
281 }
282 
283 
284 void
286  UNUSED_PARAMETER(s);
287 }
288 
289 
290 Boundary
292  Boundary b(myBoundary);
293  b.grow(20);
294  return b;
295 }
296 
297 
298 
303  new GUIManip_TriggeredRerouter(app, getFullName(), *this, 0, 0);
304  gui->create();
305  gui->show();
306  return gui;
307 }
308 
309 
310 /* -------------------------------------------------------------------------
311  * GUITriggeredRerouterEdge - methods
312  * ----------------------------------------------------------------------- */
314  GUIGlObject("rerouter_edge", GLO_TRIGGER, parent->getID() + ":" + edge->getID()),
315  myParent(parent),
316  myEdge(edge),
317  myAmClosedEdge(closed) {
318  const std::vector<MSLane*>& lanes = edge->getLanes();
319  myFGPositions.reserve(lanes.size());
320  myFGRotations.reserve(lanes.size());
321  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
322  const PositionVector& v = (*i)->getShape();
323  const double pos = closed ? 3 : v.length() - (double) 6.;
324  myFGPositions.push_back((*i)->geometryPositionAtOffset(pos));
325  myFGRotations.push_back(-v.rotationDegreeAtOffset(pos));
326  myBoundary.add(myFGPositions.back());
327  }
328 }
329 
330 
332 
333 
336  GUISUMOAbstractView& parent) {
337  return myParent->getPopUpMenu(app, parent);
338 }
339 
340 
344  return 0;
345 }
346 
347 
348 void
350  const double exaggeration = s.addSize.getExaggeration(s);
351  if (s.scale * exaggeration >= 3) {
352  glPushName(getGlID());
353  const double prob = myParent->getProbability();
354  if (myAmClosedEdge) {
355  // draw closing symbol onto all lanes
356  const RerouteInterval* const ri =
357  myParent->getCurrentReroute(MSNet::getInstance()->getCurrentTimeStep());
358  if (ri != 0 && prob > 0) {
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 int noLanes = (int)myFGPositions.size();
362  for (int j = 0; j < noLanes; ++j) {
363  Position pos = myFGPositions[j];
364  double 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(exaggeration, exaggeration, 1);
378  glColor3d(0.7, 0, 0);
379  GLHelper::drawFilledCircle((double) 1.3, noPoints);
380  glTranslated(0, 0, .1);
381  glColor3d(1, 0, 0);
382  GLHelper::drawFilledCircle((double) 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 (int i = 0; i < (int)myFGPositions.size(); ++i) {
402  const Position& pos = myFGPositions[i];
403  double 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(exaggeration, exaggeration, 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  double 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 
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
double getProbability() const
Returns the rerouting probability.
int pfDrawString(const char *c)
Definition: polyfonts.c:1074
double rotationDegreeAtOffset(double pos) const
Returns the rotation at the given length.
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)
double scale
information about a lane&#39;s width (temporary, used for a single view)
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
void pfSetScale(double s)
Definition: polyfonts.c:465
Open the object&#39;s manipulator.
Definition: GUIAppEnum.h:257
FXDEFMAP(GUITriggeredRerouter::GUIManip_TriggeredRerouter) GUIManip_TriggeredRerouterMap[]
GUIManipulator * openManipulator(GUIMainWindow &app, GUISUMOAbstractView &parent)
Stores the information about how to visualize structures.
double y() const
Returns the y-position.
Definition: Position.h:68
GUITriggeredRerouter(const std::string &id, const MSEdgeVector &edges, double prob, const std::string &aXMLFilename, bool off, SUMORTree &rtree)
Constructor.
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
double x() const
Returns the x-position.
Definition: Position.h:63
Close simulation - ID.
Definition: GUIAppEnum.h:85
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:158
GUITriggeredRerouter * myParent
The parent rerouter to which this edge instance belongs.
GUISUMOAbstractView * myParent
The parent window.
void setUserUsageProbability(double prob)
Sets the probability with which a vehicle is rerouted given by the user.
void pfSetPosition(double x, double y)
Definition: polyfonts.c:480
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.
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:340
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:38
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
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.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
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.
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
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:234
long onCmdUserDef(FXObject *, FXSelector, void *)
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.
double pfdkGetStringWidth(const char *c)
Definition: polyfonts.c:1113
double length() const
Returns the length.
A MSNet extended by some values for usage within the gui.
Definition: GUINet.h:89
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.
GUIGlID getGlID() const
Returns the numerical id of the object.
double getExaggeration(const GUIVisualizationSettings &s, double factor=20) const
return the drawing size including exaggeration and constantSize values
an aggreagated-output interval
GUIMainWindow * myApplication
The main application.
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:77
const std::string & getFullName() const
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:86
void myEndElement(int element)
Called when a closing tag occurs.
GUIGlObject * myObject
The object that belongs to this popup-menu.
Spinner control.
Boundary myBoundary
The boundary of this rerouter.
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.