Eclipse SUMO - Simulation of Urban MObility
GUILane.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3// Copyright (C) 2001-2023 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>
52#include <mesosim/MELoop.h>
53#include <mesosim/MESegment.h>
54#include "GUILane.h"
55#include "GUIEdge.h"
56#include "GUIVehicle.h"
57#include "GUINet.h"
59
61
62//#define GUILane_DEBUG_DRAW_FOE_INTERSECTIONS
63
64// ===========================================================================
65// static member declaration
66// ===========================================================================
69
70
71// ===========================================================================
72// method definitions
73// ===========================================================================
74GUILane::GUILane(const std::string& id, double maxSpeed, double friction, double length,
75 MSEdge* const edge, int numericalID,
76 const PositionVector& shape, double width,
77 SVCPermissions permissions,
78 SVCPermissions changeLeft, SVCPermissions changeRight,
79 int index, bool isRampAccel,
80 const std::string& type) :
81 MSLane(id, maxSpeed, friction, length, edge, numericalID, shape, width, permissions, changeLeft, changeRight, index, isRampAccel, type),
83 myParkingAreas(nullptr),
84 myTesselation(nullptr),
85#ifdef HAVE_OSG
86 myGeom(0),
87#endif
88 myAmClosed(false),
89 myLock(true) {
91 myShape = splitAtSegments(shape);
92 assert(fabs(myShape.length() - shape.length()) < POSITION_EPS);
93 assert(myShapeSegments.size() == myShape.size());
94 }
96 //
99}
100
101
103 // just to quit cleanly on a failure
104 if (myLock.locked()) {
105 myLock.unlock();
106 }
107 delete myParkingAreas;
108 delete myTesselation;
109}
110
111
112void
114 std::vector<double>& rotations,
115 std::vector<double>& lengths,
116 std::vector<RGBColor>& colors) {
117 rotations.clear();
118 lengths.clear();
119 colors.clear();
120 rotations.reserve(shape.size() - 1);
121 lengths.reserve(shape.size() - 1);
122 colors.reserve(shape.size() - 1);
123 int e = (int) shape.size() - 1;
124 for (int i = 0; i < e; ++i) {
125 const Position& f = shape[i];
126 const Position& s = shape[i + 1];
127 lengths.push_back(f.distanceTo2D(s));
128 rotations.push_back(RAD2DEG(atan2(s.x() - f.x(), f.y() - s.y())));
129 }
130}
131
132
133void
135 myShape2 = shape;
138}
139
140
141// ------ Vehicle insertion ------
142void
143GUILane::incorporateVehicle(MSVehicle* veh, double pos, double speed, double posLat,
144 const MSLane::VehCont::iterator& at,
145 MSMoveReminder::Notification notification) {
146 FXMutexLock locker(myLock);
147 MSLane::incorporateVehicle(veh, pos, speed, posLat, at, notification);
148}
149
150
151// ------ Access to vehicles ------
152const MSLane::VehCont&
154 myLock.lock();
155 return myVehicles;
156}
157
158
159void
161 myLock.unlock();
162}
163
164
165void
167 FXMutexLock locker(myLock);
169}
170
171void
173 FXMutexLock locker(myLock);
175}
176
177
178void
180 FXMutexLock locker(myLock);
182}
183
184
186GUILane::removeVehicle(MSVehicle* remVehicle, MSMoveReminder::Notification notification, bool notify) {
187 FXMutexLock locker(myLock);
188 return MSLane::removeVehicle(remVehicle, notification, notify);
189}
190
191
192void
194 FXMutexLock locker(myLock);
195 return MSLane::removeParking(remVehicle);
196}
197
198
199void
201 FXMutexLock locker(myLock);
203}
204
205
206void
208 FXMutexLock locker(myLock);
210}
211
212
213void
214GUILane::detectCollisions(SUMOTime timestep, const std::string& stage) {
215 FXMutexLock locker(myLock);
216 MSLane::detectCollisions(timestep, stage);
217}
218
219
220double
222 FXMutexLock locker(myLock);
224}
225
226
227void
229 FXMutexLock locker(myLock);
231}
232
233
234// ------ Drawing methods ------
235void
237 int noLinks = (int)myLinks.size();
238 if (noLinks == 0) {
239 return;
240 }
241 // draw all links
242 if (getEdge().isCrossing()) {
243 // draw indices at the start and end of the crossing
244 const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
246 shape.extrapolate(0.5); // draw on top of the walking area
249 return;
250 }
251 // draw all links
252 double w = myWidth / (double) noLinks;
253 double x1 = myHalfLaneWidth;
254 for (int i = noLinks; --i >= 0;) {
255 double x2 = x1 - (double)(w / 2.);
257 x1 -= w;
258 }
259}
260
261
262void
264 int noLinks = (int)myLinks.size();
265 if (noLinks == 0) {
266 return;
267 }
268 if (getEdge().isCrossing()) {
269 // draw indices at the start and end of the crossing
270 const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
271 int linkNo = net.getLinkTLIndex(link);
272 // maybe the reverse link is controlled separately
273 int linkNo2 = net.getLinkTLIndex(myLinks.front());
274 // otherwise, use the same index as the forward link
275 if (linkNo2 < 0) {
276 linkNo2 = linkNo;
277 }
278 if (linkNo >= 0) {
280 shape.extrapolate(0.5); // draw on top of the walking area
281 GLHelper::drawTextAtEnd(toString(linkNo2), shape, 0, s.drawLinkTLIndex, s.scale);
283 }
284 return;
285 }
286 // draw all links
287 double w = myWidth / (double) noLinks;
288 double x1 = myHalfLaneWidth;
289 for (int i = noLinks; --i >= 0;) {
290 double x2 = x1 - (double)(w / 2.);
291 int linkNo = net.getLinkTLIndex(myLinks[MSGlobals::gLefthand ? noLinks - 1 - i : i]);
292 if (linkNo < 0) {
293 continue;
294 }
296 x1 -= w;
297 }
298}
299
300
301void
303 int noLinks = (int)myLinks.size();
304 const PositionVector& shape = getShape(s.secondaryShape);
305 if (noLinks == 0) {
306 drawLinkRule(s, net, nullptr, shape, 0, 0);
307 return;
308 }
309 if (getEdge().isCrossing()) {
310 // draw rules at the start and end of the crossing
311 const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
312 const MSLink* link2 = myLinks.front();
313 if (link2->getTLLogic() == nullptr) {
314 link2 = link;
315 }
316 PositionVector tmp = shape;
317 tmp.extrapolate(0.5); // draw on top of the walking area
318 drawLinkRule(s, net, link2, tmp, 0, myWidth);
319 drawLinkRule(s, net, link, tmp.reverse(), 0, myWidth);
320 return;
321 }
322 // draw all links
323 const double isRailSignal = myEdge->getToJunction()->getType() == SumoXMLNodeType::RAIL_SIGNAL;
324 double w = myWidth / (double) noLinks;
325 if (isRailSignal && noLinks > 1 && myLinks.back()->isTurnaround() && s.showRails) {
326 w = myWidth / (double)(noLinks - 1);
327 }
328 double x1 = isRailSignal ? -myWidth * 0.5 : 0;
329 for (int i = 0; i < noLinks; ++i) {
330 double x2 = x1 + w;
331 drawLinkRule(s, net, myLinks[MSGlobals::gLefthand ? noLinks - 1 - i : i], shape, x1, x2);
332 x1 = x2;
333 }
334 // draw stopOffset for passenger cars
336 const double stopOffsetPassenger = myLaneStopOffset.getOffset();
337 const Position& end = shape.back();
338 const Position& f = shape[-2];
339 const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
342 glTranslated(end.x(), end.y(), 0);
343 glRotated(rot, 0, 0, 1);
344 glTranslated(0, stopOffsetPassenger, 0);
345 glBegin(GL_QUADS);
346 glVertex2d(-myHalfLaneWidth, 0.0);
347 glVertex2d(-myHalfLaneWidth, 0.2);
348 glVertex2d(myHalfLaneWidth, 0.2);
349 glVertex2d(myHalfLaneWidth, 0.0);
350 glEnd();
352 }
353}
354
355
356void
357GUILane::drawLinkRule(const GUIVisualizationSettings& s, const GUINet& net, const MSLink* link, const PositionVector& shape, double x1, double x2) const {
358 const Position& end = shape.back();
359 const Position& f = shape[-2];
360 const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
361 if (link == nullptr) {
362 if (static_cast<GUIEdge*>(myEdge)->showDeadEnd()) {
364 } else {
366 }
368 glTranslated(end.x(), end.y(), 0);
369 glRotated(rot, 0, 0, 1);
370 glBegin(GL_QUADS);
371 glVertex2d(-myHalfLaneWidth, 0.0);
372 glVertex2d(-myHalfLaneWidth, 0.5);
373 glVertex2d(myHalfLaneWidth, 0.5);
374 glVertex2d(myHalfLaneWidth, 0.0);
375 glEnd();
377 } else {
379 glTranslated(end.x(), end.y(), 0);
380 glRotated(rot, 0, 0, 1);
381 // select glID
382
383 switch (link->getState()) {
385 case LINKSTATE_STOP: {
386 // might be a traffic light link
387 int tlID = net.getLinkTLID(link);
388 GLHelper::pushName(tlID != 0 ? tlID : getGlID());
389 break;
390 }
393 case LINKSTATE_TL_RED:
400 break;
401 case LINKSTATE_MAJOR:
402 case LINKSTATE_MINOR:
403 case LINKSTATE_EQUAL:
404 default:
406 break;
407 }
409 if (!(drawAsRailway(s) || drawAsWaterway(s)) || link->getState() != LINKSTATE_MAJOR) {
410 // the white bar should be the default for most railway
411 // links and looks ugly so we do not draw it
412 double scale = isInternal() ? 0.5 : 1;
414 scale *= MAX2(s.laneWidthExaggeration, s.junctionSize.getExaggeration(s, this, 10));
415 }
416 glScaled(scale, scale, 1);
417 glBegin(GL_QUADS);
418 glVertex2d(x1 - myHalfLaneWidth, 0.0);
419 glVertex2d(x1 - myHalfLaneWidth, 0.5);
420 glVertex2d(x2 - myHalfLaneWidth, 0.5);
421 glVertex2d(x2 - myHalfLaneWidth, 0.0);
422 glEnd();
423 }
426 }
427}
428
429void
430GUILane::drawArrows(bool secondaryShape) const {
431 if (myLinks.size() == 0) {
432 return;
433 }
434 // draw all links
435 const Position& end = getShape(secondaryShape).back();
436 const Position& f = getShape(secondaryShape)[-2];
437 const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
439 glColor3d(1, 1, 1);
440 glTranslated(end.x(), end.y(), 0);
441 glRotated(rot, 0, 0, 1);
443 glScaled(myWidth / SUMO_const_laneWidth, 1, 1);
444 }
445 for (const MSLink* const link : myLinks) {
446 LinkDirection dir = link->getDirection();
447 LinkState state = link->getState();
448 if (state == LINKSTATE_DEADEND || dir == LinkDirection::NODIR) {
449 continue;
450 }
451 switch (dir) {
453 GLHelper::drawBoxLine(Position(0, 4), 0, 2, .05);
454 GLHelper::drawTriangleAtEnd(Position(0, 4), Position(0, 1), (double) 1, (double) .25);
455 break;
457 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
458 GLHelper::drawBoxLine(Position(0, 2.5), 90, .5, .05);
459 GLHelper::drawBoxLine(Position(0.5, 2.5), 180, 1, .05);
460 GLHelper::drawTriangleAtEnd(Position(0.5, 2.5), Position(0.5, 4), (double) 1, (double) .25);
461 break;
463 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
464 GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
465 GLHelper::drawBoxLine(Position(-0.5, 2.5), -180, 1, .05);
466 GLHelper::drawTriangleAtEnd(Position(-0.5, 2.5), Position(-0.5, 4), (double) 1, (double) .25);
467 break;
469 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
470 GLHelper::drawBoxLine(Position(0, 2.5), 90, 1, .05);
471 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.5, 2.5), (double) 1, (double) .25);
472 break;
474 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
475 GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
476 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.5, 2.5), (double) 1, (double) .25);
477 break;
479 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
480 GLHelper::drawBoxLine(Position(0, 2.5), 45, .7, .05);
481 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.2, 1.3), (double) 1, (double) .25);
482 break;
484 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
485 GLHelper::drawBoxLine(Position(0, 2.5), -45, .7, .05);
486 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.2, 1.3), (double) 1, (double) .25);
487 break;
488 default:
489 break;
490 }
491 }
493}
494
495
496void
497GUILane::drawLane2LaneConnections(double exaggeration, bool s2) const {
498 Position centroid;
499 if (exaggeration > 1) {
500 centroid = myEdge->getToJunction()->getShape().getCentroid();
501 }
502 for (const MSLink* const link : myLinks) {
503 const GUILane* connected = dynamic_cast<GUILane*>(link->getLane());
504 if (connected == nullptr) {
505 continue;
506 }
508 glBegin(GL_LINES);
509 Position p1 = myEdge->isWalkingArea() ? getShape(s2).getCentroid() : getShape(s2)[-1];
510 Position p2 = connected->getEdge().isWalkingArea() ? connected->getShape(s2).getCentroid() : connected->getShape(s2)[0];
511 if (exaggeration > 1) {
512 p1 = centroid + ((p1 - centroid) * exaggeration);
513 p2 = centroid + ((p2 - centroid) * exaggeration);
514 }
515 glVertex2d(p1.x(), p1.y());
516 glVertex2d(p2.x(), p2.y());
517 glEnd();
518 GLHelper::drawTriangleAtEnd(p1, p2, (double) .4, (double) .2);
519 }
520}
521
522
523void
527 const bool s2 = s.secondaryShape;
528 const bool isCrossing = myEdge->isCrossing();
529 const bool isWalkingArea = myEdge->isWalkingArea();
530 const bool isInternal = isCrossing || isWalkingArea || myEdge->isInternal();
531 bool mustDrawMarkings = false;
532 double exaggeration = s.laneWidthExaggeration;
534 GUIEdge* myGUIEdge = dynamic_cast<GUIEdge*>(myEdge);
535 exaggeration *= s.edgeScaler.getScheme().getColor(myGUIEdge->getScaleValue(s, s.edgeScaler.getActive()));
536 } else {
537 exaggeration *= s.laneScaler.getScheme().getColor(getScaleValue(s, s.laneScaler.getActive(), s2));
538 }
539 const bool hasRailSignal = myEdge->getToJunction()->getType() == SumoXMLNodeType::RAIL_SIGNAL;
540 const bool detailZoom = s.scale * exaggeration > 5;
541 const bool drawDetails = (detailZoom || s.junctionSize.minSize == 0 || hasRailSignal) && !s.drawForPositionSelection;
542 const bool drawRails = drawAsRailway(s);
543 if (isCrossing || isWalkingArea) {
544 // draw internal lanes on top of junctions
545 glTranslated(0, 0, GLO_JUNCTION + 0.1);
546 } else if (isWaterway(myPermissions)) {
547 // draw waterways below normal roads
548 glTranslated(0, 0, getType() - 0.2);
549 } else {
550 glTranslated(0, 0, getType());
551 }
552 // set lane color
553 const RGBColor color = setColor(s);
554 const PositionVector& baseShape = getShape(s2);
555 auto& shapeColors = getShapeColors(s2);
557 shapeColors.clear();
558 const std::vector<RGBColor>& segmentColors = static_cast<const GUIEdge*>(myEdge)->getSegmentColors();
559 if (segmentColors.size() > 0) {
560 // apply segment specific shape colors
561 //std::cout << getID() << " shape=" << myShape << " shapeSegs=" << toString(myShapeSegments) << "\n";
562 for (int ii = 0; ii < (int)baseShape.size() - 1; ++ii) {
563 shapeColors.push_back(segmentColors[myShapeSegments[ii]]);
564 }
565 }
566 }
567 // recognize full transparency and simply don't draw
568 bool hiddenBidi = getBidiLane() != nullptr && myEdge->getNumericalID() > myEdge->getBidiEdge()->getNumericalID();
569 if (color.alpha() != 0 && s.scale * exaggeration > s.laneMinSize) {
570 // scale tls-controlled lane2lane-arrows along with their junction shapes
571 double junctionExaggeration = 1;
572 if (!isInternal
575 junctionExaggeration = MAX2(1.001, s.junctionSize.getExaggeration(s, this, 4));
576 }
577 // draw lane
578 // check whether it is not too small
579 if (s.scale * exaggeration < 1. && junctionExaggeration == 1 && s.junctionSize.minSize != 0) {
580 if (!isInternal || hasRailSignal) {
581 if (shapeColors.size() > 0) {
582 GLHelper::drawLine(baseShape, shapeColors);
583 } else {
584 GLHelper::drawLine(baseShape);
585 }
586 }
588 } else {
589 GUINet* net = (GUINet*) MSNet::getInstance();
590 const bool spreadSuperposed = s.spreadSuperposed && myEdge->getBidiEdge() != nullptr;
591 if (hiddenBidi && !spreadSuperposed) {
592 // do not draw shape
593 mustDrawMarkings = !isInternal && myPermissions != 0 && myPermissions != SVC_PEDESTRIAN && exaggeration == 1.0 && !isWaterway(myPermissions) && neighLaneNotBidi();
594 } else if (drawRails) {
595 // draw as railway: assume standard gauge of 1435mm when lane width is not set
596 // draw foot width 150mm, assume that distance between rail feet inner sides is reduced on both sides by 39mm with regard to the gauge
597 // assume crosstie length of 181% gauge (2600mm for standard gauge)
598 PositionVector shape = baseShape;
599 const double width = myWidth;
600 double halfGauge = 0.5 * (width == SUMO_const_laneWidth ? 1.4350 : width) * exaggeration;
601 if (spreadSuperposed) {
602 try {
603 shape.move2side(halfGauge * 0.8);
604 } catch (InvalidArgument&) {}
605 halfGauge *= 0.4;
606 }
607 const double halfInnerFeetWidth = halfGauge - 0.039 * exaggeration;
608 const double halfRailWidth = detailZoom ? (halfInnerFeetWidth + 0.15 * exaggeration) : SUMO_const_halfLaneWidth * exaggeration;
609 const double halfCrossTieWidth = halfGauge * 1.81;
610 if (shapeColors.size() > 0) {
611 GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), getShapeColors(s2), halfRailWidth);
612 } else {
613 GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), halfRailWidth);
614 }
615 // Draw white on top with reduced width (the area between the two tracks)
616 if (detailZoom) {
617 glColor3d(1, 1, 1);
618 glTranslated(0, 0, .1);
619 GLHelper::drawBoxLines(shape, getShapeRotations(s2), getShapeLengths(s2), halfInnerFeetWidth);
620 setColor(s);
621 GLHelper::drawCrossTies(shape, getShapeRotations(s2), getShapeLengths(s2), 0.26 * exaggeration, 0.6 * exaggeration, halfCrossTieWidth, s.drawForPositionSelection);
622 }
623 } else if (isCrossing) {
624 if (s.drawCrossingsAndWalkingareas && (s.scale > 3.0 || s.junctionSize.minSize == 0)) {
625 glTranslated(0, 0, .2);
627 glTranslated(0, 0, -.2);
628 }
629 } else if (isWalkingArea) {
630 if (s.drawCrossingsAndWalkingareas && (s.scale > 3.0 || s.junctionSize.minSize == 0)) {
631 glTranslated(0, 0, .2);
632 if (s.scale * exaggeration < 20.) {
633 GLHelper::drawFilledPoly(baseShape, true);
634 } else {
635 if (myTesselation == nullptr) {
637 }
638 myTesselation->drawTesselation(baseShape);
639 }
640 glTranslated(0, 0, -.2);
641 if (s.geometryIndices.show(this)) {
643 }
644 }
645 } else {
646 // we draw the lanes with reduced width so that the lane markings below are visible
647 // (this avoids artifacts at geometry corners without having to
648 // compute lane-marking intersection points)
650 mustDrawMarkings = !isInternal && myPermissions != 0 && myPermissions != SVC_PEDESTRIAN && exaggeration == 1.0 && !isWaterway(myPermissions);
651 const int cornerDetail = drawDetails && !isInternal ? (int)(s.scale * exaggeration) : 0;
652 double offset = halfWidth * MAX2(0., (exaggeration - 1)) * (MSGlobals::gLefthand ? -1 : 1);
653 if (spreadSuperposed) {
654 offset += halfWidth * 0.5 * (MSGlobals::gLefthand ? -1 : 1);
655 halfWidth *= 0.4; // create visible gap
656 }
657 if (shapeColors.size() > 0) {
658 GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), shapeColors, halfWidth * exaggeration, cornerDetail, offset);
659 } else {
660 GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), halfWidth * exaggeration, cornerDetail, offset);
661 }
662 }
663#ifdef GUILane_DEBUG_DRAW_FOE_INTERSECTIONS
666 }
667#endif
669 if (s.geometryIndices.show(this)) {
671 }
672 // draw details
673 if ((!isInternal || isCrossing || !s.drawJunctionShape) && (drawDetails || s.drawForPositionSelection || junctionExaggeration > 1)) {
675 glTranslated(0, 0, GLO_JUNCTION); // must draw on top of junction shape
676 glTranslated(0, 0, .5);
677 if (drawDetails) {
678 if (s.showLaneDirection) {
679 if (drawRails) {
680 // improve visibility of superposed rail edges
681 GLHelper::setColor(setColor(s).changedBrightness(100));
682 } else {
683 glColor3d(0.3, 0.3, 0.3);
684 }
686 drawDirectionIndicators(exaggeration, spreadSuperposed, s.secondaryShape);
687 }
688 }
689 if (!isInternal || isCrossing
690 // controlled internal junction
691 || (getLinkCont().size() != 0 && getLinkCont()[0]->isInternalJunctionLink() && getLinkCont()[0]->getTLLogic() != nullptr)) {
692 if (MSGlobals::gLateralResolution > 0 && s.showSublanes && !hiddenBidi && (myPermissions & ~(SVC_PEDESTRIAN | SVC_RAIL_CLASSES)) != 0) {
693 // draw sublane-borders
694 const double offsetSign = MSGlobals::gLefthand ? -1 : 1;
696 for (double offset = -myHalfLaneWidth; offset < myHalfLaneWidth; offset += MSGlobals::gLateralResolution) {
697 GLHelper::drawBoxLines(baseShape, getShapeRotations(s2), getShapeLengths(s2), 0.01, 0, -offset * offsetSign);
698 }
699 }
701 // draw segment borders
703 for (int i : mySegmentStartIndex) {
704 if (shapeColors.size() > 0) {
705 GLHelper::setColor(shapeColors[i].changedBrightness(51));
706 }
707 GLHelper::drawBoxLine(baseShape[i], getShapeRotations(s2)[i] + 90, myWidth / 3, 0.2, 0);
708 GLHelper::drawBoxLine(baseShape[i], getShapeRotations(s2)[i] - 90, myWidth / 3, 0.2, 0);
709 }
710 }
711 if (s.showLinkDecals && !drawRails && !drawAsWaterway(s) && myPermissions != SVC_PEDESTRIAN) {
713 }
714 glTranslated(0, 0, 1000);
715 if (s.drawLinkJunctionIndex.show(nullptr)) {
716 drawLinkNo(s);
717 }
718 if (s.drawLinkTLIndex.show(nullptr)) {
719 drawTLSLinkNo(s, *net);
720 }
721 glTranslated(0, 0, -1000);
722 }
723 glTranslated(0, 0, .1);
724 }
725 if ((drawDetails || junctionExaggeration > 1) && s.showLane2Lane) {
726 // draw from end of first to the begin of second but respect junction scaling
727 drawLane2LaneConnections(junctionExaggeration, s.secondaryShape);
728 }
730 // make sure link rules are drawn so tls can be selected via right-click
731 if (s.showLinkRules && (drawDetails || s.drawForPositionSelection)
732 && !isWalkingArea
733 && (!myEdge->isInternal() || (getLinkCont().size() > 0 && getLinkCont()[0]->isInternalJunctionLink()))) {
735 glTranslated(0, 0, GLO_SHAPE); // must draw on top of junction shape and additionals
736 drawLinkRules(s, *net);
738 }
739 }
740 }
741 if (mustDrawMarkings && drawDetails && s.laneShowBorders) { // needs matrix reset
742 drawMarkings(s, exaggeration);
743 }
744 if (drawDetails && isInternal && s.showBikeMarkings && myPermissions == SVC_BICYCLE && exaggeration == 1.0 && s.showLinkDecals && s.laneShowBorders && !hiddenBidi) {
746 }
747 if (drawDetails && isInternal && exaggeration == 1.0 && s.showLinkDecals && s.laneShowBorders && !hiddenBidi && myIndex > 0
748 && !(myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER) && allowsChangingRight(SVC_PASSENGER))) {
749 // draw lane changing prohibitions on junction
751 }
752 } else {
754 }
755 // draw vehicles
756 if (s.scale * s.vehicleSize.getExaggeration(s, nullptr) > s.vehicleSize.minSize) {
757 // retrieve vehicles from lane; disallow simulation
758 const MSLane::VehCont& vehicles = getVehiclesSecure();
759 for (MSLane::VehCont::const_iterator v = vehicles.begin(); v != vehicles.end(); ++v) {
760 if ((*v)->getLane() == this) {
761 static_cast<const GUIVehicle*>(*v)->drawGL(s);
762 } // else: this is the shadow during a continuous lane change
763 }
764 // draw parking vehicles
765 for (const MSBaseVehicle* const v : myParkingVehicles) {
766 dynamic_cast<const GUIBaseVehicle*>(v)->drawGL(s);
767 }
768 // allow lane simulation
770 }
772}
773
774bool
776 const MSLane* right = getParallelLane(-1, false);
777 if (right && right->getBidiLane() == nullptr) {
778 return true;
779 }
780 const MSLane* left = getParallelLane(1, false);
781 if (left && left->getBidiLane() == nullptr) {
782 return true;
783 }
784 return false;
785}
786
787void
788GUILane::drawMarkings(const GUIVisualizationSettings& s, double scale) const {
790 glTranslated(0, 0, GLO_EDGE);
791 setColor(s);
792 // optionally draw inverse markings
793 const bool s2 = s.secondaryShape;
794 if (myIndex > 0 && (myEdge->getLanes()[myIndex - 1]->getPermissions() & myPermissions) != 0) {
795 const bool cl = myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER);
796 const bool cr = allowsChangingRight(SVC_PASSENGER);
798 }
799 // draw white boundings and white markings
800 glColor3d(1, 1, 1);
802 getShape(s2),
804 getShapeLengths(s2),
807}
808
809
810void
812 // draw bike lane markings onto the intersection
813 glColor3d(1, 1, 1);
815 const bool s2 = false;
816 const int e = (int) getShape(s2).size() - 1;
817 const double markWidth = 0.1;
818 const double mw = myHalfLaneWidth;
819 for (int i = 0; i < e; ++i) {
821 glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), GLO_JUNCTION + 0.4);
822 glRotated(getShapeRotations(s2)[i], 0, 0, 1);
823 for (double t = 0; t < getShapeLengths(s2)[i]; t += 0.5) {
824 // left and right marking
825 for (int side = -1; side <= 1; side += 2) {
826 glBegin(GL_QUADS);
827 glVertex2d(side * mw, -t);
828 glVertex2d(side * mw, -t - 0.35);
829 glVertex2d(side * (mw + markWidth), -t - 0.35);
830 glVertex2d(side * (mw + markWidth), -t);
831 glEnd();
832 }
833 }
835 }
836}
837
838
839void
841 // fixme
842 const bool s2 = false;
843 // draw white markings
844 if (myIndex > 0 && (myEdge->getLanes()[myIndex - 1]->getPermissions() & myPermissions) != 0) {
845 glColor3d(1, 1, 1);
846 const bool cl = myEdge->getLanes()[myIndex - 1]->allowsChangingLeft(SVC_PASSENGER);
847 const bool cr = allowsChangingRight(SVC_PASSENGER);
848 // solid line marking
849 double mw, mw2;
850 // optional broken line marking
851 double mw3, mw4;
852 if (!cl && !cr) {
853 // draw a single solid line
856 mw3 = myHalfLaneWidth;
857 mw4 = myHalfLaneWidth;
858 } else {
859 // draw one solid and one broken line
860 if (cl) {
865 } else {
870 }
871 }
873 mw *= -1;
874 mw2 *= -1;
875 }
876 int e = (int) getShape(s2).size() - 1;
877 for (int i = 0; i < e; ++i) {
879 glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), GLO_JUNCTION + 0.4);
880 glRotated(getShapeRotations(s2)[i], 0, 0, 1);
881 for (double t = 0; t < getShapeLengths(s2)[i]; t += 6) {
882 const double lengthSolid = MIN2(6.0, getShapeLengths(s2)[i] - t);
883 glBegin(GL_QUADS);
884 glVertex2d(-mw, -t);
885 glVertex2d(-mw, -t - lengthSolid);
886 glVertex2d(-mw2, -t - lengthSolid);
887 glVertex2d(-mw2, -t);
888 glEnd();
889 if (cl || cr) {
890 const double lengthBroken = MIN2(3.0, getShapeLengths(s2)[i] - t);
891 glBegin(GL_QUADS);
892 glVertex2d(-mw3, -t);
893 glVertex2d(-mw3, -t - lengthBroken);
894 glVertex2d(-mw4, -t - lengthBroken);
895 glVertex2d(-mw4, -t);
896 glEnd();
897 }
898 }
900 }
901 }
902}
903
904void
905GUILane::drawDirectionIndicators(double exaggeration, bool spreadSuperposed, bool s2) const {
907 glTranslated(0, 0, GLO_EDGE);
908 int e = (int) getShape(s2).size() - 1;
909 const double widthFactor = spreadSuperposed ? 0.4 : 1;
910 const double w = MAX2(POSITION_EPS, myWidth * widthFactor);
911 const double w2 = MAX2(POSITION_EPS, myHalfLaneWidth * widthFactor);
912 const double w4 = MAX2(POSITION_EPS, myQuarterLaneWidth * widthFactor);
913 const double sideOffset = spreadSuperposed ? w * -0.5 : 0;
914 for (int i = 0; i < e; ++i) {
916 glTranslated(getShape(s2)[i].x(), getShape(s2)[i].y(), 0.1);
917 glRotated(getShapeRotations(s2)[i], 0, 0, 1);
918 for (double t = 0; t < getShapeLengths(s2)[i]; t += w) {
919 const double length = MIN2(w2, getShapeLengths(s2)[i] - t) * exaggeration;
920 glBegin(GL_TRIANGLES);
921 glVertex2d(sideOffset, -t - length);
922 glVertex2d(sideOffset - w4 * exaggeration, -t);
923 glVertex2d(sideOffset + w4 * exaggeration, -t);
924 glEnd();
925 }
927 }
929}
930
931
932void
935 glColor3d(1.0, 0.3, 0.3);
936 const double orthoLength = 0.5;
937 const MSLink* link = getLinkCont().front();
938 const std::vector<const MSLane*>& foeLanes = link->getFoeLanes();
939 const auto& conflicts = link->getConflicts();
940 if (foeLanes.size() == conflicts.size()) {
941 for (int i = 0; i < (int)foeLanes.size(); ++i) {
942 const MSLane* l = foeLanes[i];
943 Position pos = l->geometryPositionAtOffset(l->getLength() - conflicts[i].lengthBehindCrossing);
944 PositionVector ortho = l->getShape().getOrthogonal(pos, 10, true, orthoLength);
945 if (ortho.length() < orthoLength) {
946 ortho.extrapolate(orthoLength - ortho.length(), false, true);
947 }
948 GLHelper::drawLine(ortho);
949 //std::cout << "foe=" << l->getID() << " lanePos=" << l->getLength() - lengthsBehind[i].second << " pos=" << pos << "\n";
950 }
951 }
953}
954
955
956// ------ inherited from GUIGlObject
959 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
960 buildPopupHeader(ret, app);
962 //
963 GUIDesigns::buildFXMenuCommand(ret, "Copy edge name to clipboard", nullptr, ret, MID_COPY_EDGE_NAME);
966 //
967 buildShowParamsPopupEntry(ret, false);
970 const double height = baseShape.positionAtOffset(pos).z();
971 GUIDesigns::buildFXMenuCommand(ret, ("pos: " + toString(pos) + " height: " + toString(height)).c_str(), nullptr, nullptr, 0);
972 if (getEdge().hasDistance()) {
973 GUIDesigns::buildFXMenuCommand(ret, ("distance: " + toString(getEdge().getDistanceAt(pos))).c_str(), nullptr, nullptr, 0);
974 }
975 new FXMenuSeparator(ret);
976 buildPositionCopyEntry(ret, app);
977 new FXMenuSeparator(ret);
978 if (myAmClosed) {
979 if (myPermissionChanges.empty()) {
980 GUIDesigns::buildFXMenuCommand(ret, "Reopen lane", nullptr, &parent, MID_CLOSE_LANE);
981 GUIDesigns::buildFXMenuCommand(ret, "Reopen edge", nullptr, &parent, MID_CLOSE_EDGE);
982 } else {
983 GUIDesigns::buildFXMenuCommand(ret, "Reopen lane (override rerouter)", nullptr, &parent, MID_CLOSE_LANE);
984 GUIDesigns::buildFXMenuCommand(ret, "Reopen edge (override rerouter)", nullptr, &parent, MID_CLOSE_EDGE);
985 }
986 } else {
987 GUIDesigns::buildFXMenuCommand(ret, "Close lane", nullptr, &parent, MID_CLOSE_LANE);
988 GUIDesigns::buildFXMenuCommand(ret, "Close edge", nullptr, &parent, MID_CLOSE_EDGE);
989 }
990 GUIDesigns::buildFXMenuCommand(ret, "Add rerouter", nullptr, &parent, MID_ADD_REROUTER);
991 new FXMenuSeparator(ret);
992 // reachability menu
993 FXMenuPane* reachableByClass = new FXMenuPane(ret);
994 ret->insertMenuPaneChild(reachableByClass);
995 new FXMenuCascade(ret, "Select reachable", GUIIconSubSys::getIcon(GUIIcon::FLAG), reachableByClass);
996 for (auto i : SumoVehicleClassStrings.getStrings()) {
998 }
999 return ret;
1000}
1001
1002
1006 GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
1007 // add items
1008 ret->mkItem("allowed speed [m/s]", false, getSpeedLimit());
1009 const std::map<SUMOVehicleClass, double>* restrictions = MSNet::getInstance()->getRestrictions(myEdge->getEdgeType());
1010 if (restrictions != nullptr) {
1011 for (const auto& elem : *restrictions) {
1012 ret->mkItem((" allowed speed [m/s]: " + toString(elem.first)).c_str(), false, elem.second);
1013 }
1014 }
1015 ret->mkItem("length [m]", false, myLength);
1016 ret->mkItem("width [m]", false, myWidth);
1017 ret->mkItem("street name", false, myEdge->getStreetName());
1018 ret->mkItem("stored traveltime [s]", true, new FunctionBinding<GUILane, double>(this, &GUILane::getStoredEdgeTravelTime));
1019 ret->mkItem("loaded weight", true, new FunctionBinding<GUILane, double>(this, &GUILane::getLoadedEdgeWeight));
1020 ret->mkItem("routing speed [m/s]", true, new FunctionBinding<MSEdge, double>(myEdge, &MSEdge::getRoutingSpeed));
1021 ret->mkItem("lane friction coefficient [%]", true, new FunctionBinding<GUILane, double>(this, &GUILane::getFrictionCoefficient));
1022 ret->mkItem("time penalty [s]", true, new FunctionBinding<MSEdge, double>(myEdge, &MSEdge::getTimePenalty));
1023 ret->mkItem("brutto occupancy [%]", true, new FunctionBinding<GUILane, double>(this, &GUILane::getBruttoOccupancy, 100.));
1024 ret->mkItem("netto occupancy [%]", true, new FunctionBinding<GUILane, double>(this, &GUILane::getNettoOccupancy, 100.));
1025 ret->mkItem("pending insertions [#]", true, new FunctionBinding<GUILane, double>(this, &GUILane::getPendingEmits));
1026 ret->mkItem("edge type", false, myEdge->getEdgeType());
1027 ret->mkItem("type", false, myLaneType);
1028 ret->mkItem("priority", false, myEdge->getPriority());
1029 ret->mkItem("distance [km]", false, myEdge->getDistance() / 1000);
1030 ret->mkItem("allowed vehicle class", false, getVehicleClassNames(myPermissions));
1031 ret->mkItem("disallowed vehicle class", false, getVehicleClassNames(~myPermissions));
1032 ret->mkItem("permission code", false, myPermissions);
1033 ret->mkItem("color value", true, new FunctionBinding<GUILane, double>(this, &GUILane::getColorValueForTracker));
1034 if (myBidiLane != nullptr) {
1035 ret->mkItem("bidi-lane", false, myBidiLane->getID());
1036 }
1037 for (const auto& kv : myEdge->getParametersMap()) {
1038 ret->mkItem(("edgeParam:" + kv.first).c_str(), false, kv.second);
1039 }
1041 ret->closeBuilding();
1042 return ret;
1043}
1044
1045
1048 Boundary b;
1049 b.add(myShape[0]);
1050 b.add(myShape[-1]);
1051 b.grow(10);
1052 // ensure that vehicles and persons on the side are drawn even if the edge
1053 // is outside the view
1054 return b;
1055}
1056
1057
1058const PositionVector&
1059GUILane::getShape(bool secondary) const {
1060 return secondary ? myShape2 : myShape;
1061}
1062
1063
1064const std::vector<double>&
1065GUILane::getShapeRotations(bool secondary) const {
1066 return secondary ? myShapeRotations2 : myShapeRotations;
1067}
1068
1069
1070const std::vector<double>&
1071GUILane::getShapeLengths(bool secondary) const {
1072 return secondary ? myShapeLengths2 : myShapeLengths;
1073}
1074
1075
1076std::vector<RGBColor>&
1077GUILane::getShapeColors(bool secondary) const {
1078 return secondary ? myShapeColors2 : myShapeColors;
1079}
1080
1081
1082double
1084 return myVehicles.size() == 0 ? 0 : myVehicles.back()->getWaitingSeconds();
1085}
1086
1087
1088double
1090 return (double) myEdge->getLanes().size();
1091}
1092
1093
1094double
1097 if (!ews.knowsTravelTime(myEdge)) {
1098 return -1;
1099 } else {
1100 double value(0);
1101 ews.retrieveExistingTravelTime(myEdge, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), value);
1102 return value;
1103 }
1104}
1105
1106
1107double
1110 if (!ews.knowsEffort(myEdge)) {
1111 return -1;
1112 } else {
1113 double value(-1);
1114 ews.retrieveExistingEffort(myEdge, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), value);
1115 return value;
1116 }
1117}
1118
1119
1120double
1122 switch (activeScheme) {
1123 case 18: {
1125 }
1126 default:
1127 return getColorValue(s, activeScheme);
1128 }
1129
1130}
1131
1132
1135 // setting and retrieving the color does not work in OSGView so we return it explicitliy
1136 RGBColor col;
1137 if (MSGlobals::gUseMesoSim && static_cast<const GUIEdge*>(myEdge)->getMesoColor() != MESO_USE_LANE_COLOR) {
1138 col = static_cast<const GUIEdge*>(myEdge)->getMesoColor();
1139 } else {
1140 const GUIColorer& c = s.laneColorer;
1141 if (!setFunctionalColor(c, col) && !setMultiColor(s, c, col)) {
1142 col = c.getScheme().getColor(getColorValue(s, c.getActive()));
1143 }
1144 }
1145 GLHelper::setColor(col);
1146 return col;
1147}
1148
1149
1150bool
1151GUILane::setFunctionalColor(const GUIColorer& c, RGBColor& col, int activeScheme) const {
1152 if (activeScheme < 0) {
1153 activeScheme = c.getActive();
1154 }
1155 switch (activeScheme) {
1156 case 0:
1157 if (myEdge->isCrossing()) {
1158 // determine priority to decide color
1159 const MSLink* const link = getLogicalPredecessorLane()->getLinkTo(this);
1160 if (link->havePriority() || link->getTLLogic() != nullptr) {
1161 col = RGBColor(230, 230, 230);
1162 } else {
1163 col = RGBColor(26, 26, 26);
1164 }
1165 GLHelper::setColor(col);
1166 return true;
1167 } else {
1168 return false;
1169 }
1170 case 18: {
1171 double hue = GeomHelper::naviDegree(myShape.beginEndAngle()); // [0-360]
1172 col = RGBColor::fromHSV(hue, 1., 1.);
1173 GLHelper::setColor(col);
1174 return true;
1175 }
1176 case 30: { // taz color
1177 col = c.getScheme().getColor(0);
1178 std::vector<RGBColor> tazColors;
1179 for (MSEdge* e : myEdge->getPredecessors()) {
1180 if (e->isTazConnector() && e->knowsParameter("tazColor")) {
1181 tazColors.push_back(RGBColor::parseColor(e->getParameter("tazColor")));
1182 }
1183 }
1184 for (MSEdge* e : myEdge->getSuccessors()) {
1185 if (e->isTazConnector() && e->knowsParameter("tazColor")) {
1186 tazColors.push_back(RGBColor::parseColor(e->getParameter("tazColor")));
1187 }
1188 }
1189 if (tazColors.size() > 0) {
1190 int randColor = RandHelper::rand((int)tazColors.size(), RGBColor::getColorRNG());
1191 col = tazColors[randColor];
1192 }
1193 GLHelper::setColor(col);
1194 return true;
1195 }
1196 default:
1197 return false;
1198 }
1199}
1200
1201
1202bool
1204 const int activeScheme = c.getActive();
1205 auto& shapeColors = getShapeColors(s.secondaryShape);
1206 const PositionVector& shape = getShape(s.secondaryShape);
1207 shapeColors.clear();
1208 switch (activeScheme) {
1209 case 22: // color by height at segment start
1210 for (PositionVector::const_iterator ii = shape.begin(); ii != shape.end() - 1; ++ii) {
1211 shapeColors.push_back(c.getScheme().getColor(ii->z()));
1212 }
1213 // osg fallback (edge height at start)
1214 col = c.getScheme().getColor(getColorValue(s, 21));
1215 return true;
1216 case 24: // color by inclination at segment start
1217 for (int ii = 1; ii < (int)shape.size(); ++ii) {
1218 const double inc = (shape[ii].z() - shape[ii - 1].z()) / MAX2(POSITION_EPS, shape[ii].distanceTo2D(shape[ii - 1]));
1219 shapeColors.push_back(c.getScheme().getColor(inc));
1220 }
1221 col = c.getScheme().getColor(getColorValue(s, 23));
1222 return true;
1223 default:
1224 return false;
1225 }
1226}
1227
1228double
1230 if (myCachedGUISettings != nullptr) {
1232 const GUIColorer& c = s.laneColorer;
1234 } else {
1235 return 0;
1236 }
1237}
1238
1239
1240double
1241GUILane::getColorValue(const GUIVisualizationSettings& s, int activeScheme) const {
1242 switch (activeScheme) {
1243 case 0:
1244 switch (myPermissions) {
1245 case SVC_PEDESTRIAN:
1246 return 1;
1247 case SVC_BICYCLE:
1248 return 2;
1249 case 0:
1250 // forbidden road or green verge
1251 return myEdge->getPermissions() == 0 ? 10 : 3;
1252 case SVC_SHIP:
1253 return 4;
1254 case SVC_AUTHORITY:
1255 return 8;
1256 default:
1257 break;
1258 }
1259 if (myEdge->isTazConnector()) {
1260 return 9;
1261 } else if (isRailway(myPermissions)) {
1262 if ((myPermissions & SVC_BUS) != 0) {
1263 return 6;
1264 } else {
1265 return 5;
1266 }
1267 } else if ((myPermissions & SVC_PASSENGER) != 0) {
1268 if ((myPermissions & (SVC_RAIL_CLASSES & ~SVC_RAIL_FAST)) != 0 && (myPermissions & SVC_SHIP) == 0) {
1269 return 6;
1270 } else {
1271 return 0;
1272 }
1273 } else {
1274 return 7;
1275 }
1276 case 1:
1277 return isLaneOrEdgeSelected();
1278 case 2:
1279 return (double)myPermissions;
1280 case 3:
1281 return getSpeedLimit();
1282 case 4:
1283 return getBruttoOccupancy();
1284 case 5:
1285 return getNettoOccupancy();
1286 case 6:
1287 return firstWaitingTime();
1288 case 7:
1289 return getEdgeLaneNumber();
1290 case 8:
1291 return getEmissions<PollutantsInterface::CO2>() / myLength;
1292 case 9:
1293 return getEmissions<PollutantsInterface::CO>() / myLength;
1294 case 10:
1295 return getEmissions<PollutantsInterface::PM_X>() / myLength;
1296 case 11:
1297 return getEmissions<PollutantsInterface::NO_X>() / myLength;
1298 case 12:
1299 return getEmissions<PollutantsInterface::HC>() / myLength;
1300 case 13:
1301 return getEmissions<PollutantsInterface::FUEL>() / myLength;
1302 case 14:
1304 case 15: {
1305 return getStoredEdgeTravelTime();
1306 }
1307 case 16: {
1309 if (!ews.knowsTravelTime(myEdge)) {
1310 return -1;
1311 } else {
1312 double value(0);
1313 ews.retrieveExistingTravelTime(myEdge, 0, value);
1314 return 100 * myLength / value / getSpeedLimit();
1315 }
1316 }
1317 case 17: {
1318 // geometrical length has no meaning for walkingAreas since it describes the outer boundary
1320 }
1321 case 19: {
1322 return getLoadedEdgeWeight();
1323 }
1324 case 20: {
1325 return myEdge->getPriority();
1326 }
1327 case 21: {
1328 // color by z of first shape point
1329 return getShape(s.secondaryShape)[0].z();
1330 }
1331 case 23: {
1332 // color by incline
1333 return (getShape(s.secondaryShape)[-1].z() - getShape(s.secondaryShape)[0].z()) / getLength();
1334 }
1335 case 25: {
1336 // color by average speed
1337 return getMeanSpeed();
1338 }
1339 case 26: {
1340 // color by average relative speed
1341 return getMeanSpeed() / myMaxSpeed;
1342 }
1343 case 27: {
1344 // color by routing device assumed speed
1345 return myEdge->getRoutingSpeed();
1346 }
1347 case 28:
1348 return getEmissions<PollutantsInterface::ELEC>() / myLength;
1349 case 29:
1350 return getPendingEmits();
1351 case 31: {
1352 // by numerical edge param value
1354 try {
1356 } catch (NumberFormatException&) {
1357 try {
1359 } catch (BoolFormatException&) {
1361 }
1362 }
1363 } else {
1365 }
1366 }
1367 case 32: {
1368 // by numerical lane param value
1369 if (knowsParameter(s.laneParam)) {
1370 try {
1372 } catch (NumberFormatException&) {
1373 try {
1375 } catch (BoolFormatException&) {
1377 }
1378 }
1379 } else {
1381 }
1382 }
1383 case 33: {
1384 // by edge data value
1386 }
1387 case 34: {
1388 return myEdge->getDistance();
1389 }
1390 case 35: {
1391 return fabs(myEdge->getDistance());
1392 }
1393 case 36: {
1394 return myReachability;
1395 }
1396 case 37: {
1398 }
1399 case 38: {
1400 if (myParkingAreas == nullptr) {
1401 // init
1402 myParkingAreas = new std::vector<MSParkingArea*>();
1403 for (auto& item : MSNet::getInstance()->getStoppingPlaces(SUMO_TAG_PARKING_AREA)) {
1404 if (&item.second->getLane().getEdge() == myEdge) {
1405 myParkingAreas->push_back(dynamic_cast<MSParkingArea*>(item.second));
1406 }
1407 }
1408 }
1409 int capacity = 0;
1410 for (MSParkingArea* pa : *myParkingAreas) {
1411 capacity += pa->getCapacity() - pa->getOccupancy();
1412 }
1413 return capacity;
1414 }
1415 case 39: {
1416 // by live edge data value
1418 }
1419 }
1420 return 0;
1421}
1422
1423
1424double
1425GUILane::getScaleValue(const GUIVisualizationSettings& s, int activeScheme, bool s2) const {
1426 switch (activeScheme) {
1427 case 0:
1428 return 0;
1429 case 1:
1430 return isLaneOrEdgeSelected();
1431 case 2:
1432 return getSpeedLimit();
1433 case 3:
1434 return getBruttoOccupancy();
1435 case 4:
1436 return getNettoOccupancy();
1437 case 5:
1438 return firstWaitingTime();
1439 case 6:
1440 return getEdgeLaneNumber();
1441 case 7:
1442 return getEmissions<PollutantsInterface::CO2>() / myLength;
1443 case 8:
1444 return getEmissions<PollutantsInterface::CO>() / myLength;
1445 case 9:
1446 return getEmissions<PollutantsInterface::PM_X>() / myLength;
1447 case 10:
1448 return getEmissions<PollutantsInterface::NO_X>() / myLength;
1449 case 11:
1450 return getEmissions<PollutantsInterface::HC>() / myLength;
1451 case 12:
1452 return getEmissions<PollutantsInterface::FUEL>() / myLength;
1453 case 13:
1455 case 14: {
1456 return getStoredEdgeTravelTime();
1457 }
1458 case 15: {
1460 if (!ews.knowsTravelTime(myEdge)) {
1461 return -1;
1462 } else {
1463 double value(0);
1464 ews.retrieveExistingTravelTime(myEdge, 0, value);
1465 return 100 * myLength / value / getSpeedLimit();
1466 }
1467 }
1468 case 16: {
1469 return 1 / getLengthGeometryFactor(s2);
1470 }
1471 case 17: {
1472 return getLoadedEdgeWeight();
1473 }
1474 case 18: {
1475 return myEdge->getPriority();
1476 }
1477 case 19: {
1478 // scale by average speed
1479 return getMeanSpeed();
1480 }
1481 case 20: {
1482 // scale by average relative speed
1483 return getMeanSpeed() / myMaxSpeed;
1484 }
1485 case 21:
1486 return getEmissions<PollutantsInterface::ELEC>() / myLength;
1487 case 22:
1489 case 23:
1490 // by edge data value
1492 }
1493 return 0;
1494}
1495
1496
1497bool
1500}
1501
1502
1503bool
1505 return isWaterway(myPermissions) && s.showRails && !s.drawForPositionSelection; // reusing the showRails setting
1506}
1507
1508
1509#ifdef HAVE_OSG
1510void
1511GUILane::updateColor(const GUIVisualizationSettings& s) {
1512 if (myGeom == 0) {
1513 // not drawn
1514 return;
1515 }
1516 const RGBColor col = setColor(s);
1517 osg::Vec4ubArray* colors = dynamic_cast<osg::Vec4ubArray*>(myGeom->getColorArray());
1518 (*colors)[0].set(col.red(), col.green(), col.blue(), col.alpha());
1519 myGeom->setColorArray(colors);
1520}
1521#endif
1522
1523
1524void
1525GUILane::closeTraffic(bool rebuildAllowed) {
1527 if (myAmClosed) {
1528 myPermissionChanges.clear(); // reset rerouters
1530 } else {
1532 }
1534 if (rebuildAllowed) {
1536 }
1537}
1538
1539
1542 assert(MSGlobals::gUseMesoSim);
1543 int no = MELoop::numSegmentsFor(myLength, OptionsCont::getOptions().getFloat("meso-edgelength"));
1544 const double slength = myLength / no;
1545 PositionVector result = shape;
1546 double offset = 0;
1547 for (int i = 0; i < no; ++i) {
1548 offset += slength;
1549 Position pos = shape.positionAtOffset(offset);
1550 int index = result.indexOfClosest(pos);
1551 if (pos.distanceTo(result[index]) > POSITION_EPS) {
1552 index = result.insertAtClosest(pos, false);
1553 }
1554 if (i != no - 1) {
1555 mySegmentStartIndex.push_back(index);
1556 }
1557 while ((int)myShapeSegments.size() < index) {
1558 myShapeSegments.push_back(i);
1559 }
1560 //std::cout << "splitAtSegments " << getID() << " no=" << no << " i=" << i << " offset=" << offset << " index=" << index << " segs=" << toString(myShapeSegments) << " resultSize=" << result.size() << " result=" << toString(result) << "\n";
1561 }
1562 while (myShapeSegments.size() < result.size()) {
1563 myShapeSegments.push_back(no - 1);
1564 }
1565 return result;
1566}
1567
1568bool
1571}
1572
1573bool
1575 return isSelected() || gSelected.isSelected(GLO_EDGE, dynamic_cast<GUIEdge*>(myEdge)->getGlID());
1576}
1577
1578double
1581}
1582
1583double
1586 // do not select lanes in meso mode
1587 return -std::numeric_limits<double>::max();
1588 }
1589 if (myEdge->isCrossing()) {
1590 return GLO_CROSSING;
1591 }
1592 return GLO_LANE;
1593}
1594
1595
1596/****************************************************************************/
long long int SUMOTime
Definition: GUI.h:36
@ MID_COPY_EDGE_NAME
Copy edge name (for lanes only)
Definition: GUIAppEnum.h:450
@ MID_REACHABILITY
show reachability from a given lane
Definition: GUIAppEnum.h:522
@ MID_CLOSE_LANE
close lane
Definition: GUIAppEnum.h:657
@ MID_CLOSE_EDGE
close edge
Definition: GUIAppEnum.h:659
@ MID_ADD_REROUTER
add rerouter
Definition: GUIAppEnum.h:661
@ 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 RAD2DEG(x)
Definition: GeomHelper.h:36
#define STEPS2TIME(x)
Definition: SUMOTime.h:54
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
bool isWaterway(SVCPermissions permissions)
Returns whether an edge with the given permission is a waterway 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)
@ 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_AUTHORITY
authorities vehicles
@ SVC_BUS
vehicle is a bus
@ SVC_PEDESTRIAN
pedestrian
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ 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:300
static void drawFilledPoly(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:203
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition: GLHelper.cpp:421
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:583
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:558
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:767
static void pushName(unsigned int name)
push Name
Definition: GLHelper.cpp:139
static void popMatrix()
pop matrix
Definition: GLHelper.cpp:130
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:329
static void drawCrossTies(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double length, double spacing, double halfWidth, bool drawForSelection)
draw crossties for railroads or pedestrian crossings
Definition: GLHelper.cpp:785
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:277
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:883
static void popName()
pop Name
Definition: GLHelper.cpp:148
static void pushMatrix()
push matrix
Definition: GLHelper.cpp:117
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:830
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)
build menu command
Definition: GUIDesigns.cpp:42
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:579
The popup menu of a globject.
void insertMenuPaneChild(FXMenuPane *child)
Insert a sub-menu pane in this GUIGLObjectPopupMenu.
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.
Definition: GUIGlObject.h:154
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.
Definition: GUIGlObject.h:102
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:1504
void debugDrawFoeIntersections() const
draw intersection positions of foe internal lanes with this one
Definition: GUILane.cpp:933
std::vector< double > myShapeLengths
The lengths of the shape parts.
Definition: GUILane.h:358
std::vector< MSParkingArea * > * myParkingAreas
list of parkingAreas on this lane
Definition: GUILane.h:380
const VehCont & getVehiclesSecure() const override
Returns the vehicles container; locks it for microsimulation.
Definition: GUILane.cpp:153
FXMutex myLock
The mutex used to avoid concurrent updates of the vehicle buffer.
Definition: GUILane.h:401
bool isLaneOrEdgeSelected() const
whether this lane or its parent edge is selected in the GUI
Definition: GUILane.cpp:1574
void initRotations(const PositionVector &shape, std::vector< double > &rotations, std::vector< double > &lengths, std::vector< RGBColor > &colors)
Definition: GUILane.cpp:113
double myHalfLaneWidth
Half of lane width, for speed-up.
Definition: GUILane.h:371
PositionVector splitAtSegments(const PositionVector &shape)
add intermediate points at segment borders
Definition: GUILane.cpp:1541
std::vector< int > myShapeSegments
the meso segment index for each geometry segment
Definition: GUILane.h:366
double firstWaitingTime() const
Definition: GUILane.cpp:1083
double setPartialOccupation(MSVehicle *v) override
Sets the information about a vehicle lapping into this lane.
Definition: GUILane.cpp:221
double myQuarterLaneWidth
Quarter of lane width, for speed-up.
Definition: GUILane.h:374
void drawTLSLinkNo(const GUIVisualizationSettings &s, const GUINet &net) const
Definition: GUILane.cpp:263
RGBColor setColor(const GUIVisualizationSettings &s) const
sets the color according to the currente settings
Definition: GUILane.cpp:1134
double getPendingEmits() const
get number of vehicles waiting for departure on this lane
Definition: GUILane.cpp:1579
void drawLinkNo(const GUIVisualizationSettings &s) const
helper methods
Definition: GUILane.cpp:236
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own popup-menu.
Definition: GUILane.cpp:958
static GUIVisualizationSettings * myCachedGUISettings
cached for tracking color value
Definition: GUILane.h:397
void drawJunctionChangeProhibitions() const
bike lane markings on top of an intersection
Definition: GUILane.cpp:840
static const RGBColor MESO_USE_LANE_COLOR
special color to signify alternative coloring scheme
Definition: GUILane.h:404
std::vector< double > myShapeLengths2
Definition: GUILane.h:359
MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify) override
Definition: GUILane.cpp:186
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:1203
void addSecondaryShape(const PositionVector &shape) override
Definition: GUILane.cpp:134
double getScaleValue(const GUIVisualizationSettings &s, int activeScheme, bool s2) const
gets the scaling value according to the current scheme index
Definition: GUILane.cpp:1425
void resetPartialOccupation(MSVehicle *v) override
Removes the information about a vehicle lapping into this lane.
Definition: GUILane.cpp:228
void integrateNewVehicles() override
Definition: GUILane.cpp:207
void drawGL(const GUIVisualizationSettings &s) const override
Draws the object.
Definition: GUILane.cpp:524
void drawArrows(bool secondaryShape) const
Definition: GUILane.cpp:430
std::vector< int > mySegmentStartIndex
the shape indices where the meso segment changes (for segmentsIndex > 0)
Definition: GUILane.h:368
void drawLinkRules(const GUIVisualizationSettings &s, const GUINet &net) const
Definition: GUILane.cpp:302
std::vector< RGBColor > myShapeColors
The color of the shape parts (cached)
Definition: GUILane.h:362
bool neighLaneNotBidi() const
whether any of the neighboring lanes is not a bidi-lane
Definition: GUILane.cpp:775
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const override
gets the color value according to the current scheme index
Definition: GUILane.cpp:1241
void closeTraffic(bool rebuildAllowed=true)
close this lane for traffic
Definition: GUILane.cpp:1525
double getClickPriority() const override
Returns the priority of receiving mouse clicks.
Definition: GUILane.cpp:1584
bool isSelected() const override
whether this lane is selected in the GUI
Definition: GUILane.cpp:1569
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own parameter window.
Definition: GUILane.cpp:1004
const std::vector< double > & getShapeRotations(bool secondary) const
Definition: GUILane.cpp:1065
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:1121
bool drawAsRailway(const GUIVisualizationSettings &s) const
whether to draw this lane as a railway
Definition: GUILane.cpp:1498
void removeParking(MSBaseVehicle *veh) override
remove parking vehicle
Definition: GUILane.cpp:193
std::vector< double > myShapeRotations2
Definition: GUILane.h:355
double myLengthGeometryFactor2
Definition: GUILane.h:394
void planMovements(const SUMOTime t) override
Definition: GUILane.cpp:166
double getColorValueForTracker() const
return color value based on cached settings
Definition: GUILane.cpp:1229
std::vector< RGBColor > myShapeColors2
Definition: GUILane.h:363
double getEdgeLaneNumber() const
Definition: GUILane.cpp:1089
double myReachability
the time distance from a particular edge
Definition: GUILane.h:377
double getLoadedEdgeWeight() const
Returns the loaded weight (effort) for the edge of this lane.
Definition: GUILane.cpp:1108
std::vector< double > myShapeRotations
The rotations of the shape parts.
Definition: GUILane.h:354
TesselatedPolygon * myTesselation
An object that stores the tesselation.
Definition: GUILane.h:383
void setJunctionApproaches(const SUMOTime t) const override
Definition: GUILane.cpp:172
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:143
~GUILane()
Destructor.
Definition: GUILane.cpp:102
const PositionVector & getShape(bool secondary) const override
Definition: GUILane.cpp:1059
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)
Constructor.
Definition: GUILane.cpp:74
void drawLinkRule(const GUIVisualizationSettings &s, const GUINet &net, const MSLink *link, const PositionVector &shape, double x1, double x2) const
Definition: GUILane.cpp:357
Boundary getCenteringBoundary() const override
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GUILane.cpp:1047
std::vector< RGBColor > & getShapeColors(bool secondary) const
Definition: GUILane.cpp:1077
bool setFunctionalColor(const GUIColorer &c, RGBColor &col, int activeScheme=-1) const
Definition: GUILane.cpp:1151
double getStoredEdgeTravelTime() const
Returns the stored traveltime for the edge of this lane.
Definition: GUILane.cpp:1095
const std::vector< double > & getShapeLengths(bool secondary) const
Definition: GUILane.cpp:1071
void drawMarkings(const GUIVisualizationSettings &s, double scale) const
draw lane borders and white markings
Definition: GUILane.cpp:788
void drawBikeMarkings() const
bike lane markings on top of an intersection
Definition: GUILane.cpp:811
void executeMovements(const SUMOTime t) override
Definition: GUILane.cpp:179
PositionVector myShape2
secondary shape for visualization
Definition: GUILane.h:393
bool myAmClosed
state for dynamic lane closings
Definition: GUILane.h:390
void drawLane2LaneConnections(double exaggeration, bool s2) const
Definition: GUILane.cpp:497
void releaseVehicles() const override
Allows to use the container for microsimulation again.
Definition: GUILane.cpp:160
void drawDirectionIndicators(double exaggeration, bool spreadSuperposed, bool s2) const
direction indicators for lanes
Definition: GUILane.cpp:905
void detectCollisions(SUMOTime timestep, const std::string &stage) override
Definition: GUILane.cpp:214
void swapAfterLaneChange(SUMOTime t) override
moves myTmpVehicles int myVehicles after a lane change procedure
Definition: GUILane.cpp:200
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:197
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:621
int getLinkTLIndex(const MSLink *const link) const
Definition: GUINet.cpp:212
static GUINet * getGUIInstance()
Returns the pointer to the unique instance of GUINet (singleton).
Definition: GUINet.cpp:571
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:604
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
const 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 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.
GUIVisualizationTextSettings drawLinkJunctionIndex
bool drawForPositionSelection
whether drawing is performed for the purpose of selecting objects with a single click
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 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)
Definition: GeomHelper.cpp:192
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:278
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:55
A road/street connecting two junctions.
Definition: MSEdge.h:77
bool isCrossing() const
return whether this edge is a pedestrian crossing
Definition: MSEdge.h:270
int getPriority() const
Returns the priority of the edge.
Definition: MSEdge.h:325
SVCPermissions getPermissions() const
Returns the combined permissions of all lanes of this edge.
Definition: MSEdge.h:622
const std::string & getStreetName() const
Returns the street name of the edge.
Definition: MSEdge.h:310
bool isWalkingArea() const
return whether this edge is walking area
Definition: MSEdge.h:284
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
void rebuildAllowedLanes(const bool onInit=false)
Definition: MSEdge.cpp:300
const MSEdge * getBidiEdge() const
return opposite superposable/congruent edge, if it exist and 0 else
Definition: MSEdge.h:279
const MSJunction * getToJunction() const
Definition: MSEdge.h:415
bool isTazConnector() const
Definition: MSEdge.h:288
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:265
int getNumericalID() const
Returns the numerical id of the edge.
Definition: MSEdge.h:303
double getTimePenalty() const
Definition: MSEdge.h:483
const std::string & getEdgeType() const
Returns the type of the edge.
Definition: MSEdge.h:316
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:406
double getRoutingSpeed() const
Returns the averaged speed used by the routing device.
Definition: MSEdge.cpp:939
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:1156
double getDistance() const
Returns the kilometrage/mileage encoding at the start of the edge (negative values encode descending ...
Definition: MSEdge.h:332
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:103
static bool gCheckRoutes
Definition: MSGlobals.h:88
static double gLateralResolution
Definition: MSGlobals.h:97
static int gNumSimThreads
how many threads to use for simulation
Definition: MSGlobals.h:143
static bool gLefthand
Whether lefthand-drive is being simulated.
Definition: MSGlobals.h:169
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:135
const PositionVector & getShape() const
Returns this junction's shape.
Definition: MSJunction.h:93
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
SVCPermissions myPermissions
The vClass permissions for this lane.
Definition: MSLane.h:1467
virtual void setJunctionApproaches(const SUMOTime t) const
Register junction approaches for all vehicles after velocities have been planned.
Definition: MSLane.cpp:1475
std::set< const MSBaseVehicle * > myParkingVehicles
Definition: MSLane.h:1445
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:2562
virtual void removeParking(MSBaseVehicle *veh)
remove parking vehicle. This must be syncrhonized when running with GUI
Definition: MSLane.cpp:3381
virtual void integrateNewVehicles()
Insert buffered vehicle into the real lane.
Definition: MSLane.cpp:2311
double myLength
Lane length [m].
Definition: MSLane.h:1448
double getNettoOccupancy() const
Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps)
Definition: MSLane.cpp:3103
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:2544
PositionVector myShape
The shape of the lane.
Definition: MSLane.h:1396
std::map< long long, SVCPermissions > myPermissionChanges
Definition: MSLane.h:1544
double getFrictionCoefficient() const
Returns the lane's friction coefficient.
Definition: MSLane.h:586
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:411
MSEdge *const myEdge
The lane's edge, for routing only.
Definition: MSLane.h:1459
bool allowsChangingRight(SUMOVehicleClass vclass) const
Returns whether the given vehicle class may change left from this lane.
Definition: MSLane.h:910
double myMaxSpeed
Lane-wide speedlimit [m/s].
Definition: MSLane.h:1462
const MSLink * getLinkTo(const MSLane *const) const
returns the link to the given lane or nullptr, if it is not connected
Definition: MSLane.cpp:2469
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:1435
VehCont myVehicles
The lane's vehicles. This container holds all vehicles that have their front (longitudinally) and the...
Definition: MSLane.h:1412
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition: MSLane.h:579
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:119
MSLane * myBidiLane
Definition: MSLane.h:1541
void resetPermissions(long long transientID)
Definition: MSLane.cpp:4207
const std::string myLaneType
the type of this lane
Definition: MSLane.h:1527
int myRNGIndex
Definition: MSLane.h:1547
double getLength() const
Returns the lane's length.
Definition: MSLane.h:593
const PositionVector & getShape() const
Returns this lane's shape.
Definition: MSLane.h:524
virtual void swapAfterLaneChange(SUMOTime t)
moves myTmpVehicles int myVehicles after a lane change procedure
Definition: MSLane.cpp:2530
StopOffset myLaneStopOffset
Definition: MSLane.h:1456
virtual double setPartialOccupation(MSVehicle *v)
Sets the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:340
int getIndex() const
Returns the lane's index.
Definition: MSLane.h:629
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:4195
const double myWidth
Lane width [m].
Definition: MSLane.h:1451
virtual void executeMovements(const SUMOTime t)
Executes planned vehicle movements with regards to right-of-way.
Definition: MSLane.cpp:2051
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:2908
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:3088
int myIndex
The lane index.
Definition: MSLane.h:1399
bool isCrossing() const
Definition: MSLane.cpp:2377
virtual void detectCollisions(SUMOTime timestep, const std::string &stage)
Check if vehicles are too close.
Definition: MSLane.cpp:1536
std::vector< MSLink * > myLinks
Definition: MSLane.h:1505
bool isInternal() const
Definition: MSLane.cpp:2365
static const long CHANGE_PERMISSIONS_GUI
Definition: MSLane.h:1330
double interpolateGeometryPosToLanePos(double geometryPos) const
Definition: MSLane.h:557
virtual void resetPartialOccupation(MSVehicle *v)
Removes the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:359
double getHarmonoise_NoiseEmissions() const
Returns the sum of last step noise emissions.
Definition: MSLane.cpp:3177
MSLane * getBidiLane() const
retrieve bidirectional lane or nullptr
Definition: MSLane.cpp:4321
double getLengthGeometryFactor() const
return shape.length() / myLength
Definition: MSLane.h:529
virtual const PositionVector & getShape(bool) const
Definition: MSLane.h:293
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:745
double getWidth() const
Returns the lane's width.
Definition: MSLane.h:622
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.h:707
double getMeanSpeed() const
Returns the mean speed on this lane.
Definition: MSLane.cpp:3131
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition: MSLane.h:551
Notification
Definition of a vehicle state.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:183
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:351
MSEdgeWeightsStorage & getWeightsStorage()
Returns the net's internal edge travel times/efforts container.
Definition: MSNet.cpp:1182
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:431
A lane area vehicles can halt at.
Definition: MSParkingArea.h:58
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.
Definition: OptionsCont.cpp:59
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.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
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:254
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:244
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 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 ammount
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
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)
Definition: RandHelper.cpp:94
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 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
Definition: GUIPolygon.cpp:118
static FXIcon * getVClassIcon(const SUMOVehicleClass vc)
returns icon associated to the given vClass
Definition: VClassIcons.cpp:34
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