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