SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GUILane.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // Representation of a lane in the micro simulation (gui-version)
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
12 // Copyright (C) 2001-2014 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>
34 #include <utility>
36 #include <utils/geom/GeomHelper.h>
37 #include <utils/geom/Position.h>
40 #include <utils/common/StdDefs.h>
41 #include <utils/geom/GeomHelper.h>
42 #include <utils/gui/div/GLHelper.h>
47 #include <microsim/MSLane.h>
50 #include <microsim/MSNet.h>
52 #include "GUILane.h"
53 #include "GUIEdge.h"
54 #include "GUIVehicle.h"
55 #include "GUINet.h"
56 
57 #ifdef HAVE_OSG
58 #include <osg/Geometry>
59 #endif
60 
61 #ifdef CHECK_MEMORY_LEAKS
62 #include <foreign/nvwa/debug_new.h>
63 #endif // CHECK_MEMORY_LEAKS
64 
65 //#define GUILane_DEBUG_DRAW_WALKING_AREA_VERTICES
66 
67 // ===========================================================================
68 // method definitions
69 // ===========================================================================
70 GUILane::GUILane(const std::string& id, SUMOReal maxSpeed, SUMOReal length,
71  MSEdge* const edge, unsigned int numericalID,
72  const PositionVector& shape, SUMOReal width,
73  SVCPermissions permissions, unsigned int index)
74  : MSLane(id, maxSpeed, length, edge, numericalID, shape, width, permissions),
75  GUIGlObject(GLO_LANE, id) {
76  myShapeRotations.reserve(myShape.size() - 1);
77  myShapeLengths.reserve(myShape.size() - 1);
78  int e = (int) myShape.size() - 1;
79  for (int i = 0; i < e; ++i) {
80  const Position& f = myShape[i];
81  const Position& s = myShape[i + 1];
82  myShapeLengths.push_back(f.distanceTo2D(s));
83  myShapeRotations.push_back(RAD2DEG(atan2(s.x() - f.x(), f.y() - s.y())));
84  }
85  //
88  myIndex = index;
89 }
90 
91 
93  // just to quit cleanly on a failure
94  if (myLock.locked()) {
95  myLock.unlock();
96  }
97 }
98 
99 
100 // ------ Vehicle insertion ------
101 void
103  const MSLane::VehCont::iterator& at,
104  MSMoveReminder::Notification notification) {
106  MSLane::incorporateVehicle(veh, pos, speed, at, notification);
107 }
108 
109 
110 // ------ Access to vehicles ------
111 const MSLane::VehCont&
113  myLock.lock();
114  return myVehicles;
115 }
116 
117 
118 void
120  myLock.unlock();
121 }
122 
123 
124 void
128 }
129 
130 
131 bool
132 GUILane::executeMovements(SUMOTime t, std::vector<MSLane*>& into) {
134  return MSLane::executeMovements(t, into);
135 }
136 
137 
138 MSVehicle*
141  return MSLane::removeVehicle(remVehicle, notification);
142 }
143 
144 
145 void
149 }
150 
151 
152 bool
155  return MSLane::integrateNewVehicle(t);
156 }
157 
158 
159 void
160 GUILane::detectCollisions(SUMOTime timestep, const std::string& stage) {
162  MSLane::detectCollisions(timestep, stage);
163 }
164 
165 
166 // ------ Drawing methods ------
167 void
169  unsigned int noLinks = (unsigned int)myLinks.size();
170  if (noLinks == 0) {
171  return;
172  }
173  // draw all links
174  if (getEdge().isCrossing()) {
175  // draw indices at the start and end of the crossing
177  PositionVector shape = getShape();
178  shape.extrapolate(0.5); // draw on top of the walking area
179  drawTextAtEnd(toString(link->getIndex()), shape, 0);
180  drawTextAtEnd(toString(link->getIndex()), shape.reverse(), 0);
181  return;
182  }
183  // draw all links
184  SUMOReal w = myWidth / (SUMOReal) noLinks;
186  for (int i = noLinks; --i >= 0;) {
187  SUMOReal x2 = x1 - (SUMOReal)(w / 2.);
188  drawTextAtEnd(toString(myLinks[i]->getIndex()), getShape(), x2);
189  x1 -= w;
190  }
191 }
192 
193 
194 void
195 GUILane::drawTLSLinkNo(const GUINet& net) const {
196  unsigned int noLinks = (unsigned int)myLinks.size();
197  if (noLinks == 0) {
198  return;
199  }
200  if (getEdge().isCrossing()) {
201  // draw indices at the start and end of the crossing
203  int linkNo = net.getLinkTLIndex(link);
204  if (linkNo >= 0) {
205  PositionVector shape = getShape();
206  shape.extrapolate(0.5); // draw on top of the walking area
207  drawTextAtEnd(toString(linkNo), shape, 0);
208  drawTextAtEnd(toString(linkNo), shape.reverse(), 0);
209  }
210  return;
211  }
212  // draw all links
213  SUMOReal w = myWidth / (SUMOReal) noLinks;
215  for (int i = noLinks; --i >= 0;) {
216  SUMOReal x2 = x1 - (SUMOReal)(w / 2.);
217  int linkNo = net.getLinkTLIndex(myLinks[i]);
218  if (linkNo < 0) {
219  continue;
220  }
221  drawTextAtEnd(toString(linkNo), getShape(), x2);
222  x1 -= w;
223  }
224 }
225 
226 
227 void
228 GUILane::drawTextAtEnd(const std::string& text, const PositionVector& shape, SUMOReal x) const {
229  glPushMatrix();
230  const Position& end = shape.back();
231  const Position& f = shape[-2];
232  const SUMOReal rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
233  glTranslated(end.x(), end.y(), 0);
234  glRotated(rot, 0, 0, 1);
235  GLHelper::drawText(text, Position(x, 0), 0, .6, RGBColor(128, 128, 255, 255), 180);
236  glPopMatrix();
237 }
238 
239 
240 void
241 GUILane::drawLinkRules(const GUINet& net) const {
242  unsigned int noLinks = (unsigned int)myLinks.size();
243  if (noLinks == 0) {
244  drawLinkRule(net, 0, getShape(), 0, 0);
245  return;
246  }
247  if (getEdge().isCrossing()) {
248  // draw rules at the start and end of the crossing
250  PositionVector shape = getShape();
251  shape.extrapolate(0.5); // draw on top of the walking area
252  drawLinkRule(net, link, shape, 0, myWidth);
253  drawLinkRule(net, link, shape.reverse(), 0, myWidth);
254  return;
255  }
256  // draw all links
257  SUMOReal w = myWidth / (SUMOReal) noLinks;
258  SUMOReal x1 = 0;
259  for (unsigned int i = 0; i < noLinks; ++i) {
260  SUMOReal x2 = x1 + w;
261  drawLinkRule(net, myLinks[i], getShape(), x1, x2);
262  x1 = x2;
263  }
264 }
265 
266 
267 void
268 GUILane::drawLinkRule(const GUINet& net, MSLink* link, const PositionVector& shape, SUMOReal x1, SUMOReal x2) const {
269  const Position& end = shape.back();
270  const Position& f = shape[-2];
271  const SUMOReal rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
272  if (link == 0) {
273  glPushName(getGlID());
275  glPushMatrix();
276  glTranslated(end.x(), end.y(), 0);
277  glRotated(rot, 0, 0, 1);
278  glBegin(GL_QUADS);
279  glVertex2d(-myHalfLaneWidth, 0.0);
280  glVertex2d(-myHalfLaneWidth, 0.5);
281  glVertex2d(myHalfLaneWidth, 0.5);
282  glVertex2d(myHalfLaneWidth, 0.0);
283  glEnd();
284  glPopMatrix();
285  glPopName();
286  } else {
287  glPushMatrix();
288  glTranslated(end.x(), end.y(), 0);
289  glRotated(rot, 0, 0, 1);
290  // select glID
291  switch (link->getState()) {
294  case LINKSTATE_TL_RED:
298  glPushName(net.getLinkTLID(link));
299  break;
300  case LINKSTATE_MAJOR:
301  case LINKSTATE_MINOR:
302  case LINKSTATE_EQUAL:
304  default:
305  glPushName(getGlID());
306  break;
307  }
309  if (!isRailway(myPermissions) || link->getState() != LINKSTATE_MAJOR) {
310  // THE WHITE BAR SHOULD BE THE DEFAULT FOR MOST RAILWAY
311  // LINKS AND LOOKS UGLY SO WE DO NOT DRAW IT
312  glBegin(GL_QUADS);
313  glVertex2d(x1 - myHalfLaneWidth, 0.0);
314  glVertex2d(x1 - myHalfLaneWidth, 0.5);
315  glVertex2d(x2 - myHalfLaneWidth, 0.5);
316  glVertex2d(x2 - myHalfLaneWidth, 0.0);
317  glEnd();
318  }
319  glPopName();
320  glPopMatrix();
321  }
322 }
323 
324 void
326  if (myLinks.size() == 0) {
327  return;
328  }
329  // draw all links
330  const Position& end = getShape().back();
331  const Position& f = getShape()[-2];
332  const SUMOReal rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
333  glPushMatrix();
334  glPushName(0);
335  glColor3d(1, 1, 1);
336  glTranslated(end.x(), end.y(), 0);
337  glRotated(rot, 0, 0, 1);
339  glScaled(myWidth / SUMO_const_laneWidth, 1, 1);
340  }
341  for (std::vector<MSLink*>::const_iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
342  LinkDirection dir = (*i)->getDirection();
343  LinkState state = (*i)->getState();
344  if (state == LINKSTATE_TL_OFF_NOSIGNAL || dir == LINKDIR_NODIR) {
345  continue;
346  }
347  switch (dir) {
348  case LINKDIR_STRAIGHT:
349  GLHelper::drawBoxLine(Position(0, 4), 0, 2, .05);
351  break;
352  case LINKDIR_TURN:
353  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
354  GLHelper::drawBoxLine(Position(0, 2.5), 90, .5, .05);
355  GLHelper::drawBoxLine(Position(0.5, 2.5), 180, 1, .05);
356  GLHelper::drawTriangleAtEnd(Line(Position(0.5, 2.5), Position(0.5, 4)), (SUMOReal) 1, (SUMOReal) .25);
357  break;
358  case LINKDIR_LEFT:
359  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
360  GLHelper::drawBoxLine(Position(0, 2.5), 90, 1, .05);
361  GLHelper::drawTriangleAtEnd(Line(Position(0, 2.5), Position(1.5, 2.5)), (SUMOReal) 1, (SUMOReal) .25);
362  break;
363  case LINKDIR_RIGHT:
364  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
365  GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
366  GLHelper::drawTriangleAtEnd(Line(Position(0, 2.5), Position(-1.5, 2.5)), (SUMOReal) 1, (SUMOReal) .25);
367  break;
368  case LINKDIR_PARTLEFT:
369  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
370  GLHelper::drawBoxLine(Position(0, 2.5), 45, .7, .05);
371  GLHelper::drawTriangleAtEnd(Line(Position(0, 2.5), Position(1.2, 1.3)), (SUMOReal) 1, (SUMOReal) .25);
372  break;
373  case LINKDIR_PARTRIGHT:
374  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
375  GLHelper::drawBoxLine(Position(0, 2.5), -45, .7, .05);
376  GLHelper::drawTriangleAtEnd(Line(Position(0, 2.5), Position(-1.2, 1.3)), (SUMOReal) 1, (SUMOReal) .25);
377  break;
378  default:
379  break;
380  }
381  }
382  glPopMatrix();
383  glPopName();
384 }
385 
386 
387 void
389  for (std::vector<MSLink*>::const_iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
390  LinkState state = (*i)->getState();
391  const MSLane* connected = (*i)->getLane();
392  if (connected == 0) {
393  continue;
394  }
395  switch (state) {
398  glColor3d(0, 1, 0);
399  break;
400  case LINKSTATE_TL_RED:
401  glColor3d(1, 0, 0);
402  break;
405  glColor3d(1, 1, 0);
406  break;
408  glColor3d(1, 1, 0);
409  break;
411  glColor3d(0, 1, 1);
412  break;
413  case LINKSTATE_MAJOR:
414  glColor3d(1, 1, 1);
415  break;
416  case LINKSTATE_MINOR:
417  glColor3d(.2, .2, .2);
418  break;
419  case LINKSTATE_STOP:
420  glColor3d(.4, .2, .2);
421  break;
422  case LINKSTATE_EQUAL:
423  glColor3d(.5, .5, .5);
424  break;
426  glColor3d(.2, .2, .4);
427  break;
428  case LINKSTATE_DEADEND:
429  glColor3d(0, 0, 0);
430  break;
431  }
432 
433  glBegin(GL_LINES);
434  const Position& p1 = getShape()[-1];
435  const Position& p2 = connected->getShape()[0];
436  glVertex2f(p1.x(), p1.y());
437  glVertex2f(p2.x(), p2.y());
438  glEnd();
439  GLHelper::drawTriangleAtEnd(Line(p1, p2), (SUMOReal) .4, (SUMOReal) .2);
440  }
441 }
442 
443 
444 void
446  glPushMatrix();
447  const bool isCrossing = myEdge->getPurpose() == MSEdge::EDGEFUNCTION_CROSSING;
448  const bool isWalkingArea = myEdge->getPurpose() == MSEdge::EDGEFUNCTION_WALKINGAREA;
449  const bool isInternal = isCrossing || isWalkingArea || myEdge->getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL;
450  bool mustDrawMarkings = false;
451  const bool drawDetails = s.scale * s.laneWidthExaggeration > 5;
452  if (isCrossing || isWalkingArea) {
453  // draw internal lanes on top of junctions
454  glTranslated(0, 0, GLO_JUNCTION + 0.1);
455  } else {
456  glTranslated(0, 0, getType());
457  }
458  // set lane color
459  if (!MSGlobals::gUseMesoSim) {
460  setColor(s);
461  glPushName(getGlID()); // do not register for clicks in MESOSIM
462  }
463  // draw lane
464  // check whether it is not too small
465  if (s.scale * s.laneWidthExaggeration < 1.) {
467  if (!MSGlobals::gUseMesoSim) {
468  glPopName();
469  }
470  glPopMatrix();
471  } else {
472  GUINet* net = (GUINet*) MSNet::getInstance();
473  if (isRailway(myPermissions)) {
474  // draw as railway
475  const SUMOReal halfRailWidth = 0.725 * s.laneWidthExaggeration;
477  glColor3d(1, 1, 1);
478  glTranslated(0, 0, .1);
480  if (!MSGlobals::gUseMesoSim) {
481  setColor(s);
482  }
484  } else if (isCrossing) {
485  // determine priority to decide color
487  if (link->havePriority() || net->getLinkTLIndex(link) > 0) {
488  glColor3d(0.9, 0.9, 0.9);
489  } else {
490  glColor3d(0.1, 0.1, 0.1);
491  }
492  glTranslated(0, 0, .2);
493  drawCrossties(0.5, 1.0, getWidth() * 0.5);
494  glTranslated(0, 0, -.2);
495  } else if (isWalkingArea) {
496  glTranslated(0, 0, .2);
497  if (s.scale * s.laneWidthExaggeration < 20.) {
499  } else {
501  }
502  glTranslated(0, 0, -.2);
503 #ifdef GUILane_DEBUG_DRAW_WALKING_AREA_VERTICES
504  RGBColor color = RGBColor::fromHSV(RandHelper::rand(360), 1, 1);
505  glTranslated(0, 0, .4);
506  for (int i = 0; i < (int)myShape.size(); ++i) {
508  80 / s.scale, color, 0);
509  }
510  glTranslated(0, 0, -.4);
511 #endif
512  } else {
513  const SUMOReal laneWidth = isInternal ? myQuarterLaneWidth : myHalfLaneWidth;
514  mustDrawMarkings = !isInternal && myPermissions != 0 && myPermissions != SVC_PEDESTRIAN;
515  // recognize full transparency and simply don't draw
516  GLfloat color[4];
517  glGetFloatv(GL_CURRENT_COLOR, color);
518  if (color[3] > 0) {
519  const int cornerDetail = drawDetails ? s.scale * s.laneWidthExaggeration : 0;
521  }
522  }
523  if (!MSGlobals::gUseMesoSim) {
524  glPopName();
525  }
526  glPopMatrix();
527  // draw ROWs (not for inner lanes)
528  if ((!isInternal || isCrossing) && drawDetails) {
529  glPushMatrix();
530  glTranslated(0, 0, GLO_JUNCTION); // must draw on top of junction shape
531  glTranslated(0, 0, .5);
532  drawLinkRules(*net);
534  drawArrows();
535  }
536  if (s.showLane2Lane) {
537  // this should be independent to the geometry:
538  // draw from end of first to the begin of second
540  }
541  glTranslated(0, 0, .1);
542  if (s.drawLinkJunctionIndex) {
543  drawLinkNo();
544  }
545  if (s.drawLinkTLIndex) {
546  drawTLSLinkNo(*net);
547  }
548  glPopMatrix();
549  }
550  }
551  if (mustDrawMarkings && drawDetails) { // needs matrix reset
553  }
554  // draw vehicles
555  if (s.scale > s.minVehicleSize) {
556  // retrieve vehicles from lane; disallow simulation
557  const MSLane::VehCont& vehicles = getVehiclesSecure();
558  for (MSLane::VehCont::const_iterator v = vehicles.begin(); v != vehicles.end(); ++v) {
559  if ((*v)->getLane() == this) {
560  static_cast<const GUIVehicle* const>(*v)->drawGL(s);
561  } // else: this is the shadow during a continuous lane change
562  }
563  // draw parking vehicles
564  const std::set<const MSVehicle*> parking = MSVehicleTransfer::getInstance()->getParkingVehicles(this);
565  for (std::set<const MSVehicle*>::const_iterator v = parking.begin(); v != parking.end(); ++v) {
566  static_cast<const GUIVehicle* const>(*v)->drawGL(s);
567  }
568  // allow lane simulation
569  releaseVehicles();
570  }
571 }
572 
573 
574 void
576  glPushMatrix();
577  glPushName(0);
578  glTranslated(0, 0, GLO_EDGE);
579 #ifdef HAVE_INTERNAL
581 #endif
582  setColor(s);
583  // optionally draw inverse markings
584  if (myIndex > 0 && (myEdge->getLanes()[myIndex - 1]->getPermissions() & myPermissions) != 0) {
585  SUMOReal mw = (myHalfLaneWidth + SUMO_const_laneOffset + .01) * scale;
586  int e = (int) getShape().size() - 1;
587  for (int i = 0; i < e; ++i) {
588  glPushMatrix();
589  glTranslated(getShape()[i].x(), getShape()[i].y(), 0.1);
590  glRotated(myShapeRotations[i], 0, 0, 1);
591  for (SUMOReal t = 0; t < myShapeLengths[i]; t += 6) {
592  glBegin(GL_QUADS);
593  glVertex2d(-mw, -t);
594  glVertex2d(-mw, -t - 3.);
595  glVertex2d(myQuarterLaneWidth * scale, -t - 3.);
596  glVertex2d(myQuarterLaneWidth * scale, -t);
597  glEnd();
598  }
599  glPopMatrix();
600  }
601  }
602  // draw white boundings and white markings
603  glColor3d(1, 1, 1);
605  getShape(),
607  getShapeLengths(),
608  (getHalfWidth() + SUMO_const_laneOffset) * scale);
609  glPopMatrix();
610  glPopName();
611 }
612 
613 
614 void
615 GUILane::drawCrossties(SUMOReal length, SUMOReal spacing, SUMOReal halfWidth) const {
616  glPushMatrix();
617  glPushName(0);
618  // draw on top of of the white area between the rails
619  glTranslated(0, 0, 0.1);
620  int e = (int) getShape().size() - 1;
621  for (int i = 0; i < e; ++i) {
622  glPushMatrix();
623  glTranslated(getShape()[i].x(), getShape()[i].y(), 0.0);
624  glRotated(myShapeRotations[i], 0, 0, 1);
625  for (SUMOReal t = 0; t < myShapeLengths[i]; t += spacing) {
626  glBegin(GL_QUADS);
627  glVertex2d(-halfWidth, -t);
628  glVertex2d(-halfWidth, -t - length);
629  glVertex2d(halfWidth, -t - length);
630  glVertex2d(halfWidth, -t);
631  glEnd();
632  }
633  glPopMatrix();
634  }
635  glPopMatrix();
636  glPopName();
637 }
638 
639 // ------ inherited from GUIGlObject
642  GUISUMOAbstractView& parent) {
643  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
644  buildPopupHeader(ret, app);
646  //
649  //
650  buildShowParamsPopupEntry(ret, false);
652  new FXMenuCommand(ret, ("pos: " + toString(pos)).c_str(), 0, 0, 0);
653  new FXMenuSeparator(ret);
654  buildPositionCopyEntry(ret, false);
655  return ret;
656 }
657 
658 
663  new GUIParameterTableWindow(app, *this, 7);
664  // add items
665  ret->mkItem("maxspeed [m/s]", false, getSpeedLimit());
666  ret->mkItem("length [m]", false, myLength);
667  ret->mkItem("street name", false, myEdge->getStreetName());
668  ret->mkItem("stored traveltime [s]", true, new FunctionBinding<GUILane, SUMOReal>(this, &GUILane::getStoredEdgeTravelTime));
669  ret->mkItem("edge type", false, myEdge->getEdgeType());
670  ret->mkItem("allowed vehicle class", false, getVehicleClassNames(myPermissions));
671  ret->mkItem("disallowed vehicle class", false, getVehicleClassNames(~myPermissions));
672  ret->mkItem("permission code", false, myPermissions);
673  // close building
674  ret->closeBuilding();
675  return ret;
676 }
677 
678 
679 Boundary
681  Boundary b;
682  b.add(myShape[0]);
683  b.add(myShape[-1]);
684  b.grow(20);
685  return b;
686 }
687 
688 
689 
690 
691 
692 
693 
694 const PositionVector&
696  return myShape;
697 }
698 
699 
700 const std::vector<SUMOReal>&
702  return myShapeRotations;
703 }
704 
705 
706 const std::vector<SUMOReal>&
708  return myShapeLengths;
709 }
710 
711 
712 SUMOReal
714  return myVehicles.size() == 0 ? 0 : myVehicles.back()->getWaitingSeconds();
715 }
716 
717 
718 SUMOReal
720  return (SUMOReal) myEdge->getLanes().size();
721 }
722 
723 
724 SUMOReal
727  if (!ews.knowsTravelTime(myEdge)) {
728  return -1;
729  } else {
730  SUMOReal value(0);
731  ews.retrieveExistingTravelTime(myEdge, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), value);
732  return value;
733  }
734 }
735 
736 
737 void
739  const GUIColorer& c = s.laneColorer;
740  if (!setFunctionalColor(c.getActive())) {
742  }
743 }
744 
745 
746 bool
747 GUILane::setFunctionalColor(size_t activeScheme) const {
748  switch (activeScheme) {
749  case 18: {
750  SUMOReal hue = RAD2DEG(myShape.beginEndAngle()) + 180; // [0-360]
752  return true;
753  }
754  default:
755  return false;
756  }
757 }
758 
759 
760 SUMOReal
761 GUILane::getColorValue(size_t activeScheme) const {
762  switch (activeScheme) {
763  case 0:
764  switch (myPermissions) {
765  case SVC_PEDESTRIAN:
766  return 1;
767  case SVC_BICYCLE:
768  return 2;
769  case 0:
770  return 3;
771  default:
772  return 0;
773  }
774  case 1:
775  return gSelected.isSelected(getType(), getGlID()) ||
776  gSelected.isSelected(GLO_EDGE, dynamic_cast<GUIEdge*>(myEdge)->getGlID());
777  case 2:
778  return (SUMOReal)myPermissions;
779  case 3:
780  return getSpeedLimit();
781  case 4:
782  return getBruttoOccupancy();
783  case 5:
784  return getNettoOccupancy();
785  case 6:
786  return firstWaitingTime();
787  case 7:
788  return getEdgeLaneNumber();
789  case 8:
790  return getCO2Emissions() / myLength;
791  case 9:
792  return getCOEmissions() / myLength;
793  case 10:
794  return getPMxEmissions() / myLength;
795  case 11:
796  return getNOxEmissions() / myLength;
797  case 12:
798  return getHCEmissions() / myLength;
799  case 13:
800  return getFuelConsumption() / myLength;
801  case 14:
803  case 15: {
804  return getStoredEdgeTravelTime();
805  }
806  case 16: {
808  if (!ews.knowsTravelTime(myEdge)) {
809  return -1;
810  } else {
811  SUMOReal value(0);
812  ews.retrieveExistingTravelTime(myEdge, 0, value);
813  return 100 * myLength / value / getSpeedLimit();
814  }
815  }
816  case 17: {
817  return 1 / myLengthGeometryFactor;
818  }
819  }
820  return 0;
821 }
822 
823 #ifdef HAVE_OSG
824 void
825 GUILane::updateColor(const GUIVisualizationSettings& s) {
827  osg::Vec4ubArray* colors = dynamic_cast<osg::Vec4ubArray*>(myGeom->getColorArray());
828  (*colors)[0].set(col.red(), col.green(), col.blue(), col.alpha());
829  myGeom->setColorArray(colors);
830 }
831 #endif
832 
833 
834 
835 /****************************************************************************/
836