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
453 if (myLinks.size() == 0) {
454 return;
455 }
456 const RGBColor laneCol = color.isValid() ? color : setColor(s);
457 // draw all links
458 const Position& end = getShape(s.secondaryShape).back();
459 const Position& f = getShape(s.secondaryShape)[-2];
460 const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
463 glTranslated(end.x(), end.y(), 0);
464 glRotated(rot, 0, 0, 1);
466 glScaled(myWidth / SUMO_const_laneWidth, 1, 1);
467 }
468 for (const MSLink* const link : myLinks) {
469 LinkDirection dir = link->getDirection();
470 LinkState state = link->getState();
471 if (state == LINKSTATE_DEADEND || dir == LinkDirection::NODIR) {
472 continue;
473 }
474 switch (dir) {
476 GLHelper::drawBoxLine(Position(0, 4), 0, 2, .05);
477 GLHelper::drawTriangleAtEnd(Position(0, 4), Position(0, 1), (double) 1, (double) .25);
478 break;
480 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
481 GLHelper::drawBoxLine(Position(0, 2.5), 90, .5, .05);
482 GLHelper::drawBoxLine(Position(0.5, 2.5), 180, 1, .05);
483 GLHelper::drawTriangleAtEnd(Position(0.5, 2.5), Position(0.5, 4), (double) 1, (double) .25);
484 break;
486 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
487 GLHelper::drawBoxLine(Position(0, 2.5), -90, .5, .05);
488 GLHelper::drawBoxLine(Position(-0.5, 2.5), -180, 1, .05);
489 GLHelper::drawTriangleAtEnd(Position(-0.5, 2.5), Position(-0.5, 4), (double) 1, (double) .25);
490 break;
492 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
493 GLHelper::drawBoxLine(Position(0, 2.5), 90, 1, .05);
494 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.5, 2.5), (double) 1, (double) .25);
495 break;
497 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
498 GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
499 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.5, 2.5), (double) 1, (double) .25);
500 break;
502 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
503 GLHelper::drawBoxLine(Position(0, 2.5), 45, .7, .05);
504 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.2, 1.3), (double) 1, (double) .25);
505 break;
507 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
508 GLHelper::drawBoxLine(Position(0, 2.5), -45, .7, .05);
509 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.2, 1.3), (double) 1, (double) .25);
510 break;
511 default:
512 break;
513 }
514 }
516}
517
518
519void
520GUILane::drawLane2LaneConnections(double exaggeration, bool s2) const {
521 Position centroid;
522 if (exaggeration > 1) {
523 centroid = myEdge->getToJunction()->getShape().getCentroid();
524 }
525 for (const MSLink* const link : myLinks) {
526 const GUILane* connected = dynamic_cast<GUILane*>(link->getLane());
527 if (connected == nullptr) {
528 continue;
529 }
531 glBegin(GL_LINES);
532 Position p1 = myEdge->isWalkingArea() ? getShape(s2).getCentroid() : getShape(s2)[-1];
533 Position p2 = connected->isWalkingArea() ? connected->getShape(s2).getCentroid() : connected->getShape(s2)[0];
534 if (exaggeration > 1) {
535 p1 = centroid + ((p1 - centroid) * exaggeration);
536 p2 = centroid + ((p2 - centroid) * exaggeration);
537 }
538 glVertex2d(p1.x(), p1.y());
539 glVertex2d(p2.x(), p2.y());
540 glEnd();
541 GLHelper::drawTriangleAtEnd(p1, p2, (double) .4, (double) .2);
542 }
543}
544
545
546void
550 const bool s2 = s.secondaryShape;
551 double exaggeration = s.laneWidthExaggeration;
553 GUIEdge* myGUIEdge = dynamic_cast<GUIEdge*>(myEdge);
554 exaggeration *= s.edgeScaler.getScheme().getColor(myGUIEdge->getScaleValue(s, s.edgeScaler.getActive()));
555 } else {
556 exaggeration *= s.laneScaler.getScheme().getColor(getScaleValue(s, s.laneScaler.getActive(), s2));
557 }
558 // set lane color
559 const RGBColor color = setColor(s);
560 // recognize full transparency and simply don't draw
561 if (color.alpha() != 0 && s.scale * exaggeration > s.laneMinSize) {
562
563 const bool isCrossing = myEdge->isCrossing();
564 const bool isWalkingArea = myEdge->isWalkingArea();
566 const PositionVector& baseShape = getShape(s2);
567 const bool hasRailSignal = myEdge->getToJunction()->getType() == SumoXMLNodeType::RAIL_SIGNAL;
568 if (s.trueZ) {
569 glTranslated(0, 0, baseShape.getMinZ());
570 } else {
571 if (isCrossing) {
572 // draw internal lanes on top of junctions
573 glTranslated(0, 0, GLO_JUNCTION + 0.1);
574 } else if (isWalkingArea) {
575 // draw internal lanes on top of junctions
576 glTranslated(0, 0, GLO_JUNCTION + 0.3);
577 } else if (isWaterway(myPermissions)) {
578 // draw waterways below normal roads
579 glTranslated(0, 0, getType() - 0.2);
580 } else if (myPermissions == SVC_SUBWAY) {
581 // draw subways further below
582 glTranslated(0, 0, getType() - 0.4);
583 } else {
584 glTranslated(0, 0, getType());
585 }
586 }
587 auto& shapeColors = getShapeColors(s2);
589 shapeColors.clear();
590 const std::vector<RGBColor>& segmentColors = static_cast<const GUIEdge*>(myEdge)->getSegmentColors();
591 if (segmentColors.size() > 0) {
592 // apply segment specific shape colors
593 //std::cout << getID() << " shape=" << myShape << " shapeSegs=" << toString(myShapeSegments) << "\n";
594 for (int ii = 0; ii < (int)baseShape.size() - 1; ++ii) {
595 shapeColors.push_back(segmentColors[myShapeSegments[ii]]);
596 }
597 }
598 }
599
600 // scale tls-controlled lane2lane-arrows along with their junction shapes
601 double junctionExaggeration = 1;
602 if (!isInternal
605 junctionExaggeration = MAX2(1.001, s.junctionSize.getExaggeration(s, this, 4));
606 }
607 // draw lane
608 // check whether it is not too small
609 if (s.scale * exaggeration < 1. && junctionExaggeration == 1 && s.junctionSize.minSize != 0) {
610 if (!isInternal || hasRailSignal) {
611 if (shapeColors.size() > 0) {
612 GLHelper::drawLine(baseShape, shapeColors);
613 } else {
614 GLHelper::drawLine(baseShape);
615 }
616 }
618
619 } else {
620
621 GUINet* net = (GUINet*) MSNet::getInstance();
622 bool mustDrawMarkings = false;
623 bool hiddenBidi = getBidiLane() != nullptr && myEdge->getNumericalID() > myEdge->getBidiEdge()->getNumericalID();
624 const bool detailZoom = s.scale * exaggeration > 5;
625 const bool drawDetails = (detailZoom || s.junctionSize.minSize == 0 || hasRailSignal);
626 const bool drawRails = drawAsRailway(s);
627 const bool spreadSuperposed = s.spreadSuperposed && myBidiLane != nullptr;
628 if (hiddenBidi && !spreadSuperposed) {
629 // do not draw shape
630 mustDrawMarkings = !isInternal && myPermissions != 0 && myPermissions != SVC_PEDESTRIAN && exaggeration == 1.0 && !isWaterway(myPermissions) && neighLaneNotBidi();
631 } else if (drawRails) {
632 // draw as railway: assume standard gauge of 1435mm when lane width is not set
633 // draw foot width 150mm, assume that distance between rail feet inner sides is reduced on both sides by 39mm with regard to the gauge
634 // assume crosstie length of 181% gauge (2600mm for standard gauge)
635 PositionVector shape = baseShape;
636 const double width = myWidth;
637 double halfGauge = 0.5 * (width == SUMO_const_laneWidth ? 1.4350 : width) * exaggeration;
638 if (spreadSuperposed) {
639 try {
640 shape.move2side(halfGauge * 0.8);
641 } catch (InvalidArgument&) {}
642 halfGauge *= 0.4;
643 }
644 const double halfInnerFeetWidth = halfGauge - 0.039 * exaggeration;
645 const double halfRailWidth = detailZoom ? (halfInnerFeetWidth + 0.15 * exaggeration) : SUMO_const_halfLaneWidth * exaggeration;
646 const double halfCrossTieWidth = halfGauge * 1.81;
647 if (shapeColors.size() > 0) {
648 GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), getShapeColors(s2), halfRailWidth);
649 } else {
650 GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), halfRailWidth);
651 }
652 // Draw white on top with reduced width (the area between the two tracks)
653 if (detailZoom) {
654 glColor3d(1, 1, 1);
655 glTranslated(0, 0, .1);
656 GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), halfInnerFeetWidth);
657 setColor(s);
658 GLHelper::drawCrossTies(shape, getShapeRotations(s2), getShapeLengths(s2), 0.26 * exaggeration, 0.6 * exaggeration,
659 halfCrossTieWidth, 0, s.forceDrawForRectangleSelection);
660 }
661 } else if (isCrossing) {
662 if (s.drawCrossingsAndWalkingareas && (s.scale > 3.0 || s.junctionSize.minSize == 0)) {
663 glTranslated(0, 0, .2);
664 GLHelper::drawCrossTies(baseShape, getShapeRotations(s2), getShapeLengths(s2), 0.5, 1.0, getWidth() * 0.5,
666#ifdef GUILane_DEBUG_DRAW_CROSSING_OUTLINE
667 if (myOutlineShape != nullptr) {
669 glTranslated(0, 0, 0.4);
671 glTranslated(0, 0, -0.4);
672 if (s.geometryIndices.show(this)) {
674 }
675 }
676#endif
677 glTranslated(0, 0, -.2);
678 }
679 } else if (isWalkingArea) {
680 if (s.drawCrossingsAndWalkingareas && (s.scale > 3.0 || s.junctionSize.minSize == 0)) {
681 glTranslated(0, 0, .2);
682 if (myTesselation == nullptr) {
684 }
685 myTesselation->drawTesselation(baseShape);
686 glTranslated(0, 0, -.2);
687 if (s.geometryIndices.show(this)) {
689 }
690 }
691 } else {
692 // we draw the lanes with reduced width so that the lane markings below are visible
693 // (this avoids artifacts at geometry corners without having to
694 // compute lane-marking intersection points)
696 mustDrawMarkings = !isInternal && myPermissions != 0 && myPermissions != SVC_PEDESTRIAN && exaggeration == 1.0 && !isWaterway(myPermissions) && !isAirway(myPermissions);
697 const int cornerDetail = drawDetails && !isInternal ? (s.drawForRectangleSelection ? 4 : MIN2(32, (int)(s.scale * exaggeration))) : 0;
698 double offset = halfWidth * MAX2(0., (exaggeration - 1)) * (MSGlobals::gLefthand ? -1 : 1);
699 if (spreadSuperposed) {
700 offset += halfWidth * 0.5 * (MSGlobals::gLefthand ? -1 : 1);
701 halfWidth *= 0.4; // create visible gap
702 }
703 if (shapeColors.size() > 0) {
704 GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), shapeColors, halfWidth * exaggeration, cornerDetail, offset);
705 } else {
706 GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), halfWidth * exaggeration, cornerDetail, offset);
707 }
708 }
710#ifdef GUILane_DEBUG_DRAW_FOE_INTERSECTIONS
713 }
714#endif
715 if (s.geometryIndices.show(this)) {
717 }
718 // draw details
719 if ((!isInternal || isCrossing || !s.drawJunctionShape) && (drawDetails || junctionExaggeration > 1)) {
721 glTranslated(0, 0, GLO_JUNCTION); // must draw on top of junction shape
722 glTranslated(0, 0, .5);
723 if (drawDetails) {
724 if (s.showLaneDirection) {
725 if (drawRails) {
726 // improve visibility of superposed rail edges
727 GLHelper::setColor(setColor(s).changedBrightness(100));
728 } else {
729 glColor3d(0.3, 0.3, 0.3);
730 }
732 drawDirectionIndicators(exaggeration, spreadSuperposed, s.secondaryShape);
733 }
734 }
735 if (!isInternal || isCrossing
736 // controlled internal junction
737 || (getLinkCont().size() != 0 && getLinkCont()[0]->isInternalJunctionLink() && getLinkCont()[0]->getTLLogic() != nullptr)) {
738 if (MSGlobals::gLateralResolution > 0 && s.showSublanes && !hiddenBidi && (myPermissions & ~(SVC_PEDESTRIAN | SVC_RAIL_CLASSES)) != 0) {
739 // draw sublane-borders
740 const double offsetSign = MSGlobals::gLefthand ? -1 : 1;
742 for (double offset = -myHalfLaneWidth; offset < myHalfLaneWidth; offset += MSGlobals::gLateralResolution) {
743 GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), 0.01, 0, -offset * offsetSign);
744 }
745 }
747 // draw segment borders
749 for (int i : mySegmentStartIndex) {
750 if (shapeColors.size() > 0) {
751 GLHelper::setColor(shapeColors[i].changedBrightness(51));
752 }
753 GLHelper::drawBoxLine(baseShape[i], getShapeRotations(s2)[i] + 90, myWidth / 3, 0.2, 0);
754 GLHelper::drawBoxLine(baseShape[i], getShapeRotations(s2)[i] - 90, myWidth / 3, 0.2, 0);
755 }
756 }
757 if (s.showLinkDecals && !drawRails && !drawAsWaterway(s) && myPermissions != SVC_PEDESTRIAN) {
758 drawArrows(s, color);
759 }
760 glTranslated(0, 0, 1000);
761 if (s.drawLinkJunctionIndex.show(nullptr)) {
762 drawLinkNo(s);
763 }
764 if (s.drawLinkTLIndex.show(nullptr)) {
765 drawTLSLinkNo(s, *net);
766 }
767 glTranslated(0, 0, -1000);
768 }
769 glTranslated(0, 0, .1);
770 }
771 if ((drawDetails || junctionExaggeration > 1) && s.showLane2Lane) {
772 // draw from end of first to the begin of second but respect junction scaling
773 drawLane2LaneConnections(junctionExaggeration, s.secondaryShape);
774 }
776 // make sure link rules are drawn so tls can be selected via right-click
777 if (s.showLinkRules && drawDetails && !isWalkingArea &&
778 (!myEdge->isInternal() || (getLinkCont().size() > 0 && getLinkCont()[0]->isInternalJunctionLink()))) {
780 glTranslated(0, 0, GLO_SHAPE); // must draw on top of junction shape and additionals
781 drawLinkRules(s, *net);
783 }
784 }
785 if (mustDrawMarkings && drawDetails && s.laneShowBorders) { // needs matrix reset
786 drawMarkings(s, exaggeration, color);
787 }
788 if (drawDetails && isInternal && s.showBikeMarkings && myPermissions == SVC_BICYCLE && exaggeration == 1.0 && s.showLinkDecals && s.laneShowBorders && !hiddenBidi
791 drawBikeMarkings(color);
792 }
793 if (drawDetails && isInternal && exaggeration == 1.0 && s.showLinkDecals && s.laneShowBorders && !hiddenBidi && myIndex > 0
794 && !(myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER) && allowsChangingRight(SVC_PASSENGER))) {
795 // draw lane changing prohibitions on junction
797 }
798 }
799 } else {
801 }
802 // draw vehicles
803 if (s.scale * s.vehicleSize.getExaggeration(s, nullptr) > s.vehicleSize.minSize) {
804 // retrieve vehicles from lane; disallow simulation
805 const MSLane::VehCont& vehicles = getVehiclesSecure();
806 for (MSLane::VehCont::const_iterator v = vehicles.begin(); v != vehicles.end(); ++v) {
807 if ((*v)->getLane() == this) {
808 static_cast<const GUIVehicle*>(*v)->drawGL(s);
809 } // else: this is the shadow during a continuous lane change
810 }
811 // draw long partial vehicles (#14342)
812 // must prevent concurrent access via MSVehicle::cleanupFurtherLanes to avoid crash (#18271)
813 myPartialOccupatorMutex.lock();
814 for (const MSVehicle* veh : myPartialVehicles) {
815 if (veh->getLength() > RENDERING_BUFFER) {
816 // potential double rendering taken into account
817 static_cast<const GUIVehicle*>(veh)->drawGL(s);
818 }
819 }
820 myPartialOccupatorMutex.unlock();
821 // draw parking vehicles
822 for (const MSBaseVehicle* const v : myParkingVehicles) {
823 dynamic_cast<const GUIBaseVehicle*>(v)->drawGL(s);
824 }
825 // allow lane simulation
827 }
829}
830
831bool
833 const MSLane* right = getParallelLane(-1, false);
834 if (right && right->getBidiLane() == nullptr) {
835 return true;
836 }
837 const MSLane* left = getParallelLane(1, false);
838 if (left && left->getBidiLane() == nullptr) {
839 return true;
840 }
841 return false;
842}
843
844void
845GUILane::drawMarkings(const GUIVisualizationSettings& s, double scale, const RGBColor& color) const {
847 glTranslated(0, 0, GLO_EDGE);
848 setColor(s);
849 // optionally draw inverse markings
850 const bool s2 = s.secondaryShape;
851 if (myIndex > 0 && (myEdge->getLanes()[myIndex - 1]->getPermissions() & myPermissions) != 0) {
852 const bool cl = myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER);
853 const bool cr = allowsChangingRight(SVC_PASSENGER);
855 }
856 // draw boundings and markings
857 const RGBColor laneCol = color.isValid() ? color : setColor(s);
860 getShape(s2),
862 getShapeLengths(s2),
865}
866
867
868void
870 // draw bike lane markings onto the intersection
873 const bool s2 = false;
874 const int e = (int) getShape(s2).size() - 1;
875 const double markWidth = 0.1;
876 const double mw = myHalfLaneWidth;
877 for (int i = 0; i < e; ++i) {
879 glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), GLO_JUNCTION + 0.4);
880 glRotated(getShapeRotations(s2)[i], 0, 0, 1);
881 for (double t = 0; t < getShapeLengths(s2)[i]; t += 0.5) {
882 // left and right marking
883 for (int side = -1; side <= 1; side += 2) {
884 glBegin(GL_QUADS);
885 glVertex2d(side * mw, -t);
886 glVertex2d(side * mw, -t - 0.35);
887 glVertex2d(side * (mw + markWidth), -t - 0.35);
888 glVertex2d(side * (mw + markWidth), -t);
889 glEnd();
890 }
891 }
893 }
894}
895
896
897void
899 // fixme
900 const bool s2 = false;
901 // draw markings
902 if (myIndex > 0 && (myEdge->getLanes()[myIndex - 1]->getPermissions() & myPermissions) != 0) {
904 const bool cl = myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER);
905 const bool cr = allowsChangingRight(SVC_PASSENGER);
906 // solid line marking
907 double mw, mw2;
908 // optional broken line marking
909 double mw3, mw4;
910 if (!cl && !cr) {
911 // draw a single solid line
914 mw3 = myHalfLaneWidth;
915 mw4 = myHalfLaneWidth;
916 } else {
917 // draw one solid and one broken line
918 if (cl) {
923 } else {
928 }
929 }
931 mw *= -1;
932 mw2 *= -1;
933 }
934 int e = (int) getShape(s2).size() - 1;
935 for (int i = 0; i < e; ++i) {
937 glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), GLO_JUNCTION + 0.4);
938 glRotated(getShapeRotations(s2)[i], 0, 0, 1);
939 for (double t = 0; t < getShapeLengths(s2)[i]; t += 6) {
940 const double lengthSolid = MIN2(6.0, getShapeLengths(s2)[i] - t);
941 glBegin(GL_QUADS);
942 glVertex2d(-mw, -t);
943 glVertex2d(-mw, -t - lengthSolid);
944 glVertex2d(-mw2, -t - lengthSolid);
945 glVertex2d(-mw2, -t);
946 glEnd();
947 if (cl || cr) {
948 const double lengthBroken = MIN2(3.0, getShapeLengths(s2)[i] - t);
949 glBegin(GL_QUADS);
950 glVertex2d(-mw3, -t);
951 glVertex2d(-mw3, -t - lengthBroken);
952 glVertex2d(-mw4, -t - lengthBroken);
953 glVertex2d(-mw4, -t);
954 glEnd();
955 }
956 }
958 }
959 }
960}
961
962void
963GUILane::drawDirectionIndicators(double exaggeration, bool spreadSuperposed, bool s2) const {
965 glTranslated(0, 0, GLO_EDGE);
966 int e = (int) getShape(s2).size() - 1;
967 const double widthFactor = spreadSuperposed ? 0.4 : 1;
968 const double w = MAX2(POSITION_EPS, myWidth * widthFactor);
969 const double w2 = MAX2(POSITION_EPS, myHalfLaneWidth * widthFactor);
970 const double w4 = MAX2(POSITION_EPS, myQuarterLaneWidth * widthFactor);
971 const double sideOffset = spreadSuperposed ? w * -0.5 : 0;
972 for (int i = 0; i < e; ++i) {
974 glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), 0.1);
975 glRotated(getShapeRotations(s2)[i], 0, 0, 1);
976 for (double t = 0; t < getShapeLengths(s2)[i]; t += w) {
977 const double length = MIN2(w2, getShapeLengths(s2)[i] - t) * exaggeration;
978 glBegin(GL_TRIANGLES);
979 glVertex2d(sideOffset, -t - length);
980 glVertex2d(sideOffset - w4 * exaggeration, -t);
981 glVertex2d(sideOffset + w4 * exaggeration, -t);
982 glEnd();
983 }
985 }
987}
988
989
990void
993 glTranslated(0, 0, 5);
994 glColor3d(1.0, 0.3, 0.3);
995 const double orthoLength = 0.5;
996 const MSLink* link = getLinkCont().front();
997 const std::vector<const MSLane*>& foeLanes = link->getFoeLanes();
998 const auto& conflicts = link->getConflicts();
999 if (foeLanes.size() == conflicts.size()) {
1000 for (int i = 0; i < (int)foeLanes.size(); ++i) {
1001 const MSLane* l = foeLanes[i];
1002 Position pos = l->geometryPositionAtOffset(l->getLength() - conflicts[i].lengthBehindCrossing);
1003 PositionVector ortho = l->getShape().getOrthogonal(pos, 10, true, orthoLength);
1004 if (ortho.length() < orthoLength) {
1005 ortho.extrapolate(orthoLength - ortho.length(), false, true);
1006 }
1007 GLHelper::drawLine(ortho);
1008 //std::cout << "foe=" << l->getID() << " lanePos=" << l->getLength() - conflicts[i].lengthBehindCrossing << " pos=" << pos << "\n";
1009 }
1010 }
1012}
1013
1014
1015// ------ inherited from GUIGlObject
1018 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
1019 buildPopupHeader(ret, app);
1021 //
1022 GUIDesigns::buildFXMenuCommand(ret, TL("Copy edge name to clipboard"), nullptr, ret, MID_COPY_EDGE_NAME);
1025 //
1026 buildShowParamsPopupEntry(ret, false);
1029 const double height = baseShape.positionAtOffset(pos).z();
1030 GUIDesigns::buildFXMenuCommand(ret, (TL("pos: ") + toString(pos) + " " + TL("height: ") + toString(height)).c_str(), nullptr, nullptr, 0);
1031 if (getEdge().hasDistance()) {
1032 GUIDesigns::buildFXMenuCommand(ret, ("distance: " + toString(getEdge().getDistanceAt(pos))).c_str(), nullptr, nullptr, 0);
1033 }
1034 new FXMenuSeparator(ret);
1035 buildPositionCopyEntry(ret, app);
1036 new FXMenuSeparator(ret);
1037 if (myAmClosed) {
1038 if (myPermissionChanges.empty()) {
1039 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen lane"), nullptr, &parent, MID_CLOSE_LANE);
1040 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen edge"), nullptr, &parent, MID_CLOSE_EDGE);
1041 } else {
1042 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen lane (override rerouter)"), nullptr, &parent, MID_CLOSE_LANE);
1043 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen edge (override rerouter)"), nullptr, &parent, MID_CLOSE_EDGE);
1044 }
1045 } else {
1046 GUIDesigns::buildFXMenuCommand(ret, TL("Close lane"), nullptr, &parent, MID_CLOSE_LANE);
1047 GUIDesigns::buildFXMenuCommand(ret, TL("Close edge"), nullptr, &parent, MID_CLOSE_EDGE);
1048 }
1049 GUIDesigns::buildFXMenuCommand(ret, TL("Add rerouter"), nullptr, &parent, MID_ADD_REROUTER);
1050 new FXMenuSeparator(ret);
1051 // reachability menu
1052 FXMenuPane* reachableByClass = new FXMenuPane(ret);
1053 ret->insertMenuPaneChild(reachableByClass);
1054 new FXMenuCascade(ret, TL("Select reachable"), GUIIconSubSys::getIcon(GUIIcon::FLAG), reachableByClass);
1055 for (auto i : SumoVehicleClassStrings.getStrings()) {
1057 }
1058 return ret;
1059}
1060
1061
1065 GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
1066 // add items
1067 ret->mkItem(TL("allowed speed [m/s]"), false, getSpeedLimit());
1068 const std::map<SUMOVehicleClass, double>* restrictions = MSNet::getInstance()->getRestrictions(myEdge->getEdgeType());
1069 if (restrictions != nullptr) {
1070 for (const auto& elem : *restrictions) {
1071 ret->mkItem((std::string(" ") + TL("allowed speed [m/s]") + std::string(": ") + toString(elem.first)).c_str(), false, elem.second);
1072 }
1073 }
1074 ret->mkItem(TL("length [m]"), false, myLength);
1075 ret->mkItem(TL("width [m]"), false, myWidth);
1076 ret->mkItem(TL("street name"), false, myEdge->getStreetName());
1077 ret->mkItem(TL("stored travel time [s]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getStoredEdgeTravelTime));
1078 ret->mkItem(TL("loaded weight"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getLoadedEdgeWeight));
1079 ret->mkItem(TL("routing speed [m/s]"), true, new FunctionBinding<MSEdge, double>(myEdge, &MSEdge::getRoutingSpeed));
1080 ret->mkItem(TL("lane friction coefficient [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getFrictionCoefficient));
1081 ret->mkItem(TL("time penalty [s]"), true, new FunctionBinding<MSEdge, double>(myEdge, &MSEdge::getTimePenalty));
1082 ret->mkItem(TL("brutto occupancy [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getBruttoOccupancy, 100.));
1083 ret->mkItem(TL("netto occupancy [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getNettoOccupancy, 100.));
1084 ret->mkItem(TL("pending insertions [#]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getPendingEmits));
1085 ret->mkItem(TL("edge type"), false, myEdge->getEdgeType());
1086 ret->mkItem(TL("routing type"), false, myEdge->getRoutingType());
1087 ret->mkItem(TL("type"), false, myLaneType);
1088 ret->mkItem(TL("priority"), false, myEdge->getPriority());
1089 ret->mkItem(TL("distance [km]"), false, myEdge->getDistance() / 1000);
1090 ret->mkItem(TL("allowed vehicle class"), false, StringUtils::wrapText(getVehicleClassNames(myPermissions), 60));
1091 ret->mkItem(TL("disallowed vehicle class"), false, StringUtils::wrapText(getVehicleClassNames(~myPermissions), 60));
1092 ret->mkItem(TL("permission code"), false, myPermissions);
1093 ret->mkItem(TL("color value"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getColorValueForTracker));
1094 if (myBidiLane != nullptr) {
1095 ret->mkItem(TL("bidi-lane"), false, myBidiLane->getID());
1096 }
1097 // info for blocked departDriveWay
1098 for (auto item : getParametersMap()) {
1099 if (StringUtils::startsWith(item.first, "insertionBlocked:")) {
1100 const MSDriveWay* dw = MSDriveWay::retrieveDepartDriveWay(myEdge, item.second);
1101 if (dw != nullptr) {
1102 ret->mkItem(("blocking " + dw->getID()).c_str(), false, toString(MSRailSignal::getBlockingVehicles(dw)));
1103 ret->mkItem(("driveWays blocking " + dw->getID()).c_str(), false, toString(MSRailSignal::getBlockingDriveWays(dw)));
1104 }
1105 }
1106 }
1107
1108 for (const auto& kv : myEdge->getParametersMap()) {
1109 ret->mkItem(("edgeParam:" + kv.first).c_str(), false, kv.second);
1110 }
1112 ret->closeBuilding();
1113 return ret;
1114}
1115
1116
1119 const PositionVector& shape = GUIGlobals::gSecondaryShape && myShape2.size() > 0 ? myShape2 : myShape;
1120 Boundary b;
1121 b.add(shape[0]);
1122 b.add(shape[-1]);
1124 // ensure that vehicles and persons on the side are drawn even if the edge
1125 // is outside the view
1126 return b;
1127}
1128
1129
1130const PositionVector&
1131GUILane::getShape(bool secondary) const {
1132 return secondary && myShape2.size() > 0 ? myShape2 : myShape;
1133}
1134
1135
1136const std::vector<double>&
1137GUILane::getShapeRotations(bool secondary) const {
1138 return secondary && myShapeRotations2.size() > 0 ? myShapeRotations2 : myShapeRotations;
1139}
1140
1141
1142const std::vector<double>&
1143GUILane::getShapeLengths(bool secondary) const {
1144 return secondary && myShapeLengths2.size() > 0 ? myShapeLengths2 : myShapeLengths;
1145}
1146
1147
1148std::vector<RGBColor>&
1149GUILane::getShapeColors(bool secondary) const {
1150 return secondary && myShapeColors2.size() > 0 ? myShapeColors2 : myShapeColors;
1151}
1152
1153
1154double
1156 return myVehicles.size() == 0 ? 0 : myVehicles.back()->getWaitingSeconds();
1157}
1158
1159
1160double
1162 return (double) myEdge->getLanes().size();
1163}
1164
1165
1166double
1169 if (!ews.knowsTravelTime(myEdge)) {
1170 return -1;
1171 } else {
1172 double value(0);
1173 ews.retrieveExistingTravelTime(myEdge, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), value);
1174 return value;
1175 }
1176}
1177
1178
1179double
1182 if (!ews.knowsEffort(myEdge)) {
1183 return -1;
1184 } else {
1185 double value(-1);
1186 ews.retrieveExistingEffort(myEdge, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), value);
1187 return value;
1188 }
1189}
1190
1191
1192double
1194 switch (activeScheme) {
1195 case 18: {
1197 }
1198 default:
1199 return getColorValue(s, activeScheme);
1200 }
1201
1202}
1203
1204
1207 // setting and retrieving the color does not work in OSGView so we return it explicitliy
1208 RGBColor col;
1209 if (MSGlobals::gUseMesoSim && static_cast<const GUIEdge*>(myEdge)->getMesoColor() != MESO_USE_LANE_COLOR) {
1210 col = static_cast<const GUIEdge*>(myEdge)->getMesoColor();
1211 } else {
1212 const GUIColorer& c = s.laneColorer;
1213 if (!setFunctionalColor(c, col) && !setMultiColor(s, c, col)) {
1214 col = c.getScheme().getColor(getColorValue(s, c.getActive()));
1215 }
1216 }
1217 GLHelper::setColor(col);
1218 return col;
1219}
1220
1221
1222bool
1223GUILane::setFunctionalColor(const GUIColorer& c, RGBColor& col, int activeScheme) const {
1224 if (activeScheme < 0) {
1225 activeScheme = c.getActive();
1226 }
1227 switch (activeScheme) {
1228 case 0:
1229 if (myEdge->isCrossing()) {
1230 // determine priority to decide color
1231 const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
1232 if (link->havePriority() || link->getTLLogic() != nullptr) {
1233 col = RGBColor(230, 230, 230);
1234 } else {
1235 col = RGBColor(26, 26, 26);
1236 }
1237 GLHelper::setColor(col);
1238 return true;
1239 } else {
1240 return false;
1241 }
1242 case 18: {
1243 double hue = GeomHelper::naviDegree(myShape.beginEndAngle()); // [0-360]
1244 col = RGBColor::fromHSV(hue, 1., 1.);
1245 GLHelper::setColor(col);
1246 return true;
1247 }
1248 case 30: { // taz color
1249 col = c.getScheme().getColor(0);
1250 std::vector<RGBColor> tazColors;
1251 for (MSEdge* e : myEdge->getPredecessors()) {
1252 if (e->isTazConnector() && e->hasParameter("tazColor")) {
1253 tazColors.push_back(RGBColor::parseColor(e->getParameter("tazColor")));
1254 }
1255 }
1256 for (MSEdge* e : myEdge->getSuccessors()) {
1257 if (e->isTazConnector() && e->hasParameter("tazColor")) {
1258 tazColors.push_back(RGBColor::parseColor(e->getParameter("tazColor")));
1259 }
1260 }
1261 if (tazColors.size() > 0) {
1262 int randColor = RandHelper::rand((int)tazColors.size(), RGBColor::getColorRNG());
1263 col = tazColors[randColor];
1264 }
1265 GLHelper::setColor(col);
1266 return true;
1267 }
1268 default:
1269 return false;
1270 }
1271}
1272
1273
1274bool
1276 const int activeScheme = c.getActive();
1277 auto& shapeColors = getShapeColors(s.secondaryShape);
1278 const PositionVector& shape = getShape(s.secondaryShape);
1279 shapeColors.clear();
1280 switch (activeScheme) {
1281 case 22: // color by height at segment start
1282 for (PositionVector::const_iterator ii = shape.begin(); ii != shape.end() - 1; ++ii) {
1283 shapeColors.push_back(c.getScheme().getColor(ii->z()));
1284 }
1285 // osg fallback (edge height at start)
1286 col = c.getScheme().getColor(getColorValue(s, 21));
1287 return true;
1288 case 24: // color by inclination at segment start
1289 for (int ii = 1; ii < (int)shape.size(); ++ii) {
1290 const double inc = (shape[ii].z() - shape[ii - 1].z()) / MAX2(POSITION_EPS, shape[ii].distanceTo2D(shape[ii - 1]));
1291 shapeColors.push_back(c.getScheme().getColor(inc));
1292 }
1293 col = c.getScheme().getColor(getColorValue(s, 23));
1294 return true;
1295 default:
1296 return false;
1297 }
1298}
1299
1300double
1302 if (myCachedGUISettings != nullptr) {
1304 const GUIColorer& c = s.laneColorer;
1305 double val = getColorValueWithFunctional(s, c.getActive());
1307 // blowing up the dialog or plot isn't helpful. At least 0 may be understood as neutral
1308 return 0;
1309 } else {
1310 return val;
1311 }
1312 } else {
1313 return 0;
1314 }
1315}
1316
1317
1318double
1319GUILane::getColorValue(const GUIVisualizationSettings& s, int activeScheme) const {
1320 switch (activeScheme) {
1321 case 0:
1322 switch (myPermissions) {
1323 case SVC_PEDESTRIAN:
1324 return 1;
1325 case SVC_BICYCLE:
1326 return 2;
1327 case 0:
1328 // forbidden road or green verge
1329 return myEdge->getPermissions() == 0 ? 10 : 3;
1330 case SVC_SHIP:
1331 return 4;
1332 case SVC_AUTHORITY:
1333 return 8;
1334 case SVC_AIRCRAFT:
1335 case SVC_DRONE:
1336 return 11;
1337 default:
1338 break;
1339 }
1340 if (myEdge->isTazConnector()) {
1341 return 9;
1342 } else if (isRailway(myPermissions)) {
1343 return 5;
1344 } else if ((myPermissions & SVC_PASSENGER) != 0) {
1345 if ((myPermissions & (SVC_RAIL_CLASSES & ~SVC_RAIL_FAST)) != 0 && (myPermissions & SVC_SHIP) == 0) {
1346 return 6;
1347 } else {
1348 return 0;
1349 }
1350 } else {
1351 if ((myPermissions & SVC_RAIL_CLASSES) != 0 && (myPermissions & SVC_SHIP) == 0) {
1352 return 6;
1353 } else {
1354 return 7;
1355 }
1356 }
1357 case 1:
1358 return isLaneOrEdgeSelected();
1359 case 2:
1360 return (double)myPermissions;
1361 case 3:
1362 return getSpeedLimit();
1363 case 4:
1364 return getBruttoOccupancy();
1365 case 5:
1366 return getNettoOccupancy();
1367 case 6:
1368 return firstWaitingTime();
1369 case 7:
1370 return getEdgeLaneNumber();
1371 case 8:
1372 return getEmissions<PollutantsInterface::CO2>() / myLength;
1373 case 9:
1374 return getEmissions<PollutantsInterface::CO>() / myLength;
1375 case 10:
1376 return getEmissions<PollutantsInterface::PM_X>() / myLength;
1377 case 11:
1378 return getEmissions<PollutantsInterface::NO_X>() / myLength;
1379 case 12:
1380 return getEmissions<PollutantsInterface::HC>() / myLength;
1381 case 13:
1382 return getEmissions<PollutantsInterface::FUEL>() / myLength;
1383 case 14:
1385 case 15: {
1386 return getStoredEdgeTravelTime();
1387 }
1388 case 16: {
1390 if (!ews.knowsTravelTime(myEdge)) {
1391 return -1;
1392 } else {
1393 double value(0);
1394 ews.retrieveExistingTravelTime(myEdge, 0, value);
1395 return 100 * myLength / value / getSpeedLimit();
1396 }
1397 }
1398 case 17: {
1399 // geometrical length has no meaning for walkingAreas since it describes the outer boundary
1401 }
1402 case 19: {
1403 return getLoadedEdgeWeight();
1404 }
1405 case 20: {
1406 return myEdge->getPriority();
1407 }
1408 case 21: {
1409 // color by z of first shape point
1410 return getShape(s.secondaryShape)[0].z();
1411 }
1412 case 23: {
1413 // color by incline
1414 return (getShape(s.secondaryShape)[-1].z() - getShape(s.secondaryShape)[0].z()) / getLength();
1415 }
1416 case 25: {
1417 // color by average speed
1418 return getMeanSpeed();
1419 }
1420 case 26: {
1421 // color by average relative speed
1422 return getMeanSpeed() / myMaxSpeed;
1423 }
1424 case 27: {
1425 // color by routing device assumed speed
1426 return myEdge->getRoutingSpeed();
1427 }
1428 case 28:
1429 return getEmissions<PollutantsInterface::ELEC>() / myLength;
1430 case 29:
1431 return getPendingEmits();
1432 case 31: {
1433 // by numerical edge param value
1434 if (myEdge->hasParameter(s.edgeParam)) {
1435 try {
1437 } catch (NumberFormatException&) {
1438 try {
1440 } catch (BoolFormatException&) {
1442 }
1443 }
1444 } else {
1446 }
1447 }
1448 case 32: {
1449 // by numerical lane param value
1450 if (hasParameter(s.laneParam)) {
1451 try {
1453 } catch (NumberFormatException&) {
1454 try {
1456 } catch (BoolFormatException&) {
1458 }
1459 }
1460 } else {
1462 }
1463 }
1464 case 33: {
1465 // by edge data value
1467 }
1468 case 34: {
1469 return myEdge->getDistance();
1470 }
1471 case 35: {
1472 return fabs(myEdge->getDistance());
1473 }
1474 case 36: {
1475 return myReachability;
1476 }
1477 case 37: {
1479 }
1480 case 38: {
1481 if (myParkingAreas == nullptr) {
1482 // init
1483 myParkingAreas = new std::vector<MSParkingArea*>();
1485 if (&item.second->getLane().getEdge() == myEdge) {
1486 myParkingAreas->push_back(dynamic_cast<MSParkingArea*>(item.second));
1487 }
1488 }
1489 }
1490 int capacity = 0;
1491 for (MSParkingArea* pa : *myParkingAreas) {
1492 capacity += pa->getCapacity() - pa->getOccupancy();
1493 }
1494 return capacity;
1495 }
1496 case 39: {
1497 // by live edge data value
1499 }
1500 }
1501 return 0;
1502}
1503
1504
1505double
1506GUILane::getScaleValue(const GUIVisualizationSettings& s, int activeScheme, bool s2) const {
1507 switch (activeScheme) {
1508 case 0:
1509 return 0;
1510 case 1:
1511 return isLaneOrEdgeSelected();
1512 case 2:
1513 return getSpeedLimit();
1514 case 3:
1515 return getBruttoOccupancy();
1516 case 4:
1517 return getNettoOccupancy();
1518 case 5:
1519 return firstWaitingTime();
1520 case 6:
1521 return getEdgeLaneNumber();
1522 case 7:
1523 return getEmissions<PollutantsInterface::CO2>() / myLength;
1524 case 8:
1525 return getEmissions<PollutantsInterface::CO>() / myLength;
1526 case 9:
1527 return getEmissions<PollutantsInterface::PM_X>() / myLength;
1528 case 10:
1529 return getEmissions<PollutantsInterface::NO_X>() / myLength;
1530 case 11:
1531 return getEmissions<PollutantsInterface::HC>() / myLength;
1532 case 12:
1533 return getEmissions<PollutantsInterface::FUEL>() / myLength;
1534 case 13:
1536 case 14: {
1537 return getStoredEdgeTravelTime();
1538 }
1539 case 15: {
1541 if (!ews.knowsTravelTime(myEdge)) {
1542 return -1;
1543 } else {
1544 double value(0);
1545 ews.retrieveExistingTravelTime(myEdge, 0, value);
1546 return 100 * myLength / value / getSpeedLimit();
1547 }
1548 }
1549 case 16: {
1550 return 1 / getLengthGeometryFactor(s2);
1551 }
1552 case 17: {
1553 return getLoadedEdgeWeight();
1554 }
1555 case 18: {
1556 return myEdge->getPriority();
1557 }
1558 case 19: {
1559 // scale by average speed
1560 return getMeanSpeed();
1561 }
1562 case 20: {
1563 // scale by average relative speed
1564 return getMeanSpeed() / myMaxSpeed;
1565 }
1566 case 21:
1567 return getEmissions<PollutantsInterface::ELEC>() / myLength;
1568 case 22:
1570 case 23:
1571 // by edge data value
1573 }
1574 return 0;
1575}
1576
1577
1578bool
1582
1583
1584bool
1586 return isWaterway(myPermissions) && s.showRails; // reusing the showRails setting
1587}
1588
1589
1590#ifdef HAVE_OSG
1591void
1592GUILane::updateColor(const GUIVisualizationSettings& s) {
1593 if (myGeom == 0) {
1594 // not drawn
1595 return;
1596 }
1597 const RGBColor col = setColor(s);
1598 osg::Vec4ubArray* colors = dynamic_cast<osg::Vec4ubArray*>(myGeom->getColorArray());
1599 (*colors)[0].set(col.red(), col.green(), col.blue(), col.alpha());
1600 myGeom->setColorArray(colors);
1601}
1602#endif
1603
1604
1605void
1606GUILane::closeTraffic(bool rebuildAllowed) {
1608 if (myAmClosed) {
1609 myPermissionChanges.clear(); // reset rerouters
1611 } else {
1613 }
1615 if (rebuildAllowed) {
1617 }
1618}
1619
1620
1623 assert(MSGlobals::gUseMesoSim);
1624 const MESegment::MesoEdgeType& edgeType = MSNet::getInstance()->getMesoType(getEdge().getEdgeType());
1625 int no = MELoop::numSegmentsFor(myLength, edgeType.edgeLength);
1626 const double slength = myLength / no;
1627 PositionVector result = shape;
1628 double offset = 0;
1629 for (int i = 0; i < no; ++i) {
1630 offset += slength;
1632 int index = result.indexOfClosest(pos);
1633 if (pos.distanceTo(result[index]) > POSITION_EPS) {
1634 index = result.insertAtClosest(pos, false);
1635 }
1636 if (i != no - 1) {
1637 mySegmentStartIndex.push_back(index);
1638 }
1639 while ((int)myShapeSegments.size() < index) {
1640 myShapeSegments.push_back(i);
1641 }
1642 //std::cout << "splitAtSegments " << getID() << " no=" << no << " i=" << i << " offset=" << offset << " index=" << index << " segs=" << toString(myShapeSegments) << " resultSize=" << result.size() << " result=" << toString(result) << "\n";
1643 }
1644 while (myShapeSegments.size() < result.size()) {
1645 myShapeSegments.push_back(no - 1);
1646 }
1647 return result;
1648}
1649
1650bool
1654
1655bool
1657 return isSelected() || gSelected.isSelected(GLO_EDGE, dynamic_cast<GUIEdge*>(myEdge)->getGlID());
1658}
1659
1660double
1664
1665double
1668 // do not select lanes in meso mode
1669 return INVALID_PRIORITY;
1670 }
1671 if (myEdge->isCrossing()) {
1672 return GLO_CROSSING;
1673 }
1674 return GLO_LANE;
1675}
1676
1677
1678/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
@ MID_COPY_EDGE_NAME
Copy edge name (for lanes only)
Definition GUIAppEnum.h:465
@ MID_REACHABILITY
show reachability from a given lane
Definition GUIAppEnum.h:541
@ MID_CLOSE_LANE
close lane
Definition GUIAppEnum.h:677
@ MID_CLOSE_EDGE
close edge
Definition GUIAppEnum.h:679
@ MID_ADD_REROUTER
add rerouter
Definition GUIAppEnum.h:681
@ 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:1585
void debugDrawFoeIntersections() const
draw intersection positions of foe internal lanes with this one
Definition GUILane.cpp:991
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
void drawJunctionChangeProhibitions(const RGBColor &color=RGBColor(false)) const
lane change prohibitions on top of an intersection
Definition GUILane.cpp:898
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:1656
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:1622
std::vector< int > myShapeSegments
the meso segment index for each geometry segment
Definition GUILane.h:365
double firstWaitingTime() const
Definition GUILane.cpp:1155
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:1206
double getPendingEmits() const
get number of vehicles waiting for departure on this lane
Definition GUILane.cpp:1661
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:1017
void drawBikeMarkings(const RGBColor &color=RGBColor(false)) const
bike lane markings on top of an intersection
Definition GUILane.cpp:869
static GUIVisualizationSettings * myCachedGUISettings
cached for tracking color value
Definition GUILane.h:396
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:1275
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:1506
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:547
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:832
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const override
gets the color value according to the current scheme index
Definition GUILane.cpp:1319
void drawMarkings(const GUIVisualizationSettings &s, double scale, const RGBColor &color=RGBColor(false)) const
draw lane borders and markings
Definition GUILane.cpp:845
void closeTraffic(bool rebuildAllowed=true)
close this lane for traffic
Definition GUILane.cpp:1606
double getClickPriority() const override
Returns the priority of receiving mouse clicks.
Definition GUILane.cpp:1666
bool isSelected() const override
whether this lane is selected in the GUI
Definition GUILane.cpp:1651
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own parameter window.
Definition GUILane.cpp:1063
const std::vector< double > & getShapeRotations(bool secondary) const
Definition GUILane.cpp:1137
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:1193
bool drawAsRailway(const GUIVisualizationSettings &s) const
whether to draw this lane as a railway
Definition GUILane.cpp:1579
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:1301
void drawArrows(const GUIVisualizationSettings &s, const RGBColor &color=RGBColor(false)) const
Definition GUILane.cpp:452
std::vector< RGBColor > myShapeColors2
Definition GUILane.h:362
double getEdgeLaneNumber() const
Definition GUILane.cpp:1161
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:1180
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:1131
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:1118
std::vector< RGBColor > & getShapeColors(bool secondary) const
Definition GUILane.cpp:1149
bool setFunctionalColor(const GUIColorer &c, RGBColor &col, int activeScheme=-1) const
Definition GUILane.cpp:1223
double getStoredEdgeTravelTime() const
Returns the stored traveltime for the edge of this lane.
Definition GUILane.cpp:1167
const std::vector< double > & getShapeLengths(bool secondary) const
Definition GUILane.cpp:1143
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:520
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:963
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:344
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:1099
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition MSEdge.cpp:1323
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:4607
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:4595
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 predecessor lane (sorted using by_connections_to_sorter). The result is cached in...
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:4752
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:201
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:382
MSEdgeWeightsStorage & getWeightsStorage()
Returns the net's internal edge travel times/efforts container.
Definition MSNet.cpp:1334
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:440
const NamedObjectCont< MSStoppingPlace * > & getStoppingPlaces(SumoXMLTag category) const
Definition MSNet.cpp:1572
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
static const RGBColor WHITE
Definition RGBColor.h:211
unsigned char red() const
Returns the red-amount of the color.
Definition RGBColor.cpp:78
static const RGBColor BLUE
Definition RGBColor.h:206
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition RGBColor.cpp:96
static SumoRNG * getColorRNG()
get color RNG
Definition RGBColor.cpp:222
static RGBColor parseColor(std::string coldef)
Parses a color information.
Definition RGBColor.cpp:267
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:431
unsigned char green() const
Returns the green-amount of the color.
Definition RGBColor.cpp:84
bool isValid() const
check if RGBColor is valid
Definition RGBColor.cpp:124
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:228
static const RGBColor MAGENTA
Definition RGBColor.h:209
RGBColor getContrastingColor() const
return a contrasting color for markings/arrows (darkened if bright, white if dark)
Definition RGBColor.cpp:210
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