LCOV - code coverage report
Current view: top level - src/guisim - GUIPerson.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 95 339 28.0 %
Date: 2024-04-27 15:34:54 Functions: 18 49 36.7 %

          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    GUIPerson.cpp
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Jakob Erdmann
      17             : /// @author  Michael Behrisch
      18             : /// @date    Sept 2002
      19             : ///
      20             : // A MSPerson extended by some values for usage within the gui
      21             : /****************************************************************************/
      22             : #include <config.h>
      23             : 
      24             : #include <gui/GUIApplicationWindow.h>
      25             : #include <microsim/MSStoppingPlace.h>
      26             : #include <microsim/transportables/MSTransportableControl.h>
      27             : #include <microsim/logging/FunctionBinding.h>
      28             : #include <microsim/transportables/MSPModel_Striping.h>
      29             : #include <microsim/transportables/MSStageWaiting.h>
      30             : #include <microsim/transportables/MSStageWalking.h>
      31             : #include <utils/common/MsgHandler.h>
      32             : #include <utils/common/ScopedLocker.h>
      33             : #include <utils/gui/div/GLHelper.h>
      34             : #include <utils/gui/div/GUIGlobalSelection.h>
      35             : #include <utils/gui/div/GUIParameterTableWindow.h>
      36             : #include <utils/gui/globjects/GLIncludes.h>
      37             : #include <utils/gui/div/GUIBasePersonHelper.h>
      38             : #include <utils/gui/div/GUIDesigns.h>
      39             : 
      40             : #include "GUILane.h"
      41             : #include "GUIPerson.h"
      42             : 
      43             : //#define GUIPerson_DEBUG_DRAW_WALKINGAREA_PATHS 1
      44             : 
      45             : // ===========================================================================
      46             : // FOX callback mapping
      47             : // ===========================================================================
      48             : 
      49             : FXDEFMAP(GUIPerson::GUIPersonPopupMenu) GUIPersonPopupMenuMap[] = {
      50             :     FXMAPFUNC(SEL_COMMAND, MID_SHOW_CURRENTROUTE,     GUIPerson::GUIPersonPopupMenu::onCmdShowCurrentRoute),
      51             :     FXMAPFUNC(SEL_COMMAND, MID_HIDE_CURRENTROUTE,     GUIPerson::GUIPersonPopupMenu::onCmdHideCurrentRoute),
      52             :     FXMAPFUNC(SEL_COMMAND, MID_SHOW_WALKINGAREA_PATH, GUIPerson::GUIPersonPopupMenu::onCmdShowWalkingareaPath),
      53             :     FXMAPFUNC(SEL_COMMAND, MID_HIDE_WALKINGAREA_PATH, GUIPerson::GUIPersonPopupMenu::onCmdHideWalkingareaPath),
      54             :     FXMAPFUNC(SEL_COMMAND, MID_SHOWPLAN,              GUIPerson::GUIPersonPopupMenu::onCmdShowPlan),
      55             :     FXMAPFUNC(SEL_COMMAND, MID_START_TRACK,           GUIPerson::GUIPersonPopupMenu::onCmdStartTrack),
      56             :     FXMAPFUNC(SEL_COMMAND, MID_STOP_TRACK,            GUIPerson::GUIPersonPopupMenu::onCmdStopTrack),
      57             :     FXMAPFUNC(SEL_COMMAND, MID_REMOVE_OBJECT,         GUIPerson::GUIPersonPopupMenu::onCmdRemoveObject),
      58             : };
      59             : 
      60             : // Object implementation
      61           0 : FXIMPLEMENT(GUIPerson::GUIPersonPopupMenu, GUIGLObjectPopupMenu, GUIPersonPopupMenuMap, ARRAYNUMBER(GUIPersonPopupMenuMap))
      62             : 
      63             : // ===========================================================================
      64             : // method definitions
      65             : // ===========================================================================
      66             : 
      67             : // -------------------------------------------------------------------------
      68             : // GUIPerson::GUIPersonPopupMenu - methods
      69             : // -------------------------------------------------------------------------
      70             : 
      71           0 : GUIPerson::GUIPersonPopupMenu::GUIPersonPopupMenu(
      72           0 :     GUIMainWindow& app, GUISUMOAbstractView& parent, GUIGlObject& o) :
      73           0 :     GUIGLObjectPopupMenu(app, parent, o) {
      74           0 : }
      75             : 
      76             : 
      77           0 : GUIPerson::GUIPersonPopupMenu::~GUIPersonPopupMenu() {}
      78             : 
      79             : 
      80             : long
      81           0 : GUIPerson::GUIPersonPopupMenu::onCmdShowCurrentRoute(FXObject*, FXSelector, void*) {
      82             :     assert(myObject->getType() == GLO_PERSON);
      83           0 :     if (!static_cast<GUIPerson*>(myObject)->hasActiveAddVisualisation(myParent, VO_SHOW_ROUTE)) {
      84           0 :         static_cast<GUIPerson*>(myObject)->addActiveAddVisualisation(myParent, VO_SHOW_ROUTE);
      85             :     }
      86           0 :     return 1;
      87             : }
      88             : 
      89             : 
      90             : long
      91           0 : GUIPerson::GUIPersonPopupMenu::onCmdHideCurrentRoute(FXObject*, FXSelector, void*) {
      92             :     assert(myObject->getType() == GLO_PERSON);
      93           0 :     static_cast<GUIPerson*>(myObject)->removeActiveAddVisualisation(myParent, VO_SHOW_ROUTE);
      94           0 :     return 1;
      95             : }
      96             : 
      97             : 
      98             : long
      99           0 : GUIPerson::GUIPersonPopupMenu::onCmdShowWalkingareaPath(FXObject*, FXSelector, void*) {
     100             :     assert(myObject->getType() == GLO_PERSON);
     101           0 :     if (!static_cast<GUIPerson*>(myObject)->hasActiveAddVisualisation(myParent, VO_SHOW_WALKINGAREA_PATH)) {
     102           0 :         static_cast<GUIPerson*>(myObject)->addActiveAddVisualisation(myParent, VO_SHOW_WALKINGAREA_PATH);
     103             :     }
     104           0 :     return 1;
     105             : }
     106             : 
     107             : 
     108             : long
     109           0 : GUIPerson::GUIPersonPopupMenu::onCmdHideWalkingareaPath(FXObject*, FXSelector, void*) {
     110             :     assert(myObject->getType() == GLO_PERSON);
     111           0 :     static_cast<GUIPerson*>(myObject)->removeActiveAddVisualisation(myParent, VO_SHOW_WALKINGAREA_PATH);
     112           0 :     return 1;
     113             : }
     114             : 
     115             : 
     116             : long
     117           0 : GUIPerson::GUIPersonPopupMenu::onCmdShowPlan(FXObject*, FXSelector, void*) {
     118           0 :     GUIPerson* p = dynamic_cast<GUIPerson*>(myObject);
     119           0 :     if (p == nullptr) {
     120             :         return 1;
     121             :     }
     122           0 :     GUIParameterTableWindow* ret = new GUIParameterTableWindow(*myApplication, *p);
     123             :     // add items
     124           0 :     for (int stage = 1; stage < p->getNumStages(); stage++) {
     125           0 :         ret->mkItem(toString(stage).c_str(), false, p->getStageSummary(stage));
     126             :     }
     127             :     // close building (use an object that is not Parameterised as argument)
     128           0 :     Parameterised dummyParameterised;
     129           0 :     ret->closeBuilding(&dummyParameterised);
     130             :     return 1;
     131           0 : }
     132             : 
     133             : 
     134             : long
     135           0 : GUIPerson::GUIPersonPopupMenu::onCmdStartTrack(FXObject*, FXSelector, void*) {
     136             :     assert(myObject->getType() == GLO_PERSON);
     137           0 :     if (myParent->getTrackedID() != static_cast<GUIPerson*>(myObject)->getGlID()) {
     138           0 :         myParent->startTrack(static_cast<GUIPerson*>(myObject)->getGlID());
     139             :     }
     140           0 :     return 1;
     141             : }
     142             : 
     143             : 
     144             : long
     145           0 : GUIPerson::GUIPersonPopupMenu::onCmdStopTrack(FXObject*, FXSelector, void*) {
     146             :     assert(myObject->getType() == GLO_PERSON);
     147           0 :     myParent->stopTrack();
     148           0 :     return 1;
     149             : }
     150             : 
     151             : 
     152             : long
     153           0 : GUIPerson::GUIPersonPopupMenu::onCmdRemoveObject(FXObject*, FXSelector, void*) {
     154           0 :     GUIPerson* person = static_cast<GUIPerson*>(myObject);
     155             :     MSStage* stage = person->getCurrentStage();
     156           0 :     stage->abort(person);
     157           0 :     stage->getEdge()->removeTransportable(person);
     158           0 :     if (stage->getDestinationStop() != nullptr) {
     159           0 :         stage->getDestinationStop()->removeTransportable(person);
     160             :     }
     161           0 :     MSNet::getInstance()->getPersonControl().erase(person);
     162           0 :     myParent->update();
     163           0 :     return 1;
     164             : }
     165             : 
     166             : // -------------------------------------------------------------------------
     167             : // GUIPerson - methods
     168             : // -------------------------------------------------------------------------
     169             : 
     170       25217 : GUIPerson::GUIPerson(const SUMOVehicleParameter* pars, MSVehicleType* vtype, MSTransportable::MSTransportablePlan* plan, const double speedFactor) :
     171             :     MSPerson(pars, vtype, plan, speedFactor),
     172       25217 :     GUIGlObject(GLO_PERSON, pars->id, GUIIconSubSys::getIcon(GUIIcon::PERSON)),
     173       25217 :     myLock(true)
     174       25217 : { }
     175             : 
     176             : 
     177       50348 : GUIPerson::~GUIPerson() {
     178       25174 :     myLock.lock();
     179       25174 :     for (std::map<GUISUMOAbstractView*, int>::iterator i = myAdditionalVisualizations.begin(); i != myAdditionalVisualizations.end(); ++i) {
     180           0 :         if (i->first->getTrackedID() == getGlID()) {
     181           0 :             i->first->stopTrack();
     182             :         }
     183           0 :         while (i->first->removeAdditionalGLVisualisation(this));
     184             :     }
     185       25174 :     myLock.unlock();
     186       50348 : }
     187             : 
     188             : 
     189             : GUIGLObjectPopupMenu*
     190           0 : GUIPerson::getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) {
     191           0 :     GUIGLObjectPopupMenu* ret = new GUIPersonPopupMenu(app, parent, *this);
     192           0 :     buildPopupHeader(ret, app);
     193           0 :     buildCenterPopupEntry(ret);
     194           0 :     buildNameCopyPopupEntry(ret);
     195           0 :     buildSelectionPopupEntry(ret);
     196           0 :     if (hasActiveAddVisualisation(&parent, VO_SHOW_ROUTE)) {
     197           0 :         GUIDesigns::buildFXMenuCommand(ret, "Hide Current Route", nullptr, ret, MID_HIDE_CURRENTROUTE);
     198             :     } else {
     199           0 :         GUIDesigns::buildFXMenuCommand(ret, "Show Current Route", nullptr, ret, MID_SHOW_CURRENTROUTE);
     200             :     }
     201           0 :     if (hasActiveAddVisualisation(&parent, VO_SHOW_WALKINGAREA_PATH)) {
     202           0 :         GUIDesigns::buildFXMenuCommand(ret, "Hide Walkingarea Path", nullptr, ret, MID_HIDE_WALKINGAREA_PATH);
     203             :     } else {
     204           0 :         GUIDesigns::buildFXMenuCommand(ret, "Show Walkingarea Path", nullptr, ret, MID_SHOW_WALKINGAREA_PATH);
     205             :     }
     206           0 :     new FXMenuSeparator(ret);
     207           0 :     if (parent.getTrackedID() != getGlID()) {
     208           0 :         GUIDesigns::buildFXMenuCommand(ret, "Start Tracking", nullptr, ret, MID_START_TRACK);
     209             :     } else {
     210           0 :         GUIDesigns::buildFXMenuCommand(ret, "Stop Tracking", nullptr, ret, MID_STOP_TRACK);
     211             :     }
     212           0 :     GUIDesigns::buildFXMenuCommand(ret, "Remove", nullptr, ret, MID_REMOVE_OBJECT);
     213           0 :     new FXMenuSeparator(ret);
     214             :     //
     215           0 :     buildShowParamsPopupEntry(ret);
     216           0 :     buildShowTypeParamsPopupEntry(ret);
     217           0 :     GUIDesigns::buildFXMenuCommand(ret, "Show Plan", GUIIconSubSys::getIcon(GUIIcon::APP_TABLE), ret, MID_SHOWPLAN);
     218           0 :     new FXMenuSeparator(ret);
     219           0 :     buildPositionCopyEntry(ret, app);
     220           0 :     return ret;
     221             : }
     222             : 
     223             : 
     224             : GUIParameterTableWindow*
     225           0 : GUIPerson::getParameterWindow(GUIMainWindow& app,
     226             :                               GUISUMOAbstractView&) {
     227           0 :     GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
     228             :     // add items
     229           0 :     ret->mkItem(TL("stage"), true, new FunctionBindingString<GUIPerson>(this, &MSTransportable::getCurrentStageDescription));
     230             :     // there is always the "start" stage which we do not count here because it is not strictly part of the plan
     231           0 :     ret->mkItem(TL("stage index"), true, new FunctionBindingString<GUIPerson>(this, &GUIPerson::getStageIndexDescription));
     232           0 :     ret->mkItem(TL("start edge [id]"), true, new FunctionBindingString<GUIPerson>(this, &GUIPerson::getFromEdgeID));
     233           0 :     ret->mkItem(TL("dest edge [id]"), true, new FunctionBindingString<GUIPerson>(this, &GUIPerson::getDestinationEdgeID));
     234           0 :     ret->mkItem(TL("dest stop [id]"), true, new FunctionBindingString<GUIPerson>(this, &GUIPerson::getDestinationStopID));
     235           0 :     ret->mkItem(TL("arrival position [m]"), true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getStageArrivalPos));
     236           0 :     ret->mkItem(TL("edge [id]"), true, new FunctionBindingString<GUIPerson>(this, &GUIPerson::getEdgeID));
     237           0 :     ret->mkItem(TL("position [m]"), true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getEdgePos));
     238           0 :     ret->mkItem(TL("speed [m/s]"), true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getSpeed));
     239           0 :     ret->mkItem(TL("speed factor"), false, getChosenSpeedFactor());
     240           0 :     ret->mkItem(TL("angle [degree]"), true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getNaviDegree));
     241           0 :     ret->mkItem(TL("waiting time [s]"), true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getWaitingSeconds));
     242           0 :     ret->mkItem(TL("vehicle [id]"), true, new FunctionBindingString<GUIPerson>(this, &GUIPerson::getVehicleID));
     243           0 :     ret->mkItem(TL("stop duration [s]"), true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getStopDuration));
     244           0 :     ret->mkItem(TL("desired depart [s]"), false, time2string(getParameter().depart));
     245             :     // close building
     246           0 :     ret->closeBuilding(&getParameter());
     247           0 :     return ret;
     248             : }
     249             : 
     250             : 
     251             : GUIParameterTableWindow*
     252           0 : GUIPerson::getTypeParameterWindow(GUIMainWindow& app, GUISUMOAbstractView&) {
     253           0 :     GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this, "vType:" + myVType->getID());
     254           0 :     ret->mkItem(TL("length"), false, myVType->getLength());
     255           0 :     ret->mkItem(TL("width"), false, myVType->getWidth());
     256           0 :     ret->mkItem(TL("height"), false, myVType->getHeight());
     257           0 :     ret->mkItem(TL("minGap"), false, myVType->getMinGap());
     258           0 :     ret->mkItem(TL("mass [kg]"), false, myVType->getMass());
     259           0 :     ret->mkItem(TL("desired max speed [m/s]"), false, myVType->getDesiredMaxSpeed());
     260           0 :     ret->mkItem(TL("maximum speed [m/s]"), false, myVType->getMaxSpeed());
     261           0 :     ret->closeBuilding(&(myVType->getParameter()));
     262           0 :     return ret;
     263             : }
     264             : 
     265             : 
     266             : double
     267      927844 : GUIPerson::getExaggeration(const GUIVisualizationSettings& s) const {
     268     1855688 :     return s.personSize.getExaggeration(s, this, s.personQuality == 1 ? 40 : 80);
     269             : }
     270             : 
     271             : 
     272             : Boundary
     273           0 : GUIPerson::getCenteringBoundary() const {
     274           0 :     Boundary b;
     275             :     // ensure that the vehicle is drawn, otherwise myPositionInVehicle will not be updated
     276           0 :     b.add(getGUIPosition());
     277           0 :     b.grow(MAX2(getVehicleType().getWidth(), getVehicleType().getLength()));
     278           0 :     return b;
     279           0 : }
     280             : 
     281             : 
     282             : void
     283      927844 : GUIPerson::drawGL(const GUIVisualizationSettings& s) const {
     284      927844 :     GLHelper::pushName(getGlID());
     285      927844 :     GLHelper::pushMatrix();
     286      927844 :     Position p1 = getGUIPosition(&s);
     287      927844 :     double angle = getGUIAngle();
     288      927844 :     glTranslated(p1.x(), p1.y(), getType());
     289             :     // set person color
     290      927844 :     setColor(s);
     291             :     // scale
     292      927844 :     const double exaggeration = getExaggeration(s);
     293      927844 :     glScaled(exaggeration, exaggeration, 1);
     294      927844 :     switch (s.personQuality) {
     295      874389 :         case 0:
     296      874389 :             GUIBasePersonHelper::drawAction_drawAsTriangle(angle, getVehicleType().getLength(), getVehicleType().getWidth());
     297             :             break;
     298           0 :         case 1:
     299           0 :             GUIBasePersonHelper::drawAction_drawAsCircle(angle, getVehicleType().getLength(), getVehicleType().getWidth(), s.scale * exaggeration);
     300             :             break;
     301       53455 :         case 2:
     302       53455 :             GUIBasePersonHelper::drawAction_drawAsPoly(angle, getVehicleType().getLength(), getVehicleType().getWidth());
     303             :             break;
     304           0 :         case 3:
     305             :         default:
     306           0 :             GUIBasePersonHelper::drawAction_drawAsImage(angle, getVehicleType().getLength(), getVehicleType().getWidth(),
     307           0 :                     getVehicleType().getImgFile(), getVehicleType().getGuiShape(), 1);
     308           0 :             break;
     309             :     }
     310      927844 :     GLHelper::popMatrix();
     311             : #ifdef GUIPerson_DEBUG_DRAW_WALKINGAREA_PATHS
     312             :     drawAction_drawWalkingareaPath(s);
     313             : #endif
     314      927844 :     drawName(p1, s.scale, s.personName, s.angle);
     315      927844 :     if (s.personValue.show(this)) {
     316           0 :         Position p2 = p1 + Position(0, 0.6 * s.personName.scaledSize(s.scale));
     317           0 :         const double value = getColorValue(s, s.personColorer.getActive());
     318           0 :         GLHelper::drawTextSettings(s.personValue, toString(value), p2, s.scale, s.angle, GLO_MAX - getType());
     319             :     }
     320      927844 :     GLHelper::popName();
     321      927844 : }
     322             : 
     323             : 
     324             : void
     325           0 : GUIPerson::drawAction_drawWalkingareaPath(const GUIVisualizationSettings& s) const {
     326           0 :     MSStageWalking* stage = dynamic_cast<MSStageWalking*>(getCurrentStage());
     327           0 :     if (stage != nullptr) {
     328           0 :         setColor(s);
     329           0 :         MSPModel_Striping::PState* stripingState = dynamic_cast<MSPModel_Striping::PState*>(stage->getPState());
     330           0 :         if (stripingState != nullptr) {
     331           0 :             const MSPModel_Striping::WalkingAreaPath* waPath = stripingState->myWalkingAreaPath;
     332           0 :             if (waPath != nullptr) {
     333           0 :                 GLHelper::pushMatrix();
     334           0 :                 glTranslated(0, 0, getType());
     335           0 :                 GLHelper::drawBoxLines(waPath->shape, 0.05);
     336           0 :                 GLHelper::popMatrix();
     337             :             }
     338             :         }
     339             :     }
     340           0 : }
     341             : 
     342             : void
     343           0 : GUIPerson::drawGLAdditional(GUISUMOAbstractView* const parent, const GUIVisualizationSettings& s) const {
     344           0 :     GLHelper::pushName(getGlID());
     345           0 :     GLHelper::pushMatrix();
     346           0 :     glTranslated(0, 0, getType() - .1); // don't draw on top of other cars
     347           0 :     if (hasActiveAddVisualisation(parent, VO_SHOW_WALKINGAREA_PATH)) {
     348           0 :         drawAction_drawWalkingareaPath(s);
     349             :     }
     350           0 :     if (hasActiveAddVisualisation(parent, VO_SHOW_ROUTE)) {
     351           0 :         if (getCurrentStageType() == MSStageType::WALKING) {
     352           0 :             setColor(s);
     353           0 :             RGBColor current = GLHelper::getColor();
     354           0 :             RGBColor darker = current.changedBrightness(-51);
     355           0 :             GLHelper::setColor(darker);
     356           0 :             MSStageWalking* stage = dynamic_cast<MSStageWalking*>(getCurrentStage());
     357             :             assert(stage != 0);
     358           0 :             const double exaggeration = getExaggeration(s);
     359             :             const ConstMSEdgeVector& edges = stage->getRoute();
     360           0 :             const bool s2 = s.secondaryShape;
     361           0 :             for (ConstMSEdgeVector::const_iterator it = edges.begin(); it != edges.end(); ++it) {
     362           0 :                 GUILane* lane = static_cast<GUILane*>((*it)->getLanes()[0]);
     363           0 :                 GLHelper::drawBoxLines(lane->getShape(s2), lane->getShapeRotations(s2), lane->getShapeLengths(s2), exaggeration);
     364             :             }
     365             :         }
     366             :     }
     367           0 :     GLHelper::popMatrix();
     368           0 :     GLHelper::popName();
     369           0 : }
     370             : 
     371             : 
     372             : void
     373      212324 : GUIPerson::setPositionInVehicle(const GUIBaseVehicle::Seat& pos) {
     374      212324 :     myPositionInVehicle = pos;
     375      212324 : }
     376             : 
     377             : 
     378             : void
     379      927844 : GUIPerson::setColor(const GUIVisualizationSettings& s) const {
     380      927844 :     RGBColor col;
     381             :     const GUIColorer& c = s.personColorer;
     382      927844 :     if (!setFunctionalColor(c.getActive(), this, col)) {
     383      752063 :         col = c.getScheme().getColor(getColorValue(s, c.getActive()));
     384             :     }
     385      927844 :     GLHelper::setColor(col);
     386      927844 : }
     387             : 
     388             : 
     389             : bool
     390      932370 : GUIPerson::setFunctionalColor(int activeScheme, const MSPerson* person, RGBColor& col) {
     391      932370 :     switch (activeScheme) {
     392      464993 :         case 0: {
     393      464993 :             if (person->getParameter().wasSet(VEHPARS_COLOR_SET)) {
     394       29091 :                 col = person->getParameter().color;
     395       29091 :                 return true;
     396             :             }
     397      435902 :             if (person->getVehicleType().wasSet(VTYPEPARS_COLOR_SET)) {
     398      146690 :                 col = person->getVehicleType().getColor();
     399      146690 :                 return true;
     400             :             }
     401             :             return false;
     402             :         }
     403           0 :         case 2: {
     404           0 :             if (person->getParameter().wasSet(VEHPARS_COLOR_SET)) {
     405           0 :                 col = person->getParameter().color;
     406           0 :                 return true;
     407             :             }
     408             :             return false;
     409             :         }
     410           0 :         case 3: {
     411           0 :             if (person->getVehicleType().wasSet(VTYPEPARS_COLOR_SET)) {
     412           0 :                 col = person->getVehicleType().getColor();
     413           0 :                 return true;
     414             :             }
     415             :             return false;
     416             :         }
     417           0 :         case 9: { // color by angle
     418           0 :             double hue = GeomHelper::naviDegree(person->getAngle());
     419           0 :             col = RGBColor::fromHSV(hue, 1., 1.);
     420           0 :             return true;
     421             :         }
     422           0 :         case 10: { // color randomly (by pointer)
     423           0 :             const double hue = (double)((long long int)person % 360); // [0-360]
     424           0 :             const double sat = (double)(((long long int)person / 360) % 67) / 100. + 0.33; // [0.33-1]
     425           0 :             col = RGBColor::fromHSV(hue, sat, 1.);
     426           0 :             return true;
     427             :         }
     428             :         default:
     429             :             return false;
     430             :     }
     431             : }
     432             : 
     433             : 
     434             : double
     435      756589 : GUIPerson::getColorValue(const GUIVisualizationSettings& /* s */, int activeScheme) const {
     436      756589 :     switch (activeScheme) {
     437           0 :         case 4:
     438           0 :             switch (getCurrentStageType()) {
     439             :                 case MSStageType::WAITING:
     440             :                     return -1;
     441           0 :                 case MSStageType::WAITING_FOR_DEPART:
     442           0 :                     return -2;
     443           0 :                 default:
     444           0 :                     return getSpeed();
     445             :             }
     446      467377 :         case 5:
     447      467377 :             if (isWaiting4Vehicle()) {
     448             :                 return 5;
     449             :             } else {
     450      179759 :                 return (double)getCurrentStageType();
     451             :             }
     452           0 :         case 6:
     453           0 :             return getWaitingSeconds();
     454           0 :         case 7:
     455           0 :             return isJammed() ? 1 : 0;
     456           0 :         case 8:
     457           0 :             return gSelected.isSelected(GLO_PERSON, getGlID());
     458             :     }
     459             :     return 0;
     460             : }
     461             : 
     462             : 
     463             : double
     464      463899 : GUIPerson::getEdgePos() const {
     465      463899 :     FXMutexLock locker(myLock);
     466      463899 :     if (hasArrived()) {
     467             :         return -1;
     468             :     }
     469      463899 :     return MSPerson::getEdgePos();
     470             : }
     471             : 
     472             : int
     473       92710 : GUIPerson::getDirection() const {
     474       92710 :     FXMutexLock locker(myLock);
     475       92710 :     if (hasArrived()) {
     476           0 :         return MSPModel::UNDEFINED_DIRECTION;
     477             :     }
     478       92710 :     return MSPerson::getDirection();
     479             : }
     480             : 
     481             : 
     482             : Position
     483     1087537 : GUIPerson::getPosition() const {
     484     1087537 :     FXMutexLock locker(myLock);
     485     1087537 :     if (hasArrived()) {
     486           0 :         return Position::INVALID;
     487             :     }
     488     1087537 :     return MSPerson::getPosition();
     489             : }
     490             : 
     491             : 
     492             : Position
     493      927844 : GUIPerson::getGUIPosition(const GUIVisualizationSettings* s) const {
     494      927844 :     FXMutexLock locker(myLock);
     495      927844 :     if (hasArrived()) {
     496           0 :         return Position::INVALID;
     497             :     }
     498      927844 :     if (getCurrentStageType() == MSStageType::DRIVING) {
     499      517691 :         if (!isWaiting4Vehicle() && myPositionInVehicle.pos != Position::INVALID) {
     500      212173 :             return myPositionInVehicle.pos;
     501             :         } else if (isWaiting4Vehicle()
     502      305367 :                    && s != nullptr
     503      305367 :                    && s->gaming
     504           0 :                    && getCurrentStage()->getOriginStop() != nullptr
     505      305518 :                    && s->addSize.getExaggeration(*s, nullptr) > 1) {
     506             :             // shift position away from stop center
     507           0 :             Position pos = MSPerson::getPosition();
     508           0 :             Position ref = getCurrentStage()->getOriginStop()->getCenterPos();
     509           0 :             Position shifted = ref + (pos - ref) * s->personSize.getExaggeration(*s, this);
     510           0 :             return shifted;
     511             :         }
     512             :     }
     513      715671 :     return MSPerson::getPosition();
     514             : }
     515             : 
     516             : 
     517             : double
     518      927844 : GUIPerson::getGUIAngle() const {
     519      927844 :     FXMutexLock locker(myLock);
     520      927844 :     if (hasArrived()) {
     521             :         return INVALID_DOUBLE;
     522             :     }
     523     1445535 :     if (getCurrentStageType() == MSStageType::DRIVING && !isWaiting4Vehicle() && myPositionInVehicle.pos != Position::INVALID) {
     524      212173 :         return myPositionInVehicle.angle;
     525             :     } else {
     526      715671 :         return MSPerson::getAngle();
     527             :     }
     528             : }
     529             : 
     530             : 
     531             : double
     532           0 : GUIPerson::getNaviDegree() const {
     533           0 :     FXMutexLock locker(myLock);
     534           0 :     if (hasArrived()) {
     535             :         return INVALID_DOUBLE;
     536             :     }
     537           0 :     return GeomHelper::naviDegree(MSPerson::getAngle());
     538             : }
     539             : 
     540             : 
     541             : double
     542           2 : GUIPerson::getWaitingSeconds() const {
     543           2 :     FXMutexLock locker(myLock);
     544           2 :     if (hasArrived()) {
     545             :         return -1;
     546             :     }
     547           2 :     return MSPerson::getWaitingSeconds();
     548             : }
     549             : 
     550             : 
     551             : double
     552      249644 : GUIPerson::getSpeed() const {
     553      249644 :     FXMutexLock locker(myLock);
     554      249644 :     if (hasArrived()) {
     555             :         return -1;
     556             :     }
     557      249644 :     return MSPerson::getSpeed();
     558             : }
     559             : 
     560             : 
     561             : std::string
     562           0 : GUIPerson::getStageIndexDescription() const {
     563           0 :     FXMutexLock locker(myLock);
     564           0 :     if (hasArrived()) {
     565           0 :         return "arrived";
     566             :     }
     567             :     // there is always the "start" stage which we do not count here because it is not strictly part of the plan
     568           0 :     return toString(getCurrentStageIndex()) + " of " + toString(getNumStages() - 1);
     569             : }
     570             : 
     571             : 
     572             : std::string
     573           0 : GUIPerson::getEdgeID() const {
     574           0 :     FXMutexLock locker(myLock);
     575           0 :     if (hasArrived()) {
     576           0 :         return "arrived";
     577             :     }
     578           0 :     return  getEdge()->getID();
     579             : }
     580             : 
     581             : 
     582             : std::string
     583           0 : GUIPerson::getFromEdgeID() const {
     584           0 :     FXMutexLock locker(myLock);
     585           0 :     if (hasArrived()) {
     586           0 :         return "arrived";
     587             :     }
     588             :     return getFromEdge()->getID();
     589             : }
     590             : 
     591             : 
     592             : std::string
     593           0 : GUIPerson::getDestinationEdgeID() const {
     594           0 :     FXMutexLock locker(myLock);
     595           0 :     if (hasArrived()) {
     596           0 :         return "arrived";
     597             :     }
     598             :     return getDestination()->getID();
     599             : }
     600             : 
     601             : 
     602             : std::string
     603           0 : GUIPerson::getDestinationStopID() const {
     604           0 :     FXMutexLock locker(myLock);
     605           0 :     if (hasArrived()) {
     606           0 :         return "";
     607             :     }
     608             :     MSStoppingPlace* destStop = getCurrentStage()->getDestinationStop();
     609           0 :     if (destStop != nullptr) {
     610             :         return destStop->getID();
     611             :     } else {
     612           0 :         return "";
     613             :     }
     614             : }
     615             : 
     616             : 
     617             : std::string
     618           0 : GUIPerson::getVehicleID() const {
     619           0 :     FXMutexLock locker(myLock);
     620           0 :     if (hasArrived()) {
     621           0 :         return "";
     622             :     }
     623           0 :     SUMOVehicle* veh = getCurrentStage()->getVehicle();
     624           0 :     if (veh != nullptr) {
     625             :         return veh->getID();
     626             :     } else {
     627           0 :         return "";
     628             :     }
     629             : }
     630             : 
     631             : 
     632             : double
     633           0 : GUIPerson::getStopDuration() const {
     634           0 :     FXMutexLock locker(myLock);
     635           0 :     if (hasArrived()) {
     636             :         return -1;
     637             :     }
     638           0 :     if (getCurrentStage()->getStageType() == MSStageType::WAITING) {
     639           0 :         return STEPS2TIME(dynamic_cast<MSStageWaiting*>(getCurrentStage())->getStopEnd() - SIMSTEP);
     640             :     } else {
     641             :         return -1;
     642             :     }
     643             : }
     644             : 
     645             : 
     646             : double
     647           0 : GUIPerson::getStageArrivalPos() const {
     648           0 :     FXMutexLock locker(myLock);
     649           0 :     if (hasArrived()) {
     650             :         return INVALID_DOUBLE;
     651             :     }
     652           0 :     return getCurrentStage()->getArrivalPos();
     653             : }
     654             : 
     655             : bool
     656       50229 : GUIPerson::proceed(MSNet* net, SUMOTime time, const bool vehicleArrived) {
     657             :     // acquire lock before locking the person to avoid mutual deadlock (#9468)
     658       50229 :     ScopedLocker<const MSEdge, true> edgeLocker(*getEdge());
     659       50229 :     FXMutexLock locker(myLock);
     660      100441 :     return MSTransportable::proceed(net, time, vehicleArrived);
     661             : }
     662             : 
     663             : // -------------------------------------------------------------------------
     664             : // GUIPerson - Additional Visualsation methods
     665             : // -------------------------------------------------------------------------
     666             : 
     667             : bool
     668           0 : GUIPerson::hasActiveAddVisualisation(GUISUMOAbstractView* const parent, int which) const {
     669           0 :     return myAdditionalVisualizations.find(parent) != myAdditionalVisualizations.end() && (myAdditionalVisualizations.find(parent)->second & which) != 0;
     670             : }
     671             : 
     672             : 
     673             : void
     674           0 : GUIPerson::addActiveAddVisualisation(GUISUMOAbstractView* const parent, int which) {
     675           0 :     if (myAdditionalVisualizations.find(parent) == myAdditionalVisualizations.end()) {
     676           0 :         myAdditionalVisualizations[parent] = 0;
     677             :     }
     678           0 :     myAdditionalVisualizations[parent] |= which;
     679           0 :     parent->addAdditionalGLVisualisation(this);
     680           0 : }
     681             : 
     682             : 
     683             : void
     684           0 : GUIPerson::removeActiveAddVisualisation(GUISUMOAbstractView* const parent, int which) {
     685           0 :     myAdditionalVisualizations[parent] &= ~which;
     686           0 :     parent->removeAdditionalGLVisualisation(this);
     687           0 : }
     688             : 
     689             : bool
     690    23664591 : GUIPerson::isSelected() const {
     691    23664591 :     return gSelected.isSelected(GLO_PERSON, getGlID());
     692             : }
     693             : 
     694             : 
     695             : /****************************************************************************/

Generated by: LCOV version 1.14