Eclipse SUMO - Simulation of Urban MObility
GUILane.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 // Representation of a lane in the micro simulation (gui-version)
21 /****************************************************************************/
22 #include <config.h>
23 
24 #include <string>
25 #include <utility>
27 #include <utils/geom/GeomHelper.h>
28 #include <utils/geom/Position.h>
32 #include <utils/common/StdDefs.h>
33 #include <utils/geom/GeomHelper.h>
34 #include <utils/gui/div/GLHelper.h>
42 #include <microsim/MSGlobals.h>
43 #include <microsim/MSLane.h>
44 #include <microsim/MSLink.h>
48 #include <microsim/MSNet.h>
50 #include <microsim/MSParkingArea.h>
52 #include <mesosim/MELoop.h>
53 #include <mesosim/MESegment.h>
54 #include "GUILane.h"
55 #include "GUIEdge.h"
56 #include "GUIVehicle.h"
57 #include "GUINet.h"
59 
60 #include <osgview/GUIOSGHeader.h>
61 
62 #define RENDERING_BUFFER 10
63 
64 //#define GUILane_DEBUG_DRAW_FOE_INTERSECTIONS
65 //#define GUILane_DEBUG_DRAW_CROSSING_OUTLINE
66 
67 // ===========================================================================
68 // static member declaration
69 // ===========================================================================
70 const RGBColor GUILane::MESO_USE_LANE_COLOR(0, 0, 0, 0);
72 
73 
74 // ===========================================================================
75 // method definitions
76 // ===========================================================================
77 GUILane::GUILane(const std::string& id, double maxSpeed, double friction, double length,
78  MSEdge* const edge, int numericalID,
79  const PositionVector& shape, double width,
80  SVCPermissions permissions,
81  SVCPermissions changeLeft, SVCPermissions changeRight,
82  int index, bool isRampAccel,
83  const std::string& type,
84  const PositionVector& outlineShape) :
85  MSLane(id, maxSpeed, friction, length, edge, numericalID, shape, width, permissions, changeLeft, changeRight, index, isRampAccel, type, outlineShape),
87  myParkingAreas(nullptr),
88  myTesselation(nullptr),
89 #ifdef HAVE_OSG
90  myGeom(0),
91 #endif
92  myAmClosed(false),
93  myLengthGeometryFactor2(myLengthGeometryFactor),
94  myLock(true) {
96  myShape = splitAtSegments(shape);
97  assert(fabs(myShape.length() - shape.length()) < POSITION_EPS);
98  assert(myShapeSegments.size() == myShape.size());
99  }
101  //
102  myHalfLaneWidth = myWidth / 2.;
104 }
105 
106 
108  // just to quit cleanly on a failure
109  if (myLock.locked()) {
110  myLock.unlock();
111  }
112  delete myParkingAreas;
113  delete myTesselation;
114 }
115 
116 
117 void
119  std::vector<double>& rotations,
120  std::vector<double>& lengths,
121  std::vector<RGBColor>& colors) {
122  rotations.clear();
123  lengths.clear();
124  colors.clear();
125  rotations.reserve(shape.size() - 1);
126  lengths.reserve(shape.size() - 1);
127  colors.reserve(shape.size() - 1);
128  int e = (int) shape.size() - 1;
129  for (int i = 0; i < e; ++i) {
130  const Position& f = shape[i];
131  const Position& s = shape[i + 1];
132  lengths.push_back(f.distanceTo2D(s));
133  rotations.push_back(RAD2DEG(atan2(s.x() - f.x(), f.y() - s.y())));
134  }
135 }
136 
137 
138 void
140  myShape2 = shape;
142  myLengthGeometryFactor2 = MAX2(POSITION_EPS, myShape2.length()) / myLength;
143 }
144 
145 
146 // ------ Vehicle insertion ------
147 void
148 GUILane::incorporateVehicle(MSVehicle* veh, double pos, double speed, double posLat,
149  const MSLane::VehCont::iterator& at,
150  MSMoveReminder::Notification notification) {
151  FXMutexLock locker(myLock);
152  MSLane::incorporateVehicle(veh, pos, speed, posLat, at, notification);
153 }
154 
155 
156 // ------ Access to vehicles ------
157 const MSLane::VehCont&
159  myLock.lock();
160  return myVehicles;
161 }
162 
163 
164 void
166  myLock.unlock();
167 }
168 
169 
170 void
172  FXMutexLock locker(myLock);
174 }
175 
176 void
178  FXMutexLock locker(myLock);
180 }
181 
182 
183 void
185  FXMutexLock locker(myLock);
187 }
188 
189 
190 MSVehicle*
191 GUILane::removeVehicle(MSVehicle* remVehicle, MSMoveReminder::Notification notification, bool notify) {
192  FXMutexLock locker(myLock);
193  return MSLane::removeVehicle(remVehicle, notification, notify);
194 }
195 
196 
197 void
199  FXMutexLock locker(myLock);
200  return MSLane::removeParking(remVehicle);
201 }
202 
203 
204 void
206  FXMutexLock locker(myLock);
208 }
209 
210 
211 void
213  FXMutexLock locker(myLock);
215 }
216 
217 
218 void
219 GUILane::detectCollisions(SUMOTime timestep, const std::string& stage) {
220  FXMutexLock locker(myLock);
221  MSLane::detectCollisions(timestep, stage);
222 }
223 
224 
225 double
227  FXMutexLock locker(myLock);
229 }
230 
231 
232 void
234  FXMutexLock locker(myLock);
236 }
237 
238 
239 // ------ Drawing methods ------
240 void
242  int noLinks = (int)myLinks.size();
243  if (noLinks == 0) {
244  return;
245  }
246  // draw all links
247  if (getEdge().isCrossing()) {
248  // draw indices at the start and end of the crossing
249  const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
251  shape.extrapolate(0.5); // draw on top of the walking area
254  return;
255  }
256  // draw all links
257  double w = myWidth / (double) noLinks;
258  double x1 = myHalfLaneWidth;
259  for (int i = noLinks; --i >= 0;) {
260  double x2 = x1 - (double)(w / 2.);
262  x1 -= w;
263  }
264 }
265 
266 
267 void
269  int noLinks = (int)myLinks.size();
270  if (noLinks == 0) {
271  return;
272  }
273  if (getEdge().isCrossing()) {
274  // draw indices at the start and end of the crossing
275  const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
276  int linkNo = net.getLinkTLIndex(link);
277  // maybe the reverse link is controlled separately
278  int linkNo2 = net.getLinkTLIndex(myLinks.front());
279  // otherwise, use the same index as the forward link
280  if (linkNo2 < 0) {
281  linkNo2 = linkNo;
282  }
283  if (linkNo >= 0) {
285  shape.extrapolate(0.5); // draw on top of the walking area
286  GLHelper::drawTextAtEnd(toString(linkNo2), shape, 0, s.drawLinkTLIndex, s.scale);
287  GLHelper::drawTextAtEnd(toString(linkNo), shape.reverse(), 0, s.drawLinkTLIndex, s.scale);
288  }
289  return;
290  }
291  // draw all links
292  double w = myWidth / (double) noLinks;
293  double x1 = myHalfLaneWidth;
294  for (int i = noLinks; --i >= 0;) {
295  double x2 = x1 - (double)(w / 2.);
296  int linkNo = net.getLinkTLIndex(myLinks[MSGlobals::gLefthand ? noLinks - 1 - i : i]);
297  if (linkNo < 0) {
298  continue;
299  }
301  x1 -= w;
302  }
303 }
304 
305 
306 void
308  int noLinks = (int)myLinks.size();
309  const PositionVector& shape = getShape(s.secondaryShape);
310  if (noLinks == 0) {
311  drawLinkRule(s, net, nullptr, shape, 0, 0);
312  return;
313  }
314  if (getEdge().isCrossing()) {
315  // draw rules at the start and end of the crossing
316  const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
317  const MSLink* link2 = myLinks.front();
318  if (link2->getTLLogic() == nullptr) {
319  link2 = link;
320  }
321  PositionVector tmp = shape;
322  tmp.extrapolate(0.5); // draw on top of the walking area
323  drawLinkRule(s, net, link2, tmp, 0, myWidth);
324  drawLinkRule(s, net, link, tmp.reverse(), 0, myWidth);
325  return;
326  }
327  // draw all links
328  const double isRailSignal = myEdge->getToJunction()->getType() == SumoXMLNodeType::RAIL_SIGNAL;
329  double w = myWidth / (double) noLinks;
330  if (isRailSignal && noLinks > 1 && myLinks.back()->isTurnaround() && s.showRails) {
331  w = myWidth / (double)(noLinks - 1);
332  }
333  double x1 = isRailSignal ? -myWidth * 0.5 : 0;
334  for (int i = 0; i < noLinks; ++i) {
335  double x2 = x1 + w;
336  drawLinkRule(s, net, myLinks[MSGlobals::gLefthand ? noLinks - 1 - i : i], shape, x1, x2);
337  x1 = x2;
338  }
339  // draw stopOffset for passenger cars
341  const double stopOffsetPassenger = myLaneStopOffset.getOffset();
342  const Position& end = shape.back();
343  const Position& f = shape[-2];
344  const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
347  glTranslated(end.x(), end.y(), 0);
348  glRotated(rot, 0, 0, 1);
349  glTranslated(0, stopOffsetPassenger, 0);
350  glBegin(GL_QUADS);
351  glVertex2d(-myHalfLaneWidth, 0.0);
352  glVertex2d(-myHalfLaneWidth, 0.2);
353  glVertex2d(myHalfLaneWidth, 0.2);
354  glVertex2d(myHalfLaneWidth, 0.0);
355  glEnd();
357  }
358 }
359 
360 
361 void
362 GUILane::drawLinkRule(const GUIVisualizationSettings& s, const GUINet& net, const MSLink* link, const PositionVector& shape, double x1, double x2) const {
363  const Position& end = shape.back();
364  const Position& f = shape[-2];
365  const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
366  if (link == nullptr) {
367  if (static_cast<GUIEdge*>(myEdge)->showDeadEnd()) {
369  } else {
371  }
373  glTranslated(end.x(), end.y(), 0);
374  glRotated(rot, 0, 0, 1);
375  glBegin(GL_QUADS);
376  glVertex2d(-myHalfLaneWidth, 0.0);
377  glVertex2d(-myHalfLaneWidth, 0.5);
378  glVertex2d(myHalfLaneWidth, 0.5);
379  glVertex2d(myHalfLaneWidth, 0.0);
380  glEnd();
382  } else {
384  glTranslated(end.x(), end.y(), 0);
385  glRotated(rot, 0, 0, 1);
386  // select glID
387 
388  switch (link->getState()) {
390  case LINKSTATE_STOP: {
391  // might be a traffic light link
392  int tlID = net.getLinkTLID(link);
393  GLHelper::pushName(tlID != 0 ? tlID : getGlID());
394  break;
395  }
398  case LINKSTATE_TL_RED:
404  GLHelper::pushName(net.getLinkTLID(link));
405  break;
406  case LINKSTATE_MAJOR:
407  case LINKSTATE_MINOR:
408  case LINKSTATE_EQUAL:
409  default:
411  break;
412  }
414  if (!(drawAsRailway(s) || drawAsWaterway(s)) || link->getState() != LINKSTATE_MAJOR) {
415  // the white bar should be the default for most railway
416  // links and looks ugly so we do not draw it
417  double scale = isInternal() ? 0.5 : 1;
419  scale *= MAX2(s.laneWidthExaggeration, s.junctionSize.getExaggeration(s, this, 10));
420  }
421  glScaled(scale, scale, 1);
422  glBegin(GL_QUADS);
423  glVertex2d(x1 - myHalfLaneWidth, 0.0);
424  glVertex2d(x1 - myHalfLaneWidth, 0.5);
425  glVertex2d(x2 - myHalfLaneWidth, 0.5);
426  glVertex2d(x2 - myHalfLaneWidth, 0.0);
427  glEnd();
428  }
431  }
432 }
433 
434 void
435 GUILane::drawArrows(bool secondaryShape) const {
436  if (myLinks.size() == 0) {
437  return;
438  }
439  // draw all links
440  const Position& end = getShape(secondaryShape).back();
441  const Position& f = getShape(secondaryShape)[-2];
442  const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
444  glColor3d(1, 1, 1);
445  glTranslated(end.x(), end.y(), 0);
446  glRotated(rot, 0, 0, 1);
448  glScaled(myWidth / SUMO_const_laneWidth, 1, 1);
449  }
450  for (const MSLink* const link : myLinks) {
451  LinkDirection dir = link->getDirection();
452  LinkState state = link->getState();
453  if (state == LINKSTATE_DEADEND || dir == LinkDirection::NODIR) {
454  continue;
455  }
456  switch (dir) {
458  GLHelper::drawBoxLine(Position(0, 4), 0, 2, .05);
459  GLHelper::drawTriangleAtEnd(Position(0, 4), Position(0, 1), (double) 1, (double) .25);
460  break;
461  case LinkDirection::TURN:
462  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
463  GLHelper::drawBoxLine(Position(0, 2.5), 90, .5, .05);
464  GLHelper::drawBoxLine(Position(0.5, 2.5), 180, 1, .05);
465  GLHelper::drawTriangleAtEnd(Position(0.5, 2.5), Position(0.5, 4), (double) 1, (double) .25);
466  break;
468  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
469  GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
470  GLHelper::drawBoxLine(Position(-0.5, 2.5), -180, 1, .05);
471  GLHelper::drawTriangleAtEnd(Position(-0.5, 2.5), Position(-0.5, 4), (double) 1, (double) .25);
472  break;
473  case LinkDirection::LEFT:
474  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
475  GLHelper::drawBoxLine(Position(0, 2.5), 90, 1, .05);
476  GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.5, 2.5), (double) 1, (double) .25);
477  break;
479  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
480  GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
481  GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.5, 2.5), (double) 1, (double) .25);
482  break;
484  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
485  GLHelper::drawBoxLine(Position(0, 2.5), 45, .7, .05);
486  GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.2, 1.3), (double) 1, (double) .25);
487  break;
489  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
490  GLHelper::drawBoxLine(Position(0, 2.5), -45, .7, .05);
491  GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.2, 1.3), (double) 1, (double) .25);
492  break;
493  default:
494  break;
495  }
496  }
498 }
499 
500 
501 void
502 GUILane::drawLane2LaneConnections(double exaggeration, bool s2) const {
503  Position centroid;
504  if (exaggeration > 1) {
505  centroid = myEdge->getToJunction()->getShape().getCentroid();
506  }
507  for (const MSLink* const link : myLinks) {
508  const GUILane* connected = dynamic_cast<GUILane*>(link->getLane());
509  if (connected == nullptr) {
510  continue;
511  }
513  glBegin(GL_LINES);
514  Position p1 = myEdge->isWalkingArea() ? getShape(s2).getCentroid() : getShape(s2)[-1];
515  Position p2 = connected->getEdge().isWalkingArea() ? connected->getShape(s2).getCentroid() : connected->getShape(s2)[0];
516  if (exaggeration > 1) {
517  p1 = centroid + ((p1 - centroid) * exaggeration);
518  p2 = centroid + ((p2 - centroid) * exaggeration);
519  }
520  glVertex2d(p1.x(), p1.y());
521  glVertex2d(p2.x(), p2.y());
522  glEnd();
523  GLHelper::drawTriangleAtEnd(p1, p2, (double) .4, (double) .2);
524  }
525 }
526 
527 
528 void
532  const bool s2 = s.secondaryShape;
533  const bool isCrossing = myEdge->isCrossing();
534  const bool isWalkingArea = myEdge->isWalkingArea();
535  const bool isInternal = isCrossing || isWalkingArea || myEdge->isInternal();
536  bool mustDrawMarkings = false;
537  double exaggeration = s.laneWidthExaggeration;
539  GUIEdge* myGUIEdge = dynamic_cast<GUIEdge*>(myEdge);
540  exaggeration *= s.edgeScaler.getScheme().getColor(myGUIEdge->getScaleValue(s, s.edgeScaler.getActive()));
541  } else {
542  exaggeration *= s.laneScaler.getScheme().getColor(getScaleValue(s, s.laneScaler.getActive(), s2));
543  }
544  const bool hasRailSignal = myEdge->getToJunction()->getType() == SumoXMLNodeType::RAIL_SIGNAL;
545  const bool detailZoom = s.scale * exaggeration > 5;
546  const bool drawDetails = (detailZoom || s.junctionSize.minSize == 0 || hasRailSignal);
547  const bool drawRails = drawAsRailway(s);
548  const PositionVector& baseShape = getShape(s2);
549  if (s.trueZ) {
550  glTranslated(0, 0, baseShape.getMinZ());
551  } else {
552  if (isCrossing) {
553  // draw internal lanes on top of junctions
554  glTranslated(0, 0, GLO_JUNCTION + 0.1);
555  } else if (isWalkingArea) {
556  // draw internal lanes on top of junctions
557  glTranslated(0, 0, GLO_JUNCTION + 0.3);
558  } else if (isWaterway(myPermissions)) {
559  // draw waterways below normal roads
560  glTranslated(0, 0, getType() - 0.2);
561  } else if (myPermissions == SVC_SUBWAY) {
562  // draw subways further below
563  glTranslated(0, 0, getType() - 0.4);
564  } else {
565  glTranslated(0, 0, getType());
566  }
567  }
568  // set lane color
569  const RGBColor color = setColor(s);
570  auto& shapeColors = getShapeColors(s2);
572  shapeColors.clear();
573  const std::vector<RGBColor>& segmentColors = static_cast<const GUIEdge*>(myEdge)->getSegmentColors();
574  if (segmentColors.size() > 0) {
575  // apply segment specific shape colors
576  //std::cout << getID() << " shape=" << myShape << " shapeSegs=" << toString(myShapeSegments) << "\n";
577  for (int ii = 0; ii < (int)baseShape.size() - 1; ++ii) {
578  shapeColors.push_back(segmentColors[myShapeSegments[ii]]);
579  }
580  }
581  }
582  // recognize full transparency and simply don't draw
583  bool hiddenBidi = getBidiLane() != nullptr && myEdge->getNumericalID() > myEdge->getBidiEdge()->getNumericalID();
584  if (color.alpha() != 0 && s.scale * exaggeration > s.laneMinSize) {
585  // scale tls-controlled lane2lane-arrows along with their junction shapes
586  double junctionExaggeration = 1;
587  if (!isInternal
590  junctionExaggeration = MAX2(1.001, s.junctionSize.getExaggeration(s, this, 4));
591  }
592  // draw lane
593  // check whether it is not too small
594  if (s.scale * exaggeration < 1. && junctionExaggeration == 1 && s.junctionSize.minSize != 0) {
595  if (!isInternal || hasRailSignal) {
596  if (shapeColors.size() > 0) {
597  GLHelper::drawLine(baseShape, shapeColors);
598  } else {
599  GLHelper::drawLine(baseShape);
600  }
601  }
603  } else {
604  GUINet* net = (GUINet*) MSNet::getInstance();
605  const bool spreadSuperposed = s.spreadSuperposed && myBidiLane != nullptr;
606  if (hiddenBidi && !spreadSuperposed) {
607  // do not draw shape
608  mustDrawMarkings = !isInternal && myPermissions != 0 && myPermissions != SVC_PEDESTRIAN && exaggeration == 1.0 && !isWaterway(myPermissions) && neighLaneNotBidi();
609  } else if (drawRails) {
610  // draw as railway: assume standard gauge of 1435mm when lane width is not set
611  // draw foot width 150mm, assume that distance between rail feet inner sides is reduced on both sides by 39mm with regard to the gauge
612  // assume crosstie length of 181% gauge (2600mm for standard gauge)
613  PositionVector shape = baseShape;
614  const double width = myWidth;
615  double halfGauge = 0.5 * (width == SUMO_const_laneWidth ? 1.4350 : width) * exaggeration;
616  if (spreadSuperposed) {
617  try {
618  shape.move2side(halfGauge * 0.8);
619  } catch (InvalidArgument&) {}
620  halfGauge *= 0.4;
621  }
622  const double halfInnerFeetWidth = halfGauge - 0.039 * exaggeration;
623  const double halfRailWidth = detailZoom ? (halfInnerFeetWidth + 0.15 * exaggeration) : SUMO_const_halfLaneWidth * exaggeration;
624  const double halfCrossTieWidth = halfGauge * 1.81;
625  if (shapeColors.size() > 0) {
626  GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), getShapeColors(s2), halfRailWidth);
627  } else {
628  GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), halfRailWidth);
629  }
630  // Draw white on top with reduced width (the area between the two tracks)
631  if (detailZoom) {
632  glColor3d(1, 1, 1);
633  glTranslated(0, 0, .1);
634  GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), halfInnerFeetWidth);
635  setColor(s);
636  GLHelper::drawCrossTies(shape, getShapeRotations(s2), getShapeLengths(s2), 0.26 * exaggeration, 0.6 * exaggeration,
637  halfCrossTieWidth, 0, s.forceDrawForRectangleSelection);
638  }
639  } else if (isCrossing) {
640  if (s.drawCrossingsAndWalkingareas && (s.scale > 3.0 || s.junctionSize.minSize == 0)) {
641  glTranslated(0, 0, .2);
642  GLHelper::drawCrossTies(baseShape, getShapeRotations(s2), getShapeLengths(s2), 0.5, 1.0, getWidth() * 0.5,
644 #ifdef GUILane_DEBUG_DRAW_CROSSING_OUTLINE
645  if (myOutlineShape != nullptr) {
647  glTranslated(0, 0, 0.4);
649  glTranslated(0, 0, -0.4);
650  if (s.geometryIndices.show(this)) {
652  }
653  }
654 #endif
655  glTranslated(0, 0, -.2);
656  }
657  } else if (isWalkingArea) {
658  if (s.drawCrossingsAndWalkingareas && (s.scale > 3.0 || s.junctionSize.minSize == 0)) {
659  glTranslated(0, 0, .2);
660  if (myTesselation == nullptr) {
661  myTesselation = new TesselatedPolygon(getID(), "", RGBColor::MAGENTA, PositionVector(), false, true, 0);
662  }
663  myTesselation->drawTesselation(baseShape);
664  glTranslated(0, 0, -.2);
665  if (s.geometryIndices.show(this)) {
667  }
668  }
669  } else {
670  // we draw the lanes with reduced width so that the lane markings below are visible
671  // (this avoids artifacts at geometry corners without having to
672  // compute lane-marking intersection points)
674  mustDrawMarkings = !isInternal && myPermissions != 0 && myPermissions != SVC_PEDESTRIAN && exaggeration == 1.0 && !isWaterway(myPermissions) && !isAirway(myPermissions);
675  const int cornerDetail = drawDetails && !isInternal ? (s.drawForRectangleSelection ? 8 : (int)(s.scale * exaggeration)) : 0;
676  double offset = halfWidth * MAX2(0., (exaggeration - 1)) * (MSGlobals::gLefthand ? -1 : 1);
677  if (spreadSuperposed) {
678  offset += halfWidth * 0.5 * (MSGlobals::gLefthand ? -1 : 1);
679  halfWidth *= 0.4; // create visible gap
680  }
681  if (shapeColors.size() > 0) {
682  GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), shapeColors, halfWidth * exaggeration, cornerDetail, offset);
683  } else {
684  GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), halfWidth * exaggeration, cornerDetail, offset);
685  }
686  }
687 #ifdef GUILane_DEBUG_DRAW_FOE_INTERSECTIONS
690  }
691 #endif
693  if (s.geometryIndices.show(this)) {
695  }
696  // draw details
697  if ((!isInternal || isCrossing || !s.drawJunctionShape) && (drawDetails || junctionExaggeration > 1)) {
699  glTranslated(0, 0, GLO_JUNCTION); // must draw on top of junction shape
700  glTranslated(0, 0, .5);
701  if (drawDetails) {
702  if (s.showLaneDirection) {
703  if (drawRails) {
704  // improve visibility of superposed rail edges
705  GLHelper::setColor(setColor(s).changedBrightness(100));
706  } else {
707  glColor3d(0.3, 0.3, 0.3);
708  }
710  drawDirectionIndicators(exaggeration, spreadSuperposed, s.secondaryShape);
711  }
712  }
713  if (!isInternal || isCrossing
714  // controlled internal junction
715  || (getLinkCont().size() != 0 && getLinkCont()[0]->isInternalJunctionLink() && getLinkCont()[0]->getTLLogic() != nullptr)) {
716  if (MSGlobals::gLateralResolution > 0 && s.showSublanes && !hiddenBidi && (myPermissions & ~(SVC_PEDESTRIAN | SVC_RAIL_CLASSES)) != 0) {
717  // draw sublane-borders
718  const double offsetSign = MSGlobals::gLefthand ? -1 : 1;
720  for (double offset = -myHalfLaneWidth; offset < myHalfLaneWidth; offset += MSGlobals::gLateralResolution) {
721  GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), 0.01, 0, -offset * offsetSign);
722  }
723  }
725  // draw segment borders
727  for (int i : mySegmentStartIndex) {
728  if (shapeColors.size() > 0) {
729  GLHelper::setColor(shapeColors[i].changedBrightness(51));
730  }
731  GLHelper::drawBoxLine(baseShape[i], getShapeRotations(s2)[i] + 90, myWidth / 3, 0.2, 0);
732  GLHelper::drawBoxLine(baseShape[i], getShapeRotations(s2)[i] - 90, myWidth / 3, 0.2, 0);
733  }
734  }
735  if (s.showLinkDecals && !drawRails && !drawAsWaterway(s) && myPermissions != SVC_PEDESTRIAN) {
737  }
738  glTranslated(0, 0, 1000);
739  if (s.drawLinkJunctionIndex.show(nullptr)) {
740  drawLinkNo(s);
741  }
742  if (s.drawLinkTLIndex.show(nullptr)) {
743  drawTLSLinkNo(s, *net);
744  }
745  glTranslated(0, 0, -1000);
746  }
747  glTranslated(0, 0, .1);
748  }
749  if ((drawDetails || junctionExaggeration > 1) && s.showLane2Lane) {
750  // draw from end of first to the begin of second but respect junction scaling
751  drawLane2LaneConnections(junctionExaggeration, s.secondaryShape);
752  }
754  // make sure link rules are drawn so tls can be selected via right-click
755  if (s.showLinkRules && drawDetails && !isWalkingArea &&
756  (!myEdge->isInternal() || (getLinkCont().size() > 0 && getLinkCont()[0]->isInternalJunctionLink()))) {
758  glTranslated(0, 0, GLO_SHAPE); // must draw on top of junction shape and additionals
759  drawLinkRules(s, *net);
761  }
762  }
763  }
764  if (mustDrawMarkings && drawDetails && s.laneShowBorders) { // needs matrix reset
765  drawMarkings(s, exaggeration);
766  }
767  if (drawDetails && isInternal && s.showBikeMarkings && myPermissions == SVC_BICYCLE && exaggeration == 1.0 && s.showLinkDecals && s.laneShowBorders && !hiddenBidi
771  }
772  if (drawDetails && isInternal && exaggeration == 1.0 && s.showLinkDecals && s.laneShowBorders && !hiddenBidi && myIndex > 0
773  && !(myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER) && allowsChangingRight(SVC_PASSENGER))) {
774  // draw lane changing prohibitions on junction
776  }
777  } else {
779  }
780  // draw vehicles
781  if (s.scale * s.vehicleSize.getExaggeration(s, nullptr) > s.vehicleSize.minSize) {
782  // retrieve vehicles from lane; disallow simulation
783  const MSLane::VehCont& vehicles = getVehiclesSecure();
784  for (MSLane::VehCont::const_iterator v = vehicles.begin(); v != vehicles.end(); ++v) {
785  if ((*v)->getLane() == this) {
786  static_cast<const GUIVehicle*>(*v)->drawGL(s);
787  } // else: this is the shadow during a continuous lane change
788  }
789  // draw long partial vehicles (#14342)
790  for (const MSVehicle* veh : myPartialVehicles) {
791  if (veh->getLength() > RENDERING_BUFFER) {
792  // potential double rendering taken into account
793  static_cast<const GUIVehicle*>(veh)->drawGL(s);
794  }
795  }
796  // draw parking vehicles
797  for (const MSBaseVehicle* const v : myParkingVehicles) {
798  dynamic_cast<const GUIBaseVehicle*>(v)->drawGL(s);
799  }
800  // allow lane simulation
801  releaseVehicles();
802  }
804 }
805 
806 bool
808  const MSLane* right = getParallelLane(-1, false);
809  if (right && right->getBidiLane() == nullptr) {
810  return true;
811  }
812  const MSLane* left = getParallelLane(1, false);
813  if (left && left->getBidiLane() == nullptr) {
814  return true;
815  }
816  return false;
817 }
818 
819 void
820 GUILane::drawMarkings(const GUIVisualizationSettings& s, double scale) const {
822  glTranslated(0, 0, GLO_EDGE);
823  setColor(s);
824  // optionally draw inverse markings
825  const bool s2 = s.secondaryShape;
826  if (myIndex > 0 && (myEdge->getLanes()[myIndex - 1]->getPermissions() & myPermissions) != 0) {
827  const bool cl = myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER);
828  const bool cr = allowsChangingRight(SVC_PASSENGER);
830  }
831  // draw white boundings and white markings
832  glColor3d(1, 1, 1);
834  getShape(s2),
835  getShapeRotations(s2),
836  getShapeLengths(s2),
839 }
840 
841 
842 void
844  // draw bike lane markings onto the intersection
845  glColor3d(1, 1, 1);
847  const bool s2 = false;
848  const int e = (int) getShape(s2).size() - 1;
849  const double markWidth = 0.1;
850  const double mw = myHalfLaneWidth;
851  for (int i = 0; i < e; ++i) {
853  glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), GLO_JUNCTION + 0.4);
854  glRotated(getShapeRotations(s2)[i], 0, 0, 1);
855  for (double t = 0; t < getShapeLengths(s2)[i]; t += 0.5) {
856  // left and right marking
857  for (int side = -1; side <= 1; side += 2) {
858  glBegin(GL_QUADS);
859  glVertex2d(side * mw, -t);
860  glVertex2d(side * mw, -t - 0.35);
861  glVertex2d(side * (mw + markWidth), -t - 0.35);
862  glVertex2d(side * (mw + markWidth), -t);
863  glEnd();
864  }
865  }
867  }
868 }
869 
870 
871 void
873  // fixme
874  const bool s2 = false;
875  // draw white markings
876  if (myIndex > 0 && (myEdge->getLanes()[myIndex - 1]->getPermissions() & myPermissions) != 0) {
877  glColor3d(1, 1, 1);
878  const bool cl = myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER);
879  const bool cr = allowsChangingRight(SVC_PASSENGER);
880  // solid line marking
881  double mw, mw2;
882  // optional broken line marking
883  double mw3, mw4;
884  if (!cl && !cr) {
885  // draw a single solid line
888  mw3 = myHalfLaneWidth;
889  mw4 = myHalfLaneWidth;
890  } else {
891  // draw one solid and one broken line
892  if (cl) {
897  } else {
902  }
903  }
904  if (MSGlobals::gLefthand) {
905  mw *= -1;
906  mw2 *= -1;
907  }
908  int e = (int) getShape(s2).size() - 1;
909  for (int i = 0; i < e; ++i) {
911  glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), GLO_JUNCTION + 0.4);
912  glRotated(getShapeRotations(s2)[i], 0, 0, 1);
913  for (double t = 0; t < getShapeLengths(s2)[i]; t += 6) {
914  const double lengthSolid = MIN2(6.0, getShapeLengths(s2)[i] - t);
915  glBegin(GL_QUADS);
916  glVertex2d(-mw, -t);
917  glVertex2d(-mw, -t - lengthSolid);
918  glVertex2d(-mw2, -t - lengthSolid);
919  glVertex2d(-mw2, -t);
920  glEnd();
921  if (cl || cr) {
922  const double lengthBroken = MIN2(3.0, getShapeLengths(s2)[i] - t);
923  glBegin(GL_QUADS);
924  glVertex2d(-mw3, -t);
925  glVertex2d(-mw3, -t - lengthBroken);
926  glVertex2d(-mw4, -t - lengthBroken);
927  glVertex2d(-mw4, -t);
928  glEnd();
929  }
930  }
932  }
933  }
934 }
935 
936 void
937 GUILane::drawDirectionIndicators(double exaggeration, bool spreadSuperposed, bool s2) const {
939  glTranslated(0, 0, GLO_EDGE);
940  int e = (int) getShape(s2).size() - 1;
941  const double widthFactor = spreadSuperposed ? 0.4 : 1;
942  const double w = MAX2(POSITION_EPS, myWidth * widthFactor);
943  const double w2 = MAX2(POSITION_EPS, myHalfLaneWidth * widthFactor);
944  const double w4 = MAX2(POSITION_EPS, myQuarterLaneWidth * widthFactor);
945  const double sideOffset = spreadSuperposed ? w * -0.5 : 0;
946  for (int i = 0; i < e; ++i) {
948  glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), 0.1);
949  glRotated(getShapeRotations(s2)[i], 0, 0, 1);
950  for (double t = 0; t < getShapeLengths(s2)[i]; t += w) {
951  const double length = MIN2(w2, getShapeLengths(s2)[i] - t) * exaggeration;
952  glBegin(GL_TRIANGLES);
953  glVertex2d(sideOffset, -t - length);
954  glVertex2d(sideOffset - w4 * exaggeration, -t);
955  glVertex2d(sideOffset + w4 * exaggeration, -t);
956  glEnd();
957  }
959  }
961 }
962 
963 
964 void
967  glColor3d(1.0, 0.3, 0.3);
968  const double orthoLength = 0.5;
969  const MSLink* link = getLinkCont().front();
970  const std::vector<const MSLane*>& foeLanes = link->getFoeLanes();
971  const auto& conflicts = link->getConflicts();
972  if (foeLanes.size() == conflicts.size()) {
973  for (int i = 0; i < (int)foeLanes.size(); ++i) {
974  const MSLane* l = foeLanes[i];
975  Position pos = l->geometryPositionAtOffset(l->getLength() - conflicts[i].lengthBehindCrossing);
976  PositionVector ortho = l->getShape().getOrthogonal(pos, 10, true, orthoLength);
977  if (ortho.length() < orthoLength) {
978  ortho.extrapolate(orthoLength - ortho.length(), false, true);
979  }
980  GLHelper::drawLine(ortho);
981  //std::cout << "foe=" << l->getID() << " lanePos=" << l->getLength() - lengthsBehind[i].second << " pos=" << pos << "\n";
982  }
983  }
985 }
986 
987 
988 // ------ inherited from GUIGlObject
991  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
992  buildPopupHeader(ret, app);
994  //
995  GUIDesigns::buildFXMenuCommand(ret, TL("Copy edge name to clipboard"), nullptr, ret, MID_COPY_EDGE_NAME);
998  //
999  buildShowParamsPopupEntry(ret, false);
1000  const PositionVector& baseShape = getShape(parent.getVisualisationSettings().secondaryShape);
1002  const double height = baseShape.positionAtOffset(pos).z();
1003  GUIDesigns::buildFXMenuCommand(ret, (TL("pos: ") + toString(pos) + " " + TL("height: ") + toString(height)).c_str(), nullptr, nullptr, 0);
1004  if (getEdge().hasDistance()) {
1005  GUIDesigns::buildFXMenuCommand(ret, ("distance: " + toString(getEdge().getDistanceAt(pos))).c_str(), nullptr, nullptr, 0);
1006  }
1007  new FXMenuSeparator(ret);
1008  buildPositionCopyEntry(ret, app);
1009  new FXMenuSeparator(ret);
1010  if (myAmClosed) {
1011  if (myPermissionChanges.empty()) {
1012  GUIDesigns::buildFXMenuCommand(ret, TL("Reopen lane"), nullptr, &parent, MID_CLOSE_LANE);
1013  GUIDesigns::buildFXMenuCommand(ret, TL("Reopen edge"), nullptr, &parent, MID_CLOSE_EDGE);
1014  } else {
1015  GUIDesigns::buildFXMenuCommand(ret, TL("Reopen lane (override rerouter)"), nullptr, &parent, MID_CLOSE_LANE);
1016  GUIDesigns::buildFXMenuCommand(ret, TL("Reopen edge (override rerouter)"), nullptr, &parent, MID_CLOSE_EDGE);
1017  }
1018  } else {
1019  GUIDesigns::buildFXMenuCommand(ret, TL("Close lane"), nullptr, &parent, MID_CLOSE_LANE);
1020  GUIDesigns::buildFXMenuCommand(ret, TL("Close edge"), nullptr, &parent, MID_CLOSE_EDGE);
1021  }
1022  GUIDesigns::buildFXMenuCommand(ret, TL("Add rerouter"), nullptr, &parent, MID_ADD_REROUTER);
1023  new FXMenuSeparator(ret);
1024  // reachability menu
1025  FXMenuPane* reachableByClass = new FXMenuPane(ret);
1026  ret->insertMenuPaneChild(reachableByClass);
1027  new FXMenuCascade(ret, TL("Select reachable"), GUIIconSubSys::getIcon(GUIIcon::FLAG), reachableByClass);
1028  for (auto i : SumoVehicleClassStrings.getStrings()) {
1030  }
1031  return ret;
1032 }
1033 
1034 
1038  GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
1039  // add items
1040  ret->mkItem(TL("allowed speed [m/s]"), false, getSpeedLimit());
1041  const std::map<SUMOVehicleClass, double>* restrictions = MSNet::getInstance()->getRestrictions(myEdge->getEdgeType());
1042  if (restrictions != nullptr) {
1043  for (const auto& elem : *restrictions) {
1044  ret->mkItem((std::string(" ") + TL("allowed speed [m/s]") + std::string(": ") + toString(elem.first)).c_str(), false, elem.second);
1045  }
1046  }
1047  ret->mkItem(TL("length [m]"), false, myLength);
1048  ret->mkItem(TL("width [m]"), false, myWidth);
1049  ret->mkItem(TL("street name"), false, myEdge->getStreetName());
1050  ret->mkItem(TL("stored travel time [s]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getStoredEdgeTravelTime));
1051  ret->mkItem(TL("loaded weight"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getLoadedEdgeWeight));
1052  ret->mkItem(TL("routing speed [m/s]"), true, new FunctionBinding<MSEdge, double>(myEdge, &MSEdge::getRoutingSpeed));
1053  ret->mkItem(TL("lane friction coefficient [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getFrictionCoefficient));
1054  ret->mkItem(TL("time penalty [s]"), true, new FunctionBinding<MSEdge, double>(myEdge, &MSEdge::getTimePenalty));
1055  ret->mkItem(TL("brutto occupancy [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getBruttoOccupancy, 100.));
1056  ret->mkItem(TL("netto occupancy [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getNettoOccupancy, 100.));
1057  ret->mkItem(TL("pending insertions [#]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getPendingEmits));
1058  ret->mkItem(TL("edge type"), false, myEdge->getEdgeType());
1059  ret->mkItem(TL("type"), false, myLaneType);
1060  ret->mkItem(TL("priority"), false, myEdge->getPriority());
1061  ret->mkItem(TL("distance [km]"), false, myEdge->getDistance() / 1000);
1062  ret->mkItem(TL("allowed vehicle class"), false, StringUtils::wrapText(getVehicleClassNames(myPermissions), 60));
1063  ret->mkItem(TL("disallowed vehicle class"), false, StringUtils::wrapText(getVehicleClassNames(~myPermissions), 60));
1064  ret->mkItem(TL("permission code"), false, myPermissions);
1065  ret->mkItem(TL("color value"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getColorValueForTracker));
1066  if (myBidiLane != nullptr) {
1067  ret->mkItem(TL("bidi-lane"), false, myBidiLane->getID());
1068  }
1069  for (const auto& kv : myEdge->getParametersMap()) {
1070  ret->mkItem(("edgeParam:" + kv.first).c_str(), false, kv.second);
1071  }
1072  ret->checkFont(myEdge->getStreetName());
1073  ret->closeBuilding();
1074  return ret;
1075 }
1076 
1077 
1078 Boundary
1080  Boundary b;
1081  b.add(myShape[0]);
1082  b.add(myShape[-1]);
1084  // ensure that vehicles and persons on the side are drawn even if the edge
1085  // is outside the view
1086  return b;
1087 }
1088 
1089 
1090 const PositionVector&
1091 GUILane::getShape(bool secondary) const {
1092  return secondary && myShape2.size() > 0 ? myShape2 : myShape;
1093 }
1094 
1095 
1096 const std::vector<double>&
1097 GUILane::getShapeRotations(bool secondary) const {
1098  return secondary && myShapeRotations2.size() > 0 ? myShapeRotations2 : myShapeRotations;
1099 }
1100 
1101 
1102 const std::vector<double>&
1103 GUILane::getShapeLengths(bool secondary) const {
1104  return secondary && myShapeLengths2.size() > 0 ? myShapeLengths2 : myShapeLengths;
1105 }
1106 
1107 
1108 std::vector<RGBColor>&
1109 GUILane::getShapeColors(bool secondary) const {
1110  return secondary && myShapeColors2.size() > 0 ? myShapeColors2 : myShapeColors;
1111 }
1112 
1113 
1114 double
1116  return myVehicles.size() == 0 ? 0 : myVehicles.back()->getWaitingSeconds();
1117 }
1118 
1119 
1120 double
1122  return (double) myEdge->getLanes().size();
1123 }
1124 
1125 
1126 double
1129  if (!ews.knowsTravelTime(myEdge)) {
1130  return -1;
1131  } else {
1132  double value(0);
1133  ews.retrieveExistingTravelTime(myEdge, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), value);
1134  return value;
1135  }
1136 }
1137 
1138 
1139 double
1142  if (!ews.knowsEffort(myEdge)) {
1143  return -1;
1144  } else {
1145  double value(-1);
1146  ews.retrieveExistingEffort(myEdge, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), value);
1147  return value;
1148  }
1149 }
1150 
1151 
1152 double
1154  switch (activeScheme) {
1155  case 18: {
1157  }
1158  default:
1159  return getColorValue(s, activeScheme);
1160  }
1161 
1162 }
1163 
1164 
1165 RGBColor
1167  // setting and retrieving the color does not work in OSGView so we return it explicitliy
1168  RGBColor col;
1169  if (MSGlobals::gUseMesoSim && static_cast<const GUIEdge*>(myEdge)->getMesoColor() != MESO_USE_LANE_COLOR) {
1170  col = static_cast<const GUIEdge*>(myEdge)->getMesoColor();
1171  } else {
1172  const GUIColorer& c = s.laneColorer;
1173  if (!setFunctionalColor(c, col) && !setMultiColor(s, c, col)) {
1174  col = c.getScheme().getColor(getColorValue(s, c.getActive()));
1175  }
1176  }
1177  GLHelper::setColor(col);
1178  return col;
1179 }
1180 
1181 
1182 bool
1183 GUILane::setFunctionalColor(const GUIColorer& c, RGBColor& col, int activeScheme) const {
1184  if (activeScheme < 0) {
1185  activeScheme = c.getActive();
1186  }
1187  switch (activeScheme) {
1188  case 0:
1189  if (myEdge->isCrossing()) {
1190  // determine priority to decide color
1191  const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
1192  if (link->havePriority() || link->getTLLogic() != nullptr) {
1193  col = RGBColor(230, 230, 230);
1194  } else {
1195  col = RGBColor(26, 26, 26);
1196  }
1197  GLHelper::setColor(col);
1198  return true;
1199  } else {
1200  return false;
1201  }
1202  case 18: {
1203  double hue = GeomHelper::naviDegree(myShape.beginEndAngle()); // [0-360]
1204  col = RGBColor::fromHSV(hue, 1., 1.);
1205  GLHelper::setColor(col);
1206  return true;
1207  }
1208  case 30: { // taz color
1209  col = c.getScheme().getColor(0);
1210  std::vector<RGBColor> tazColors;
1211  for (MSEdge* e : myEdge->getPredecessors()) {
1212  if (e->isTazConnector() && e->hasParameter("tazColor")) {
1213  tazColors.push_back(RGBColor::parseColor(e->getParameter("tazColor")));
1214  }
1215  }
1216  for (MSEdge* e : myEdge->getSuccessors()) {
1217  if (e->isTazConnector() && e->hasParameter("tazColor")) {
1218  tazColors.push_back(RGBColor::parseColor(e->getParameter("tazColor")));
1219  }
1220  }
1221  if (tazColors.size() > 0) {
1222  int randColor = RandHelper::rand((int)tazColors.size(), RGBColor::getColorRNG());
1223  col = tazColors[randColor];
1224  }
1225  GLHelper::setColor(col);
1226  return true;
1227  }
1228  default:
1229  return false;
1230  }
1231 }
1232 
1233 
1234 bool
1236  const int activeScheme = c.getActive();
1237  auto& shapeColors = getShapeColors(s.secondaryShape);
1238  const PositionVector& shape = getShape(s.secondaryShape);
1239  shapeColors.clear();
1240  switch (activeScheme) {
1241  case 22: // color by height at segment start
1242  for (PositionVector::const_iterator ii = shape.begin(); ii != shape.end() - 1; ++ii) {
1243  shapeColors.push_back(c.getScheme().getColor(ii->z()));
1244  }
1245  // osg fallback (edge height at start)
1246  col = c.getScheme().getColor(getColorValue(s, 21));
1247  return true;
1248  case 24: // color by inclination at segment start
1249  for (int ii = 1; ii < (int)shape.size(); ++ii) {
1250  const double inc = (shape[ii].z() - shape[ii - 1].z()) / MAX2(POSITION_EPS, shape[ii].distanceTo2D(shape[ii - 1]));
1251  shapeColors.push_back(c.getScheme().getColor(inc));
1252  }
1253  col = c.getScheme().getColor(getColorValue(s, 23));
1254  return true;
1255  default:
1256  return false;
1257  }
1258 }
1259 
1260 double
1262  if (myCachedGUISettings != nullptr) {
1264  const GUIColorer& c = s.laneColorer;
1265  return getColorValueWithFunctional(s, c.getActive());
1266  } else {
1267  return 0;
1268  }
1269 }
1270 
1271 
1272 double
1273 GUILane::getColorValue(const GUIVisualizationSettings& s, int activeScheme) const {
1274  switch (activeScheme) {
1275  case 0:
1276  switch (myPermissions) {
1277  case SVC_PEDESTRIAN:
1278  return 1;
1279  case SVC_BICYCLE:
1280  return 2;
1281  case 0:
1282  // forbidden road or green verge
1283  return myEdge->getPermissions() == 0 ? 10 : 3;
1284  case SVC_SHIP:
1285  return 4;
1286  case SVC_AUTHORITY:
1287  return 8;
1288  case SVC_AIRCRAFT:
1289  case SVC_DRONE:
1290  return 11;
1291  default:
1292  break;
1293  }
1294  if (myEdge->isTazConnector()) {
1295  return 9;
1296  } else if (isRailway(myPermissions)) {
1297  if ((myPermissions & SVC_BUS) != 0) {
1298  return 6;
1299  } else {
1300  return 5;
1301  }
1302  } else if ((myPermissions & SVC_PASSENGER) != 0) {
1303  if ((myPermissions & (SVC_RAIL_CLASSES & ~SVC_RAIL_FAST)) != 0 && (myPermissions & SVC_SHIP) == 0) {
1304  return 6;
1305  } else {
1306  return 0;
1307  }
1308  } else {
1309  return 7;
1310  }
1311  case 1:
1312  return isLaneOrEdgeSelected();
1313  case 2:
1314  return (double)myPermissions;
1315  case 3:
1316  return getSpeedLimit();
1317  case 4:
1318  return getBruttoOccupancy();
1319  case 5:
1320  return getNettoOccupancy();
1321  case 6:
1322  return firstWaitingTime();
1323  case 7:
1324  return getEdgeLaneNumber();
1325  case 8:
1326  return getEmissions<PollutantsInterface::CO2>() / myLength;
1327  case 9:
1328  return getEmissions<PollutantsInterface::CO>() / myLength;
1329  case 10:
1330  return getEmissions<PollutantsInterface::PM_X>() / myLength;
1331  case 11:
1332  return getEmissions<PollutantsInterface::NO_X>() / myLength;
1333  case 12:
1334  return getEmissions<PollutantsInterface::HC>() / myLength;
1335  case 13:
1336  return getEmissions<PollutantsInterface::FUEL>() / myLength;
1337  case 14:
1339  case 15: {
1340  return getStoredEdgeTravelTime();
1341  }
1342  case 16: {
1344  if (!ews.knowsTravelTime(myEdge)) {
1345  return -1;
1346  } else {
1347  double value(0);
1348  ews.retrieveExistingTravelTime(myEdge, 0, value);
1349  return 100 * myLength / value / getSpeedLimit();
1350  }
1351  }
1352  case 17: {
1353  // geometrical length has no meaning for walkingAreas since it describes the outer boundary
1355  }
1356  case 19: {
1357  return getLoadedEdgeWeight();
1358  }
1359  case 20: {
1360  return myEdge->getPriority();
1361  }
1362  case 21: {
1363  // color by z of first shape point
1364  return getShape(s.secondaryShape)[0].z();
1365  }
1366  case 23: {
1367  // color by incline
1368  return (getShape(s.secondaryShape)[-1].z() - getShape(s.secondaryShape)[0].z()) / getLength();
1369  }
1370  case 25: {
1371  // color by average speed
1372  return getMeanSpeed();
1373  }
1374  case 26: {
1375  // color by average relative speed
1376  return getMeanSpeed() / myMaxSpeed;
1377  }
1378  case 27: {
1379  // color by routing device assumed speed
1380  return myEdge->getRoutingSpeed();
1381  }
1382  case 28:
1383  return getEmissions<PollutantsInterface::ELEC>() / myLength;
1384  case 29:
1385  return getPendingEmits();
1386  case 31: {
1387  // by numerical edge param value
1388  if (myEdge->hasParameter(s.edgeParam)) {
1389  try {
1391  } catch (NumberFormatException&) {
1392  try {
1394  } catch (BoolFormatException&) {
1396  }
1397  }
1398  } else {
1400  }
1401  }
1402  case 32: {
1403  // by numerical lane param value
1404  if (hasParameter(s.laneParam)) {
1405  try {
1407  } catch (NumberFormatException&) {
1408  try {
1409  return StringUtils::toBool(getParameter(s.laneParam, "0"));
1410  } catch (BoolFormatException&) {
1412  }
1413  }
1414  } else {
1416  }
1417  }
1418  case 33: {
1419  // by edge data value
1421  }
1422  case 34: {
1423  return myEdge->getDistance();
1424  }
1425  case 35: {
1426  return fabs(myEdge->getDistance());
1427  }
1428  case 36: {
1429  return myReachability;
1430  }
1431  case 37: {
1433  }
1434  case 38: {
1435  if (myParkingAreas == nullptr) {
1436  // init
1437  myParkingAreas = new std::vector<MSParkingArea*>();
1438  for (auto& item : MSNet::getInstance()->getStoppingPlaces(SUMO_TAG_PARKING_AREA)) {
1439  if (&item.second->getLane().getEdge() == myEdge) {
1440  myParkingAreas->push_back(dynamic_cast<MSParkingArea*>(item.second));
1441  }
1442  }
1443  }
1444  int capacity = 0;
1445  for (MSParkingArea* pa : *myParkingAreas) {
1446  capacity += pa->getCapacity() - pa->getOccupancy();
1447  }
1448  return capacity;
1449  }
1450  case 39: {
1451  // by live edge data value
1452  return GUINet::getGUIInstance()->getMeanData(this, s.edgeDataID, s.edgeData);
1453  }
1454  }
1455  return 0;
1456 }
1457 
1458 
1459 double
1460 GUILane::getScaleValue(const GUIVisualizationSettings& s, int activeScheme, bool s2) const {
1461  switch (activeScheme) {
1462  case 0:
1463  return 0;
1464  case 1:
1465  return isLaneOrEdgeSelected();
1466  case 2:
1467  return getSpeedLimit();
1468  case 3:
1469  return getBruttoOccupancy();
1470  case 4:
1471  return getNettoOccupancy();
1472  case 5:
1473  return firstWaitingTime();
1474  case 6:
1475  return getEdgeLaneNumber();
1476  case 7:
1477  return getEmissions<PollutantsInterface::CO2>() / myLength;
1478  case 8:
1479  return getEmissions<PollutantsInterface::CO>() / myLength;
1480  case 9:
1481  return getEmissions<PollutantsInterface::PM_X>() / myLength;
1482  case 10:
1483  return getEmissions<PollutantsInterface::NO_X>() / myLength;
1484  case 11:
1485  return getEmissions<PollutantsInterface::HC>() / myLength;
1486  case 12:
1487  return getEmissions<PollutantsInterface::FUEL>() / myLength;
1488  case 13:
1490  case 14: {
1491  return getStoredEdgeTravelTime();
1492  }
1493  case 15: {
1495  if (!ews.knowsTravelTime(myEdge)) {
1496  return -1;
1497  } else {
1498  double value(0);
1499  ews.retrieveExistingTravelTime(myEdge, 0, value);
1500  return 100 * myLength / value / getSpeedLimit();
1501  }
1502  }
1503  case 16: {
1504  return 1 / getLengthGeometryFactor(s2);
1505  }
1506  case 17: {
1507  return getLoadedEdgeWeight();
1508  }
1509  case 18: {
1510  return myEdge->getPriority();
1511  }
1512  case 19: {
1513  // scale by average speed
1514  return getMeanSpeed();
1515  }
1516  case 20: {
1517  // scale by average relative speed
1518  return getMeanSpeed() / myMaxSpeed;
1519  }
1520  case 21:
1521  return getEmissions<PollutantsInterface::ELEC>() / myLength;
1522  case 22:
1524  case 23:
1525  // by edge data value
1527  }
1528  return 0;
1529 }
1530 
1531 
1532 bool
1534  return isRailway(myPermissions) && ((myPermissions & SVC_BUS) == 0) && s.showRails;
1535 }
1536 
1537 
1538 bool
1540  return isWaterway(myPermissions) && s.showRails; // reusing the showRails setting
1541 }
1542 
1543 
1544 #ifdef HAVE_OSG
1545 void
1546 GUILane::updateColor(const GUIVisualizationSettings& s) {
1547  if (myGeom == 0) {
1548  // not drawn
1549  return;
1550  }
1551  const RGBColor col = setColor(s);
1552  osg::Vec4ubArray* colors = dynamic_cast<osg::Vec4ubArray*>(myGeom->getColorArray());
1553  (*colors)[0].set(col.red(), col.green(), col.blue(), col.alpha());
1554  myGeom->setColorArray(colors);
1555 }
1556 #endif
1557 
1558 
1559 void
1560 GUILane::closeTraffic(bool rebuildAllowed) {
1561  MSGlobals::gCheckRoutes = false;
1562  if (myAmClosed) {
1563  myPermissionChanges.clear(); // reset rerouters
1565  } else {
1567  }
1569  if (rebuildAllowed) {
1571  }
1572 }
1573 
1574 
1577  assert(MSGlobals::gUseMesoSim);
1578  int no = MELoop::numSegmentsFor(myLength, OptionsCont::getOptions().getFloat("meso-edgelength"));
1579  const double slength = myLength / no;
1580  PositionVector result = shape;
1581  double offset = 0;
1582  for (int i = 0; i < no; ++i) {
1583  offset += slength;
1584  Position pos = shape.positionAtOffset(offset);
1585  int index = result.indexOfClosest(pos);
1586  if (pos.distanceTo(result[index]) > POSITION_EPS) {
1587  index = result.insertAtClosest(pos, false);
1588  }
1589  if (i != no - 1) {
1590  mySegmentStartIndex.push_back(index);
1591  }
1592  while ((int)myShapeSegments.size() < index) {
1593  myShapeSegments.push_back(i);
1594  }
1595  //std::cout << "splitAtSegments " << getID() << " no=" << no << " i=" << i << " offset=" << offset << " index=" << index << " segs=" << toString(myShapeSegments) << " resultSize=" << result.size() << " result=" << toString(result) << "\n";
1596  }
1597  while (myShapeSegments.size() < result.size()) {
1598  myShapeSegments.push_back(no - 1);
1599  }
1600  return result;
1601 }
1602 
1603 bool
1605  return gSelected.isSelected(GLO_LANE, getGlID());
1606 }
1607 
1608 bool
1610  return isSelected() || gSelected.isSelected(GLO_EDGE, dynamic_cast<GUIEdge*>(myEdge)->getGlID());
1611 }
1612 
1613 double
1616 }
1617 
1618 double
1620  if (MSGlobals::gUseMesoSim) {
1621  // do not select lanes in meso mode
1622  return INVALID_PRIORITY;
1623  }
1624  if (myEdge->isCrossing()) {
1625  return GLO_CROSSING;
1626  }
1627  return GLO_LANE;
1628 }
1629 
1630 
1631 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
@ MID_COPY_EDGE_NAME
Copy edge name (for lanes only)
Definition: GUIAppEnum.h:459
@ MID_REACHABILITY
show reachability from a given lane
Definition: GUIAppEnum.h:531
@ MID_CLOSE_LANE
close lane
Definition: GUIAppEnum.h:667
@ MID_CLOSE_EDGE
close edge
Definition: GUIAppEnum.h:669
@ MID_ADD_REROUTER
add rerouter
Definition: GUIAppEnum.h:671
@ GLO_JUNCTION
a junction
@ GLO_LANE
a lane
@ GLO_EDGE
an edge
@ GLO_SHAPE
reserved GLO type to pack shapes
@ GLO_CROSSING
a tl-logic
GUISelectedStorage gSelected
A global holder of selected objects.
GUIIcon
An enumeration of icons used by the gui applications.
Definition: GUIIcons.h:33
#define RENDERING_BUFFER
Definition: GUILane.cpp:62
#define RAD2DEG(x)
Definition: GeomHelper.h:36
#define TL(string)
Definition: MsgHandler.h:315
#define STEPS2TIME(x)
Definition: SUMOTime.h:55
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a railway edge.
bool isWaterway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a waterway edge.
bool isAirway(SVCPermissions permissions)
Returns whether an edge with the given permissions is an airway edge.
const std::string & getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a ' '.
StringBijection< SUMOVehicleClass > SumoVehicleClassStrings(sumoVehicleClassStringInitializer, SVC_CUSTOM2, false)
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ SVC_SHIP
is an arbitrary ship
@ SVC_RAIL_CLASSES
classes which drive on tracks
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_RAIL_FAST
vehicle that is allowed to drive on high-speed rail tracks
@ SVC_DRONE
@ SVC_AUTHORITY
authorities vehicles
@ SVC_BUS
vehicle is a bus
@ SVC_AIRCRAFT
@ SVC_SUBWAY
@ SVC_PEDESTRIAN
pedestrian
@ SUMO_TAG_PARKING_AREA
A parking area.
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)....
@ PARTLEFT
The link is a partial left direction.
@ RIGHT
The link is a (hard) right direction.
@ TURN
The link is a 180 degree turn.
@ LEFT
The link is a (hard) left direction.
@ STRAIGHT
The link is a straight direction.
@ TURN_LEFTHAND
The link is a 180 degree turn (left-hand network)
@ PARTRIGHT
The link is a partial right direction.
@ NODIR
The link has no direction (is a dead end link)
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
@ LINKSTATE_TL_REDYELLOW
The link has red light (must brake) but indicates upcoming green.
@ LINKSTATE_ALLWAY_STOP
This is an uncontrolled, all-way stop link.
@ LINKSTATE_MAJOR
This is an uncontrolled, major link, may pass.
@ LINKSTATE_STOP
This is an uncontrolled, minor link, has to stop.
@ LINKSTATE_TL_YELLOW_MAJOR
The link has yellow light, may pass.
@ LINKSTATE_TL_GREEN_MAJOR
The link has green light, may pass.
@ LINKSTATE_EQUAL
This is an uncontrolled, right-before-left link.
@ LINKSTATE_DEADEND
This is a dead end link.
@ LINKSTATE_TL_OFF_BLINKING
The link is controlled by a tls which is off and blinks, has to brake.
@ LINKSTATE_TL_YELLOW_MINOR
The link has yellow light, has to brake anyway.
@ LINKSTATE_TL_RED
The link has red light (must brake)
@ LINKSTATE_TL_GREEN_MINOR
The link has green light, has to brake.
@ LINKSTATE_MINOR
This is an uncontrolled, minor link, has to brake.
@ LINKSTATE_TL_OFF_NOSIGNAL
The link is controlled by a tls which is off, not blinking, may pass.
const double SUMO_const_laneWidth
Definition: StdDefs.h:48
T MIN2(T a, T b)
Definition: StdDefs.h:76
const double SUMO_const_laneMarkWidth
Definition: StdDefs.h:51
T MAX2(T a, T b)
Definition: StdDefs.h:82
const double SUMO_const_halfLaneWidth
Definition: StdDefs.h:49
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:78
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:319
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition: GLHelper.cpp:438
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:654
static void drawTriangleAtEnd(const Position &p1, const Position &p2, double tLength, double tWidth, const double extraOffset=0)
Draws a triangle at the end of the given line.
Definition: GLHelper.cpp:629
static void drawTextAtEnd(const std::string &text, const PositionVector &shape, double x, const GUIVisualizationTextSettings &settings, const double scale)
draw text and the end of shape
Definition: GLHelper.cpp:838
static void pushName(unsigned int name)
push Name
Definition: GLHelper.cpp:139
static void popMatrix()
pop matrix
Definition: GLHelper.cpp:130
static void drawBoxLines(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double width, int cornerDetail=0, double offset=0)
Draws thick lines.
Definition: GLHelper.cpp:347
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:295
static void debugVertices(const PositionVector &shape, const GUIVisualizationTextSettings &settings, double scale, double layer=1024)
draw vertex numbers for the given shape (in a random color)
Definition: GLHelper.cpp:953
static void popName()
pop Name
Definition: GLHelper.cpp:148
static void pushMatrix()
push matrix
Definition: GLHelper.cpp:117
static void drawInverseMarkings(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double maxLength, double spacing, double halfWidth, bool cl, bool cr, bool lefthand, double scale)
@bried draw the space between markings (in road color)
Definition: GLHelper.cpp:900
static void drawCrossTies(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double length, double spacing, double halfWidth, double offset, bool lessDetail)
draw crossties for railroads or pedestrian crossings
Definition: GLHelper.cpp:857
A MSVehicle extended by some values for usage within the gui.
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
static FXMenuCommand * buildFXMenuCommand(FXComposite *p, const std::string &text, FXIcon *icon, FXObject *tgt, FXSelector sel, const bool disable=false)
build menu command
Definition: GUIDesigns.cpp:42
A road/street connecting two junctions (gui-version)
Definition: GUIEdge.h:51
double getScaleValue(const GUIVisualizationSettings &s, int activeScheme) const
gets the scaling value according to the current scheme index
Definition: GUIEdge.cpp:580
The popup menu of a globject.
void insertMenuPaneChild(FXMenuPane *child)
Insert a sub-menu pane in this GUIGLObjectPopupMenu.
static const double INVALID_PRIORITY
Definition: GUIGlObject.h:73
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
Definition: GUIGlObject.h:156
void buildSelectionPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to (de)select the object.
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, const GUIMainWindow &app) const
Builds an entry which allows to copy the cursor position if geo projection is used,...
GUIGlID getGlID() const
Returns the numerical id of the object.
Definition: GUIGlObject.h:104
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
Representation of a lane in the micro simulation (gui-version)
Definition: GUILane.h:60
bool drawAsWaterway(const GUIVisualizationSettings &s) const
whether to draw this lane as a waterway
Definition: GUILane.cpp:1539
void debugDrawFoeIntersections() const
draw intersection positions of foe internal lanes with this one
Definition: GUILane.cpp:965
std::vector< double > myShapeLengths
The lengths of the shape parts.
Definition: GUILane.h:355
std::vector< MSParkingArea * > * myParkingAreas
list of parkingAreas on this lane
Definition: GUILane.h:377
const VehCont & getVehiclesSecure() const override
Returns the vehicles container; locks it for microsimulation.
Definition: GUILane.cpp:158
FXMutex myLock
The mutex used to avoid concurrent updates of the vehicle buffer.
Definition: GUILane.h:398
bool isLaneOrEdgeSelected() const
whether this lane or its parent edge is selected in the GUI
Definition: GUILane.cpp:1609
void initRotations(const PositionVector &shape, std::vector< double > &rotations, std::vector< double > &lengths, std::vector< RGBColor > &colors)
Definition: GUILane.cpp:118
double myHalfLaneWidth
Half of lane width, for speed-up.
Definition: GUILane.h:368
PositionVector splitAtSegments(const PositionVector &shape)
add intermediate points at segment borders
Definition: GUILane.cpp:1576
std::vector< int > myShapeSegments
the meso segment index for each geometry segment
Definition: GUILane.h:363
double firstWaitingTime() const
Definition: GUILane.cpp:1115
double setPartialOccupation(MSVehicle *v) override
Sets the information about a vehicle lapping into this lane.
Definition: GUILane.cpp:226
double myQuarterLaneWidth
Quarter of lane width, for speed-up.
Definition: GUILane.h:371
void drawTLSLinkNo(const GUIVisualizationSettings &s, const GUINet &net) const
Definition: GUILane.cpp:268
RGBColor setColor(const GUIVisualizationSettings &s) const
sets the color according to the currente settings
Definition: GUILane.cpp:1166
double getPendingEmits() const
get number of vehicles waiting for departure on this lane
Definition: GUILane.cpp:1614
void drawLinkNo(const GUIVisualizationSettings &s) const
helper methods
Definition: GUILane.cpp:241
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own popup-menu.
Definition: GUILane.cpp:990
static GUIVisualizationSettings * myCachedGUISettings
cached for tracking color value
Definition: GUILane.h:394
void drawJunctionChangeProhibitions() const
bike lane markings on top of an intersection
Definition: GUILane.cpp:872
static const RGBColor MESO_USE_LANE_COLOR
special color to signify alternative coloring scheme
Definition: GUILane.h:401
std::vector< double > myShapeLengths2
Definition: GUILane.h:356
MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify) override
Definition: GUILane.cpp:191
bool setMultiColor(const GUIVisualizationSettings &s, const GUIColorer &c, RGBColor &col) const
sets multiple colors according to the current scheme index and some lane function
Definition: GUILane.cpp:1235
void addSecondaryShape(const PositionVector &shape) override
Definition: GUILane.cpp:139
double getScaleValue(const GUIVisualizationSettings &s, int activeScheme, bool s2) const
gets the scaling value according to the current scheme index
Definition: GUILane.cpp:1460
void resetPartialOccupation(MSVehicle *v) override
Removes the information about a vehicle lapping into this lane.
Definition: GUILane.cpp:233
void integrateNewVehicles() override
Definition: GUILane.cpp:212
void drawGL(const GUIVisualizationSettings &s) const override
Draws the object.
Definition: GUILane.cpp:529
void drawArrows(bool secondaryShape) const
Definition: GUILane.cpp:435
std::vector< int > mySegmentStartIndex
the shape indices where the meso segment changes (for segmentsIndex > 0)
Definition: GUILane.h:365
void drawLinkRules(const GUIVisualizationSettings &s, const GUINet &net) const
Definition: GUILane.cpp:307
std::vector< RGBColor > myShapeColors
The color of the shape parts (cached)
Definition: GUILane.h:359
bool neighLaneNotBidi() const
whether any of the neighboring lanes is not a bidi-lane
Definition: GUILane.cpp:807
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const override
gets the color value according to the current scheme index
Definition: GUILane.cpp:1273
void closeTraffic(bool rebuildAllowed=true)
close this lane for traffic
Definition: GUILane.cpp:1560
double getClickPriority() const override
Returns the priority of receiving mouse clicks.
Definition: GUILane.cpp:1619
bool isSelected() const override
whether this lane is selected in the GUI
Definition: GUILane.cpp:1604
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own parameter window.
Definition: GUILane.cpp:1036
const std::vector< double > & getShapeRotations(bool secondary) const
Definition: GUILane.cpp:1097
double getColorValueWithFunctional(const GUIVisualizationSettings &s, int activeScheme) const
gets the color value according to the current scheme index including values for things that set the c...
Definition: GUILane.cpp:1153
bool drawAsRailway(const GUIVisualizationSettings &s) const
whether to draw this lane as a railway
Definition: GUILane.cpp:1533
GUILane(const std::string &id, double maxSpeed, double friction, double length, MSEdge *const edge, int numericalID, const PositionVector &shape, double width, SVCPermissions permissions, SVCPermissions changeLeft, SVCPermissions changeRight, int index, bool isRampAccel, const std::string &type, const PositionVector &outlineShape)
Constructor.
Definition: GUILane.cpp:77
void removeParking(MSBaseVehicle *veh) override
remove parking vehicle
Definition: GUILane.cpp:198
std::vector< double > myShapeRotations2
Definition: GUILane.h:352
double myLengthGeometryFactor2
Definition: GUILane.h:391
void planMovements(const SUMOTime t) override
Definition: GUILane.cpp:171
double getColorValueForTracker() const
return color value based on cached settings
Definition: GUILane.cpp:1261
std::vector< RGBColor > myShapeColors2
Definition: GUILane.h:360
double getEdgeLaneNumber() const
Definition: GUILane.cpp:1121
double myReachability
the time distance from a particular edge
Definition: GUILane.h:374
double getLoadedEdgeWeight() const
Returns the loaded weight (effort) for the edge of this lane.
Definition: GUILane.cpp:1140
std::vector< double > myShapeRotations
The rotations of the shape parts.
Definition: GUILane.h:351
TesselatedPolygon * myTesselation
An object that stores the tesselation.
Definition: GUILane.h:380
void setJunctionApproaches(const SUMOTime t) const override
Definition: GUILane.cpp:177
void incorporateVehicle(MSVehicle *veh, double pos, double speed, double posLat, const MSLane::VehCont::iterator &at, MSMoveReminder::Notification notification=MSMoveReminder::NOTIFICATION_DEPARTED) override
Inserts the vehicle into this lane, and informs it about entering the network.
Definition: GUILane.cpp:148
~GUILane()
Destructor.
Definition: GUILane.cpp:107
const PositionVector & getShape(bool secondary) const override
Definition: GUILane.cpp:1091
void drawLinkRule(const GUIVisualizationSettings &s, const GUINet &net, const MSLink *link, const PositionVector &shape, double x1, double x2) const
Definition: GUILane.cpp:362
Boundary getCenteringBoundary() const override
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GUILane.cpp:1079
std::vector< RGBColor > & getShapeColors(bool secondary) const
Definition: GUILane.cpp:1109
bool setFunctionalColor(const GUIColorer &c, RGBColor &col, int activeScheme=-1) const
Definition: GUILane.cpp:1183
double getStoredEdgeTravelTime() const
Returns the stored traveltime for the edge of this lane.
Definition: GUILane.cpp:1127
const std::vector< double > & getShapeLengths(bool secondary) const
Definition: GUILane.cpp:1103
void drawMarkings(const GUIVisualizationSettings &s, double scale) const
draw lane borders and white markings
Definition: GUILane.cpp:820
void drawBikeMarkings() const
bike lane markings on top of an intersection
Definition: GUILane.cpp:843
void executeMovements(const SUMOTime t) override
Definition: GUILane.cpp:184
PositionVector myShape2
secondary shape for visualization
Definition: GUILane.h:390
bool myAmClosed
state for dynamic lane closings
Definition: GUILane.h:387
void drawLane2LaneConnections(double exaggeration, bool s2) const
Definition: GUILane.cpp:502
void releaseVehicles() const override
Allows to use the container for microsimulation again.
Definition: GUILane.cpp:165
void drawDirectionIndicators(double exaggeration, bool spreadSuperposed, bool s2) const
direction indicators for lanes
Definition: GUILane.cpp:937
void detectCollisions(SUMOTime timestep, const std::string &stage) override
Definition: GUILane.cpp:219
void swapAfterLaneChange(SUMOTime t) override
moves myTmpVehicles int myVehicles after a lane change procedure
Definition: GUILane.cpp:205
A MSNet extended by some values for usage within the gui.
Definition: GUINet.h:82
int getLinkTLID(const MSLink *const link) const
Definition: GUINet.cpp:198
double getMeanData(const MSLane *lane, const std::string &id, const std::string &attr)
retrieve live lane/edge weight for the given meanData id and attribute
Definition: GUINet.cpp:622
int getLinkTLIndex(const MSLink *const link) const
Definition: GUINet.cpp:213
static GUINet * getGUIInstance()
Returns the pointer to the unique instance of GUINet (singleton).
Definition: GUINet.cpp:572
double getEdgeData(const MSEdge *edge, const std::string &attr)
retrieve loaded edged weight for the given attribute and the current simulation time
Definition: GUINet.cpp:605
A window containing a gl-object's parameter.
void mkItem(const char *name, bool dynamic, ValueSource< T > *src)
Adds a row which obtains its value from a ValueSource.
void closeBuilding(const Parameterised *p=0)
Closes the building of the table.
void checkFont(const std::string &text)
ensure that the font covers the given text
T getColor(const double value) const
const GUIVisualizationSettings & getVisualisationSettings() const
get visualization settings (read only)
GUIVisualizationSettings * editVisualisationSettings() const
edit visualization settings (allow modify VisualizationSetings, use carefully)
virtual Position getPositionInformation() const
Returns the cursor's x/y position within the network.
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
A MSVehicle extended by some values for usage within the gui.
Definition: GUIVehicle.h:51
Stores the information about how to visualize structures.
GUIVisualizationSizeSettings vehicleSize
GUIVisualizationSizeSettings junctionSize
bool showBikeMarkings
Information whether bicycle lane marking shall be drawn.
std::string edgeDataID
id for coloring by live edgeData
GUIScaler laneScaler
The lane scaler.
bool drawForRectangleSelection
whether drawing is performed for the purpose of selecting objects using a rectangle
bool showLinkRules
Information whether link rules (colored bars) shall be drawn.
bool drawJunctionShape
whether the shape of the junction should be drawn
std::string edgeData
key for coloring by edgeData
GUIVisualizationTextSettings geometryIndices
bool realisticLinkRules
Information whether link rules (colored bars) shall be drawn with a realistic color scheme.
bool trueZ
drawl all objects according to their z data
GUIVisualizationTextSettings drawLinkJunctionIndex
bool showRails
Information whether rails shall be drawn.
double laneWidthExaggeration
The lane exaggeration (upscale thickness)
bool showLane2Lane
Information whether lane-to-lane arrows shall be drawn.
bool showSublanes
Whether to show sublane boundaries.
static const RGBColor & getLinkColor(const LinkState &ls, bool realistic=false)
map from LinkState to color constants
double scale
information about a lane's width (temporary, used for a single view)
bool forceDrawForRectangleSelection
flag to force draw for rectangle selection (see drawForRectangleSelection)
bool showLaneDirection
Whether to show direction indicators for lanes.
bool secondaryShape
whether secondary lane shape shall be drawn
GUIScaler edgeScaler
The mesoscopic edge scaler.
bool showLinkDecals
Information whether link textures (arrows) shall be drawn.
GUIColorer laneColorer
The lane colorer.
bool laneShowBorders
Information whether lane borders shall be drawn.
double laneMinSize
The minimum visual lane width for drawing.
GUIVisualizationTextSettings drawLinkTLIndex
bool drawCrossingsAndWalkingareas
whether crosings and walkingareas shall be drawn
bool spreadSuperposed
Whether to improve visualisation of superposed (rail) edges.
std::string edgeParam
key for coloring by edge parameter
std::string edgeDataScaling
key for scaling by edgeData
static double naviDegree(const double angle)
Definition: GeomHelper.cpp:191
static int numSegmentsFor(const double length, const double slength)
Compute number of segments per edge (best value stay close to the configured segment length)
Definition: MELoop.cpp:286
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:57
A road/street connecting two junctions.
Definition: MSEdge.h:77
bool isCrossing() const
return whether this edge is a pedestrian crossing
Definition: MSEdge.h:273
int getPriority() const
Returns the priority of the edge.
Definition: MSEdge.h:328
SVCPermissions getPermissions() const
Returns the combined permissions of all lanes of this edge.
Definition: MSEdge.h:634
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:409
const std::string & getStreetName() const
Returns the street name of the edge.
Definition: MSEdge.h:313
bool isWalkingArea() const
return whether this edge is walking area
Definition: MSEdge.h:287
void rebuildAllowedLanes(const bool onInit=false)
Definition: MSEdge.cpp:322
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
bool isTazConnector() const
Definition: MSEdge.h:291
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:268
int getNumericalID() const
Returns the numerical id of the edge.
Definition: MSEdge.h:306
double getTimePenalty() const
Definition: MSEdge.h:486
const std::string & getEdgeType() const
Returns the type of the edge.
Definition: MSEdge.h:319
const MSJunction * getToJunction() const
Definition: MSEdge.h:418
double getRoutingSpeed() const
Returns the averaged speed used by the routing device.
Definition: MSEdge.cpp:989
const MSEdge * getBidiEdge() const
return opposite superposable/congruent edge, if it exist and 0 else
Definition: MSEdge.h:282
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:1206
double getDistance() const
Returns the kilometrage/mileage encoding at the start of the edge (negative values encode descending ...
Definition: MSEdge.h:335
A storage for edge travel times and efforts.
bool retrieveExistingTravelTime(const MSEdge *const e, const double t, double &value) const
Returns a travel time for an edge and time if stored.
bool knowsTravelTime(const MSEdge *const e) const
Returns the information whether any travel time is known for the given edge.
bool knowsEffort(const MSEdge *const e) const
Returns the information whether any effort is known for the given edge.
bool retrieveExistingEffort(const MSEdge *const e, const double t, double &value) const
Returns an effort for an edge and time if stored.
static bool gUseMesoSim
Definition: MSGlobals.h:103
static bool gCheckRoutes
Definition: MSGlobals.h:88
static double gLateralResolution
Definition: MSGlobals.h:97
static int gNumSimThreads
how many threads to use for simulation
Definition: MSGlobals.h:143
static bool gLefthand
Whether lefthand-drive is being simulated.
Definition: MSGlobals.h:171
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:78
int getPendingEmits(const MSLane *lane)
return the number of pending emits for the given lane
const PositionVector & getShape() const
Returns this junction's shape.
Definition: MSJunction.h:91
SumoXMLNodeType getType() const
return the type of this Junction
Definition: MSJunction.h:133
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
SVCPermissions myPermissions
The vClass permissions for this lane.
Definition: MSLane.h:1511
virtual void setJunctionApproaches(const SUMOTime t) const
Register junction approaches for all vehicles after velocities have been planned.
Definition: MSLane.cpp:1544
std::set< const MSBaseVehicle * > myParkingVehicles
Definition: MSLane.h:1483
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.h:716
MSLane * getParallelLane(int offset, bool includeOpposite=true) const
Returns the lane with the given offset parallel to this one or 0 if it does not exist.
Definition: MSLane.cpp:2754
virtual void removeParking(MSBaseVehicle *veh)
remove parking vehicle. This must be syncrhonized when running with GUI
Definition: MSLane.cpp:3589
virtual void integrateNewVehicles()
Insert buffered vehicle into the real lane.
Definition: MSLane.cpp:2472
double myLength
Lane length [m].
Definition: MSLane.h:1486
double getNettoOccupancy() const
Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps)
Definition: MSLane.cpp:3311
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:2736
PositionVector myShape
The shape of the lane.
Definition: MSLane.h:1431
PositionVector * myOutlineShape
the outline of the lane (optional)
Definition: MSLane.h:1434
std::map< long long, SVCPermissions > myPermissionChanges
Definition: MSLane.h:1591
double getFrictionCoefficient() const
Returns the lane's friction coefficient.
Definition: MSLane.h:591
virtual void incorporateVehicle(MSVehicle *veh, double pos, double speed, double posLat, const MSLane::VehCont::iterator &at, MSMoveReminder::Notification notification=MSMoveReminder::NOTIFICATION_DEPARTED)
Inserts the vehicle into this lane, and informs it about entering the network.
Definition: MSLane.cpp:431
const MSLane * getNormalSuccessorLane() const
get normal lane following this internal lane, for normal lanes, the lane itself is returned
Definition: MSLane.cpp:3151
MSEdge *const myEdge
The lane's edge, for routing only.
Definition: MSLane.h:1497
bool allowsChangingRight(SUMOVehicleClass vclass) const
Returns whether the given vehicle class may change left from this lane.
Definition: MSLane.h:929
double myMaxSpeed
Lane-wide speed limit [m/s].
Definition: MSLane.h:1500
const MSLink * getLinkTo(const MSLane *const) const
returns the link to the given lane or nullptr, if it is not connected
Definition: MSLane.cpp:2649
virtual void planMovements(const SUMOTime t)
Compute safe velocities for all vehicles based on positions and speeds from the last time step....
Definition: MSLane.cpp:1504
VehCont myVehicles
The lane's vehicles. This container holds all vehicles that have their front (longitudinally) and the...
Definition: MSLane.h:1450
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition: MSLane.h:584
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:119
MSLane * myBidiLane
Definition: MSLane.h:1588
bool isWalkingArea() const
Definition: MSLane.cpp:2543
SVCPermissions getPermissions() const
Returns the vehicle class permissions for this lane.
Definition: MSLane.h:606
void resetPermissions(long long transientID)
Definition: MSLane.cpp:4431
const std::string myLaneType
the type of this lane
Definition: MSLane.h:1574
int myRNGIndex
Definition: MSLane.h:1594
double getLength() const
Returns the lane's length.
Definition: MSLane.h:598
virtual void swapAfterLaneChange(SUMOTime t)
moves myTmpVehicles int myVehicles after a lane change procedure
Definition: MSLane.cpp:2719
StopOffset myLaneStopOffset
Definition: MSLane.h:1494
virtual double setPartialOccupation(MSVehicle *v)
Sets the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:360
int getIndex() const
Returns the lane's index.
Definition: MSLane.h:634
void setPermissions(SVCPermissions permissions, long long transientID)
Sets the permissions to the given value. If a transientID is given, the permissions are recored as te...
Definition: MSLane.cpp:4419
const double myWidth
Lane width [m].
Definition: MSLane.h:1489
virtual void executeMovements(const SUMOTime t)
Executes planned vehicle movements with regards to right-of-way.
Definition: MSLane.cpp:2190
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:3116
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:3296
int myIndex
The lane index.
Definition: MSLane.h:1437
bool isCrossing() const
Definition: MSLane.cpp:2538
virtual void detectCollisions(SUMOTime timestep, const std::string &stage)
Check if vehicles are too close.
Definition: MSLane.cpp:1605
std::vector< MSLink * > myLinks
Definition: MSLane.h:1552
bool isInternal() const
Definition: MSLane.cpp:2526
static const long CHANGE_PERMISSIONS_GUI
Definition: MSLane.h:1358
VehCont myPartialVehicles
The lane's partial vehicles. This container holds all vehicles that are partially on this lane but wh...
Definition: MSLane.h:1462
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:756
const PositionVector & getShape() const
Returns this lane's shape.
Definition: MSLane.h:525
double interpolateGeometryPosToLanePos(double geometryPos) const
Definition: MSLane.h:558
virtual void resetPartialOccupation(MSVehicle *v)
Removes the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:379
double getHarmonoise_NoiseEmissions() const
Returns the sum of last step noise emissions.
Definition: MSLane.cpp:3385
MSLane * getBidiLane() const
retrieve bidirectional lane or nullptr
Definition: MSLane.cpp:4545
double getLengthGeometryFactor() const
return shape.length() / myLength
Definition: MSLane.h:530
const MSLane * getNormalPredecessorLane() const
get normal lane leading to this internal lane, for normal lanes, the lane itself is returned
Definition: MSLane.cpp:3141
double getWidth() const
Returns the lane's width.
Definition: MSLane.h:627
double getMeanSpeed() const
Returns the mean speed on this lane.
Definition: MSLane.cpp:3339
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition: MSLane.h:552
virtual const PositionVector & getShape(bool) const
Definition: MSLane.h:294
Notification
Definition of a vehicle state.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:184
const std::map< SUMOVehicleClass, double > * getRestrictions(const std::string &id) const
Returns the restrictions for an edge type If no restrictions are present, 0 is returned.
Definition: MSNet.cpp:353
MSEdgeWeightsStorage & getWeightsStorage()
Returns the net's internal edge travel times/efforts container.
Definition: MSNet.cpp:1205
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:431
A lane area vehicles can halt at.
Definition: MSParkingArea.h:60
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
const std::string & getID() const
Returns the id.
Definition: Named.h:74
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
bool hasParameter(const std::string &key) const
Returns whether the parameter is set.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:276
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimensions
Definition: Position.h:266
double x() const
Returns the x-position.
Definition: Position.h:55
double z() const
Returns the z-position.
Definition: Position.h:65
double y() const
Returns the y-position.
Definition: Position.h:60
A list of positions.
double beginEndAngle() const
returns the angle in radians of the line connecting the first and the last position
double getMinZ() const
return minimum z-coordinate
double length() const
Returns the length.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
PositionVector getOrthogonal(const Position &p, double extend, bool before, double length=1.0, double deg=90) const
return orthogonal through p (extending this vector if necessary)
int indexOfClosest(const Position &p, bool twoD=false) const
void move2side(double amount, double maxExtension=100)
move position vector to side using certain amount
void extrapolate(const double val, const bool onlyFirst=false, const bool onlyLast=false)
extrapolate position vector
Position getCentroid() const
Returns the centroid (closes the polygon if unclosed)
int insertAtClosest(const Position &p, bool interpolateZ)
inserts p between the two closest positions
double nearest_offset_to_point25D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D projected onto the 3D geometry
PositionVector reverse() const
reverse position vector
unsigned char red() const
Returns the red-amount of the color.
Definition: RGBColor.cpp:74
static const RGBColor BLUE
Definition: RGBColor.h:187
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition: RGBColor.cpp:92
static SumoRNG * getColorRNG()
get color RNG
Definition: RGBColor.cpp:194
static RGBColor parseColor(std::string coldef)
Parses a color information.
Definition: RGBColor.cpp:239
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.cpp:80
static RGBColor fromHSV(double h, double s, double v)
Converts the given hsv-triplet to rgb, inspired by http://alvyray.com/Papers/CG/hsv2rgb....
Definition: RGBColor.cpp:371
unsigned char blue() const
Returns the blue-amount of the color.
Definition: RGBColor.cpp:86
RGBColor changedBrightness(int change, int toChange=3) const
Returns a new color with altered brightness.
Definition: RGBColor.cpp:200
static const RGBColor MAGENTA
Definition: RGBColor.h:190
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.cpp:94
bool isDefined() const
check if stopOffset was defined
SVCPermissions getPermissions() const
get permissions
double getOffset() const
get offset
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static std::string wrapText(const std::string s, int width)
remove leading and trailing whitespace
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
void drawTesselation(const PositionVector &shape) const
perform the tesselation / drawing
Definition: GUIPolygon.cpp:117
static FXIcon * getVClassIcon(const SUMOVehicleClass vc)
returns icon associated to the given vClass
Definition: VClassIcons.cpp:35
static const RGBColor SUMO_color_DEADEND_SHOW
color for highlighthing deadends
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values
double exaggeration
The size exaggeration (upscale)
bool constantSize
whether the object shall be drawn with constant size regardless of zoom
double minSize
The minimum size to draw this object.
bool show(const GUIGlObject *o) const
whether to show the text