Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/elements/network/GNEWalkingArea.cpp
185790 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 GNEWalkingArea.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date Jun 2022
17
///
18
// A class for visualizing and editing WalkingAreas
19
/****************************************************************************/
20
21
#include <netedit/GNENet.h>
22
#include <netedit/GNETagProperties.h>
23
#include <netedit/changes/GNEChange_Attribute.h>
24
#include <utils/gui/div/GLHelper.h>
25
#include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
26
#include <utils/gui/windows/GUIAppEnum.h>
27
#include <utils/gui/div/GUIDesigns.h>
28
29
#include "GNEWalkingArea.h"
30
31
// ===========================================================================
32
// method definitions
33
// ===========================================================================
34
35
GNEWalkingArea::GNEWalkingArea(GNEJunction* junction, const std::string& ID) :
36
GNENetworkElement(junction->getNet(), ID, SUMO_TAG_WALKINGAREA),
37
myTesselation(ID, "", RGBColor::GREY, junction->getNBNode()->getWalkingArea(ID).shape, false, true, 0) {
38
// set parent
39
setParent<GNEJunction*>(junction);
40
}
41
42
43
GNEWalkingArea::~GNEWalkingArea() {
44
}
45
46
47
GNEMoveElement*
48
GNEWalkingArea::getMoveElement() const {
49
return nullptr;
50
}
51
52
53
Parameterised*
54
GNEWalkingArea::getParameters() {
55
return nullptr;
56
}
57
58
59
const Parameterised*
60
GNEWalkingArea::getParameters() const {
61
return nullptr;
62
}
63
64
65
void
66
GNEWalkingArea::updateGeometry() {
67
// Nothing to update
68
}
69
70
71
Position
72
GNEWalkingArea::getPositionInView() const {
73
return getParentJunctions().front()->getPositionInView();
74
}
75
76
77
bool
78
GNEWalkingArea::checkDrawFromContour() const {
79
return false;
80
}
81
82
83
bool
84
GNEWalkingArea::checkDrawToContour() const {
85
return false;
86
}
87
88
89
bool
90
GNEWalkingArea::checkDrawRelatedContour() const {
91
// check opened popup
92
if (myNet->getViewNet()->getPopup()) {
93
return myNet->getViewNet()->getPopup()->getGLObject() == this;
94
}
95
return false;
96
}
97
98
99
bool
100
GNEWalkingArea::checkDrawOverContour() const {
101
return false;
102
}
103
104
105
bool
106
GNEWalkingArea::checkDrawDeleteContour() const {
107
// get edit modes
108
const auto& editModes = myNet->getViewNet()->getEditModes();
109
// check if we're in delete mode
110
if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_DELETE)) {
111
return myNet->getViewNet()->checkOverLockedElement(this, mySelected);
112
} else {
113
return false;
114
}
115
}
116
117
118
bool
119
GNEWalkingArea::checkDrawDeleteContourSmall() const {
120
return false;
121
}
122
123
124
bool
125
GNEWalkingArea::checkDrawSelectContour() const {
126
// get edit modes
127
const auto& editModes = myNet->getViewNet()->getEditModes();
128
// check if we're in select mode
129
if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_SELECT)) {
130
return myNet->getViewNet()->checkOverLockedElement(this, mySelected);
131
} else {
132
return false;
133
}
134
}
135
136
137
bool
138
GNEWalkingArea::checkDrawMoveContour() const {
139
return false;
140
}
141
142
143
NBNode::WalkingArea&
144
GNEWalkingArea::getNBWalkingArea() const {
145
return getParentJunctions().front()->getNBNode()->getWalkingArea(getMicrosimID());
146
}
147
148
149
void
150
GNEWalkingArea::drawGL(const GUIVisualizationSettings& s) const {
151
// declare variables
152
const double walkingAreaExaggeration = getExaggeration(s);
153
// get walking area shape
154
const auto& walkingAreaShape = getParentJunctions().front()->getNBNode()->getWalkingArea(getID()).shape;
155
// only continue if exaggeration is greater than 0 and junction's shape is greater than 4
156
if ((getParentJunctions().front()->getNBNode()->getShape().area() > 4) &&
157
(walkingAreaShape.size() > 0) && s.drawCrossingsAndWalkingareas) {
158
// don't draw this walking area if we're editing their junction parent
159
const GNENetworkElement* editedNetworkElement = myNet->getViewNet()->getEditNetworkElementShapes().getEditedNetworkElement();
160
if (!editedNetworkElement || (editedNetworkElement != getParentJunctions().front())) {
161
const auto contourMode = drawInContourMode();
162
// get detail level
163
const auto d = s.getDetailLevel(walkingAreaExaggeration);
164
// draw geometry only if we'rent in drawForObjectUnderCursor mode
165
if (!s.drawForViewObjectsHandler) {
166
// draw walking area
167
if (!contourMode) {
168
drawWalkingArea(s, d, walkingAreaShape, walkingAreaExaggeration);
169
}
170
// draw walkingArea name
171
if (s.cwaEdgeName.show(this)) {
172
drawName(walkingAreaShape.getCentroid(), s.scale, s.edgeName, 0, true);
173
}
174
// draw dotted contour
175
if (contourMode) {
176
myNetworkElementContour.drawDottedContour(s, GUIDottedGeometry::DottedContourType::WALKINGAREA, s.dottedContourSettings.segmentWidth, false);
177
} else {
178
myNetworkElementContour.drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidth, true);
179
}
180
}
181
// draw dotted contour (except in contour mode) checking if junction parent was inserted with full boundary
182
myNetworkElementContour.calculateContourClosedShape(s, d, this, walkingAreaShape, getType(),
183
walkingAreaExaggeration, getParentJunctions().front(), !contourMode);
184
}
185
}
186
}
187
188
189
void
190
GNEWalkingArea::deleteGLObject() {
191
// currently WalkingAreas cannot be removed
192
}
193
194
195
void
196
GNEWalkingArea::updateGLObject() {
197
updateGeometry();
198
}
199
200
201
GUIGLObjectPopupMenu*
202
GNEWalkingArea::getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) {
203
// create popup
204
GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
205
// build common options
206
buildPopUpMenuCommonOptions(ret, app, myNet->getViewNet(), myTagProperty->getTag(), mySelected);
207
// check if we're in supermode network
208
if (myNet->getViewNet()->getEditModes().isCurrentSupermodeNetwork()) {
209
// create menu commands
210
FXMenuCommand* mcCustomShape = GUIDesigns::buildFXMenuCommand(ret, "Set custom WalkingArea shape", nullptr, &parent, MID_GNE_WALKINGAREA_EDIT_SHAPE);
211
// check if menu commands has to be disabled
212
NetworkEditMode editMode = myNet->getViewNet()->getEditModes().networkEditMode;
213
if ((editMode == NetworkEditMode::NETWORK_CONNECT) || (editMode == NetworkEditMode::NETWORK_TLS) || (editMode == NetworkEditMode::NETWORK_CREATE_EDGE)) {
214
mcCustomShape->disable();
215
}
216
// disabled for release 1.15
217
mcCustomShape->disable();
218
}
219
return ret;
220
}
221
222
223
Boundary
224
GNEWalkingArea::getCenteringBoundary() const {
225
return myNetworkElementContour.getContourBoundary();
226
}
227
228
229
void
230
GNEWalkingArea::updateCenteringBoundary(const bool /*updateGrid*/) {
231
// nothing to update
232
}
233
234
235
std::string
236
GNEWalkingArea::getAttribute(SumoXMLAttr key) const {
237
if (key == SUMO_ATTR_ID) {
238
// for security purposes, avoid get WalkingArea if we want only the ID
239
return getMicrosimID();
240
}
241
const auto& walkingArea = getNBWalkingArea();
242
switch (key) {
243
case SUMO_ATTR_WIDTH:
244
return toString(walkingArea.width);
245
case SUMO_ATTR_LENGTH:
246
return toString(walkingArea.length);
247
case SUMO_ATTR_SHAPE:
248
return toString(walkingArea.shape);
249
default:
250
return getCommonAttribute(key);
251
}
252
}
253
254
255
double
256
GNEWalkingArea::getAttributeDouble(SumoXMLAttr key) const {
257
return getCommonAttributeDouble(key);
258
}
259
260
261
Position
262
GNEWalkingArea::getAttributePosition(SumoXMLAttr key) const {
263
return getCommonAttributePosition(key);
264
}
265
266
267
PositionVector
268
GNEWalkingArea::getAttributePositionVector(SumoXMLAttr key) const {
269
switch (key) {
270
case SUMO_ATTR_SHAPE:
271
return getNBWalkingArea().shape;
272
default:
273
return getCommonAttributePositionVector(key);
274
}
275
}
276
277
278
void
279
GNEWalkingArea::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
280
if (value == getAttribute(key)) {
281
return; //avoid needless changes, later logic relies on the fact that attributes have changed
282
}
283
switch (key) {
284
case SUMO_ATTR_ID:
285
throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + getTagStr() + " isn't allowed");
286
case SUMO_ATTR_WIDTH:
287
case SUMO_ATTR_LENGTH:
288
case SUMO_ATTR_SHAPE:
289
GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);
290
break;
291
default:
292
setCommonAttribute(key, value, undoList);
293
break;
294
}
295
}
296
297
298
bool
299
GNEWalkingArea::isAttributeEnabled(SumoXMLAttr key) const {
300
switch (key) {
301
case GNE_ATTR_SELECTED:
302
return true;
303
default:
304
return false;
305
}
306
}
307
308
309
bool
310
GNEWalkingArea::isValid(SumoXMLAttr key, const std::string& value) {
311
switch (key) {
312
case SUMO_ATTR_ID:
313
return false;
314
case SUMO_ATTR_WIDTH:
315
case SUMO_ATTR_LENGTH:
316
return canParse<double>(value) && (parse<double>(value) > 0);
317
case SUMO_ATTR_SHAPE:
318
if (canParse<PositionVector>(value)) {
319
return parse<PositionVector>(value).size() > 0;
320
} else {
321
return false;
322
}
323
default:
324
return isCommonAttributeValid(key, value);
325
}
326
}
327
328
// ===========================================================================
329
// private
330
// ===========================================================================
331
332
void
333
GNEWalkingArea::drawWalkingArea(const GUIVisualizationSettings& s, const GUIVisualizationSettings::Detail d,
334
const PositionVector& shape, const double exaggeration) const {
335
// adjust shape to exaggeration
336
if (((exaggeration > 1) || (myExaggeration > 1)) && (exaggeration != myExaggeration)) {
337
myExaggeration = exaggeration;
338
myTesselation.setShape(shape);
339
myTesselation.getShapeRef().closePolygon();
340
myTesselation.getShapeRef().scaleRelative(exaggeration);
341
myTesselation.myTesselation.clear();
342
}
343
// push layer matrix
344
GLHelper::pushMatrix();
345
// translate to front
346
drawInLayer(GLO_WALKINGAREA, 0.1);
347
// set color
348
if (myShapeEdited) {
349
GLHelper::setColor(s.colorSettings.editShapeColor);
350
} else if (isAttributeCarrierSelected()) {
351
GLHelper::setColor(RGBColor::BLUE);
352
} else {
353
GLHelper::setColor(s.junctionColorer.getScheme().getColor(6));
354
}
355
// check if draw walking area tesselated or contour
356
if (drawInContourMode()) {
357
myInnenContour.drawInnenContourClosed(s, d, shape, exaggeration, s.dottedContourSettings.segmentWidth);
358
} else {
359
drawTesselatedWalkingArea(s, d);
360
}
361
// pop layer Matrix
362
GLHelper::popMatrix();
363
}
364
365
366
bool
367
GNEWalkingArea::drawInContourMode() const {
368
const auto& modes = myNet->getViewNet()->getEditModes();
369
// check modes
370
if (!modes.isCurrentSupermodeNetwork()) {
371
return true;
372
} else if (modes.networkEditMode == NetworkEditMode::NETWORK_MOVE) {
373
return true;
374
} else if (modes.networkEditMode == NetworkEditMode::NETWORK_DELETE) {
375
return true;
376
} else if (modes.networkEditMode == NetworkEditMode::NETWORK_CONNECT) {
377
return true;
378
} else {
379
return false;
380
}
381
}
382
383
384
void
385
GNEWalkingArea::drawTesselatedWalkingArea(const GUIVisualizationSettings& s, const GUIVisualizationSettings::Detail d) const {
386
// check if draw polygon or tesselation
387
if (d <= GUIVisualizationSettings::Detail::JunctionElementDetails) {
388
// draw shape with high detail
389
myTesselation.drawTesselation(myTesselation.getShape());
390
} else {
391
// draw shape
392
GLHelper::drawFilledPoly(myTesselation.getShape(), true);
393
}
394
// draw shape points only in Network supemode
395
if (myShapeEdited && s.drawMovingGeometryPoint(1, s.neteditSizeSettings.junctionGeometryPointRadius)) {
396
// draw geometry points
397
GUIGeometry::drawGeometryPoints(d, myTesselation.getShape(), GLHelper::getColor().changedBrightness(-32),
398
s.neteditSizeSettings.crossingGeometryPointRadius, 1,
399
myNet->getViewNet()->getNetworkViewOptions().editingElevation());
400
}
401
}
402
403
404
void
405
GNEWalkingArea::setAttribute(SumoXMLAttr key, const std::string& value) {
406
auto& walkingArea = getNBWalkingArea();
407
switch (key) {
408
case SUMO_ATTR_ID:
409
throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + getTagStr() + " isn't allowed");
410
case SUMO_ATTR_WIDTH:
411
walkingArea.width = parse<double>(value);
412
break;
413
case SUMO_ATTR_LENGTH:
414
walkingArea.length = parse<double>(value);
415
break;
416
case SUMO_ATTR_SHAPE:
417
walkingArea.shape = parse<PositionVector>(value);
418
walkingArea.hasCustomShape = true;
419
break;
420
default:
421
setCommonAttribute(key, value);
422
break;
423
}
424
}
425
426
/****************************************************************************/
427
428