/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 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;262263264/// @name locator-methods265//@{266267/* @brief Returns the gl-ids of all junctions within the net268* @param[in] includeInternal Whether to include ids of internal junctions269*/270std::vector<GUIGlID> getJunctionIDs(bool includeInternal) const;271272/// Returns the gl-ids of all traffic light logics within the net273std::vector<GUIGlID> getTLSIDs() const;274//@}275276277/// Initialises gui wrappers278void initGUIStructures();279280281/** @brief Returns the RTree used for visualisation speed-up282* @return The visualisation speed-up283*/284SUMORTree& getVisualisationSpeedUp() {285return myGrid;286}287288289/** @brief Returns the RTree used for visualisation speed-up290* @return The visualisation speed-up291*/292const SUMORTree& getVisualisationSpeedUp(bool secondary = false) const {293return secondary ? myGrid2 : myGrid;294}295296/// @brief add object into rtree297void registerRenderedObject(GUIGlObject* o);298299/** @brief Returns the vehicle control300* @return The vehicle control301* @see MSVehicleControl302* @see myVehicleControl303*/304GUIVehicleControl* getGUIVehicleControl();305306/** @brief Returns the vehicle control307* @return The vehicle control308* @see MSVehicleControl309* @see myVehicleControl310*/311GUIMEVehicleControl* getGUIMEVehicleControl();312313/// @brief retrieve loaded edged weight for the given attribute and the current simulation time314double getEdgeData(const MSEdge* edge, const std::string& attr);315316/// @brief retrieve live lane/edge weight for the given meanData id and attribute317double getMeanData(const MSLane* lane, const std::string& id, const std::string& attr);318319/// @brief load edgeData from file320bool loadEdgeData(const std::string& file);321322/// @brief return list of loaded edgeData attributes323std::vector<std::string> getEdgeDataAttrs() const;324325/// @brief return list of loaded edgeData ids (being computed in the current simulation)326std::vector<std::string> getMeanDataIDs() const;327328/// @brief return list of available attributes for the given meanData id329std::vector<std::string> getMeanDataAttrs(const std::string& meanDataID) const;330331#ifdef HAVE_OSG332void updateColor(const GUIVisualizationSettings& s);333#endif334335/// @brief grant exclusive access to the simulation state336void lock();337338/// @brief release exclusive access to the simulation state339void unlock();340341/** @brief Returns the pointer to the unique instance of GUINet (singleton).342* @return Pointer to the unique GUINet-instance343* @exception ProcessError If a network was not yet constructed344*/345static GUINet* getGUIInstance();346347/// @brief creates a wrapper for the given logic348void createTLWrapper(MSTrafficLightLogic* tll) override;349350/// @brief return wheter the given logic (or rather it's wrapper) is selected in the GUI351bool isSelected(const MSTrafficLightLogic* tll) const override;352353/// @brief update view after simulation.loadState354void updateGUI() const override;355356/// @brief register custom hotkey action357void addHotkey(int key, Command* press, Command* release = nullptr);358359/// @brief flush outputs once the simulation has reached its end360void flushOutputsAtEnd();361362virtual bool skipFinalReset() const override {363return mySkipFinalReset;364}365366private:367/// @brief Initialises the tl-logic map and wrappers368void initTLMap();369370friend class GUIOSGBuilder;371372protected:373/// @brief The visualization speed-up374LayeredRTree myGrid;375376/// @brief The visualization speed-up for secondary shapes377SUMORTree myGrid2;378379/// @brief The networks boundary380Boundary myBoundary;381382/// @brief Wrapped MS-edges383std::vector<GUIEdge*> myEdgeWrapper;384385/// @brief Wrapped MS-junctions386std::vector<GUIJunctionWrapper*> myJunctionWrapper;387388/// @brief A detector dictionary389std::vector<GUIDetectorWrapper*> myDetectorWrapper;390391/// @brief A calibrator dictionary392std::vector<GUICalibrator*> myCalibratorWrapper;393394/// @brief Definition of a link-to-logic-id map395typedef std::map<const MSLink*, std::string> Links2LogicMap;396/// @brief The link-to-logic-id map397Links2LogicMap myLinks2Logic;398399400/// @brief Definition of a traffic light-to-wrapper map401typedef std::map<MSTrafficLightLogic*, GUITrafficLightLogicWrapper*> Logics2WrapperMap;402/// @brief The traffic light-to-wrapper map403Logics2WrapperMap myLogics2Wrapper;404405406/// @brief The step durations (simulation, /*visualisation, */idle)407int myLastSimDuration, /*myLastVisDuration, */myLastIdleDuration;408409long myLastVehicleMovementCount, myOverallVehicleCount;410long myOverallSimDuration;411412/// @brief loaded edge data for visualization413std::map<std::string, MSEdgeWeightsStorage*> myLoadedEdgeData;414415bool mySkipFinalReset = false;416417/// @brief class for discovering edge attributes418class DiscoverAttributes : public SUMOSAXHandler {419public:420DiscoverAttributes(const std::string& file):421SUMOSAXHandler(file), firstIntervalBegin(SUMOTime_MAX), lastIntervalEnd(0), numIntervals(0) {};422~DiscoverAttributes() {};423void myStartElement(int element, const SUMOSAXAttributes& attrs);424std::vector<std::string> getEdgeAttrs();425SUMOTime firstIntervalBegin;426SUMOTime lastIntervalEnd;427int numIntervals;428private:429std::set<std::string> edgeAttrs;430};431432class EdgeFloatTimeLineRetriever_GUI : public SAXWeightsHandler::EdgeFloatTimeLineRetriever {433public:434/// @brief Constructor435EdgeFloatTimeLineRetriever_GUI(MSEdgeWeightsStorage* weightStorage) : myWeightStorage(weightStorage) {}436437/// @brief Destructor438~EdgeFloatTimeLineRetriever_GUI() { }439440/** @brief Adds an effort for a given edge and time period441*442* @param[in] id The id of the object to add a weight for443* @param[in] val The effort444* @param[in] beg The begin of the interval the weight is valid for445* @param[in] end The end of the interval the weight is valid for446* @see SAXWeightsHandler::EdgeFloatTimeLineRetriever::addEdgeWeight447*/448void addEdgeWeight(const std::string& id, double val, double beg, double end) const;449void addEdgeRelWeight(const std::string& from, const std::string& to, double val, double beg, double end) const;450451private:452/// @brief The storage that edges shall be added to453MSEdgeWeightsStorage* myWeightStorage;454455};456457private:458/// The mutex used to avoid concurrent updates of the vehicle buffer459mutable FXMutex myLock;460461};462463464