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),
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#ifdef _DEBUG
122 assert(fabs(myShape.length() - origLength) < POSITION_EPS);
123#endif
124 assert(myShapeSegments.size() == myShape.size());
126}
127
128
129void
131 std::vector<double>& rotations,
132 std::vector<double>& lengths,
133 std::vector<RGBColor>& colors) {
134 rotations.clear();
135 lengths.clear();
136 colors.clear();
137 rotations.reserve(shape.size() - 1);
138 lengths.reserve(shape.size() - 1);
139 colors.reserve(shape.size() - 1);
140 int e = (int) shape.size() - 1;
141 for (int i = 0; i < e; ++i) {
142 const Position& f = shape[i];
143 const Position& s = shape[i + 1];
144 lengths.push_back(f.distanceTo2D(s));
145 rotations.push_back(RAD2DEG(atan2(s.x() - f.x(), f.y() - s.y())));
146 }
147}
148
149
150void
156
157
158// ------ Vehicle insertion ------
159void
160GUILane::incorporateVehicle(MSVehicle* veh, double pos, double speed, double posLat,
161 const MSLane::VehCont::iterator& at,
162 MSMoveReminder::Notification notification) {
163 FXMutexLock locker(myLock);
164 MSLane::incorporateVehicle(veh, pos, speed, posLat, at, notification);
165}
166
167
168// ------ Access to vehicles ------
169const MSLane::VehCont&
171 myLock.lock();
172 return myVehicles;
173}
174
175
176void
178 myLock.unlock();
179}
180
181
182void
184 FXMutexLock locker(myLock);
186}
187
188void
190 FXMutexLock locker(myLock);
192}
193
194
195void
197 FXMutexLock locker(myLock);
199}
200
201
203GUILane::removeVehicle(MSVehicle* remVehicle, MSMoveReminder::Notification notification, bool notify) {
204 FXMutexLock locker(myLock);
205 return MSLane::removeVehicle(remVehicle, notification, notify);
206}
207
208
209void
211 FXMutexLock locker(myLock);
212 return MSLane::removeParking(remVehicle);
213}
214
215
216void
221
222
223void
228
229
230void
231GUILane::detectCollisions(SUMOTime timestep, const std::string& stage) {
232 FXMutexLock locker(myLock);
233 MSLane::detectCollisions(timestep, stage);
234}
235
236
237double
239 FXMutexLock locker(myLock);
241}
242
243
244void
249
250
251// ------ Drawing methods ------
252void
254 int noLinks = (int)myLinks.size();
255 if (noLinks == 0) {
256 return;
257 }
258 // draw all links
259 if (isCrossing()) {
260 // draw indices at the start and end of the crossing
261 const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
263 shape.extrapolate(0.5); // draw on top of the walking area
266 return;
267 }
268 // draw all links
269 double w = myWidth / (double) noLinks;
270 double x1 = myHalfLaneWidth;
271 for (int i = noLinks; --i >= 0;) {
272 double x2 = x1 - (double)(w / 2.);
274 x1 -= w;
275 }
276}
277
278
279void
281 int noLinks = (int)myLinks.size();
282 if (noLinks == 0) {
283 return;
284 }
285 if (isCrossing()) {
286 // draw indices at the start and end of the crossing
287 const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
288 int linkNo = net.getLinkTLIndex(link);
289 // maybe the reverse link is controlled separately
290 int linkNo2 = net.getLinkTLIndex(myLinks.front());
291 // otherwise, use the same index as the forward link
292 if (linkNo2 < 0) {
293 linkNo2 = linkNo;
294 }
295 if (linkNo >= 0) {
297 shape.extrapolate(0.5); // draw on top of the walking area
298 GLHelper::drawTextAtEnd(toString(linkNo2), shape, 0, s.drawLinkTLIndex, s.scale);
300 }
301 return;
302 }
303 // draw all links
304 double w = myWidth / (double) noLinks;
305 double x1 = myHalfLaneWidth;
306 for (int i = noLinks; --i >= 0;) {
307 double x2 = x1 - (double)(w / 2.);
308 int linkNo = net.getLinkTLIndex(myLinks[MSGlobals::gLefthand ? noLinks - 1 - i : i]);
309 if (linkNo < 0) {
310 continue;
311 }
313 x1 -= w;
314 }
315}
316
317
318void
320 int noLinks = (int)myLinks.size();
321 const PositionVector& shape = getShape(s.secondaryShape);
322 if (noLinks == 0) {
323 drawLinkRule(s, net, nullptr, shape, 0, 0);
324 return;
325 }
326 if (isCrossing()) {
327 // draw rules at the start and end of the crossing
328 const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
329 const MSLink* link2 = myLinks.front();
330 if (link2->getTLLogic() == nullptr) {
331 link2 = link;
332 }
333 PositionVector tmp = shape;
334 tmp.extrapolate(0.5); // draw on top of the walking area
335 drawLinkRule(s, net, link2, tmp, 0, myWidth);
336 drawLinkRule(s, net, link, tmp.reverse(), 0, myWidth);
337 return;
338 }
339 // draw all links
340 const double isRailSignal = myEdge->getToJunction()->getType() == SumoXMLNodeType::RAIL_SIGNAL;
341 double w = myWidth / (double) noLinks;
342 if (isRailSignal && noLinks > 1 && myLinks.back()->isTurnaround() && s.showRails) {
343 w = myWidth / (double)(noLinks - 1);
344 }
345 double x1 = isRailSignal && myIndex == 0 ? -myWidth * 0.5 : 0;
346 for (int i = 0; i < noLinks; ++i) {
347 double x2 = x1 + w;
348 drawLinkRule(s, net, myLinks[MSGlobals::gLefthand ? noLinks - 1 - i : i], shape, x1, x2);
349 x1 = x2;
350 }
351 // draw stopOffset for passenger cars
352 if (myLaneStopOffset.isDefined() && (myLaneStopOffset.getPermissions() & SVC_PASSENGER) != 0) {
353 const double stopOffsetPassenger = myLaneStopOffset.getOffset();
354 const Position& end = shape.back();
355 const Position& f = shape[-2];
356 const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
359 glTranslated(end.x(), end.y(), 0);
360 glRotated(rot, 0, 0, 1);
361 glTranslated(0, stopOffsetPassenger, 0);
362 glBegin(GL_QUADS);
363 glVertex2d(-myHalfLaneWidth, 0.0);
364 glVertex2d(-myHalfLaneWidth, 0.2);
365 glVertex2d(myHalfLaneWidth, 0.2);
366 glVertex2d(myHalfLaneWidth, 0.0);
367 glEnd();
369 }
370}
371
372
373void
374GUILane::drawLinkRule(const GUIVisualizationSettings& s, const GUINet& net, const MSLink* link, const PositionVector& shape, double x1, double x2) const {
375 const Position& end = shape.back();
376 const Position& f = shape[-2];
377 const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
378 if (link == nullptr) {
379 if (static_cast<GUIEdge*>(myEdge)->showDeadEnd()) {
381 } else {
383 }
385 glTranslated(end.x(), end.y(), 0);
386 glRotated(rot, 0, 0, 1);
387 glBegin(GL_QUADS);
388 glVertex2d(-myHalfLaneWidth, 0.0);
389 glVertex2d(-myHalfLaneWidth, 0.5);
390 glVertex2d(myHalfLaneWidth, 0.5);
391 glVertex2d(myHalfLaneWidth, 0.0);
392 glEnd();
394 } else {
396 glTranslated(end.x(), end.y(), 0);
397 glRotated(rot, 0, 0, 1);
398 // select glID
399
400 switch (link->getState()) {
402 case LINKSTATE_STOP: {
403 // might be a traffic light link
404 int tlID = net.getLinkTLID(link);
405 GLHelper::pushName(tlID != 0 ? tlID : getGlID());
406 break;
407 }
410 case LINKSTATE_TL_RED:
417 break;
418 case LINKSTATE_MAJOR:
419 case LINKSTATE_MINOR:
420 case LINKSTATE_EQUAL:
421 default:
423 break;
424 }
426 if (!(drawAsRailway(s) || drawAsWaterway(s)) || link->getState() != LINKSTATE_MAJOR) {
427 // the white bar should be the default for most railway
428 // links and looks ugly so we do not draw it
429 double scale = isInternal() ? 0.5 : 1;
430 if (myEdge->getToJunction()->getType() == SumoXMLNodeType::RAIL_SIGNAL) {
431 scale *= MAX2(s.laneWidthExaggeration, s.junctionSize.getExaggeration(s, this, 10));
432 }
433 glScaled(scale, scale, 1);
434 glBegin(GL_QUADS);
435 glVertex2d(x1 - myHalfLaneWidth, 0.0);
436 glVertex2d(x1 - myHalfLaneWidth, 0.5);
437 glVertex2d(x2 - myHalfLaneWidth, 0.5);
438 glVertex2d(x2 - myHalfLaneWidth, 0.0);
439 glEnd();
440 if (s.gaming && link->haveGreen()) {
441 const MSLane* lane = link->getLane();
442 // exaggerate green signals for railway game
443 if (isRailway(lane->getPermissions())) {
444 GLHelper::drawFilledCircle(lane->getWidth() / 2., 8, 90, 270);
445 }
446 }
447 }
450 }
451}
452
453void
454GUILane::drawArrows(bool secondaryShape) const {
455 if (myLinks.size() == 0) {
456 return;
457 }
458 // draw all links
459 const Position& end = getShape(secondaryShape).back();
460 const Position& f = getShape(secondaryShape)[-2];
461 const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
463 glColor3d(1, 1, 1);
464 glTranslated(end.x(), end.y(), 0);
465 glRotated(rot, 0, 0, 1);
467 glScaled(myWidth / SUMO_const_laneWidth, 1, 1);
468 }
469 for (const MSLink* const link : myLinks) {
470 LinkDirection dir = link->getDirection();
471 LinkState state = link->getState();
472 if (state == LINKSTATE_DEADEND || dir == LinkDirection::NODIR) {
473 continue;
474 }
475 switch (dir) {
477 GLHelper::drawBoxLine(Position(0, 4), 0, 2, .05);
478 GLHelper::drawTriangleAtEnd(Position(0, 4), Position(0, 1), (double) 1, (double) .25);
479 break;
481 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
482 GLHelper::drawBoxLine(Position(0, 2.5), 90, .5, .05);
483 GLHelper::drawBoxLine(Position(0.5, 2.5), 180, 1, .05);
484 GLHelper::drawTriangleAtEnd(Position(0.5, 2.5), Position(0.5, 4), (double) 1, (double) .25);
485 break;
487 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
488 GLHelper::drawBoxLine(Position(0, 2.5), -90, .5, .05);
489 GLHelper::drawBoxLine(Position(-0.5, 2.5), -180, 1, .05);
490 GLHelper::drawTriangleAtEnd(Position(-0.5, 2.5), Position(-0.5, 4), (double) 1, (double) .25);
491 break;
493 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
494 GLHelper::drawBoxLine(Position(0, 2.5), 90, 1, .05);
495 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.5, 2.5), (double) 1, (double) .25);
496 break;
498 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
499 GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
500 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.5, 2.5), (double) 1, (double) .25);
501 break;
503 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
504 GLHelper::drawBoxLine(Position(0, 2.5), 45, .7, .05);
505 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.2, 1.3), (double) 1, (double) .25);
506 break;
508 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
509 GLHelper::drawBoxLine(Position(0, 2.5), -45, .7, .05);
510 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.2, 1.3), (double) 1, (double) .25);
511 break;
512 default:
513 break;
514 }
515 }
517}
518
519
520void
521GUILane::drawLane2LaneConnections(double exaggeration, bool s2) const {
522 Position centroid;
523 if (exaggeration > 1) {
524 centroid = myEdge->getToJunction()->getShape().getCentroid();
525 }
526 for (const MSLink* const link : myLinks) {
527 const GUILane* connected = dynamic_cast<GUILane*>(link->getLane());
528 if (connected == nullptr) {
529 continue;
530 }
532 glBegin(GL_LINES);
533 Position p1 = myEdge->isWalkingArea() ? getShape(s2).getCentroid() : getShape(s2)[-1];
534 Position p2 = connected->isWalkingArea() ? connected->getShape(s2).getCentroid() : connected->getShape(s2)[0];
535 if (exaggeration > 1) {
536 p1 = centroid + ((p1 - centroid) * exaggeration);
537 p2 = centroid + ((p2 - centroid) * exaggeration);
538 }
539 glVertex2d(p1.x(), p1.y());
540 glVertex2d(p2.x(), p2.y());
541 glEnd();
542 GLHelper::drawTriangleAtEnd(p1, p2, (double) .4, (double) .2);
543 }
544}
545
546
547void
551 const bool s2 = s.secondaryShape;
552 double exaggeration = s.laneWidthExaggeration;
554 GUIEdge* myGUIEdge = dynamic_cast<GUIEdge*>(myEdge);
555 exaggeration *= s.edgeScaler.getScheme().getColor(myGUIEdge->getScaleValue(s, s.edgeScaler.getActive()));
556 } else {
557 exaggeration *= s.laneScaler.getScheme().getColor(getScaleValue(s, s.laneScaler.getActive(), s2));
558 }
559 // set lane color
560 const RGBColor color = setColor(s);
561 // recognize full transparency and simply don't draw
562 if (color.alpha() != 0 && s.scale * exaggeration > s.laneMinSize) {
563
564 const bool isCrossing = myEdge->isCrossing();
565 const bool isWalkingArea = myEdge->isWalkingArea();
566 const bool isInternal = isCrossing || isWalkingArea || myEdge->isInternal();
567 const PositionVector& baseShape = getShape(s2);
568 const bool hasRailSignal = myEdge->getToJunction()->getType() == SumoXMLNodeType::RAIL_SIGNAL;
569 if (s.trueZ) {
570 glTranslated(0, 0, baseShape.getMinZ());
571 } else {
572 if (isCrossing) {
573 // draw internal lanes on top of junctions
574 glTranslated(0, 0, GLO_JUNCTION + 0.1);
575 } else if (isWalkingArea) {
576 // draw internal lanes on top of junctions
577 glTranslated(0, 0, GLO_JUNCTION + 0.3);
578 } else if (isWaterway(myPermissions)) {
579 // draw waterways below normal roads
580 glTranslated(0, 0, getType() - 0.2);
581 } else if (myPermissions == SVC_SUBWAY) {
582 // draw subways further below
583 glTranslated(0, 0, getType() - 0.4);
584 } else {
585 glTranslated(0, 0, getType());
586 }
587 }
588 auto& shapeColors = getShapeColors(s2);
590 shapeColors.clear();
591 const std::vector<RGBColor>& segmentColors = static_cast<const GUIEdge*>(myEdge)->getSegmentColors();
592 if (segmentColors.size() > 0) {
593 // apply segment specific shape colors
594 //std::cout << getID() << " shape=" << myShape << " shapeSegs=" << toString(myShapeSegments) << "\n";
595 for (int ii = 0; ii < (int)baseShape.size() - 1; ++ii) {
596 shapeColors.push_back(segmentColors[myShapeSegments[ii]]);
597 }
598 }
599 }
600
601 // scale tls-controlled lane2lane-arrows along with their junction shapes
602 double junctionExaggeration = 1;
603 if (!isInternal
604 && myEdge->getToJunction()->getType() <= SumoXMLNodeType::RAIL_CROSSING
606 junctionExaggeration = MAX2(1.001, s.junctionSize.getExaggeration(s, this, 4));
607 }
608 // draw lane
609 // check whether it is not too small
610 if (s.scale * exaggeration < 1. && junctionExaggeration == 1 && s.junctionSize.minSize != 0) {
611 if (!isInternal || hasRailSignal) {
612 if (shapeColors.size() > 0) {
613 GLHelper::drawLine(baseShape, shapeColors);
614 } else {
615 GLHelper::drawLine(baseShape);
616 }
617 }
619
620 } else {
621
622 GUINet* net = (GUINet*) MSNet::getInstance();
623 bool mustDrawMarkings = false;
624 bool hiddenBidi = getBidiLane() != nullptr && myEdge->getNumericalID() > myEdge->getBidiEdge()->getNumericalID();
625 const bool detailZoom = s.scale * exaggeration > 5;
626 const bool drawDetails = (detailZoom || s.junctionSize.minSize == 0 || hasRailSignal);
627 const bool drawRails = drawAsRailway(s);
628 const bool spreadSuperposed = s.spreadSuperposed && myBidiLane != nullptr;
629 if (hiddenBidi && !spreadSuperposed) {
630 // do not draw shape
631 mustDrawMarkings = !isInternal && myPermissions != 0 && myPermissions != SVC_PEDESTRIAN && exaggeration == 1.0 && !isWaterway(myPermissions) && neighLaneNotBidi();
632 } else if (drawRails) {
633 // draw as railway: assume standard gauge of 1435mm when lane width is not set
634 // draw foot width 150mm, assume that distance between rail feet inner sides is reduced on both sides by 39mm with regard to the gauge
635 // assume crosstie length of 181% gauge (2600mm for standard gauge)
636 PositionVector shape = baseShape;
637 const double width = myWidth;
638 double halfGauge = 0.5 * (width == SUMO_const_laneWidth ? 1.4350 : width) * exaggeration;
639 if (spreadSuperposed) {
640 try {
641 shape.move2side(halfGauge * 0.8);
642 } catch (InvalidArgument&) {}
643 halfGauge *= 0.4;
644 }
645 const double halfInnerFeetWidth = halfGauge - 0.039 * exaggeration;
646 const double halfRailWidth = detailZoom ? (halfInnerFeetWidth + 0.15 * exaggeration) : SUMO_const_halfLaneWidth * exaggeration;
647 const double halfCrossTieWidth = halfGauge * 1.81;
648 if (shapeColors.size() > 0) {
649 GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), getShapeColors(s2), halfRailWidth);
650 } else {
651 GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), halfRailWidth);
652 }
653 // Draw white on top with reduced width (the area between the two tracks)
654 if (detailZoom) {
655 glColor3d(1, 1, 1);
656 glTranslated(0, 0, .1);
657 GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), halfInnerFeetWidth);
658 setColor(s);
659 GLHelper::drawCrossTies(shape, getShapeRotations(s2), getShapeLengths(s2), 0.26 * exaggeration, 0.6 * exaggeration,
660 halfCrossTieWidth, 0, s.forceDrawForRectangleSelection);
661 }
662 } else if (isCrossing) {
663 if (s.drawCrossingsAndWalkingareas && (s.scale > 3.0 || s.junctionSize.minSize == 0)) {
664 glTranslated(0, 0, .2);
665 GLHelper::drawCrossTies(baseShape, getShapeRotations(s2), getShapeLengths(s2), 0.5, 1.0, getWidth() * 0.5,
667#ifdef GUILane_DEBUG_DRAW_CROSSING_OUTLINE
668 if (myOutlineShape != nullptr) {
670 glTranslated(0, 0, 0.4);
672 glTranslated(0, 0, -0.4);
673 if (s.geometryIndices.show(this)) {
675 }
676 }
677#endif
678 glTranslated(0, 0, -.2);
679 }
680 } else if (isWalkingArea) {
681 if (s.drawCrossingsAndWalkingareas && (s.scale > 3.0 || s.junctionSize.minSize == 0)) {
682 glTranslated(0, 0, .2);
683 if (myTesselation == nullptr) {
685 }
686 myTesselation->drawTesselation(baseShape);
687 glTranslated(0, 0, -.2);
688 if (s.geometryIndices.show(this)) {
690 }
691 }
692 } else {
693 // we draw the lanes with reduced width so that the lane markings below are visible
694 // (this avoids artifacts at geometry corners without having to
695 // compute lane-marking intersection points)
697 mustDrawMarkings = !isInternal && myPermissions != 0 && myPermissions != SVC_PEDESTRIAN && exaggeration == 1.0 && !isWaterway(myPermissions) && !isAirway(myPermissions);
698 const int cornerDetail = drawDetails && !isInternal ? (s.drawForRectangleSelection ? 4 : MIN2(32, (int)(s.scale * exaggeration))) : 0;
699 double offset = halfWidth * MAX2(0., (exaggeration - 1)) * (MSGlobals::gLefthand ? -1 : 1);
700 if (spreadSuperposed) {
701 offset += halfWidth * 0.5 * (MSGlobals::gLefthand ? -1 : 1);
702 halfWidth *= 0.4; // create visible gap
703 }
704 if (shapeColors.size() > 0) {
705 GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), shapeColors, halfWidth * exaggeration, cornerDetail, offset);
706 } else {
707 GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), halfWidth * exaggeration, cornerDetail, offset);
708 }
709 }
711#ifdef GUILane_DEBUG_DRAW_FOE_INTERSECTIONS
712 if (myEdge->isInternal() && gSelected.isSelected(getType(), getGlID())) {
714 }
715#endif
716 if (s.geometryIndices.show(this)) {
718 }
719 // draw details
720 if ((!isInternal || isCrossing || !s.drawJunctionShape) && (drawDetails || junctionExaggeration > 1)) {
722 glTranslated(0, 0, GLO_JUNCTION); // must draw on top of junction shape
723 glTranslated(0, 0, .5);
724 if (drawDetails) {
725 if (s.showLaneDirection) {
726 if (drawRails) {
727 // improve visibility of superposed rail edges
728 GLHelper::setColor(setColor(s).changedBrightness(100));
729 } else {
730 glColor3d(0.3, 0.3, 0.3);
731 }
733 drawDirectionIndicators(exaggeration, spreadSuperposed, s.secondaryShape);
734 }
735 }
736 if (!isInternal || isCrossing
737 // controlled internal junction
738 || (getLinkCont().size() != 0 && getLinkCont()[0]->isInternalJunctionLink() && getLinkCont()[0]->getTLLogic() != nullptr)) {
739 if (MSGlobals::gLateralResolution > 0 && s.showSublanes && !hiddenBidi && (myPermissions & ~(SVC_PEDESTRIAN | SVC_RAIL_CLASSES)) != 0) {
740 // draw sublane-borders
741 const double offsetSign = MSGlobals::gLefthand ? -1 : 1;
743 for (double offset = -myHalfLaneWidth; offset < myHalfLaneWidth; offset += MSGlobals::gLateralResolution) {
744 GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), 0.01, 0, -offset * offsetSign);
745 }
746 }
748 // draw segment borders
750 for (int i : mySegmentStartIndex) {
751 if (shapeColors.size() > 0) {
752 GLHelper::setColor(shapeColors[i].changedBrightness(51));
753 }
754 GLHelper::drawBoxLine(baseShape[i], getShapeRotations(s2)[i] + 90, myWidth / 3, 0.2, 0);
755 GLHelper::drawBoxLine(baseShape[i], getShapeRotations(s2)[i] - 90, myWidth / 3, 0.2, 0);
756 }
757 }
758 if (s.showLinkDecals && !drawRails && !drawAsWaterway(s) && myPermissions != SVC_PEDESTRIAN) {
760 }
761 glTranslated(0, 0, 1000);
762 if (s.drawLinkJunctionIndex.show(nullptr)) {
763 drawLinkNo(s);
764 }
765 if (s.drawLinkTLIndex.show(nullptr)) {
766 drawTLSLinkNo(s, *net);
767 }
768 glTranslated(0, 0, -1000);
769 }
770 glTranslated(0, 0, .1);
771 }
772 if ((drawDetails || junctionExaggeration > 1) && s.showLane2Lane) {
773 // draw from end of first to the begin of second but respect junction scaling
774 drawLane2LaneConnections(junctionExaggeration, s.secondaryShape);
775 }
777 // make sure link rules are drawn so tls can be selected via right-click
778 if (s.showLinkRules && drawDetails && !isWalkingArea &&
779 (!myEdge->isInternal() || (getLinkCont().size() > 0 && getLinkCont()[0]->isInternalJunctionLink()))) {
781 glTranslated(0, 0, GLO_SHAPE); // must draw on top of junction shape and additionals
782 drawLinkRules(s, *net);
784 }
785 }
786 if (mustDrawMarkings && drawDetails && s.laneShowBorders) { // needs matrix reset
787 drawMarkings(s, exaggeration);
788 }
789 if (drawDetails && isInternal && s.showBikeMarkings && myPermissions == SVC_BICYCLE && exaggeration == 1.0 && s.showLinkDecals && s.laneShowBorders && !hiddenBidi
793 }
794 if (drawDetails && isInternal && exaggeration == 1.0 && s.showLinkDecals && s.laneShowBorders && !hiddenBidi && myIndex > 0
795 && !(myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER) && allowsChangingRight(SVC_PASSENGER))) {
796 // draw lane changing prohibitions on junction
798 }
799 }
800 } else {
802 }
803 // draw vehicles
804 if (s.scale * s.vehicleSize.getExaggeration(s, nullptr) > s.vehicleSize.minSize) {
805 // retrieve vehicles from lane; disallow simulation
806 const MSLane::VehCont& vehicles = getVehiclesSecure();
807 for (MSLane::VehCont::const_iterator v = vehicles.begin(); v != vehicles.end(); ++v) {
808 if ((*v)->getLane() == this) {
809 static_cast<const GUIVehicle*>(*v)->drawGL(s);
810 } // else: this is the shadow during a continuous lane change
811 }
812 // draw long partial vehicles (#14342)
813 for (const MSVehicle* veh : myPartialVehicles) {
814 if (veh->getLength() > RENDERING_BUFFER) {
815 // potential double rendering taken into account
816 static_cast<const GUIVehicle*>(veh)->drawGL(s);
817 }
818 }
819 // draw parking vehicles
820 for (const MSBaseVehicle* const v : myParkingVehicles) {
821 dynamic_cast<const GUIBaseVehicle*>(v)->drawGL(s);
822 }
823 // allow lane simulation
825 }
827}
828
829bool
831 const MSLane* right = getParallelLane(-1, false);
832 if (right && right->getBidiLane() == nullptr) {
833 return true;
834 }
835 const MSLane* left = getParallelLane(1, false);
836 if (left && left->getBidiLane() == nullptr) {
837 return true;
838 }
839 return false;
840}
841
842void
843GUILane::drawMarkings(const GUIVisualizationSettings& s, double scale) const {
845 glTranslated(0, 0, GLO_EDGE);
846 setColor(s);
847 // optionally draw inverse markings
848 const bool s2 = s.secondaryShape;
849 if (myIndex > 0 && (myEdge->getLanes()[myIndex - 1]->getPermissions() & myPermissions) != 0) {
850 const bool cl = myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER);
851 const bool cr = allowsChangingRight(SVC_PASSENGER);
853 }
854 // draw white boundings and white markings
855 glColor3d(1, 1, 1);
857 getShape(s2),
859 getShapeLengths(s2),
862}
863
864
865void
867 // draw bike lane markings onto the intersection
868 glColor3d(1, 1, 1);
870 const bool s2 = false;
871 const int e = (int) getShape(s2).size() - 1;
872 const double markWidth = 0.1;
873 const double mw = myHalfLaneWidth;
874 for (int i = 0; i < e; ++i) {
876 glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), GLO_JUNCTION + 0.4);
877 glRotated(getShapeRotations(s2)[i], 0, 0, 1);
878 for (double t = 0; t < getShapeLengths(s2)[i]; t += 0.5) {
879 // left and right marking
880 for (int side = -1; side <= 1; side += 2) {
881 glBegin(GL_QUADS);
882 glVertex2d(side * mw, -t);
883 glVertex2d(side * mw, -t - 0.35);
884 glVertex2d(side * (mw + markWidth), -t - 0.35);
885 glVertex2d(side * (mw + markWidth), -t);
886 glEnd();
887 }
888 }
890 }
891}
892
893
894void
896 // fixme
897 const bool s2 = false;
898 // draw white markings
899 if (myIndex > 0 && (myEdge->getLanes()[myIndex - 1]->getPermissions() & myPermissions) != 0) {
900 glColor3d(1, 1, 1);
901 const bool cl = myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER);
902 const bool cr = allowsChangingRight(SVC_PASSENGER);
903 // solid line marking
904 double mw, mw2;
905 // optional broken line marking
906 double mw3, mw4;
907 if (!cl && !cr) {
908 // draw a single solid line
911 mw3 = myHalfLaneWidth;
912 mw4 = myHalfLaneWidth;
913 } else {
914 // draw one solid and one broken line
915 if (cl) {
920 } else {
925 }
926 }
928 mw *= -1;
929 mw2 *= -1;
930 }
931 int e = (int) getShape(s2).size() - 1;
932 for (int i = 0; i < e; ++i) {
934 glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), GLO_JUNCTION + 0.4);
935 glRotated(getShapeRotations(s2)[i], 0, 0, 1);
936 for (double t = 0; t < getShapeLengths(s2)[i]; t += 6) {
937 const double lengthSolid = MIN2(6.0, getShapeLengths(s2)[i] - t);
938 glBegin(GL_QUADS);
939 glVertex2d(-mw, -t);
940 glVertex2d(-mw, -t - lengthSolid);
941 glVertex2d(-mw2, -t - lengthSolid);
942 glVertex2d(-mw2, -t);
943 glEnd();
944 if (cl || cr) {
945 const double lengthBroken = MIN2(3.0, getShapeLengths(s2)[i] - t);
946 glBegin(GL_QUADS);
947 glVertex2d(-mw3, -t);
948 glVertex2d(-mw3, -t - lengthBroken);
949 glVertex2d(-mw4, -t - lengthBroken);
950 glVertex2d(-mw4, -t);
951 glEnd();
952 }
953 }
955 }
956 }
957}
958
959void
960GUILane::drawDirectionIndicators(double exaggeration, bool spreadSuperposed, bool s2) const {
962 glTranslated(0, 0, GLO_EDGE);
963 int e = (int) getShape(s2).size() - 1;
964 const double widthFactor = spreadSuperposed ? 0.4 : 1;
965 const double w = MAX2(POSITION_EPS, myWidth * widthFactor);
966 const double w2 = MAX2(POSITION_EPS, myHalfLaneWidth * widthFactor);
967 const double w4 = MAX2(POSITION_EPS, myQuarterLaneWidth * widthFactor);
968 const double sideOffset = spreadSuperposed ? w * -0.5 : 0;
969 for (int i = 0; i < e; ++i) {
971 glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), 0.1);
972 glRotated(getShapeRotations(s2)[i], 0, 0, 1);
973 for (double t = 0; t < getShapeLengths(s2)[i]; t += w) {
974 const double length = MIN2(w2, getShapeLengths(s2)[i] - t) * exaggeration;
975 glBegin(GL_TRIANGLES);
976 glVertex2d(sideOffset, -t - length);
977 glVertex2d(sideOffset - w4 * exaggeration, -t);
978 glVertex2d(sideOffset + w4 * exaggeration, -t);
979 glEnd();
980 }
982 }
984}
985
986
987void
990 glTranslated(0, 0, 5);
991 glColor3d(1.0, 0.3, 0.3);
992 const double orthoLength = 0.5;
993 const MSLink* link = getLinkCont().front();
994 const std::vector<const MSLane*>& foeLanes = link->getFoeLanes();
995 const auto& conflicts = link->getConflicts();
996 if (foeLanes.size() == conflicts.size()) {
997 for (int i = 0; i < (int)foeLanes.size(); ++i) {
998 const MSLane* l = foeLanes[i];
999 Position pos = l->geometryPositionAtOffset(l->getLength() - conflicts[i].lengthBehindCrossing);
1000 PositionVector ortho = l->getShape().getOrthogonal(pos, 10, true, orthoLength);
1001 if (ortho.length() < orthoLength) {
1002 ortho.extrapolate(orthoLength - ortho.length(), false, true);
1003 }
1004 GLHelper::drawLine(ortho);
1005 //std::cout << "foe=" << l->getID() << " lanePos=" << l->getLength() - conflicts[i].lengthBehindCrossing << " pos=" << pos << "\n";
1006 }
1007 }
1009}
1010
1011
1012// ------ inherited from GUIGlObject
1015 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
1016 buildPopupHeader(ret, app);
1018 //
1019 GUIDesigns::buildFXMenuCommand(ret, TL("Copy edge name to clipboard"), nullptr, ret, MID_COPY_EDGE_NAME);
1022 //
1023 buildShowParamsPopupEntry(ret, false);
1024 const PositionVector& baseShape = getShape(parent.getVisualisationSettings().secondaryShape);
1025 const double pos = interpolateGeometryPosToLanePos(baseShape.nearest_offset_to_point25D(parent.getPositionInformation()));
1026 const double height = baseShape.positionAtOffset(pos).z();
1027 GUIDesigns::buildFXMenuCommand(ret, (TL("pos: ") + toString(pos) + " " + TL("height: ") + toString(height)).c_str(), nullptr, nullptr, 0);
1028 if (getEdge().hasDistance()) {
1029 GUIDesigns::buildFXMenuCommand(ret, ("distance: " + toString(getEdge().getDistanceAt(pos))).c_str(), nullptr, nullptr, 0);
1030 }
1031 new FXMenuSeparator(ret);
1032 buildPositionCopyEntry(ret, app);
1033 new FXMenuSeparator(ret);
1034 if (myAmClosed) {
1035 if (myPermissionChanges.empty()) {
1036 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen lane"), nullptr, &parent, MID_CLOSE_LANE);
1037 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen edge"), nullptr, &parent, MID_CLOSE_EDGE);
1038 } else {
1039 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen lane (override rerouter)"), nullptr, &parent, MID_CLOSE_LANE);
1040 GUIDesigns::buildFXMenuCommand(ret, TL("Reopen edge (override rerouter)"), nullptr, &parent, MID_CLOSE_EDGE);
1041 }
1042 } else {
1043 GUIDesigns::buildFXMenuCommand(ret, TL("Close lane"), nullptr, &parent, MID_CLOSE_LANE);
1044 GUIDesigns::buildFXMenuCommand(ret, TL("Close edge"), nullptr, &parent, MID_CLOSE_EDGE);
1045 }
1046 GUIDesigns::buildFXMenuCommand(ret, TL("Add rerouter"), nullptr, &parent, MID_ADD_REROUTER);
1047 new FXMenuSeparator(ret);
1048 // reachability menu
1049 FXMenuPane* reachableByClass = new FXMenuPane(ret);
1050 ret->insertMenuPaneChild(reachableByClass);
1051 new FXMenuCascade(ret, TL("Select reachable"), GUIIconSubSys::getIcon(GUIIcon::FLAG), reachableByClass);
1052 for (auto i : SumoVehicleClassStrings.getStrings()) {
1054 }
1055 return ret;
1056}
1057
1058
1062 GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
1063 // add items
1064 ret->mkItem(TL("allowed speed [m/s]"), false, getSpeedLimit());
1065 const std::map<SUMOVehicleClass, double>* restrictions = MSNet::getInstance()->getRestrictions(myEdge->getEdgeType());
1066 if (restrictions != nullptr) {
1067 for (const auto& elem : *restrictions) {
1068 ret->mkItem((std::string(" ") + TL("allowed speed [m/s]") + std::string(": ") + toString(elem.first)).c_str(), false, elem.second);
1069 }
1070 }
1071 ret->mkItem(TL("length [m]"), false, myLength);
1072 ret->mkItem(TL("width [m]"), false, myWidth);
1073 ret->mkItem(TL("street name"), false, myEdge->getStreetName());
1074 ret->mkItem(TL("stored travel time [s]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getStoredEdgeTravelTime));
1075 ret->mkItem(TL("loaded weight"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getLoadedEdgeWeight));
1076 ret->mkItem(TL("routing speed [m/s]"), true, new FunctionBinding<MSEdge, double>(myEdge, &MSEdge::getRoutingSpeed));
1077 ret->mkItem(TL("lane friction coefficient [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getFrictionCoefficient));
1078 ret->mkItem(TL("time penalty [s]"), true, new FunctionBinding<MSEdge, double>(myEdge, &MSEdge::getTimePenalty));
1079 ret->mkItem(TL("brutto occupancy [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getBruttoOccupancy, 100.));
1080 ret->mkItem(TL("netto occupancy [%]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getNettoOccupancy, 100.));
1081 ret->mkItem(TL("pending insertions [#]"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getPendingEmits));
1082 ret->mkItem(TL("edge type"), false, myEdge->getEdgeType());
1083 ret->mkItem(TL("routing type"), false, myEdge->getRoutingType());
1084 ret->mkItem(TL("type"), false, myLaneType);
1085 ret->mkItem(TL("priority"), false, myEdge->getPriority());
1086 ret->mkItem(TL("distance [km]"), false, myEdge->getDistance() / 1000);
1087 ret->mkItem(TL("allowed vehicle class"), false, StringUtils::wrapText(getVehicleClassNames(myPermissions), 60));
1088 ret->mkItem(TL("disallowed vehicle class"), false, StringUtils::wrapText(getVehicleClassNames(~myPermissions), 60));
1089 ret->mkItem(TL("permission code"), false, myPermissions);
1090 ret->mkItem(TL("color value"), true, new FunctionBinding<GUILane, double>(this, &GUILane::getColorValueForTracker));
1091 if (myBidiLane != nullptr) {
1092 ret->mkItem(TL("bidi-lane"), false, myBidiLane->getID());
1093 }
1094 // info for blocked departDriveWay
1095 for (auto item : getParametersMap()) {
1096 if (StringUtils::startsWith(item.first, "insertionBlocked:")) {
1097 const MSDriveWay* dw = MSDriveWay::retrieveDepartDriveWay(myEdge, item.second);
1098 if (dw != nullptr) {
1099 ret->mkItem(("blocking " + dw->getID()).c_str(), false, toString(MSRailSignal::getBlockingVehicles(dw)));
1100 ret->mkItem(("driveWays blocking " + dw->getID()).c_str(), false, toString(MSRailSignal::getBlockingDriveWays(dw)));
1101 }
1102 }
1103 }
1104
1105 for (const auto& kv : myEdge->getParametersMap()) {
1106 ret->mkItem(("edgeParam:" + kv.first).c_str(), false, kv.second);
1107 }
1108 ret->checkFont(myEdge->getStreetName());
1109 ret->closeBuilding();
1110 return ret;
1111}
1112
1113
1116 const PositionVector& shape = GUIGlobals::gSecondaryShape && myShape2.size() > 0 ? myShape2 : myShape;
1117 Boundary b;
1118 b.add(shape[0]);
1119 b.add(shape[-1]);
1120 b.grow(RENDERING_BUFFER);
1121 // ensure that vehicles and persons on the side are drawn even if the edge
1122 // is outside the view
1123 return b;
1124}
1125
1126
1127const PositionVector&
1128GUILane::getShape(bool secondary) const {
1129 return secondary && myShape2.size() > 0 ? myShape2 : myShape;
1130}
1131
1132
1133const std::vector<double>&
1134GUILane::getShapeRotations(bool secondary) const {
1135 return secondary && myShapeRotations2.size() > 0 ? myShapeRotations2 : myShapeRotations;
1136}
1137
1138
1139const std::vector<double>&
1140GUILane::getShapeLengths(bool secondary) const {
1141 return secondary && myShapeLengths2.size() > 0 ? myShapeLengths2 : myShapeLengths;
1142}
1143
1144
1145std::vector<RGBColor>&
1146GUILane::getShapeColors(bool secondary) const {
1147 return secondary && myShapeColors2.size() > 0 ? myShapeColors2 : myShapeColors;
1148}
1149
1150
1151double
1153 return myVehicles.size() == 0 ? 0 : myVehicles.back()->getWaitingSeconds();
1154}
1155
1156
1157double
1159 return (double) myEdge->getLanes().size();
1160}
1161
1162
1163double
1166 if (!ews.knowsTravelTime(myEdge)) {
1167 return -1;
1168 } else {
1169 double value(0);
1171 return value;
1172 }
1173}
1174
1175
1176double
1179 if (!ews.knowsEffort(myEdge)) {
1180 return -1;
1181 } else {
1182 double value(-1);
1183 ews.retrieveExistingEffort(myEdge, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), value);
1184 return value;
1185 }
1186}
1187
1188
1189double
1191 switch (activeScheme) {
1192 case 18: {
1194 }
1195 default:
1196 return getColorValue(s, activeScheme);
1197 }
1198
1199}
1200
1201
1204 // setting and retrieving the color does not work in OSGView so we return it explicitliy
1205 RGBColor col;
1206 if (MSGlobals::gUseMesoSim && static_cast<const GUIEdge*>(myEdge)->getMesoColor() != MESO_USE_LANE_COLOR) {
1207 col = static_cast<const GUIEdge*>(myEdge)->getMesoColor();
1208 } else {
1209 const GUIColorer& c = s.laneColorer;
1210 if (!setFunctionalColor(c, col) && !setMultiColor(s, c, col)) {
1211 col = c.getScheme().getColor(getColorValue(s, c.getActive()));
1212 }
1213 }
1214 GLHelper::setColor(col);
1215 return col;
1216}
1217
1218
1219bool
1220GUILane::setFunctionalColor(const GUIColorer& c, RGBColor& col, int activeScheme) const {
1221 if (activeScheme < 0) {
1222 activeScheme = c.getActive();
1223 }
1224 switch (activeScheme) {
1225 case 0:
1226 if (myEdge->isCrossing()) {
1227 // determine priority to decide color
1228 const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
1229 if (link->havePriority() || link->getTLLogic() != nullptr) {
1230 col = RGBColor(230, 230, 230);
1231 } else {
1232 col = RGBColor(26, 26, 26);
1233 }
1234 GLHelper::setColor(col);
1235 return true;
1236 } else {
1237 return false;
1238 }
1239 case 18: {
1240 double hue = GeomHelper::naviDegree(myShape.beginEndAngle()); // [0-360]
1241 col = RGBColor::fromHSV(hue, 1., 1.);
1242 GLHelper::setColor(col);
1243 return true;
1244 }
1245 case 30: { // taz color
1246 col = c.getScheme().getColor(0);
1247 std::vector<RGBColor> tazColors;
1248 for (MSEdge* e : myEdge->getPredecessors()) {
1249 if (e->isTazConnector() && e->hasParameter("tazColor")) {
1250 tazColors.push_back(RGBColor::parseColor(e->getParameter("tazColor")));
1251 }
1252 }
1253 for (MSEdge* e : myEdge->getSuccessors()) {
1254 if (e->isTazConnector() && e->hasParameter("tazColor")) {
1255 tazColors.push_back(RGBColor::parseColor(e->getParameter("tazColor")));
1256 }
1257 }
1258 if (tazColors.size() > 0) {
1259 int randColor = RandHelper::rand((int)tazColors.size(), RGBColor::getColorRNG());
1260 col = tazColors[randColor];
1261 }
1262 GLHelper::setColor(col);
1263 return true;
1264 }
1265 default:
1266 return false;
1267 }
1268}
1269
1270
1271bool
1273 const int activeScheme = c.getActive();
1274 auto& shapeColors = getShapeColors(s.secondaryShape);
1275 const PositionVector& shape = getShape(s.secondaryShape);
1276 shapeColors.clear();
1277 switch (activeScheme) {
1278 case 22: // color by height at segment start
1279 for (PositionVector::const_iterator ii = shape.begin(); ii != shape.end() - 1; ++ii) {
1280 shapeColors.push_back(c.getScheme().getColor(ii->z()));
1281 }
1282 // osg fallback (edge height at start)
1283 col = c.getScheme().getColor(getColorValue(s, 21));
1284 return true;
1285 case 24: // color by inclination at segment start
1286 for (int ii = 1; ii < (int)shape.size(); ++ii) {
1287 const double inc = (shape[ii].z() - shape[ii - 1].z()) / MAX2(POSITION_EPS, shape[ii].distanceTo2D(shape[ii - 1]));
1288 shapeColors.push_back(c.getScheme().getColor(inc));
1289 }
1290 col = c.getScheme().getColor(getColorValue(s, 23));
1291 return true;
1292 default:
1293 return false;
1294 }
1295}
1296
1297double
1299 if (myCachedGUISettings != nullptr) {
1301 const GUIColorer& c = s.laneColorer;
1302 double val = getColorValueWithFunctional(s, c.getActive());
1304 // blowing up the dialog or plot isn't helpful. At least 0 may be understood as neutral
1305 return 0;
1306 } else {
1307 return val;
1308 }
1309 } else {
1310 return 0;
1311 }
1312}
1313
1314
1315double
1316GUILane::getColorValue(const GUIVisualizationSettings& s, int activeScheme) const {
1317 switch (activeScheme) {
1318 case 0:
1319 switch (myPermissions) {
1320 case SVC_PEDESTRIAN:
1321 return 1;
1322 case SVC_BICYCLE:
1323 return 2;
1324 case 0:
1325 // forbidden road or green verge
1326 return myEdge->getPermissions() == 0 ? 10 : 3;
1327 case SVC_SHIP:
1328 return 4;
1329 case SVC_AUTHORITY:
1330 return 8;
1331 case SVC_AIRCRAFT:
1332 case SVC_DRONE:
1333 return 11;
1334 default:
1335 break;
1336 }
1337 if (myEdge->isTazConnector()) {
1338 return 9;
1339 } else if (isRailway(myPermissions)) {
1340 return 5;
1341 } else if ((myPermissions & SVC_PASSENGER) != 0) {
1342 if ((myPermissions & (SVC_RAIL_CLASSES & ~SVC_RAIL_FAST)) != 0 && (myPermissions & SVC_SHIP) == 0) {
1343 return 6;
1344 } else {
1345 return 0;
1346 }
1347 } else {
1348 if ((myPermissions & SVC_RAIL_CLASSES) != 0 && (myPermissions & SVC_SHIP) == 0) {
1349 return 6;
1350 } else {
1351 return 7;
1352 }
1353 }
1354 case 1:
1355 return isLaneOrEdgeSelected();
1356 case 2:
1357 return (double)myPermissions;
1358 case 3:
1359 return getSpeedLimit();
1360 case 4:
1361 return getBruttoOccupancy();
1362 case 5:
1363 return getNettoOccupancy();
1364 case 6:
1365 return firstWaitingTime();
1366 case 7:
1367 return getEdgeLaneNumber();
1368 case 8:
1370 case 9:
1372 case 10:
1374 case 11:
1376 case 12:
1378 case 13:
1380 case 14:
1382 case 15: {
1383 return getStoredEdgeTravelTime();
1384 }
1385 case 16: {
1387 if (!ews.knowsTravelTime(myEdge)) {
1388 return -1;
1389 } else {
1390 double value(0);
1392 return 100 * myLength / value / getSpeedLimit();
1393 }
1394 }
1395 case 17: {
1396 // geometrical length has no meaning for walkingAreas since it describes the outer boundary
1397 return myEdge->isWalkingArea() ? 1 : 1 / getLengthGeometryFactor(s.secondaryShape);
1398 }
1399 case 19: {
1400 return getLoadedEdgeWeight();
1401 }
1402 case 20: {
1403 return myEdge->getPriority();
1404 }
1405 case 21: {
1406 // color by z of first shape point
1407 return getShape(s.secondaryShape)[0].z();
1408 }
1409 case 23: {
1410 // color by incline
1411 return (getShape(s.secondaryShape)[-1].z() - getShape(s.secondaryShape)[0].z()) / getLength();
1412 }
1413 case 25: {
1414 // color by average speed
1415 return getMeanSpeed();
1416 }
1417 case 26: {
1418 // color by average relative speed
1419 return getMeanSpeed() / myMaxSpeed;
1420 }
1421 case 27: {
1422 // color by routing device assumed speed
1423 return myEdge->getRoutingSpeed();
1424 }
1425 case 28:
1427 case 29:
1428 return getPendingEmits();
1429 case 31: {
1430 // by numerical edge param value
1431 if (myEdge->hasParameter(s.edgeParam)) {
1432 try {
1433 return StringUtils::toDouble(myEdge->getParameter(s.edgeParam, "0"));
1434 } catch (NumberFormatException&) {
1435 try {
1436 return StringUtils::toBool(myEdge->getParameter(s.edgeParam, "0"));
1437 } catch (BoolFormatException&) {
1439 }
1440 }
1441 } else {
1443 }
1444 }
1445 case 32: {
1446 // by numerical lane param value
1447 if (hasParameter(s.laneParam)) {
1448 try {
1450 } catch (NumberFormatException&) {
1451 try {
1453 } catch (BoolFormatException&) {
1455 }
1456 }
1457 } else {
1459 }
1460 }
1461 case 33: {
1462 // by edge data value
1464 }
1465 case 34: {
1466 return myEdge->getDistance();
1467 }
1468 case 35: {
1469 return fabs(myEdge->getDistance());
1470 }
1471 case 36: {
1472 return myReachability;
1473 }
1474 case 37: {
1476 }
1477 case 38: {
1478 if (myParkingAreas == nullptr) {
1479 // init
1480 myParkingAreas = new std::vector<MSParkingArea*>();
1481 for (auto& item : MSNet::getInstance()->getStoppingPlaces(SUMO_TAG_PARKING_AREA)) {
1482 if (&item.second->getLane().getEdge() == myEdge) {
1483 myParkingAreas->push_back(dynamic_cast<MSParkingArea*>(item.second));
1484 }
1485 }
1486 }
1487 int capacity = 0;
1488 for (MSParkingArea* pa : *myParkingAreas) {
1489 capacity += pa->getCapacity() - pa->getOccupancy();
1490 }
1491 return capacity;
1492 }
1493 case 39: {
1494 // by live edge data value
1496 }
1497 }
1498 return 0;
1499}
1500
1501
1502double
1503GUILane::getScaleValue(const GUIVisualizationSettings& s, int activeScheme, bool s2) const {
1504 switch (activeScheme) {
1505 case 0:
1506 return 0;
1507 case 1:
1508 return isLaneOrEdgeSelected();
1509 case 2:
1510 return getSpeedLimit();
1511 case 3:
1512 return getBruttoOccupancy();
1513 case 4:
1514 return getNettoOccupancy();
1515 case 5:
1516 return firstWaitingTime();
1517 case 6:
1518 return getEdgeLaneNumber();
1519 case 7:
1521 case 8:
1523 case 9:
1525 case 10:
1527 case 11:
1529 case 12:
1531 case 13:
1533 case 14: {
1534 return getStoredEdgeTravelTime();
1535 }
1536 case 15: {
1538 if (!ews.knowsTravelTime(myEdge)) {
1539 return -1;
1540 } else {
1541 double value(0);
1543 return 100 * myLength / value / getSpeedLimit();
1544 }
1545 }
1546 case 16: {
1547 return 1 / getLengthGeometryFactor(s2);
1548 }
1549 case 17: {
1550 return getLoadedEdgeWeight();
1551 }
1552 case 18: {
1553 return myEdge->getPriority();
1554 }
1555 case 19: {
1556 // scale by average speed
1557 return getMeanSpeed();
1558 }
1559 case 20: {
1560 // scale by average relative speed
1561 return getMeanSpeed() / myMaxSpeed;
1562 }
1563 case 21:
1565 case 22:
1567 case 23:
1568 // by edge data value
1570 }
1571 return 0;
1572}
1573
1574
1575bool
1579
1580
1581bool
1583 return isWaterway(myPermissions) && s.showRails; // reusing the showRails setting
1584}
1585
1586
1587#ifdef HAVE_OSG
1588void
1589GUILane::updateColor(const GUIVisualizationSettings& s) {
1590 if (myGeom == 0) {
1591 // not drawn
1592 return;
1593 }
1594 const RGBColor col = setColor(s);
1595 osg::Vec4ubArray* colors = dynamic_cast<osg::Vec4ubArray*>(myGeom->getColorArray());
1596 (*colors)[0].set(col.red(), col.green(), col.blue(), col.alpha());
1597 myGeom->setColorArray(colors);
1598}
1599#endif
1600
1601
1602void
1603GUILane::closeTraffic(bool rebuildAllowed) {
1605 if (myAmClosed) {
1606 myPermissionChanges.clear(); // reset rerouters
1608 } else {
1610 }
1612 if (rebuildAllowed) {
1614 }
1615}
1616
1617
1620 assert(MSGlobals::gUseMesoSim);
1621 const MESegment::MesoEdgeType& edgeType = MSNet::getInstance()->getMesoType(getEdge().getEdgeType());
1622 int no = MELoop::numSegmentsFor(myLength, edgeType.edgeLength);
1623 const double slength = myLength / no;
1624 PositionVector result = shape;
1625 double offset = 0;
1626 for (int i = 0; i < no; ++i) {
1627 offset += slength;
1629 int index = result.indexOfClosest(pos);
1630 if (pos.distanceTo(result[index]) > POSITION_EPS) {
1631 index = result.insertAtClosest(pos, false);
1632 }
1633 if (i != no - 1) {
1634 mySegmentStartIndex.push_back(index);
1635 }
1636 while ((int)myShapeSegments.size() < index) {
1637 myShapeSegments.push_back(i);
1638 }
1639 //std::cout << "splitAtSegments " << getID() << " no=" << no << " i=" << i << " offset=" << offset << " index=" << index << " segs=" << toString(myShapeSegments) << " resultSize=" << result.size() << " result=" << toString(result) << "\n";
1640 }
1641 while (myShapeSegments.size() < result.size()) {
1642 myShapeSegments.push_back(no - 1);
1643 }
1644 return result;
1645}
1646
1647bool
1649 return gSelected.isSelected(GLO_LANE, getGlID());
1650}
1651
1652bool
1654 return isSelected() || gSelected.isSelected(GLO_EDGE, dynamic_cast<GUIEdge*>(myEdge)->getGlID());
1655}
1656
1657double
1661
1662double
1665 // do not select lanes in meso mode
1666 return INVALID_PRIORITY;
1667 }
1668 if (myEdge->isCrossing()) {
1669 return GLO_CROSSING;
1670 }
1671 return GLO_LANE;
1672}
1673
1674
1675/****************************************************************************/
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
GUIPropertySchemeStorage< GUIColorScheme > GUIColorer
#define RAD2DEG(x)
Definition GeomHelper.h:36
#define TL(string)
Definition MsgHandler.h:304
const std::string invalid_return< std::string >::value
#define STEPS2TIME(x)
Definition SUMOTime.h:58
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a (exclusive) railway edge.
bool isWaterway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a waterway edge.
bool isAirway(SVCPermissions permissions)
Returns whether an edge with the given permissions is an airway edge.
const std::string & getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a ' '.
StringBijection< SUMOVehicleClass > SumoVehicleClassStrings(sumoVehicleClassStringInitializer, SVC_CUSTOM2, false)
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ SVC_SHIP
is an arbitrary ship
@ SVC_RAIL_CLASSES
classes which drive on tracks
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_RAIL_FAST
vehicle that is allowed to drive on high-speed rail tracks
@ SVC_DRONE
@ SVC_AUTHORITY
authorities vehicles
@ SVC_BUS
vehicle is a bus
@ SVC_AIRCRAFT
@ SVC_SUBWAY
@ SVC_PEDESTRIAN
pedestrian
@ SUMO_TAG_PARKING_AREA
A parking area.
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)....
@ PARTLEFT
The link is a partial left direction.
@ RIGHT
The link is a (hard) right direction.
@ TURN
The link is a 180 degree turn.
@ LEFT
The link is a (hard) left direction.
@ STRAIGHT
The link is a straight direction.
@ TURN_LEFTHAND
The link is a 180 degree turn (left-hand network).
@ PARTRIGHT
The link is a partial right direction.
@ NODIR
The link has no direction (is a dead end link).
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
@ LINKSTATE_TL_REDYELLOW
The link has red light (must brake) but indicates upcoming green.
@ LINKSTATE_ALLWAY_STOP
This is an uncontrolled, all-way stop link.
@ LINKSTATE_MAJOR
This is an uncontrolled, major link, may pass.
@ LINKSTATE_STOP
This is an uncontrolled, minor link, has to stop.
@ LINKSTATE_TL_YELLOW_MAJOR
The link has yellow light, may pass.
@ LINKSTATE_TL_GREEN_MAJOR
The link has green light, may pass.
@ LINKSTATE_EQUAL
This is an uncontrolled, right-before-left link.
@ LINKSTATE_DEADEND
This is a dead end link.
@ LINKSTATE_TL_OFF_BLINKING
The link is controlled by a tls which is off and blinks, has to brake.
@ LINKSTATE_TL_YELLOW_MINOR
The link has yellow light, has to brake anyway.
@ LINKSTATE_TL_RED
The link has red light (must brake).
@ LINKSTATE_TL_GREEN_MINOR
The link has green light, has to brake.
@ LINKSTATE_MINOR
This is an uncontrolled, minor link, has to brake.
@ LINKSTATE_TL_OFF_NOSIGNAL
The link is controlled by a tls which is off, not blinking, may pass.
const double SUMO_const_laneWidth
Definition StdDefs.h:52
T MIN2(T a, T b)
Definition StdDefs.h:80
const double SUMO_const_laneMarkWidth
Definition StdDefs.h:55
T MAX2(T a, T b)
Definition StdDefs.h:86
const double SUMO_const_halfLaneWidth
Definition StdDefs.h:53
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition GLHelper.cpp:437
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition GLHelper.cpp:653
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:628
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:829
static void pushName(unsigned int name)
push Name
Definition GLHelper.cpp:144
static void drawFilledCircle(const double widradiusth, const int steps=8)
Draws a filled circle around (0,0).
Definition GLHelper.cpp:568
static void popMatrix()
pop matrix
Definition GLHelper.cpp:135
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:352
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition GLHelper.cpp:300
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:944
static void popName()
pop Name
Definition GLHelper.cpp:153
static void pushMatrix()
push matrix
Definition GLHelper.cpp:122
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:891
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:848
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:549
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.
GUIGlObject(GUIGlObjectType type, const std::string &microsimID, FXIcon *icon)
Constructor.
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
bool drawAsWaterway(const GUIVisualizationSettings &s) const
whether to draw this lane as a waterway
Definition GUILane.cpp:1582
void debugDrawFoeIntersections() const
draw intersection positions of foe internal lanes with this one
Definition GUILane.cpp:988
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:170
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:1653
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:130
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:1619
std::vector< int > myShapeSegments
the meso segment index for each geometry segment
Definition GUILane.h:365
double firstWaitingTime() const
Definition GUILane.cpp:1152
double setPartialOccupation(MSVehicle *v) override
Sets the information about a vehicle lapping into this lane.
Definition GUILane.cpp:238
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:280
RGBColor setColor(const GUIVisualizationSettings &s) const
sets the color according to the currente settings
Definition GUILane.cpp:1203
double getPendingEmits() const
get number of vehicles waiting for departure on this lane
Definition GUILane.cpp:1658
void setJunctionApproaches() const override
Definition GUILane.cpp:189
void drawLinkNo(const GUIVisualizationSettings &s) const
helper methods
Definition GUILane.cpp:253
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own popup-menu.
Definition GUILane.cpp:1014
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:895
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:203
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:1272
void addSecondaryShape(const PositionVector &shape) override
Definition GUILane.cpp:151
double getScaleValue(const GUIVisualizationSettings &s, int activeScheme, bool s2) const
gets the scaling value according to the current scheme index
Definition GUILane.cpp:1503
void resetPartialOccupation(MSVehicle *v) override
Removes the information about a vehicle lapping into this lane.
Definition GUILane.cpp:245
void integrateNewVehicles() override
Definition GUILane.cpp:224
void drawGL(const GUIVisualizationSettings &s) const override
Draws the object.
Definition GUILane.cpp:548
void drawArrows(bool secondaryShape) const
Definition GUILane.cpp:454
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:319
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:830
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const override
gets the color value according to the current scheme index
Definition GUILane.cpp:1316
void closeTraffic(bool rebuildAllowed=true)
close this lane for traffic
Definition GUILane.cpp:1603
double getClickPriority() const override
Returns the priority of receiving mouse clicks.
Definition GUILane.cpp:1663
bool isSelected() const override
whether this lane is selected in the GUI
Definition GUILane.cpp:1648
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own parameter window.
Definition GUILane.cpp:1060
const std::vector< double > & getShapeRotations(bool secondary) const
Definition GUILane.cpp:1134
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:1190
bool drawAsRailway(const GUIVisualizationSettings &s) const
whether to draw this lane as a railway
Definition GUILane.cpp:1576
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:210
std::vector< double > myShapeRotations2
Definition GUILane.h:354
double myLengthGeometryFactor2
Definition GUILane.h:393
void planMovements(const SUMOTime t) override
Definition GUILane.cpp:183
double getColorValueForTracker() const
return color value based on cached settings
Definition GUILane.cpp:1298
std::vector< RGBColor > myShapeColors2
Definition GUILane.h:362
double getEdgeLaneNumber() const
Definition GUILane.cpp:1158
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:1177
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:160
~GUILane()
Destructor.
Definition GUILane.cpp:105
const PositionVector & getShape(bool secondary) const override
Definition GUILane.cpp:1128
void drawLinkRule(const GUIVisualizationSettings &s, const GUINet &net, const MSLink *link, const PositionVector &shape, double x1, double x2) const
Definition GUILane.cpp:374
Boundary getCenteringBoundary() const override
Returns the boundary to which the view shall be centered in order to show the object.
Definition GUILane.cpp:1115
std::vector< RGBColor > & getShapeColors(bool secondary) const
Definition GUILane.cpp:1146
bool setFunctionalColor(const GUIColorer &c, RGBColor &col, int activeScheme=-1) const
Definition GUILane.cpp:1220
double getStoredEdgeTravelTime() const
Returns the stored traveltime for the edge of this lane.
Definition GUILane.cpp:1164
const std::vector< double > & getShapeLengths(bool secondary) const
Definition GUILane.cpp:1140
void drawMarkings(const GUIVisualizationSettings &s, double scale) const
draw lane borders and white markings
Definition GUILane.cpp:843
void drawBikeMarkings() const
bike lane markings on top of an intersection
Definition GUILane.cpp:866
void executeMovements(const SUMOTime t) override
Definition GUILane.cpp:196
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:521
void releaseVehicles() const override
Allows to use the container for microsimulation again.
Definition GUILane.cpp:177
void drawDirectionIndicators(double exaggeration, bool spreadSuperposed, bool s2) const
direction indicators for lanes
Definition GUILane.cpp:960
void detectCollisions(SUMOTime timestep, const std::string &stage) override
Definition GUILane.cpp:231
void swapAfterLaneChange(SUMOTime t) override
moves myTmpVehicles int myVehicles after a lane change procedure
Definition GUILane.cpp:217
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
GUIVisualizationSettings * editVisualisationSettings() const
edit visualization settings (allow modify VisualizationSetings, use carefully)
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:302
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
double getTimePenalty() const
Definition MSEdge.h:495
double getRoutingSpeed() const
Returns the averaged speed used by the routing device.
Definition MSEdge.cpp:1075
void rebuildAllowedLanes(const bool onInit=false, bool updateVehicles=false)
Definition MSEdge.cpp:323
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
SVCPermissions myPermissions
The vClass permissions for this lane.
Definition MSLane.h:1550
std::set< const MSBaseVehicle * > myParkingVehicles
Definition MSLane.h:1525
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:2888
virtual void removeParking(MSBaseVehicle *veh)
remove parking vehicle. This must be syncrhonized when running with GUI
Definition MSLane.cpp:3727
virtual void integrateNewVehicles()
Insert buffered vehicle into the real lane.
Definition MSLane.cpp:2598
double myLength
Lane length [m].
Definition MSLane.h:1528
double getNettoOccupancy() const
Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps)...
Definition MSLane.cpp:3449
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition MSLane.cpp:2870
PositionVector myShape
The shape of the lane.
Definition MSLane.h:1473
PositionVector * myOutlineShape
the outline of the lane (optional)
Definition MSLane.h:1476
std::map< long long, SVCPermissions > myPermissionChanges
Definition MSLane.h:1630
double getFrictionCoefficient() const
Returns the lane's friction coefficient.
Definition MSLane.h:610
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:456
MSLane(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 MSLane.cpp:254
const MSLane * getNormalSuccessorLane() const
get normal lane following this internal lane, for normal lanes, the lane itself is returned
Definition MSLane.cpp:3289
MSEdge *const myEdge
The lane's edge, for routing only.
Definition MSLane.h:1539
bool allowsChangingRight(SUMOVehicleClass vclass) const
Returns whether the given vehicle class may change left from this lane.
Definition MSLane.h:953
double myMaxSpeed
Lane-wide speed limit [m/s].
Definition MSLane.h:1542
const MSLink * getLinkTo(const MSLane *const) const
returns the link to the given lane or nullptr, if it is not connected
Definition MSLane.cpp:2784
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:1588
VehCont myVehicles
The lane's vehicles. This container holds all vehicles that have their front (longitudinally) and the...
Definition MSLane.h:1492
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition MSLane.h:603
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition MSLane.h:119
MSLane * myBidiLane
Definition MSLane.h:1627
bool isWalkingArea() const
Definition MSLane.cpp:2676
SVCPermissions getPermissions() const
Returns the vehicle class permissions for this lane.
Definition MSLane.h:625
void resetPermissions(long long transientID)
Definition MSLane.cpp:4574
const std::string myLaneType
the type of this lane
Definition MSLane.h:1613
int myRNGIndex
Definition MSLane.h:1633
double getLength() const
Returns the lane's length.
Definition MSLane.h:617
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:2853
StopOffset myLaneStopOffset
Definition MSLane.h:1536
virtual double setPartialOccupation(MSVehicle *v)
Sets the information about a vehicle lapping into this lane.
Definition MSLane.cpp:385
int getIndex() const
Returns the lane's index.
Definition MSLane.h:653
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:4562
const double myWidth
Lane width [m].
Definition MSLane.h:1531
const double myLengthGeometryFactor
precomputed myShape.length / myLength
Definition MSLane.h:1607
virtual void executeMovements(const SUMOTime t)
Executes planned vehicle movements with regards to right-of-way.
Definition MSLane.cpp:2311
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition MSLane.cpp:3254
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition MSLane.cpp:3434
int myIndex
The lane index.
Definition MSLane.h:1479
bool isCrossing() const
Definition MSLane.cpp:2664
virtual void detectCollisions(SUMOTime timestep, const std::string &stage)
Check if vehicles are too close.
Definition MSLane.cpp:1689
std::vector< MSLink * > myLinks
Definition MSLane.h:1591
bool isInternal() const
Definition MSLane.cpp:2652
static const long CHANGE_PERMISSIONS_GUI
Definition MSLane.h:1391
VehCont myPartialVehicles
The lane's partial vehicles. This container holds all vehicles that are partially on this lane but wh...
Definition MSLane.h:1504
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:404
double getHarmonoise_NoiseEmissions() const
Returns the sum of last step noise emissions.
Definition MSLane.cpp:3523
double interpolateLanePosToGeometryPos(double lanePos) const
Definition MSLane.h:555
virtual void setJunctionApproaches() const
Register junction approaches for all vehicles after velocities have been planned.
Definition MSLane.cpp:1628
MSLane * getBidiLane() const
retrieve bidirectional lane or nullptr
Definition MSLane.cpp:4719
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:775
double getEmissions() const
Returns the sum of last step emissions The value is always per 1s, so multiply by step length if nece...
Definition MSLane.h:1185
const MSLane * getNormalPredecessorLane() const
get normal lane leading to this internal lane, for normal lanes, the lane itself is returned
Definition MSLane.cpp:3279
double getWidth() const
Returns the lane's width.
Definition MSLane.h:646
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
Definition MSLane.h:735
double getMeanSpeed() const
Returns the mean speed on this lane.
Definition MSLane.cpp:3477
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition MSLane.h:561
Notification
Definition of a vehicle state.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:199
const std::map< SUMOVehicleClass, double > * getRestrictions(const std::string &id) const
Returns the restrictions for an edge type If no restrictions are present, 0 is returned.
Definition MSNet.cpp:374
MSEdgeWeightsStorage & getWeightsStorage()
Returns the net's internal edge travel times/efforts container.
Definition MSNet.cpp:1314
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition MSNet.h:455
const MESegment::MesoEdgeType & getMesoType(const std::string &typeID)
Returns edge type specific meso parameters if no type specific parameters have been loaded,...
Definition MSNet.cpp:432
A lane area vehicles can halt at.
VehicleVector getBlockingVehicles(int linkIndex) override
return vehicles that block the intersection/rail signal for vehicles that wish to pass the given link...
std::vector< const MSDriveWay * > getBlockingDriveWays(int linkIndex) override
return vehicles that approach the intersection/rail signal and have priority over vehicles that wish ...
Representation of a vehicle in the micro simulation.
Definition MSVehicle.h:77
const std::string & getID() const
Returns the id.
Definition Named.h:73
bool hasParameter(const std::string &key) const
Returns whether the parameter is set.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition Position.h:273
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimensions
Definition Position.h:263
double x() const
Returns the x-position.
Definition Position.h:52
double z() const
Returns the z-position.
Definition Position.h:62
double y() const
Returns the y-position.
Definition Position.h:57
A list of positions.
double beginEndAngle() const
returns the angle in radians of the line connecting the first and the last position
double getMinZ() const
return minimum z-coordinate
double length() const
Returns the length.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
PositionVector getOrthogonal(const Position &p, double extend, bool before, double length=1.0, double deg=90) const
return orthogonal through p (extending this vector if necessary)
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).
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:194
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:197
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1).
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
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