/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file GUINet.h14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @date Sept 200218///19// A MSNet extended by some values for usage within the gui20/****************************************************************************/21#pragma once22#include <config.h>2324#include <string>25#include <utility>26#include <microsim/MSNet.h>27#include <microsim/devices/MSDevice_Tripinfo.h>28#include <utils/geom/Boundary.h>29#include <utils/geom/Position.h>30#include <utils/xml/SUMOSAXHandler.h>31#include <utils/xml/SAXWeightsHandler.h>32#include <foreign/rtree/SUMORTree.h>33#include <foreign/rtree/LayeredRTree.h>34#include <utils/geom/PositionVector.h>35#include <utils/gui/globjects/GUIGlObjectStorage.h>36#include <utils/gui/globjects/GUIGLObjectPopupMenu.h>37#include <utils/gui/globjects/GUIGlObject.h>38#include <utils/gui/globjects/GUIGlObject_AbstractAdd.h>394041// ===========================================================================42// class declarations43// ===========================================================================44class MSEdgeControl;45class MSJunctionControl;46class MSTLLogicControl;47class MSTrafficLightLogic;48class MSLink;49class GUIJunctionWrapper;50class GUIDetectorWrapper;51class GUICalibrator;52class GUITrafficLightLogicWrapper;53class RGBColor;54class GUIEdge;55class OutputDevice;56class GUIVehicle;57class GUIVehicleControl;58class MSVehicleControl;59class GUIMEVehicleControl;60class Command;616263// ===========================================================================64// class definitions65// ===========================================================================66/**67* @class GUINet68* @brief A MSNet extended by some values for usage within the gui69*70* This gui version of the network allows the retrieval of some more71* information than the normal network version does. Due to this, not only72* these retrieval, but also some further initialisation methods must have73* been implemented. Nonethenless, this class has almost the same functions74* as the MSNet-class.75*76* Some microsimulation items are wrapped in certain classes to allow their77* drawing and their enumerated access. This enumeration is realised by78* inserting the wrapped items into vectors and is needed to fasten the79* network's drawing as only visible items are being drawn.80*/81class GUINet : public MSNet, public GUIGlObject {8283friend class GUITrafficLightLogicWrapper; // see createTLWrapper8485public:86/** @brief Constructor87* @param[in] vc The vehicle control to use88* @param[in] beginOfTimestepEvents The event control to use for simulation step begin events89* @param[in] endOfTimestepEvents The event control to use for simulation step end events90* @param[in] insertionEvents The event control to use for insertion events91* @exception ProcessError If a network was already constructed92*/93GUINet(MSVehicleControl* vc, MSEventControl* beginOfTimestepEvents,94MSEventControl* endOfTimestepEvents,95MSEventControl* insertionEvents);969798/// @brief Destructor99~GUINet();100101102/**103* @brief Returns whether this is a GUI Net104*/105bool isGUINet() const override {106return true;107}108109110/// @name inherited from GUIGlObject111//@{112113/** @brief Returns an own popup-menu114*115* @param[in] app The application needed to build the popup-menu116* @param[in] parent The parent window needed to build the popup-menu117* @return The built popup-menu118* @see GUIGlObject::getPopUpMenu119*/120GUIGLObjectPopupMenu* getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) override;121122/** @brief Returns an own parameter window123*124* @param[in] app The application needed to build the parameter window125* @param[in] parent The parent window needed to build the parameter window126* @return The built parameter window127* @see GUIGlObject::getParameterWindow128*/129GUIParameterTableWindow* getParameterWindow(GUIMainWindow& app, GUISUMOAbstractView& parent) override;130131/** @brief Returns the boundary to which the view shall be centered in order to show the object132*133* @return The boundary the object is within134* @see GUIGlObject::getCenteringBoundary135*/136Boundary getCenteringBoundary() const override;137138/** @brief Draws the object139* @param[in] s The settings for the current view (may influence drawing)140* @see GUIGlObject::drawGL141*/142void drawGL(const GUIVisualizationSettings& s) const override;143//@}144145146/// returns the bounder of the network147const Boundary& getBoundary() const;148149/// returns the position of a junction150Position getJunctionPosition(const std::string& name) const;151152/// returns the information whether the vehicle still exists153bool vehicleExists(const std::string& name) const;154155/// Some further steps needed for gui processing156void guiSimulationStep();157158/** @brief Performs a single simulation step (locking the simulation)159*/160void simulationStep();161162/// @name functions for performance measurements163/// @{164165/** @brief Returns the duration of the last step (sim+visualisation+idle) (in ms)166* @return How long it took to compute and display the last step167*/168int getWholeDuration() const;169170171/** @brief Returns the duration of the last step's simulation part (in ms)172* @return How long it took to compute the last step173*/174int getSimDuration() const;175176177/// Returns the simulation speed as a factor to real time178double getRTFactor() const;179180/// Returns the update per seconds rate181double getUPS() const;182183/// Returns the simulation speed as a factor to real time184double getMeanRTFactor(int duration) const;185186/// Returns the update per seconds rate187double getMeanUPS() const;188189// Returns the duration of the last step's visualisation part (in ms)190//int getVisDuration() const;191192/// Returns the duration of the last step's idle part (in ms)193int getIdleDuration() const;194195/// Sets the duration of the last step's simulation part196void setSimDuration(int val);197198// Sets the duration of the last step's visualisation part199//void setVisDuration(int val);200201/// Sets the duration of the last step's idle part202void setIdleDuration(int val);203//}204205double getAvgRouteLength() const {206return MSDevice_Tripinfo::getAvgRouteLength();207}208double getAvgDuration() const {209return MSDevice_Tripinfo::getAvgDuration();210}211double getAvgWaitingTime() const {212return MSDevice_Tripinfo::getAvgWaitingTime();213}214double getAvgTimeLoss() const {215return MSDevice_Tripinfo::getAvgTimeLoss();216}217double getAvgDepartDelay() const {218return MSDevice_Tripinfo::getAvgDepartDelay();219}220double getAvgTripSpeed() const {221return MSDevice_Tripinfo::getAvgDuration() != 0 ? MSDevice_Tripinfo::getAvgRouteLength() / MSDevice_Tripinfo::getAvgDuration() : 0;222}223double getAvgWalkRouteLength() const {224return MSDevice_Tripinfo::getAvgWalkRouteLength();225}226double getAvgWalkDuration() const {227return MSDevice_Tripinfo::getAvgWalkDuration();228}229double getAvgWalkTimeLoss() const {230return MSDevice_Tripinfo::getAvgWalkTimeLoss();231}232233/** @brief Returns the person control234*235* If the person control does not exist, yet, it is created.236*237* @return The person control238* @see MSPersonControl239* @see myPersonControl240*/241MSTransportableControl& getPersonControl() override;242243244/** @brief Returns the container control245*246* If the container control does not exist, yet, it is created.247*248* @return The container control249* @see MSContainerControl250* @see myContainerControl251*/252MSTransportableControl& getContainerControl() override;253254255/** Returns the gl-id of the traffic light that controls the given link256* valid only if the link is controlled by a tls */257int getLinkTLID(const MSLink* const link) const;258259/** Returns the index of the link within the junction that controls the given link;260* Returns -1 if the link is not controlled by a tls */261int getLinkTLIndex(const MSLink* const link) const;262263/** Returns the logic wrapper for the given tls if it exists */264GUITrafficLightLogicWrapper* getTLLWrapper(MSTrafficLightLogic* tll);265266/// @name locator-methods267//@{268269/* @brief Returns the gl-ids of all junctions within the net270* @param[in] includeInternal Whether to include ids of internal junctions271*/272std::vector<GUIGlID> getJunctionIDs(bool includeInternal) const;273274/// Returns the gl-ids of all traffic light logics within the net275std::vector<GUIGlID> getTLSIDs() const;276//@}277278279/// Initialises gui wrappers280void initGUIStructures();281282283/** @brief Returns the RTree used for visualisation speed-up284* @return The visualisation speed-up285*/286SUMORTree& getVisualisationSpeedUp() {287return myGrid;288}289290291/** @brief Returns the RTree used for visualisation speed-up292* @return The visualisation speed-up293*/294const SUMORTree& getVisualisationSpeedUp(bool secondary = false) const {295return secondary ? myGrid2 : myGrid;296}297298/// @brief add object into rtree299void registerRenderedObject(GUIGlObject* o);300301/** @brief Returns the vehicle control302* @return The vehicle control303* @see MSVehicleControl304* @see myVehicleControl305*/306GUIVehicleControl* getGUIVehicleControl();307308/** @brief Returns the vehicle control309* @return The vehicle control310* @see MSVehicleControl311* @see myVehicleControl312*/313GUIMEVehicleControl* getGUIMEVehicleControl();314315/// @brief retrieve loaded edged weight for the given attribute and the current simulation time316double getEdgeData(const MSEdge* edge, const std::string& attr);317318/// @brief retrieve live lane/edge weight for the given meanData id and attribute319double getMeanData(const MSLane* lane, const std::string& id, const std::string& attr);320321/// @brief load edgeData from file322bool loadEdgeData(const std::string& file);323324/// @brief return list of loaded edgeData attributes325std::vector<std::string> getEdgeDataAttrs() const;326327/// @brief return list of loaded edgeData ids (being computed in the current simulation)328std::vector<std::string> getMeanDataIDs() const;329330/// @brief return list of available attributes for the given meanData id331std::vector<std::string> getMeanDataAttrs(const std::string& meanDataID) const;332333#ifdef HAVE_OSG334void updateColor(const GUIVisualizationSettings& s);335#endif336337/// @brief grant exclusive access to the simulation state338void lock();339340/// @brief release exclusive access to the simulation state341void unlock();342343/** @brief Returns the pointer to the unique instance of GUINet (singleton).344* @return Pointer to the unique GUINet-instance345* @exception ProcessError If a network was not yet constructed346*/347static GUINet* getGUIInstance();348349/// @brief creates a wrapper for the given logic350void createTLWrapper(MSTrafficLightLogic* tll) override;351352/// @brief return wheter the given logic (or rather it's wrapper) is selected in the GUI353bool isSelected(const MSTrafficLightLogic* tll) const override;354355/// @brief update view after simulation.loadState356void updateGUI() const override;357358/// @brief register custom hotkey action359void addHotkey(int key, Command* press, Command* release = nullptr);360361/// @brief flush outputs once the simulation has reached its end362void flushOutputsAtEnd();363364virtual bool skipFinalReset() const override {365return mySkipFinalReset;366}367368private:369/// @brief Initialises the tl-logic map and wrappers370void initTLMap();371372friend class GUIOSGBuilder;373374protected:375/// @brief The visualization speed-up376LayeredRTree myGrid;377378/// @brief The visualization speed-up for secondary shapes379SUMORTree myGrid2;380381/// @brief The networks boundary382Boundary myBoundary;383384/// @brief Wrapped MS-edges385std::vector<GUIEdge*> myEdgeWrapper;386387/// @brief Wrapped MS-junctions388std::vector<GUIJunctionWrapper*> myJunctionWrapper;389390/// @brief A detector dictionary391std::vector<GUIDetectorWrapper*> myDetectorWrapper;392393/// @brief A calibrator dictionary394std::vector<GUICalibrator*> myCalibratorWrapper;395396/// @brief Definition of a link-to-logic-id map397typedef std::map<const MSLink*, std::string> Links2LogicMap;398/// @brief The link-to-logic-id map399Links2LogicMap myLinks2Logic;400401402/// @brief Definition of a traffic light-to-wrapper map403typedef std::map<MSTrafficLightLogic*, GUITrafficLightLogicWrapper*> Logics2WrapperMap;404/// @brief The traffic light-to-wrapper map405Logics2WrapperMap myLogics2Wrapper;406407408/// @brief The step durations (simulation, /*visualisation, */idle)409int myLastSimDuration, /*myLastVisDuration, */myLastIdleDuration;410411long myLastVehicleMovementCount, myOverallVehicleCount;412long myOverallSimDuration;413414/// @brief loaded edge data for visualization415std::map<std::string, MSEdgeWeightsStorage*> myLoadedEdgeData;416417bool mySkipFinalReset = false;418419/// @brief class for discovering edge attributes420class DiscoverAttributes : public SUMOSAXHandler {421public:422DiscoverAttributes(const std::string& file):423SUMOSAXHandler(file), firstIntervalBegin(SUMOTime_MAX), lastIntervalEnd(0), numIntervals(0) {};424~DiscoverAttributes() {};425void myStartElement(int element, const SUMOSAXAttributes& attrs);426std::vector<std::string> getEdgeAttrs();427SUMOTime firstIntervalBegin;428SUMOTime lastIntervalEnd;429int numIntervals;430private:431std::set<std::string> edgeAttrs;432};433434class EdgeFloatTimeLineRetriever_GUI : public SAXWeightsHandler::EdgeFloatTimeLineRetriever {435public:436/// @brief Constructor437EdgeFloatTimeLineRetriever_GUI(MSEdgeWeightsStorage* weightStorage) : myWeightStorage(weightStorage) {}438439/// @brief Destructor440~EdgeFloatTimeLineRetriever_GUI() { }441442/** @brief Adds an effort for a given edge and time period443*444* @param[in] id The id of the object to add a weight for445* @param[in] val The effort446* @param[in] beg The begin of the interval the weight is valid for447* @param[in] end The end of the interval the weight is valid for448* @see SAXWeightsHandler::EdgeFloatTimeLineRetriever::addEdgeWeight449*/450void addEdgeWeight(const std::string& id, double val, double beg, double end) const;451void addEdgeRelWeight(const std::string& from, const std::string& to, double val, double beg, double end) const;452453private:454/// @brief The storage that edges shall be added to455MSEdgeWeightsStorage* myWeightStorage;456457};458459private:460/// The mutex used to avoid concurrent updates of the vehicle buffer461mutable FXMutex myLock;462463};464465466