Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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-2025 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>
28#include <utils/geom/Position.h>
42#include <gui/GUIGlobals.h>
43#include <microsim/MSGlobals.h>
44#include <microsim/MSLane.h>
45#include <microsim/MSLink.h>
49#include <microsim/MSNet.h>
55#include <mesosim/MELoop.h>
56#include <mesosim/MESegment.h>
57#include "GUILane.h"
58#include "GUIEdge.h"
59#include "GUIVehicle.h"
60#include "GUINet.h"
62
64
65#define RENDERING_BUFFER 10
66
67//#define GUILane_DEBUG_DRAW_FOE_INTERSECTIONS
68//#define GUILane_DEBUG_DRAW_CROSSING_OUTLINE
69
70// ===========================================================================
71// static member declaration
72// ===========================================================================
75
76
77// ===========================================================================
78// method definitions
79// ===========================================================================
80GUILane::GUILane(const std::string& id, double maxSpeed, double friction, double length,
81 MSEdge* const edge, int numericalID,
82 const PositionVector& shape, double width,
83 SVCPermissions permissions,
84 SVCPermissions changeLeft, SVCPermissions changeRight,
85 int index, bool isRampAccel,
86 const std::string& type,
87 const PositionVector& outlineShape) :
88 MSLane(id, maxSpeed, friction, length, edge, numericalID, shape, width, permissions, changeLeft, changeRight, index, isRampAccel, type, outlineShape),
90 myParkingAreas(nullptr),
91 myTesselation(nullptr),
92#ifdef HAVE_OSG
93 myGeom(0),
94#endif
95 myAmClosed(false),
96 myLengthGeometryFactor2(myLengthGeometryFactor),
97 myLock(true) {
99 myShape = splitAtSegments(shape);
100 assert(fabs(myShape.length() - shape.length()) < POSITION_EPS);
101 assert(myShapeSegments.size() == myShape.size());
102 }
104 //
107}
108
109
111 // just to quit cleanly on a failure
112 if (myLock.locked()) {
113 myLock.unlock();
114 }
115 delete myParkingAreas;
116 delete myTesselation;
117}
118
119
120void
122 std::vector<double>& rotations,
123 std::vector<double>& lengths,
124 std::vector<RGBColor>& colors) {
125 rotations.clear();
126 lengths.clear();
127 colors.clear();
128 rotations.reserve(shape.size() - 1);
129 lengths.reserve(shape.size() - 1);
130 colors.reserve(shape.size() - 1);
131 int e = (int) shape.size() - 1;
132 for (int i = 0; i < e; ++i) {
133 const Position& f = shape[i];
134 const Position& s = shape[i + 1];
135 lengths.push_back(f.distanceTo2D(s));
136 rotations.push_back(RAD2DEG(atan2(s.x() - f.x(), f.y() - s.y())));
137 }
138}
139
140
141void
147
148
149// ------ Vehicle insertion ------
150void
151GUILane::incorporateVehicle(MSVehicle* veh, double pos, double speed, double posLat,
152 const MSLane::VehCont::iterator& at,
153 MSMoveReminder::Notification notification) {
154 FXMutexLock locker(myLock);
155 MSLane::incorporateVehicle(veh, pos, speed, posLat, at, notification);
156}
157
158
159// ------ Access to vehicles ------
160const MSLane::VehCont&
162 myLock.lock();
163 return myVehicles;
164}
165
166
167void
169 myLock.unlock();
170}
171
172
173void
175 FXMutexLock locker(myLock);
177}
178
179void
181 FXMutexLock locker(myLock);
183}
184
185
186void
188 FXMutexLock locker(myLock);
190}
191
192
194GUILane::removeVehicle(MSVehicle* remVehicle, MSMoveReminder::Notification notification, bool notify) {
195 FXMutexLock locker(myLock);
196 return MSLane::removeVehicle(remVehicle, notification, notify);
197}
198
199
200void
202 FXMutexLock locker(myLock);
203 return MSLane::removeParking(remVehicle);
204}
205
206
207void
212
213
214void
219
220
221void
222GUILane::detectCollisions(SUMOTime timestep, const std::string& stage) {
223 FXMutexLock locker(myLock);
224 MSLane::detectCollisions(timestep, stage);
225}
226
227
228double
230 FXMutexLock locker(myLock);
232}
233
234
235void
240
241
242// ------ Drawing methods ------
243void
245 int noLinks = (int)myLinks.size();
246 if (noLinks == 0) {
247 return;
248 }
249 // draw all links
250 if (getEdge().isCrossing()) {
251 // draw indices at the start and end of the crossing
252 const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
254 shape.extrapolate(0.5); // draw on top of the walking area
257 return;
258 }
259 // draw all links
260 double w = myWidth / (double) noLinks;
261 double x1 = myHalfLaneWidth;
262 for (int i = noLinks; --i >= 0;) {
263 double x2 = x1 - (double)(w / 2.);
265 x1 -= w;
266 }
267}
268
269
270void
272 int noLinks = (int)myLinks.size();
273 if (noLinks == 0) {
274 return;
275 }
276 if (getEdge().isCrossing()) {
277 // draw indices at the start and end of the crossing
278 const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
279 int linkNo = net.getLinkTLIndex(link);
280 // maybe the reverse link is controlled separately
281 int linkNo2 = net.getLinkTLIndex(myLinks.front());
282 // otherwise, use the same index as the forward link
283 if (linkNo2 < 0) {
284 linkNo2 = linkNo;
285 }
286 if (linkNo >= 0) {
288 shape.extrapolate(0.5); // draw on top of the walking area
289 GLHelper::drawTextAtEnd(toString(linkNo2), shape, 0, s.drawLinkTLIndex, s.scale);
291 }
292 return;
293 }
294 // draw all links
295 double w = myWidth / (double) noLinks;
296 double x1 = myHalfLaneWidth;
297 for (int i = noLinks; --i >= 0;) {
298 double x2 = x1 - (double)(w / 2.);
299 int linkNo = net.getLinkTLIndex(myLinks[MSGlobals::gLefthand ? noLinks - 1 - i : i]);
300 if (linkNo < 0) {
301 continue;
302 }
304 x1 -= w;
305 }
306}
307
308
309void
311 int noLinks = (int)myLinks.size();
312 const PositionVector& shape = getShape(s.secondaryShape);
313 if (noLinks == 0) {
314 drawLinkRule(s, net, nullptr, shape, 0, 0);
315 return;
316 }
317 if (getEdge().isCrossing()) {
318 // draw rules at the start and end of the crossing
319 const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
320 const MSLink* link2 = myLinks.front();
321 if (link2->getTLLogic() == nullptr) {
322 link2 = link;
323 }
324 PositionVector tmp = shape;
325 tmp.extrapolate(0.5); // draw on top of the walking area
326 drawLinkRule(s, net, link2, tmp, 0, myWidth);
327 drawLinkRule(s, net, link, tmp.reverse(), 0, myWidth);
328 return;
329 }
330 // draw all links
331 const double isRailSignal = myEdge->getToJunction()->getType() == SumoXMLNodeType::RAIL_SIGNAL;
332 double w = myWidth / (double) noLinks;
333 if (isRailSignal && noLinks > 1 && myLinks.back()->isTurnaround() && s.showRails) {
334 w = myWidth / (double)(noLinks - 1);
335 }
336 double x1 = isRailSignal ? -myWidth * 0.5 : 0;
337 for (int i = 0; i < noLinks; ++i) {
338 double x2 = x1 + w;
339 drawLinkRule(s, net, myLinks[MSGlobals::gLefthand ? noLinks - 1 - i : i], shape, x1, x2);
340 x1 = x2;
341 }
342 // draw stopOffset for passenger cars
344 const double stopOffsetPassenger = myLaneStopOffset.getOffset();
345 const Position& end = shape.back();
346 const Position& f = shape[-2];
347 const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
350 glTranslated(end.x(), end.y(), 0);
351 glRotated(rot, 0, 0, 1);
352 glTranslated(0, stopOffsetPassenger, 0);
353 glBegin(GL_QUADS);
354 glVertex2d(-myHalfLaneWidth, 0.0);
355 glVertex2d(-myHalfLaneWidth, 0.2);
356 glVertex2d(myHalfLaneWidth, 0.2);
357 glVertex2d(myHalfLaneWidth, 0.0);
358 glEnd();
360 }
361}
362
363
364void
365GUILane::drawLinkRule(const GUIVisualizationSettings& s, const GUINet& net, const MSLink* link, const PositionVector& shape, double x1, double x2) const {
366 const Position& end = shape.back();
367 const Position& f = shape[-2];
368 const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
369 if (link == nullptr) {
370 if (static_cast<GUIEdge*>(myEdge)->showDeadEnd()) {
372 } else {
374 }
376 glTranslated(end.x(), end.y(), 0);
377 glRotated(rot, 0, 0, 1);
378 glBegin(GL_QUADS);
379 glVertex2d(-myHalfLaneWidth, 0.0);
380 glVertex2d(-myHalfLaneWidth, 0.5);
381 glVertex2d(myHalfLaneWidth, 0.5);
382 glVertex2d(myHalfLaneWidth, 0.0);
383 glEnd();
385 } else {
387 glTranslated(end.x(), end.y(), 0);
388 glRotated(rot, 0, 0, 1);
389 // select glID
390
391 switch (link->getState()) {
393 case LINKSTATE_STOP: {
394 // might be a traffic light link
395 int tlID = net.getLinkTLID(link);
396 GLHelper::pushName(tlID != 0 ? tlID : getGlID());
397 break;
398 }
401 case LINKSTATE_TL_RED:
408 break;
409 case LINKSTATE_MAJOR:
410 case LINKSTATE_MINOR:
411 case LINKSTATE_EQUAL:
412 default:
414 break;
415 }
417 if (!(drawAsRailway(s) || drawAsWaterway(s)) || link->getState() != LINKSTATE_MAJOR) {
418 // the white bar should be the default for most railway
419 // links and looks ugly so we do not draw it
420 double scale = isInternal() ? 0.5 : 1;
422 scale *= MAX2(s.laneWidthExaggeration, s.junctionSize.getExaggeration(s, this, 10));
423 }
424 glScaled(scale, scale, 1);
425 glBegin(GL_QUADS);
426 glVertex2d(x1 - myHalfLaneWidth, 0.0);
427 glVertex2d(x1 - myHalfLaneWidth, 0.5);
428 glVertex2d(x2 - myHalfLaneWidth, 0.5);
429 glVertex2d(x2 - myHalfLaneWidth, 0.0);
430 glEnd();
431 if (s.gaming && link->haveGreen()) {
432 const MSLane* lane = link->getLane();
433 // exaggerate green signals for railway game
434 if (isRailway(lane->getPermissions())) {
435 GLHelper::drawFilledCircle(lane->getWidth() / 2., 8, 90, 270);
436 }
437 }
438 }
441 }
442}
443
444void
445GUILane::drawArrows(bool secondaryShape) const {
446 if (myLinks.size() == 0) {
447 return;
448 }
449 // draw all links
450 const Position& end = getShape(secondaryShape).back();
451 const Position& f = getShape(secondaryShape)[-2];
452 const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
454 glColor3d(1, 1, 1);
455 glTranslated(end.x(), end.y(), 0);
456 glRotated(rot, 0, 0, 1);
458 glScaled(myWidth / SUMO_const_laneWidth, 1, 1);
459 }
460 for (const MSLink* const link : myLinks) {
461 LinkDirection dir = link->getDirection();
462 LinkState state = link->getState();
463 if (state == LINKSTATE_DEADEND || dir == LinkDirection::NODIR) {
464 continue;
465 }
466 switch (dir) {
468 GLHelper::drawBoxLine(Position(0, 4), 0, 2, .05);
469 GLHelper::drawTriangleAtEnd(Position(0, 4), Position(0, 1), (double) 1, (double) .25);
470 break;
472 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
473 GLHelper::drawBoxLine(Position(0, 2.5), 90, .5, .05);
474 GLHelper::drawBoxLine(Position(0.5, 2.5), 180, 1, .05);
475 GLHelper::drawTriangleAtEnd(Position(0.5, 2.5), Position(0.5, 4), (double) 1, (double) .25);
476 break;
478 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
479 GLHelper::drawBoxLine(Position(0, 2.5), -90, .5, .05);
480 GLHelper::drawBoxLine(Position(-0.5, 2.5), -180, 1, .05);
481 GLHelper::drawTriangleAtEnd(Position(-0.5, 2.5), Position(-0.5, 4), (double) 1, (double) .25);
482 break;
484 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
485 GLHelper::drawBoxLine(Position(0, 2.5), 90, 1, .05);
486 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.5, 2.5), (double) 1, (double) .25);
487 break;
489 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
490 GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
491 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.5, 2.5), (double) 1, (double) .25);
492 break;
494 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
495 GLHelper::drawBoxLine(Position(0, 2.5), 45, .7, .05);
496 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.2, 1.3), (double) 1, (double) .25);
497 break;
499 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
500 GLHelper::drawBoxLine(Position(0, 2.5), -45, .7, .05);
501 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.2, 1.3), (double) 1, (double) .25);
502 break;
503 default:
504 break;
505 }
506 }
508}
509
510
511void
512GUILane::drawLane2LaneConnections(double exaggeration, bool s2) const {
513 Position centroid;
514 if (exaggeration > 1) {
515 centroid = myEdge->getToJunction()->getShape().getCentroid();
516 }
517 for (const MSLink* const link : myLinks) {
518 const GUILane* connected = dynamic_cast<GUILane*>(link->getLane());
519 if (connected == nullptr) {
520 continue;
521 }
523 glBegin(GL_LINES);
524 Position p1 = myEdge->isWalkingArea() ? getShape(s2).getCentroid() : getShape(s2)[-1];
525 Position p2 = connected->getEdge().isWalkingArea() ? connected->getShape(s2).getCentroid() : connected->getShape(s2)[0];
526 if (exaggeration > 1) {
527 p1 = centroid + ((p1 - centroid) * exaggeration);
528 p2 = centroid + ((p2 - centroid) * exaggeration);
529 }
530 glVertex2d(p1.x(), p1.y());
531 glVertex2d(p2.x(), p2.y());
532 glEnd();
533 GLHelper::drawTriangleAtEnd(p1, p2, (double) .4, (double) .2);
534 }
535}
536
537
538void
542 const bool s2 = s.secondaryShape;
543 double exaggeration = s.laneWidthExaggeration;
545 GUIEdge* myGUIEdge = dynamic_cast<GUIEdge*>(myEdge);
546 exaggeration *= s.edgeScaler.getScheme().getColor(myGUIEdge->getScaleValue(s, s.edgeScaler.getActive()));
547 } else {
548 exaggeration *= s.laneScaler.getScheme().getColor(getScaleValue(s, s.laneScaler.getActive(), s2));
549 }
550 // set lane color
551 const RGBColor color = setColor(s);
552 // recognize full transparency and simply don't draw
553 if (color.alpha() != 0 && s.scale * exaggeration > s.laneMinSize) {
554
555 const bool isCrossing = myEdge->isCrossing();
556 const bool isWalkingArea = myEdge->isWalkingArea();
558 const PositionVector& baseShape = getShape(s2);
559 const bool hasRailSignal = myEdge->getToJunction()->getType() == SumoXMLNodeType::RAIL_SIGNAL;
560 if (s.trueZ) {
561 glTranslated(0, 0, baseShape.getMinZ());
562 } else {
563 if (isCrossing) {
564 // draw internal lanes on top of junctions
565 glTranslated(0, 0, GLO_JUNCTION + 0.1);
566 } else if (isWalkingArea) {
567 // draw internal lanes on top of junctions
568 glTranslated(0, 0, GLO_JUNCTION + 0.3);
569 } else if (isWaterway(myPermissions)) {
570 // draw waterways below normal roads
571 glTranslated(0, 0, getType() - 0.2);
572 } else if (myPermissions == SVC_SUBWAY) {
573 // draw subways further below
574 glTranslated(0, 0, getType() - 0.4);
575 } else {
576 glTranslated(0, 0, getType());
577 }
578 }
579 auto& shapeColors = getShapeColors(s2);
581 shapeColors.clear();
582 const std::vector<RGBColor>& segmentColors = static_cast<const GUIEdge*>(myEdge)->getSegmentColors();
583 if (segmentColors.size() > 0) {
584 // apply segment specific shape colors
585 //std::cout << getID() << " shape=" << myShape << " shapeSegs=" << toString(myShapeSegments) << "\n";
586 for (int ii = 0; ii < (int)baseShape.size() - 1; ++ii) {
587 shapeColors.push_back(segmentColors[myShapeSegments[ii]]);
588 }
589 }
590 }
591
592 // scale tls-controlled lane2lane-arrows along with their junction shapes
593 double junctionExaggeration = 1;
594 if (!isInternal
597 junctionExaggeration = MAX2(1.001, s.junctionSize.getExaggeration(s, this, 4));
598 }
599 // draw lane
600 // check whether it is not too small
601 if (s.scale * exaggeration < 1. && junctionExaggeration == 1 && s.junctionSize.minSize != 0) {
602 if (!isInternal || hasRailSignal) {
603 if (shapeColors.size() > 0) {
604 GLHelper::drawLine(baseShape, shapeColors);
605 } else {
606 GLHelper::drawLine(baseShape);
607 }
608 }
610
611 } else {
612
613 GUINet* net = (GUINet*) MSNet::getInstance();
614 bool mustDrawMarkings = false;
615 bool hiddenBidi = getBidiLane() != nullptr && myEdge->getNumericalID() > myEdge->getBidiEdge()->getNumericalID();
616 const bool detailZoom = s.scale * exaggeration > 5;
617 const bool drawDetails = (detailZoom || s.junctionSize.minSize == 0 || hasRailSignal);
618 const bool drawRails = drawAsRailway(s);
619 const bool spreadSuperposed = s.spreadSuperposed && myBidiLane != nullptr;
620 if (hiddenBidi && !spreadSuperposed) {
621 // do not draw shape
622 mustDrawMarkings = !isInternal && myPermissions != 0 && myPermissions != SVC_PEDESTRIAN && exaggeration == 1.0 && !isWaterway(myPermissions) && neighLaneNotBidi();
623 } else if (drawRails) {
624 // draw as railway: assume standard gauge of 1435mm when lane width is not set
625 // draw foot width 150mm, assume that distance between rail feet inner sides is reduced on both sides by 39mm with regard to the gauge
626 // assume crosstie length of 181% gauge (2600mm for standard gauge)
627 PositionVector shape = baseShape;
628 const double width = myWidth;
629 double halfGauge = 0.5 * (width == SUMO_const_laneWidth ? 1.4350 : width) * exaggeration;
630 if (spreadSuperposed) {
631 try {
632 shape.move2side(halfGauge * 0.8);
633 } catch (InvalidArgument&) {}
634 halfGauge *= 0.4;
635 }
636 const double halfInnerFeetWidth = halfGauge - 0.039 * exaggeration;
637 const double halfRailWidth = detailZoom ? (halfInnerFeetWidth + 0.15 * exaggeration) : SUMO_const_halfLaneWidth * exaggeration;
638 const double halfCrossTieWidth = halfGauge * 1.81;
639 if (shapeColors.size() > 0) {
640 GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), getShapeColors(s2), halfRailWidth);
641 } else {
642 GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), halfRailWidth);
643 }
644 // Draw white on top with reduced width (the area between the two tracks)
645 if (detailZoom) {
646 glColor3d(1, 1, 1);
647 glTranslated(0, 0, .1);
648 GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), halfInnerFeetWidth);
649 setColor(s);
650 GLHelper::drawCrossTies(shape, getShapeRotations(s2), getShapeLengths(s2), 0.26 * exaggeration, 0.6 * exaggeration,
651 halfCrossTieWidth, 0, s.forceDrawForRectangleSelection);
652 }
653 } else if (isCrossing) {
654 if (s.drawCrossingsAndWalkingareas && (s.scale > 3.0 || s.junctionSize.minSize == 0)) {
655 glTranslated(0, 0, .2);
656 GLHelper::drawCrossTies(baseShape, getShapeRotations(s2), getShapeLengths(s2), 0.5, 1.0, getWidth() * 0.5,
658#ifdef GUILane_DEBUG_DRAW_CROSSING_OUTLINE
659 if (myOutlineShape != nullptr) {
661 glTranslated(0, 0, 0.4);
663 glTranslated(0, 0, -0.4);
664 if (s.geometryIndices.show(this)) {
666 }
667 }
668#endif
669 glTranslated(0, 0, -.2);
670 }
671 } else if (isWalkingArea) {
672 if (s.drawCrossingsAndWalkingareas && (s.scale > 3.0 || s.junctionSize.minSize == 0)) {
673 glTranslated(0, 0, .2);
674 if (myTesselation == nullptr) {
676 }
677 myTesselation->drawTesselation(baseShape);
678 glTranslated(0, 0, -.2);
679 if (s.geometryIndices.show(this)) {
681 }
682 }
683 } else {
684 // we draw the lanes with reduced width so that the lane markings below are visible
685 // (this avoids artifacts at geometry corners without having to
686 // compute lane-marking intersection points)
688 mustDrawMarkings = !isInternal && myPermissions != 0 && myPermissions != SVC_PEDESTRIAN && exaggeration == 1.0 && !isWaterway(myPermissions) && !isAirway(myPermissions);
689 const int cornerDetail = drawDetails && !isInternal ? (s.drawForRectangleSelection ? 4 : MIN2(32, (int)(s.scale * exaggeration))) : 0;
690 double offset = halfWidth * MAX2(0., (exaggeration - 1)) * (MSGlobals::gLefthand ? -1 : 1);
691 if (spreadSuperposed) {
692 offset += halfWidth * 0.5 * (MSGlobals::gLefthand ? -1 : 1);
693 halfWidth *= 0.4; // create visible gap
694 }
695 if (shapeColors.size() > 0) {
696 GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), shapeColors, halfWidth * exaggeration, cornerDetail, offset);
697 } else {
698 GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), halfWidth * exaggeration, cornerDetail, offset);
699 }
700 }
702#ifdef GUILane_DEBUG_DRAW_FOE_INTERSECTIONS
705 }
706#endif
707 if (s.geometryIndices.show(this)) {
709 }
710 // draw details
711 if ((!isInternal || isCrossing || !s.drawJunctionShape) && (drawDetails || junctionExaggeration > 1)) {
713 glTranslated(0, 0, GLO_JUNCTION); // must draw on top of junction shape
714 glTranslated(0, 0, .5);
715 if (drawDetails) {
716 if (s.showLaneDirection) {
717 if (drawRails) {
718 // improve visibility of superposed rail edges
719 GLHelper::setColor(setColor(s).changedBrightness(100));
720 } else {
721 glColor3d(0.3, 0.3, 0.3);
722 }
724 drawDirectionIndicators(exaggeration, spreadSuperposed, s.secondaryShape);
725 }
726 }
727 if (!isInternal || isCrossing
728 // controlled internal junction
729 || (getLinkCont().size() != 0 && getLinkCont()[0]->isInternalJunctionLink() && getLinkCont()[0]->getTLLogic() != nullptr)) {
730 if (MSGlobals::gLateralResolution > 0 && s.showSublanes && !hiddenBidi && (myPermissions & ~(SVC_PEDESTRIAN | SVC_RAIL_CLASSES)) != 0) {
731 // draw sublane-borders
732 const double offsetSign = MSGlobals::gLefthand ? -1 : 1;
734 for (double offset = -myHalfLaneWidth; offset < myHalfLaneWidth; offset += MSGlobals::gLateralResolution) {
735 GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), 0.01, 0, -offset * offsetSign);
736 }
737 }
739 // draw segment borders
741 for (int i : mySegmentStartIndex) {
742 if (shapeColors.size() > 0) {
743 GLHelper::setColor(shapeColors[i].changedBrightness(51));
744 }
745 GLHelper::drawBoxLine(baseShape[i], getShapeRotations(s2)[i] + 90, myWidth / 3, 0.2, 0);
746 GLHelper::drawBoxLine(baseShape[i], getShapeRotations(s2)[i] - 90, myWidth / 3, 0.2, 0);
747 }
748 }
749 if (s.showLinkDecals && !drawRails && !drawAsWaterway(s) && myPermissions != SVC_PEDESTRIAN) {
751 }
752 glTranslated(0, 0, 1000);
753 if (s.drawLinkJunctionIndex.show(nullptr)) {
754 drawLinkNo(s);
755 }
756 if (s.drawLinkTLIndex.show(nullptr)) {
757 drawTLSLinkNo(s, *net);
758 }
759 glTranslated(0, 0, -1000);
760 }
761 glTranslated(0, 0, .1);
762 }
763 if ((drawDetails || junctionExaggeration > 1) && s.showLane2Lane) {
764 // draw from end of first to the begin of second but respect junction scaling
765 drawLane2LaneConnections(junctionExaggeration, s.secondaryShape);
766 }
768 // make sure link rules are drawn so tls can be selected via right-click
769 if (s.showLinkRules && drawDetails && !isWalkingArea &&
770 (!myEdge->isInternal() || (getLinkCont().size() > 0 && getLinkCont()[0]->isInternalJunctionLink()))) {
772 glTranslated(0, 0, GLO_SHAPE); // must draw on top of junction shape and additionals
773 drawLinkRules(s, *net);
775 }
776 }
777 if (mustDrawMarkings && drawDetails && s.laneShowBorders) { // needs matrix reset
778 drawMarkings(s, exaggeration);
779 }
780 if (drawDetails && isInternal && s.showBikeMarkings && myPermissions == SVC_BICYCLE && exaggeration == 1.0 && s.showLinkDecals && s.laneShowBorders && !hiddenBidi
784 }
785 if (drawDetails && isInternal && exaggeration == 1.0 && s.showLinkDecals && s.laneShowBorders && !hiddenBidi && myIndex > 0
786 && !(myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER) && allowsChangingRight(SVC_PASSENGER))) {
787 // draw lane changing prohibitions on junction
789 }
790 }
791 } else {
793 }
794 // draw vehicles
795 if (s.scale * s.vehicleSize.getExaggeration(s, nullptr) > s.vehicleSize.minSize) {
796 // retrieve vehicles from lane; disallow simulation
797 const MSLane::VehCont& vehicles = getVehiclesSecure();
798 for (MSLane::VehCont::const_iterator v = vehicles.begin(); v != vehicles.end(); ++v) {
799 if ((*v)->getLane() == this) {
800 static_cast<const GUIVehicle*>(*v)->drawGL(s);
801 } // else: this is the shadow during a continuous lane change
802 }
803 // draw long partial vehicles (#14342)
804 for (const MSVehicle* veh : myPartialVehicles) {
805 if (veh->getLength() > RENDERING_BUFFER) {
806 // potential double rendering taken into account
807 static_cast<const GUIVehicle*>(veh)->drawGL(s);
808 }
809 }
810 // draw parking vehicles
811 for (const MSBaseVehicle* const v : myParkingVehicles) {
812 dynamic_cast<const GUIBaseVehicle*>(v)->drawGL(s);
813 }
814 // allow lane simulation
816 }
818}
819
820bool
822 const MSLane* right = getParallelLane(-1, false);
823 if (right && right->getBidiLane() == nullptr) {
824 return true;
825 }
826 const MSLane* left = getParallelLane(1, false);
827 if (left && left->getBidiLane() == nullptr) {
828 return true;
829 }
830 return false;
831}
832
833void
834GUILane::drawMarkings(const GUIVisualizationSettings& s, double scale) const {
836 glTranslated(0, 0, GLO_EDGE);
837 setColor(s);
838 // optionally draw inverse markings
839 const bool s2 = s.secondaryShape;
840 if (myIndex > 0 && (myEdge->getLanes()[myIndex - 1]->getPermissions() & myPermissions) != 0) {
841 const bool cl = myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER);
842 const bool cr = allowsChangingRight(SVC_PASSENGER);
844 }
845 // draw white boundings and white markings
846 glColor3d(1, 1, 1);
848 getShape(s2),
850 getShapeLengths(s2),
853}
854
855
856void
858 // draw bike lane markings onto the intersection
859 glColor3d(1, 1, 1);
861 const bool s2 = false;
862 const int e = (int) getShape(s2).size() - 1;
863 const double markWidth = 0.1;
864 const double mw = myHalfLaneWidth;
865 for (int i = 0; i < e; ++i) {
867 glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), GLO_JUNCTION + 0.4);
868 glRotated(getShapeRotations(s2)[i], 0, 0, 1);
869 for (double t = 0; t < getShapeLengths(s2)[i]; t += 0.5) {
870 // left and right marking
871 for (int side = -1; side <= 1; side += 2) {
872 glBegin(GL_QUADS);
873 glVertex2d(side * mw, -t);
874 glVertex2d(side * mw, -t - 0.35);
875 glVertex2d(side * (mw + markWidth), -t - 0.35);
876 glVertex2d(side * (mw + markWidth), -t);
877 glEnd();
878 }
879 }
881 }
882}
883
884
885void
887 // fixme
888 const bool s2 = false;
889 // draw white markings
890 if (myIndex > 0 && (myEdge->getLanes()[myIndex - 1]->getPermissions() & myPermissions) != 0) {
891 glColor3d(1, 1, 1);
892 const bool cl = myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER);
893 const bool cr = allowsChangingRight(SVC_PASSENGER);
894 // solid line marking
895 double mw, mw2;
896 // optional broken line marking
897 double mw3, mw4;
898 if (!cl && !cr) {
899 // draw a single solid line
902 mw3 = myHalfLaneWidth;
903 mw4 = myHalfLaneWidth;
904 } else {
905 // draw one solid and one broken line
906 if (cl) {
911 } else {
916 }
917 }
919 mw *= -1;
920 mw2 *= -1;
921 }
922 int e = (int) getShape(s2).size() - 1;
923 for (int i = 0; i < e; ++i) {
925 glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), GLO_JUNCTION + 0.4);
926 glRotated(getShapeRotations(s2)[i], 0, 0, 1);
927 for (double t = 0; t < getShapeLengths(s2)[i]; t += 6) {
928 const double lengthSolid = MIN2(6.0, getShapeLengths(s2)[i] - t);
929 glBegin(GL_QUADS);
930 glVertex2d(-mw, -t);
931 glVertex2d(-mw, -t - lengthSolid);
932 glVertex2d(-mw2, -t - lengthSolid);
933 glVertex2d(-mw2, -t);
934 glEnd();
935 if (cl || cr) {
936 const double lengthBroken = MIN2(3.0, getShapeLengths(s2)[i] - t);
937 glBegin(GL_QUADS);
938 glVertex2d(-mw3, -t);
939 glVertex2d(-mw3, -t - lengthBroken);
940 glVertex2d(-mw4, -t - lengthBroken);
941 glVertex2d(-mw4, -t);
942 glEnd();
943 }
944 }
946 }
947 }
948}
949
950void
951GUILane::drawDirectionIndicators(double exaggeration, bool spreadSuperposed, bool s2) const {
953 glTranslated(0, 0, GLO_EDGE);
954 int e = (int) getShape(s2).size() - 1;
955 const double widthFactor = spreadSuperposed ? 0.4 : 1;
956 const double w = MAX2(POSITION_EPS, myWidth * widthFactor);
957 const double w2 = MAX2(POSITION_EPS, myHalfLaneWidth * widthFactor);
958 const double w4 = MAX2(POSITION_EPS, myQuarterLaneWidth * widthFactor);
959 const double sideOffset = spreadSuperposed ? w * -0.5 : 0;
960 for (int i = 0; i < e; ++i) {
962 glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), 0.1);
963 glRotated(getShapeRotations(s2)[i], 0, 0, 1);
964 for (double t = 0; t < getShapeLengths(s2)[i]; t += w) {
965 const double length = MIN2(w2, getShapeLengths(s2)[i] - t) * exaggeration;
966 glBegin(GL_TRIANGLES);
967 glVertex2d(sideOffset, -t - length);
968 glVertex2d(sideOffset - w4 * exaggeration, -t);
969 glVertex2d(sideOffset + w4 * exaggeration, -t);
970 glEnd();
971 }
973 }
975}
976
977
978void
981 glTranslated(0, 0, 5);
982 glColor3d(1.0, 0.3, 0.3);
983 const double orthoLength = 0.5;
984 const MSLink* link = getLinkCont().front();
985 const std::vector<const MSLane*>& foeLanes = link->getFoeLanes();
986 const auto& conflicts = link->getConflicts();
987 if (foeLanes.size() == conflicts.size()) {
988 for (int i = 0; i < (int)foeLanes.size(); ++i) {
989 const MSLane* l = foeLanes[i];
990 Position pos = l->geometryPositionAtOffset(l->getLength() - conflicts[i].lengthBehindCrossing);
991 PositionVector ortho = l->getShape().getOrthogonal(pos, 10, true, orthoLength);
992 if (ortho.length() < orthoLength) {
993 ortho.extrapolate(orthoLength - ortho.length(), false, true);
994 }
995 GLHelper::drawLine(ortho);
996 //std::cout << "foe=" << l->getID() << " lanePos=" << l->getLength() - conflicts[i].lengthBehindCrossing << " pos=" << pos << "\n";
997 }
998 }
1000}
1001
1002
1003// ------ inherited from GUIGlObject
1006 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
1007 buildPopupHeader(ret, app);
1009 //
1010 GUIDesigns::buildFXMenuCommand(ret, TL("Copy edge name to clipboard"), nullptr, ret, MID_COPY_EDGE_NAME);
1013 //
1014 buildShowParamsPopupEntry(ret, false);
1017 const double height = baseShape.positionAtOffset(pos).z();
1018 GUIDesigns::buildFXMenuCommand(ret, (TL("pos: ") + toString(pos) + " " + TL("height: ") + toString(height)).c_str(), nullptr, nullptr, 0);
1019 if (getEdge().hasDistance()) {
1020 GUIDesigns::buildFXMenuCommand(ret, ("distance: " + toString(getEdge().getDistanceAt(pos))).c_str(), nullptr, nullptr, 0);
1021 }
1022 new FXMenuSeparator(ret);
1023 buildPositionCopyEntry(ret, app);
1024 new FXMenuSeparator(ret);
1025 if (myAmClosed) {
1026 if (myPermissionChanges.empty()) {
1027 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen lane"), nullptr, &parent, MID_CLOSE_LANE);
1028 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen edge"), nullptr, &parent, MID_CLOSE_EDGE);
1029 } else {
1030 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen lane (override rerouter)"), nullptr, &parent, MID_CLOSE_LANE);
1031 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen edge (override rerouter)"), nullptr, &parent, MID_CLOSE_EDGE);
1032 }
1033 } else {
1034 GUIDesigns::buildFXMenuCommand(ret, TL("Close lane"), nullptr, &parent, MID_CLOSE_LANE);
1035 GUIDesigns::buildFXMenuCommand(ret, TL("Close edge"), nullptr, &parent, MID_CLOSE_EDGE);
1036 }
1037 GUIDesigns::buildFXMenuCommand(ret, TL("Add rerouter"), nullptr, &parent, MID_ADD_REROUTER);
1038 new FXMenuSeparator(ret);
1039 // reachability menu
1040 FXMenuPane* reachableByClass = new FXMenuPane(ret);
1041 ret->insertMenuPaneChild(reachableByClass);
1042 new FXMenuCascade(ret, TL("Select reachable"), GUIIconSubSys::getIcon(GUIIcon::FLAG), reachableByClass);
1043 for (auto i : SumoVehicleClassStrings.getStrings()) {
1045 }
1046 return ret;
1047}
1048
1049
1053 GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
1054 // add items
1055 ret->mkItem(TL("allowed speed [m/s]"), false, getSpeedLimit());
1056 const std::map<SUMOVehicleClass, double>* restrictions = MSNet::getInstance()->getRestrictions(myEdge->getEdgeType());
1057 if (restrictions != nullptr) {
1058 for (const auto& elem : *restrictions) {
1059 ret->mkItem((std::string(" ") + TL("allowed speed [m/s]") + std::string(": ") + toString(elem.first)).c_str(), false, elem.second);
1060 }
1061 }
1062 ret->mkItem(TL("length [m]"), false, myLength);
1063 ret->mkItem(TL("width [m]"), false, myWidth);
1064 ret->mkItem(TL("street name"), false, myEdge->getStreetName());
1065 ret->mkItem(TL("stored travel time [s]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getStoredEdgeTravelTime));
1066 ret->mkItem(TL("loaded weight"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getLoadedEdgeWeight));
1067 ret->mkItem(TL("routing speed [m/s]"), true, new FunctionBinding<MSEdge, double>(myEdge, &MSEdge::getRoutingSpeed));
1068 ret->mkItem(TL("lane friction coefficient [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getFrictionCoefficient));
1069 ret->mkItem(TL("time penalty [s]"), true, new FunctionBinding<MSEdge, double>(myEdge, &MSEdge::getTimePenalty));
1070 ret->mkItem(TL("brutto occupancy [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getBruttoOccupancy, 100.));
1071 ret->mkItem(TL("netto occupancy [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getNettoOccupancy, 100.));
1072 ret->mkItem(TL("pending insertions [#]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getPendingEmits));
1073 ret->mkItem(TL("edge type"), false, myEdge->getEdgeType());
1074 ret->mkItem(TL("routing type"), false, myEdge->getRoutingType());
1075 ret->mkItem(TL("type"), false, myLaneType);
1076 ret->mkItem(TL("priority"), false, myEdge->getPriority());
1077 ret->mkItem(TL("distance [km]"), false, myEdge->getDistance() / 1000);
1078 ret->mkItem(TL("allowed vehicle class"), false, StringUtils::wrapText(getVehicleClassNames(myPermissions), 60));
1079 ret->mkItem(TL("disallowed vehicle class"), false, StringUtils::wrapText(getVehicleClassNames(~myPermissions), 60));
1080 ret->mkItem(TL("permission code"), false, myPermissions);
1081 ret->mkItem(TL("color value"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getColorValueForTracker));
1082 if (myBidiLane != nullptr) {
1083 ret->mkItem(TL("bidi-lane"), false, myBidiLane->getID());
1084 }
1085 // info for blocked departDriveWay
1086 for (auto item : getParametersMap()) {
1087 if (StringUtils::startsWith(item.first, "insertionBlocked:")) {
1088 const MSDriveWay* dw = MSDriveWay::retrieveDepartDriveWay(myEdge, item.second);
1089 if (dw != nullptr) {
1090 ret->mkItem(("blocking " + dw->getID()).c_str(), false, toString(MSRailSignal::getBlockingVehicles(dw)));
1091 ret->mkItem(("driveWays blocking " + dw->getID()).c_str(), false, toString(MSRailSignal::getBlockingDriveWays(dw)));
1092 }
1093 }
1094 }
1095
1096 for (const auto& kv : myEdge->getParametersMap()) {
1097 ret->mkItem(("edgeParam:" + kv.first).c_str(), false, kv.second);
1098 }
1100 ret->closeBuilding();
1101 return ret;
1102}
1103
1104
1107 const PositionVector& shape = GUIGlobals::gSecondaryShape && myShape2.size() > 0 ? myShape2 : myShape;
1108 Boundary b;
1109 b.add(shape[0]);
1110 b.add(shape[-1]);
1112 // ensure that vehicles and persons on the side are drawn even if the edge
1113 // is outside the view
1114 return b;
1115}
1116
1117
1118const PositionVector&
1119GUILane::getShape(bool secondary) const {
1120 return secondary && myShape2.size() > 0 ? myShape2 : myShape;
1121}
1122
1123
1124const std::vector<double>&
1125GUILane::getShapeRotations(bool secondary) const {
1126 return secondary && myShapeRotations2.size() > 0 ? myShapeRotations2 : myShapeRotations;
1127}
1128
1129
1130const std::vector<double>&
1131GUILane::getShapeLengths(bool secondary) const {
1132 return secondary && myShapeLengths2.size() > 0 ? myShapeLengths2 : myShapeLengths;
1133}
1134
1135
1136std::vector<RGBColor>&
1137GUILane::getShapeColors(bool secondary) const {
1138 return secondary && myShapeColors2.size() > 0 ? myShapeColors2 : myShapeColors;
1139}
1140
1141
1142double
1144 return myVehicles.size() == 0 ? 0 : myVehicles.back()->getWaitingSeconds();
1145}
1146
1147
1148double
1150 return (double) myEdge->getLanes().size();
1151}
1152
1153
1154double
1157 if (!ews.knowsTravelTime(myEdge)) {
1158 return -1;
1159 } else {
1160 double value(0);
1161 ews.retrieveExistingTravelTime(myEdge, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), value);
1162 return value;
1163 }
1164}
1165
1166
1167double
1170 if (!ews.knowsEffort(myEdge)) {
1171 return -1;
1172 } else {
1173 double value(-1);
1174 ews.retrieveExistingEffort(myEdge, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), value);
1175 return value;
1176 }
1177}
1178
1179
1180double
1182 switch (activeScheme) {
1183 case 18: {
1185 }
1186 default:
1187 return getColorValue(s, activeScheme);
1188 }
1189
1190}
1191
1192
1195 // setting and retrieving the color does not work in OSGView so we return it explicitliy
1196 RGBColor col;
1197 if (MSGlobals::gUseMesoSim && static_cast<const GUIEdge*>(myEdge)->getMesoColor() != MESO_USE_LANE_COLOR) {
1198 col = static_cast<const GUIEdge*>(myEdge)->getMesoColor();
1199 } else {
1200 const GUIColorer& c = s.laneColorer;
1201 if (!setFunctionalColor(c, col) && !setMultiColor(s, c, col)) {
1202 col = c.getScheme().getColor(getColorValue(s, c.getActive()));
1203 }
1204 }
1205 GLHelper::setColor(col);
1206 return col;
1207}
1208
1209
1210bool
1211GUILane::setFunctionalColor(const GUIColorer& c, RGBColor& col, int activeScheme) const {
1212 if (activeScheme < 0) {
1213 activeScheme = c.getActive();
1214 }
1215 switch (activeScheme) {
1216 case 0:
1217 if (myEdge->isCrossing()) {
1218 // determine priority to decide color
1219 const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
1220 if (link->havePriority() || link->getTLLogic() != nullptr) {
1221 col = RGBColor(230, 230, 230);
1222 } else {
1223 col = RGBColor(26, 26, 26);
1224 }
1225 GLHelper::setColor(col);
1226 return true;
1227 } else {
1228 return false;
1229 }
1230 case 18: {
1231 double hue = GeomHelper::naviDegree(myShape.beginEndAngle()); // [0-360]
1232 col = RGBColor::fromHSV(hue, 1., 1.);
1233 GLHelper::setColor(col);
1234 return true;
1235 }
1236 case 30: { // taz color
1237 col = c.getScheme().getColor(0);
1238 std::vector<RGBColor> tazColors;
1239 for (MSEdge* e : myEdge->getPredecessors()) {
1240 if (e->isTazConnector() && e->hasParameter("tazColor")) {
1241 tazColors.push_back(RGBColor::parseColor(e->getParameter("tazColor")));
1242 }
1243 }
1244 for (MSEdge* e : myEdge->getSuccessors()) {
1245 if (e->isTazConnector() && e->hasParameter("tazColor")) {
1246 tazColors.push_back(RGBColor::parseColor(e->getParameter("tazColor")));
1247 }
1248 }
1249 if (tazColors.size() > 0) {
1250 int randColor = RandHelper::rand((int)tazColors.size(), RGBColor::getColorRNG());
1251 col = tazColors[randColor];
1252 }
1253 GLHelper::setColor(col);
1254 return true;
1255 }
1256 default:
1257 return false;
1258 }
1259}
1260
1261
1262bool
1264 const int activeScheme = c.getActive();
1265 auto& shapeColors = getShapeColors(s.secondaryShape);
1266 const PositionVector& shape = getShape(s.secondaryShape);
1267 shapeColors.clear();
1268 switch (activeScheme) {
1269 case 22: // color by height at segment start
1270 for (PositionVector::const_iterator ii = shape.begin(); ii != shape.end() - 1; ++ii) {
1271 shapeColors.push_back(c.getScheme().getColor(ii->z()));
1272 }
1273 // osg fallback (edge height at start)
1274 col = c.getScheme().getColor(getColorValue(s, 21));
1275 return true;
1276 case 24: // color by inclination at segment start
1277 for (int ii = 1; ii < (int)shape.size(); ++ii) {
1278 const double inc = (shape[ii].z() - shape[ii - 1].z()) / MAX2(POSITION_EPS, shape[ii].distanceTo2D(shape[ii - 1]));
1279 shapeColors.push_back(c.getScheme().getColor(inc));
1280 }
1281 col = c.getScheme().getColor(getColorValue(s, 23));
1282 return true;
1283 default:
1284 return false;
1285 }
1286}
1287
1288double
1290 if (myCachedGUISettings != nullptr) {
1292 const GUIColorer& c = s.laneColorer;
1293 double val = getColorValueWithFunctional(s, c.getActive());
1295 // blowing up the dialog or plot isn't helpful. At least 0 may be understood as neutral
1296 return 0;
1297 } else {
1298 return val;
1299 }
1300 } else {
1301 return 0;
1302 }
1303}
1304
1305
1306double
1307GUILane::getColorValue(const GUIVisualizationSettings& s, int activeScheme) const {
1308 switch (activeScheme) {
1309 case 0:
1310 switch (myPermissions) {
1311 case SVC_PEDESTRIAN:
1312 return 1;
1313 case SVC_BICYCLE:
1314 return 2;
1315 case 0:
1316 // forbidden road or green verge
1317 return myEdge->getPermissions() == 0 ? 10 : 3;
1318 case SVC_SHIP:
1319 return 4;
1320 case SVC_AUTHORITY:
1321 return 8;
1322 case SVC_AIRCRAFT:
1323 case SVC_DRONE:
1324 return 11;
1325 default:
1326 break;
1327 }
1328 if (myEdge->isTazConnector()) {
1329 return 9;
1330 } else if (isRailway(myPermissions)) {
1331 return 5;
1332 } else if ((myPermissions & SVC_PASSENGER) != 0) {
1333 if ((myPermissions & (SVC_RAIL_CLASSES & ~SVC_RAIL_FAST)) != 0 && (myPermissions & SVC_SHIP) == 0) {
1334 return 6;
1335 } else {
1336 return 0;
1337 }
1338 } else {
1339 if ((myPermissions & SVC_RAIL_CLASSES) != 0 && (myPermissions & SVC_SHIP) == 0) {
1340 return 6;
1341 } else {
1342 return 7;
1343 }
1344 }
1345 case 1:
1346 return isLaneOrEdgeSelected();
1347 case 2:
1348 return (double)myPermissions;
1349 case 3:
1350 return getSpeedLimit();
1351 case 4:
1352 return getBruttoOccupancy();
1353 case 5:
1354 return getNettoOccupancy();
1355 case 6:
1356 return firstWaitingTime();
1357 case 7:
1358 return getEdgeLaneNumber();
1359 case 8:
1360 return getEmissions<PollutantsInterface::CO2>() / myLength;
1361 case 9:
1362 return getEmissions<PollutantsInterface::CO>() / myLength;
1363 case 10:
1364 return getEmissions<PollutantsInterface::PM_X>() / myLength;
1365 case 11:
1366 return getEmissions<PollutantsInterface::NO_X>() / myLength;
1367 case 12:
1368 return getEmissions<PollutantsInterface::HC>() / myLength;
1369 case 13:
1370 return getEmissions<PollutantsInterface::FUEL>() / myLength;
1371 case 14:
1373 case 15: {
1374 return getStoredEdgeTravelTime();
1375 }
1376 case 16: {
1378 if (!ews.knowsTravelTime(myEdge)) {
1379 return -1;
1380 } else {
1381 double value(0);
1382 ews.retrieveExistingTravelTime(myEdge, 0, value);
1383 return 100 * myLength / value / getSpeedLimit();
1384 }
1385 }
1386 case 17: {
1387 // geometrical length has no meaning for walkingAreas since it describes the outer boundary
1389 }
1390 case 19: {
1391 return getLoadedEdgeWeight();
1392 }
1393 case 20: {
1394 return myEdge->getPriority();
1395 }
1396 case 21: {
1397 // color by z of first shape point
1398 return getShape(s.secondaryShape)[0].z();
1399 }
1400 case 23: {
1401 // color by incline
1402 return (getShape(s.secondaryShape)[-1].z() - getShape(s.secondaryShape)[0].z()) / getLength();
1403 }
1404 case 25: {
1405 // color by average speed
1406 return getMeanSpeed();
1407 }
1408 case 26: {
1409 // color by average relative speed
1410 return getMeanSpeed() / myMaxSpeed;
1411 }
1412 case 27: {
1413 // color by routing device assumed speed
1414 return myEdge->getRoutingSpeed();
1415 }
1416 case 28:
1417 return getEmissions<PollutantsInterface::ELEC>() / myLength;
1418 case 29:
1419 return getPendingEmits();
1420 case 31: {
1421 // by numerical edge param value
1422 if (myEdge->hasParameter(s.edgeParam)) {
1423 try {
1425 } catch (NumberFormatException&) {
1426 try {
1428 } catch (BoolFormatException&) {
1430 }
1431 }
1432 } else {
1434 }
1435 }
1436 case 32: {
1437 // by numerical lane param value
1438 if (hasParameter(s.laneParam)) {
1439 try {
1441 } catch (NumberFormatException&) {
1442 try {
1444 } catch (BoolFormatException&) {
1446 }
1447 }
1448 } else {
1450 }
1451 }
1452 case 33: {
1453 // by edge data value
1455 }
1456 case 34: {
1457 return myEdge->getDistance();
1458 }
1459 case 35: {
1460 return fabs(myEdge->getDistance());
1461 }
1462 case 36: {
1463 return myReachability;
1464 }
1465 case 37: {
1467 }
1468 case 38: {
1469 if (myParkingAreas == nullptr) {
1470 // init
1471 myParkingAreas = new std::vector<MSParkingArea*>();
1473 if (&item.second->getLane().getEdge() == myEdge) {
1474 myParkingAreas->push_back(dynamic_cast<MSParkingArea*>(item.second));
1475 }
1476 }
1477 }
1478 int capacity = 0;
1479 for (MSParkingArea* pa : *myParkingAreas) {
1480 capacity += pa->getCapacity() - pa->getOccupancy();
1481 }
1482 return capacity;
1483 }
1484 case 39: {
1485 // by live edge data value
1487 }
1488 }
1489 return 0;
1490}
1491
1492
1493double
1494GUILane::getScaleValue(const GUIVisualizationSettings& s, int activeScheme, bool s2) const {
1495 switch (activeScheme) {
1496 case 0:
1497 return 0;
1498 case 1:
1499 return isLaneOrEdgeSelected();
1500 case 2:
1501 return getSpeedLimit();
1502 case 3:
1503 return getBruttoOccupancy();
1504 case 4:
1505 return getNettoOccupancy();
1506 case 5:
1507 return firstWaitingTime();
1508 case 6:
1509 return getEdgeLaneNumber();
1510 case 7:
1511 return getEmissions<PollutantsInterface::CO2>() / myLength;
1512 case 8:
1513 return getEmissions<PollutantsInterface::CO>() / myLength;
1514 case 9:
1515 return getEmissions<PollutantsInterface::PM_X>() / myLength;
1516 case 10:
1517 return getEmissions<PollutantsInterface::NO_X>() / myLength;
1518 case 11:
1519 return getEmissions<PollutantsInterface::HC>() / myLength;
1520 case 12:
1521 return getEmissions<PollutantsInterface::FUEL>() / myLength;
1522 case 13:
1524 case 14: {
1525 return getStoredEdgeTravelTime();
1526 }
1527 case 15: {
1529 if (!ews.knowsTravelTime(myEdge)) {
1530 return -1;
1531 } else {
1532 double value(0);
1533 ews.retrieveExistingTravelTime(myEdge, 0, value);
1534 return 100 * myLength / value / getSpeedLimit();
1535 }
1536 }
1537 case 16: {
1538 return 1 / getLengthGeometryFactor(s2);
1539 }
1540 case 17: {
1541 return getLoadedEdgeWeight();
1542 }
1543 case 18: {
1544 return myEdge->getPriority();
1545 }
1546 case 19: {
1547 // scale by average speed
1548 return getMeanSpeed();
1549 }
1550 case 20: {
1551 // scale by average relative speed
1552 return getMeanSpeed() / myMaxSpeed;
1553 }
1554 case 21:
1555 return getEmissions<PollutantsInterface::ELEC>() / myLength;
1556 case 22:
1558 case 23:
1559 // by edge data value
1561 }
1562 return 0;
1563}
1564
1565
1566bool
1570
1571
1572bool
1574 return isWaterway(myPermissions) && s.showRails; // reusing the showRails setting
1575}
1576
1577
1578#ifdef HAVE_OSG
1579void
1580GUILane::updateColor(const GUIVisualizationSettings& s) {
1581 if (myGeom == 0) {
1582 // not drawn
1583 return;
1584 }
1585 const RGBColor col = setColor(s);
1586 osg::Vec4ubArray* colors = dynamic_cast<osg::Vec4ubArray*>(myGeom->getColorArray());
1587 (*colors)[0].set(col.red(), col.green(), col.blue(), col.alpha());
1588 myGeom->setColorArray(colors);
1589}
1590#endif
1591
1592
1593void
1594GUILane::closeTraffic(bool rebuildAllowed) {
1596 if (myAmClosed) {
1597 myPermissionChanges.clear(); // reset rerouters
1599 } else {
1601 }
1603 if (rebuildAllowed) {
1605 }
1606}
1607
1608
1611 assert(MSGlobals::gUseMesoSim);
1612 int no = MELoop::numSegmentsFor(myLength, OptionsCont::getOptions().getFloat("meso-edgelength"));
1613 const double slength = myLength / no;
1614 PositionVector result = shape;
1615 double offset = 0;
1616 for (int i = 0; i < no; ++i) {
1617 offset += slength;
1618 Position pos = shape.positionAtOffset(offset);
1619 int index = result.indexOfClosest(pos);
1620 if (pos.distanceTo(result[index]) > POSITION_EPS) {
1621 index = result.insertAtClosest(pos, false);
1622 }
1623 if (i != no - 1) {
1624 mySegmentStartIndex.push_back(index);
1625 }
1626 while ((int)myShapeSegments.size() < index) {
1627 myShapeSegments.push_back(i);
1628 }
1629 //std::cout << "splitAtSegments " << getID() << " no=" << no << " i=" << i << " offset=" << offset << " index=" << index << " segs=" << toString(myShapeSegments) << " resultSize=" << result.size() << " result=" << toString(result) << "\n";
1630 }
1631 while (myShapeSegments.size() < result.size()) {
1632 myShapeSegments.push_back(no - 1);
1633 }
1634 return result;
1635}
1636
1637bool
1641
1642bool
1644 return isSelected() || gSelected.isSelected(GLO_EDGE, dynamic_cast<GUIEdge*>(myEdge)->getGlID());
1645}
1646
1647double
1651
1652double
1655 // do not select lanes in meso mode
1656 return INVALID_PRIORITY;
1657 }
1658 if (myEdge->isCrossing()) {
1659 return GLO_CROSSING;
1660 }
1661 return GLO_LANE;
1662}
1663
1664
1665/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
@ MID_COPY_EDGE_NAME
Copy edge name (for lanes only)
Definition GUIAppEnum.h:461
@ MID_REACHABILITY
show reachability from a given lane
Definition GUIAppEnum.h:533
@ MID_CLOSE_LANE
close lane
Definition GUIAppEnum.h:669
@ MID_CLOSE_EDGE
close edge
Definition GUIAppEnum.h:671
@ MID_ADD_REROUTER
add rerouter
Definition GUIAppEnum.h:673
@ 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:65
#define RAD2DEG(x)
Definition GeomHelper.h:36
#define TL(string)
Definition MsgHandler.h:304
#define STEPS2TIME(x)
Definition SUMOTime.h:55
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a (exclusive) 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:52
T MIN2(T a, T b)
Definition StdDefs.h:80
const double SUMO_const_laneMarkWidth
Definition StdDefs.h:55
T MAX2(T a, T b)
Definition StdDefs.h:86
const double SUMO_const_halfLaneWidth
Definition StdDefs.h:53
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:75
Boundary & grow(double by)
extends the boundary by the given amount
Definition Boundary.cpp:340
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition GLHelper.cpp:433
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition GLHelper.cpp:649
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:624
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:824
static void pushName(unsigned int name)
push Name
Definition GLHelper.cpp:140
static void drawFilledCircle(const double widradiusth, const int steps=8)
Draws a filled circle around (0,0)
Definition GLHelper.cpp:564
static void popMatrix()
pop matrix
Definition GLHelper.cpp:131
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:348
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition GLHelper.cpp:296
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:939
static void popName()
pop Name
Definition GLHelper.cpp:149
static void pushMatrix()
push matrix
Definition GLHelper.cpp:118
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:886
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:843
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
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:584
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:74
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, const GUIMainWindow &app, bool addSeparator=true) const
Builds an entry which allows to copy the cursor position if geo projection is used,...
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.
void buildSelectionPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to (de)select the object.
GUIGlID getGlID() const
Returns the numerical id of the object.
static bool gSecondaryShape
whether secondary shapes are currently being drawn
Definition GUIGlobals.h:49
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:1573
void debugDrawFoeIntersections() const
draw intersection positions of foe internal lanes with this one
Definition GUILane.cpp:979
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:161
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:1643
void initRotations(const PositionVector &shape, std::vector< double > &rotations, std::vector< double > &lengths, std::vector< RGBColor > &colors)
Definition GUILane.cpp:121
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:1610
std::vector< int > myShapeSegments
the meso segment index for each geometry segment
Definition GUILane.h:363
double firstWaitingTime() const
Definition GUILane.cpp:1143
double setPartialOccupation(MSVehicle *v) override
Sets the information about a vehicle lapping into this lane.
Definition GUILane.cpp:229
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:271
RGBColor setColor(const GUIVisualizationSettings &s) const
sets the color according to the currente settings
Definition GUILane.cpp:1194
double getPendingEmits() const
get number of vehicles waiting for departure on this lane
Definition GUILane.cpp:1648
void setJunctionApproaches() const override
Definition GUILane.cpp:180
void drawLinkNo(const GUIVisualizationSettings &s) const
helper methods
Definition GUILane.cpp:244
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own popup-menu.
Definition GUILane.cpp:1005
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:886
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:194
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:1263
void addSecondaryShape(const PositionVector &shape) override
Definition GUILane.cpp:142
double getScaleValue(const GUIVisualizationSettings &s, int activeScheme, bool s2) const
gets the scaling value according to the current scheme index
Definition GUILane.cpp:1494
void resetPartialOccupation(MSVehicle *v) override
Removes the information about a vehicle lapping into this lane.
Definition GUILane.cpp:236
void integrateNewVehicles() override
Definition GUILane.cpp:215
void drawGL(const GUIVisualizationSettings &s) const override
Draws the object.
Definition GUILane.cpp:539
void drawArrows(bool secondaryShape) const
Definition GUILane.cpp:445
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:310
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:821
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const override
gets the color value according to the current scheme index
Definition GUILane.cpp:1307
void closeTraffic(bool rebuildAllowed=true)
close this lane for traffic
Definition GUILane.cpp:1594
double getClickPriority() const override
Returns the priority of receiving mouse clicks.
Definition GUILane.cpp:1653
bool isSelected() const override
whether this lane is selected in the GUI
Definition GUILane.cpp:1638
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own parameter window.
Definition GUILane.cpp:1051
const std::vector< double > & getShapeRotations(bool secondary) const
Definition GUILane.cpp:1125
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:1181
bool drawAsRailway(const GUIVisualizationSettings &s) const
whether to draw this lane as a railway
Definition GUILane.cpp:1567
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:80
void removeParking(MSBaseVehicle *veh) override
remove parking vehicle
Definition GUILane.cpp:201
std::vector< double > myShapeRotations2
Definition GUILane.h:352
double myLengthGeometryFactor2
Definition GUILane.h:391
void planMovements(const SUMOTime t) override
Definition GUILane.cpp:174
double getColorValueForTracker() const
return color value based on cached settings
Definition GUILane.cpp:1289
std::vector< RGBColor > myShapeColors2
Definition GUILane.h:360
double getEdgeLaneNumber() const
Definition GUILane.cpp:1149
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:1168
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 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:151
~GUILane()
Destructor.
Definition GUILane.cpp:110
const PositionVector & getShape(bool secondary) const override
Definition GUILane.cpp:1119
void drawLinkRule(const GUIVisualizationSettings &s, const GUINet &net, const MSLink *link, const PositionVector &shape, double x1, double x2) const
Definition GUILane.cpp:365
Boundary getCenteringBoundary() const override
Returns the boundary to which the view shall be centered in order to show the object.
Definition GUILane.cpp:1106
std::vector< RGBColor > & getShapeColors(bool secondary) const
Definition GUILane.cpp:1137
bool setFunctionalColor(const GUIColorer &c, RGBColor &col, int activeScheme=-1) const
Definition GUILane.cpp:1211
double getStoredEdgeTravelTime() const
Returns the stored traveltime for the edge of this lane.
Definition GUILane.cpp:1155
const std::vector< double > & getShapeLengths(bool secondary) const
Definition GUILane.cpp:1131
void drawMarkings(const GUIVisualizationSettings &s, double scale) const
draw lane borders and white markings
Definition GUILane.cpp:834
void drawBikeMarkings() const
bike lane markings on top of an intersection
Definition GUILane.cpp:857
void executeMovements(const SUMOTime t) override
Definition GUILane.cpp:187
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:512
void releaseVehicles() const override
Allows to use the container for microsimulation again.
Definition GUILane.cpp:168
void drawDirectionIndicators(double exaggeration, bool spreadSuperposed, bool s2) const
direction indicators for lanes
Definition GUILane.cpp:951
void detectCollisions(SUMOTime timestep, const std::string &stage) override
Definition GUILane.cpp:222
void swapAfterLaneChange(SUMOTime t) override
moves myTmpVehicles int myVehicles after a lane change procedure
Definition GUILane.cpp:208
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:631
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:581
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:614
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 gaming
whether the application is in gaming mode or not
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 crossings 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)
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:293
The base class for microscopic and mesoscopic vehicles.
static const MSDriveWay * retrieveDepartDriveWay(const MSEdge *edge, const std::string &id)
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:336
SVCPermissions getPermissions() const
Returns the combined permissions of all lanes of this edge.
Definition MSEdge.h:657
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
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition MSEdge.h:168
const MSEdge * getBidiEdge() const
return opposite superposable/congruent edge, if it exist and 0 else
Definition MSEdge.h:282
const MSJunction * getToJunction() const
Definition MSEdge.h:426
bool isTazConnector() const
Definition MSEdge.h:291
const std::string & getRoutingType() const
Returns the type of the edge.
Definition MSEdge.h:325
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:494
const std::string & getEdgeType() const
Returns the type of the edge.
Definition MSEdge.h:319
const MSEdgeVector & getPredecessors() const
Definition MSEdge.h:417
double getRoutingSpeed() const
Returns the averaged speed used by the routing device.
Definition MSEdge.cpp:1051
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition MSEdge.cpp:1268
void rebuildAllowedLanes(const bool onInit=false, bool updateVehicles=false)
Definition MSEdge.cpp:325
double getDistance() const
Returns the kilometrage/mileage encoding at the start of the edge (negative values encode descending ...
Definition MSEdge.h:343
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:106
static bool gCheckRoutes
Definition MSGlobals.h:91
static double gLateralResolution
Definition MSGlobals.h:100
static int gNumSimThreads
how many threads to use for simulation
Definition MSGlobals.h:146
static bool gLefthand
Whether lefthand-drive is being simulated.
Definition MSGlobals.h:174
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition MSGlobals.h:81
int getPendingEmits(const MSLane *lane)
return the number of pending emits for the given lane
SumoXMLNodeType getType() const
return the type of this Junction
Definition MSJunction.h:133
const PositionVector & getShape() const
Returns this junction's shape.
Definition MSJunction.h:91
Representation of a lane in the micro simulation.
Definition MSLane.h:84
SVCPermissions myPermissions
The vClass permissions for this lane.
Definition MSLane.h:1536
std::set< const MSBaseVehicle * > myParkingVehicles
Definition MSLane.h:1508
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:2851
virtual void removeParking(MSBaseVehicle *veh)
remove parking vehicle. This must be syncrhonized when running with GUI
Definition MSLane.cpp:3690
virtual void integrateNewVehicles()
Insert buffered vehicle into the real lane.
Definition MSLane.cpp:2567
double myLength
Lane length [m].
Definition MSLane.h:1511
double getNettoOccupancy() const
Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps)
Definition MSLane.cpp:3412
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition MSLane.cpp:2833
PositionVector myShape
The shape of the lane.
Definition MSLane.h:1456
PositionVector * myOutlineShape
the outline of the lane (optional)
Definition MSLane.h:1459
std::map< long long, SVCPermissions > myPermissionChanges
Definition MSLane.h:1616
double getFrictionCoefficient() const
Returns the lane's friction coefficient.
Definition MSLane.h:604
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:455
const MSLane * getNormalSuccessorLane() const
get normal lane following this internal lane, for normal lanes, the lane itself is returned
Definition MSLane.cpp:3252
MSEdge *const myEdge
The lane's edge, for routing only.
Definition MSLane.h:1522
bool allowsChangingRight(SUMOVehicleClass vclass) const
Returns whether the given vehicle class may change left from this lane.
Definition MSLane.h:942
double myMaxSpeed
Lane-wide speed limit [m/s].
Definition MSLane.h:1525
const MSLink * getLinkTo(const MSLane *const) const
returns the link to the given lane or nullptr, if it is not connected
Definition MSLane.cpp:2746
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:1557
VehCont myVehicles
The lane's vehicles. This container holds all vehicles that have their front (longitudinally) and the...
Definition MSLane.h:1475
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition MSLane.h:597
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition MSLane.h:119
MSLane * myBidiLane
Definition MSLane.h:1613
bool isWalkingArea() const
Definition MSLane.cpp:2638
SVCPermissions getPermissions() const
Returns the vehicle class permissions for this lane.
Definition MSLane.h:619
void resetPermissions(long long transientID)
Definition MSLane.cpp:4535
const std::string myLaneType
the type of this lane
Definition MSLane.h:1599
int myRNGIndex
Definition MSLane.h:1619
double getLength() const
Returns the lane's length.
Definition MSLane.h:611
const PositionVector & getShape() const
Returns this lane's shape.
Definition MSLane.h:533
virtual void swapAfterLaneChange(SUMOTime t)
moves myTmpVehicles int myVehicles after a lane change procedure
Definition MSLane.cpp:2816
StopOffset myLaneStopOffset
Definition MSLane.h:1519
virtual double setPartialOccupation(MSVehicle *v)
Sets the information about a vehicle lapping into this lane.
Definition MSLane.cpp:384
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:4523
const double myWidth
Lane width [m].
Definition MSLane.h:1514
virtual void executeMovements(const SUMOTime t)
Executes planned vehicle movements with regards to right-of-way.
Definition MSLane.cpp:2280
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition MSLane.cpp:3217
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition MSLane.cpp:3397
int myIndex
The lane index.
Definition MSLane.h:1462
bool isCrossing() const
Definition MSLane.cpp:2633
virtual void detectCollisions(SUMOTime timestep, const std::string &stage)
Check if vehicles are too close.
Definition MSLane.cpp:1658
std::vector< MSLink * > myLinks
Definition MSLane.h:1577
bool isInternal() const
Definition MSLane.cpp:2621
static const long CHANGE_PERMISSIONS_GUI
Definition MSLane.h:1380
VehCont myPartialVehicles
The lane's partial vehicles. This container holds all vehicles that are partially on this lane but wh...
Definition MSLane.h:1487
double interpolateGeometryPosToLanePos(double geometryPos) const
Definition MSLane.h:566
virtual void resetPartialOccupation(MSVehicle *v)
Removes the information about a vehicle lapping into this lane.
Definition MSLane.cpp:403
double getHarmonoise_NoiseEmissions() const
Returns the sum of last step noise emissions.
Definition MSLane.cpp:3486
virtual void setJunctionApproaches() const
Register junction approaches for all vehicles after velocities have been planned.
Definition MSLane.cpp:1597
MSLane * getBidiLane() const
retrieve bidirectional lane or nullptr
Definition MSLane.cpp:4680
double getLengthGeometryFactor() const
return shape.length() / myLength
Definition MSLane.h:538
virtual const PositionVector & getShape(bool) const
Definition MSLane.h:294
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:769
const MSLane * getNormalPredecessorLane() const
get normal lane leading to this internal lane, for normal lanes, the lane itself is returned
Definition MSLane.cpp:3242
double getWidth() const
Returns the lane's width.
Definition MSLane.h:640
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
Definition MSLane.h:729
double getMeanSpeed() const
Returns the mean speed on this lane.
Definition MSLane.cpp:3440
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition MSLane.h:560
Notification
Definition of a vehicle state.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:186
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:354
MSEdgeWeightsStorage & getWeightsStorage()
Returns the net's internal edge travel times/efforts container.
Definition MSNet.cpp:1273
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition MSNet.h:445
const NamedObjectCont< MSStoppingPlace * > & getStoppingPlaces(SumoXMLTag category) const
Definition MSNet.cpp:1488
A lane area vehicles can halt at.
VehicleVector getBlockingVehicles(int linkIndex) override
return vehicles that block the intersection/rail signal for vehicles that wish to pass the given link...
std::vector< const MSDriveWay * > getBlockingDriveWays(int linkIndex) override
return vehicles that approach the intersection/rail signal and have priority over vehicles that wish ...
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.
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:273
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimensions
Definition Position.h:263
double x() const
Returns the x-position.
Definition Position.h:52
double z() const
Returns the z-position.
Definition Position.h:62
double y() const
Returns the y-position.
Definition Position.h:57
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:190
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:403
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:193
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
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 startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
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
static FXIcon * getVClassIcon(const SUMOVehicleClass vc)
returns icon associated to the given vClass
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