Path: blob/main/src/utils/gui/windows/GUISUMOAbstractView.h
169684 views
/****************************************************************************/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 GUISUMOAbstractView.h14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @author Andreas Gaubatz18/// @date Sept 200219///20// The base class for a view21/****************************************************************************/22#pragma once23#include <config.h>2425#include <string>26#include <vector>27#include <map>28#include <utils/foxtools/fxheader.h>29// fx3d includes windows.h so we need to guard against macro pollution30#ifdef WIN3231#define NOMINMAX32#endif33#include <fx3d.h>34#ifdef WIN3235#undef NOMINMAX36#endif3738#include <utils/geom/Boundary.h>39#include <utils/geom/Position.h>40#include <utils/common/RGBColor.h>41#include <utils/common/SUMOTime.h>42#include <utils/gui/globjects/GUIGlObjectTypes.h>43#include <foreign/rtree/SUMORTree.h>444546// ===========================================================================47// class declarations48// ===========================================================================49class GUIGlChildWindow;50class GUIVehicle;51class GUIPerspectiveChanger;52class GUIMainWindow;53class GUIGLObjectPopupMenu;54class GUIGlObject;55class GUIDialog_EditViewport;56class GUIDialog_ViewSettings;57class GUIVisualizationSettings;58class GUILane;5960/// @brief comparator for resolving clicks61struct ComparatorClickPriority {62bool operator()(const GUIGlObject* const a, const GUIGlObject* const b) const {63if (a->getClickPriority() == b->getClickPriority()) {64// sorty by GUIGlID as second criterion to simplify65// duplicate removal66return a->getGlID() > b->getGlID();67} else {68return a->getClickPriority() > b->getClickPriority();69}70}71};7273// ===========================================================================74// class definitions75// ===========================================================================76/**77* @class GUISUMOAbstractView78* This class is meant to be pure virtual later;79* It shall be the main class to inherit views of the simulation (micro-80* or macroscopic ones) from it.81*/82class GUISUMOAbstractView : public FXGLCanvas {83FXDECLARE(GUISUMOAbstractView)8485public:86/// @brief constructor87GUISUMOAbstractView(FXComposite* p, GUIMainWindow& app, GUIGlChildWindow* parent, const SUMORTree& grid, FXGLVisual* glVis, FXGLCanvas* share);8889/// @brief destructor90virtual ~GUISUMOAbstractView();9192/// @brief recalculate boundaries93virtual void recalculateBoundaries() { };9495/// @brief builds the view toolbars96virtual void buildViewToolBars(GUIGlChildWindow*) { }9798/// @brief recenters the view99virtual void recenterView();100101/** @brief centers to the chosen artifact102* @param[in] id The id of the artifact to center to103* @param[in] applyZoom Whether to zoom in104* @param[in] zoomDist The distance in m to use for the zoom, values < 0 means: use the centeringBoundary105* @note caller is responsible for calling update106*/107virtual void centerTo(GUIGlID id, bool applyZoom, double zoomDist = 20);108109/** @brief centers to the chosen position110* @param[in] pos Position to center view111* @param[in] applyZoom Whether to zoom in112* @param[in] zoomDist The distance in m to use for the zoom, values < 0 means: use the centeringBoundary113* @note caller is responsible for calling update114*/115virtual void centerTo(const Position& pos, bool applyZoom, double zoomDist = 20);116117/// @brief centers to the chosen artifact118void centerTo(const Boundary& bound);119120/// @brief applies the given viewport settings121virtual void setViewportFromToRot(const Position& lookFrom, const Position& lookAt, double rotation);122123/// @brief copy the viewport to the given view124virtual void copyViewportTo(GUISUMOAbstractView* view);125126/// @brief meter-to-pixels conversion method127double m2p(double meter) const;128129/// @brief pixels-to-meters conversion method130double p2m(double pixel) const;131132/// @brief get main window133GUIMainWindow* getMainWindow() const;134135/// @brief return windows cursor position136Position getWindowCursorPosition() const;137138/// @brief Returns the gl-id of the object under the given coordinates139void setWindowCursorPosition(FXint x, FXint y);140141/// @brief A reimplementation due to some internal reasons142FXbool makeCurrent();143144/// @brief returns true, if the edit button was pressed145bool isInEditMode();146147/// @brief get changer148GUIPerspectiveChanger& getChanger() const;149150/// @brief get visible boundary151Boundary getVisibleBoundary() const;152153/// @brief return whether this is a 3D view154virtual bool is3DView() const;155156/// @brief zoom interface for 3D view157virtual void zoom2Pos(Position& camera, Position& lookAt, double zoom);158159/// @brief mouse functions160//@{161virtual long onConfigure(FXObject*, FXSelector, void*);162virtual long onPaint(FXObject*, FXSelector, void*);163virtual long onLeftBtnPress(FXObject*, FXSelector, void*);164virtual long onLeftBtnRelease(FXObject*, FXSelector, void*);165virtual long onMiddleBtnPress(FXObject*, FXSelector, void*);166virtual long onMiddleBtnRelease(FXObject*, FXSelector, void*);167virtual long onRightBtnPress(FXObject*, FXSelector, void*);168virtual long onRightBtnRelease(FXObject*, FXSelector, void*);169virtual long onDoubleClicked(FXObject*, FXSelector, void*);170virtual long onMouseWheel(FXObject*, FXSelector, void*);171virtual long onMouseMove(FXObject*, FXSelector, void*);172virtual long onMouseLeft(FXObject*, FXSelector, void*);173//@}174175/// @brief keyboard functions176//@{177virtual long onKeyPress(FXObject* o, FXSelector sel, void* data);178virtual long onKeyRelease(FXObject* o, FXSelector sel, void* data);179//@}180181/// @brief interaction with the simulation182virtual long onCmdCloseLane(FXObject*, FXSelector, void*);183virtual long onCmdCloseEdge(FXObject*, FXSelector, void*);184virtual long onCmdAddRerouter(FXObject*, FXSelector, void*);185186/// @brief highlight edges according to reachability187virtual long onCmdShowReachability(FXObject*, FXSelector, void*);188189/// @brief hook to react on change in visualization settings190virtual long onVisualizationChange(FXObject*, FXSelector, void*);191192/// @brief filter out duplicate and forbidden objects193std::vector<GUIGlObject*> filterContextObjects(const std::vector<GUIGlObject*>& objects);194195/// @brief open object dialog at the cursor position196virtual void openObjectDialogAtCursor(const FXEvent* ev);197198/// @brief open object dialog for the given object199void openObjectDialog(const std::vector<GUIGlObject*>& objects, const bool filter = true);200201/// @brief A method that updates the tooltip202void updateToolTip();203204/// @brief @name Dealing with snapshots205///@{206207/** @brief Sets the snapshot time to file map208* @param[in] snaps The snapshots to take at certain times209* @param[in] w The snapshot image width210* @param[in] w The snapshot image height211*/212void addSnapshot(SUMOTime time, const std::string& file, const int w = -1, const int h = -1);213214/** @brief Takes a snapshots and writes it into the given file215*216* The format to use is determined from the extension.217* If compiled with ffmpeg and a video format is requested it will instantiate a video encoder.218* @param[in] destFile The name of the file to write the snapshot into219* @param[in] w The snapshot image width220* @param[in] w The snapshot image height221* @return The error message, if an error occurred; "" otherwise222*/223std::string makeSnapshot(const std::string& destFile, const int w = -1, const int h = -1);224225/// @brief Adds a frame to a video snapshot which will be initialized if necessary226virtual void saveFrame(const std::string& destFile, FXColor* buf);227228/// @brief Ends a video snapshot229virtual void endSnapshot() {}230231/// @brief Checks whether it is time for a snapshot232virtual void checkSnapshots();233234void waitForSnapshots(const SUMOTime snapshotTime);235236/// @brief get the current simulation time237virtual SUMOTime getCurrentTimeStep() const;238239///@}240241/// @brief get the viewport and create it on first access242GUIDialog_EditViewport* getViewportEditor();243244/// @brief update the viewport chooser with the current view values245virtual void updateViewportValues();246247/// @brief show viewport editor248virtual void showViewportEditor();249250/// @brief show viewsscheme editor251void showViewschemeEditor();252253/// @brief set color scheme254virtual bool setColorScheme(const std::string&);255256/// @brief get visualization settings (read only)257const GUIVisualizationSettings& getVisualisationSettings() const;258259/// @brief edit visualization settings (allow modify VisualizationSetings, use carefully)260GUIVisualizationSettings* editVisualisationSettings() const;261262/// @brief recalibrate color scheme according to the current value range263virtual void buildColorRainbow(const GUIVisualizationSettings& /*s*/, GUIColorScheme& /*scheme*/, int /*active*/, GUIGlObjectType /*objectType*/,264const GUIVisualizationRainbowSettings& /*rs*/) {265}266267/// @brief return list of loaded edgeData attributes268virtual std::vector<std::string> getEdgeDataAttrs() const {269return std::vector<std::string>();270}271272/// @brief return list of loaded edgeData ids (being computed in the current simulation)273virtual std::vector<std::string> getMeanDataIDs() const {274return std::vector<std::string>();275}276277/// @brief return list of available attributes for the given meanData id278virtual std::vector<std::string> getMeanDataAttrs(const std::string& meanDataID) const {279UNUSED_PARAMETER(meanDataID);280return std::vector<std::string>();281}282283/// @brief return list of loaded edgeRelation and tazRelation attributes284virtual std::vector<std::string> getRelDataAttrs() const {285return std::vector<std::string>();286}287288/// @brief return list of available edge parameters289virtual std::vector<std::string> getEdgeLaneParamKeys(bool /*edgeKeys*/) const {290return std::vector<std::string>();291}292293/// @brief return list of available vehicle parameters294virtual std::vector<std::string> getVehicleParamKeys(bool /*vTypeKeys*/) const {295return std::vector<std::string>();296}297298/// @brief return list of available vehicle parameters299virtual std::vector<std::string> getPOIParamKeys() const {300return std::vector<std::string>();301}302303/// @brief remove viewport304void remove(GUIDialog_EditViewport*);305306/// @brief remove view settings307void remove(GUIDialog_ViewSettings*);308309/// @brief get grid width310// @todo: check why this is here311double getGridWidth() const;312313/// @brief get grid height314// @todo: check why this is here315double getGridHeight() const;316317/// @brief star track318virtual void startTrack(int /*id*/);319320/// @brief stop track321virtual void stopTrack();322323/// @brief get tracked id324virtual GUIGlID getTrackedID() const;325326/// @brief on gaming click327virtual void onGamingClick(Position /*pos*/);328virtual void onGamingRightClick(Position /*pos*/);329330/// @brief @name Additional visualisations331///@{332333/** @brief Adds an object to call its additional visualisation method334* @param[in] which The object to add335* @return Always true336* @see GUIGlObject::drawGLAdditional337*/338bool addAdditionalGLVisualisation(GUIGlObject* const which);339340/** @brief Removes an object from the list of objects that show additional things341* @param[in] which The object to remove342* @return True if the object was known, false otherwise343* @see GUIGlObject::drawGLAdditional344*/345bool removeAdditionalGLVisualisation(GUIGlObject* const which);346347/** @brief Check if an object is added in the additional GL visualitation348* @param[in] which The object to check349* @see GUIGlObject::drawGLAdditional350*/351bool isAdditionalGLVisualisationEnabled(GUIGlObject* const which) const;352353///@}354355/// @brief ge the current popup-menu356GUIGLObjectPopupMenu* getPopup() const;357358/// @brief get position of current popup359const Position& getPopupPosition() const;360361/// @brief destroys the popup362void destroyPopup();363364/// @brief replace PopUp365void replacePopup(GUIGLObjectPopupMenu* popUp);366367///@struct Decal368/// @brief A decal (an image) that can be shown369struct Decal {370371/// @brief Constructor372Decal() {};373374/// @brief The path to the file the image is located at375std::string filename;376377/// @brief The center of the image in x-direction (net coordinates, in m)378double centerX = 0;379380/// @brief The center of the image in y-direction (net coordinates, in m)381double centerY = 0;382383/// @brief The center of the image in z-direction (net coordinates, in m)384double centerZ = 0;385386/// @brief The width of the image (net coordinates in x-direction, in m)387double width = 0;388389/// @brief The height of the image (net coordinates in y-direction, in m)390double height = 0;391392/// @brief The altitude of the image (net coordinates in z-direction, in m)393double altitude = 0;394395/// @brief The rotation of the image in the ground plane (in degrees)396double rot = 0;397398/// @brief The tilt of the image to the ground plane (in degrees)399double tilt = 0;400401/// @brief The roll of the image to the ground plane (in degrees)402double roll = 0;403404/// @brief The layer of the image405double layer = 0;406407/// @brief Whether this image was initialised (inserted as a texture)408bool initialised = false;409410/// @brief Whether this image should be skipped in 2D-views411bool skip2D = false;412413/// @brief Whether this image should be skipped in 2D-views414bool screenRelative = false;415416/// @brief whether the decal shall be drawn in screen coordinates, rather than network coordinates417int glID = -1;418419/// @brief The image pointer for later cleanup420FXImage* image = nullptr;421};422423/// @brief The list of decals to show424std::vector<Decal>& getDecals();425426/// @brief The mutex to use before accessing the decals list in order to avoid thread conflicts427FXMutex& getDecalsLockMutex();428429/// @brief get coloring schemes combo430MFXComboBoxIcon* getColoringSchemesCombo();431432/// @brief Returns the cursor's x/y position within the network433virtual Position getPositionInformation() const;434435/**@brief Returns a position that is mapped to the closest grid point if the grid is active436* @brief note: formats are pos(x,y,0) por pos(0,0,z)437*/438Position snapToActiveGrid(const Position& pos, bool snapXY = true) const;439440/// @brief Translate screen position to network position441Position screenPos2NetPos(int x, int y) const;442443/// @brief add decals444void addDecals(const std::vector<Decal>& decals);445446/// @brief Returns the delay of the parent application447double getDelay() const;448449/// @brief Sets the delay of the parent application450void setDelay(double delay);451452/// @brief Sets the breakpoints of the parent application453void setBreakpoints(const std::vector<SUMOTime>& breakpoints);454455/// @brief retrieve breakpoints if provided by the application456virtual const std::vector<SUMOTime> retrieveBreakpoints() const {457return std::vector<SUMOTime>();458}459460/// @brief retrieve FPS461double getFPS() const;462463/// @brief get GUIGlChildWindow464GUIGlChildWindow* getGUIGlChildWindow();465466/// @brief Draw (or not) the JuPedSim pedestrian network467/// @param s The visualization settings468virtual void drawPedestrianNetwork(const GUIVisualizationSettings& /*s*/) const { };469470/// @brief Change the color of the JuPedSim pedestrian network471/// @param s The visualization settings472virtual void changePedestrianNetworkColor(const GUIVisualizationSettings& /*s*/) const { };473474protected:475/// @brief FOX needs this476FOX_CONSTRUCTOR(GUISUMOAbstractView)477478/// @brief performs the painting of the simulation479void paintGL();480481/// @brief update position information labels482virtual void updatePositionInformationLabel() const;483484/// @brief paint GL485virtual int doPaintGL(int /*mode*/, const Boundary& /*boundary*/);486487/// @brief doInit488virtual void doInit();489490/// @brief paints a grid491void paintGLGrid() const;492493/// @brief Draws a line with ticks, and the length information.494void displayLegend();495496/// @brief Draws the configured legends497void displayLegends();498499/// @brief Draws a legend for the given scheme500void displayColorLegend(const GUIColorScheme& scheme, bool leftSide, const std::string& key);501502/// @brief Draws frames-per-second indicator503void drawFPS();504505/// @brief returns the GUILane at cursor position (implementation depends on view)506virtual GUILane* getLaneUnderCursor();507508/// @brief returns the id of object under cursor to show their tooltip509virtual GUIGlID getToolTipID();510511/// @brief returns the id of the front object under the cursor using GL_SELECT512GUIGlID getObjectUnderCursor(double sensitivity = SENSITIVITY);513514/// @brief returns the id of the objects under the cursor using GL_SELECT (including overlapped objects)515std::vector<GUIGlID> getObjectsUnderCursor();516517/// @brief returns the GUIGlObject under the cursor using GL_SELECT (including overlapped objects)518std::vector<GUIGlObject*> getGUIGlObjectsUnderCursor();519520/// @brief returns the GUIGlObject under the gripped cursor using GL_SELECT (including overlapped objects)521std::vector<GUIGlObject*> getGUIGlObjectsUnderSnappedCursor();522523/// @brief returns the id of the object at position using GL_SELECT524GUIGlID getObjectAtPosition(Position pos, double sensitivity = SENSITIVITY);525526/// @brief returns the ids of the object at position within the given (rectangular) radius using GL_SELECT527std::vector<GUIGlID> getObjectsAtPosition(Position pos, double radius);528529/// @brief returns the GUIGlObjects at position within the given (rectangular) radius using GL_SELECT530std::vector<GUIGlObject*> getGUIGlObjectsAtPosition(Position pos, double radius);531532/// @brief returns the ids of all objects in the given boundary533std::vector<GUIGlID> getObjectsInBoundary(Boundary bound);534535/// @brief filter internal lanes in Objects under cursor536std::vector<GUIGlObject*> filterInternalLanes(const std::vector<GUIGlObject*>& objects) const;537538/// @brief invokes the tooltip for the given object539bool showToolTipFor(const GUIGlID idToolTip);540541/// @brief Draws the stored decals542void drawDecals();543544/// @brief open popup dialog545void openPopupDialog();546547/// @brief helper function for buildColorRainbow548void buildMinMaxRainbow(const GUIVisualizationSettings& s, GUIColorScheme& scheme, const GUIVisualizationRainbowSettings& rs, double minValue, double maxValue, bool hasMissingData);549550/// @brief applies gl-transformations to fit the Boundary given by myChanger onto the canvas.551/// If fixRatio is true, this boundary will be enlarged to prevent anisotropic stretching.552/// (this should be set to false when doing selections)553Boundary applyGLTransform(bool fixRatio = true);554555/// @brief check whether we can read image data or position with gdal556FXImage* checkGDALImage(Decal& d);557558/// @brief The application559GUIMainWindow* myApp;560561/// @brief The parent window562GUIGlChildWindow* myGlChildWindowParent;563564/// @brief The visualization speed-up565const SUMORTree* myGrid;566567/// @brief The perspective changer568GUIPerspectiveChanger* myChanger = nullptr;569570/// @brief Panning flag571bool myPanning = false;572573/// @brief Information whether too-tip informations shall be generated574bool myInEditMode = false;575576/// @brief Offset to the mouse-hotspot from the mouse position577int myMouseHotspotX, myMouseHotspotY;578579/// @brief The current popup-menu580GUIGLObjectPopupMenu* myPopup = nullptr;581582/// @brief clicked poup position583Position myClickedPopupPosition = Position::INVALID;584585/// @brief The current popup-menu position586Position myPopupPosition = Position(0, 0);587588/// @brief vector with current objects dialog589std::vector<GUIGlObject*> myCurrentObjectsDialog;590591/// @brief visualization settings592GUIVisualizationSettings* myVisualizationSettings;593594/// @brief Internal information whether doInit() was called595bool myAmInitialised = false;596597/// @brief viewport chooser598GUIDialog_EditViewport* myGUIDialogEditViewport = nullptr;599600/// @brief Position of the cursor relative to the window601FXint myWindowCursorPositionX, myWindowCursorPositionY;602603/// @brief Visualization changer604GUIDialog_ViewSettings* myGUIDialogViewSettings = nullptr;605606/// @brief @name Optionally shown decals607///@{608609/// @brief The list of decals to show610std::vector<Decal> myDecals;611612/// @brief The mutex to use before accessing the decals list in order to avoid thread conflicts613FXMutex myDecalsLockMutex;614615///@}616617/// @brief Snapshots618std::map<SUMOTime, std::vector<std::tuple<std::string, int, int> > > mySnapshots;619620/// @brief The mutex to use before accessing the decals list in order to avoid thread conflicts621FXMutex mySnapshotsMutex;622623/// @brief the semaphore when waiting for snapshots to finish624FXCondition mySnapshotCondition;625626/// @brief poly draw lock627mutable FXMutex myPolyDrawLock;628629/// @brief List of objects for which GUIGlObject::drawGLAdditional is called630std::map<GUIGlObject*, int> myAdditionallyDrawn;631632/// @brief counter for measuring rendering time633long myFrameDrawTime = 0;634635// @brief sensitivity for "<>AtPosition(...) functions636static const double SENSITIVITY;637638private:639/// @brief struct used for sorting objects by layer640struct LayerObject : public std::pair<double, std::pair<GUIGlObjectType, std::string> > {641642public:643/// @brief constructor for shapes644LayerObject(double layer, GUIGlObject* object);645646/// @brief constructor for non-shape elements647LayerObject(GUIGlObject* object);648649/// @brief get GLObject650GUIGlObject* getGLObject() const;651652private:653/// @brief GLObject654GUIGlObject* myGLObject;655};656657};658659660