Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/guisim/GUILaneSpeedTrigger.cpp
169666 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 GUILaneSpeedTrigger.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Michael Behrisch
18
/// @date Mon, 26.04.2004
19
///
20
// Changes the speed allowed on a set of lanes (gui version)
21
/****************************************************************************/
22
#include <config.h>
23
24
#include <string>
25
#include <utils/common/MsgHandler.h>
26
#include <utils/geom/PositionVector.h>
27
#include <utils/geom/Boundary.h>
28
#include <utils/gui/div/GLHelper.h>
29
#include <utils/common/ToString.h>
30
#include <utils/common/Command.h>
31
#include <microsim/MSNet.h>
32
#include <microsim/MSLane.h>
33
#include <microsim/MSEdge.h>
34
#include <guisim/GUINet.h>
35
#include <guisim/GUIEdge.h>
36
#include "GUILaneSpeedTrigger.h"
37
#include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
38
#include <utils/gui/windows/GUIAppEnum.h>
39
#include <gui/GUIGlobals.h>
40
#include <utils/gui/div/GUIParameterTableWindow.h>
41
#include <gui/GUIApplicationWindow.h>
42
#include <microsim/logging/FunctionBinding.h>
43
#include <utils/gui/div/GUIGlobalSelection.h>
44
#include <utils/gui/images/GUIIconSubSys.h>
45
#include <guisim/GUILaneSpeedTrigger.h>
46
#include <utils/gui/globjects/GLIncludes.h>
47
#include <utils/gui/div/GUIDesigns.h>
48
49
50
// ===========================================================================
51
// FOX callback mapping
52
// ===========================================================================
53
/* -------------------------------------------------------------------------
54
* GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu - mapping
55
* ----------------------------------------------------------------------- */
56
FXDEFMAP(GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu)
57
GUILaneSpeedTriggerPopupMenuMap[] = {
58
FXMAPFUNC(SEL_COMMAND, MID_MANIP, GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu::onCmdOpenManip),
59
60
};
61
62
// Object implementation
63
FXIMPLEMENT(GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu, GUIGLObjectPopupMenu, GUILaneSpeedTriggerPopupMenuMap, ARRAYNUMBER(GUILaneSpeedTriggerPopupMenuMap))
64
65
66
/* -------------------------------------------------------------------------
67
* GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger - mapping
68
* ----------------------------------------------------------------------- */
69
FXDEFMAP(GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger) GUIManip_LaneSpeedTriggerMap[] = {
70
FXMAPFUNC(SEL_COMMAND, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_USER_DEF, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdUserDef),
71
FXMAPFUNC(SEL_UPDATE, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_USER_DEF, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onUpdUserDef),
72
FXMAPFUNC(SEL_COMMAND, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_PRE_DEF, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdPreDef),
73
FXMAPFUNC(SEL_UPDATE, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_PRE_DEF, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onUpdPreDef),
74
FXMAPFUNC(SEL_COMMAND, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_OPTION, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdChangeOption),
75
FXMAPFUNC(SEL_COMMAND, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_CLOSE, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdClose),
76
};
77
78
FXIMPLEMENT(GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger, GUIManipulator, GUIManip_LaneSpeedTriggerMap, ARRAYNUMBER(GUIManip_LaneSpeedTriggerMap))
79
80
81
// ===========================================================================
82
// method definitions
83
// ===========================================================================
84
/* -------------------------------------------------------------------------
85
* GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger - methods
86
* ----------------------------------------------------------------------- */
87
GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::GUIManip_LaneSpeedTrigger(
88
GUIMainWindow& app,
89
const std::string& name, GUILaneSpeedTrigger& o,
90
int /*xpos*/, int /*ypos*/)
91
: GUIManipulator(app, name, 0, 0),
92
myParent(&app), myChosenValue(0), myChosenTarget(myChosenValue, nullptr, MID_OPTION),
93
mySpeed(o.getDefaultSpeed()), mySpeedTarget(mySpeed),
94
myObject(&o) {
95
myChosenTarget.setTarget(this);
96
FXVerticalFrame* f1 =
97
new FXVerticalFrame(this, LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0);
98
99
FXGroupBox* gp = new FXGroupBox(f1, "Change Speed",
100
GROUPBOX_TITLE_LEFT | FRAME_RIDGE,
101
0, 0, 0, 0, 4, 4, 1, 1, 2, 0);
102
{
103
// default
104
FXHorizontalFrame* gf1 =
105
new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
106
new FXRadioButton(gf1, "Default", &myChosenTarget, FXDataTarget::ID_OPTION + 0,
107
ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
108
0, 0, 0, 0, 2, 2, 0, 0);
109
}
110
{
111
// loaded
112
FXHorizontalFrame* gf0 =
113
new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
114
new FXRadioButton(gf0, "Loaded", &myChosenTarget, FXDataTarget::ID_OPTION + 1,
115
ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
116
0, 0, 0, 0, 2, 2, 0, 0);
117
}
118
{
119
// predefined
120
FXHorizontalFrame* gf2 =
121
new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
122
new FXRadioButton(gf2, "Predefined: ", &myChosenTarget, FXDataTarget::ID_OPTION + 2,
123
ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y,
124
0, 0, 0, 0, 2, 2, 0, 0);
125
myPredefinedValues = new MFXComboBoxIcon(gf2, nullptr, false, GUIDesignComboBoxVisibleItems, this, MID_PRE_DEF,
126
ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y | COMBOBOX_STATIC);
127
myPredefinedValues->appendIconItem("20 km/h");
128
myPredefinedValues->appendIconItem("40 km/h");
129
myPredefinedValues->appendIconItem("60 km/h");
130
myPredefinedValues->appendIconItem("80 km/h");
131
myPredefinedValues->appendIconItem("100 km/h");
132
myPredefinedValues->appendIconItem("120 km/h");
133
myPredefinedValues->appendIconItem("140 km/h");
134
myPredefinedValues->appendIconItem("160 km/h");
135
myPredefinedValues->appendIconItem("180 km/h");
136
myPredefinedValues->appendIconItem("200 km/h");
137
}
138
{
139
// free
140
FXHorizontalFrame* gf12 =
141
new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
142
new FXRadioButton(gf12, "Free Entry: ", &myChosenTarget, FXDataTarget::ID_OPTION + 3,
143
ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y,
144
0, 0, 0, 0, 2, 2, 0, 0);
145
myUserDefinedSpeed =
146
new FXRealSpinner(gf12, 10, this, MID_USER_DEF,
147
LAYOUT_TOP | FRAME_SUNKEN | FRAME_THICK);
148
//myUserDefinedSpeed->setFormatString("%.0f km/h");
149
//myUserDefinedSpeed->setIncrements(1, 10, 10);
150
myUserDefinedSpeed->setIncrement(10);
151
myUserDefinedSpeed->setRange(0, 300);
152
myUserDefinedSpeed->setValue(myObject->getDefaultSpeed() * 3.6);
153
}
154
GUIDesigns::buildFXButton(f1, "Close", "", "", nullptr, this, MID_CLOSE,
155
BUTTON_INITIAL | BUTTON_DEFAULT | FRAME_RAISED | FRAME_THICK | LAYOUT_TOP | LAYOUT_LEFT | LAYOUT_CENTER_X, 0, 0, 0, 0, 30, 30, 4, 4);
156
myObject->setOverriding(true);
157
}
158
159
160
GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::~GUIManip_LaneSpeedTrigger() {}
161
162
163
long
164
GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdClose(FXObject*, FXSelector, void*) {
165
destroy();
166
return 1;
167
}
168
169
170
long
171
GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdUserDef(FXObject*, FXSelector, void*) {
172
mySpeed = myUserDefinedSpeed->getValue() / 3.6;
173
myObject->setOverridingValue(mySpeed);
174
myParent->updateChildren();
175
return 1;
176
}
177
178
179
long
180
GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onUpdUserDef(FXObject* sender, FXSelector, void* ptr) {
181
sender->handle(this,
182
myChosenValue != 3 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
183
ptr);
184
myParent->updateChildren();
185
return 1;
186
}
187
188
189
long
190
GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdPreDef(FXObject*, FXSelector, void*) {
191
mySpeed = ((double)myPredefinedValues->getCurrentItem() * 20. + 20.) / 3.6;
192
myObject->setOverridingValue(mySpeed);
193
myParent->updateChildren();
194
return 1;
195
}
196
197
198
long
199
GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onUpdPreDef(FXObject* sender, FXSelector, void* ptr) {
200
sender->handle(this,
201
myChosenValue != 2 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
202
ptr);
203
myParent->updateChildren();
204
return 1;
205
}
206
207
208
long
209
GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdChangeOption(FXObject*, FXSelector, void*) {
210
myObject->setOverriding(true);
211
switch (myChosenValue) {
212
case 0:
213
mySpeed = myObject->getDefaultSpeed();
214
break;
215
case 1:
216
mySpeed = myObject->getLoadedSpeed();
217
break;
218
case 2:
219
mySpeed = ((double)myPredefinedValues->getCurrentItem() * 20. + 20.) / 3.6;
220
break;
221
case 3:
222
mySpeed = myUserDefinedSpeed->getValue() / 3.6;
223
break;
224
default:
225
// hmmm, should not happen
226
break;
227
}
228
myObject->setOverridingValue(mySpeed);
229
myParent->updateChildren();
230
if (myChosenValue == 1) {
231
// !!! lock in between
232
myObject->setOverriding(false);
233
}
234
return 1;
235
}
236
237
238
239
/* -------------------------------------------------------------------------
240
* GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu - methods
241
* ----------------------------------------------------------------------- */
242
GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu::GUILaneSpeedTriggerPopupMenu(
243
GUIMainWindow& app, GUISUMOAbstractView& parent, GUIGlObject* o) :
244
GUIGLObjectPopupMenu(app, parent, o) {}
245
246
247
GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu::~GUILaneSpeedTriggerPopupMenu() {}
248
249
250
long
251
GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu::onCmdOpenManip(FXObject*,
252
FXSelector,
253
void*) {
254
static_cast<GUILaneSpeedTrigger*>(myObject)->openManipulator(
255
*myApplication, *myParent);
256
return 1;
257
}
258
259
// -------------------------------------------------------------------------
260
// GUILaneSpeedTrigger - methods
261
// -------------------------------------------------------------------------
262
263
GUILaneSpeedTrigger::GUILaneSpeedTrigger(
264
const std::string& id, const std::vector<MSLane*>& destLanes,
265
const std::string& aXMLFilename) :
266
MSLaneSpeedTrigger(id, destLanes, aXMLFilename),
267
GUIGlObject_AbstractAdd(GLO_VSS, id, GUIIconSubSys::getIcon(GUIIcon::VARIABLESPEEDSIGN)),
268
myShowAsKMH(true), myLastValue(-1) {
269
myFGPositions.reserve(destLanes.size());
270
myFGRotations.reserve(destLanes.size());
271
std::vector<MSLane*>::const_iterator i;
272
for (i = destLanes.begin(); i != destLanes.end(); ++i) {
273
const PositionVector& v = (*i)->getShape();
274
myFGPositions.push_back(v.positionAtOffset(0));
275
myBoundary.add(v.positionAtOffset(0));
276
myFGRotations.push_back(-v.rotationDegreeAtOffset(0));
277
}
278
}
279
280
281
GUILaneSpeedTrigger::~GUILaneSpeedTrigger() {}
282
283
284
GUIGLObjectPopupMenu*
285
GUILaneSpeedTrigger::getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) {
286
GUIGLObjectPopupMenu* ret = new GUILaneSpeedTriggerPopupMenu(app, parent, this);
287
buildPopupHeader(ret, app);
288
buildCenterPopupEntry(ret);
289
buildShowManipulatorPopupEntry(ret);
290
buildNameCopyPopupEntry(ret);
291
buildSelectionPopupEntry(ret);
292
buildShowParamsPopupEntry(ret);
293
buildPositionCopyEntry(ret, app);
294
return ret;
295
}
296
297
298
GUIParameterTableWindow*
299
GUILaneSpeedTrigger::getParameterWindow(GUIMainWindow& app, GUISUMOAbstractView&) {
300
GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
301
// add items
302
ret->mkItem(TL("speed [m/s]"), true,
303
new FunctionBinding<GUILaneSpeedTrigger, double>(this, &GUILaneSpeedTrigger::getCurrentSpeed));
304
// close building
305
ret->closeBuilding();
306
return ret;
307
}
308
309
310
void
311
GUILaneSpeedTrigger::drawGL(const GUIVisualizationSettings& s) const {
312
GLHelper::pushName(getGlID());
313
GLHelper::pushMatrix();
314
glTranslated(0, 0, getType());
315
const double exaggeration = getExaggeration(s);
316
for (int i = 0; i < (int)myFGPositions.size(); ++i) {
317
const Position& pos = myFGPositions[i];
318
double rot = myFGRotations[i];
319
GLHelper::pushMatrix();
320
glTranslated(pos.x(), pos.y(), 0);
321
glRotated(rot, 0, 0, 1);
322
glTranslated(0, -1.5, 0);
323
glScaled(exaggeration, exaggeration, 1);
324
int noPoints = 9;
325
if (s.scale > 25) {
326
noPoints = (int)(9.0 + s.scale / 10.0);
327
if (noPoints > 36) {
328
noPoints = 36;
329
}
330
}
331
glColor3d(1, 0, 0);
332
GLHelper::drawFilledCircle((double) 1.3, noPoints);
333
if (s.scale >= 5) {
334
glTranslated(0, 0, .1);
335
glColor3d(0, 0, 0);
336
GLHelper::drawFilledCircle((double) 1.1, noPoints);
337
// draw the speed string
338
// not if scale to low
339
// compute
340
double value = (double) getCurrentSpeed();
341
if (myShowAsKMH) {
342
value *= 3.6f;
343
if (((int) value + 1) % 10 == 0) {
344
value = (double)(((int) value + 1) / 10 * 10);
345
}
346
}
347
if (value != myLastValue) {
348
myLastValue = value;
349
myLastValueString = toString<double>(myLastValue);
350
std::string::size_type idx = myLastValueString.find('.');
351
if (idx != std::string::npos) {
352
if (idx > myLastValueString.length()) {
353
idx = myLastValueString.length();
354
}
355
myLastValueString = myLastValueString.substr(0, idx);
356
}
357
}
358
//draw
359
glColor3d(1, 1, 0);
360
glTranslated(0, 0, .1);
361
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
362
// draw last value string
363
GLHelper::drawText(myLastValueString.c_str(), Position(0, 0), .1, 1.2, RGBColor(255, 255, 0), 180);
364
}
365
GLHelper::popMatrix();
366
}
367
GLHelper::popMatrix();
368
drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
369
GLHelper::popName();
370
}
371
372
373
double
374
GUILaneSpeedTrigger::getExaggeration(const GUIVisualizationSettings& s) const {
375
return s.addSize.getExaggeration(s, this);
376
}
377
378
379
Boundary
380
GUILaneSpeedTrigger::getCenteringBoundary() const {
381
Boundary b(myBoundary);
382
b.grow(20);
383
return b;
384
}
385
386
387
GUIManipulator*
388
GUILaneSpeedTrigger::openManipulator(GUIMainWindow& app,
389
GUISUMOAbstractView&) {
390
GUIManip_LaneSpeedTrigger* gui =
391
new GUIManip_LaneSpeedTrigger(app, getFullName(), *this, 0, 0);
392
gui->create();
393
gui->show();
394
return gui;
395
}
396
397
398
/****************************************************************************/
399
400