LCOV - code coverage report
Current view: top level - src/guisim - GUITriggeredRerouter.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 144 270 53.3 %
Date: 2024-04-27 15:34:54 Functions: 10 36 27.8 %

          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    GUITriggeredRerouter.cpp
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Jakob Erdmann
      17             : /// @author  Michael Behrisch
      18             : /// @date    Mon, 25.07.2005
      19             : ///
      20             : // Reroutes vehicles passing an edge (gui version)
      21             : /****************************************************************************/
      22             : #include <config.h>
      23             : 
      24             : #include <string>
      25             : #include <utils/common/MsgHandler.h>
      26             : #include <utils/geom/PositionVector.h>
      27             : #include <utils/geom/Boundary.h>
      28             : #include <utils/gui/div/GLHelper.h>
      29             : #include <utils/common/ToString.h>
      30             : #include <utils/common/Command.h>
      31             : #include <microsim/MSNet.h>
      32             : #include <microsim/MSLane.h>
      33             : #include <microsim/MSEdge.h>
      34             : #include <microsim/MSRoute.h>
      35             : #include <microsim/MSVehicle.h>
      36             : #include <guisim/GUINet.h>
      37             : #include <guisim/GUIEdge.h>
      38             : #include "GUITriggeredRerouter.h"
      39             : #include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
      40             : #include <utils/gui/windows/GUIAppEnum.h>
      41             : #include <gui/GUIGlobals.h>
      42             : #include <utils/gui/div/GUIParameterTableWindow.h>
      43             : #include <gui/GUIApplicationWindow.h>
      44             : #include <microsim/logging/FunctionBinding.h>
      45             : #include <utils/gui/div/GUIGlobalSelection.h>
      46             : #include <utils/gui/globjects/GLIncludes.h>
      47             : #include <utils/gui/globjects/GLIncludes.h>
      48             : #include <utils/gui/div/GUIDesigns.h>
      49             : 
      50             : 
      51             : // ===========================================================================
      52             : // FOX callback mapping
      53             : // ===========================================================================
      54             : /* -------------------------------------------------------------------------
      55             :  * GUITriggeredRerouter::GUITriggeredRerouterPopupMenu - mapping
      56             :  * ----------------------------------------------------------------------- */
      57             : FXDEFMAP(GUITriggeredRerouter::GUITriggeredRerouterPopupMenu)
      58             : GUITriggeredRerouterPopupMenuMap[] = {
      59             :     FXMAPFUNC(SEL_COMMAND,  MID_MANIP,         GUITriggeredRerouter::GUITriggeredRerouterPopupMenu::onCmdOpenManip),
      60             : 
      61             : };
      62             : 
      63             : // Object implementation
      64           0 : FXIMPLEMENT(GUITriggeredRerouter::GUITriggeredRerouterPopupMenu, GUIGLObjectPopupMenu, GUITriggeredRerouterPopupMenuMap, ARRAYNUMBER(GUITriggeredRerouterPopupMenuMap))
      65             : 
      66             : 
      67             : /* -------------------------------------------------------------------------
      68             :  * GUITriggeredRerouter::GUIManip_TriggeredRerouter - mapping
      69             :  * ----------------------------------------------------------------------- */
      70             : FXDEFMAP(GUITriggeredRerouter::GUIManip_TriggeredRerouter) GUIManip_TriggeredRerouterMap[] = {
      71             :     FXMAPFUNC(SEL_COMMAND,  GUITriggeredRerouter::GUIManip_TriggeredRerouter::MID_USER_DEF, GUITriggeredRerouter::GUIManip_TriggeredRerouter::onCmdUserDef),
      72             :     FXMAPFUNC(SEL_UPDATE,   GUITriggeredRerouter::GUIManip_TriggeredRerouter::MID_USER_DEF, GUITriggeredRerouter::GUIManip_TriggeredRerouter::onUpdUserDef),
      73             :     FXMAPFUNC(SEL_COMMAND,  GUITriggeredRerouter::GUIManip_TriggeredRerouter::MID_OPTION,   GUITriggeredRerouter::GUIManip_TriggeredRerouter::onCmdChangeOption),
      74             :     FXMAPFUNC(SEL_COMMAND,  GUITriggeredRerouter::GUIManip_TriggeredRerouter::MID_SHIFT_PROBS,  GUITriggeredRerouter::GUIManip_TriggeredRerouter::onCmdShiftProbs),
      75             :     FXMAPFUNC(SEL_COMMAND,  GUITriggeredRerouter::GUIManip_TriggeredRerouter::MID_CLOSE,    GUITriggeredRerouter::GUIManip_TriggeredRerouter::onCmdClose),
      76             : };
      77             : 
      78           0 : FXIMPLEMENT(GUITriggeredRerouter::GUIManip_TriggeredRerouter, GUIManipulator, GUIManip_TriggeredRerouterMap, ARRAYNUMBER(GUIManip_TriggeredRerouterMap))
      79             : 
      80             : 
      81             : // ===========================================================================
      82             : // method definitions
      83             : // ===========================================================================
      84             : /* -------------------------------------------------------------------------
      85             :  * GUITriggeredRerouter::GUIManip_TriggeredRerouter - methods
      86             :  * ----------------------------------------------------------------------- */
      87           0 : GUITriggeredRerouter::GUIManip_TriggeredRerouter::GUIManip_TriggeredRerouter(
      88           0 :     GUIMainWindow& app, const std::string& name, GUITriggeredRerouter& o) :
      89           0 :     GUIManipulator(app, name, 0, 0), myParent(&app),
      90           0 :     myChosenValue(0), myChosenTarget(myChosenValue, nullptr, MID_OPTION),
      91           0 :     myUsageProbability(o.getProbability()), myUsageProbabilityTarget(myUsageProbability),
      92           0 :     myObject(&o) {
      93           0 :     myChosenTarget.setTarget(this);
      94             :     FXVerticalFrame* f1 =
      95           0 :         new FXVerticalFrame(this, LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0);
      96             : 
      97             :     FXGroupBox* gp = new FXGroupBox(f1, "Change Trigger Probability",
      98             :                                     GROUPBOX_TITLE_LEFT | FRAME_SUNKEN | FRAME_RIDGE,
      99           0 :                                     0, 0, 0, 0,  4, 4, 1, 1, 2, 0);
     100             :     {
     101             :         // default
     102             :         FXHorizontalFrame* gf1 =
     103           0 :             new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
     104           0 :         new FXRadioButton(gf1, "Default", &myChosenTarget, FXDataTarget::ID_OPTION + 0,
     105             :                           ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
     106           0 :                           0, 0, 0, 0,   2, 2, 0, 0);
     107             :     }
     108             :     {
     109             :         // free
     110             :         FXHorizontalFrame* gf12 =
     111           0 :             new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
     112           0 :         new FXRadioButton(gf12, "User Given: ", &myChosenTarget, FXDataTarget::ID_OPTION + 1,
     113             :                           ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y,
     114           0 :                           0, 0, 0, 0,   2, 2, 0, 0);
     115           0 :         myUsageProbabilityDial =
     116             :             new FXRealSpinner(gf12, 10, this, MID_USER_DEF,
     117           0 :                               LAYOUT_TOP | FRAME_SUNKEN | FRAME_THICK);
     118             :         //myUsageProbabilityDial->setFormatString("%.2f");
     119             :         //myUsageProbabilityDial->setIncrements(.1, .1, .1);
     120           0 :         myUsageProbabilityDial->setIncrement(.1);
     121           0 :         myUsageProbabilityDial->setRange(0, 1);
     122           0 :         myUsageProbabilityDial->setValue(myObject->getUserProbability());
     123             :     }
     124             :     {
     125             :         // off
     126             :         FXHorizontalFrame* gf13 =
     127           0 :             new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
     128           0 :         new FXRadioButton(gf13, "Off", &myChosenTarget, FXDataTarget::ID_OPTION + 2,
     129             :                           ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
     130           0 :                           0, 0, 0, 0,   2, 2, 0, 0);
     131             :     }
     132           0 :     myChosenValue = myObject->inUserMode()
     133           0 :                     ? myObject->getUserProbability() > 0
     134           0 :                     ? 1 : 2
     135             :                     : 0;
     136             : 
     137             :     FXGroupBox* gp2 = new FXGroupBox(f1, "Change Route Probability",
     138             :                                      GROUPBOX_TITLE_LEFT | FRAME_SUNKEN | FRAME_RIDGE,
     139           0 :                                      0, 0, 0, 0,  4, 4, 1, 1, 2, 0);
     140           0 :     GUIDesigns::buildFXButton(gp2, "Shift", "", "", nullptr, this, MID_SHIFT_PROBS,
     141             :                               BUTTON_INITIAL | BUTTON_DEFAULT | FRAME_RAISED | FRAME_THICK | LAYOUT_TOP | LAYOUT_LEFT | LAYOUT_CENTER_X, 0, 0, 0, 0, 30, 30, 4, 4);
     142             : 
     143           0 :     GUIDesigns::buildFXButton(f1, "Close", "", "", nullptr, this, MID_CLOSE,
     144             :                               BUTTON_INITIAL | BUTTON_DEFAULT | FRAME_RAISED | FRAME_THICK | LAYOUT_TOP | LAYOUT_LEFT | LAYOUT_CENTER_X, 0, 0, 0, 0, 30, 30, 4, 4);
     145             : 
     146           0 : }
     147             : 
     148             : 
     149           0 : GUITriggeredRerouter::GUIManip_TriggeredRerouter::~GUIManip_TriggeredRerouter() {}
     150             : 
     151             : 
     152             : long
     153           0 : GUITriggeredRerouter::GUIManip_TriggeredRerouter::onCmdClose(FXObject*, FXSelector, void*) {
     154           0 :     destroy();
     155           0 :     return 1;
     156             : }
     157             : 
     158             : 
     159             : long
     160           0 : GUITriggeredRerouter::GUIManip_TriggeredRerouter::onCmdUserDef(FXObject*, FXSelector, void*) {
     161           0 :     myUsageProbability = (double)(myUsageProbabilityDial->getValue());
     162           0 :     static_cast<GUITriggeredRerouter*>(myObject)->setUserUsageProbability(myUsageProbability);
     163           0 :     static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(true);
     164           0 :     myParent->updateChildren();
     165           0 :     return 1;
     166             : }
     167             : 
     168             : 
     169             : long
     170           0 : GUITriggeredRerouter::GUIManip_TriggeredRerouter::onUpdUserDef(FXObject* sender, FXSelector, void* ptr) {
     171           0 :     sender->handle(this,
     172           0 :                    myChosenValue != 1 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
     173             :                    ptr);
     174           0 :     myParent->updateChildren();
     175           0 :     return 1;
     176             : }
     177             : 
     178             : 
     179             : long
     180           0 : GUITriggeredRerouter::GUIManip_TriggeredRerouter::onCmdChangeOption(FXObject*, FXSelector, void*) {
     181           0 :     static_cast<GUITriggeredRerouter*>(myObject)->setUserUsageProbability(myUsageProbability);
     182           0 :     switch (myChosenValue) {
     183           0 :         case 0:
     184           0 :             static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(false);
     185           0 :             break;
     186           0 :         case 1:
     187           0 :             static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(true);
     188           0 :             break;
     189           0 :         case 2:
     190           0 :             static_cast<GUITriggeredRerouter*>(myObject)->setUserUsageProbability(0);
     191           0 :             static_cast<GUITriggeredRerouter*>(myObject)->setUserMode(true);
     192           0 :             break;
     193           0 :         default:
     194           0 :             throw 1;
     195             :     }
     196           0 :     myParent->updateChildren();
     197           0 :     return 1;
     198             : }
     199             : 
     200             : long
     201           0 : GUITriggeredRerouter::GUIManip_TriggeredRerouter::onCmdShiftProbs(FXObject*, FXSelector, void*) {
     202           0 :     static_cast<GUITriggeredRerouter*>(myObject)->shiftProbs();
     203           0 :     myParent->updateChildren();
     204           0 :     return 1;
     205             : }
     206             : 
     207             : 
     208             : 
     209             : /* -------------------------------------------------------------------------
     210             :  * GUITriggeredRerouter::GUITriggeredRerouterPopupMenu - methods
     211             :  * ----------------------------------------------------------------------- */
     212           0 : GUITriggeredRerouter::GUITriggeredRerouterPopupMenu::GUITriggeredRerouterPopupMenu(
     213             :     GUIMainWindow& app, GUISUMOAbstractView& parent,
     214           0 :     GUIGlObject& o)
     215           0 :     : GUIGLObjectPopupMenu(app, parent, o) {}
     216             : 
     217             : 
     218           0 : GUITriggeredRerouter::GUITriggeredRerouterPopupMenu::~GUITriggeredRerouterPopupMenu() {}
     219             : 
     220             : 
     221             : long
     222           0 : GUITriggeredRerouter::GUITriggeredRerouterPopupMenu::onCmdOpenManip(FXObject*,
     223             :         FXSelector,
     224             :         void*) {
     225           0 :     static_cast<GUITriggeredRerouter*>(myObject)->openManipulator(
     226           0 :         *myApplication, *myParent);
     227           0 :     return 1;
     228             : }
     229             : 
     230             : // -------------------------------------------------------------------------
     231             : // GUITriggeredRerouter - methods
     232             : // -------------------------------------------------------------------------
     233             : 
     234         647 : GUITriggeredRerouter::GUITriggeredRerouter(const std::string& id, const MSEdgeVector& edges, double prob,
     235         647 :         bool off, bool optional, SUMOTime timeThreshold, const std::string& vTypes, const Position& pos, SUMORTree& rtree) :
     236             :     MSTriggeredRerouter(id, edges, prob, off, optional, timeThreshold, vTypes, pos),
     237             :     GUIGlObject_AbstractAdd(GLO_REROUTER, id, GUIIconSubSys::getIcon(GUIIcon::REROUTER)),
     238         647 :     myShiftProbDistIndex(0) {
     239             :     // add visualisation objects for edges which trigger the rerouter
     240        1484 :     for (MSEdgeVector::const_iterator it = edges.begin(); it != edges.end(); ++it) {
     241         837 :         myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast<GUIEdge*>(*it), this, REROUTER_TRIGGER_EDGE));
     242         837 :         rtree.addAdditionalGLObject(myEdgeVisualizations.back());
     243         837 :         myBoundary.add(myEdgeVisualizations.back()->getCenteringBoundary());
     244             :     }
     245         647 : }
     246             : 
     247             : 
     248        1294 : GUITriggeredRerouter::~GUITriggeredRerouter() {
     249        1708 :     for (std::vector<GUITriggeredRerouterEdge*>::iterator it = myEdgeVisualizations.begin(); it != myEdgeVisualizations.end(); ++it) {
     250        1061 :         delete *it;
     251             :     }
     252             :     myEdgeVisualizations.clear();
     253        1294 : }
     254             : 
     255             : 
     256             : void
     257        4184 : GUITriggeredRerouter::myEndElement(int element) {
     258        4184 :     MSTriggeredRerouter::myEndElement(element);
     259        4184 :     if (element == SUMO_TAG_INTERVAL) {
     260             :         // add visualisation objects for closed edges
     261             :         const RerouteInterval& ri = myIntervals.back();
     262         856 :         for (MSEdgeVector::const_iterator it = ri.closed.begin(); it != ri.closed.end(); ++it) {
     263         205 :             myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast<GUIEdge*>(*it), this, REROUTER_CLOSED_EDGE));
     264         205 :             dynamic_cast<GUINet*>(GUINet::getInstance())->getVisualisationSpeedUp().addAdditionalGLObject(myEdgeVisualizations.back());
     265         205 :             myBoundary.add(myEdgeVisualizations.back()->getCenteringBoundary());
     266             :         }
     267             :         // add visualisation objects for switches
     268         651 :         if (ri.routeProbs.getProbs().size() > 1) {
     269             :             // find last common edge of all routes
     270             :             ConstMSRoutePtr route0 = ri.routeProbs.getVals()[0];
     271             :             const MSEdge* lastEdge = nullptr;
     272             :             int nextIndex = 0;
     273          16 :             for (int i = 0; i < (int)route0->getEdges().size(); i++) {
     274          16 :                 const MSEdge* cand = route0->getEdges()[i];
     275          58 :                 for (ConstMSRoutePtr route : ri.routeProbs.getVals()) {
     276          42 :                     const MSEdge* nextEdge = i < (int)route->getEdges().size() ? route->getEdges()[i] : nullptr;
     277          42 :                     if (nextEdge != cand) {
     278             :                         cand = nullptr;
     279             :                     }
     280             :                 }
     281          16 :                 if (cand != nullptr) {
     282             :                     lastEdge = cand;
     283             :                 } else {
     284             :                     nextIndex = i;
     285             :                     break;
     286             :                 }
     287             :             }
     288           7 :             if (lastEdge != nullptr) {
     289          26 :                 for (int i = 0; i < (int)ri.routeProbs.getVals().size(); i++) {
     290          19 :                     const ConstMSEdgeVector& edges = ri.routeProbs.getVals()[i]->getEdges();
     291          19 :                     if (nextIndex < (int)edges.size()) {
     292          19 :                         GUIEdge* edge = dynamic_cast<GUIEdge*>(const_cast<MSEdge*>(edges[nextIndex]));
     293          19 :                         myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(edge, this, REROUTER_SWITCH_EDGE, i));
     294          19 :                         dynamic_cast<GUINet*>(GUINet::getInstance())->getVisualisationSpeedUp().addAdditionalGLObject(myEdgeVisualizations.back());
     295          19 :                         myBoundary.add(myEdgeVisualizations.back()->getCenteringBoundary());
     296             :                     }
     297             :                 }
     298             :             }
     299             :         }
     300             :     }
     301        4184 : }
     302             : 
     303             : 
     304             : GUIGLObjectPopupMenu*
     305           0 : GUITriggeredRerouter::getPopUpMenu(GUIMainWindow& app,
     306             :                                    GUISUMOAbstractView& parent) {
     307           0 :     GUIGLObjectPopupMenu* ret = new GUITriggeredRerouterPopupMenu(app, parent, *this);
     308           0 :     buildPopupHeader(ret, app);
     309           0 :     buildCenterPopupEntry(ret);
     310           0 :     buildShowManipulatorPopupEntry(ret, false);
     311           0 :     buildNameCopyPopupEntry(ret);
     312           0 :     buildSelectionPopupEntry(ret);
     313           0 :     buildPositionCopyEntry(ret, app);
     314           0 :     return ret;
     315             : }
     316             : 
     317             : 
     318             : GUIParameterTableWindow*
     319           0 : GUITriggeredRerouter::getParameterWindow(GUIMainWindow&,
     320             :         GUISUMOAbstractView&) {
     321           0 :     return nullptr;
     322             : }
     323             : 
     324             : 
     325             : void
     326           0 : GUITriggeredRerouter::drawGL(const GUIVisualizationSettings& s) const {
     327             :     UNUSED_PARAMETER(s);
     328           0 : }
     329             : 
     330             : 
     331             : Boundary
     332           0 : GUITriggeredRerouter::getCenteringBoundary() const {
     333             :     Boundary b(myBoundary);
     334           0 :     b.grow(20);
     335           0 :     return b;
     336           0 : }
     337             : 
     338             : 
     339             : double
     340           0 : GUITriggeredRerouter::getExaggeration(const GUIVisualizationSettings& s) const {
     341           0 :     return s.addSize.getExaggeration(s, this);
     342             : }
     343             : 
     344             : 
     345             : GUIManipulator*
     346           0 : GUITriggeredRerouter::openManipulator(GUIMainWindow& app,
     347             :                                       GUISUMOAbstractView&) {
     348           0 :     GUIManip_TriggeredRerouter* gui = new GUIManip_TriggeredRerouter(app, getFullName(), *this);
     349           0 :     gui->create();
     350           0 :     gui->show(PLACEMENT_SCREEN);
     351           0 :     return gui;
     352             : }
     353             : 
     354             : 
     355             : void
     356           0 : GUITriggeredRerouter::shiftProbs() {
     357           0 :     const RerouteInterval* const ri = getCurrentReroute(MSNet::getInstance()->getCurrentTimeStep());
     358           0 :     if (ri != nullptr && ri->routeProbs.getProbs().size() > 1) {
     359           0 :         auto& rp = const_cast<RandomDistributor<ConstMSRoutePtr>&>(ri->routeProbs);
     360           0 :         myShiftProbDistIndex = myShiftProbDistIndex % rp.getProbs().size();
     361           0 :         double prob = rp.getProbs()[myShiftProbDistIndex];
     362           0 :         rp.add(rp.getVals()[myShiftProbDistIndex], -prob);
     363           0 :         myShiftProbDistIndex = (myShiftProbDistIndex + 1) % rp.getProbs().size();
     364           0 :         rp.add(rp.getVals()[myShiftProbDistIndex], prob);
     365             :         // notify vehicles currently on a trigger edge
     366           0 :         for (auto rrEdge : myEdgeVisualizations) {
     367           0 :             if (rrEdge->getRerouterEdgeType() == REROUTER_TRIGGER_EDGE) {
     368           0 :                 if (!MSGlobals::gUseMesoSim) {
     369           0 :                     for (MSLane* lane : rrEdge->getEdge()->getLanes()) {
     370           0 :                         for (const MSVehicle* veh : lane->getVehiclesSecure()) {
     371           0 :                             const_cast<MSVehicle*>(veh)->addReminder(this);
     372             :                         }
     373           0 :                         lane->releaseVehicles();
     374             :                     }
     375             :                 }
     376             :             }
     377             :         }
     378             :     }
     379           0 : }
     380             : 
     381             : 
     382             : /* -------------------------------------------------------------------------
     383             :  * GUITriggeredRerouterEdge - methods
     384             :  * ----------------------------------------------------------------------- */
     385        1061 : GUITriggeredRerouter::GUITriggeredRerouterEdge::GUITriggeredRerouterEdge(GUIEdge* edge, GUITriggeredRerouter* parent, RerouterEdgeType edgeType, int distIndex) :
     386        2122 :     GUIGlObject(GLO_REROUTER_EDGE, parent->getID() + ":" + edge->getID(), GUIIconSubSys::getIcon(GUIIcon::REROUTER)),
     387        1061 :     myParent(parent),
     388        1061 :     myEdge(edge),
     389        1061 :     myEdgeType(edgeType),
     390        3183 :     myDistIndex(distIndex) {
     391             :     const std::vector<MSLane*>& lanes = edge->getLanes();
     392        1061 :     myFGPositions.reserve(lanes.size());
     393        1061 :     myFGRotations.reserve(lanes.size());
     394        2219 :     for (const MSLane* lane : lanes) {
     395        1158 :         if ((lane->getPermissions() & ~SVC_PEDESTRIAN) == 0) {
     396          24 :             continue;
     397             :         }
     398             :         const PositionVector& v = lane->getShape();
     399        1134 :         const double pos = edgeType == REROUTER_TRIGGER_EDGE ? MAX2(0.0, v.length() - 6) : MIN2(v.length(), 3.0);
     400        1134 :         myFGPositions.push_back(v.positionAtOffset(pos));
     401        1134 :         myFGRotations.push_back(-v.rotationDegreeAtOffset(pos));
     402        1134 :         myBoundary.add(myFGPositions.back());
     403        1134 :         myHalfWidths.push_back(lane->getWidth() * 0.5 * 0.875);
     404             :     }
     405        1061 : }
     406             : 
     407             : 
     408        4244 : GUITriggeredRerouter::GUITriggeredRerouterEdge::~GUITriggeredRerouterEdge() {}
     409             : 
     410             : 
     411             : GUIGLObjectPopupMenu*
     412           0 : GUITriggeredRerouter::GUITriggeredRerouterEdge::getPopUpMenu(GUIMainWindow& app,
     413             :         GUISUMOAbstractView& parent) {
     414           0 :     return myParent->getPopUpMenu(app, parent);
     415             : }
     416             : 
     417             : 
     418             : GUIParameterTableWindow*
     419           0 : GUITriggeredRerouter::GUITriggeredRerouterEdge::getParameterWindow(GUIMainWindow&,
     420             :         GUISUMOAbstractView&) {
     421           0 :     return nullptr;
     422             : }
     423             : 
     424             : 
     425             : void
     426      189072 : GUITriggeredRerouter::GUITriggeredRerouterEdge::drawGL(const GUIVisualizationSettings& s) const {
     427      189072 :     const double exaggeration = getExaggeration(s);
     428      189072 :     if (s.scale * exaggeration >= 3) {
     429        1469 :         GLHelper::pushName(getGlID());
     430        1469 :         const double prob = myParent->getProbability();
     431        1469 :         if (myEdgeType == REROUTER_CLOSED_EDGE) {
     432             :             // draw closing symbol onto all lanes
     433             :             const RerouteInterval* const ri =
     434          24 :                 myParent->getCurrentReroute(MSNet::getInstance()->getCurrentTimeStep());
     435          24 :             if (ri != nullptr && prob > 0) {
     436             :                 // draw only if the edge is closed at this time
     437          11 :                 if (std::find(ri->closed.begin(), ri->closed.end(), myEdge) != ri->closed.end()) {
     438          11 :                     const int noLanes = (int)myFGPositions.size();
     439          23 :                     for (int j = 0; j < noLanes; ++j) {
     440          12 :                         Position pos = myFGPositions[j];
     441          12 :                         double rot = myFGRotations[j];
     442          12 :                         GLHelper::pushMatrix();
     443          12 :                         glTranslated(pos.x(), pos.y(), 0);
     444          12 :                         glRotated(rot, 0, 0, 1);
     445          12 :                         glTranslated(0, -1.5, 0);
     446             :                         int noPoints = 9;
     447          12 :                         if (s.scale > 25) {
     448           0 :                             noPoints = (int)(9.0 + s.scale / 10.0);
     449             :                             if (noPoints > 36) {
     450             :                                 noPoints = 36;
     451             :                             }
     452             :                         }
     453          12 :                         glTranslated(0, 0, getType());
     454             :                         //glScaled(exaggeration, exaggeration, 1);
     455          12 :                         glColor3d(0.7, 0, 0);
     456          12 :                         GLHelper::drawFilledCircle((double) 1.3, noPoints);
     457          12 :                         glTranslated(0, 0, .1);
     458          12 :                         glColor3d(1, 0, 0);
     459          12 :                         GLHelper::drawFilledCircle((double) 1.3, noPoints, 0, prob * 360);
     460          12 :                         glTranslated(0, 0, .1);
     461          12 :                         glColor3d(1, 1, 1);
     462          12 :                         glRotated(-90, 0, 0, 1);
     463          12 :                         glBegin(GL_TRIANGLES);
     464          12 :                         glVertex2d(0 - .3, -1.);
     465          12 :                         glVertex2d(0 - .3, 1.);
     466          12 :                         glVertex2d(0 + .3, 1.);
     467          12 :                         glVertex2d(0 + .3, -1.);
     468          12 :                         glVertex2d(0 - .3, -1.);
     469          12 :                         glVertex2d(0 + .3, 1.);
     470          12 :                         glEnd();
     471          12 :                         GLHelper::popMatrix();
     472             :                     }
     473             :                 }
     474             :             }
     475             : 
     476        1445 :         } else if (myEdgeType == REROUTER_TRIGGER_EDGE) {
     477             :             // draw rerouter symbol onto all lanes
     478        3603 :             for (int i = 0; i < (int)myFGPositions.size(); ++i) {
     479        2524 :                 const Position& pos = myFGPositions[i];
     480        2524 :                 double rot = myFGRotations[i];
     481        2524 :                 const double w = myHalfWidths[i];
     482        2524 :                 GLHelper::pushMatrix();
     483        2524 :                 glTranslated(pos.x(), pos.y(), 0);
     484        2524 :                 glRotated(rot, 0, 0, 1);
     485        2524 :                 glTranslated(0, 0, getType());
     486        2524 :                 glScaled(exaggeration, exaggeration, 1);
     487        2524 :                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     488             : 
     489        2524 :                 glBegin(GL_TRIANGLES);
     490        2524 :                 glColor3d(1, .8f, 0);
     491             :                 // base
     492        2524 :                 glVertex2d(0 - w, 0);
     493        2524 :                 glVertex2d(0 - w, 6);
     494        2524 :                 glVertex2d(0 + w, 6);
     495        2524 :                 glVertex2d(0 + w, 0);
     496        2524 :                 glVertex2d(0 - w, 0);
     497        2524 :                 glVertex2d(0 + w, 6);
     498        2524 :                 glEnd();
     499             : 
     500             :                 // draw "U"
     501        5048 :                 GLHelper::drawText("U", Position(0, 2), .1, 3 * (w / 1.4), RGBColor::BLACK, 180);
     502             : 
     503             :                 // draw Probability
     504        5048 :                 GLHelper::drawText((toString((int)(prob * 100)) + "%").c_str(), Position(0, 4), .1, 0.7, RGBColor::BLACK, 180);
     505             : 
     506        2524 :                 GLHelper::popMatrix();
     507             :             }
     508         366 :         } else if (myEdgeType == REROUTER_SWITCH_EDGE) {
     509             :             const RerouteInterval* const ri =
     510         366 :                 myParent->getCurrentReroute(MSNet::getInstance()->getCurrentTimeStep());
     511         366 :             const double routeProb = ri != nullptr && prob > 0 ?  ri->routeProbs.getProbs()[myDistIndex] / ri->routeProbs.getOverallProb() : 0;
     512         366 :             if (routeProb > 0) {
     513         720 :                 for (int i = 0; i < (int)myFGPositions.size(); ++i) {
     514         360 :                     const Position& pos = myFGPositions[i];
     515         360 :                     double rot = myFGRotations[i];
     516         360 :                     const double w = myHalfWidths[i];
     517         360 :                     GLHelper::pushMatrix();
     518         360 :                     glTranslated(pos.x(), pos.y(), 0);
     519         360 :                     glRotated(rot, 0, 0, 1);
     520         360 :                     glTranslated(0, 0, getType());
     521         360 :                     glScaled(exaggeration, exaggeration, 1);
     522         360 :                     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     523             : 
     524         360 :                     glBegin(GL_TRIANGLES);
     525         360 :                     glColor3d(0, 1, 1);
     526             :                     // base
     527         360 :                     glVertex2d(0 - 0.0, 0);
     528         360 :                     glVertex2d(0 - w, 6);
     529         360 :                     glVertex2d(0 + w, 6);
     530         360 :                     glVertex2d(0 + 0.0, 0);
     531         360 :                     glVertex2d(0 + w, 6);
     532         360 :                     glEnd();
     533             : 
     534             :                     // draw "P"
     535         720 :                     GLHelper::drawText("P", Position(0, 3.5), .1, 2, RGBColor::BLACK, 180);
     536             : 
     537             :                     // draw Probability for this target edge
     538         720 :                     GLHelper::drawText((toString((int)(routeProb * 100)) + "%").c_str(), Position(0, 5), .1, 0.7, RGBColor::BLACK, 180);
     539             : 
     540         360 :                     GLHelper::popMatrix();
     541             :                 }
     542             :             }
     543             :         }
     544        1469 :         GLHelper::popName();
     545             :     }
     546      189072 : }
     547             : 
     548             : 
     549             : double
     550      189072 : GUITriggeredRerouter::GUITriggeredRerouterEdge::getExaggeration(const GUIVisualizationSettings& s) const {
     551      189072 :     return s.addSize.getExaggeration(s, this);
     552             : }
     553             : 
     554             : 
     555             : Boundary
     556        2122 : GUITriggeredRerouter::GUITriggeredRerouterEdge::getCenteringBoundary() const {
     557             :     Boundary b(myBoundary);
     558        2122 :     b.grow(20);
     559        2122 :     return b;
     560           0 : }
     561             : 
     562             : 
     563             : void
     564           0 : GUITriggeredRerouter::GUITriggeredRerouterEdge::onLeftBtnPress(void* /*data*/) {
     565           0 :     myParent->shiftProbs();
     566           0 : }
     567             : 
     568             : 
     569             : /****************************************************************************/

Generated by: LCOV version 1.14