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.sourceforge.net/
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>
57 
58 #ifdef CHECK_MEMORY_LEAKS
59 #include <foreign/nvwa/debug_new.h>
60 #endif // CHECK_MEMORY_LEAKS
61 
62 
63 // ===========================================================================
64 // FOX callback mapping
65 // ===========================================================================
66 /* -------------------------------------------------------------------------
67  * GUITriggeredRerouter::GUITriggeredRerouterPopupMenu - mapping
68  * ----------------------------------------------------------------------- */
72 
73 };
74 
75 // Object implementation
77 
78 
79 /* -------------------------------------------------------------------------
80  * GUITriggeredRerouter::GUIManip_TriggeredRerouter - mapping
81  * ----------------------------------------------------------------------- */
82 FXDEFMAP(GUITriggeredRerouter::GUIManip_TriggeredRerouter) GUIManip_TriggeredRerouterMap[] = {
87 };
88 
89 FXIMPLEMENT(GUITriggeredRerouter::GUIManip_TriggeredRerouter, GUIManipulator, GUIManip_TriggeredRerouterMap, ARRAYNUMBER(GUIManip_TriggeredRerouterMap))
90 
91 
92 // ===========================================================================
93 // method definitions
94 // ===========================================================================
95 /* -------------------------------------------------------------------------
96  * GUITriggeredRerouter::GUIManip_TriggeredRerouter - methods
97  * ----------------------------------------------------------------------- */
99  GUIMainWindow& app,
100  const std::string& name, GUITriggeredRerouter& o,
101  int /*xpos*/, int /*ypos*/)
102  : GUIManipulator(app, name, 0, 0), myParent(&app),
103  myChosenValue(0), myChosenTarget(myChosenValue, NULL, MID_OPTION),
104  myUsageProbability(o.getProbability()), myUsageProbabilityTarget(myUsageProbability),
105  myObject(&o) {
106  myChosenTarget.setTarget(this);
107  FXVerticalFrame* f1 =
108  new FXVerticalFrame(this, LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0);
109 
110  FXGroupBox* gp = new FXGroupBox(f1, "Change Probability",
111  GROUPBOX_TITLE_LEFT | FRAME_SUNKEN | FRAME_RIDGE,
112  0, 0, 0, 0, 4, 4, 1, 1, 2, 0);
113  {
114  // default
115  FXHorizontalFrame* gf1 =
116  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
117  new FXRadioButton(gf1, "Default", &myChosenTarget, FXDataTarget::ID_OPTION + 0,
118  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
119  0, 0, 0, 0, 2, 2, 0, 0);
120  }
121  {
122  // free
123  FXHorizontalFrame* gf12 =
124  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
125  new FXRadioButton(gf12, "User Given: ", &myChosenTarget, FXDataTarget::ID_OPTION + 1,
126  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y,
127  0, 0, 0, 0, 2, 2, 0, 0);
128  myUsageProbabilityDial =
129  new FXRealSpinDial(gf12, 10, this, MID_USER_DEF,
130  LAYOUT_TOP | FRAME_SUNKEN | FRAME_THICK);
131  myUsageProbabilityDial->setFormatString("%.2f");
132  myUsageProbabilityDial->setIncrements(.1, .1, .1);
133  myUsageProbabilityDial->setRange(0, 1);
134  myUsageProbabilityDial->setValue(myObject->getUserProbability());
135  }
136  {
137  // off
138  FXHorizontalFrame* gf13 =
139  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
140  new FXRadioButton(gf13, "Off", &myChosenTarget, FXDataTarget::ID_OPTION + 2,
141  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
142  0, 0, 0, 0, 2, 2, 0, 0);
143  }
144  myChosenValue = myObject->inUserMode()
145  ? myObject->getUserProbability() > 0
146  ? 1 : 2
147  : 0;
148  new FXButton(f1, "Close", NULL, this, MID_CLOSE,
149  BUTTON_INITIAL | BUTTON_DEFAULT | FRAME_RAISED | FRAME_THICK | LAYOUT_TOP | LAYOUT_LEFT | LAYOUT_CENTER_X, 0, 0, 0, 0, 30, 30, 4, 4);
150 }
151 
152 
154 
155 
156 long
158  destroy();
159  return 1;
160 }
161 
162 
163 long
165  myUsageProbability = (SUMOReal)(myUsageProbabilityDial->getValue());
166  static_cast<GUITriggeredRerouter*>(myObject)->setUserUsageProbability(myUsageProbability);
167  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(true);
168  myParent->updateChildren();
169  return 1;
170 }
171 
172 
173 long
175  sender->handle(this,
176  myChosenValue != 1 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
177  ptr);
178  myParent->updateChildren();
179  return 1;
180 }
181 
182 
183 long
185  static_cast<GUITriggeredRerouter*>(myObject)->setUserUsageProbability(myUsageProbability);
186  switch (myChosenValue) {
187  case 0:
188  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(false);
189  break;
190  case 1:
191  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(true);
192  break;
193  case 2:
194  static_cast<GUITriggeredRerouter*>(myObject)->setUserUsageProbability(0);
195  static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(true);
196  break;
197  default:
198  throw 1;
199  }
200  myParent->updateChildren();
201  return 1;
202 }
203 
204 
205 /* -------------------------------------------------------------------------
206  * GUITriggeredRerouter::GUITriggeredRerouterPopupMenu - methods
207  * ----------------------------------------------------------------------- */
209  GUIMainWindow& app, GUISUMOAbstractView& parent,
210  GUIGlObject& o)
211  : GUIGLObjectPopupMenu(app, parent, o) {}
212 
213 
215 
216 
217 long
219  FXSelector,
220  void*) {
221  static_cast<GUITriggeredRerouter*>(myObject)->openManipulator(
222  *myApplication, *myParent);
223  return 1;
224 }
225 
226 
227 /* -------------------------------------------------------------------------
228  * GUITriggeredRerouter - methods
229  * ----------------------------------------------------------------------- */
231  const std::string& id,
232  const std::vector<MSEdge*>& edges,
233  SUMOReal prob, const std::string& aXMLFilename, bool off,
234  SUMORTree& rtree) :
235  MSTriggeredRerouter(id, edges, prob, aXMLFilename, off),
236  GUIGlObject_AbstractAdd("rerouter", GLO_TRIGGER, id) {
237  // add visualisation objects for edges which trigger the rerouter
238  for (std::vector<MSEdge*>::const_iterator it = edges.begin(); it != edges.end(); ++it) {
239  myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast<GUIEdge*>(*it), this, false));
240  }
241  // add visualisation objects for closed edges
242  for (std::vector<RerouteInterval>::const_iterator it_interval = myIntervals.begin();
243  it_interval != myIntervals.end(); ++it_interval) {
244  const std::vector<MSEdge*>& closed = it_interval->closed;
245  for (std::vector<MSEdge*>::const_iterator it = closed.begin(); it != closed.end(); ++it) {
246  myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast<GUIEdge*>(*it), this, true));
247  }
248  }
249  // register with rtree and rerouter boundary
250  for (std::vector<GUITriggeredRerouterEdge*>::iterator it = myEdgeVisualizations.begin(); it != myEdgeVisualizations.end(); ++it) {
251  rtree.addAdditionalGLObject(*it);
252  myBoundary.add((*it)->getCenteringBoundary());
253  }
254 }
255 
256 
258  for (std::vector<GUITriggeredRerouterEdge*>::iterator it = myEdgeVisualizations.begin(); it != myEdgeVisualizations.end(); ++it) {
259  delete *it;
260  }
261  myEdgeVisualizations.clear();
262 }
263 
264 
267  GUISUMOAbstractView& parent) {
268  GUIGLObjectPopupMenu* ret = new GUITriggeredRerouterPopupMenu(app, parent, *this);
269  buildPopupHeader(ret, app);
271  buildShowManipulatorPopupEntry(ret, false);
274  buildPositionCopyEntry(ret, false);
275  return ret;
276 }
277 
278 
282  return 0;
283 }
284 
285 
286 void
288  UNUSED_PARAMETER(s);
289 }
290 
291 
292 Boundary
294  Boundary b(myBoundary);
295  b.grow(20);
296  return b;
297 }
298 
299 
300 
305  new GUIManip_TriggeredRerouter(app, getFullName(), *this, 0, 0);
306  gui->create();
307  gui->show();
308  return gui;
309 }
310 
311 
312 /* -------------------------------------------------------------------------
313  * GUITriggeredRerouterEdge - methods
314  * ----------------------------------------------------------------------- */
316  GUIGlObject("rerouter_edge", GLO_TRIGGER, parent->getID() + ":" + edge->getID()),
317  myParent(parent),
318  myEdge(edge),
319  myAmClosedEdge(closed) {
320  const std::vector<MSLane*>& lanes = edge->getLanes();
321  const size_t noLanes = lanes.size();
322  myFGPositions.reserve(noLanes);
323  myFGRotations.reserve(noLanes);
324  for (size_t i = 0; i < noLanes; ++i) {
325  const PositionVector& v = edge->getLaneGeometry(i).getShape();
326  SUMOReal pos = closed ? 3 : v.length() - (SUMOReal) 6.;
327  myFGPositions.push_back(v.positionAtOffset(pos));
328  myFGRotations.push_back(-v.rotationDegreeAtOffset(pos));
330  }
331 }
332 
333 
335 
336 
339  GUISUMOAbstractView& parent) {
340  return myParent->getPopUpMenu(app, parent);
341 }
342 
343 
347  return 0;
348 }
349 
350 
351 void
353  if (s.scale * s.addExaggeration >= 3) {
354  glPushName(getGlID());
355  const SUMOReal prob = myParent->getProbability();
356  if (myAmClosedEdge) {
357  // draw closing symbol onto all lanes
358  if (myParent->hasCurrentReroute(MSNet::getInstance()->getCurrentTimeStep()) && prob > 0) {
359  const RerouteInterval& ri =
360  myParent->getCurrentReroute(MSNet::getInstance()->getCurrentTimeStep());
361  // draw only if the edge is closed at this time
362  if (std::find(ri.closed.begin(), ri.closed.end(), myEdge) != ri.closed.end()) {
363  const size_t noLanes = myFGPositions.size();
364  for (size_t j = 0; j < noLanes; ++j) {
365  Position pos = myFGPositions[j];
366  SUMOReal rot = myFGRotations[j];
367  glPushMatrix();
368  glTranslated(pos.x(), pos.y(), 0);
369  glRotated(rot, 0, 0, 1);
370  glTranslated(0, -1.5, 0);
371  int noPoints = 9;
372  if (s.scale > 25) {
373  noPoints = (int)(9.0 + s.scale / 10.0);
374  if (noPoints > 36) {
375  noPoints = 36;
376  }
377  }
378  glTranslated(0, 0, getType());
379  //glScaled(s.addExaggeration, s.addExaggeration, 1);
380  glColor3d(0.7, 0, 0);
381  GLHelper::drawFilledCircle((SUMOReal) 1.3, noPoints);
382  glTranslated(0, 0, .1);
383  glColor3d(1, 0, 0);
384  GLHelper::drawFilledCircle((SUMOReal) 1.3, noPoints, 0, prob * 360);
385  glTranslated(0, 0, .1);
386  glColor3d(1, 1, 1);
387  glRotated(-90, 0, 0, 1);
388  glBegin(GL_TRIANGLES);
389  glVertex2d(0 - .3, -1.);
390  glVertex2d(0 - .3, 1.);
391  glVertex2d(0 + .3, 1.);
392  glVertex2d(0 + .3, -1.);
393  glVertex2d(0 - .3, -1.);
394  glVertex2d(0 + .3, 1.);
395  glEnd();
396  glPopMatrix();
397  }
398  }
399  }
400 
401  } else {
402  // draw rerouter symbol onto all lanes
403  for (size_t i = 0; i < myFGPositions.size(); ++i) {
404  const Position& pos = myFGPositions[i];
405  SUMOReal rot = myFGRotations[i];
406  glPushMatrix();
407  glTranslated(pos.x(), pos.y(), 0);
408  glRotated(rot, 0, 0, 1);
409  glTranslated(0, 0, getType());
410  glScaled(s.addExaggeration, s.addExaggeration, 1);
411  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
412 
413  glBegin(GL_TRIANGLES);
414  glColor3d(1, .8f, 0);
415  // base
416  glVertex2d(0 - 1.4, 0);
417  glVertex2d(0 - 1.4, 6);
418  glVertex2d(0 + 1.4, 6);
419  glVertex2d(0 + 1.4, 0);
420  glVertex2d(0 - 1.4, 0);
421  glVertex2d(0 + 1.4, 6);
422  glEnd();
423 
424  glTranslated(0, 0, .1);
425  glColor3d(0, 0, 0);
426  pfSetPosition(0, 0);
427  pfSetScale(3.f);
428  SUMOReal w = pfdkGetStringWidth("U");
429  glRotated(180, 0, 1, 0);
430  glTranslated(-w / 2., 2, 0);
431  pfDrawString("U");
432 
433  glTranslated(w / 2., -2, 0);
434  std::string str = toString((int)(prob * 100)) + "%";
435  pfSetPosition(0, 0);
436  pfSetScale(.7f);
437  w = pfdkGetStringWidth(str.c_str());
438  glTranslated(-w / 2., 4, 0);
439  pfDrawString(str.c_str());
440  glPopMatrix();
441  }
442  }
443  glPopName();
444  }
445 }
446 
447 
448 Boundary
450  Boundary b(myBoundary);
451  b.grow(20);
452  return b;
453 }
454 
455 
456 /****************************************************************************/
457