LCOV - code coverage report
Current view: top level - src/guisim - GUINet.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 37.4 % 377 141
Test Date: 2024-11-22 15:46:21 Functions: 39.2 % 51 20

            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    GUINet.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @author  Laura Bieker
      19              : /// @date    Sept 2002
      20              : ///
      21              : // A MSNet extended by some values for usage within the gui
      22              : /****************************************************************************/
      23              : #include <config.h>
      24              : 
      25              : #include <utility>
      26              : #include <set>
      27              : #include <vector>
      28              : #include <map>
      29              : #include <utils/shapes/ShapeContainer.h>
      30              : #include <utils/gui/globjects/GUIPolygon.h>
      31              : #include <utils/gui/globjects/GUIPointOfInterest.h>
      32              : #include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
      33              : #include <utils/gui/div/GUIDesigns.h>
      34              : #include <utils/gui/div/GUIParameterTableWindow.h>
      35              : #include <utils/gui/div/GUIGlobalSelection.h>
      36              : #include <utils/gui/globjects/GUIShapeContainer.h>
      37              : #include <utils/xml/XMLSubSys.h>
      38              : #include <utils/common/MsgHandler.h>
      39              : #include <utils/common/StringUtils.h>
      40              : #include <utils/common/RGBColor.h>
      41              : #include <utils/iodevices/OutputDevice.h>
      42              : #include <utils/gui/div/GLObjectValuePassConnector.h>
      43              : #include <microsim/MSNet.h>
      44              : #include <microsim/MSEdgeWeightsStorage.h>
      45              : #include <microsim/MSJunction.h>
      46              : #include <microsim/output/MSDetectorControl.h>
      47              : #include <microsim/MSEdge.h>
      48              : #include <microsim/transportables/MSPModel.h>
      49              : #include <microsim/MSInsertionControl.h>
      50              : #include <microsim/traffic_lights/MSTrafficLightLogic.h>
      51              : #include <microsim/traffic_lights/MSTLLogicControl.h>
      52              : #include <microsim/MSJunctionControl.h>
      53              : #include <guisim/Command_Hotkey_TrafficLight.h>
      54              : #include <guisim/GUIEdge.h>
      55              : #include <guisim/GUILane.h>
      56              : #include <guisim/GUITransportableControl.h>
      57              : #include <guisim/GUILaneSpeedTrigger.h>
      58              : #include <guisim/GUIDetectorWrapper.h>
      59              : #include <guisim/GUICalibrator.h>
      60              : #include <guisim/GUITrafficLightLogicWrapper.h>
      61              : #include <guisim/GUIJunctionWrapper.h>
      62              : #include <guisim/GUIVehicleControl.h>
      63              : #include <gui/GUIGlobals.h>
      64              : #include <gui/GUIApplicationWindow.h>
      65              : #include "GUINet.h"
      66              : 
      67              : #include <mesogui/GUIMEVehicleControl.h>
      68              : 
      69              : 
      70              : // ===========================================================================
      71              : // definition of static variables used for visualisation of objects' values
      72              : // ===========================================================================
      73              : template std::vector< GLObjectValuePassConnector<double>* > GLObjectValuePassConnector<double>::myContainer;
      74              : template FXMutex GLObjectValuePassConnector<double>::myLock;
      75              : 
      76              : template std::vector< GLObjectValuePassConnector<std::pair<int, class MSPhaseDefinition> >* > GLObjectValuePassConnector<std::pair<int, class MSPhaseDefinition> >::myContainer;
      77              : template FXMutex GLObjectValuePassConnector<std::pair<int, class MSPhaseDefinition> >::myLock;
      78              : 
      79              : 
      80              : // ===========================================================================
      81              : // member method definitions
      82              : // ===========================================================================
      83         7525 : GUINet::GUINet(MSVehicleControl* vc, MSEventControl* beginOfTimestepEvents,
      84              :                MSEventControl* endOfTimestepEvents,
      85         7525 :                MSEventControl* insertionEvents) :
      86         7525 :     MSNet(vc, beginOfTimestepEvents, endOfTimestepEvents, insertionEvents, new GUIShapeContainer(myGrid)),
      87              :     GUIGlObject(GLO_NETWORK, "", nullptr),
      88         7525 :     myLastSimDuration(0), /*myLastVisDuration(0),*/ myLastIdleDuration(0),
      89        22575 :     myLastVehicleMovementCount(0), myOverallVehicleCount(0), myOverallSimDuration(0) {
      90              :     GUIGlObjectStorage::gIDStorage.setNetObject(this);
      91         7525 : }
      92              : 
      93              : 
      94        15024 : GUINet::~GUINet() {
      95         7512 :     if (myLock.locked()) {
      96            0 :         myLock.unlock();
      97              :     }
      98              :     // delete allocated wrappers
      99              :     //  of junctions
     100        93849 :     for (std::vector<GUIJunctionWrapper*>::iterator i1 = myJunctionWrapper.begin(); i1 != myJunctionWrapper.end(); i1++) {
     101        86337 :         delete (*i1);
     102              :     }
     103              :     //  of additional structures
     104         7512 :     GUIGlObject_AbstractAdd::clearDictionary();
     105              :     //  of tl-logics
     106        27774 :     for (Logics2WrapperMap::iterator i3 = myLogics2Wrapper.begin(); i3 != myLogics2Wrapper.end(); i3++) {
     107        20262 :         delete (*i3).second;
     108              :     }
     109              :     //  of detectors
     110         8616 :     for (std::vector<GUIDetectorWrapper*>::iterator i = myDetectorWrapper.begin(); i != myDetectorWrapper.end(); ++i) {
     111         1104 :         delete *i;
     112              :     }
     113              :     //  of calibrators
     114         7594 :     for (GUICalibrator* cw : myCalibratorWrapper) {
     115           82 :         delete cw;
     116              :     }
     117         7512 :     for (auto& item : myLoadedEdgeData) {
     118            0 :         delete item.second;
     119              :     }
     120        22536 : }
     121              : 
     122              : 
     123              : const Boundary&
     124            0 : GUINet::getBoundary() const {
     125            0 :     return myBoundary;
     126              : }
     127              : 
     128              : 
     129              : MSTransportableControl&
     130      3434550 : GUINet::getPersonControl() {
     131      3434550 :     if (myPersonControl == nullptr) {
     132         1407 :         myPersonControl = new GUITransportableControl(true);
     133              :     }
     134      3434550 :     return *myPersonControl;
     135              : }
     136              : 
     137              : 
     138              : MSTransportableControl&
     139       146839 : GUINet::getContainerControl() {
     140       146839 :     if (myContainerControl == nullptr) {
     141          167 :         myContainerControl = new GUITransportableControl(false);
     142              :     }
     143       146839 :     return *myContainerControl;
     144              : }
     145              : 
     146              : 
     147              : void
     148         7274 : GUINet::initTLMap() {
     149              :     // go through the loaded tl-logics
     150        27538 :     for (MSTrafficLightLogic* const tll : getTLSControl().getAllLogics()) {
     151        20264 :         createTLWrapper(tll);
     152         7274 :     }
     153         7274 : }
     154              : 
     155              : 
     156              : void
     157        20275 : GUINet::createTLWrapper(MSTrafficLightLogic* tll) {
     158              :     if (myLogics2Wrapper.count(tll) > 0) {
     159              :         return;
     160              :     }
     161              :     // get the links
     162        20275 :     const MSTrafficLightLogic::LinkVectorVector& links = tll->getLinks();
     163        20275 :     if (links.size() == 0) { // @legacy this should never happen in 0.13.0+ networks
     164              :         return;
     165              :     }
     166              :     // build the wrapper
     167        20275 :     GUITrafficLightLogicWrapper* tllw = new GUITrafficLightLogicWrapper(*myLogics, *tll);
     168        40550 :     if (tll->hasParameter("hotkeyAbort")) {
     169            0 :         Command_Hotkey_TrafficLight::registerHotkey(tll->getParameter("hotkeyAbort"), *tll);
     170              :     }
     171              :     // build the association link->wrapper
     172              :     MSTrafficLightLogic::LinkVectorVector::const_iterator j;
     173       228930 :     for (j = links.begin(); j != links.end(); ++j) {
     174              :         MSTrafficLightLogic::LinkVector::const_iterator j2;
     175       416998 :         for (j2 = (*j).begin(); j2 != (*j).end(); ++j2) {
     176       208343 :             myLinks2Logic[*j2] = tll->getID();
     177              :         }
     178              :     }
     179        20275 :     myGrid.addAdditionalGLObject(tllw);
     180        20275 :     myLogics2Wrapper[tll] = tllw;
     181              : }
     182              : 
     183              : 
     184              : Position
     185            0 : GUINet::getJunctionPosition(const std::string& name) const {
     186              :     // !!! no check for existance!
     187            0 :     return myJunctions->get(name)->getPosition();
     188              : }
     189              : 
     190              : 
     191              : bool
     192            0 : GUINet::vehicleExists(const std::string& name) const {
     193            0 :     return myVehicleControl->getVehicle(name) != nullptr;
     194              : }
     195              : 
     196              : 
     197              : int
     198        49173 : GUINet::getLinkTLID(const MSLink* const link) const {
     199              :     if (myLinks2Logic.count(link) == 0) {
     200              :         //assert(false);
     201              :         return 0;
     202              :     }
     203        98318 :     MSTrafficLightLogic* tll = myLogics->getActive(myLinks2Logic.find(link)->second);
     204              :     if (myLogics2Wrapper.count(tll) == 0) {
     205              :         // tll may have been added via traci. @see ticket #459
     206              :         return 0;
     207              :     }
     208        49159 :     return myLogics2Wrapper.find(tll)->second->getGlID();
     209              : }
     210              : 
     211              : 
     212              : int
     213            0 : GUINet::getLinkTLIndex(const MSLink* const link) const {
     214              :     Links2LogicMap::const_iterator i = myLinks2Logic.find(link);
     215            0 :     if (i == myLinks2Logic.end()) {
     216              :         return -1;
     217              :     }
     218            0 :     if (myLogics2Wrapper.find(myLogics->getActive((*i).second)) == myLogics2Wrapper.end()) {
     219              :         return -1;
     220              :     }
     221            0 :     return myLogics2Wrapper.find(myLogics->getActive((*i).second))->second->getLinkIndex(link);
     222              : }
     223              : 
     224              : 
     225              : void
     226      5836382 : GUINet::guiSimulationStep() {
     227      5836382 :     GLObjectValuePassConnector<double>::updateAll();
     228      5836382 :     GLObjectValuePassConnector<std::pair<SUMOTime, MSPhaseDefinition> >::updateAll();
     229      5836382 : }
     230              : 
     231              : 
     232              : void
     233      5836494 : GUINet::simulationStep() {
     234      5836494 :     FXMutexLock locker(myLock);
     235      5836494 :     MSNet::simulationStep();
     236      5836382 : }
     237              : 
     238              : 
     239              : std::vector<GUIGlID>
     240            0 : GUINet::getJunctionIDs(bool includeInternal) const {
     241              :     std::vector<GUIGlID> ret;
     242            0 :     for (std::vector<GUIJunctionWrapper*>::const_iterator i = myJunctionWrapper.begin(); i != myJunctionWrapper.end(); ++i) {
     243            0 :         if (!(*i)->isInternal() || includeInternal) {
     244            0 :             ret.push_back((*i)->getGlID());
     245              :         }
     246              :     }
     247            0 :     return ret;
     248            0 : }
     249              : 
     250              : 
     251              : std::vector<GUIGlID>
     252            0 : GUINet::getTLSIDs() const {
     253              :     std::vector<GUIGlID> ret;
     254              :     std::vector<std::string> ids;
     255            0 :     for (std::map<MSTrafficLightLogic*, GUITrafficLightLogicWrapper*>::const_iterator i = myLogics2Wrapper.begin(); i != myLogics2Wrapper.end(); ++i) {
     256            0 :         std::string sid = (*i).second->getMicrosimID();
     257            0 :         if (find(ids.begin(), ids.end(), sid) == ids.end()) {
     258            0 :             ret.push_back((*i).second->getGlID());
     259            0 :             ids.push_back(sid);
     260              :         }
     261              :     }
     262            0 :     return ret;
     263            0 : }
     264              : 
     265              : 
     266              : void
     267         7274 : GUINet::initGUIStructures() {
     268              :     // initialise detector storage for gui
     269         7274 :     const std::vector<SumoXMLTag> types = myDetectorControl->getAvailableTypes();
     270         7763 :     for (std::vector<SumoXMLTag>::const_iterator i = types.begin(); i != types.end(); ++i) {
     271         1626 :         for (const auto& j : myDetectorControl->getTypedDetectors(*i)) {
     272         1137 :             GUIDetectorWrapper* wrapper = j.second->buildDetectorGUIRepresentation();
     273         1137 :             if (wrapper != nullptr) {
     274         1106 :                 myDetectorWrapper.push_back(wrapper);
     275         1106 :                 myGrid.addAdditionalGLObject(wrapper);
     276              :             }
     277              :         }
     278              :     }
     279              :     // let's always track emission parameters for the GUI
     280         7274 :     MSGlobals::gHaveEmissions = true;
     281              :     // initialise calibrators
     282         7356 :     for (auto& item : MSCalibrator::getInstances()) {
     283           82 :         GUICalibrator* wrapper = new GUICalibrator(item.second);
     284           82 :         myCalibratorWrapper.push_back(wrapper);
     285           82 :         myGrid.addAdditionalGLObject(wrapper);
     286              :     }
     287              :     // initialise the tl-map
     288         7274 :     initTLMap();
     289              :     // initialise edge storage for gui
     290         7274 :     const MSEdgeVector& edges = MSEdge::getAllEdges();
     291         7274 :     myEdgeWrapper.reserve(edges.size());
     292       304441 :     for (MSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
     293              :         // VISIM connector edges shall be drawn (they have lanes)
     294       297167 :         if (!(*i)->isTazConnector() || (*i)->getLanes().size() > 0) {
     295       294027 :             myEdgeWrapper.push_back(static_cast<GUIEdge*>(*i));
     296              :         }
     297              :     }
     298              :     // initialise junction storage for gui
     299         7274 :     int size = myJunctions->size();
     300         7274 :     myJunctionWrapper.reserve(size);
     301              :     std::map<MSJunction*, std::string> junction2TLL;
     302        27538 :     for (const auto tls : getTLSControl().getAllLogics()) {
     303       228713 :         for (const auto& links : tls->getLinks()) {
     304       416590 :             for (const MSLink* l : links) {
     305       416282 :                 junction2TLL[l->getJunction()] = l->getTLLogic()->getID();
     306              :             }
     307              :         }
     308         7274 :     }
     309        93760 :     for (const auto& i : *myJunctions) {
     310        86486 :         myJunctionWrapper.push_back(new GUIJunctionWrapper(*i.second, junction2TLL[i.second]));
     311              :     }
     312              :     // build the visualization tree
     313       301301 :     for (std::vector<GUIEdge*>::iterator i = myEdgeWrapper.begin(); i != myEdgeWrapper.end(); ++i) {
     314       294027 :         GUIEdge* edge = *i;
     315       294027 :         Boundary b;
     316              :         const std::vector<MSLane*>& lanes = edge->getLanes();
     317       639541 :         for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
     318       345514 :             b.add((*j)->getShape().getBoxBoundary());
     319              :         }
     320              :         // make sure persons are always drawn and selectable since they depend on their edge being drawn
     321       294027 :         b.grow(MSPModel::SIDEWALK_OFFSET + 1 + lanes.front()->getWidth() / 2);
     322       294027 :         const float cmin[2] = { (float)b.xmin(), (float)b.ymin() };
     323       294027 :         const float cmax[2] = { (float)b.xmax(), (float)b.ymax() };
     324       294027 :         myGrid.Insert(cmin, cmax, edge);
     325       294027 :         myBoundary.add(b);
     326       294027 :         if (myBoundary.getWidth() > 10e16 || myBoundary.getHeight() > 10e16) {
     327            0 :             throw ProcessError(TL("Network size exceeds 1 Lightyear. Please reconsider your inputs.\n"));
     328              :         }
     329       294027 :     }
     330        93760 :     for (std::vector<GUIJunctionWrapper*>::iterator i = myJunctionWrapper.begin(); i != myJunctionWrapper.end(); ++i) {
     331        86486 :         GUIJunctionWrapper* junction = *i;
     332              :         Boundary b = junction->getBoundary();
     333        86486 :         b.grow(2.);
     334        86486 :         const float cmin[2] = { (float)b.xmin(), (float)b.ymin() };
     335        86486 :         const float cmax[2] = { (float)b.xmax(), (float)b.ymax() };
     336        86486 :         myGrid.Insert(cmin, cmax, junction);
     337        86486 :         myBoundary.add(b);
     338        86486 :     }
     339         7274 :     myGrid.add(myBoundary);
     340              : 
     341        14548 :     if (OptionsCont::getOptions().isSet("alternative-net-file")) {
     342              :         // build secondary visualization tree
     343            0 :         for (GUIEdge* edge : myEdgeWrapper) {
     344            0 :             Boundary b;
     345            0 :             for (MSLane* lane : edge->getLanes()) {
     346            0 :                 b.add(static_cast<GUILane*>(lane)->getShape(true).getBoxBoundary());
     347              :             }
     348              :             // make sure persons are always drawn and selectable since they depend on their edge being drawn
     349            0 :             b.grow(MSPModel::SIDEWALK_OFFSET + 1);
     350            0 :             const float cmin[2] = { (float)b.xmin(), (float)b.ymin() };
     351            0 :             const float cmax[2] = { (float)b.xmax(), (float)b.ymax() };
     352            0 :             myGrid2.Insert(cmin, cmax, edge);
     353            0 :         }
     354            0 :         for (std::vector<GUIJunctionWrapper*>::iterator i = myJunctionWrapper.begin(); i != myJunctionWrapper.end(); ++i) {
     355            0 :             GUIJunctionWrapper* junction = *i;
     356            0 :             Position pos = junction->getJunction().getPosition(true);
     357            0 :             Boundary b = Boundary(pos.x() - 3., pos.y() - 3., pos.x() + 3., pos.y() + 3.);
     358            0 :             const float cmin[2] = { (float)b.xmin(), (float)b.ymin() };
     359            0 :             const float cmax[2] = { (float)b.xmax(), (float)b.ymax() };
     360            0 :             myGrid2.Insert(cmin, cmax, junction);
     361            0 :         }
     362              :     }
     363         7274 : }
     364              : 
     365              : 
     366              : void
     367         3006 : GUINet::registerRenderedObject(GUIGlObject* o) {
     368         3006 :     getVisualisationSpeedUp().addAdditionalGLObject(o);
     369         6012 :     if (OptionsCont::getOptions().isSet("alternative-net-file")) {
     370            0 :         GUIGlobals::gSecondaryShape = true;
     371            0 :         myGrid2.addAdditionalGLObject(o);
     372            0 :         GUIGlobals::gSecondaryShape = false;
     373              :     }
     374         3006 : }
     375              : 
     376              : 
     377              : int
     378            0 : GUINet::getWholeDuration() const {
     379            0 :     return myLastSimDuration +/*myLastVisDuration+*/myLastIdleDuration;
     380              : }
     381              : 
     382              : 
     383              : int
     384            0 : GUINet::getSimDuration() const {
     385            0 :     return myLastSimDuration;
     386              : }
     387              : 
     388              : /*
     389              : int
     390              : GUINet::getVisDuration() const
     391              : {
     392              :     return myLastVisDuration;
     393              : }
     394              : */
     395              : 
     396              : 
     397              : double
     398            0 : GUINet::getRTFactor() const {
     399            0 :     if (myLastSimDuration == 0) {
     400              :         return -1;
     401              :     }
     402            0 :     return (double)DELTA_T / (double)myLastSimDuration;
     403              : }
     404              : 
     405              : 
     406              : double
     407            0 : GUINet::getUPS() const {
     408            0 :     if (myLastSimDuration == 0) {
     409              :         return -1;
     410              :     }
     411            0 :     return (double) myLastVehicleMovementCount / (double) myLastSimDuration * (double) 1000.;
     412              : }
     413              : 
     414              : 
     415              : double
     416            0 : GUINet::getMeanRTFactor(int duration) const {
     417            0 :     if (myOverallSimDuration == 0) {
     418              :         return -1;
     419              :     }
     420            0 :     return ((double)(duration) * (double) 1000. / (double)myOverallSimDuration);
     421              : }
     422              : 
     423              : 
     424              : double
     425            0 : GUINet::getMeanUPS() const {
     426            0 :     if (myOverallSimDuration == 0) {
     427              :         return -1;
     428              :     }
     429            0 :     return ((double)myVehiclesMoved / (double)myOverallSimDuration * (double) 1000.);
     430              : }
     431              : 
     432              : 
     433              : int
     434            0 : GUINet::getIdleDuration() const {
     435            0 :     return myLastIdleDuration;
     436              : }
     437              : 
     438              : 
     439              : void
     440      5836494 : GUINet::setSimDuration(int val) {
     441      5836494 :     myLastSimDuration = val;
     442      5836494 :     myOverallSimDuration += val;
     443      5836494 :     myLastVehicleMovementCount = getVehicleControl().getRunningVehicleNo();
     444      5836494 :     myOverallVehicleCount += myLastVehicleMovementCount;
     445      5836494 : }
     446              : 
     447              : /*
     448              : void
     449              : GUINet::setVisDuration(int val)
     450              : {
     451              :     myLastVisDuration = val;
     452              : }
     453              : */
     454              : 
     455              : void
     456      5829447 : GUINet::setIdleDuration(int val) {
     457      5829447 :     myLastIdleDuration = val;
     458      5829447 : }
     459              : 
     460              : 
     461              : GUIGLObjectPopupMenu*
     462            0 : GUINet::getPopUpMenu(GUIMainWindow& app,
     463              :                      GUISUMOAbstractView& parent) {
     464            0 :     GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
     465            0 :     buildPopupHeader(ret, app);
     466            0 :     buildCenterPopupEntry(ret);
     467            0 :     buildShowParamsPopupEntry(ret);
     468            0 :     buildPositionCopyEntry(ret, app);
     469            0 :     if (GeoConvHelper::getFinal().usingGeoProjection()) {
     470            0 :         GUIDesigns::buildFXMenuCommand(ret, TL("Copy view geo-boundary to clipboard"), nullptr, ret, MID_COPY_VIEW_GEOBOUNDARY);
     471              :     }
     472            0 :     return ret;
     473              : }
     474              : 
     475              : 
     476              : GUIParameterTableWindow*
     477            0 : GUINet::getParameterWindow(GUIMainWindow& app,
     478              :                            GUISUMOAbstractView& parent) {
     479            0 :     GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
     480              :     // add items
     481            0 :     ret->mkItem(TL("loaded vehicles [#]"), true,
     482            0 :                 new FunctionBinding<MSVehicleControl, int>(&getVehicleControl(), &MSVehicleControl::getLoadedVehicleNo));
     483            0 :     ret->mkItem(TL("insertion-backlogged vehicles [#]"), true,
     484            0 :                 new FunctionBinding<MSInsertionControl, int>(&getInsertionControl(), &MSInsertionControl::getWaitingVehicleNo));
     485            0 :     ret->mkItem(TL("departed vehicles [#]"), true,
     486            0 :                 new FunctionBinding<MSVehicleControl, int>(&getVehicleControl(), &MSVehicleControl::getDepartedVehicleNo));
     487            0 :     ret->mkItem(TL("running vehicles [#]"), true,
     488            0 :                 new FunctionBinding<MSVehicleControl, int>(&getVehicleControl(), &MSVehicleControl::getRunningVehicleNo));
     489            0 :     ret->mkItem(TL("arrived vehicles [#]"), true,
     490            0 :                 new FunctionBinding<MSVehicleControl, int>(&getVehicleControl(), &MSVehicleControl::getArrivedVehicleNo));
     491            0 :     ret->mkItem(TL("discarded vehicles [#]"), true,
     492            0 :                 new FunctionBinding<MSVehicleControl, int>(&getVehicleControl(), &MSVehicleControl::getDiscardedVehicleNo));
     493            0 :     ret->mkItem(TL("collisions [#]"), true,
     494            0 :                 new FunctionBinding<MSVehicleControl, int>(&getVehicleControl(), &MSVehicleControl::getCollisionCount));
     495            0 :     ret->mkItem(TL("teleports [#]"), true,
     496            0 :                 new FunctionBinding<MSVehicleControl, int>(&getVehicleControl(), &MSVehicleControl::getTeleportCount));
     497            0 :     ret->mkItem(TL("halting [#]"), true,
     498            0 :                 new FunctionBinding<MSVehicleControl, int>(&getVehicleControl(), &MSVehicleControl::getHaltingVehicleNo));
     499            0 :     ret->mkItem(TL("stopped [#]"), true,
     500            0 :                 new FunctionBinding<MSVehicleControl, int>(&getVehicleControl(), &MSVehicleControl::getStoppedVehiclesCount));
     501            0 :     ret->mkItem(TL("avg. speed [m/s]"), true,
     502            0 :                 new FunctionBinding<MSVehicleControl, double>(&getVehicleControl(), &MSVehicleControl::getVehicleMeanSpeed));
     503            0 :     ret->mkItem(TL("avg. relative speed"), true,
     504            0 :                 new FunctionBinding<MSVehicleControl, double>(&getVehicleControl(), &MSVehicleControl::getVehicleMeanSpeedRelative));
     505            0 :     if (myPersonControl != nullptr) {
     506            0 :         ret->mkItem(TL("loaded persons [#]"), true,
     507            0 :                     new FunctionBinding<MSTransportableControl, int>(&getPersonControl(), &MSTransportableControl::getLoadedNumber));
     508            0 :         ret->mkItem(TL("running persons [#]"), true,
     509            0 :                     new FunctionBinding<MSTransportableControl, int>(&getPersonControl(), &MSTransportableControl::getRunningNumber));
     510            0 :         ret->mkItem(TL("jammed persons [#]"), true,
     511            0 :                     new FunctionBinding<MSTransportableControl, int>(&getPersonControl(), &MSTransportableControl::getJammedNumber));
     512              :     }
     513            0 :     ret->mkItem(TL("end time [s]"), false, OptionsCont::getOptions().getString("end"));
     514            0 :     ret->mkItem(TL("begin time [s]"), false, OptionsCont::getOptions().getString("begin"));
     515              : //    ret->mkItem(TL("time step [s]"), true, new FunctionBinding<GUINet, SUMOTime>(this, &GUINet::getCurrentTimeStep));
     516            0 :     if (logSimulationDuration()) {
     517            0 :         ret->mkItem(TL("step duration [ms]"), true, new FunctionBinding<GUINet, int>(this, &GUINet::getWholeDuration));
     518            0 :         ret->mkItem(TL("FPS"), true, new FunctionBinding<GUISUMOAbstractView, double>(&parent, &GUISUMOAbstractView::getFPS));
     519            0 :         ret->mkItem(TL("simulation duration [ms]"), true, new FunctionBinding<GUINet, int>(this, &GUINet::getSimDuration));
     520              :         /*
     521              :         ret->mkItem(TL("visualisation duration [ms]"), true,
     522              :             new CastingFunctionBinding<GUINet, double, int>(
     523              :                 &(getNet()), &GUINet::getVisDuration));
     524              :         */
     525            0 :         ret->mkItem(TL("idle duration [ms]"), true, new FunctionBinding<GUINet, int>(this, &GUINet::getIdleDuration));
     526            0 :         ret->mkItem(TL("duration factor"), true, new FunctionBinding<GUINet, double>(this, &GUINet::getRTFactor));
     527              :         /*
     528              :         ret->mkItem(TL("mean duration factor []"), true,
     529              :             new FuncBinding_IntParam<GUINet, double>(
     530              :                 &(getNet()), &GUINet::getMeanRTFactor), 1);
     531              :                 */
     532            0 :         ret->mkItem(TL("updates per second"), true, new FunctionBinding<GUINet, double>(this, &GUINet::getUPS));
     533            0 :         ret->mkItem(TL("avg. updates per second"), true, new FunctionBinding<GUINet, double>(this, &GUINet::getMeanUPS));
     534              :     }
     535            0 :     if (OptionsCont::getOptions().isSet("tripinfo-output") || OptionsCont::getOptions().getBool("duration-log.statistics")) {
     536            0 :         ret->mkItem(TL("avg. trip length [m]"), true, new FunctionBinding<GUINet, double>(this, &GUINet::getAvgRouteLength));
     537            0 :         ret->mkItem(TL("avg. trip duration [s]"), true, new FunctionBinding<GUINet, double>(this, &GUINet::getAvgDuration));
     538            0 :         ret->mkItem(TL("avg. trip waiting time [s]"), true, new FunctionBinding<GUINet, double>(this, &GUINet::getAvgWaitingTime));
     539            0 :         ret->mkItem(TL("avg. trip time loss [s]"), true, new FunctionBinding<GUINet, double>(this, &GUINet::getAvgTimeLoss));
     540            0 :         ret->mkItem(TL("avg. trip depart delay [s]"), true, new FunctionBinding<GUINet, double>(this, &GUINet::getAvgDepartDelay));
     541            0 :         ret->mkItem(TL("avg. trip speed [m/s]"), true, new FunctionBinding<GUINet, double>(this, &GUINet::getAvgTripSpeed));
     542            0 :         if (myPersonControl != nullptr) {
     543            0 :             ret->mkItem(TL("avg. walk length [m]"), true, new FunctionBinding<GUINet, double>(this, &GUINet::getAvgWalkRouteLength));
     544            0 :             ret->mkItem(TL("avg. walk duration [s]"), true, new FunctionBinding<GUINet, double>(this, &GUINet::getAvgWalkDuration));
     545            0 :             ret->mkItem(TL("avg. walk time loss [s]"), true, new FunctionBinding<GUINet, double>(this, &GUINet::getAvgWalkTimeLoss));
     546              :         }
     547              :     }
     548            0 :     ret->mkItem(TL("nodes [#]"), false, (int)getJunctionIDs(false).size());
     549            0 :     ret->mkItem(TL("edges [#]"), false, (int)GUIEdge::getIDs(false).size());
     550            0 :     ret->mkItem(TL("total edge length [km]"), false, GUIEdge::getTotalLength(false, false) / 1000);
     551            0 :     ret->mkItem(TL("total lane length [km]"), false, GUIEdge::getTotalLength(false, true) / 1000);
     552            0 :     ret->mkItem(TL("network version "), false, toString(myVersion));
     553              : 
     554              :     // close building
     555            0 :     ret->closeBuilding();
     556            0 :     return ret;
     557              : }
     558              : 
     559              : 
     560              : void
     561            0 : GUINet::drawGL(const GUIVisualizationSettings& /*s*/) const {
     562            0 : }
     563              : 
     564              : 
     565              : Boundary
     566            0 : GUINet::getCenteringBoundary() const {
     567            0 :     return getBoundary();
     568              : }
     569              : 
     570              : 
     571              : GUINet*
     572       873429 : GUINet::getGUIInstance() {
     573       873429 :     GUINet* net = dynamic_cast<GUINet*>(MSNet::getInstance());
     574       873429 :     if (net != nullptr) {
     575       873429 :         return net;
     576              :     }
     577            0 :     throw ProcessError("A gui-network was not yet constructed.");
     578              : }
     579              : 
     580              : 
     581              : GUIVehicleControl*
     582            0 : GUINet::getGUIVehicleControl() {
     583            0 :     return dynamic_cast<GUIVehicleControl*>(myVehicleControl);
     584              : }
     585              : 
     586              : 
     587              : void
     588            3 : GUINet::lock() {
     589            3 :     myLock.lock();
     590            3 : }
     591              : 
     592              : 
     593              : void
     594            3 : GUINet::unlock() {
     595            3 :     myLock.unlock();
     596            3 : }
     597              : 
     598              : GUIMEVehicleControl*
     599       323253 : GUINet::getGUIMEVehicleControl() {
     600       323253 :     return dynamic_cast<GUIMEVehicleControl*>(myVehicleControl);
     601              : }
     602              : 
     603              : 
     604              : double
     605            0 : GUINet::getEdgeData(const MSEdge* edge, const std::string& attr) {
     606              :     auto it = myLoadedEdgeData.find(attr);
     607            0 :     if (it != myLoadedEdgeData.end()) {
     608              :         double value;
     609            0 :         bool found = it->second->retrieveExistingEffort(edge, STEPS2TIME(getCurrentTimeStep()), value);
     610            0 :         if (found) {
     611            0 :             return value;
     612              :         } else {
     613            0 :             return GUIVisualizationSettings::MISSING_DATA;
     614              :         }
     615              :     } else {
     616            0 :         return GUIVisualizationSettings::MISSING_DATA;
     617              :     }
     618              : }
     619              : 
     620              : 
     621              : double
     622            0 : GUINet::getMeanData(const MSLane* lane, const std::string& id, const std::string& attr) {
     623            0 :     auto item = myDetectorControl->getMeanData().find(id);
     624            0 :     if (item != myDetectorControl->getMeanData().end() && !item->second.empty()) {
     625            0 :         SumoXMLAttr a = (SumoXMLAttr)SUMOXMLDefinitions::Attrs.get(attr);
     626            0 :         return item->second.front()->getAttributeValue(lane, a, GUIVisualizationSettings::MISSING_DATA);
     627              :     } else {
     628            0 :         return GUIVisualizationSettings::MISSING_DATA;
     629              :     }
     630              : }
     631              : 
     632              : 
     633              : void
     634            0 : GUINet::DiscoverAttributes::myStartElement(int element, const SUMOSAXAttributes& attrs) {
     635            0 :     if (element == SUMO_TAG_EDGE || element == SUMO_TAG_LANE) {
     636            0 :         std::vector<std::string> tmp = attrs.getAttributeNames();
     637              :         edgeAttrs.insert(tmp.begin(), tmp.end());
     638            0 :     } else if (element == SUMO_TAG_EDGEREL) {
     639            0 :         for (const std::string& a : attrs.getAttributeNames()) {
     640            0 :             if (a != "from" && a != "to") {
     641              :                 edgeAttrs.insert(a);
     642              :             }
     643            0 :         }
     644            0 :     } else if (element == SUMO_TAG_INTERVAL) {
     645              :         bool ok;
     646            0 :         numIntervals++;
     647            0 :         firstIntervalBegin = MIN2(firstIntervalBegin, attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, nullptr, ok));
     648            0 :         lastIntervalEnd = MAX2(lastIntervalEnd, attrs.getSUMOTimeReporting(SUMO_ATTR_END, nullptr, ok));
     649              :     }
     650            0 : }
     651              : 
     652              : 
     653              : std::vector<std::string>
     654            0 : GUINet::DiscoverAttributes::getEdgeAttrs() {
     655            0 :     edgeAttrs.erase(toString(SUMO_ATTR_ID));
     656            0 :     return std::vector<std::string>(edgeAttrs.begin(), edgeAttrs.end());
     657              : }
     658              : 
     659              : 
     660              : void
     661            0 : GUINet::EdgeFloatTimeLineRetriever_GUI::addEdgeWeight(const std::string& id,
     662              :         double value, double begTime, double endTime) const {
     663            0 :     MSEdge* const edge = MSEdge::dictionary(id);
     664            0 :     if (edge != nullptr) {
     665            0 :         myWeightStorage->addEffort(edge, begTime, endTime, value);
     666              :     } else {
     667            0 :         WRITE_WARNINGF(TL("Trying to set data value for the unknown edge '%'."), id);
     668              :     }
     669            0 : }
     670              : 
     671              : 
     672              : void
     673            0 : GUINet::EdgeFloatTimeLineRetriever_GUI::addEdgeRelWeight(const std::string& from, const std::string& to,
     674              :         double val, double beg, double end) const {
     675            0 :     MSEdge* const fromEdge = MSEdge::dictionary(from);
     676            0 :     MSEdge* const toEdge = MSEdge::dictionary(to);
     677              :     bool haveRel = false;
     678            0 :     if (fromEdge != nullptr && toEdge != nullptr) {
     679            0 :         for (auto item : fromEdge->getViaSuccessors()) {
     680            0 :             if (item.first == toEdge) {
     681              :                 const MSEdge* edge = item.second;
     682            0 :                 while (edge != nullptr && edge->isInternal()) {
     683            0 :                     myWeightStorage->addEffort(edge, beg, end, val);
     684            0 :                     edge = edge->getViaSuccessors().front().second;
     685              :                     haveRel = true;
     686              :                 }
     687              :             }
     688              :         }
     689              :     }
     690            0 :     if (!haveRel) {
     691            0 :         WRITE_WARNINGF(TL("Trying to set data value for the unknown relation from edge '%' to edge '%'."), from, to);
     692              :     }
     693            0 : }
     694              : 
     695              : 
     696              : bool
     697            0 : GUINet::loadEdgeData(const std::string& file) {
     698              :     // discover edge attributes
     699            0 :     DiscoverAttributes discoveryHandler(file);
     700            0 :     XMLSubSys::runParser(discoveryHandler, file);
     701            0 :     std::vector<std::string> attrs = discoveryHandler.getEdgeAttrs();
     702            0 :     WRITE_MESSAGE("Loading edgedata from '" + file + "':"
     703              :                   + "\n    " + toString(discoveryHandler.numIntervals) + " intervals between"
     704              :                   + " " + time2string(discoveryHandler.firstIntervalBegin) + " and"
     705              :                   + " " + time2string(discoveryHandler.lastIntervalEnd)
     706              :                   + ".\n    Found " + toString(attrs.size())
     707              :                   + " attributes: " + toString(attrs));
     708            0 :     if (discoveryHandler.lastIntervalEnd < string2time(OptionsCont::getOptions().getString("begin"))) {
     709            0 :         WRITE_WARNING(TL("No data defined after simulation begin time."));
     710              :     }
     711            0 :     myEdgeDataEndTime = MAX2(myEdgeDataEndTime, discoveryHandler.lastIntervalEnd);
     712              :     // create a retriever for each attribute
     713              :     std::vector<EdgeFloatTimeLineRetriever_GUI> retrieverDefsInternal;
     714            0 :     retrieverDefsInternal.reserve(attrs.size());
     715              :     std::vector<SAXWeightsHandler::ToRetrieveDefinition*> retrieverDefs;
     716            0 :     for (const std::string& attr : attrs) {
     717            0 :         MSEdgeWeightsStorage* ws = new MSEdgeWeightsStorage();
     718            0 :         myLoadedEdgeData[attr] = ws;
     719            0 :         retrieverDefsInternal.push_back(EdgeFloatTimeLineRetriever_GUI(ws));
     720            0 :         retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition(attr, true, retrieverDefsInternal.back()));
     721              :     }
     722            0 :     SAXWeightsHandler handler(retrieverDefs, "");
     723            0 :     return XMLSubSys::runParser(handler, file);
     724            0 : }
     725              : 
     726              : 
     727              : std::vector<std::string>
     728            0 : GUINet::getEdgeDataAttrs() const {
     729              :     std::vector<std::string> result;
     730            0 :     for (const auto& item : myLoadedEdgeData) {
     731            0 :         result.push_back(item.first);
     732              :     }
     733            0 :     return result;
     734            0 : }
     735              : 
     736              : 
     737              : std::vector<std::string>
     738            0 : GUINet::getMeanDataIDs() const {
     739              :     std::vector<std::string> result;
     740              : 
     741            0 :     for (auto item : myDetectorControl->getMeanData()) {
     742            0 :         result.push_back(item.first);
     743              :     }
     744            0 :     std::sort(result.begin(), result.end());
     745            0 :     return result;
     746            0 : }
     747              : 
     748              : std::vector<std::string>
     749            0 : GUINet::getMeanDataAttrs(const std::string& meanDataID) const {
     750            0 :     auto item = myDetectorControl->getMeanData().find(meanDataID);
     751            0 :     if (item != myDetectorControl->getMeanData().end() && !item->second.empty()) {
     752            0 :         return item->second.front()->getAttributeNames();
     753              :     } else {
     754            0 :         return std::vector<std::string>();
     755              :     }
     756              : }
     757              : 
     758              : 
     759              : bool
     760            0 : GUINet::isSelected(const MSTrafficLightLogic* tll) const {
     761              :     const auto it = myLogics2Wrapper.find(const_cast<MSTrafficLightLogic*>(tll));
     762            0 :     return it != myLogics2Wrapper.end() && gSelected.isSelected(GLO_TLLOGIC, it->second->getGlID());
     763              : }
     764              : 
     765              : void
     766           34 : GUINet::updateGUI() const {
     767              :     try {
     768              :         // gui only
     769           34 :         GUIApplicationWindow* aw = static_cast<GUIApplicationWindow*>(GUIMainWindow::getInstance());
     770              :         // update the view
     771           34 :         aw->handleEvent_SimulationStep(nullptr);
     772            0 :     } catch (ProcessError&) { }
     773           34 : }
     774              : 
     775              : void
     776            0 : GUINet::addHotkey(int key, Command* press, Command* release) {
     777              :     try {
     778              :         // gui only
     779            0 :         GUIApplicationWindow* aw = static_cast<GUIApplicationWindow*>(GUIMainWindow::getInstance());
     780              :         // update the view
     781            0 :         aw->addHotkey(key, press, release);
     782            0 :     } catch (ProcessError&) { }
     783            0 : }
     784              : 
     785              : void
     786            0 : GUINet::flushOutputsAtEnd() {
     787            0 :     mySkipFinalReset = true;
     788            0 :     myDetectorControl->close(SIMSTEP);
     789            0 :     OutputDevice::flushAll();
     790              :     // update tracker windows
     791            0 :     guiSimulationStep();
     792            0 : }
     793              : 
     794              : #ifdef HAVE_OSG
     795              : void
     796        11672 : GUINet::updateColor(const GUIVisualizationSettings& s) {
     797       191421 :     for (std::vector<GUIEdge*>::const_iterator i = myEdgeWrapper.begin(); i != myEdgeWrapper.end(); ++i) {
     798       179749 :         if (!(*i)->isInternal()) {
     799              :             const std::vector<MSLane*>& lanes = (*i)->getLanes();
     800       209698 :             for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
     801       134097 :                 static_cast<GUILane*>(*j)->updateColor(s);
     802              :             }
     803              :         }
     804              :     }
     805        97554 :     for (std::vector<GUIJunctionWrapper*>::iterator i = myJunctionWrapper.begin(); i != myJunctionWrapper.end(); ++i) {
     806        85882 :         (*i)->updateColor(s);
     807              :     }
     808        11672 : }
     809              : #endif
     810              : 
     811              : 
     812              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1