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