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  if (isCrossing) {
549  // draw internal lanes on top of junctions
550  glTranslated(0, 0, GLO_JUNCTION + 0.1);
551  } else if (isWalkingArea) {
552  // draw internal lanes on top of junctions
553  glTranslated(0, 0, GLO_JUNCTION + 0.3);
554  } else if (isWaterway(myPermissions)) {
555  // draw waterways below normal roads
556  glTranslated(0, 0, getType() - 0.2);
557  } else {
558  glTranslated(0, 0, getType());
559  }
560  // set lane color
561  const RGBColor color = setColor(s);
562  const PositionVector& baseShape = getShape(s2);
563  auto& shapeColors = getShapeColors(s2);
565  shapeColors.clear();
566  const std::vector<RGBColor>& segmentColors = static_cast<const GUIEdge*>(myEdge)->getSegmentColors();
567  if (segmentColors.size() > 0) {
568  // apply segment specific shape colors
569  //std::cout << getID() << " shape=" << myShape << " shapeSegs=" << toString(myShapeSegments) << "\n";
570  for (int ii = 0; ii < (int)baseShape.size() - 1; ++ii) {
571  shapeColors.push_back(segmentColors[myShapeSegments[ii]]);
572  }
573  }
574  }
575  // recognize full transparency and simply don't draw
576  bool hiddenBidi = getBidiLane() != nullptr && myEdge->getNumericalID() > myEdge->getBidiEdge()->getNumericalID();
577  if (color.alpha() != 0 && s.scale * exaggeration > s.laneMinSize) {
578  // scale tls-controlled lane2lane-arrows along with their junction shapes
579  double junctionExaggeration = 1;
580  if (!isInternal
583  junctionExaggeration = MAX2(1.001, s.junctionSize.getExaggeration(s, this, 4));
584  }
585  // draw lane
586  // check whether it is not too small
587  if (s.scale * exaggeration < 1. && junctionExaggeration == 1 && s.junctionSize.minSize != 0) {
588  if (!isInternal || hasRailSignal) {
589  if (shapeColors.size() > 0) {
590  GLHelper::drawLine(baseShape, shapeColors);
591  } else {
592  GLHelper::drawLine(baseShape);
593  }
594  }
596  } else {
597  GUINet* net = (GUINet*) MSNet::getInstance();
598  const bool spreadSuperposed = s.spreadSuperposed && myBidiLane != nullptr;
599  if (hiddenBidi && !spreadSuperposed) {
600  // do not draw shape
601  mustDrawMarkings = !isInternal && myPermissions != 0 && myPermissions != SVC_PEDESTRIAN && exaggeration == 1.0 && !isWaterway(myPermissions) && neighLaneNotBidi();
602  } else if (drawRails) {
603  // draw as railway: assume standard gauge of 1435mm when lane width is not set
604  // draw foot width 150mm, assume that distance between rail feet inner sides is reduced on both sides by 39mm with regard to the gauge
605  // assume crosstie length of 181% gauge (2600mm for standard gauge)
606  PositionVector shape = baseShape;
607  const double width = myWidth;
608  double halfGauge = 0.5 * (width == SUMO_const_laneWidth ? 1.4350 : width) * exaggeration;
609  if (spreadSuperposed) {
610  try {
611  shape.move2side(halfGauge * 0.8);
612  } catch (InvalidArgument&) {}
613  halfGauge *= 0.4;
614  }
615  const double halfInnerFeetWidth = halfGauge - 0.039 * exaggeration;
616  const double halfRailWidth = detailZoom ? (halfInnerFeetWidth + 0.15 * exaggeration) : SUMO_const_halfLaneWidth * exaggeration;
617  const double halfCrossTieWidth = halfGauge * 1.81;
618  if (shapeColors.size() > 0) {
619  GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), getShapeColors(s2), halfRailWidth);
620  } else {
621  GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), halfRailWidth);
622  }
623  // Draw white on top with reduced width (the area between the two tracks)
624  if (detailZoom) {
625  glColor3d(1, 1, 1);
626  glTranslated(0, 0, .1);
627  GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), halfInnerFeetWidth);
628  setColor(s);
629  GLHelper::drawCrossTies(shape, getShapeRotations(s2), getShapeLengths(s2), 0.26 * exaggeration, 0.6 * exaggeration,
630  halfCrossTieWidth, 0, s.forceDrawForRectangleSelection);
631  }
632  } else if (isCrossing) {
633  if (s.drawCrossingsAndWalkingareas && (s.scale > 3.0 || s.junctionSize.minSize == 0)) {
634  glTranslated(0, 0, .2);
635  GLHelper::drawCrossTies(baseShape, getShapeRotations(s2), getShapeLengths(s2), 0.5, 1.0, getWidth() * 0.5,
637 #ifdef GUILane_DEBUG_DRAW_CROSSING_OUTLINE
638  if (myOutlineShape != nullptr) {
640  glTranslated(0, 0, 0.4);
642  glTranslated(0, 0, -0.4);
643  if (s.geometryIndices.show(this)) {
645  }
646  }
647 #endif
648  glTranslated(0, 0, -.2);
649  }
650  } else if (isWalkingArea) {
651  if (s.drawCrossingsAndWalkingareas && (s.scale > 3.0 || s.junctionSize.minSize == 0)) {
652  glTranslated(0, 0, .2);
653  if (s.scale * exaggeration < 20.) {
654  GLHelper::drawFilledPoly(baseShape, true);
655  } else {
656  if (myTesselation == nullptr) {
657  myTesselation = new TesselatedPolygon(getID(), "", RGBColor::MAGENTA, PositionVector(), false, true, 0);
658  }
659  myTesselation->drawTesselation(baseShape);
660  }
661  glTranslated(0, 0, -.2);
662  if (s.geometryIndices.show(this)) {
664  }
665  }
666  } else {
667  // we draw the lanes with reduced width so that the lane markings below are visible
668  // (this avoids artifacts at geometry corners without having to
669  // compute lane-marking intersection points)
671  mustDrawMarkings = !isInternal && myPermissions != 0 && myPermissions != SVC_PEDESTRIAN && exaggeration == 1.0 && !isWaterway(myPermissions) && !isAirway(myPermissions);
672  const int cornerDetail = drawDetails && !isInternal ? (s.drawForRectangleSelection ? 8 : (int)(s.scale * exaggeration)) : 0;
673  double offset = halfWidth * MAX2(0., (exaggeration - 1)) * (MSGlobals::gLefthand ? -1 : 1);
674  if (spreadSuperposed) {
675  offset += halfWidth * 0.5 * (MSGlobals::gLefthand ? -1 : 1);
676  halfWidth *= 0.4; // create visible gap
677  }
678  if (shapeColors.size() > 0) {
679  GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), shapeColors, halfWidth * exaggeration, cornerDetail, offset);
680  } else {
681  GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), halfWidth * exaggeration, cornerDetail, offset);
682  }
683  }
684 #ifdef GUILane_DEBUG_DRAW_FOE_INTERSECTIONS
687  }
688 #endif
690  if (s.geometryIndices.show(this)) {
692  }
693  // draw details
694  if ((!isInternal || isCrossing || !s.drawJunctionShape) && (drawDetails || junctionExaggeration > 1)) {
696  glTranslated(0, 0, GLO_JUNCTION); // must draw on top of junction shape
697  glTranslated(0, 0, .5);
698  if (drawDetails) {
699  if (s.showLaneDirection) {
700  if (drawRails) {
701  // improve visibility of superposed rail edges
702  GLHelper::setColor(setColor(s).changedBrightness(100));
703  } else {
704  glColor3d(0.3, 0.3, 0.3);
705  }
707  drawDirectionIndicators(exaggeration, spreadSuperposed, s.secondaryShape);
708  }
709  }
710  if (!isInternal || isCrossing
711  // controlled internal junction
712  || (getLinkCont().size() != 0 && getLinkCont()[0]->isInternalJunctionLink() && getLinkCont()[0]->getTLLogic() != nullptr)) {
713  if (MSGlobals::gLateralResolution > 0 && s.showSublanes && !hiddenBidi && (myPermissions & ~(SVC_PEDESTRIAN | SVC_RAIL_CLASSES)) != 0) {
714  // draw sublane-borders
715  const double offsetSign = MSGlobals::gLefthand ? -1 : 1;
717  for (double offset = -myHalfLaneWidth; offset < myHalfLaneWidth; offset += MSGlobals::gLateralResolution) {
718  GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), 0.01, 0, -offset * offsetSign);
719  }
720  }
722  // draw segment borders
724  for (int i : mySegmentStartIndex) {
725  if (shapeColors.size() > 0) {
726  GLHelper::setColor(shapeColors[i].changedBrightness(51));
727  }
728  GLHelper::drawBoxLine(baseShape[i], getShapeRotations(s2)[i] + 90, myWidth / 3, 0.2, 0);
729  GLHelper::drawBoxLine(baseShape[i], getShapeRotations(s2)[i] - 90, myWidth / 3, 0.2, 0);
730  }
731  }
732  if (s.showLinkDecals && !drawRails && !drawAsWaterway(s) && myPermissions != SVC_PEDESTRIAN) {
734  }
735  glTranslated(0, 0, 1000);
736  if (s.drawLinkJunctionIndex.show(nullptr)) {
737  drawLinkNo(s);
738  }
739  if (s.drawLinkTLIndex.show(nullptr)) {
740  drawTLSLinkNo(s, *net);
741  }
742  glTranslated(0, 0, -1000);
743  }
744  glTranslated(0, 0, .1);
745  }
746  if ((drawDetails || junctionExaggeration > 1) && s.showLane2Lane) {
747  // draw from end of first to the begin of second but respect junction scaling
748  drawLane2LaneConnections(junctionExaggeration, s.secondaryShape);
749  }
751  // make sure link rules are drawn so tls can be selected via right-click
752  if (s.showLinkRules && drawDetails && !isWalkingArea &&
753  (!myEdge->isInternal() || (getLinkCont().size() > 0 && getLinkCont()[0]->isInternalJunctionLink()))) {
755  glTranslated(0, 0, GLO_SHAPE); // must draw on top of junction shape and additionals
756  drawLinkRules(s, *net);
758  }
759  }
760  }
761  if (mustDrawMarkings && drawDetails && s.laneShowBorders) { // needs matrix reset
762  drawMarkings(s, exaggeration);
763  }
764  if (drawDetails && isInternal && s.showBikeMarkings && myPermissions == SVC_BICYCLE && exaggeration == 1.0 && s.showLinkDecals && s.laneShowBorders && !hiddenBidi
768  }
769  if (drawDetails && isInternal && exaggeration == 1.0 && s.showLinkDecals && s.laneShowBorders && !hiddenBidi && myIndex > 0
770  && !(myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER) && allowsChangingRight(SVC_PASSENGER))) {
771  // draw lane changing prohibitions on junction
773  }
774  } else {
776  }
777  // draw vehicles
778  if (s.scale * s.vehicleSize.getExaggeration(s, nullptr) > s.vehicleSize.minSize) {
779  // retrieve vehicles from lane; disallow simulation
780  const MSLane::VehCont& vehicles = getVehiclesSecure();
781  for (MSLane::VehCont::const_iterator v = vehicles.begin(); v != vehicles.end(); ++v) {
782  if ((*v)->getLane() == this) {
783  static_cast<const GUIVehicle*>(*v)->drawGL(s);
784  } // else: this is the shadow during a continuous lane change
785  }
786  // draw long partial vehicles (#14342)
787  for (const MSVehicle* veh : myPartialVehicles) {
788  if (veh->getLength() > RENDERING_BUFFER) {
789  // potential double rendering taken into account
790  static_cast<const GUIVehicle*>(veh)->drawGL(s);
791  }
792  }
793  // draw parking vehicles
794  for (const MSBaseVehicle* const v : myParkingVehicles) {
795  dynamic_cast<const GUIBaseVehicle*>(v)->drawGL(s);
796  }
797  // allow lane simulation
798  releaseVehicles();
799  }
801 }
802 
803 bool
805  const MSLane* right = getParallelLane(-1, false);
806  if (right && right->getBidiLane() == nullptr) {
807  return true;
808  }
809  const MSLane* left = getParallelLane(1, false);
810  if (left && left->getBidiLane() == nullptr) {
811  return true;
812  }
813  return false;
814 }
815 
816 void
817 GUILane::drawMarkings(const GUIVisualizationSettings& s, double scale) const {
819  glTranslated(0, 0, GLO_EDGE);
820  setColor(s);
821  // optionally draw inverse markings
822  const bool s2 = s.secondaryShape;
823  if (myIndex > 0 && (myEdge->getLanes()[myIndex - 1]->getPermissions() & myPermissions) != 0) {
824  const bool cl = myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER);
825  const bool cr = allowsChangingRight(SVC_PASSENGER);
827  }
828  // draw white boundings and white markings
829  glColor3d(1, 1, 1);
831  getShape(s2),
832  getShapeRotations(s2),
833  getShapeLengths(s2),
836 }
837 
838 
839 void
841  // draw bike lane markings onto the intersection
842  glColor3d(1, 1, 1);
844  const bool s2 = false;
845  const int e = (int) getShape(s2).size() - 1;
846  const double markWidth = 0.1;
847  const double mw = myHalfLaneWidth;
848  for (int i = 0; i < e; ++i) {
850  glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), GLO_JUNCTION + 0.4);
851  glRotated(getShapeRotations(s2)[i], 0, 0, 1);
852  for (double t = 0; t < getShapeLengths(s2)[i]; t += 0.5) {
853  // left and right marking
854  for (int side = -1; side <= 1; side += 2) {
855  glBegin(GL_QUADS);
856  glVertex2d(side * mw, -t);
857  glVertex2d(side * mw, -t - 0.35);
858  glVertex2d(side * (mw + markWidth), -t - 0.35);
859  glVertex2d(side * (mw + markWidth), -t);
860  glEnd();
861  }
862  }
864  }
865 }
866 
867 
868 void
870  // fixme
871  const bool s2 = false;
872  // draw white markings
873  if (myIndex > 0 && (myEdge->getLanes()[myIndex - 1]->getPermissions() & myPermissions) != 0) {
874  glColor3d(1, 1, 1);
875  const bool cl = myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER);
876  const bool cr = allowsChangingRight(SVC_PASSENGER);
877  // solid line marking
878  double mw, mw2;
879  // optional broken line marking
880  double mw3, mw4;
881  if (!cl && !cr) {
882  // draw a single solid line
885  mw3 = myHalfLaneWidth;
886  mw4 = myHalfLaneWidth;
887  } else {
888  // draw one solid and one broken line
889  if (cl) {
894  } else {
899  }
900  }
901  if (MSGlobals::gLefthand) {
902  mw *= -1;
903  mw2 *= -1;
904  }
905  int e = (int) getShape(s2).size() - 1;
906  for (int i = 0; i < e; ++i) {
908  glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), GLO_JUNCTION + 0.4);
909  glRotated(getShapeRotations(s2)[i], 0, 0, 1);
910  for (double t = 0; t < getShapeLengths(s2)[i]; t += 6) {
911  const double lengthSolid = MIN2(6.0, getShapeLengths(s2)[i] - t);
912  glBegin(GL_QUADS);
913  glVertex2d(-mw, -t);
914  glVertex2d(-mw, -t - lengthSolid);
915  glVertex2d(-mw2, -t - lengthSolid);
916  glVertex2d(-mw2, -t);
917  glEnd();
918  if (cl || cr) {
919  const double lengthBroken = MIN2(3.0, getShapeLengths(s2)[i] - t);
920  glBegin(GL_QUADS);
921  glVertex2d(-mw3, -t);
922  glVertex2d(-mw3, -t - lengthBroken);
923  glVertex2d(-mw4, -t - lengthBroken);
924  glVertex2d(-mw4, -t);
925  glEnd();
926  }
927  }
929  }
930  }
931 }
932 
933 void
934 GUILane::drawDirectionIndicators(double exaggeration, bool spreadSuperposed, bool s2) const {
936  glTranslated(0, 0, GLO_EDGE);
937  int e = (int) getShape(s2).size() - 1;
938  const double widthFactor = spreadSuperposed ? 0.4 : 1;
939  const double w = MAX2(POSITION_EPS, myWidth * widthFactor);
940  const double w2 = MAX2(POSITION_EPS, myHalfLaneWidth * widthFactor);
941  const double w4 = MAX2(POSITION_EPS, myQuarterLaneWidth * widthFactor);
942  const double sideOffset = spreadSuperposed ? w * -0.5 : 0;
943  for (int i = 0; i < e; ++i) {
945  glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), 0.1);
946  glRotated(getShapeRotations(s2)[i], 0, 0, 1);
947  for (double t = 0; t < getShapeLengths(s2)[i]; t += w) {
948  const double length = MIN2(w2, getShapeLengths(s2)[i] - t) * exaggeration;
949  glBegin(GL_TRIANGLES);
950  glVertex2d(sideOffset, -t - length);
951  glVertex2d(sideOffset - w4 * exaggeration, -t);
952  glVertex2d(sideOffset + w4 * exaggeration, -t);
953  glEnd();
954  }
956  }
958 }
959 
960 
961 void
964  glColor3d(1.0, 0.3, 0.3);
965  const double orthoLength = 0.5;
966  const MSLink* link = getLinkCont().front();
967  const std::vector<const MSLane*>& foeLanes = link->getFoeLanes();
968  const auto& conflicts = link->getConflicts();
969  if (foeLanes.size() == conflicts.size()) {
970  for (int i = 0; i < (int)foeLanes.size(); ++i) {
971  const MSLane* l = foeLanes[i];
972  Position pos = l->geometryPositionAtOffset(l->getLength() - conflicts[i].lengthBehindCrossing);
973  PositionVector ortho = l->getShape().getOrthogonal(pos, 10, true, orthoLength);
974  if (ortho.length() < orthoLength) {
975  ortho.extrapolate(orthoLength - ortho.length(), false, true);
976  }
977  GLHelper::drawLine(ortho);
978  //std::cout << "foe=" << l->getID() << " lanePos=" << l->getLength() - lengthsBehind[i].second << " pos=" << pos << "\n";
979  }
980  }
982 }
983 
984 
985 // ------ inherited from GUIGlObject
988  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
989  buildPopupHeader(ret, app);
991  //
992  GUIDesigns::buildFXMenuCommand(ret, TL("Copy edge name to clipboard"), nullptr, ret, MID_COPY_EDGE_NAME);
995  //
996  buildShowParamsPopupEntry(ret, false);
997  const PositionVector& baseShape = getShape(parent.getVisualisationSettings().secondaryShape);
999  const double height = baseShape.positionAtOffset(pos).z();
1000  GUIDesigns::buildFXMenuCommand(ret, (TL("pos: ") + toString(pos) + " " + TL("height: ") + toString(height)).c_str(), nullptr, nullptr, 0);
1001  if (getEdge().hasDistance()) {
1002  GUIDesigns::buildFXMenuCommand(ret, ("distance: " + toString(getEdge().getDistanceAt(pos))).c_str(), nullptr, nullptr, 0);
1003  }
1004  new FXMenuSeparator(ret);
1005  buildPositionCopyEntry(ret, app);
1006  new FXMenuSeparator(ret);
1007  if (myAmClosed) {
1008  if (myPermissionChanges.empty()) {
1009  GUIDesigns::buildFXMenuCommand(ret, TL("Reopen lane"), nullptr, &parent, MID_CLOSE_LANE);
1010  GUIDesigns::buildFXMenuCommand(ret, TL("Reopen edge"), nullptr, &parent, MID_CLOSE_EDGE);
1011  } else {
1012  GUIDesigns::buildFXMenuCommand(ret, TL("Reopen lane (override rerouter)"), nullptr, &parent, MID_CLOSE_LANE);
1013  GUIDesigns::buildFXMenuCommand(ret, TL("Reopen edge (override rerouter)"), nullptr, &parent, MID_CLOSE_EDGE);
1014  }
1015  } else {
1016  GUIDesigns::buildFXMenuCommand(ret, TL("Close lane"), nullptr, &parent, MID_CLOSE_LANE);
1017  GUIDesigns::buildFXMenuCommand(ret, TL("Close edge"), nullptr, &parent, MID_CLOSE_EDGE);
1018  }
1019  GUIDesigns::buildFXMenuCommand(ret, TL("Add rerouter"), nullptr, &parent, MID_ADD_REROUTER);
1020  new FXMenuSeparator(ret);
1021  // reachability menu
1022  FXMenuPane* reachableByClass = new FXMenuPane(ret);
1023  ret->insertMenuPaneChild(reachableByClass);
1024  new FXMenuCascade(ret, TL("Select reachable"), GUIIconSubSys::getIcon(GUIIcon::FLAG), reachableByClass);
1025  for (auto i : SumoVehicleClassStrings.getStrings()) {
1027  }
1028  return ret;
1029 }
1030 
1031 
1035  GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
1036  // add items
1037  ret->mkItem(TL("allowed speed [m/s]"), false, getSpeedLimit());
1038  const std::map<SUMOVehicleClass, double>* restrictions = MSNet::getInstance()->getRestrictions(myEdge->getEdgeType());
1039  if (restrictions != nullptr) {
1040  for (const auto& elem : *restrictions) {
1041  ret->mkItem((std::string(" ") + TL("allowed speed [m/s]") + std::string(": ") + toString(elem.first)).c_str(), false, elem.second);
1042  }
1043  }
1044  ret->mkItem(TL("length [m]"), false, myLength);
1045  ret->mkItem(TL("width [m]"), false, myWidth);
1046  ret->mkItem(TL("street name"), false, myEdge->getStreetName());
1047  ret->mkItem(TL("stored travel time [s]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getStoredEdgeTravelTime));
1048  ret->mkItem(TL("loaded weight"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getLoadedEdgeWeight));
1049  ret->mkItem(TL("routing speed [m/s]"), true, new FunctionBinding<MSEdge, double>(myEdge, &MSEdge::getRoutingSpeed));
1050  ret->mkItem(TL("lane friction coefficient [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getFrictionCoefficient));
1051  ret->mkItem(TL("time penalty [s]"), true, new FunctionBinding<MSEdge, double>(myEdge, &MSEdge::getTimePenalty));
1052  ret->mkItem(TL("brutto occupancy [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getBruttoOccupancy, 100.));
1053  ret->mkItem(TL("netto occupancy [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getNettoOccupancy, 100.));
1054  ret->mkItem(TL("pending insertions [#]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getPendingEmits));
1055  ret->mkItem(TL("edge type"), false, myEdge->getEdgeType());
1056  ret->mkItem(TL("type"), false, myLaneType);
1057  ret->mkItem(TL("priority"), false, myEdge->getPriority());
1058  ret->mkItem(TL("distance [km]"), false, myEdge->getDistance() / 1000);
1059  ret->mkItem(TL("allowed vehicle class"), false, getVehicleClassNames(myPermissions));
1060  ret->mkItem(TL("disallowed vehicle class"), false, getVehicleClassNames(~myPermissions));
1061  ret->mkItem(TL("permission code"), false, myPermissions);
1062  ret->mkItem(TL("color value"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getColorValueForTracker));
1063  if (myBidiLane != nullptr) {
1064  ret->mkItem(TL("bidi-lane"), false, myBidiLane->getID());
1065  }
1066  for (const auto& kv : myEdge->getParametersMap()) {
1067  ret->mkItem(("edgeParam:" + kv.first).c_str(), false, kv.second);
1068  }
1069  ret->checkFont(myEdge->getStreetName());
1070  ret->closeBuilding();
1071  return ret;
1072 }
1073 
1074 
1075 Boundary
1077  Boundary b;
1078  b.add(myShape[0]);
1079  b.add(myShape[-1]);
1081  // ensure that vehicles and persons on the side are drawn even if the edge
1082  // is outside the view
1083  return b;
1084 }
1085 
1086 
1087 const PositionVector&
1088 GUILane::getShape(bool secondary) const {
1089  return secondary && myShape2.size() > 0 ? myShape2 : myShape;
1090 }
1091 
1092 
1093 const std::vector<double>&
1094 GUILane::getShapeRotations(bool secondary) const {
1095  return secondary && myShapeRotations2.size() > 0 ? myShapeRotations2 : myShapeRotations;
1096 }
1097 
1098 
1099 const std::vector<double>&
1100 GUILane::getShapeLengths(bool secondary) const {
1101  return secondary && myShapeLengths2.size() > 0 ? myShapeLengths2 : myShapeLengths;
1102 }
1103 
1104 
1105 std::vector<RGBColor>&
1106 GUILane::getShapeColors(bool secondary) const {
1107  return secondary && myShapeColors2.size() > 0 ? myShapeColors2 : myShapeColors;
1108 }
1109 
1110 
1111 double
1113  return myVehicles.size() == 0 ? 0 : myVehicles.back()->getWaitingSeconds();
1114 }
1115 
1116 
1117 double
1119  return (double) myEdge->getLanes().size();
1120 }
1121 
1122 
1123 double
1126  if (!ews.knowsTravelTime(myEdge)) {
1127  return -1;
1128  } else {
1129  double value(0);
1130  ews.retrieveExistingTravelTime(myEdge, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), value);
1131  return value;
1132  }
1133 }
1134 
1135 
1136 double
1139  if (!ews.knowsEffort(myEdge)) {
1140  return -1;
1141  } else {
1142  double value(-1);
1143  ews.retrieveExistingEffort(myEdge, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), value);
1144  return value;
1145  }
1146 }
1147 
1148 
1149 double
1151  switch (activeScheme) {
1152  case 18: {
1154  }
1155  default:
1156  return getColorValue(s, activeScheme);
1157  }
1158 
1159 }
1160 
1161 
1162 RGBColor
1164  // setting and retrieving the color does not work in OSGView so we return it explicitliy
1165  RGBColor col;
1166  if (MSGlobals::gUseMesoSim && static_cast<const GUIEdge*>(myEdge)->getMesoColor() != MESO_USE_LANE_COLOR) {
1167  col = static_cast<const GUIEdge*>(myEdge)->getMesoColor();
1168  } else {
1169  const GUIColorer& c = s.laneColorer;
1170  if (!setFunctionalColor(c, col) && !setMultiColor(s, c, col)) {
1171  col = c.getScheme().getColor(getColorValue(s, c.getActive()));
1172  }
1173  }
1174  GLHelper::setColor(col);
1175  return col;
1176 }
1177 
1178 
1179 bool
1180 GUILane::setFunctionalColor(const GUIColorer& c, RGBColor& col, int activeScheme) const {
1181  if (activeScheme < 0) {
1182  activeScheme = c.getActive();
1183  }
1184  switch (activeScheme) {
1185  case 0:
1186  if (myEdge->isCrossing()) {
1187  // determine priority to decide color
1188  const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
1189  if (link->havePriority() || link->getTLLogic() != nullptr) {
1190  col = RGBColor(230, 230, 230);
1191  } else {
1192  col = RGBColor(26, 26, 26);
1193  }
1194  GLHelper::setColor(col);
1195  return true;
1196  } else {
1197  return false;
1198  }
1199  case 18: {
1200  double hue = GeomHelper::naviDegree(myShape.beginEndAngle()); // [0-360]
1201  col = RGBColor::fromHSV(hue, 1., 1.);
1202  GLHelper::setColor(col);
1203  return true;
1204  }
1205  case 30: { // taz color
1206  col = c.getScheme().getColor(0);
1207  std::vector<RGBColor> tazColors;
1208  for (MSEdge* e : myEdge->getPredecessors()) {
1209  if (e->isTazConnector() && e->hasParameter("tazColor")) {
1210  tazColors.push_back(RGBColor::parseColor(e->getParameter("tazColor")));
1211  }
1212  }
1213  for (MSEdge* e : myEdge->getSuccessors()) {
1214  if (e->isTazConnector() && e->hasParameter("tazColor")) {
1215  tazColors.push_back(RGBColor::parseColor(e->getParameter("tazColor")));
1216  }
1217  }
1218  if (tazColors.size() > 0) {
1219  int randColor = RandHelper::rand((int)tazColors.size(), RGBColor::getColorRNG());
1220  col = tazColors[randColor];
1221  }
1222  GLHelper::setColor(col);
1223  return true;
1224  }
1225  default:
1226  return false;
1227  }
1228 }
1229 
1230 
1231 bool
1233  const int activeScheme = c.getActive();
1234  auto& shapeColors = getShapeColors(s.secondaryShape);
1235  const PositionVector& shape = getShape(s.secondaryShape);
1236  shapeColors.clear();
1237  switch (activeScheme) {
1238  case 22: // color by height at segment start
1239  for (PositionVector::const_iterator ii = shape.begin(); ii != shape.end() - 1; ++ii) {
1240  shapeColors.push_back(c.getScheme().getColor(ii->z()));
1241  }
1242  // osg fallback (edge height at start)
1243  col = c.getScheme().getColor(getColorValue(s, 21));
1244  return true;
1245  case 24: // color by inclination at segment start
1246  for (int ii = 1; ii < (int)shape.size(); ++ii) {
1247  const double inc = (shape[ii].z() - shape[ii - 1].z()) / MAX2(POSITION_EPS, shape[ii].distanceTo2D(shape[ii - 1]));
1248  shapeColors.push_back(c.getScheme().getColor(inc));
1249  }
1250  col = c.getScheme().getColor(getColorValue(s, 23));
1251  return true;
1252  default:
1253  return false;
1254  }
1255 }
1256 
1257 double
1259  if (myCachedGUISettings != nullptr) {
1261  const GUIColorer& c = s.laneColorer;
1262  return getColorValueWithFunctional(s, c.getActive());
1263  } else {
1264  return 0;
1265  }
1266 }
1267 
1268 
1269 double
1270 GUILane::getColorValue(const GUIVisualizationSettings& s, int activeScheme) const {
1271  switch (activeScheme) {
1272  case 0:
1273  switch (myPermissions) {
1274  case SVC_PEDESTRIAN:
1275  return 1;
1276  case SVC_BICYCLE:
1277  return 2;
1278  case 0:
1279  // forbidden road or green verge
1280  return myEdge->getPermissions() == 0 ? 10 : 3;
1281  case SVC_SHIP:
1282  return 4;
1283  case SVC_AUTHORITY:
1284  return 8;
1285  case SVC_AIRCRAFT:
1286  case SVC_DRONE:
1287  return 11;
1288  default:
1289  break;
1290  }
1291  if (myEdge->isTazConnector()) {
1292  return 9;
1293  } else if (isRailway(myPermissions)) {
1294  if ((myPermissions & SVC_BUS) != 0) {
1295  return 6;
1296  } else {
1297  return 5;
1298  }
1299  } else if ((myPermissions & SVC_PASSENGER) != 0) {
1300  if ((myPermissions & (SVC_RAIL_CLASSES & ~SVC_RAIL_FAST)) != 0 && (myPermissions & SVC_SHIP) == 0) {
1301  return 6;
1302  } else {
1303  return 0;
1304  }
1305  } else {
1306  return 7;
1307  }
1308  case 1:
1309  return isLaneOrEdgeSelected();
1310  case 2:
1311  return (double)myPermissions;
1312  case 3:
1313  return getSpeedLimit();
1314  case 4:
1315  return getBruttoOccupancy();
1316  case 5:
1317  return getNettoOccupancy();
1318  case 6:
1319  return firstWaitingTime();
1320  case 7:
1321  return getEdgeLaneNumber();
1322  case 8:
1323  return getEmissions<PollutantsInterface::CO2>() / myLength;
1324  case 9:
1325  return getEmissions<PollutantsInterface::CO>() / myLength;
1326  case 10:
1327  return getEmissions<PollutantsInterface::PM_X>() / myLength;
1328  case 11:
1329  return getEmissions<PollutantsInterface::NO_X>() / myLength;
1330  case 12:
1331  return getEmissions<PollutantsInterface::HC>() / myLength;
1332  case 13:
1333  return getEmissions<PollutantsInterface::FUEL>() / myLength;
1334  case 14:
1336  case 15: {
1337  return getStoredEdgeTravelTime();
1338  }
1339  case 16: {
1341  if (!ews.knowsTravelTime(myEdge)) {
1342  return -1;
1343  } else {
1344  double value(0);
1345  ews.retrieveExistingTravelTime(myEdge, 0, value);
1346  return 100 * myLength / value / getSpeedLimit();
1347  }
1348  }
1349  case 17: {
1350  // geometrical length has no meaning for walkingAreas since it describes the outer boundary
1352  }
1353  case 19: {
1354  return getLoadedEdgeWeight();
1355  }
1356  case 20: {
1357  return myEdge->getPriority();
1358  }
1359  case 21: {
1360  // color by z of first shape point
1361  return getShape(s.secondaryShape)[0].z();
1362  }
1363  case 23: {
1364  // color by incline
1365  return (getShape(s.secondaryShape)[-1].z() - getShape(s.secondaryShape)[0].z()) / getLength();
1366  }
1367  case 25: {
1368  // color by average speed
1369  return getMeanSpeed();
1370  }
1371  case 26: {
1372  // color by average relative speed
1373  return getMeanSpeed() / myMaxSpeed;
1374  }
1375  case 27: {
1376  // color by routing device assumed speed
1377  return myEdge->getRoutingSpeed();
1378  }
1379  case 28:
1380  return getEmissions<PollutantsInterface::ELEC>() / myLength;
1381  case 29:
1382  return getPendingEmits();
1383  case 31: {
1384  // by numerical edge param value
1385  if (myEdge->hasParameter(s.edgeParam)) {
1386  try {
1388  } catch (NumberFormatException&) {
1389  try {
1391  } catch (BoolFormatException&) {
1393  }
1394  }
1395  } else {
1397  }
1398  }
1399  case 32: {
1400  // by numerical lane param value
1401  if (hasParameter(s.laneParam)) {
1402  try {
1404  } catch (NumberFormatException&) {
1405  try {
1406  return StringUtils::toBool(getParameter(s.laneParam, "0"));
1407  } catch (BoolFormatException&) {
1409  }
1410  }
1411  } else {
1413  }
1414  }
1415  case 33: {
1416  // by edge data value
1418  }
1419  case 34: {
1420  return myEdge->getDistance();
1421  }
1422  case 35: {
1423  return fabs(myEdge->getDistance());
1424  }
1425  case 36: {
1426  return myReachability;
1427  }
1428  case 37: {
1430  }
1431  case 38: {
1432  if (myParkingAreas == nullptr) {
1433  // init
1434  myParkingAreas = new std::vector<MSParkingArea*>();
1435  for (auto& item : MSNet::getInstance()->getStoppingPlaces(SUMO_TAG_PARKING_AREA)) {
1436  if (&item.second->getLane().getEdge() == myEdge) {
1437  myParkingAreas->push_back(dynamic_cast<MSParkingArea*>(item.second));
1438  }
1439  }
1440  }
1441  int capacity = 0;
1442  for (MSParkingArea* pa : *myParkingAreas) {
1443  capacity += pa->getCapacity() - pa->getOccupancy();
1444  }
1445  return capacity;
1446  }
1447  case 39: {
1448  // by live edge data value
1449  return GUINet::getGUIInstance()->getMeanData(this, s.edgeDataID, s.edgeData);
1450  }
1451  }
1452  return 0;
1453 }
1454 
1455 
1456 double
1457 GUILane::getScaleValue(const GUIVisualizationSettings& s, int activeScheme, bool s2) const {
1458  switch (activeScheme) {
1459  case 0:
1460  return 0;
1461  case 1:
1462  return isLaneOrEdgeSelected();
1463  case 2:
1464  return getSpeedLimit();
1465  case 3:
1466  return getBruttoOccupancy();
1467  case 4:
1468  return getNettoOccupancy();
1469  case 5:
1470  return firstWaitingTime();
1471  case 6:
1472  return getEdgeLaneNumber();
1473  case 7:
1474  return getEmissions<PollutantsInterface::CO2>() / myLength;
1475  case 8:
1476  return getEmissions<PollutantsInterface::CO>() / myLength;
1477  case 9:
1478  return getEmissions<PollutantsInterface::PM_X>() / myLength;
1479  case 10:
1480  return getEmissions<PollutantsInterface::NO_X>() / myLength;
1481  case 11:
1482  return getEmissions<PollutantsInterface::HC>() / myLength;
1483  case 12:
1484  return getEmissions<PollutantsInterface::FUEL>() / myLength;
1485  case 13:
1487  case 14: {
1488  return getStoredEdgeTravelTime();
1489  }
1490  case 15: {
1492  if (!ews.knowsTravelTime(myEdge)) {
1493  return -1;
1494  } else {
1495  double value(0);
1496  ews.retrieveExistingTravelTime(myEdge, 0, value);
1497  return 100 * myLength / value / getSpeedLimit();
1498  }
1499  }
1500  case 16: {
1501  return 1 / getLengthGeometryFactor(s2);
1502  }
1503  case 17: {
1504  return getLoadedEdgeWeight();
1505  }
1506  case 18: {
1507  return myEdge->getPriority();
1508  }
1509  case 19: {
1510  // scale by average speed
1511  return getMeanSpeed();
1512  }
1513  case 20: {
1514  // scale by average relative speed
1515  return getMeanSpeed() / myMaxSpeed;
1516  }
1517  case 21:
1518  return getEmissions<PollutantsInterface::ELEC>() / myLength;
1519  case 22:
1521  case 23:
1522  // by edge data value
1524  }
1525  return 0;
1526 }
1527 
1528 
1529 bool
1531  return isRailway(myPermissions) && ((myPermissions & SVC_BUS) == 0) && s.showRails;
1532 }
1533 
1534 
1535 bool
1537  return isWaterway(myPermissions) && s.showRails; // reusing the showRails setting
1538 }
1539 
1540 
1541 #ifdef HAVE_OSG
1542 void
1543 GUILane::updateColor(const GUIVisualizationSettings& s) {
1544  if (myGeom == 0) {
1545  // not drawn
1546  return;
1547  }
1548  const RGBColor col = setColor(s);
1549  osg::Vec4ubArray* colors = dynamic_cast<osg::Vec4ubArray*>(myGeom->getColorArray());
1550  (*colors)[0].set(col.red(), col.green(), col.blue(), col.alpha());
1551  myGeom->setColorArray(colors);
1552 }
1553 #endif
1554 
1555 
1556 void
1557 GUILane::closeTraffic(bool rebuildAllowed) {
1558  MSGlobals::gCheckRoutes = false;
1559  if (myAmClosed) {
1560  myPermissionChanges.clear(); // reset rerouters
1562  } else {
1564  }
1566  if (rebuildAllowed) {
1568  }
1569 }
1570 
1571 
1574  assert(MSGlobals::gUseMesoSim);
1575  int no = MELoop::numSegmentsFor(myLength, OptionsCont::getOptions().getFloat("meso-edgelength"));
1576  const double slength = myLength / no;
1577  PositionVector result = shape;
1578  double offset = 0;
1579  for (int i = 0; i < no; ++i) {
1580  offset += slength;
1581  Position pos = shape.positionAtOffset(offset);
1582  int index = result.indexOfClosest(pos);
1583  if (pos.distanceTo(result[index]) > POSITION_EPS) {
1584  index = result.insertAtClosest(pos, false);
1585  }
1586  if (i != no - 1) {
1587  mySegmentStartIndex.push_back(index);
1588  }
1589  while ((int)myShapeSegments.size() < index) {
1590  myShapeSegments.push_back(i);
1591  }
1592  //std::cout << "splitAtSegments " << getID() << " no=" << no << " i=" << i << " offset=" << offset << " index=" << index << " segs=" << toString(myShapeSegments) << " resultSize=" << result.size() << " result=" << toString(result) << "\n";
1593  }
1594  while (myShapeSegments.size() < result.size()) {
1595  myShapeSegments.push_back(no - 1);
1596  }
1597  return result;
1598 }
1599 
1600 bool
1602  return gSelected.isSelected(GLO_LANE, getGlID());
1603 }
1604 
1605 bool
1607  return isSelected() || gSelected.isSelected(GLO_EDGE, dynamic_cast<GUIEdge*>(myEdge)->getGlID());
1608 }
1609 
1610 double
1613 }
1614 
1615 double
1617  if (MSGlobals::gUseMesoSim) {
1618  // do not select lanes in meso mode
1619  return INVALID_PRIORITY;
1620  }
1621  if (myEdge->isCrossing()) {
1622  return GLO_CROSSING;
1623  }
1624  return GLO_LANE;
1625 }
1626 
1627 
1628 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
@ MID_COPY_EDGE_NAME
Copy edge name (for lanes only)
Definition: GUIAppEnum.h:455
@ MID_REACHABILITY
show reachability from a given lane
Definition: GUIAppEnum.h:527
@ MID_CLOSE_LANE
close lane
Definition: GUIAppEnum.h:663
@ MID_CLOSE_EDGE
close edge
Definition: GUIAppEnum.h:665
@ MID_ADD_REROUTER
add rerouter
Definition: GUIAppEnum.h:667
@ 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 permission is a railway edge.
bool isWaterway(SVCPermissions permissions)
Returns whether an edge with the given permission is a waterway edge.
bool isAirway(SVCPermissions permissions)
Returns whether an edge with the given permission 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_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 drawFilledPoly(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:203
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:1536
void debugDrawFoeIntersections() const
draw intersection positions of foe internal lanes with this one
Definition: GUILane.cpp:962
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:1606
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:1573
std::vector< int > myShapeSegments
the meso segment index for each geometry segment
Definition: GUILane.h:363
double firstWaitingTime() const
Definition: GUILane.cpp:1112
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:1163
double getPendingEmits() const
get number of vehicles waiting for departure on this lane
Definition: GUILane.cpp:1611
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:987
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:869
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:1232
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:1457
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:804
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const override
gets the color value according to the current scheme index
Definition: GUILane.cpp:1270
void closeTraffic(bool rebuildAllowed=true)
close this lane for traffic
Definition: GUILane.cpp:1557
double getClickPriority() const override
Returns the priority of receiving mouse clicks.
Definition: GUILane.cpp:1616
bool isSelected() const override
whether this lane is selected in the GUI
Definition: GUILane.cpp:1601
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own parameter window.
Definition: GUILane.cpp:1033
const std::vector< double > & getShapeRotations(bool secondary) const
Definition: GUILane.cpp:1094
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:1150
bool drawAsRailway(const GUIVisualizationSettings &s) const
whether to draw this lane as a railway
Definition: GUILane.cpp:1530
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:1258
std::vector< RGBColor > myShapeColors2
Definition: GUILane.h:360
double getEdgeLaneNumber() const
Definition: GUILane.cpp:1118
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:1137
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:1088
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:1076
std::vector< RGBColor > & getShapeColors(bool secondary) const
Definition: GUILane.cpp:1106
bool setFunctionalColor(const GUIColorer &c, RGBColor &col, int activeScheme=-1) const
Definition: GUILane.cpp:1180
double getStoredEdgeTravelTime() const
Returns the stored traveltime for the edge of this lane.
Definition: GUILane.cpp:1124
const std::vector< double > & getShapeLengths(bool secondary) const
Definition: GUILane.cpp:1100
void drawMarkings(const GUIVisualizationSettings &s, double scale) const
draw lane borders and white markings
Definition: GUILane.cpp:817
void drawBikeMarkings() const
bike lane markings on top of an intersection
Definition: GUILane.cpp:840
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:934
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.
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:278
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:55
A road/street connecting two junctions.
Definition: MSEdge.h:77
bool isCrossing() const
return whether this edge is a pedestrian crossing
Definition: MSEdge.h:270
int getPriority() const
Returns the priority of the edge.
Definition: MSEdge.h:325
SVCPermissions getPermissions() const
Returns the combined permissions of all lanes of this edge.
Definition: MSEdge.h:626
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:406
const std::string & getStreetName() const
Returns the street name of the edge.
Definition: MSEdge.h:310
bool isWalkingArea() const
return whether this edge is walking area
Definition: MSEdge.h:284
void rebuildAllowedLanes(const bool onInit=false)
Definition: MSEdge.cpp:317
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
bool isTazConnector() const
Definition: MSEdge.h:288
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:265
int getNumericalID() const
Returns the numerical id of the edge.
Definition: MSEdge.h:303
double getTimePenalty() const
Definition: MSEdge.h:483
const std::string & getEdgeType() const
Returns the type of the edge.
Definition: MSEdge.h:316
const MSJunction * getToJunction() const
Definition: MSEdge.h:415
double getRoutingSpeed() const
Returns the averaged speed used by the routing device.
Definition: MSEdge.cpp:977
const MSEdge * getBidiEdge() const
return opposite superposable/congruent edge, if it exist and 0 else
Definition: MSEdge.h:279
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:1194
double getDistance() const
Returns the kilometrage/mileage encoding at the start of the edge (negative values encode descending ...
Definition: MSEdge.h:332
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:169
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:1537
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:2744
virtual void removeParking(MSBaseVehicle *veh)
remove parking vehicle. This must be syncrhonized when running with GUI
Definition: MSLane.cpp:3568
virtual void integrateNewVehicles()
Insert buffered vehicle into the real lane.
Definition: MSLane.cpp:2462
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:3290
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:2726
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:3130
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:2639
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:1497
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:2533
SVCPermissions getPermissions() const
Returns the vehicle class permissions for this lane.
Definition: MSLane.h:606
void resetPermissions(long long transientID)
Definition: MSLane.cpp:4410
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:2709
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:4398
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:2183
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:3095
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:3275
int myIndex
The lane index.
Definition: MSLane.h:1437
bool isCrossing() const
Definition: MSLane.cpp:2528
virtual void detectCollisions(SUMOTime timestep, const std::string &stage)
Check if vehicles are too close.
Definition: MSLane.cpp:1598
std::vector< MSLink * > myLinks
Definition: MSLane.h:1552
bool isInternal() const
Definition: MSLane.cpp:2516
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:3364
MSLane * getBidiLane() const
retrieve bidirectional lane or nullptr
Definition: MSLane.cpp:4524
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:3120
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:3318
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:182
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:351
MSEdgeWeightsStorage & getWeightsStorage()
Returns the net's internal edge travel times/efforts container.
Definition: MSNet.cpp:1196
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:271
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimensions
Definition: Position.h:261
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 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 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