LCOV - code coverage report
Current view: top level - src/gui - GUIViewTraffic.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 111 377 29.4 %
Date: 2024-05-18 15:37:58 Functions: 12 32 37.5 %

          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        6452 : GUIViewTraffic::GUIViewTraffic(
      75             :     FXComposite* p,
      76             :     GUIMainWindow& app,
      77             :     GUISUMOViewParent* parent,
      78             :     GUINet& net, FXGLVisual* glVis,
      79        6452 :     FXGLCanvas* share) :
      80             :     GUISUMOAbstractView(p, app, parent, net.getVisualisationSpeedUp(), glVis, share),
      81        6452 :     myTrackedID(GUIGlObject::INVALID_ID),
      82       12904 :     myTLSGame(OptionsCont::getOptions().getString("game.mode") == "tls")
      83             : #ifdef HAVE_FFMPEG
      84        6452 :     , myCurrentVideo(nullptr)
      85             : #endif
      86        6452 : {}
      87             : 
      88             : 
      89       12868 : GUIViewTraffic::~GUIViewTraffic() {
      90        6434 :     endSnapshot();
      91       12868 : }
      92             : 
      93             : 
      94             : void
      95        6452 : GUIViewTraffic::buildViewToolBars(GUIGlChildWindow* v) {
      96             :     // build coloring tools
      97             :     {
      98        6452 :         const std::vector<std::string>& names = gSchemeStorage.getNames();
      99       38744 :         for (std::vector<std::string>::const_iterator i = names.begin(); i != names.end(); ++i) {
     100       32292 :             v->getColoringSchemesCombo()->appendIconItem(i->c_str());
     101       32292 :             if ((*i) == myVisualizationSettings->name) {
     102        6452 :                 v->getColoringSchemesCombo()->setCurrentItem(v->getColoringSchemesCombo()->getNumItems() - 1);
     103             :             }
     104             :         }
     105             :     }
     106             :     // for junctions
     107       19356 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     108       12904 :                          (std::string("\t") + TL("Locate Junctions") + std::string("\t") + TL("Locate a junction within the network.")).c_str(),
     109        6452 :                          GUIIconSubSys::getIcon(GUIIcon::LOCATEJUNCTION), v, MID_HOTKEY_SHIFT_J_LOCATEJUNCTION,
     110        6452 :                          GUIDesignButtonPopup);
     111             :     // for edges
     112       19356 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     113       12904 :                          (std::string("\t") + TL("Locate Edges") + std::string("\t") + TL("Locate an edge within the network.")).c_str(),
     114        6452 :                          GUIIconSubSys::getIcon(GUIIcon::LOCATEEDGE), v, MID_HOTKEY_SHIFT_E_LOCATEEDGE,
     115        6452 :                          GUIDesignButtonPopup);
     116             :     // for vehicles
     117       19356 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     118       12904 :                          (std::string("\t") + TL("Locate Vehicles") + std::string("\t") + TL("Locate a vehicle within the network.")).c_str(),
     119        6452 :                          GUIIconSubSys::getIcon(GUIIcon::LOCATEVEHICLE), v, MID_HOTKEY_SHIFT_V_LOCATEVEHICLE,
     120        6452 :                          GUIDesignButtonPopup);
     121             :     // for persons
     122       19356 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     123       12904 :                          (std::string("\t") + TL("Locate Persons") + std::string("\t") + TL("Locate a person within the network.")).c_str(),
     124        6452 :                          GUIIconSubSys::getIcon(GUIIcon::LOCATEPERSON), v, MID_HOTKEY_SHIFT_P_LOCATEPERSON,
     125        6452 :                          GUIDesignButtonPopup);
     126             :     // for containers
     127       19356 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     128       12904 :                          (std::string("\t") + TL("Locate Container") + std::string("\t") + TL("Locate a container within the network.")).c_str(),
     129        6452 :                          GUIIconSubSys::getIcon(GUIIcon::LOCATECONTAINER), v, MID_HOTKEY_SHIFT_C_LOCATECONTAINER,
     130        6452 :                          GUIDesignButtonPopup);
     131             :     // for tls
     132       19356 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     133       12904 :                          (std::string("\t") + TL("Locate TLS") + std::string("\t") + TL("Locate a tls within the network.")).c_str(),
     134        6452 :                          GUIIconSubSys::getIcon(GUIIcon::LOCATETLS), v, MID_HOTKEY_SHIFT_T_LOCATETLS,
     135        6452 :                          GUIDesignButtonPopup);
     136             :     // for additional stuff
     137       19356 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     138       12904 :                          (std::string("\t") + TL("Locate Additional") + std::string("\t") + TL("Locate an additional structure within the network.")).c_str(),
     139        6452 :                          GUIIconSubSys::getIcon(GUIIcon::LOCATEADD), v, MID_HOTKEY_SHIFT_A_LOCATEADDITIONAL,
     140        6452 :                          GUIDesignButtonPopup);
     141             :     // for pois
     142       19356 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     143       12904 :                          (std::string("\t") + TL("Locate PoI") + std::string("\t") + TL("Locate a PoI within the network.")).c_str(),
     144        6452 :                          GUIIconSubSys::getIcon(GUIIcon::LOCATEPOI), v, MID_HOTKEY_SHIFT_O_LOCATEPOI,
     145        6452 :                          GUIDesignButtonPopup);
     146             :     // for polygons
     147       19356 :     new MFXButtonTooltip(v->getLocatorPopup(), myApp->getStaticTooltipMenu(),
     148       12904 :                          (std::string("\t") + TL("Locate Polygon") + std::string("\t") + TL("Locate a Polygon within the network.")).c_str(),
     149        6452 :                          GUIIconSubSys::getIcon(GUIIcon::LOCATEPOLY), v, MID_HOTKEY_SHIFT_L_LOCATEPOLY,
     150        6452 :                          GUIDesignButtonPopup);
     151        6452 : }
     152             : 
     153             : 
     154             : bool
     155          49 : GUIViewTraffic::setColorScheme(const std::string& name) {
     156          49 :     if (!gSchemeStorage.contains(name)) {
     157             :         return false;
     158             :     }
     159          43 :     if (myGUIDialogViewSettings != nullptr) {
     160           0 :         if (myGUIDialogViewSettings->getCurrentScheme() != name) {
     161           0 :             myGUIDialogViewSettings->setCurrentScheme(name);
     162             :         }
     163             :     }
     164          43 :     myVisualizationSettings = &gSchemeStorage.get(name.c_str());
     165          43 :     myVisualizationSettings->gaming = myApp->isGaming();
     166          43 :     update();
     167          43 :     return true;
     168             : }
     169             : 
     170             : 
     171             : void
     172           0 : GUIViewTraffic::buildColorRainbow(const GUIVisualizationSettings& s, GUIColorScheme& scheme, int active, GUIGlObjectType objectType,
     173             :                                   bool hide, double hideThreshold, bool hide2, double hideThreshold2) {
     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             : 
     240           0 :     if (hide && hide2 && minValue == std::numeric_limits<double>::infinity()) {
     241             :         minValue = hideThreshold;
     242             :         maxValue = hideThreshold2;
     243             :     }
     244           0 :     if (minValue != std::numeric_limits<double>::infinity()) {
     245           0 :         scheme.clear();
     246             :         // add new thresholds
     247           0 :         if (scheme.getName() == GUIVisualizationSettings::SCHEME_NAME_EDGEDATA_NUMERICAL
     248           0 :                 || scheme.getName() == GUIVisualizationSettings::SCHEME_NAME_EDGE_PARAM_NUMERICAL
     249           0 :                 || scheme.getName() == GUIVisualizationSettings::SCHEME_NAME_LANE_PARAM_NUMERICAL
     250           0 :                 || scheme.getName() == GUIVisualizationSettings::SCHEME_NAME_DATA_ATTRIBUTE_NUMERICAL
     251           0 :                 || scheme.getName() == GUIVisualizationSettings::SCHEME_NAME_PARAM_NUMERICAL
     252           0 :                 || hasMissingData)  {
     253           0 :             scheme.addColor(s.COL_MISSING_DATA, s.MISSING_DATA, "missing data");
     254             :         }
     255           0 :         if (hide) {
     256           0 :             const double rawRange = maxValue - minValue;
     257           0 :             minValue = MAX2(hideThreshold + MIN2(1.0, rawRange / 100.0), minValue);
     258           0 :             scheme.addColor(RGBColor(204, 204, 204), hideThreshold);
     259             :         }
     260           0 :         if (hide2) {
     261           0 :             const double rawRange = maxValue - minValue;
     262           0 :             maxValue = MIN2(hideThreshold2 - MIN2(1.0, rawRange / 100.0), maxValue);
     263           0 :             scheme.addColor(RGBColor(204, 204, 204), hideThreshold2);
     264             :         }
     265           0 :         double range = maxValue - minValue;
     266           0 :         scheme.addColor(RGBColor::RED, (minValue));
     267           0 :         scheme.addColor(RGBColor::ORANGE, (minValue + range * 1 / 6.0));
     268           0 :         scheme.addColor(RGBColor::YELLOW, (minValue + range * 2 / 6.0));
     269           0 :         scheme.addColor(RGBColor::GREEN, (minValue + range * 3 / 6.0));
     270           0 :         scheme.addColor(RGBColor::CYAN, (minValue + range * 4 / 6.0));
     271           0 :         scheme.addColor(RGBColor::BLUE, (minValue + range * 5 / 6.0));
     272           0 :         scheme.addColor(RGBColor::MAGENTA, (maxValue));
     273             :     }
     274             : }
     275             : 
     276             : 
     277             : std::vector<std::string>
     278           0 : GUIViewTraffic::getEdgeDataAttrs() const {
     279           0 :     if (GUINet::getGUIInstance() != nullptr) {
     280           0 :         return GUINet::getGUIInstance()->getEdgeDataAttrs();
     281             :     }
     282           0 :     return std::vector<std::string>();
     283             : }
     284             : 
     285             : 
     286             : std::vector<std::string>
     287           0 : GUIViewTraffic::getMeanDataIDs() const {
     288           0 :     if (GUINet::getGUIInstance() != nullptr) {
     289           0 :         return GUINet::getGUIInstance()->getMeanDataIDs();
     290             :     }
     291           0 :     return std::vector<std::string>();
     292             : }
     293             : 
     294             : std::vector<std::string>
     295           0 : GUIViewTraffic::getMeanDataAttrs(const std::string& meanDataID) const {
     296           0 :     if (GUINet::getGUIInstance() != nullptr) {
     297           0 :         return GUINet::getGUIInstance()->getMeanDataAttrs(meanDataID);
     298             :     }
     299           0 :     return std::vector<std::string>();
     300             : }
     301             : 
     302             : 
     303             : std::vector<std::string>
     304           0 : GUIViewTraffic::getEdgeLaneParamKeys(bool edgeKeys) const {
     305             :     std::set<std::string> keys;
     306           0 :     for (const MSEdge* e : MSEdge::getAllEdges()) {
     307           0 :         if (edgeKeys) {
     308           0 :             for (const auto& item : e->getParametersMap()) {
     309           0 :                 keys.insert(item.first);
     310             :             }
     311             :         } else {
     312           0 :             for (const auto lane : e->getLanes()) {
     313           0 :                 for (const auto& item : lane->getParametersMap()) {
     314           0 :                     keys.insert(item.first);
     315             :                 }
     316             :             }
     317             :         }
     318             :     }
     319           0 :     return std::vector<std::string>(keys.begin(), keys.end());
     320             : }
     321             : 
     322             : 
     323             : std::vector<std::string>
     324           0 : GUIViewTraffic::getVehicleParamKeys(bool /*vTypeKeys*/) const {
     325             :     std::set<std::string> keys;
     326           0 :     GUIVehicleControl* vc = GUINet::getGUIInstance()->getGUIVehicleControl();
     327           0 :     vc->secureVehicles();
     328           0 :     for (auto vehIt = vc->loadedVehBegin(); vehIt != vc->loadedVehEnd(); ++vehIt) {
     329           0 :         for (auto kv : vehIt->second->getParameter().getParametersMap()) {
     330             :             keys.insert(kv.first);
     331           0 :         }
     332             :     }
     333           0 :     vc->releaseVehicles();
     334           0 :     return std::vector<std::string>(keys.begin(), keys.end());
     335             : }
     336             : 
     337             : std::vector<std::string>
     338           0 : GUIViewTraffic::getPOIParamKeys() const {
     339             :     std::set<std::string> keys;
     340           0 :     const ShapeContainer::POIs& pois = static_cast<ShapeContainer&>(GUINet::getInstance()->getShapeContainer()).getPOIs();
     341           0 :     for (auto item : pois) {
     342           0 :         for (auto kv : item.second->getParametersMap()) {
     343             :             keys.insert(kv.first);
     344           0 :         }
     345             :     }
     346           0 :     return std::vector<std::string>(keys.begin(), keys.end());
     347             : }
     348             : 
     349             : int
     350      473247 : GUIViewTraffic::doPaintGL(int mode, const Boundary& bound) {
     351             :     // init view settings
     352      473247 :     glRenderMode(mode);
     353      473247 :     glMatrixMode(GL_MODELVIEW);
     354      473247 :     GLHelper::pushMatrix();
     355      473247 :     glDisable(GL_TEXTURE_2D);
     356      473247 :     glDisable(GL_ALPHA_TEST);
     357      473247 :     glEnable(GL_BLEND);
     358      473247 :     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     359      473247 :     glEnable(GL_DEPTH_TEST);
     360             : 
     361             :     // draw decals (if not in grabbing mode)
     362      473247 :     drawDecals();
     363      473247 :     myVisualizationSettings->scale = m2p(SUMO_const_laneWidth);
     364      473247 :     if (myVisualizationSettings->showGrid) {
     365           0 :         paintGLGrid();
     366             :     }
     367      473247 :     glLineWidth(1);
     368      473247 :     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     369      473247 :     const float minB[2] = { (float)bound.xmin(), (float)bound.ymin() };
     370      473247 :     const float maxB[2] = { (float)bound.xmax(), (float)bound.ymax() };
     371      473247 :     glEnable(GL_POLYGON_OFFSET_FILL);
     372      473247 :     glEnable(GL_POLYGON_OFFSET_LINE);
     373      473247 :     const SUMORTree& grid = GUINet::getGUIInstance()->getVisualisationSpeedUp(myVisualizationSettings->secondaryShape);
     374      473247 :     int hits2 = grid.Search(minB, maxB, *myVisualizationSettings);
     375      473247 :     GUIGlobals::gSecondaryShape = myVisualizationSettings->secondaryShape;
     376             :     // Draw additional objects
     377      473247 :     if (myAdditionallyDrawn.size() > 0) {
     378           2 :         glTranslated(0, 0, -.01);
     379           2 :         GUINet::getGUIInstance()->lock();
     380           4 :         for (auto i : myAdditionallyDrawn) {
     381           2 :             i.first->drawGLAdditional(this, *myVisualizationSettings);
     382             :         }
     383           2 :         GUINet::getGUIInstance()->unlock();
     384           2 :         glTranslated(0, 0, .01);
     385             :     }
     386      473247 :     GLHelper::popMatrix();
     387             :     /*
     388             :     // draw legends
     389             :     glMatrixMode(GL_MODELVIEW);
     390             :     glLoadIdentity();
     391             :     glTranslated(1.-.2, 1.-.5, 0.);
     392             :     glScaled(.2, .5, 1.);
     393             :     GUIColoringSchemesMap<GUILane> &sm = GUIViewTraffic::getLaneSchemesMap(); //!!!
     394             :     sm.getColorer(myVisualizationSettings->laneEdgeMode)->drawLegend();
     395             :     */
     396      473247 :     return hits2;
     397             : }
     398             : 
     399             : 
     400             : void
     401           4 : GUIViewTraffic::startTrack(int id) {
     402           4 :     myTrackedID = id;
     403           4 :     GUIGlObject* o = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id);
     404           4 :     if (o != nullptr) {
     405           4 :         GUIBaseVehicle* v = dynamic_cast<GUIBaseVehicle*>(o);
     406           4 :         if (v != nullptr) {
     407           4 :             v->addActiveAddVisualisation(this, GUIBaseVehicle::VO_TRACK);
     408             :         }
     409             :     }
     410           4 : }
     411             : 
     412             : 
     413             : void
     414           4 : GUIViewTraffic::stopTrack() {
     415           4 :     myTrackedID = GUIGlObject::INVALID_ID;
     416           4 : }
     417             : 
     418             : 
     419             : GUIGlID
     420     1051079 : GUIViewTraffic::getTrackedID() const {
     421     1051079 :     return myTrackedID;
     422             : }
     423             : 
     424             : 
     425             : void
     426           0 : GUIViewTraffic::onGamingClick(Position pos) {
     427           0 :     if (myTLSGame) {
     428           0 :         MSTLLogicControl& tlsControl = MSNet::getInstance()->getTLSControl();
     429             :         MSTrafficLightLogic* minTll = nullptr;
     430             :         double minDist = std::numeric_limits<double>::infinity();
     431           0 :         for (MSTrafficLightLogic* const tll : tlsControl.getAllLogics()) {
     432           0 :             if (tlsControl.isActive(tll) && tll->getProgramID() != "off") {
     433             :                 // get the links
     434             :                 const MSTrafficLightLogic::LaneVector& lanes = tll->getLanesAt(0);
     435           0 :                 if (lanes.size() > 0) {
     436           0 :                     const Position& endPos = lanes[0]->getShape().back();
     437           0 :                     if (endPos.distanceTo(pos) < minDist) {
     438           0 :                         minDist = endPos.distanceTo(pos);
     439             :                         minTll = tll;
     440             :                     }
     441             :                 }
     442             :             }
     443             :         }
     444           0 :         if (minTll != nullptr) {
     445           0 :             if (minTll->getPhaseNumber() == 0) {
     446             :                 // MSRailSignal
     447             :                 return;
     448             :             }
     449           0 :             const int ci = minTll->getCurrentPhaseIndex();
     450           0 :             const int n = minTll->getPhaseNumber();
     451             :             int greenCount = 0;
     452           0 :             for (auto& phase : minTll->getPhases()) {
     453           0 :                 if (phase->isGreenPhase()) {
     454           0 :                     greenCount++;
     455             :                 }
     456             :             }
     457           0 :             int nextPhase = (ci + 1) % n;
     458             :             SUMOTime nextDuration = 0;
     459           0 :             if (minTll->getCurrentPhaseDef().isGreenPhase() || (greenCount == 1 && minTll->getCurrentPhaseDef().isAllRedPhase())) {
     460           0 :                 nextDuration = minTll->getPhase(nextPhase).duration;
     461             :             } else {
     462             :                 // we are in transition to a green phase
     463             :                 // -> skip forward to the transition into the next green phase
     464             :                 // but ensure that the total transition time is maintained
     465             :                 // taking into account how much time was already spent
     466           0 :                 SUMOTime spentTransition = minTll->getSpentDuration();
     467             :                 // the transition may consist of more than one phase so we
     468             :                 // search backwards until the prior green phase
     469           0 :                 for (int i = ci - 1; i != ci; i--) {
     470           0 :                     if (i < 0) {
     471           0 :                         i = n - 1;
     472             :                     }
     473           0 :                     if (minTll->getPhase(i).isGreenPhase()) {
     474             :                         break;
     475             :                     }
     476           0 :                     spentTransition += minTll->getPhase(i).duration;
     477             :                 }
     478             :                 // now we skip past the next greenphase
     479             :                 int numGreen = 0;
     480             :                 int i = nextPhase;
     481           0 :                 for (; numGreen < 2; i = (i + 1) % n) {
     482           0 :                     if (minTll->getPhase(i).isGreenPhase()) {
     483           0 :                         numGreen++;
     484           0 :                         continue;
     485             :                     }
     486             :                     // transition after the next green
     487           0 :                     if (numGreen == 1) {
     488           0 :                         SUMOTime dur = minTll->getPhase(i).duration;
     489           0 :                         if (dur <= spentTransition) {
     490           0 :                             spentTransition -= dur;
     491             :                         } else {
     492             :                             nextPhase = i;
     493           0 :                             nextDuration = dur - spentTransition;
     494           0 :                             break;
     495             :                         }
     496             :                     }
     497             :                 }
     498             :             }
     499           0 :             minTll->changeStepAndDuration(tlsControl, MSNet::getInstance()->getCurrentTimeStep(), nextPhase, nextDuration);
     500           0 :             update();
     501             :         }
     502             :     } else {
     503             :         // DRT game
     504           0 :         if (MSGlobals::gUseMesoSim) {
     505             :             return;
     506             :         }
     507           0 :         const std::set<GUIGlID>& sel = gSelected.getSelected(GLO_VEHICLE);
     508           0 :         if (sel.size() == 0) {
     509             :             // find closest pt vehicle
     510             :             double minDist = std::numeric_limits<double>::infinity();
     511             :             GUIVehicle* closest = nullptr;
     512           0 :             MSVehicleControl& vc = MSNet::getInstance()->getVehicleControl();
     513             :             MSVehicleControl::constVehIt it = vc.loadedVehBegin();
     514             :             MSVehicleControl::constVehIt end = vc.loadedVehEnd();
     515           0 :             for (it = vc.loadedVehBegin(); it != end; ++it) {
     516           0 :                 GUIVehicle* veh = dynamic_cast<GUIVehicle*>(it->second);
     517             :                 assert(veh != 0);
     518           0 :                 if (veh->getParameter().line != "") {
     519           0 :                     const double dist = veh->getPosition().distanceTo2D(pos);
     520           0 :                     if (dist < minDist) {
     521             :                         minDist = dist;
     522             :                         closest = veh;
     523             :                     }
     524             :                 }
     525             :             }
     526           0 :             if (closest != nullptr) {
     527           0 :                 gSelected.select(closest->getGlID());
     528           0 :                 closest->addActiveAddVisualisation(this, GUIBaseVehicle::VO_SHOW_FUTURE_ROUTE);
     529             :             }
     530             :         } else {
     531             :             // find closest pt stop
     532             :             double minDist = std::numeric_limits<double>::infinity();
     533             :             MSStoppingPlace* closestStop = nullptr;
     534           0 :             const NamedObjectCont<MSStoppingPlace*>& stops = MSNet::getInstance()->getStoppingPlaces(SUMO_TAG_BUS_STOP);
     535           0 :             for (auto it = stops.begin(); it != stops.end(); ++it) {
     536           0 :                 MSStoppingPlace* stop = it->second;
     537           0 :                 const double dist = pos.distanceTo2D(stop->getLane().geometryPositionAtOffset(stop->getEndLanePosition()));
     538           0 :                 if (dist < minDist) {
     539             :                     minDist = dist;
     540             :                     closestStop = stop;
     541             :                 }
     542             :             }
     543           0 :             if (closestStop != 0) {
     544           0 :                 GUIGlID id = *sel.begin();
     545           0 :                 GUIVehicle* veh = dynamic_cast<GUIVehicle*>(GUIGlObjectStorage::gIDStorage.getObjectBlocking(id));
     546             :                 assert(veh != 0);
     547             :                 MSLane* lane = veh->getMutableLane();
     548           0 :                 lane->getVehiclesSecure();
     549           0 :                 veh->rerouteDRTStop(closestStop);
     550           0 :                 GUIGlObjectStorage::gIDStorage.unblockObject(id);
     551           0 :                 lane->releaseVehicles();
     552             :             }
     553             :         }
     554             :     }
     555             : }
     556             : 
     557             : 
     558             : void
     559           0 : GUIViewTraffic::onGamingRightClick(Position /*pos*/) {
     560           0 :     const std::set<GUIGlID>& sel = gSelected.getSelected(GLO_VEHICLE);
     561           0 :     if (sel.size() > 0) {
     562           0 :         GUIGlID id = *sel.begin();
     563           0 :         GUIVehicle* veh = dynamic_cast<GUIVehicle*>(GUIGlObjectStorage::gIDStorage.getObjectBlocking(id));
     564           0 :         if (veh != 0) {
     565           0 :             veh->removeActiveAddVisualisation(this, GUIBaseVehicle::VO_SHOW_FUTURE_ROUTE);
     566             :         }
     567           0 :         GUIGlObjectStorage::gIDStorage.unblockObject(id);
     568             :     }
     569           0 :     gSelected.clear();
     570           0 : }
     571             : 
     572             : 
     573             : SUMOTime
     574     5026470 : GUIViewTraffic::getCurrentTimeStep() const {
     575     5026470 :     return MSNet::getInstance()->getCurrentTimeStep();
     576             : }
     577             : 
     578             : 
     579             : long
     580           0 : GUIViewTraffic::onCmdCloseLane(FXObject*, FXSelector, void*) {
     581           0 :     GUILane* lane = getLaneUnderCursor();
     582           0 :     if (lane != nullptr) {
     583           0 :         lane->closeTraffic();
     584           0 :         GUIGlObjectStorage::gIDStorage.unblockObject(lane->getGlID());
     585           0 :         update();
     586             :     }
     587           0 :     return 1;
     588             : }
     589             : 
     590             : 
     591             : long
     592           0 : GUIViewTraffic::onCmdCloseEdge(FXObject*, FXSelector, void*) {
     593           0 :     GUILane* lane = getLaneUnderCursor();
     594           0 :     if (lane != nullptr) {
     595           0 :         dynamic_cast<GUIEdge*>(&lane->getEdge())->closeTraffic(lane);
     596           0 :         GUIGlObjectStorage::gIDStorage.unblockObject(lane->getGlID());
     597           0 :         update();
     598             :     }
     599           0 :     return 1;
     600             : }
     601             : 
     602             : 
     603             : long
     604           0 : GUIViewTraffic::onCmdAddRerouter(FXObject*, FXSelector, void*) {
     605           0 :     GUILane* lane = getLaneUnderCursor();
     606           0 :     if (lane != nullptr) {
     607           0 :         dynamic_cast<GUIEdge*>(&lane->getEdge())->addRerouter();
     608           0 :         GUIGlObjectStorage::gIDStorage.unblockObject(lane->getGlID());
     609           0 :         update();
     610             :     }
     611           0 :     return 1;
     612             : }
     613             : 
     614             : 
     615             : long
     616           0 : GUIViewTraffic::showLaneReachability(GUILane* lane, FXObject* menu, FXSelector) {
     617           0 :     if (lane != nullptr) {
     618             :         // reset
     619             :         const double UNREACHED = INVALID_DOUBLE;
     620           0 :         gSelected.clear();
     621           0 :         for (const MSEdge* const e : MSEdge::getAllEdges()) {
     622           0 :             for (MSLane* const l : e->getLanes()) {
     623           0 :                 GUILane* gLane = dynamic_cast<GUILane*>(l);
     624             :                 gLane->setReachability(UNREACHED);
     625             :             }
     626             :         }
     627             :         // prepare
     628           0 :         FXMenuCommand* mc = dynamic_cast<FXMenuCommand*>(menu);
     629           0 :         const SUMOVehicleClass svc = SumoVehicleClassStrings.get(mc->getText().text());
     630           0 :         const double defaultMaxSpeed = SUMOVTypeParameter::VClassDefaultValues(svc).maxSpeed;
     631             :         // find reachable
     632             :         std::map<MSEdge*, double> reachableEdges;
     633           0 :         reachableEdges[&lane->getEdge()] = 0;
     634             :         MSEdgeVector check;
     635           0 :         check.push_back(&lane->getEdge());
     636           0 :         while (check.size() > 0) {
     637           0 :             MSEdge* e = check.front();
     638             :             check.erase(check.begin());
     639           0 :             double traveltime = reachableEdges[e];
     640           0 :             for (MSLane* const l : e->getLanes()) {
     641           0 :                 if (l->allowsVehicleClass(svc)) {
     642           0 :                     GUILane* gLane = dynamic_cast<GUILane*>(l);
     643           0 :                     gSelected.select(gLane->getGlID(), false);
     644             :                     gLane->setReachability(traveltime);
     645             :                 }
     646             :             }
     647           0 :             const double dt = e->getLength() / MIN2(e->getSpeedLimit(), defaultMaxSpeed);
     648             :             // ensure algorithm termination
     649           0 :             traveltime += MAX2(dt, NUMERICAL_EPS);
     650           0 :             for (MSEdge* const nextEdge : e->getSuccessors(svc)) {
     651           0 :                 if (reachableEdges.count(nextEdge) == 0 ||
     652             :                         // revisit edge via faster path
     653           0 :                         reachableEdges[nextEdge] > traveltime) {
     654           0 :                     reachableEdges[nextEdge] = traveltime;
     655           0 :                     check.push_back(nextEdge);
     656             :                 }
     657             :             }
     658           0 :             if (svc == SVC_PEDESTRIAN) {
     659             :                 // can also walk backwards
     660           0 :                 for (MSEdge* const prevEdge : e->getPredecessors()) {
     661           0 :                     if (prevEdge->allowedLanes(*e, svc) != nullptr &&
     662           0 :                             (reachableEdges.count(prevEdge) == 0 ||
     663             :                              // revisit edge via faster path
     664           0 :                              reachableEdges[prevEdge] > traveltime)) {
     665           0 :                         reachableEdges[prevEdge] = traveltime;
     666           0 :                         check.push_back(prevEdge);
     667             :                     }
     668             :                 }
     669             :             }
     670             :         }
     671           0 :         gSelected.notifyChanged();
     672             :     }
     673           0 :     return 1;
     674             : }
     675             : 
     676             : 
     677             : long
     678           0 : GUIViewTraffic::onCmdShowReachability(FXObject* menu, FXSelector selector, void*) {
     679           0 :     GUILane* lane = getLaneUnderCursor();
     680           0 :     if (lane != nullptr) {
     681             :         // reset
     682           0 :         showLaneReachability(lane, menu, selector);
     683             :         // switch to 'color by selection' unless coloring 'by reachability'
     684           0 :         if (myVisualizationSettings->laneColorer.getActive() != 36) {
     685             :             myVisualizationSettings->laneColorer.setActive(1);
     686             :         }
     687           0 :         update();
     688             :     }
     689           0 :     return 1;
     690             : }
     691             : 
     692             : 
     693             : GUILane*
     694           0 : GUIViewTraffic::getLaneUnderCursor() {
     695           0 :     if (makeCurrent()) {
     696           0 :         int id = getObjectUnderCursor();
     697           0 :         if (id != 0) {
     698           0 :             GUIGlObject* o = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id);
     699           0 :             if (o != nullptr) {
     700           0 :                 return dynamic_cast<GUILane*>(o);
     701             :             }
     702             :         }
     703           0 :         makeNonCurrent();
     704             :     }
     705             :     return nullptr;
     706             : }
     707             : 
     708             : 
     709             : long
     710           0 : GUIViewTraffic::onDoubleClicked(FXObject*, FXSelector, void*) {
     711             :     // leave fullscreen mode
     712           0 :     if (myApp->isFullScreen()) {
     713           0 :         myApp->onCmdFullScreen(nullptr, 0, nullptr);
     714             :     } else {
     715           0 :         stopTrack();
     716             :     }
     717           0 :     return 1;
     718             : }
     719             : 
     720             : 
     721             : 
     722             : void
     723           0 : GUIViewTraffic::saveFrame(const std::string& destFile, FXColor* buf) {
     724             : #ifdef HAVE_FFMPEG
     725           0 :     if (myCurrentVideo == nullptr) {
     726           0 :         myCurrentVideo = new GUIVideoEncoder(destFile.c_str(), getWidth(), getHeight(), myApp->getDelay());
     727             :     }
     728           0 :     myCurrentVideo->writeFrame((uint8_t*)buf);
     729             : #else
     730             :     UNUSED_PARAMETER(destFile);
     731             :     UNUSED_PARAMETER(buf);
     732             : #endif
     733           0 : }
     734             : 
     735             : 
     736             : void
     737        6434 : GUIViewTraffic::endSnapshot() {
     738             : #ifdef HAVE_FFMPEG
     739        6434 :     if (myCurrentVideo != nullptr) {
     740           0 :         delete myCurrentVideo;
     741           0 :         myCurrentVideo = nullptr;
     742             :     }
     743             : #endif
     744        6434 : }
     745             : 
     746             : 
     747             : void
     748     5026470 : GUIViewTraffic::checkSnapshots() {
     749             : #ifdef HAVE_FFMPEG
     750     5026470 :     if (myCurrentVideo != nullptr) {
     751           0 :         addSnapshot(getCurrentTimeStep() - DELTA_T, "");
     752             :     }
     753             : #endif
     754     5026470 :     GUISUMOAbstractView::checkSnapshots();
     755     5026470 : }
     756             : 
     757             : 
     758             : const std::vector<SUMOTime>
     759           0 : GUIViewTraffic::retrieveBreakpoints() const {
     760           0 :     return myApp->retrieveBreakpoints();
     761             : }
     762             : 
     763             : 
     764             : void
     765           0 : GUIViewTraffic::drawPedestrianNetwork(const GUIVisualizationSettings& s) const {
     766           0 :     GUIShapeContainer& shapeContainer = dynamic_cast<GUIShapeContainer&>(GUINet::getInstance()->getShapeContainer());
     767           0 :     if (s.showPedestrianNetwork) {
     768           0 :         shapeContainer.removeInactivePolygonTypes(std::set<std::string> {"jupedsim.pedestrian_network"});
     769             :     } else {
     770           0 :         shapeContainer.addInactivePolygonTypes(std::set<std::string> {"jupedsim.pedestrian_network"});
     771             :     }
     772           0 :     update();
     773           0 : }
     774             : 
     775             : 
     776             : void
     777           0 : GUIViewTraffic::changePedestrianNetworkColor(const GUIVisualizationSettings& s) const {
     778           0 :     GUIShapeContainer& shapeContainer = dynamic_cast<GUIShapeContainer&>(GUINet::getInstance()->getShapeContainer());
     779           0 :     for (auto polygonwithID : shapeContainer.getPolygons()) {
     780           0 :         if (polygonwithID.second->getShapeType() == "jupedsim.pedestrian_network") {
     781           0 :             polygonwithID.second->setShapeColor(s.pedestrianNetworkColor);
     782             :         }
     783             :     }
     784           0 :     update();
     785           0 : }
     786             : 
     787             : /****************************************************************************/

Generated by: LCOV version 1.14