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