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 ? -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 for (const MSVehicle* veh : myPartialVehicles) {
812 if (veh->getLength() > RENDERING_BUFFER) {
813 // potential double rendering taken into account
814 static_cast<const GUIVehicle*>(veh)->drawGL(s);
815 }
816 }
817 // draw parking vehicles
818 for (const MSBaseVehicle* const v : myParkingVehicles) {
819 dynamic_cast<const GUIBaseVehicle*>(v)->drawGL(s);
820 }
821 // allow lane simulation
823 }
825}
826
827bool
829 const MSLane* right = getParallelLane(-1, false);
830 if (right && right->getBidiLane() == nullptr) {
831 return true;
832 }
833 const MSLane* left = getParallelLane(1, false);
834 if (left && left->getBidiLane() == nullptr) {
835 return true;
836 }
837 return false;
838}
839
840void
841GUILane::drawMarkings(const GUIVisualizationSettings& s, double scale) const {
843 glTranslated(0, 0, GLO_EDGE);
844 setColor(s);
845 // optionally draw inverse markings
846 const bool s2 = s.secondaryShape;
847 if (myIndex > 0 && (myEdge->getLanes()[myIndex - 1]->getPermissions() & myPermissions) != 0) {
848 const bool cl = myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER);
849 const bool cr = allowsChangingRight(SVC_PASSENGER);
851 }
852 // draw white boundings and white markings
853 glColor3d(1, 1, 1);
855 getShape(s2),
857 getShapeLengths(s2),
860}
861
862
863void
865 // draw bike lane markings onto the intersection
866 glColor3d(1, 1, 1);
868 const bool s2 = false;
869 const int e = (int) getShape(s2).size() - 1;
870 const double markWidth = 0.1;
871 const double mw = myHalfLaneWidth;
872 for (int i = 0; i < e; ++i) {
874 glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), GLO_JUNCTION + 0.4);
875 glRotated(getShapeRotations(s2)[i], 0, 0, 1);
876 for (double t = 0; t < getShapeLengths(s2)[i]; t += 0.5) {
877 // left and right marking
878 for (int side = -1; side <= 1; side += 2) {
879 glBegin(GL_QUADS);
880 glVertex2d(side * mw, -t);
881 glVertex2d(side * mw, -t - 0.35);
882 glVertex2d(side * (mw + markWidth), -t - 0.35);
883 glVertex2d(side * (mw + markWidth), -t);
884 glEnd();
885 }
886 }
888 }
889}
890
891
892void
894 // fixme
895 const bool s2 = false;
896 // draw white markings
897 if (myIndex > 0 && (myEdge->getLanes()[myIndex - 1]->getPermissions() & myPermissions) != 0) {
898 glColor3d(1, 1, 1);
899 const bool cl = myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER);
900 const bool cr = allowsChangingRight(SVC_PASSENGER);
901 // solid line marking
902 double mw, mw2;
903 // optional broken line marking
904 double mw3, mw4;
905 if (!cl && !cr) {
906 // draw a single solid line
909 mw3 = myHalfLaneWidth;
910 mw4 = myHalfLaneWidth;
911 } else {
912 // draw one solid and one broken line
913 if (cl) {
918 } else {
923 }
924 }
926 mw *= -1;
927 mw2 *= -1;
928 }
929 int e = (int) getShape(s2).size() - 1;
930 for (int i = 0; i < e; ++i) {
932 glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), GLO_JUNCTION + 0.4);
933 glRotated(getShapeRotations(s2)[i], 0, 0, 1);
934 for (double t = 0; t < getShapeLengths(s2)[i]; t += 6) {
935 const double lengthSolid = MIN2(6.0, getShapeLengths(s2)[i] - t);
936 glBegin(GL_QUADS);
937 glVertex2d(-mw, -t);
938 glVertex2d(-mw, -t - lengthSolid);
939 glVertex2d(-mw2, -t - lengthSolid);
940 glVertex2d(-mw2, -t);
941 glEnd();
942 if (cl || cr) {
943 const double lengthBroken = MIN2(3.0, getShapeLengths(s2)[i] - t);
944 glBegin(GL_QUADS);
945 glVertex2d(-mw3, -t);
946 glVertex2d(-mw3, -t - lengthBroken);
947 glVertex2d(-mw4, -t - lengthBroken);
948 glVertex2d(-mw4, -t);
949 glEnd();
950 }
951 }
953 }
954 }
955}
956
957void
958GUILane::drawDirectionIndicators(double exaggeration, bool spreadSuperposed, bool s2) const {
960 glTranslated(0, 0, GLO_EDGE);
961 int e = (int) getShape(s2).size() - 1;
962 const double widthFactor = spreadSuperposed ? 0.4 : 1;
963 const double w = MAX2(POSITION_EPS, myWidth * widthFactor);
964 const double w2 = MAX2(POSITION_EPS, myHalfLaneWidth * widthFactor);
965 const double w4 = MAX2(POSITION_EPS, myQuarterLaneWidth * widthFactor);
966 const double sideOffset = spreadSuperposed ? w * -0.5 : 0;
967 for (int i = 0; i < e; ++i) {
969 glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), 0.1);
970 glRotated(getShapeRotations(s2)[i], 0, 0, 1);
971 for (double t = 0; t < getShapeLengths(s2)[i]; t += w) {
972 const double length = MIN2(w2, getShapeLengths(s2)[i] - t) * exaggeration;
973 glBegin(GL_TRIANGLES);
974 glVertex2d(sideOffset, -t - length);
975 glVertex2d(sideOffset - w4 * exaggeration, -t);
976 glVertex2d(sideOffset + w4 * exaggeration, -t);
977 glEnd();
978 }
980 }
982}
983
984
985void
988 glTranslated(0, 0, 5);
989 glColor3d(1.0, 0.3, 0.3);
990 const double orthoLength = 0.5;
991 const MSLink* link = getLinkCont().front();
992 const std::vector<const MSLane*>& foeLanes = link->getFoeLanes();
993 const auto& conflicts = link->getConflicts();
994 if (foeLanes.size() == conflicts.size()) {
995 for (int i = 0; i < (int)foeLanes.size(); ++i) {
996 const MSLane* l = foeLanes[i];
997 Position pos = l->geometryPositionAtOffset(l->getLength() - conflicts[i].lengthBehindCrossing);
998 PositionVector ortho = l->getShape().getOrthogonal(pos, 10, true, orthoLength);
999 if (ortho.length() < orthoLength) {
1000 ortho.extrapolate(orthoLength - ortho.length(), false, true);
1001 }
1002 GLHelper::drawLine(ortho);
1003 //std::cout << "foe=" << l->getID() << " lanePos=" << l->getLength() - conflicts[i].lengthBehindCrossing << " pos=" << pos << "\n";
1004 }
1005 }
1007}
1008
1009
1010// ------ inherited from GUIGlObject
1013 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
1014 buildPopupHeader(ret, app);
1016 //
1017 GUIDesigns::buildFXMenuCommand(ret, TL("Copy edge name to clipboard"), nullptr, ret, MID_COPY_EDGE_NAME);
1020 //
1021 buildShowParamsPopupEntry(ret, false);
1024 const double height = baseShape.positionAtOffset(pos).z();
1025 GUIDesigns::buildFXMenuCommand(ret, (TL("pos: ") + toString(pos) + " " + TL("height: ") + toString(height)).c_str(), nullptr, nullptr, 0);
1026 if (getEdge().hasDistance()) {
1027 GUIDesigns::buildFXMenuCommand(ret, ("distance: " + toString(getEdge().getDistanceAt(pos))).c_str(), nullptr, nullptr, 0);
1028 }
1029 new FXMenuSeparator(ret);
1030 buildPositionCopyEntry(ret, app);
1031 new FXMenuSeparator(ret);
1032 if (myAmClosed) {
1033 if (myPermissionChanges.empty()) {
1034 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen lane"), nullptr, &parent, MID_CLOSE_LANE);
1035 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen edge"), nullptr, &parent, MID_CLOSE_EDGE);
1036 } else {
1037 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen lane (override rerouter)"), nullptr, &parent, MID_CLOSE_LANE);
1038 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen edge (override rerouter)"), nullptr, &parent, MID_CLOSE_EDGE);
1039 }
1040 } else {
1041 GUIDesigns::buildFXMenuCommand(ret, TL("Close lane"), nullptr, &parent, MID_CLOSE_LANE);
1042 GUIDesigns::buildFXMenuCommand(ret, TL("Close edge"), nullptr, &parent, MID_CLOSE_EDGE);
1043 }
1044 GUIDesigns::buildFXMenuCommand(ret, TL("Add rerouter"), nullptr, &parent, MID_ADD_REROUTER);
1045 new FXMenuSeparator(ret);
1046 // reachability menu
1047 FXMenuPane* reachableByClass = new FXMenuPane(ret);
1048 ret->insertMenuPaneChild(reachableByClass);
1049 new FXMenuCascade(ret, TL("Select reachable"), GUIIconSubSys::getIcon(GUIIcon::FLAG), reachableByClass);
1050 for (auto i : SumoVehicleClassStrings.getStrings()) {
1052 }
1053 return ret;
1054}
1055
1056
1060 GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
1061 // add items
1062 ret->mkItem(TL("allowed speed [m/s]"), false, getSpeedLimit());
1063 const std::map<SUMOVehicleClass, double>* restrictions = MSNet::getInstance()->getRestrictions(myEdge->getEdgeType());
1064 if (restrictions != nullptr) {
1065 for (const auto& elem : *restrictions) {
1066 ret->mkItem((std::string(" ") + TL("allowed speed [m/s]") + std::string(": ") + toString(elem.first)).c_str(), false, elem.second);
1067 }
1068 }
1069 ret->mkItem(TL("length [m]"), false, myLength);
1070 ret->mkItem(TL("width [m]"), false, myWidth);
1071 ret->mkItem(TL("street name"), false, myEdge->getStreetName());
1072 ret->mkItem(TL("stored travel time [s]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getStoredEdgeTravelTime));
1073 ret->mkItem(TL("loaded weight"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getLoadedEdgeWeight));
1074 ret->mkItem(TL("routing speed [m/s]"), true, new FunctionBinding<MSEdge, double>(myEdge, &MSEdge::getRoutingSpeed));
1075 ret->mkItem(TL("lane friction coefficient [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getFrictionCoefficient));
1076 ret->mkItem(TL("time penalty [s]"), true, new FunctionBinding<MSEdge, double>(myEdge, &MSEdge::getTimePenalty));
1077 ret->mkItem(TL("brutto occupancy [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getBruttoOccupancy, 100.));
1078 ret->mkItem(TL("netto occupancy [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getNettoOccupancy, 100.));
1079 ret->mkItem(TL("pending insertions [#]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getPendingEmits));
1080 ret->mkItem(TL("edge type"), false, myEdge->getEdgeType());
1081 ret->mkItem(TL("routing type"), false, myEdge->getRoutingType());
1082 ret->mkItem(TL("type"), false, myLaneType);
1083 ret->mkItem(TL("priority"), false, myEdge->getPriority());
1084 ret->mkItem(TL("distance [km]"), false, myEdge->getDistance() / 1000);
1085 ret->mkItem(TL("allowed vehicle class"), false, StringUtils::wrapText(getVehicleClassNames(myPermissions), 60));
1086 ret->mkItem(TL("disallowed vehicle class"), false, StringUtils::wrapText(getVehicleClassNames(~myPermissions), 60));
1087 ret->mkItem(TL("permission code"), false, myPermissions);
1088 ret->mkItem(TL("color value"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getColorValueForTracker));
1089 if (myBidiLane != nullptr) {
1090 ret->mkItem(TL("bidi-lane"), false, myBidiLane->getID());
1091 }
1092 // info for blocked departDriveWay
1093 for (auto item : getParametersMap()) {
1094 if (StringUtils::startsWith(item.first, "insertionBlocked:")) {
1095 const MSDriveWay* dw = MSDriveWay::retrieveDepartDriveWay(myEdge, item.second);
1096 if (dw != nullptr) {
1097 ret->mkItem(("blocking " + dw->getID()).c_str(), false, toString(MSRailSignal::getBlockingVehicles(dw)));
1098 ret->mkItem(("driveWays blocking " + dw->getID()).c_str(), false, toString(MSRailSignal::getBlockingDriveWays(dw)));
1099 }
1100 }
1101 }
1102
1103 for (const auto& kv : myEdge->getParametersMap()) {
1104 ret->mkItem(("edgeParam:" + kv.first).c_str(), false, kv.second);
1105 }
1107 ret->closeBuilding();
1108 return ret;
1109}
1110
1111
1114 const PositionVector& shape = GUIGlobals::gSecondaryShape && myShape2.size() > 0 ? myShape2 : myShape;
1115 Boundary b;
1116 b.add(shape[0]);
1117 b.add(shape[-1]);
1119 // ensure that vehicles and persons on the side are drawn even if the edge
1120 // is outside the view
1121 return b;
1122}
1123
1124
1125const PositionVector&
1126GUILane::getShape(bool secondary) const {
1127 return secondary && myShape2.size() > 0 ? myShape2 : myShape;
1128}
1129
1130
1131const std::vector<double>&
1132GUILane::getShapeRotations(bool secondary) const {
1133 return secondary && myShapeRotations2.size() > 0 ? myShapeRotations2 : myShapeRotations;
1134}
1135
1136
1137const std::vector<double>&
1138GUILane::getShapeLengths(bool secondary) const {
1139 return secondary && myShapeLengths2.size() > 0 ? myShapeLengths2 : myShapeLengths;
1140}
1141
1142
1143std::vector<RGBColor>&
1144GUILane::getShapeColors(bool secondary) const {
1145 return secondary && myShapeColors2.size() > 0 ? myShapeColors2 : myShapeColors;
1146}
1147
1148
1149double
1151 return myVehicles.size() == 0 ? 0 : myVehicles.back()->getWaitingSeconds();
1152}
1153
1154
1155double
1157 return (double) myEdge->getLanes().size();
1158}
1159
1160
1161double
1164 if (!ews.knowsTravelTime(myEdge)) {
1165 return -1;
1166 } else {
1167 double value(0);
1168 ews.retrieveExistingTravelTime(myEdge, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), value);
1169 return value;
1170 }
1171}
1172
1173
1174double
1177 if (!ews.knowsEffort(myEdge)) {
1178 return -1;
1179 } else {
1180 double value(-1);
1181 ews.retrieveExistingEffort(myEdge, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), value);
1182 return value;
1183 }
1184}
1185
1186
1187double
1189 switch (activeScheme) {
1190 case 18: {
1192 }
1193 default:
1194 return getColorValue(s, activeScheme);
1195 }
1196
1197}
1198
1199
1202 // setting and retrieving the color does not work in OSGView so we return it explicitliy
1203 RGBColor col;
1204 if (MSGlobals::gUseMesoSim && static_cast<const GUIEdge*>(myEdge)->getMesoColor() != MESO_USE_LANE_COLOR) {
1205 col = static_cast<const GUIEdge*>(myEdge)->getMesoColor();
1206 } else {
1207 const GUIColorer& c = s.laneColorer;
1208 if (!setFunctionalColor(c, col) && !setMultiColor(s, c, col)) {
1209 col = c.getScheme().getColor(getColorValue(s, c.getActive()));
1210 }
1211 }
1212 GLHelper::setColor(col);
1213 return col;
1214}
1215
1216
1217bool
1218GUILane::setFunctionalColor(const GUIColorer& c, RGBColor& col, int activeScheme) const {
1219 if (activeScheme < 0) {
1220 activeScheme = c.getActive();
1221 }
1222 switch (activeScheme) {
1223 case 0:
1224 if (myEdge->isCrossing()) {
1225 // determine priority to decide color
1226 const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
1227 if (link->havePriority() || link->getTLLogic() != nullptr) {
1228 col = RGBColor(230, 230, 230);
1229 } else {
1230 col = RGBColor(26, 26, 26);
1231 }
1232 GLHelper::setColor(col);
1233 return true;
1234 } else {
1235 return false;
1236 }
1237 case 18: {
1238 double hue = GeomHelper::naviDegree(myShape.beginEndAngle()); // [0-360]
1239 col = RGBColor::fromHSV(hue, 1., 1.);
1240 GLHelper::setColor(col);
1241 return true;
1242 }
1243 case 30: { // taz color
1244 col = c.getScheme().getColor(0);
1245 std::vector<RGBColor> tazColors;
1246 for (MSEdge* e : myEdge->getPredecessors()) {
1247 if (e->isTazConnector() && e->hasParameter("tazColor")) {
1248 tazColors.push_back(RGBColor::parseColor(e->getParameter("tazColor")));
1249 }
1250 }
1251 for (MSEdge* e : myEdge->getSuccessors()) {
1252 if (e->isTazConnector() && e->hasParameter("tazColor")) {
1253 tazColors.push_back(RGBColor::parseColor(e->getParameter("tazColor")));
1254 }
1255 }
1256 if (tazColors.size() > 0) {
1257 int randColor = RandHelper::rand((int)tazColors.size(), RGBColor::getColorRNG());
1258 col = tazColors[randColor];
1259 }
1260 GLHelper::setColor(col);
1261 return true;
1262 }
1263 default:
1264 return false;
1265 }
1266}
1267
1268
1269bool
1271 const int activeScheme = c.getActive();
1272 auto& shapeColors = getShapeColors(s.secondaryShape);
1273 const PositionVector& shape = getShape(s.secondaryShape);
1274 shapeColors.clear();
1275 switch (activeScheme) {
1276 case 22: // color by height at segment start
1277 for (PositionVector::const_iterator ii = shape.begin(); ii != shape.end() - 1; ++ii) {
1278 shapeColors.push_back(c.getScheme().getColor(ii->z()));
1279 }
1280 // osg fallback (edge height at start)
1281 col = c.getScheme().getColor(getColorValue(s, 21));
1282 return true;
1283 case 24: // color by inclination at segment start
1284 for (int ii = 1; ii < (int)shape.size(); ++ii) {
1285 const double inc = (shape[ii].z() - shape[ii - 1].z()) / MAX2(POSITION_EPS, shape[ii].distanceTo2D(shape[ii - 1]));
1286 shapeColors.push_back(c.getScheme().getColor(inc));
1287 }
1288 col = c.getScheme().getColor(getColorValue(s, 23));
1289 return true;
1290 default:
1291 return false;
1292 }
1293}
1294
1295double
1297 if (myCachedGUISettings != nullptr) {
1299 const GUIColorer& c = s.laneColorer;
1300 double val = getColorValueWithFunctional(s, c.getActive());
1302 // blowing up the dialog or plot isn't helpful. At least 0 may be understood as neutral
1303 return 0;
1304 } else {
1305 return val;
1306 }
1307 } else {
1308 return 0;
1309 }
1310}
1311
1312
1313double
1314GUILane::getColorValue(const GUIVisualizationSettings& s, int activeScheme) const {
1315 switch (activeScheme) {
1316 case 0:
1317 switch (myPermissions) {
1318 case SVC_PEDESTRIAN:
1319 return 1;
1320 case SVC_BICYCLE:
1321 return 2;
1322 case 0:
1323 // forbidden road or green verge
1324 return myEdge->getPermissions() == 0 ? 10 : 3;
1325 case SVC_SHIP:
1326 return 4;
1327 case SVC_AUTHORITY:
1328 return 8;
1329 case SVC_AIRCRAFT:
1330 case SVC_DRONE:
1331 return 11;
1332 default:
1333 break;
1334 }
1335 if (myEdge->isTazConnector()) {
1336 return 9;
1337 } else if (isRailway(myPermissions)) {
1338 return 5;
1339 } else if ((myPermissions & SVC_PASSENGER) != 0) {
1340 if ((myPermissions & (SVC_RAIL_CLASSES & ~SVC_RAIL_FAST)) != 0 && (myPermissions & SVC_SHIP) == 0) {
1341 return 6;
1342 } else {
1343 return 0;
1344 }
1345 } else {
1346 if ((myPermissions & SVC_RAIL_CLASSES) != 0 && (myPermissions & SVC_SHIP) == 0) {
1347 return 6;
1348 } else {
1349 return 7;
1350 }
1351 }
1352 case 1:
1353 return isLaneOrEdgeSelected();
1354 case 2:
1355 return (double)myPermissions;
1356 case 3:
1357 return getSpeedLimit();
1358 case 4:
1359 return getBruttoOccupancy();
1360 case 5:
1361 return getNettoOccupancy();
1362 case 6:
1363 return firstWaitingTime();
1364 case 7:
1365 return getEdgeLaneNumber();
1366 case 8:
1367 return getEmissions<PollutantsInterface::CO2>() / myLength;
1368 case 9:
1369 return getEmissions<PollutantsInterface::CO>() / myLength;
1370 case 10:
1371 return getEmissions<PollutantsInterface::PM_X>() / myLength;
1372 case 11:
1373 return getEmissions<PollutantsInterface::NO_X>() / myLength;
1374 case 12:
1375 return getEmissions<PollutantsInterface::HC>() / myLength;
1376 case 13:
1377 return getEmissions<PollutantsInterface::FUEL>() / myLength;
1378 case 14:
1380 case 15: {
1381 return getStoredEdgeTravelTime();
1382 }
1383 case 16: {
1385 if (!ews.knowsTravelTime(myEdge)) {
1386 return -1;
1387 } else {
1388 double value(0);
1389 ews.retrieveExistingTravelTime(myEdge, 0, value);
1390 return 100 * myLength / value / getSpeedLimit();
1391 }
1392 }
1393 case 17: {
1394 // geometrical length has no meaning for walkingAreas since it describes the outer boundary
1396 }
1397 case 19: {
1398 return getLoadedEdgeWeight();
1399 }
1400 case 20: {
1401 return myEdge->getPriority();
1402 }
1403 case 21: {
1404 // color by z of first shape point
1405 return getShape(s.secondaryShape)[0].z();
1406 }
1407 case 23: {
1408 // color by incline
1409 return (getShape(s.secondaryShape)[-1].z() - getShape(s.secondaryShape)[0].z()) / getLength();
1410 }
1411 case 25: {
1412 // color by average speed
1413 return getMeanSpeed();
1414 }
1415 case 26: {
1416 // color by average relative speed
1417 return getMeanSpeed() / myMaxSpeed;
1418 }
1419 case 27: {
1420 // color by routing device assumed speed
1421 return myEdge->getRoutingSpeed();
1422 }
1423 case 28:
1424 return getEmissions<PollutantsInterface::ELEC>() / myLength;
1425 case 29:
1426 return getPendingEmits();
1427 case 31: {
1428 // by numerical edge param value
1429 if (myEdge->hasParameter(s.edgeParam)) {
1430 try {
1432 } catch (NumberFormatException&) {
1433 try {
1435 } catch (BoolFormatException&) {
1437 }
1438 }
1439 } else {
1441 }
1442 }
1443 case 32: {
1444 // by numerical lane param value
1445 if (hasParameter(s.laneParam)) {
1446 try {
1448 } catch (NumberFormatException&) {
1449 try {
1451 } catch (BoolFormatException&) {
1453 }
1454 }
1455 } else {
1457 }
1458 }
1459 case 33: {
1460 // by edge data value
1462 }
1463 case 34: {
1464 return myEdge->getDistance();
1465 }
1466 case 35: {
1467 return fabs(myEdge->getDistance());
1468 }
1469 case 36: {
1470 return myReachability;
1471 }
1472 case 37: {
1474 }
1475 case 38: {
1476 if (myParkingAreas == nullptr) {
1477 // init
1478 myParkingAreas = new std::vector<MSParkingArea*>();
1480 if (&item.second->getLane().getEdge() == myEdge) {
1481 myParkingAreas->push_back(dynamic_cast<MSParkingArea*>(item.second));
1482 }
1483 }
1484 }
1485 int capacity = 0;
1486 for (MSParkingArea* pa : *myParkingAreas) {
1487 capacity += pa->getCapacity() - pa->getOccupancy();
1488 }
1489 return capacity;
1490 }
1491 case 39: {
1492 // by live edge data value
1494 }
1495 }
1496 return 0;
1497}
1498
1499
1500double
1501GUILane::getScaleValue(const GUIVisualizationSettings& s, int activeScheme, bool s2) const {
1502 switch (activeScheme) {
1503 case 0:
1504 return 0;
1505 case 1:
1506 return isLaneOrEdgeSelected();
1507 case 2:
1508 return getSpeedLimit();
1509 case 3:
1510 return getBruttoOccupancy();
1511 case 4:
1512 return getNettoOccupancy();
1513 case 5:
1514 return firstWaitingTime();
1515 case 6:
1516 return getEdgeLaneNumber();
1517 case 7:
1518 return getEmissions<PollutantsInterface::CO2>() / myLength;
1519 case 8:
1520 return getEmissions<PollutantsInterface::CO>() / myLength;
1521 case 9:
1522 return getEmissions<PollutantsInterface::PM_X>() / myLength;
1523 case 10:
1524 return getEmissions<PollutantsInterface::NO_X>() / myLength;
1525 case 11:
1526 return getEmissions<PollutantsInterface::HC>() / myLength;
1527 case 12:
1528 return getEmissions<PollutantsInterface::FUEL>() / myLength;
1529 case 13:
1531 case 14: {
1532 return getStoredEdgeTravelTime();
1533 }
1534 case 15: {
1536 if (!ews.knowsTravelTime(myEdge)) {
1537 return -1;
1538 } else {
1539 double value(0);
1540 ews.retrieveExistingTravelTime(myEdge, 0, value);
1541 return 100 * myLength / value / getSpeedLimit();
1542 }
1543 }
1544 case 16: {
1545 return 1 / getLengthGeometryFactor(s2);
1546 }
1547 case 17: {
1548 return getLoadedEdgeWeight();
1549 }
1550 case 18: {
1551 return myEdge->getPriority();
1552 }
1553 case 19: {
1554 // scale by average speed
1555 return getMeanSpeed();
1556 }
1557 case 20: {
1558 // scale by average relative speed
1559 return getMeanSpeed() / myMaxSpeed;
1560 }
1561 case 21:
1562 return getEmissions<PollutantsInterface::ELEC>() / myLength;
1563 case 22:
1565 case 23:
1566 // by edge data value
1568 }
1569 return 0;
1570}
1571
1572
1573bool
1577
1578
1579bool
1581 return isWaterway(myPermissions) && s.showRails; // reusing the showRails setting
1582}
1583
1584
1585#ifdef HAVE_OSG
1586void
1587GUILane::updateColor(const GUIVisualizationSettings& s) {
1588 if (myGeom == 0) {
1589 // not drawn
1590 return;
1591 }
1592 const RGBColor col = setColor(s);
1593 osg::Vec4ubArray* colors = dynamic_cast<osg::Vec4ubArray*>(myGeom->getColorArray());
1594 (*colors)[0].set(col.red(), col.green(), col.blue(), col.alpha());
1595 myGeom->setColorArray(colors);
1596}
1597#endif
1598
1599
1600void
1601GUILane::closeTraffic(bool rebuildAllowed) {
1603 if (myAmClosed) {
1604 myPermissionChanges.clear(); // reset rerouters
1606 } else {
1608 }
1610 if (rebuildAllowed) {
1612 }
1613}
1614
1615
1618 assert(MSGlobals::gUseMesoSim);
1619 const MESegment::MesoEdgeType& edgeType = MSNet::getInstance()->getMesoType(getEdge().getEdgeType());
1620 int no = MELoop::numSegmentsFor(myLength, edgeType.edgeLength);
1621 const double slength = myLength / no;
1622 PositionVector result = shape;
1623 double offset = 0;
1624 for (int i = 0; i < no; ++i) {
1625 offset += slength;
1626 Position pos = shape.positionAtOffset(offset);
1627 int index = result.indexOfClosest(pos);
1628 if (pos.distanceTo(result[index]) > POSITION_EPS) {
1629 index = result.insertAtClosest(pos, false);
1630 }
1631 if (i != no - 1) {
1632 mySegmentStartIndex.push_back(index);
1633 }
1634 while ((int)myShapeSegments.size() < index) {
1635 myShapeSegments.push_back(i);
1636 }
1637 //std::cout << "splitAtSegments " << getID() << " no=" << no << " i=" << i << " offset=" << offset << " index=" << index << " segs=" << toString(myShapeSegments) << " resultSize=" << result.size() << " result=" << toString(result) << "\n";
1638 }
1639 while (myShapeSegments.size() < result.size()) {
1640 myShapeSegments.push_back(no - 1);
1641 }
1642 return result;
1643}
1644
1645bool
1649
1650bool
1652 return isSelected() || gSelected.isSelected(GLO_EDGE, dynamic_cast<GUIEdge*>(myEdge)->getGlID());
1653}
1654
1655double
1659
1660double
1663 // do not select lanes in meso mode
1664 return INVALID_PRIORITY;
1665 }
1666 if (myEdge->isCrossing()) {
1667 return GLO_CROSSING;
1668 }
1669 return GLO_LANE;
1670}
1671
1672
1673/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
@ MID_COPY_EDGE_NAME
Copy edge name (for lanes only)
Definition GUIAppEnum.h:461
@ MID_REACHABILITY
show reachability from a given lane
Definition GUIAppEnum.h:533
@ MID_CLOSE_LANE
close lane
Definition GUIAppEnum.h:669
@ MID_CLOSE_EDGE
close edge
Definition GUIAppEnum.h:671
@ MID_ADD_REROUTER
add rerouter
Definition GUIAppEnum.h:673
@ GLO_JUNCTION
a junction
@ GLO_LANE
a lane
@ GLO_EDGE
an edge
@ GLO_SHAPE
reserved GLO type to pack shapes
@ GLO_CROSSING
a tl-logic
GUISelectedStorage gSelected
A global holder of selected objects.
GUIIcon
An enumeration of icons used by the gui applications.
Definition GUIIcons.h:33
#define RENDERING_BUFFER
Definition GUILane.cpp:65
#define RAD2DEG(x)
Definition GeomHelper.h:36
#define TL(string)
Definition MsgHandler.h:304
#define STEPS2TIME(x)
Definition SUMOTime.h: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:46
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition Boundary.cpp:75
Boundary & grow(double by)
extends the boundary by the given amount
Definition Boundary.cpp:340
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition GLHelper.cpp:433
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition GLHelper.cpp:649
static void drawTriangleAtEnd(const Position &p1, const Position &p2, double tLength, double tWidth, const double extraOffset=0)
Draws a triangle at the end of the given line.
Definition GLHelper.cpp:624
static void drawTextAtEnd(const std::string &text, const PositionVector &shape, double x, const GUIVisualizationTextSettings &settings, const double scale)
draw text and the end of shape
Definition GLHelper.cpp:824
static void pushName(unsigned int name)
push Name
Definition GLHelper.cpp:140
static void drawFilledCircle(const double widradiusth, const int steps=8)
Draws a filled circle around (0,0)
Definition GLHelper.cpp:564
static void popMatrix()
pop matrix
Definition GLHelper.cpp:131
static void drawBoxLines(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double width, int cornerDetail=0, double offset=0)
Draws thick lines.
Definition GLHelper.cpp:348
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition GLHelper.cpp:296
static void debugVertices(const PositionVector &shape, const GUIVisualizationTextSettings &settings, double scale, double layer=1024)
draw vertex numbers for the given shape (in a random color)
Definition GLHelper.cpp:939
static void popName()
pop Name
Definition GLHelper.cpp:149
static void pushMatrix()
push matrix
Definition GLHelper.cpp:118
static void drawInverseMarkings(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double maxLength, double spacing, double halfWidth, bool cl, bool cr, bool lefthand, double scale)
@bried draw the space between markings (in road color)
Definition GLHelper.cpp:886
static void drawCrossTies(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double length, double spacing, double halfWidth, double offset, bool lessDetail)
draw crossties for railroads or pedestrian crossings
Definition GLHelper.cpp:843
A MSVehicle extended by some values for usage within the gui.
void drawGL(const GUIVisualizationSettings &s) const 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:584
The popup menu of a globject.
void insertMenuPaneChild(FXMenuPane *child)
Insert a sub-menu pane in this GUIGLObjectPopupMenu.
static const double INVALID_PRIORITY
Definition GUIGlObject.h:74
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, const GUIMainWindow &app, bool addSeparator=true) const
Builds an entry which allows to copy the cursor position if geo projection is used,...
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
void buildSelectionPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to (de)select the object.
GUIGlID getGlID() const
Returns the numerical id of the object.
static bool gSecondaryShape
whether secondary shapes are currently being drawn
Definition GUIGlobals.h:49
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
Representation of a lane in the micro simulation (gui-version)
Definition GUILane.h:60
bool drawAsWaterway(const GUIVisualizationSettings &s) const
whether to draw this lane as a waterway
Definition GUILane.cpp:1580
void debugDrawFoeIntersections() const
draw intersection positions of foe internal lanes with this one
Definition GUILane.cpp:986
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:1651
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:1617
std::vector< int > myShapeSegments
the meso segment index for each geometry segment
Definition GUILane.h:365
double firstWaitingTime() const
Definition GUILane.cpp:1150
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:1201
double getPendingEmits() const
get number of vehicles waiting for departure on this lane
Definition GUILane.cpp:1656
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:1012
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:893
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:1270
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:1501
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:828
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const override
gets the color value according to the current scheme index
Definition GUILane.cpp:1314
void closeTraffic(bool rebuildAllowed=true)
close this lane for traffic
Definition GUILane.cpp:1601
double getClickPriority() const override
Returns the priority of receiving mouse clicks.
Definition GUILane.cpp:1661
bool isSelected() const override
whether this lane is selected in the GUI
Definition GUILane.cpp:1646
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own parameter window.
Definition GUILane.cpp:1058
const std::vector< double > & getShapeRotations(bool secondary) const
Definition GUILane.cpp:1132
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:1188
bool drawAsRailway(const GUIVisualizationSettings &s) const
whether to draw this lane as a railway
Definition GUILane.cpp:1574
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:1296
std::vector< RGBColor > myShapeColors2
Definition GUILane.h:362
double getEdgeLaneNumber() const
Definition GUILane.cpp:1156
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:1175
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:1126
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:1113
std::vector< RGBColor > & getShapeColors(bool secondary) const
Definition GUILane.cpp:1144
bool setFunctionalColor(const GUIColorer &c, RGBColor &col, int activeScheme=-1) const
Definition GUILane.cpp:1218
double getStoredEdgeTravelTime() const
Returns the stored traveltime for the edge of this lane.
Definition GUILane.cpp:1162
const std::vector< double > & getShapeLengths(bool secondary) const
Definition GUILane.cpp:1138
void drawMarkings(const GUIVisualizationSettings &s, double scale) const
draw lane borders and white markings
Definition GUILane.cpp:841
void drawBikeMarkings() const
bike lane markings on top of an intersection
Definition GUILane.cpp:864
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:958
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:631
int getLinkTLIndex(const MSLink *const link) const
Definition GUINet.cpp:213
static GUINet * getGUIInstance()
Returns the pointer to the unique instance of GUINet (singleton).
Definition GUINet.cpp:581
double getEdgeData(const MSEdge *edge, const std::string &attr)
retrieve loaded edged weight for the given attribute and the current simulation time
Definition GUINet.cpp:614
A window containing a gl-object's parameter.
void mkItem(const char *name, bool dynamic, ValueSource< T > *src)
Adds a row which obtains its value from a ValueSource.
void closeBuilding(const Parameterised *p=0)
Closes the building of the table.
void checkFont(const std::string &text)
ensure that the font covers the given text
T getColor(const double value) const
const GUIVisualizationSettings & getVisualisationSettings() const
get visualization settings (read only)
GUIVisualizationSettings * editVisualisationSettings() const
edit visualization settings (allow modify VisualizationSetings, use carefully)
virtual Position getPositionInformation() const
Returns the cursor's x/y position within the network.
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
A MSVehicle extended by some values for usage within the gui.
Definition GUIVehicle.h: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:293
The base class for microscopic and mesoscopic vehicles.
static const MSDriveWay * retrieveDepartDriveWay(const MSEdge *edge, const std::string &id)
A road/street connecting two junctions.
Definition MSEdge.h:77
bool isCrossing() const
return whether this edge is a pedestrian crossing
Definition MSEdge.h: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:1069
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition MSEdge.cpp:1286
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:146
static bool gLefthand
Whether lefthand-drive is being simulated.
Definition MSGlobals.h:174
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition MSGlobals.h:81
int getPendingEmits(const MSLane *lane)
return the number of pending emits for the given lane
SumoXMLNodeType getType() const
return the type of this Junction
Definition MSJunction.h:133
const PositionVector & getShape() const
Returns this junction's shape.
Definition MSJunction.h:91
Representation of a lane in the micro simulation.
Definition MSLane.h:84
SVCPermissions myPermissions
The vClass permissions for this lane.
Definition MSLane.h:1542
std::set< const MSBaseVehicle * > myParkingVehicles
Definition MSLane.h:1514
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:2864
virtual void removeParking(MSBaseVehicle *veh)
remove parking vehicle. This must be syncrhonized when running with GUI
Definition MSLane.cpp:3703
virtual void integrateNewVehicles()
Insert buffered vehicle into the real lane.
Definition MSLane.cpp:2573
double myLength
Lane length [m].
Definition MSLane.h:1517
double getNettoOccupancy() const
Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps)
Definition MSLane.cpp:3425
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition MSLane.cpp:2846
PositionVector myShape
The shape of the lane.
Definition MSLane.h:1462
PositionVector * myOutlineShape
the outline of the lane (optional)
Definition MSLane.h:1465
std::map< long long, SVCPermissions > myPermissionChanges
Definition MSLane.h:1622
double getFrictionCoefficient() const
Returns the lane's friction coefficient.
Definition MSLane.h:605
virtual void incorporateVehicle(MSVehicle *veh, double pos, double speed, double posLat, const MSLane::VehCont::iterator &at, MSMoveReminder::Notification notification=MSMoveReminder::NOTIFICATION_DEPARTED)
Inserts the vehicle into this lane, and informs it about entering the network.
Definition MSLane.cpp:455
const MSLane * getNormalSuccessorLane() const
get normal lane following this internal lane, for normal lanes, the lane itself is returned
Definition MSLane.cpp:3265
MSEdge *const myEdge
The lane's edge, for routing only.
Definition MSLane.h:1528
bool allowsChangingRight(SUMOVehicleClass vclass) const
Returns whether the given vehicle class may change left from this lane.
Definition MSLane.h:948
double myMaxSpeed
Lane-wide speed limit [m/s].
Definition MSLane.h:1531
const MSLink * getLinkTo(const MSLane *const) const
returns the link to the given lane or nullptr, if it is not connected
Definition MSLane.cpp:2759
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:1563
VehCont myVehicles
The lane's vehicles. This container holds all vehicles that have their front (longitudinally) and the...
Definition MSLane.h:1481
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition MSLane.h:598
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition MSLane.h:119
MSLane * myBidiLane
Definition MSLane.h:1619
bool isWalkingArea() const
Definition MSLane.cpp:2651
SVCPermissions getPermissions() const
Returns the vehicle class permissions for this lane.
Definition MSLane.h:620
void resetPermissions(long long transientID)
Definition MSLane.cpp:4548
const std::string myLaneType
the type of this lane
Definition MSLane.h:1605
int myRNGIndex
Definition MSLane.h:1625
double getLength() const
Returns the lane's length.
Definition MSLane.h:612
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:2829
StopOffset myLaneStopOffset
Definition MSLane.h:1525
virtual double setPartialOccupation(MSVehicle *v)
Sets the information about a vehicle lapping into this lane.
Definition MSLane.cpp:384
void setPermissions(SVCPermissions permissions, long long transientID)
Sets the permissions to the given value. If a transientID is given, the permissions are recored as te...
Definition MSLane.cpp:4536
const double myWidth
Lane width [m].
Definition MSLane.h:1520
virtual void executeMovements(const SUMOTime t)
Executes planned vehicle movements with regards to right-of-way.
Definition MSLane.cpp:2286
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition MSLane.cpp:3230
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition MSLane.cpp:3410
int myIndex
The lane index.
Definition MSLane.h:1468
bool isCrossing() const
Definition MSLane.cpp:2639
virtual void detectCollisions(SUMOTime timestep, const std::string &stage)
Check if vehicles are too close.
Definition MSLane.cpp:1664
std::vector< MSLink * > myLinks
Definition MSLane.h:1583
bool isInternal() const
Definition MSLane.cpp:2627
static const long CHANGE_PERMISSIONS_GUI
Definition MSLane.h:1386
VehCont myPartialVehicles
The lane's partial vehicles. This container holds all vehicles that are partially on this lane but wh...
Definition MSLane.h:1493
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:403
double getHarmonoise_NoiseEmissions() const
Returns the sum of last step noise emissions.
Definition MSLane.cpp:3499
virtual void setJunctionApproaches() const
Register junction approaches for all vehicles after velocities have been planned.
Definition MSLane.cpp:1603
MSLane * getBidiLane() const
retrieve bidirectional lane or nullptr
Definition MSLane.cpp:4693
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:770
const MSLane * getNormalPredecessorLane() const
get normal lane leading to this internal lane, for normal lanes, the lane itself is returned
Definition MSLane.cpp:3255
double getWidth() const
Returns the lane's width.
Definition MSLane.h:641
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
Definition MSLane.h:730
double getMeanSpeed() const
Returns the mean speed on this lane.
Definition MSLane.cpp:3453
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:187
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:355
MSEdgeWeightsStorage & getWeightsStorage()
Returns the net's internal edge travel times/efforts container.
Definition MSNet.cpp:1281
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition MSNet.h:445
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:413
const NamedObjectCont< MSStoppingPlace * > & getStoppingPlaces(SumoXMLTag category) const
Definition MSNet.cpp:1519
A lane area vehicles can halt at.
VehicleVector getBlockingVehicles(int linkIndex) override
return vehicles that block the intersection/rail signal for vehicles that wish to pass the given link...
std::vector< const MSDriveWay * > getBlockingDriveWays(int linkIndex) override
return vehicles that approach the intersection/rail signal and have priority over vehicles that wish ...
Representation of a vehicle in the micro simulation.
Definition MSVehicle.h:77
const std::string & getID() const
Returns the id.
Definition Named.h:74
bool hasParameter(const std::string &key) const
Returns whether the parameter is set.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition Position.h:273
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimensions
Definition Position.h:263
double x() const
Returns the x-position.
Definition Position.h:52
double z() const
Returns the z-position.
Definition Position.h:62
double y() const
Returns the y-position.
Definition Position.h:57
A list of positions.
double beginEndAngle() const
returns the angle in radians of the line connecting the first and the last position
double getMinZ() const
return minimum z-coordinate
double length() const
Returns the length.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
PositionVector getOrthogonal(const Position &p, double extend, bool before, double length=1.0, double deg=90) const
return orthogonal through p (extending this vector if necessary)
int indexOfClosest(const Position &p, bool twoD=false) const
void move2side(double amount, double maxExtension=100)
move position vector to side using certain amount
void extrapolate(const double val, const bool onlyFirst=false, const bool onlyLast=false)
extrapolate position vector
Position getCentroid() const
Returns the centroid (closes the polygon if unclosed)
int insertAtClosest(const Position &p, bool interpolateZ)
inserts p between the two closest positions
double nearest_offset_to_point25D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D projected onto the 3D geometry
PositionVector reverse() const
reverse position vector
unsigned char red() const
Returns the red-amount of the color.
Definition RGBColor.cpp:74
static const RGBColor BLUE
Definition RGBColor.h:190
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition RGBColor.cpp:92
static SumoRNG * getColorRNG()
get color RNG
Definition RGBColor.cpp:194
static RGBColor parseColor(std::string coldef)
Parses a color information.
Definition RGBColor.cpp:239
unsigned char green() const
Returns the green-amount of the color.
Definition RGBColor.cpp:80
static RGBColor fromHSV(double h, double s, double v)
Converts the given hsv-triplet to rgb, inspired by http://alvyray.com/Papers/CG/hsv2rgb....
Definition RGBColor.cpp:403
unsigned char blue() const
Returns the blue-amount of the color.
Definition RGBColor.cpp:86
RGBColor changedBrightness(int change, int toChange=3) const
Returns a new color with altered brightness.
Definition RGBColor.cpp:200
static const RGBColor MAGENTA
Definition RGBColor.h:193
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
bool isDefined() const
check if stopOffset was defined
SVCPermissions getPermissions() const
get permissions
double getOffset() const
get offset
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
static std::string wrapText(const std::string s, int width)
remove leading and trailing whitespace
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
void drawTesselation(const PositionVector &shape) const
perform the tesselation / drawing
static FXIcon * getVClassIcon(const SUMOVehicleClass vc)
returns icon associated to the given vClass
static const RGBColor SUMO_color_DEADEND_SHOW
color for highlighthing deadends
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values
double exaggeration
The size exaggeration (upscale)
bool constantSize
whether the object shall be drawn with constant size regardless of zoom
double minSize
The minimum size to draw this object.
bool show(const GUIGlObject *o) const
whether to show the text
edge type specific meso parameters
Definition MESegment.h:58