LCOV - code coverage report
Current view: top level - src/gui - GUIViewTraffic.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 26.0 % 350 91
Test Date: 2024-12-21 15:45:41 Functions: 31.2 % 32 10

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    GUIViewTraffic.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Christian Roessel
      18              : /// @author  Michael Behrisch
      19              : /// @author  Andreas Gaubatz
      20              : /// @date    Sept 2002
      21              : ///
      22              : // A view on the simulation; this view is a microscopic one
      23              : /****************************************************************************/
      24              : #include <config.h>
      25              : 
      26              : #ifdef HAVE_FFMPEG
      27              : #include <utils/gui/div/GUIVideoEncoder.h>
      28              : #endif
      29              : 
      30              : #include <iostream>
      31              : #include <utility>
      32              : #include <cmath>
      33              : #include <limits>
      34              : #include <foreign/rtree/SUMORTree.h>
      35              : #include <gui/GUIApplicationWindow.h>
      36              : #include <gui/GUIGlobals.h>
      37              : #include <guisim/GUIEdge.h>
      38              : #include <guisim/GUILane.h>
      39              : #include <guisim/GUINet.h>
      40              : #include <guisim/GUIVehicle.h>
      41              : #include <guisim/GUIVehicleControl.h>
      42              : #include <microsim/MSEdge.h>
      43              : #include <microsim/MSGlobals.h>
      44              : #include <microsim/MSJunctionControl.h>
      45              : #include <microsim/MSLane.h>
      46              : #include <microsim/MSStoppingPlace.h>
      47              : #include <microsim/traffic_lights/MSSimpleTrafficLightLogic.h>
      48              : #include <microsim/traffic_lights/MSTLLogicControl.h>
      49              : #include <utils/common/RGBColor.h>
      50              : #include <utils/foxtools/MFXButtonTooltip.h>
      51              : #include <utils/foxtools/MFXCheckableButton.h>
      52              : #include <utils/foxtools/MFXImageHelper.h>
      53              : #include <utils/geom/PositionVector.h>
      54              : #include <utils/gui/div/GLHelper.h>
      55              : #include <utils/gui/div/GUIDesigns.h>
      56              : #include <utils/gui/div/GUIGlobalSelection.h>
      57              : #include <utils/gui/globjects/GLIncludes.h>
      58              : #include <utils/gui/globjects/GUIGlObjectStorage.h>
      59              : #include <utils/gui/globjects/GUIShapeContainer.h>
      60              : #include <utils/gui/images/GUIIconSubSys.h>
      61              : #include <utils/gui/settings/GUICompleteSchemeStorage.h>
      62              : #include <utils/gui/windows/GUIAppEnum.h>
      63              : #include <utils/gui/windows/GUIDialog_ViewSettings.h>
      64              : #include <utils/gui/windows/GUIPerspectiveChanger.h>
      65              : #include <utils/gui/windows/GUISUMOAbstractView.h>
      66              : #include <utils/shapes/ShapeContainer.h>
      67              : 
      68              : #include "GUISUMOViewParent.h"
      69              : #include "GUIViewTraffic.h"
      70              : 
      71              : // ===========================================================================
      72              : // member method definitions
      73              : // ===========================================================================
      74         6739 : GUIViewTraffic::GUIViewTraffic(
      75              :     FXComposite* p,
      76              :     GUIMainWindow& app,
      77              :     GUISUMOViewParent* parent,
      78              :     GUINet& net, FXGLVisual* glVis,
      79         6739 :     FXGLCanvas* share) :
      80              :     GUISUMOAbstractView(p, app, parent, net.getVisualisationSpeedUp(), glVis, share),
      81         6739 :     myTrackedID(GUIGlObject::INVALID_ID),
      82         6739 :     myTLSGame(OptionsCont::getOptions().getString("game.mode") == "tls")
      83              : #ifdef HAVE_FFMPEG
      84         6739 :     , myCurrentVideo(nullptr)
      85              : #endif
      86         6739 : {}
      87              : 
      88              : 
      89        13444 : GUIViewTraffic::~GUIViewTraffic() {
      90         6722 :     endSnapshot();
      91        13444 : }
      92              : 
      93              : 
      94              : void
      95         6739 : GUIViewTraffic::buildViewToolBars(GUIGlChildWindow* v) {
      96              :     // build coloring tools
      97              :     {
      98         6739 :         const std::vector<std::string>& names = gSchemeStorage.getNames();
      99        40467 :         for (std::vector<std::string>::const_iterator i = names.begin(); i != names.end(); ++i) {
     100        33728 :             v->getColoringSchemesCombo()->appendIconItem(i->c_str());
     101        33728 :             if ((*i) == myVisualizationSettings->name) {
     102         6739 :                 v->getColoringSchemesCombo()->setCurrentItem(v->getColoringSchemesCombo()->getNumItems() - 1);
     103              :             }
     104              :         }
     105              :     }
     106              :     // for junctions
     107         6739 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     108        20217 :                          (std::string("\t") + TL("Locate Junctions") + std::string("\t") + TL("Locate a junction within the network.")).c_str(),
     109              :                          GUIIconSubSys::getIcon(GUIIcon::LOCATEJUNCTION), v, MID_HOTKEY_SHIFT_J_LOCATEJUNCTION,
     110        20217 :                          GUIDesignButtonPopup);
     111              :     // for edges
     112         6739 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     113        20217 :                          (std::string("\t") + TL("Locate Edges") + std::string("\t") + TL("Locate an edge within the network.")).c_str(),
     114              :                          GUIIconSubSys::getIcon(GUIIcon::LOCATEEDGE), v, MID_HOTKEY_SHIFT_E_LOCATEEDGE,
     115        20217 :                          GUIDesignButtonPopup);
     116              :     // for vehicles
     117         6739 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     118        20217 :                          (std::string("\t") + TL("Locate Vehicles") + std::string("\t") + TL("Locate a vehicle within the network.")).c_str(),
     119              :                          GUIIconSubSys::getIcon(GUIIcon::LOCATEVEHICLE), v, MID_HOTKEY_SHIFT_V_LOCATEVEHICLE,
     120        20217 :                          GUIDesignButtonPopup);
     121              :     // for persons
     122         6739 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     123        20217 :                          (std::string("\t") + TL("Locate Persons") + std::string("\t") + TL("Locate a person within the network.")).c_str(),
     124              :                          GUIIconSubSys::getIcon(GUIIcon::LOCATEPERSON), v, MID_HOTKEY_SHIFT_P_LOCATEPERSON,
     125        20217 :                          GUIDesignButtonPopup);
     126              :     // for containers
     127         6739 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     128        20217 :                          (std::string("\t") + TL("Locate Container") + std::string("\t") + TL("Locate a container within the network.")).c_str(),
     129              :                          GUIIconSubSys::getIcon(GUIIcon::LOCATECONTAINER), v, MID_HOTKEY_SHIFT_C_LOCATECONTAINER,
     130        20217 :                          GUIDesignButtonPopup);
     131              :     // for tls
     132         6739 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     133        20217 :                          (std::string("\t") + TL("Locate TLS") + std::string("\t") + TL("Locate a tls within the network.")).c_str(),
     134              :                          GUIIconSubSys::getIcon(GUIIcon::LOCATETLS), v, MID_HOTKEY_SHIFT_T_LOCATETLS,
     135        20217 :                          GUIDesignButtonPopup);
     136              :     // for additional stuff
     137         6739 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     138        20217 :                          (std::string("\t") + TL("Locate Additional") + std::string("\t") + TL("Locate an additional structure within the network.")).c_str(),
     139              :                          GUIIconSubSys::getIcon(GUIIcon::LOCATEADD), v, MID_HOTKEY_SHIFT_A_LOCATEADDITIONAL,
     140        20217 :                          GUIDesignButtonPopup);
     141              :     // for pois
     142         6739 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     143        20217 :                          (std::string("\t") + TL("Locate PoI") + std::string("\t") + TL("Locate a PoI within the network.")).c_str(),
     144              :                          GUIIconSubSys::getIcon(GUIIcon::LOCATEPOI), v, MID_HOTKEY_SHIFT_O_LOCATEPOI,
     145        20217 :                          GUIDesignButtonPopup);
     146              :     // for polygons
     147         6739 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     148        20217 :                          (std::string("\t") + TL("Locate Polygon") + std::string("\t") + TL("Locate a Polygon within the network.")).c_str(),
     149              :                          GUIIconSubSys::getIcon(GUIIcon::LOCATEPOLY), v, MID_HOTKEY_SHIFT_L_LOCATEPOLY,
     150        20217 :                          GUIDesignButtonPopup);
     151         6739 : }
     152              : 
     153              : 
     154              : bool
     155           35 : GUIViewTraffic::setColorScheme(const std::string& name) {
     156           35 :     if (!gSchemeStorage.contains(name)) {
     157              :         return false;
     158              :     }
     159           32 :     if (myGUIDialogViewSettings != nullptr) {
     160            0 :         if (myGUIDialogViewSettings->getCurrentScheme() != name) {
     161            0 :             myGUIDialogViewSettings->setCurrentScheme(name);
     162              :         }
     163              :     }
     164           32 :     myVisualizationSettings = &gSchemeStorage.get(name.c_str());
     165           32 :     myVisualizationSettings->gaming = myApp->isGaming();
     166           32 :     update();
     167           32 :     return true;
     168              : }
     169              : 
     170              : 
     171              : void
     172            0 : GUIViewTraffic::buildColorRainbow(const GUIVisualizationSettings& s, GUIColorScheme& scheme, int active, GUIGlObjectType objectType,
     173              :                                   const GUIVisualizationRainbowSettings& rs) {
     174              :     assert(!scheme.isFixed());
     175              :     double minValue = std::numeric_limits<double>::infinity();
     176              :     double maxValue = -std::numeric_limits<double>::infinity();
     177              :     // retrieve range
     178              :     bool hasMissingData = false;
     179            0 :     if (objectType == GLO_LANE) {
     180              :         // XXX (see #3409) multi-colors are not currently handled. this is a quick hack
     181            0 :         if (active == 22) {
     182              :             active = 21; // segment height, fall back to start height
     183            0 :         } else if (active == 24) {
     184              :             active = 23; // segment incline, fall back to total incline
     185              :         }
     186            0 :         const MSEdgeVector& edges = MSEdge::getAllEdges();
     187            0 :         for (MSEdgeVector::const_iterator it = edges.begin(); it != edges.end(); ++it) {
     188            0 :             if (MSGlobals::gUseMesoSim) {
     189            0 :                 const double val = static_cast<GUIEdge*>(*it)->getColorValue(s, active);
     190            0 :                 if (val == s.MISSING_DATA) {
     191              :                     hasMissingData = true;
     192            0 :                     continue;
     193              :                 }
     194              :                 minValue = MIN2(minValue, val);
     195              :                 maxValue = MAX2(maxValue, val);
     196              :             } else {
     197            0 :                 const std::vector<MSLane*>& lanes = (*it)->getLanes();
     198            0 :                 for (std::vector<MSLane*>::const_iterator it_l = lanes.begin(); it_l != lanes.end(); it_l++) {
     199            0 :                     const double val = static_cast<GUILane*>(*it_l)->getColorValue(s, active);
     200            0 :                     if (val == s.MISSING_DATA) {
     201              :                         hasMissingData = true;
     202            0 :                         continue;
     203              :                     }
     204              :                     minValue = MIN2(minValue, val);
     205              :                     maxValue = MAX2(maxValue, val);
     206              :                 }
     207              :             }
     208              :         }
     209            0 :     } else if (objectType == GLO_JUNCTION) {
     210            0 :         if (active == 3) {
     211              :             std::set<const MSJunction*> junctions;
     212            0 :             for (MSEdge* edge : MSEdge::getAllEdges()) {
     213            0 :                 junctions.insert(edge->getFromJunction());
     214            0 :                 junctions.insert(edge->getToJunction());
     215              :             }
     216            0 :             for (const MSJunction* junction : junctions) {
     217            0 :                 minValue = MIN2(minValue, junction->getPosition().z());
     218            0 :                 maxValue = MAX2(maxValue, junction->getPosition().z());
     219              :             }
     220              :         }
     221              :     }
     222            0 :     if (scheme.getName() == GUIVisualizationSettings::SCHEME_NAME_PERMISSION_CODE) {
     223            0 :         scheme.clear();
     224              :         // add threshold for every distinct value
     225              :         std::set<SVCPermissions> codes;
     226            0 :         for (MSEdge* edge : MSEdge::getAllEdges()) {
     227            0 :             for (MSLane* lane : edge->getLanes()) {
     228            0 :                 codes.insert(lane->getPermissions());
     229              :             }
     230              :         }
     231            0 :         int step = MAX2(1, 360 / (int)codes.size());
     232              :         int hue = 0;
     233            0 :         for (SVCPermissions p : codes) {
     234            0 :             scheme.addColor(RGBColor::fromHSV(hue, 1, 1), (double)p);
     235            0 :             hue = (hue + step) % 360;
     236              :         }
     237              :         return;
     238              :     }
     239            0 :     buildMinMaxRainbow(s, scheme, rs, minValue, maxValue, hasMissingData);
     240              : }
     241              : 
     242              : 
     243              : std::vector<std::string>
     244            0 : GUIViewTraffic::getEdgeDataAttrs() const {
     245            0 :     if (GUINet::getGUIInstance() != nullptr) {
     246            0 :         return GUINet::getGUIInstance()->getEdgeDataAttrs();
     247              :     }
     248            0 :     return std::vector<std::string>();
     249              : }
     250              : 
     251              : 
     252              : std::vector<std::string>
     253            0 : GUIViewTraffic::getMeanDataIDs() const {
     254            0 :     if (GUINet::getGUIInstance() != nullptr) {
     255            0 :         return GUINet::getGUIInstance()->getMeanDataIDs();
     256              :     }
     257            0 :     return std::vector<std::string>();
     258              : }
     259              : 
     260              : std::vector<std::string>
     261            0 : GUIViewTraffic::getMeanDataAttrs(const std::string& meanDataID) const {
     262            0 :     if (GUINet::getGUIInstance() != nullptr) {
     263            0 :         return GUINet::getGUIInstance()->getMeanDataAttrs(meanDataID);
     264              :     }
     265            0 :     return std::vector<std::string>();
     266              : }
     267              : 
     268              : 
     269              : std::vector<std::string>
     270            0 : GUIViewTraffic::getEdgeLaneParamKeys(bool edgeKeys) const {
     271              :     std::set<std::string> keys;
     272            0 :     for (const MSEdge* e : MSEdge::getAllEdges()) {
     273            0 :         if (edgeKeys) {
     274            0 :             for (const auto& item : e->getParametersMap()) {
     275            0 :                 keys.insert(item.first);
     276              :             }
     277              :         } else {
     278            0 :             for (const auto lane : e->getLanes()) {
     279            0 :                 for (const auto& item : lane->getParametersMap()) {
     280            0 :                     keys.insert(item.first);
     281              :                 }
     282              :             }
     283              :         }
     284              :     }
     285            0 :     return std::vector<std::string>(keys.begin(), keys.end());
     286              : }
     287              : 
     288              : 
     289              : std::vector<std::string>
     290            0 : GUIViewTraffic::getVehicleParamKeys(bool /*vTypeKeys*/) const {
     291              :     std::set<std::string> keys;
     292            0 :     GUIVehicleControl* vc = GUINet::getGUIInstance()->getGUIVehicleControl();
     293            0 :     vc->secureVehicles();
     294            0 :     for (auto vehIt = vc->loadedVehBegin(); vehIt != vc->loadedVehEnd(); ++vehIt) {
     295            0 :         for (auto kv : vehIt->second->getParameter().getParametersMap()) {
     296              :             keys.insert(kv.first);
     297              :         }
     298              :     }
     299            0 :     vc->releaseVehicles();
     300            0 :     return std::vector<std::string>(keys.begin(), keys.end());
     301              : }
     302              : 
     303              : std::vector<std::string>
     304            0 : GUIViewTraffic::getPOIParamKeys() const {
     305              :     std::set<std::string> keys;
     306            0 :     const ShapeContainer::POIs& pois = static_cast<ShapeContainer&>(GUINet::getInstance()->getShapeContainer()).getPOIs();
     307            0 :     for (auto item : pois) {
     308            0 :         for (auto kv : item.second->getParametersMap()) {
     309              :             keys.insert(kv.first);
     310              :         }
     311              :     }
     312            0 :     return std::vector<std::string>(keys.begin(), keys.end());
     313              : }
     314              : 
     315              : int
     316       519573 : GUIViewTraffic::doPaintGL(int mode, const Boundary& bound) {
     317              :     // init view settings
     318       519573 :     glRenderMode(mode);
     319       519573 :     glMatrixMode(GL_MODELVIEW);
     320       519573 :     GLHelper::pushMatrix();
     321       519573 :     glDisable(GL_TEXTURE_2D);
     322       519573 :     glDisable(GL_ALPHA_TEST);
     323       519573 :     glEnable(GL_BLEND);
     324       519573 :     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     325       519573 :     glEnable(GL_DEPTH_TEST);
     326              : 
     327              :     // draw decals (if not in grabbing mode)
     328       519573 :     drawDecals();
     329       519573 :     myVisualizationSettings->scale = m2p(SUMO_const_laneWidth);
     330       519573 :     if (myVisualizationSettings->showGrid) {
     331            0 :         paintGLGrid();
     332              :     }
     333       519573 :     glLineWidth(1);
     334       519573 :     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     335       519573 :     const float minB[2] = { (float)bound.xmin(), (float)bound.ymin() };
     336       519573 :     const float maxB[2] = { (float)bound.xmax(), (float)bound.ymax() };
     337       519573 :     glEnable(GL_POLYGON_OFFSET_FILL);
     338       519573 :     glEnable(GL_POLYGON_OFFSET_LINE);
     339       519573 :     const SUMORTree& grid = GUINet::getGUIInstance()->getVisualisationSpeedUp(myVisualizationSettings->secondaryShape);
     340       519573 :     int hits2 = grid.Search(minB, maxB, *myVisualizationSettings);
     341       519569 :     GUIGlobals::gSecondaryShape = myVisualizationSettings->secondaryShape;
     342              :     // Draw additional objects
     343       519569 :     if (myAdditionallyDrawn.size() > 0) {
     344            5 :         glTranslated(0, 0, -.01);
     345            5 :         GUINet::getGUIInstance()->lock();
     346           10 :         for (auto i : myAdditionallyDrawn) {
     347            5 :             i.first->drawGLAdditional(this, *myVisualizationSettings);
     348              :         }
     349            5 :         GUINet::getGUIInstance()->unlock();
     350            5 :         glTranslated(0, 0, .01);
     351              :     }
     352       519569 :     GLHelper::popMatrix();
     353              :     /*
     354              :     // draw legends
     355              :     glMatrixMode(GL_MODELVIEW);
     356              :     glLoadIdentity();
     357              :     glTranslated(1.-.2, 1.-.5, 0.);
     358              :     glScaled(.2, .5, 1.);
     359              :     GUIColoringSchemesMap<GUILane> &sm = GUIViewTraffic::getLaneSchemesMap(); //!!!
     360              :     sm.getColorer(myVisualizationSettings->laneEdgeMode)->drawLegend();
     361              :     */
     362       519569 :     return hits2;
     363              : }
     364              : 
     365              : 
     366              : void
     367            0 : GUIViewTraffic::startTrack(int id) {
     368            0 :     myTrackedID = id;
     369            0 :     GUIGlObject* o = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id);
     370            0 :     if (o != nullptr) {
     371            0 :         GUIBaseVehicle* v = dynamic_cast<GUIBaseVehicle*>(o);
     372            0 :         if (v != nullptr) {
     373            0 :             v->addActiveAddVisualisation(this, GUIBaseVehicle::VO_TRACK);
     374              :         }
     375              :     }
     376            0 : }
     377              : 
     378              : 
     379              : void
     380            0 : GUIViewTraffic::stopTrack() {
     381            0 :     myTrackedID = GUIGlObject::INVALID_ID;
     382            0 : }
     383              : 
     384              : 
     385              : GUIGlID
     386       974972 : GUIViewTraffic::getTrackedID() const {
     387       974972 :     return myTrackedID;
     388              : }
     389              : 
     390              : 
     391              : void
     392            0 : GUIViewTraffic::onGamingClick(Position pos) {
     393            0 :     if (myTLSGame) {
     394            0 :         MSTLLogicControl& tlsControl = MSNet::getInstance()->getTLSControl();
     395              :         MSTrafficLightLogic* minTll = nullptr;
     396              :         double minDist = std::numeric_limits<double>::infinity();
     397            0 :         for (MSTrafficLightLogic* const tll : tlsControl.getAllLogics()) {
     398            0 :             if (tlsControl.isActive(tll) && tll->getProgramID() != "off") {
     399              :                 // get the links
     400              :                 const MSTrafficLightLogic::LaneVector& lanes = tll->getLanesAt(0);
     401            0 :                 if (lanes.size() > 0) {
     402            0 :                     const Position& endPos = lanes[0]->getShape().back();
     403            0 :                     if (endPos.distanceTo(pos) < minDist) {
     404            0 :                         minDist = endPos.distanceTo(pos);
     405              :                         minTll = tll;
     406              :                     }
     407              :                 }
     408              :             }
     409            0 :         }
     410            0 :         if (minTll != nullptr) {
     411            0 :             if (minTll->getPhaseNumber() == 0) {
     412              :                 // MSRailSignal
     413              :                 return;
     414              :             }
     415            0 :             const int ci = minTll->getCurrentPhaseIndex();
     416            0 :             const int n = minTll->getPhaseNumber();
     417              :             int greenCount = 0;
     418            0 :             for (auto& phase : minTll->getPhases()) {
     419            0 :                 if (phase->isGreenPhase()) {
     420            0 :                     greenCount++;
     421              :                 }
     422              :             }
     423            0 :             int nextPhase = (ci + 1) % n;
     424              :             SUMOTime nextDuration = 0;
     425            0 :             if (minTll->getCurrentPhaseDef().isGreenPhase() || (greenCount == 1 && minTll->getCurrentPhaseDef().isAllRedPhase())) {
     426            0 :                 nextDuration = minTll->getPhase(nextPhase).duration;
     427              :             } else {
     428              :                 // we are in transition to a green phase
     429              :                 // -> skip forward to the transition into the next green phase
     430              :                 // but ensure that the total transition time is maintained
     431              :                 // taking into account how much time was already spent
     432            0 :                 SUMOTime spentTransition = minTll->getSpentDuration();
     433              :                 // the transition may consist of more than one phase so we
     434              :                 // search backwards until the prior green phase
     435            0 :                 for (int i = ci - 1; i != ci; i--) {
     436            0 :                     if (i < 0) {
     437            0 :                         i = n - 1;
     438              :                     }
     439            0 :                     if (minTll->getPhase(i).isGreenPhase()) {
     440              :                         break;
     441              :                     }
     442            0 :                     spentTransition += minTll->getPhase(i).duration;
     443              :                 }
     444              :                 // now we skip past the next greenphase
     445              :                 int numGreen = 0;
     446              :                 int i = nextPhase;
     447            0 :                 for (; numGreen < 2; i = (i + 1) % n) {
     448            0 :                     if (minTll->getPhase(i).isGreenPhase()) {
     449            0 :                         numGreen++;
     450            0 :                         continue;
     451              :                     }
     452              :                     // transition after the next green
     453            0 :                     if (numGreen == 1) {
     454            0 :                         SUMOTime dur = minTll->getPhase(i).duration;
     455            0 :                         if (dur <= spentTransition) {
     456            0 :                             spentTransition -= dur;
     457              :                         } else {
     458              :                             nextPhase = i;
     459            0 :                             nextDuration = dur - spentTransition;
     460            0 :                             break;
     461              :                         }
     462              :                     }
     463              :                 }
     464              :             }
     465            0 :             minTll->changeStepAndDuration(tlsControl, MSNet::getInstance()->getCurrentTimeStep(), nextPhase, nextDuration);
     466            0 :             update();
     467              :         }
     468              :     } else {
     469              :         // DRT game
     470            0 :         if (MSGlobals::gUseMesoSim) {
     471              :             return;
     472              :         }
     473            0 :         const auto& sel = gSelected.getSelected(GLO_VEHICLE);
     474            0 :         if (sel.size() == 0) {
     475              :             // find closest pt vehicle
     476              :             double minDist = std::numeric_limits<double>::infinity();
     477              :             GUIVehicle* closest = nullptr;
     478            0 :             MSVehicleControl& vc = MSNet::getInstance()->getVehicleControl();
     479              :             MSVehicleControl::constVehIt it = vc.loadedVehBegin();
     480              :             MSVehicleControl::constVehIt end = vc.loadedVehEnd();
     481            0 :             for (it = vc.loadedVehBegin(); it != end; ++it) {
     482            0 :                 GUIVehicle* veh = dynamic_cast<GUIVehicle*>(it->second);
     483              :                 assert(veh != 0);
     484            0 :                 if (veh->getParameter().line != "") {
     485            0 :                     const double dist = veh->getPosition().distanceTo2D(pos);
     486            0 :                     if (dist < minDist) {
     487              :                         minDist = dist;
     488              :                         closest = veh;
     489              :                     }
     490              :                 }
     491              :             }
     492            0 :             if (closest != nullptr) {
     493            0 :                 gSelected.select(closest->getGlID());
     494            0 :                 closest->addActiveAddVisualisation(this, GUIBaseVehicle::VO_SHOW_FUTURE_ROUTE);
     495              :             }
     496              :         } else {
     497              :             // find closest pt stop
     498              :             double minDist = std::numeric_limits<double>::infinity();
     499              :             MSStoppingPlace* closestStop = nullptr;
     500            0 :             const NamedObjectCont<MSStoppingPlace*>& stops = MSNet::getInstance()->getStoppingPlaces(SUMO_TAG_BUS_STOP);
     501            0 :             for (auto it = stops.begin(); it != stops.end(); ++it) {
     502            0 :                 MSStoppingPlace* stop = it->second;
     503            0 :                 const double dist = pos.distanceTo2D(stop->getLane().geometryPositionAtOffset(stop->getEndLanePosition()));
     504            0 :                 if (dist < minDist) {
     505              :                     minDist = dist;
     506              :                     closestStop = stop;
     507              :                 }
     508              :             }
     509            0 :             if (closestStop != 0) {
     510            0 :                 GUIGlID id = *sel.begin();
     511            0 :                 GUIVehicle* veh = dynamic_cast<GUIVehicle*>(GUIGlObjectStorage::gIDStorage.getObjectBlocking(id));
     512              :                 assert(veh != 0);
     513              :                 MSLane* lane = veh->getMutableLane();
     514            0 :                 lane->getVehiclesSecure();
     515            0 :                 veh->rerouteDRTStop(closestStop);
     516            0 :                 GUIGlObjectStorage::gIDStorage.unblockObject(id);
     517            0 :                 lane->releaseVehicles();
     518              :             }
     519              :         }
     520              :     }
     521              : }
     522              : 
     523              : 
     524              : void
     525            0 : GUIViewTraffic::onGamingRightClick(Position /*pos*/) {
     526            0 :     const auto& sel = gSelected.getSelected(GLO_VEHICLE);
     527            0 :     if (sel.size() > 0) {
     528            0 :         GUIGlID id = *sel.begin();
     529            0 :         GUIVehicle* veh = dynamic_cast<GUIVehicle*>(GUIGlObjectStorage::gIDStorage.getObjectBlocking(id));
     530            0 :         if (veh != 0) {
     531            0 :             veh->removeActiveAddVisualisation(this, GUIBaseVehicle::VO_SHOW_FUTURE_ROUTE);
     532              :         }
     533            0 :         GUIGlObjectStorage::gIDStorage.unblockObject(id);
     534              :     }
     535            0 :     gSelected.clear();
     536            0 : }
     537              : 
     538              : 
     539              : SUMOTime
     540      5547283 : GUIViewTraffic::getCurrentTimeStep() const {
     541      5547283 :     return MSNet::getInstance()->getCurrentTimeStep();
     542              : }
     543              : 
     544              : 
     545              : long
     546            0 : GUIViewTraffic::onCmdCloseLane(FXObject*, FXSelector, void*) {
     547            0 :     GUILane* lane = getLaneUnderCursor();
     548            0 :     if (lane != nullptr) {
     549            0 :         lane->closeTraffic();
     550            0 :         GUIGlObjectStorage::gIDStorage.unblockObject(lane->getGlID());
     551            0 :         update();
     552              :     }
     553            0 :     return 1;
     554              : }
     555              : 
     556              : 
     557              : long
     558            0 : GUIViewTraffic::onCmdCloseEdge(FXObject*, FXSelector, void*) {
     559            0 :     GUILane* lane = getLaneUnderCursor();
     560            0 :     if (lane != nullptr) {
     561            0 :         dynamic_cast<GUIEdge*>(&lane->getEdge())->closeTraffic(lane);
     562            0 :         GUIGlObjectStorage::gIDStorage.unblockObject(lane->getGlID());
     563            0 :         update();
     564              :     }
     565            0 :     return 1;
     566              : }
     567              : 
     568              : 
     569              : long
     570            0 : GUIViewTraffic::onCmdAddRerouter(FXObject*, FXSelector, void*) {
     571            0 :     GUILane* lane = getLaneUnderCursor();
     572            0 :     if (lane != nullptr) {
     573            0 :         dynamic_cast<GUIEdge*>(&lane->getEdge())->addRerouter();
     574            0 :         GUIGlObjectStorage::gIDStorage.unblockObject(lane->getGlID());
     575            0 :         update();
     576              :     }
     577            0 :     return 1;
     578              : }
     579              : 
     580              : 
     581              : long
     582            0 : GUIViewTraffic::showLaneReachability(GUILane* lane, FXObject* menu, FXSelector) {
     583            0 :     if (lane != nullptr) {
     584              :         // reset
     585              :         const double UNREACHED = INVALID_DOUBLE;
     586            0 :         gSelected.clear();
     587            0 :         for (const MSEdge* const e : MSEdge::getAllEdges()) {
     588            0 :             for (MSLane* const l : e->getLanes()) {
     589            0 :                 GUILane* gLane = dynamic_cast<GUILane*>(l);
     590              :                 gLane->setReachability(UNREACHED);
     591              :             }
     592              :         }
     593              :         // prepare
     594            0 :         FXMenuCommand* mc = dynamic_cast<FXMenuCommand*>(menu);
     595            0 :         const SUMOVehicleClass svc = SumoVehicleClassStrings.get(mc->getText().text());
     596            0 :         const double defaultMaxSpeed = SUMOVTypeParameter::VClassDefaultValues(svc).desiredMaxSpeed;
     597              :         // find reachable
     598              :         std::map<MSEdge*, double> reachableEdges;
     599            0 :         reachableEdges[&lane->getEdge()] = 0;
     600              :         MSEdgeVector check;
     601            0 :         check.push_back(&lane->getEdge());
     602            0 :         while (check.size() > 0) {
     603            0 :             MSEdge* e = check.front();
     604              :             check.erase(check.begin());
     605            0 :             double traveltime = reachableEdges[e];
     606            0 :             for (MSLane* const l : e->getLanes()) {
     607            0 :                 if (l->allowsVehicleClass(svc)) {
     608            0 :                     GUILane* gLane = dynamic_cast<GUILane*>(l);
     609            0 :                     gSelected.select(gLane->getGlID(), false);
     610              :                     gLane->setReachability(traveltime);
     611              :                 }
     612              :             }
     613            0 :             const double dt = e->getLength() / MIN2(e->getSpeedLimit(), defaultMaxSpeed);
     614              :             // ensure algorithm termination
     615            0 :             traveltime += MAX2(dt, NUMERICAL_EPS);
     616            0 :             for (MSEdge* const nextEdge : e->getSuccessors(svc)) {
     617            0 :                 if (reachableEdges.count(nextEdge) == 0 ||
     618              :                         // revisit edge via faster path
     619            0 :                         reachableEdges[nextEdge] > traveltime) {
     620            0 :                     reachableEdges[nextEdge] = traveltime;
     621            0 :                     check.push_back(nextEdge);
     622              :                 }
     623              :             }
     624            0 :             if (svc == SVC_PEDESTRIAN) {
     625              :                 // can also walk backwards
     626            0 :                 for (MSEdge* const prevEdge : e->getPredecessors()) {
     627            0 :                     if (prevEdge->allowedLanes(*e, svc) != nullptr &&
     628            0 :                             (reachableEdges.count(prevEdge) == 0 ||
     629              :                              // revisit edge via faster path
     630            0 :                              reachableEdges[prevEdge] > traveltime)) {
     631            0 :                         reachableEdges[prevEdge] = traveltime;
     632            0 :                         check.push_back(prevEdge);
     633              :                     }
     634              :                 }
     635              :                 // and connect to arbitrary incoming if there are no walkingareas
     636            0 :                 if (!MSNet::getInstance()->hasPedestrianNetwork()) {
     637            0 :                     for (const MSEdge* const in_const : e->getToJunction()->getIncoming()) {
     638            0 :                         MSEdge* in = const_cast<MSEdge*>(in_const);
     639            0 :                         if ((in->getPermissions() & svc) == svc &&
     640            0 :                                 (reachableEdges.count(in) == 0 ||
     641              :                                  // revisit edge via faster path
     642            0 :                                  reachableEdges[in] > traveltime)) {
     643            0 :                             reachableEdges[in] = traveltime;
     644            0 :                             check.push_back(in);
     645              :                         }
     646              :                     }
     647              :                 }
     648              :             }
     649              :         }
     650            0 :         gSelected.notifyChanged();
     651            0 :     }
     652            0 :     return 1;
     653              : }
     654              : 
     655              : 
     656              : long
     657            0 : GUIViewTraffic::onCmdShowReachability(FXObject* menu, FXSelector selector, void*) {
     658            0 :     GUILane* lane = getLaneUnderCursor();
     659            0 :     if (lane != nullptr) {
     660              :         // reset
     661            0 :         showLaneReachability(lane, menu, selector);
     662              :         // switch to 'color by selection' unless coloring 'by reachability'
     663            0 :         if (myVisualizationSettings->laneColorer.getActive() != 36) {
     664              :             myVisualizationSettings->laneColorer.setActive(1);
     665              :         }
     666            0 :         update();
     667              :     }
     668            0 :     return 1;
     669              : }
     670              : 
     671              : 
     672              : GUILane*
     673            0 : GUIViewTraffic::getLaneUnderCursor() {
     674            0 :     if (makeCurrent()) {
     675            0 :         int id = getObjectUnderCursor();
     676            0 :         if (id != 0) {
     677            0 :             GUIGlObject* o = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id);
     678            0 :             if (o != nullptr) {
     679            0 :                 return dynamic_cast<GUILane*>(o);
     680              :             }
     681              :         }
     682            0 :         makeNonCurrent();
     683              :     }
     684              :     return nullptr;
     685              : }
     686              : 
     687              : 
     688              : long
     689            0 : GUIViewTraffic::onDoubleClicked(FXObject*, FXSelector, void*) {
     690              :     // leave fullscreen mode
     691            0 :     if (myApp->isFullScreen()) {
     692            0 :         myApp->onCmdFullScreen(nullptr, 0, nullptr);
     693              :     } else {
     694            0 :         stopTrack();
     695              :     }
     696            0 :     return 1;
     697              : }
     698              : 
     699              : 
     700              : 
     701              : void
     702            0 : GUIViewTraffic::saveFrame(const std::string& destFile, FXColor* buf) {
     703              : #ifdef HAVE_FFMPEG
     704            0 :     if (myCurrentVideo == nullptr) {
     705            0 :         myCurrentVideo = new GUIVideoEncoder(destFile.c_str(), getWidth(), getHeight(), myApp->getDelay());
     706              :     }
     707            0 :     myCurrentVideo->writeFrame((uint8_t*)buf);
     708              : #else
     709              :     UNUSED_PARAMETER(destFile);
     710              :     UNUSED_PARAMETER(buf);
     711              : #endif
     712            0 : }
     713              : 
     714              : 
     715              : void
     716         6722 : GUIViewTraffic::endSnapshot() {
     717              : #ifdef HAVE_FFMPEG
     718         6722 :     if (myCurrentVideo != nullptr) {
     719            0 :         delete myCurrentVideo;
     720            0 :         myCurrentVideo = nullptr;
     721              :     }
     722              : #endif
     723         6722 : }
     724              : 
     725              : 
     726              : void
     727      5547283 : GUIViewTraffic::checkSnapshots() {
     728              : #ifdef HAVE_FFMPEG
     729      5547283 :     if (myCurrentVideo != nullptr) {
     730            0 :         addSnapshot(getCurrentTimeStep() - DELTA_T, "");
     731              :     }
     732              : #endif
     733      5547283 :     GUISUMOAbstractView::checkSnapshots();
     734      5547283 : }
     735              : 
     736              : 
     737              : const std::vector<SUMOTime>
     738            0 : GUIViewTraffic::retrieveBreakpoints() const {
     739            0 :     return myApp->retrieveBreakpoints();
     740              : }
     741              : 
     742              : 
     743              : void
     744            0 : GUIViewTraffic::drawPedestrianNetwork(const GUIVisualizationSettings& s) const {
     745            0 :     GUIShapeContainer& shapeContainer = dynamic_cast<GUIShapeContainer&>(GUINet::getInstance()->getShapeContainer());
     746            0 :     if (s.showPedestrianNetwork) {
     747            0 :         shapeContainer.removeInactivePolygonTypes(std::set<std::string> {"jupedsim.pedestrian_network"});
     748              :     } else {
     749            0 :         shapeContainer.addInactivePolygonTypes(std::set<std::string> {"jupedsim.pedestrian_network"});
     750              :     }
     751            0 :     update();
     752            0 : }
     753              : 
     754              : 
     755              : void
     756            0 : GUIViewTraffic::changePedestrianNetworkColor(const GUIVisualizationSettings& s) const {
     757            0 :     GUIShapeContainer& shapeContainer = dynamic_cast<GUIShapeContainer&>(GUINet::getInstance()->getShapeContainer());
     758            0 :     for (auto polygonwithID : shapeContainer.getPolygons()) {
     759            0 :         if (polygonwithID.second->getShapeType() == "jupedsim.pedestrian_network") {
     760              :             polygonwithID.second->setShapeColor(s.pedestrianNetworkColor);
     761              :         }
     762              :     }
     763            0 :     update();
     764            0 : }
     765              : 
     766              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1