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 : /****************************************************************************/
|