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