LCOV - code coverage report
Current view: top level - src/guisim - GUIPerson.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 27.4 % 354 97
Test Date: 2025-11-13 15:38:19 Functions: 36.0 % 50 18

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2025 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        29148 : GUIPerson::GUIPerson(const SUMOVehicleParameter* pars, MSVehicleType* vtype, MSTransportable::MSTransportablePlan* plan, const double speedFactor) :
     171              :     MSPerson(pars, vtype, plan, speedFactor),
     172        29148 :     GUIGlObject(GLO_PERSON, pars->id, GUIIconSubSys::getIcon(GUIIcon::PERSON)),
     173        29148 :     myLock(true)
     174        29148 : { }
     175              : 
     176              : 
     177        58214 : GUIPerson::~GUIPerson() {
     178        29107 :     myLock.lock();
     179        29107 :     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        29107 :     gSelected.deselect(GLO_PERSON, getGlID());
     186        29107 :     myLock.unlock();
     187        58214 : }
     188              : 
     189              : 
     190              : GUIGLObjectPopupMenu*
     191            0 : GUIPerson::getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) {
     192            0 :     GUIGLObjectPopupMenu* ret = new GUIPersonPopupMenu(app, parent, this);
     193            0 :     buildPopupHeader(ret, app);
     194            0 :     buildCenterPopupEntry(ret);
     195            0 :     buildNameCopyPopupEntry(ret);
     196            0 :     buildSelectionPopupEntry(ret);
     197            0 :     if (hasActiveAddVisualisation(&parent, VO_SHOW_ROUTE)) {
     198            0 :         GUIDesigns::buildFXMenuCommand(ret, "Hide Current Route", nullptr, ret, MID_HIDE_CURRENTROUTE);
     199              :     } else {
     200            0 :         GUIDesigns::buildFXMenuCommand(ret, "Show Current Route", nullptr, ret, MID_SHOW_CURRENTROUTE);
     201              :     }
     202            0 :     if (hasActiveAddVisualisation(&parent, VO_SHOW_WALKINGAREA_PATH)) {
     203            0 :         GUIDesigns::buildFXMenuCommand(ret, "Hide Walkingarea Path", nullptr, ret, MID_HIDE_WALKINGAREA_PATH);
     204              :     } else {
     205            0 :         GUIDesigns::buildFXMenuCommand(ret, "Show Walkingarea Path", nullptr, ret, MID_SHOW_WALKINGAREA_PATH);
     206              :     }
     207            0 :     new FXMenuSeparator(ret);
     208            0 :     if (parent.getTrackedID() != getGlID()) {
     209            0 :         GUIDesigns::buildFXMenuCommand(ret, "Start Tracking", nullptr, ret, MID_START_TRACK);
     210              :     } else {
     211            0 :         GUIDesigns::buildFXMenuCommand(ret, "Stop Tracking", nullptr, ret, MID_STOP_TRACK);
     212              :     }
     213            0 :     GUIDesigns::buildFXMenuCommand(ret, "Remove", nullptr, ret, MID_REMOVE_OBJECT);
     214            0 :     new FXMenuSeparator(ret);
     215              :     //
     216            0 :     buildShowParamsPopupEntry(ret);
     217            0 :     buildShowTypeParamsPopupEntry(ret);
     218            0 :     GUIDesigns::buildFXMenuCommand(ret, "Show Plan", GUIIconSubSys::getIcon(GUIIcon::APP_TABLE), ret, MID_SHOWPLAN);
     219            0 :     new FXMenuSeparator(ret);
     220            0 :     buildPositionCopyEntry(ret, app);
     221            0 :     return ret;
     222              : }
     223              : 
     224              : 
     225              : GUIParameterTableWindow*
     226            0 : GUIPerson::getParameterWindow(GUIMainWindow& app,
     227              :                               GUISUMOAbstractView&) {
     228            0 :     GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
     229              :     // add items
     230            0 :     ret->mkItem(TL("stage"), true, new FunctionBindingString<GUIPerson>(this, &MSTransportable::getCurrentStageDescription));
     231              :     // there is always the "start" stage which we do not count here because it is not strictly part of the plan
     232            0 :     ret->mkItem(TL("stage index"), true, new FunctionBindingString<GUIPerson>(this, &GUIPerson::getStageIndexDescription));
     233            0 :     ret->mkItem(TL("start edge [id]"), true, new FunctionBindingString<GUIPerson>(this, &GUIPerson::getFromEdgeID));
     234            0 :     ret->mkItem(TL("dest edge [id]"), true, new FunctionBindingString<GUIPerson>(this, &GUIPerson::getDestinationEdgeID));
     235            0 :     ret->mkItem(TL("dest stop [id]"), true, new FunctionBindingString<GUIPerson>(this, &GUIPerson::getDestinationStopID));
     236            0 :     ret->mkItem(TL("arrival position [m]"), true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getStageArrivalPos));
     237            0 :     ret->mkItem(TL("edge [id]"), true, new FunctionBindingString<GUIPerson>(this, &GUIPerson::getEdgeID));
     238            0 :     ret->mkItem(TL("lane [id]"), true, new FunctionBindingString<GUIPerson>(this, &GUIPerson::getLaneID));
     239            0 :     ret->mkItem(TL("position [m]"), true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getEdgePos));
     240            0 :     ret->mkItem(TL("speed [m/s]"), true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getSpeed));
     241            0 :     ret->mkItem(TL("speed factor"), false, getChosenSpeedFactor());
     242            0 :     ret->mkItem(TL("angle [degree]"), true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getNaviDegree));
     243            0 :     ret->mkItem(TL("waiting time [s]"), true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getWaitingSeconds));
     244            0 :     ret->mkItem(TL("vehicle [id]"), true, new FunctionBindingString<GUIPerson>(this, &GUIPerson::getVehicleID));
     245            0 :     ret->mkItem(TL("stop duration [s]"), true, new FunctionBinding<GUIPerson, double>(this, &GUIPerson::getStopDuration));
     246            0 :     ret->mkItem(TL("desired depart [s]"), false, time2string(getParameter().depart));
     247              :     // close building
     248            0 :     ret->closeBuilding(&getParameter());
     249            0 :     return ret;
     250              : }
     251              : 
     252              : 
     253              : GUIParameterTableWindow*
     254            0 : GUIPerson::getTypeParameterWindow(GUIMainWindow& app, GUISUMOAbstractView&) {
     255            0 :     GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this, "vType:" + myVType->getID());
     256            0 :     ret->mkItem(TL("length"), false, myVType->getLength());
     257            0 :     ret->mkItem(TL("width"), false, myVType->getWidth());
     258            0 :     ret->mkItem(TL("height"), false, myVType->getHeight());
     259            0 :     ret->mkItem(TL("minGap"), false, myVType->getMinGap());
     260            0 :     ret->mkItem(TL("mass [kg]"), false, myVType->getMass());
     261            0 :     ret->mkItem(TL("desired max speed [m/s]"), false, myVType->getDesiredMaxSpeed());
     262            0 :     ret->mkItem(TL("maximum speed [m/s]"), false, myVType->getMaxSpeed());
     263            0 :     ret->closeBuilding(&(myVType->getParameter()));
     264            0 :     return ret;
     265              : }
     266              : 
     267              : 
     268              : double
     269      1194678 : GUIPerson::getExaggeration(const GUIVisualizationSettings& s) const {
     270      2389356 :     return s.personSize.getExaggeration(s, this, s.personQuality == 1 ? 40 : 80);
     271              : }
     272              : 
     273              : 
     274              : Boundary
     275            0 : GUIPerson::getCenteringBoundary() const {
     276            0 :     Boundary b;
     277              :     // ensure that the vehicle is drawn, otherwise myPositionInVehicle will not be updated
     278            0 :     b.add(getGUIPosition());
     279            0 :     b.grow(MAX2(getVehicleType().getWidth(), getVehicleType().getLength()));
     280            0 :     return b;
     281              : }
     282              : 
     283              : 
     284              : void
     285      1194678 : GUIPerson::drawGL(const GUIVisualizationSettings& s) const {
     286      1194678 :     GLHelper::pushName(getGlID());
     287      1194678 :     GLHelper::pushMatrix();
     288      1194678 :     Position p1 = getGUIPosition(&s);
     289      1194678 :     double angle = getGUIAngle();
     290      1194678 :     glTranslated(p1.x(), p1.y(), getType());
     291              :     // set person color
     292      1194678 :     setColor(s);
     293              :     // scale
     294      1194678 :     const double exaggeration = getExaggeration(s);
     295      1194678 :     glScaled(exaggeration, exaggeration, 1);
     296      1194678 :     switch (s.personQuality) {
     297      1143771 :         case 0:
     298      1143771 :             GUIBasePersonHelper::drawAction_drawAsTriangle(angle, getVehicleType().getLength(), getVehicleType().getWidth());
     299              :             break;
     300            0 :         case 1:
     301            0 :             GUIBasePersonHelper::drawAction_drawAsCircle(angle, getVehicleType().getLength(), getVehicleType().getWidth(), s.scale * exaggeration);
     302              :             break;
     303        50907 :         case 2:
     304        50907 :             GUIBasePersonHelper::drawAction_drawAsPoly(angle, getVehicleType().getLength(), getVehicleType().getWidth());
     305              :             break;
     306            0 :         case 3:
     307              :         default:
     308            0 :             GUIBasePersonHelper::drawAction_drawAsImage(angle, getVehicleType().getLength(), getVehicleType().getWidth(),
     309            0 :                     getVehicleType().getImgFile(), getVehicleType().getGuiShape(), 1);
     310            0 :             break;
     311              :     }
     312      1194678 :     GLHelper::popMatrix();
     313              : #ifdef GUIPerson_DEBUG_DRAW_WALKINGAREA_PATHS
     314              :     drawAction_drawWalkingareaPath(s);
     315              : #endif
     316      1194678 :     drawName(p1, s.scale, s.personName, s.angle);
     317      1194678 :     if (s.personValue.show(this)) {
     318            0 :         Position p2 = p1 + Position(0, 0.6 * s.personName.scaledSize(s.scale));
     319            0 :         const double value = getColorValue(s, s.personColorer.getActive());
     320            0 :         GLHelper::drawTextSettings(s.personValue, toString(value), p2, s.scale, s.angle, GLO_MAX - getType());
     321              :     }
     322      1194678 :     GLHelper::popName();
     323      1194678 : }
     324              : 
     325              : 
     326              : void
     327            0 : GUIPerson::drawAction_drawWalkingareaPath(const GUIVisualizationSettings& s) const {
     328            0 :     MSStageWalking* stage = dynamic_cast<MSStageWalking*>(getCurrentStage());
     329            0 :     if (stage != nullptr) {
     330            0 :         setColor(s);
     331            0 :         MSPModel_Striping::PState* stripingState = dynamic_cast<MSPModel_Striping::PState*>(stage->getPState());
     332            0 :         if (stripingState != nullptr) {
     333            0 :             const MSPModel_Striping::WalkingAreaPath* waPath = stripingState->myWalkingAreaPath;
     334            0 :             if (waPath != nullptr) {
     335            0 :                 GLHelper::pushMatrix();
     336            0 :                 glTranslated(0, 0, getType());
     337            0 :                 GLHelper::drawBoxLines(waPath->shape, 0.05);
     338            0 :                 GLHelper::popMatrix();
     339              :             }
     340              :         }
     341              :     }
     342            0 : }
     343              : 
     344              : void
     345            0 : GUIPerson::drawGLAdditional(GUISUMOAbstractView* const parent, const GUIVisualizationSettings& s) const {
     346            0 :     GLHelper::pushName(getGlID());
     347            0 :     GLHelper::pushMatrix();
     348            0 :     glTranslated(0, 0, getType() - .1); // don't draw on top of other cars
     349            0 :     if (hasActiveAddVisualisation(parent, VO_SHOW_WALKINGAREA_PATH)) {
     350            0 :         drawAction_drawWalkingareaPath(s);
     351              :     }
     352            0 :     if (hasActiveAddVisualisation(parent, VO_SHOW_ROUTE)) {
     353            0 :         if (getCurrentStageType() == MSStageType::WALKING) {
     354            0 :             setColor(s);
     355            0 :             RGBColor current = GLHelper::getColor();
     356            0 :             RGBColor darker = current.changedBrightness(-51);
     357            0 :             GLHelper::setColor(darker);
     358            0 :             MSStageWalking* stage = dynamic_cast<MSStageWalking*>(getCurrentStage());
     359              :             assert(stage != 0);
     360            0 :             const double exaggeration = getExaggeration(s);
     361              :             const ConstMSEdgeVector& edges = stage->getRoute();
     362            0 :             const bool s2 = s.secondaryShape;
     363            0 :             for (ConstMSEdgeVector::const_iterator it = edges.begin(); it != edges.end(); ++it) {
     364            0 :                 GUILane* lane = static_cast<GUILane*>((*it)->getLanes()[0]);
     365            0 :                 GLHelper::drawBoxLines(lane->getShape(s2), lane->getShapeRotations(s2), lane->getShapeLengths(s2), exaggeration);
     366              :             }
     367              :         }
     368              :     }
     369            0 :     GLHelper::popMatrix();
     370            0 :     GLHelper::popName();
     371            0 : }
     372              : 
     373              : 
     374              : void
     375       210566 : GUIPerson::setPositionInVehicle(const GUIBaseVehicle::Seat& pos) {
     376       210566 :     myPositionInVehicle = pos;
     377       210566 : }
     378              : 
     379              : 
     380              : void
     381      1194678 : GUIPerson::setColor(const GUIVisualizationSettings& s) const {
     382      1194678 :     RGBColor col;
     383              :     const GUIColorer& c = s.personColorer;
     384      1194678 :     if (!setFunctionalColor(c.getActive(), this, col)) {
     385       894933 :         col = c.getScheme().getColor(getColorValue(s, c.getActive()));
     386              :     }
     387      1194678 :     GLHelper::setColor(col);
     388      1194678 : }
     389              : 
     390              : 
     391              : bool
     392      1197904 : GUIPerson::setFunctionalColor(int activeScheme, const MSPerson* person, RGBColor& col) {
     393      1197904 :     switch (activeScheme) {
     394       728714 :         case 0: {
     395       728714 :             if (person->getParameter().wasSet(VEHPARS_COLOR_SET)) {
     396        39133 :                 col = person->getParameter().color;
     397        39133 :                 return true;
     398              :             }
     399       689581 :             if (person->getVehicleType().wasSet(VTYPEPARS_COLOR_SET)) {
     400       260686 :                 col = person->getVehicleType().getColor();
     401       260686 :                 return true;
     402              :             }
     403              :             return false;
     404              :         }
     405            0 :         case 2: {
     406            0 :             if (person->getParameter().wasSet(VEHPARS_COLOR_SET)) {
     407            0 :                 col = person->getParameter().color;
     408            0 :                 return true;
     409              :             }
     410              :             return false;
     411              :         }
     412            0 :         case 3: {
     413            0 :             if (person->getVehicleType().wasSet(VTYPEPARS_COLOR_SET)) {
     414            0 :                 col = person->getVehicleType().getColor();
     415            0 :                 return true;
     416              :             }
     417              :             return false;
     418              :         }
     419            0 :         case 9: { // color by angle
     420            0 :             double hue = GeomHelper::naviDegree(person->getAngle());
     421            0 :             col = RGBColor::fromHSV(hue, 1., 1.);
     422            0 :             return true;
     423              :         }
     424            0 :         case 10: { // color randomly (by pointer)
     425            0 :             const double hue = (double)((long long int)person % 360); // [0-360]
     426            0 :             const double sat = (double)(((long long int)person / 360) % 67) / 100. + 0.33; // [0.33-1]
     427            0 :             col = RGBColor::fromHSV(hue, sat, 1.);
     428            0 :             return true;
     429              :         }
     430              :         default:
     431              :             return false;
     432              :     }
     433              : }
     434              : 
     435              : 
     436              : double
     437       898085 : GUIPerson::getColorValue(const GUIVisualizationSettings& /* s */, int activeScheme) const {
     438       898085 :     switch (activeScheme) {
     439            0 :         case 4:
     440            0 :             switch (getCurrentStageType()) {
     441              :                 case MSStageType::WAITING:
     442              :                     return -1;
     443            0 :                 case MSStageType::WAITING_FOR_DEPART:
     444            0 :                     return -2;
     445            0 :                 default:
     446            0 :                     return getSpeed();
     447              :             }
     448       469190 :         case 5:
     449       469190 :             if (isWaiting4Vehicle()) {
     450              :                 return 5;
     451              :             } else {
     452       179820 :                 return (double)getCurrentStageType();
     453              :             }
     454            0 :         case 6:
     455            0 :             return getWaitingSeconds();
     456            0 :         case 7:
     457            0 :             return isJammed() ? 1 : 0;
     458            0 :         case 8:
     459            0 :             return gSelected.isSelected(GLO_PERSON, getGlID());
     460              :     }
     461              :     return 0;
     462              : }
     463              : 
     464              : 
     465              : double
     466       478848 : GUIPerson::getEdgePos() const {
     467       478848 :     FXMutexLock locker(myLock);
     468       478848 :     if (hasArrived()) {
     469              :         return -1;
     470              :     }
     471       478848 :     return MSPerson::getEdgePos();
     472              : }
     473              : 
     474              : int
     475        92712 : GUIPerson::getDirection() const {
     476        92712 :     FXMutexLock locker(myLock);
     477        92712 :     if (hasArrived()) {
     478            0 :         return MSPModel::UNDEFINED_DIRECTION;
     479              :     }
     480        92712 :     return MSPerson::getDirection();
     481              : }
     482              : 
     483              : 
     484              : Position
     485      1126239 : GUIPerson::getPosition() const {
     486      1126239 :     FXMutexLock locker(myLock);
     487      1126239 :     if (hasArrived()) {
     488            0 :         return Position::INVALID;
     489              :     }
     490      1126239 :     return MSPerson::getPosition();
     491              : }
     492              : 
     493              : 
     494              : Position
     495      1194678 : GUIPerson::getGUIPosition(const GUIVisualizationSettings* s) const {
     496      1194678 :     FXMutexLock locker(myLock);
     497      1194678 :     if (hasArrived()) {
     498            0 :         return Position::INVALID;
     499              :     }
     500      1194678 :     if (getCurrentStageType() == MSStageType::DRIVING) {
     501       517974 :         if (!isWaiting4Vehicle() && myPositionInVehicle.pos != Position::INVALID) {
     502       210417 :             if (s != nullptr) {
     503       210417 :                 return myPositionInVehicle.pos;
     504              :             } else {
     505              :                 // centering boundary must cover the vehicle regardless of exaggeration and zoom
     506            0 :                 SUMOVehicle* veh = getCurrentStage()->getVehicle();
     507            0 :                 if (veh == nullptr) {
     508              :                     // should not happen
     509            0 :                     return myPositionInVehicle.pos;
     510              :                 }
     511            0 :                 PositionVector b = veh->getBoundingBox();
     512            0 :                 if (b.around(myPositionInVehicle.pos)) {
     513            0 :                     return myPositionInVehicle.pos;
     514              :                 } else {
     515            0 :                     return b.getCentroid();
     516              :                 }
     517            0 :             }
     518              :         } else if (isWaiting4Vehicle()
     519       307408 :                    && s != nullptr
     520       307408 :                    && s->gaming
     521            0 :                    && getCurrentStage()->getOriginStop() != nullptr
     522       307557 :                    && s->addSize.getExaggeration(*s, nullptr) > 1) {
     523              :             // shift position away from stop center
     524            0 :             Position pos = MSPerson::getPosition();
     525            0 :             Position ref = getCurrentStage()->getOriginStop()->getCenterPos();
     526            0 :             Position shifted = ref + (pos - ref) * s->personSize.getExaggeration(*s, this);
     527            0 :             return shifted;
     528              :         }
     529              :     }
     530       984261 :     return MSPerson::getPosition();
     531              : }
     532              : 
     533              : 
     534              : double
     535      1194678 : GUIPerson::getGUIAngle() const {
     536      1194678 :     FXMutexLock locker(myLock);
     537      1194678 :     if (hasArrived()) {
     538              :         return INVALID_DOUBLE;
     539              :     }
     540      1712652 :     if (getCurrentStageType() == MSStageType::DRIVING && !isWaiting4Vehicle() && myPositionInVehicle.pos != Position::INVALID) {
     541       210417 :         return myPositionInVehicle.angle;
     542              :     } else {
     543       984261 :         return MSPerson::getAngle();
     544              :     }
     545              : }
     546              : 
     547              : 
     548              : double
     549            0 : GUIPerson::getNaviDegree() const {
     550            0 :     FXMutexLock locker(myLock);
     551            0 :     if (hasArrived()) {
     552              :         return INVALID_DOUBLE;
     553              :     }
     554            0 :     return GeomHelper::naviDegree(MSPerson::getAngle());
     555              : }
     556              : 
     557              : 
     558              : double
     559            2 : GUIPerson::getWaitingSeconds() const {
     560            2 :     FXMutexLock locker(myLock);
     561            2 :     if (hasArrived()) {
     562              :         return -1;
     563              :     }
     564            2 :     return MSPerson::getWaitingSeconds();
     565              : }
     566              : 
     567              : 
     568              : double
     569       251617 : GUIPerson::getSpeed() const {
     570       251617 :     FXMutexLock locker(myLock);
     571       251617 :     if (hasArrived()) {
     572              :         return -1;
     573              :     }
     574       251617 :     return MSPerson::getSpeed();
     575              : }
     576              : 
     577              : 
     578              : std::string
     579            0 : GUIPerson::getStageIndexDescription() const {
     580            0 :     FXMutexLock locker(myLock);
     581            0 :     if (hasArrived()) {
     582            0 :         return "arrived";
     583              :     }
     584              :     // there is always the "start" stage which we do not count here because it is not strictly part of the plan
     585            0 :     return toString(getCurrentStageIndex()) + " of " + toString(getNumStages() - 1);
     586              : }
     587              : 
     588              : 
     589              : std::string
     590            0 : GUIPerson::getEdgeID() const {
     591            0 :     FXMutexLock locker(myLock);
     592            0 :     if (hasArrived()) {
     593            0 :         return "arrived";
     594              :     }
     595            0 :     return  getEdge()->getID();
     596              : }
     597              : 
     598              : 
     599              : std::string
     600            0 : GUIPerson::getLaneID() const {
     601            0 :     FXMutexLock locker(myLock);
     602            0 :     if (hasArrived()) {
     603            0 :         return "arrived";
     604              :     }
     605            0 :     return getLane() != nullptr ? getLane()->getID() : "";
     606              : }
     607              : 
     608              : 
     609              : std::string
     610            0 : GUIPerson::getFromEdgeID() const {
     611            0 :     FXMutexLock locker(myLock);
     612            0 :     if (hasArrived()) {
     613            0 :         return "arrived";
     614              :     }
     615              :     return getFromEdge()->getID();
     616              : }
     617              : 
     618              : 
     619              : std::string
     620            0 : GUIPerson::getDestinationEdgeID() const {
     621            0 :     FXMutexLock locker(myLock);
     622            0 :     if (hasArrived()) {
     623            0 :         return "arrived";
     624              :     }
     625              :     return getDestination()->getID();
     626              : }
     627              : 
     628              : 
     629              : std::string
     630            0 : GUIPerson::getDestinationStopID() const {
     631            0 :     FXMutexLock locker(myLock);
     632            0 :     if (hasArrived()) {
     633            0 :         return "";
     634              :     }
     635              :     MSStoppingPlace* destStop = getCurrentStage()->getDestinationStop();
     636            0 :     if (destStop != nullptr) {
     637              :         return destStop->getID();
     638              :     } else {
     639            0 :         return "";
     640              :     }
     641              : }
     642              : 
     643              : 
     644              : std::string
     645            0 : GUIPerson::getVehicleID() const {
     646            0 :     FXMutexLock locker(myLock);
     647            0 :     if (hasArrived()) {
     648            0 :         return "";
     649              :     }
     650            0 :     SUMOVehicle* veh = getCurrentStage()->getVehicle();
     651            0 :     if (veh != nullptr) {
     652              :         return veh->getID();
     653              :     } else {
     654            0 :         return "";
     655              :     }
     656              : }
     657              : 
     658              : 
     659              : double
     660            0 : GUIPerson::getStopDuration() const {
     661            0 :     FXMutexLock locker(myLock);
     662            0 :     if (hasArrived()) {
     663              :         return -1;
     664              :     }
     665            0 :     if (getCurrentStage()->getStageType() == MSStageType::WAITING) {
     666            0 :         return STEPS2TIME(dynamic_cast<MSStageWaiting*>(getCurrentStage())->getStopEnd() - SIMSTEP);
     667              :     } else {
     668              :         return -1;
     669              :     }
     670              : }
     671              : 
     672              : 
     673              : double
     674            0 : GUIPerson::getStageArrivalPos() const {
     675            0 :     FXMutexLock locker(myLock);
     676            0 :     if (hasArrived()) {
     677              :         return INVALID_DOUBLE;
     678              :     }
     679            0 :     return getCurrentStage()->getArrivalPos();
     680              : }
     681              : 
     682              : bool
     683        59368 : GUIPerson::proceed(MSNet* net, SUMOTime time, const bool vehicleArrived) {
     684              :     // acquire lock before locking the person to avoid mutual deadlock (#9468)
     685        59368 :     ScopedLocker<const MSEdge, true> edgeLocker(*getEdge());
     686        59368 :     FXMutexLock locker(myLock);
     687       118711 :     return MSTransportable::proceed(net, time, vehicleArrived);
     688              : }
     689              : 
     690              : // -------------------------------------------------------------------------
     691              : // GUIPerson - Additional Visualsation methods
     692              : // -------------------------------------------------------------------------
     693              : 
     694              : bool
     695            0 : GUIPerson::hasActiveAddVisualisation(GUISUMOAbstractView* const parent, int which) const {
     696            0 :     return myAdditionalVisualizations.find(parent) != myAdditionalVisualizations.end() && (myAdditionalVisualizations.find(parent)->second & which) != 0;
     697              : }
     698              : 
     699              : 
     700              : void
     701            0 : GUIPerson::addActiveAddVisualisation(GUISUMOAbstractView* const parent, int which) {
     702            0 :     if (myAdditionalVisualizations.find(parent) == myAdditionalVisualizations.end()) {
     703            0 :         myAdditionalVisualizations[parent] = 0;
     704              :     }
     705            0 :     myAdditionalVisualizations[parent] |= which;
     706            0 :     parent->addAdditionalGLVisualisation(this);
     707            0 : }
     708              : 
     709              : 
     710              : void
     711            0 : GUIPerson::removeActiveAddVisualisation(GUISUMOAbstractView* const parent, int which) {
     712            0 :     myAdditionalVisualizations[parent] &= ~which;
     713            0 :     parent->removeAdditionalGLVisualisation(this);
     714            0 : }
     715              : 
     716              : bool
     717     32955357 : GUIPerson::isSelected() const {
     718     32955357 :     return gSelected.isSelected(GLO_PERSON, getGlID());
     719              : }
     720              : 
     721              : 
     722              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1