SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GUILaneWrapper.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // A MSLane extended for visualisation purposes.
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
12 // Copyright (C) 2001-2012 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 #ifdef WIN32
34 #include <windows.h>
35 #endif
36 
37 #include <GL/gl.h>
38 
39 #include <string>
40 #include <iostream>
41 #include <utility>
42 #include <microsim/MSLane.h>
43 #include <microsim/MSEdge.h>
44 #include <microsim/MSGlobals.h>
46 #include <microsim/MSNet.h>
47 #include <gui/GUIGlobals.h>
49 #include "GUILaneWrapper.h"
50 #include <utils/common/ToString.h>
51 #include <utils/geom/GeomHelper.h>
52 #include <guisim/GUINet.h>
60 #include <utils/gui/div/GLHelper.h>
61 #include <gui/GUIViewTraffic.h>
63 #include <guisim/GUIVehicle.h>
67 
68 
69 #ifdef CHECK_MEMORY_LEAKS
70 #include <foreign/nvwa/debug_new.h>
71 #endif // CHECK_MEMORY_LEAKS
72 
73 
74 // ===========================================================================
75 // static member definitions
76 // ===========================================================================
78 
79 
80 // ===========================================================================
81 // method definitions
82 // ===========================================================================
83 GUILaneWrapper::GUILaneWrapper(MSLane& lane, const PositionVector& shape, unsigned int index) :
84  GUIGlObject(GLO_LANE, lane.getID()),
85  myLane(lane),
86  myShape(shape),
87  myIndex(index) {
88  myShapeRotations.reserve(myShape.size() - 1);
89  myShapeLengths.reserve(myShape.size() - 1);
90  int e = (int) myShape.size() - 1;
91  for (int i = 0; i < e; ++i) {
92  const Position& f = myShape[i];
93  const Position& s = myShape[i + 1];
94  myShapeLengths.push_back(f.distanceTo2D(s));
95  myShapeRotations.push_back((SUMOReal) atan2((s.x() - f.x()), (f.y() - s.y())) * (SUMOReal) 180.0 / (SUMOReal) PI);
96  }
97  //
100 }
101 
102 
104 
105 
106 bool
107 GUILaneWrapper::forLane(const MSLane& lane) const {
108  return (&myLane) == (&lane);
109 }
110 
111 
112 
113 void
115  unsigned int noLinks = getLinkNumber();
116  if (noLinks == 0) {
117  return;
118  }
119  // draw all links
120  SUMOReal w = myLane.getWidth() / (SUMOReal) noLinks;
121  SUMOReal x1 = myLane.getWidth() / (SUMOReal) 2.;
122  glPushMatrix();
123  const PositionVector& g = getShape();
124  const Position& end = g.getEnd();
125  const Position& f = g[-2];
126  const Position& s = end;
127  SUMOReal rot = (SUMOReal) atan2((s.x() - f.x()), (f.y() - s.y())) * (SUMOReal) 180.0 / (SUMOReal) PI;
128  glTranslated(end.x(), end.y(), 0);
129  glRotated(rot, 0, 0, 1);
130  for (int i = noLinks; --i >= 0; ) {
131  SUMOReal x2 = x1 - (SUMOReal)(w / 2.);
132  GLHelper::drawText(toString(getLane().getLinkCont()[i]->getRespondIndex()),
133  Position(x2, 0), 0, .6, RGBColor(.5, .5, 1), 180);
134  x1 -= w;
135  }
136  glPopMatrix();
137 }
138 
139 
140 void
142  unsigned int noLinks = getLinkNumber();
143  if (noLinks == 0) {
144  return;
145  }
146  // draw all links
147  SUMOReal w = myLane.getWidth() / (SUMOReal) noLinks;
148  SUMOReal x1 = (SUMOReal)(myLane.getWidth() / 2.);
149  glPushMatrix();
150  const PositionVector& g = getShape();
151  const Position& end = g.getEnd();
152  const Position& f = g[-2];
153  const Position& s = end;
154  SUMOReal rot = (SUMOReal) atan2((s.x() - f.x()), (f.y() - s.y())) * (SUMOReal) 180.0 / (SUMOReal) PI;
155  glTranslated(end.x(), end.y(), 0);
156  glRotated(rot, 0, 0, 1);
157  for (int i = noLinks; --i >= 0; ) {
158  SUMOReal x2 = x1 - (SUMOReal)(w / 2.);
159  int linkNo = net.getLinkTLIndex(getLane().getLinkCont()[i]);
160  if (linkNo < 0) {
161  continue;
162  }
164  Position(x2, 0), 0, .6, RGBColor(.5, .5, 1), 180);
165  x1 -= w;
166  }
167  glPopMatrix();
168 }
169 
170 
171 void
173  unsigned int noLinks = getLinkNumber();
174  const PositionVector& g = getShape();
175  const Position& end = g.getEnd();
176  const Position& f = g[-2];
177  const Position& s = end;
178  SUMOReal rot = (SUMOReal) atan2((s.x() - f.x()), (f.y() - s.y())) * (SUMOReal) 180.0 / (SUMOReal) PI;
179  if (noLinks == 0) {
180  glPushName(getGlID());
181  // draw a grey bar if no links are on the street
182  glColor3d(0.5, 0.5, 0.5);
183  glPushMatrix();
184  glTranslated(end.x(), end.y(), 0);
185  glRotated(rot, 0, 0, 1);
186  glBegin(GL_QUADS);
187  glVertex2d(-myHalfLaneWidth, 0.0);
188  glVertex2d(-myHalfLaneWidth, 0.5);
189  glVertex2d(myHalfLaneWidth, 0.5);
190  glVertex2d(myHalfLaneWidth, 0.0);
191  glEnd();
192  glPopMatrix();
193  glPopName();
194  return;
195  }
196  // draw all links
197  SUMOReal w = myLane.getWidth() / (SUMOReal) noLinks;
198  SUMOReal x1 = 0;
199  glPushMatrix();
200  glTranslated(end.x(), end.y(), 0);
201  glRotated(rot, 0, 0, 1);
202  for (unsigned int i = 0; i < noLinks; ++i) {
203  SUMOReal x2 = x1 + w;
204  MSLink* link = getLane().getLinkCont()[i];
205  // select glID
206  switch (link->getState()) {
209  case LINKSTATE_TL_RED:
213  glPushName(net.getLinkTLID(link));
214  break;
215  case LINKSTATE_MAJOR:
216  case LINKSTATE_MINOR:
217  case LINKSTATE_EQUAL:
219  default:
220  glPushName(getGlID());
221  break;
222  }
223  // select color
224  switch (link->getState()) {
227  glColor3d(0, 1, 0);
228  break;
229  case LINKSTATE_TL_RED:
230  glColor3d(1, 0, 0);
231  break;
234  glColor3d(1, 1, 0);
235  break;
237  glColor3d(.7, .7, 0);
238  break;
240  glColor3d(0, 1, 1);
241  break;
242  case LINKSTATE_MAJOR:
243  glColor3d(1, 1, 1);
244  break;
245  case LINKSTATE_MINOR:
246  glColor3d(.2, .2, .2);
247  break;
248  case LINKSTATE_EQUAL:
249  glColor3d(.5, .5, .5);
250  break;
251  case LINKSTATE_DEADEND:
252  glColor3d(0, 0, 0);
253  break;
254  }
255  glBegin(GL_QUADS);
256  glVertex2d(x1 - myHalfLaneWidth, 0.0);
257  glVertex2d(x1 - myHalfLaneWidth, 0.5);
258  glVertex2d(x2 - myHalfLaneWidth, 0.5);
259  glVertex2d(x2 - myHalfLaneWidth, 0.0);
260  glEnd();
261  glPopName();
262  x1 = x2;
263  x2 += w;
264  }
265  glPopMatrix();
266 }
267 
268 
269 void
271  unsigned int noLinks = getLinkNumber();
272  if (noLinks == 0) {
273  return;
274  }
275  // draw all links
276  const Position& end = getShape().getEnd();
277  const Position& f = getShape()[-2];
278  SUMOReal rot = (SUMOReal) atan2((end.x() - f.x()), (f.y() - end.y())) * (SUMOReal) 180.0 / (SUMOReal) PI;
279  glPushMatrix();
280  glPushName(0);
281  glColor3d(1, 1, 1);
282  glTranslated(end.x(), end.y(), 0);
283  glRotated(rot, 0, 0, 1);
284  for (unsigned int i = 0; i < noLinks; ++i) {
285  LinkDirection dir = getLane().getLinkCont()[i]->getDirection();
286  LinkState state = getLane().getLinkCont()[i]->getState();
287  if (state == LINKSTATE_TL_OFF_NOSIGNAL || dir == LINKDIR_NODIR) {
288  continue;
289  }
290  switch (dir) {
291  case LINKDIR_STRAIGHT:
292  GLHelper::drawBoxLine(Position(0, 4), 0, 2, .05);
294  break;
295  case LINKDIR_TURN:
296  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
297  GLHelper::drawBoxLine(Position(0, 2.5), 90, .5, .05);
298  GLHelper::drawBoxLine(Position(0.5, 2.5), 180, 1, .05);
299  GLHelper::drawTriangleAtEnd(Line(Position(0.5, 2.5), Position(0.5, 4)), (SUMOReal) 1, (SUMOReal) .25);
300  break;
301  case LINKDIR_LEFT:
302  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
303  GLHelper::drawBoxLine(Position(0, 2.5), 90, 1, .05);
304  GLHelper::drawTriangleAtEnd(Line(Position(0, 2.5), Position(1.5, 2.5)), (SUMOReal) 1, (SUMOReal) .25);
305  break;
306  case LINKDIR_RIGHT:
307  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
308  GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
309  GLHelper::drawTriangleAtEnd(Line(Position(0, 2.5), Position(-1.5, 2.5)), (SUMOReal) 1, (SUMOReal) .25);
310  break;
311  case LINKDIR_PARTLEFT:
312  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
313  GLHelper::drawBoxLine(Position(0, 2.5), 45, .7, .05);
314  GLHelper::drawTriangleAtEnd(Line(Position(0, 2.5), Position(1.2, 1.3)), (SUMOReal) 1, (SUMOReal) .25);
315  break;
316  case LINKDIR_PARTRIGHT:
317  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
318  GLHelper::drawBoxLine(Position(0, 2.5), -45, .7, .05);
319  GLHelper::drawTriangleAtEnd(Line(Position(0, 2.5), Position(-1.2, 1.3)), (SUMOReal) 1, (SUMOReal) .25);
320  break;
321  }
322  }
323  glPopMatrix();
324  glPopName();
325 }
326 
327 
328 void
330  unsigned int noLinks = getLinkNumber();
331  for (unsigned int i = 0; i < noLinks; ++i) {
332  LinkState state = getLane().getLinkCont()[i]->getState();
333  const MSLane* connected = getLane().getLinkCont()[i]->getLane();
334  if (connected == 0) {
335  continue;
336  }
337  switch (state) {
340  glColor3d(0, 1, 0);
341  break;
342  case LINKSTATE_TL_RED:
343  glColor3d(1, 0, 0);
344  break;
347  glColor3d(1, 1, 0);
348  break;
350  glColor3d(1, 1, 0);
351  break;
353  glColor3d(0, 1, 1);
354  break;
355  case LINKSTATE_MAJOR:
356  glColor3d(1, 1, 1);
357  break;
358  case LINKSTATE_MINOR:
359  glColor3d(.2, .2, .2);
360  break;
361  case LINKSTATE_EQUAL:
362  glColor3d(.5, .5, .5);
363  break;
364  case LINKSTATE_DEADEND:
365  glColor3d(0, 0, 0);
366  break;
367  }
368 
369  glBegin(GL_LINES);
370  const Position& p1 = getShape()[-1];
371  const Position& p2 = connected->getShape()[0];
372  glVertex2f(p1.x(), p1.y());
373  glVertex2f(p2.x(), p2.y());
374  glEnd();
375  GLHelper::drawTriangleAtEnd(Line(p1, p2), (SUMOReal) .4, (SUMOReal) .2);
376  }
377 }
378 
379 
380 void
382  glPushMatrix();
383  const bool isInternal = getLane().getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL;
384  bool mustDrawMarkings = false;
385  if (isInternal) {
386  // draw internal lanes on top of junctions
387  glTranslated(0, 0, GLO_JUNCTION + 0.1);
388  } else {
389  glTranslated(0, 0, getType());
390  }
391  // set lane color
392  if (!MSGlobals::gUseMesoSim) {
393  setColor(s);
394  glPushName(getGlID()); // do not register for clicks in MESOSIM
395  }
396  // draw lane
397  // check whether it is not too small
398  if (s.scale < 1.) {
400  if (!MSGlobals::gUseMesoSim) {
401  glPopName();
402  }
403  glPopMatrix();
404  } else {
405  if (!isInternal) {
407  mustDrawMarkings = true;
408  } else {
410  }
411  if (!MSGlobals::gUseMesoSim) {
412  glPopName();
413  }
414  glPopMatrix();
415  // draw ROWs (not for inner lanes)
416  if (!isInternal) {
417  glPushMatrix();
418  glTranslated(0, 0, GLO_JUNCTION); // must draw on top of junction shape
419  GUINet* net = (GUINet*) MSNet::getInstance();
420  glTranslated(0, 0, .2);
422  if (s.showLinkDecals) {
424  }
425  if (s.showLane2Lane) {
426  // this should be independent to the geometry:
427  // draw from end of first to the begin of second
429  }
430  glTranslated(0, 0, .1);
431  if (s.drawLinkJunctionIndex) {
433  }
434  if (s.drawLinkTLIndex) {
436  }
437  glPopMatrix();
438  }
439  }
440  if (mustDrawMarkings) { // needs matrix reset
441  drawMarkings(s);
442  }
443  // draw vehicles
444  if (s.scale > s.minVehicleSize) {
445  // retrieve vehicles from lane; disallow simulation
446  const MSLane::VehCont& vehicles = myLane.getVehiclesSecure();
447  for (MSLane::VehCont::const_iterator v = vehicles.begin(); v != vehicles.end(); ++v) {
448  static_cast<const GUIVehicle * const>(*v)->drawGL(s);
449  }
450  // allow lane simulation
452  }
453 }
454 
455 
456 void
458  glPushMatrix();
459  glPushName(0);
460  glTranslated(0, 0, GLO_EDGE);
461 #ifdef HAVE_MESOSIM
463 #endif
464  setColor(s);
465  // optionally draw inverse markings
466  if (myIndex > 0) {
467  int e = (int) getShape().size() - 1;
468  for (int i = 0; i < e; i++) {
469  glPushMatrix();
470  glTranslated(getShape()[i].x(), getShape()[i].y(), 0.1);
471  glRotated(myShapeRotations[i], 0, 0, 1);
472  for (SUMOReal t = 0; t < myShapeLengths[i]; t += 6) {
473  glBegin(GL_QUADS);
474  glVertex2d(-1.8, -t);
475  glVertex2d(-1.8, -t - 3.);
476  glVertex2d(1.0, -t - 3.);
477  glVertex2d(1.0, -t);
478  glEnd();
479  }
480  glPopMatrix();
481  }
482  }
483  // draw white boundings and white markings
484  glColor3d(1, 1, 1);
486  getShape(),
488  getShapeLengths(),
490  glPopMatrix();
491  glPopName();
492 }
493 
494 
497  GUISUMOAbstractView& parent) {
498  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
499  buildPopupHeader(ret, app);
501  //
504  //
505  buildShowParamsPopupEntry(ret, false);
507  new FXMenuCommand(ret, ("pos: " + toString(pos)).c_str(), 0, 0, 0);
508  new FXMenuSeparator(ret);
509  buildPositionCopyEntry(ret, false);
510  return ret;
511 }
512 
513 
518  new GUIParameterTableWindow(app, *this, 2);
519  // add items
520  ret->mkItem("maxspeed [m/s]", false, myLane.getMaxSpeed());
521  ret->mkItem("length [m]", false, myLane.getLength());
522  // close building
523  ret->closeBuilding();
524  return ret;
525 }
526 
527 
528 Boundary
530  Boundary b;
531  b.add(myShape[0]);
532  b.add(myShape[-1]);
533  b.grow(20);
534  return b;
535 }
536 
537 
538 
539 
540 const PositionVector&
542  return myShape;
543 }
544 
545 
546 unsigned int
548  return (unsigned int) myLane.getLinkCont().size();
549 }
550 
551 
552 const std::vector<SUMOReal>&
554  return myShapeRotations;
555 }
556 
557 
558 const std::vector<SUMOReal>&
560  return myShapeLengths;
561 }
562 
563 
564 SUMOReal
566  return myLane.myVehicles.size() == 0
567  ? 0
568  : (*(myLane.myVehicles.end() - 1))->getWaitingSeconds();
569 }
570 
571 
572 SUMOReal
574  return (SUMOReal) myLane.getEdge().getLanes().size();
575 }
576 
577 
578 // ------------ Current state retrieval
579 SUMOReal
582 }
583 
584 
585 SUMOReal
588 }
589 
590 
591 SUMOReal
594 }
595 
596 
597 SUMOReal
600 }
601 
602 
603 SUMOReal
606 }
607 
608 
609 SUMOReal
612 }
613 
614 
615 void
618 }
619 
620 
621 SUMOReal
622 GUILaneWrapper::getColorValue(size_t activeScheme) const {
623  switch (activeScheme) {
624  case 1:
625  return gSelected.isSelected(getType(), getGlID());
626  case 2: {
627  if (getLane().allowsVehicleClass(SVC_PASSENGER)) {
628  return 0;
629  } else {
630  return 1;
631  }
632  }
633  case 3:
634  return getLane().getMaxSpeed();
635  case 4:
636  return getLane().getOccupancy();
637  case 5:
638  return firstWaitingTime();
639  case 6:
640  return getEdgeLaneNumber();
641  case 7:
643  case 8:
645  case 9:
647  case 10:
649  case 11:
651  case 12:
653  case 13:
655  case 14: {
657  MSEdge& e = getLane().getEdge();
658  if (!ews.knowsTravelTime(&e)) {
659  return -1;
660  } else {
661  SUMOReal value(0);
662  ews.retrieveExistingTravelTime(&e, 0, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), value);
663  return value;
664  }
665  }
666  case 15: {
668  MSEdge& e = getLane().getEdge();
669  if (!ews.knowsTravelTime(&e)) {
670  return -1;
671  } else {
672  SUMOReal value(0);
673  ews.retrieveExistingTravelTime(&e, 0, 0, value);
674  return (getLane().getLength() / getLane().getMaxSpeed()) / (getLane().getMaxSpeed() / value);
675  }
676  }
677  }
678  return 0;
679 }
680 
681 /****************************************************************************/
682