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