Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/elements/network/GNECrossing.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 GNECrossing.cpp
15
/// @author Jakob Erdmann
16
/// @date June 2011
17
///
18
// A class for visualizing Inner Lanes (used when editing traffic lights)
19
/****************************************************************************/
20
21
#include <netedit/changes/GNEChange_Attribute.h>
22
#include <netedit/elements/moving/GNEMoveElementCrossing.h>
23
#include <netedit/GNENet.h>
24
#include <netedit/GNETagProperties.h>
25
#include <utils/gui/div/GLHelper.h>
26
#include <utils/gui/div/GUIDesigns.h>
27
#include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
28
#include <utils/gui/windows/GUIAppEnum.h>
29
30
#include "GNECrossing.h"
31
32
// ===========================================================================
33
// method definitions
34
// ===========================================================================
35
36
GNECrossing::GNECrossing(GNENet* net) :
37
GNENetworkElement(net, "", SUMO_TAG_CROSSING),
38
myMoveElementCrossing(new GNEMoveElementCrossing(this)),
39
myTemplateNBCrossing(new NBNode::Crossing(nullptr, {}, 0, false, 0, 0, {})) {
40
}
41
42
43
GNECrossing::GNECrossing(GNEJunction* junction, std::vector<NBEdge*> crossingEdges) :
44
GNENetworkElement(junction->getNet(), junction->getNBNode()->getCrossing(crossingEdges)->id, SUMO_TAG_CROSSING),
45
myMoveElementCrossing(new GNEMoveElementCrossing(this)),
46
myCrossingEdges(crossingEdges),
47
myTemplateNBCrossing(nullptr) {
48
// set parent
49
setParent<GNEJunction*>(junction);
50
}
51
52
53
GNECrossing::~GNECrossing() {
54
if (myTemplateNBCrossing) {
55
delete myTemplateNBCrossing;
56
}
57
}
58
59
60
GNEMoveElement*
61
GNECrossing::getMoveElement() const {
62
return myMoveElementCrossing;
63
}
64
65
66
Parameterised*
67
GNECrossing::getParameters() {
68
return myTemplateNBCrossing;
69
}
70
71
72
const Parameterised*
73
GNECrossing::getParameters() const {
74
return myTemplateNBCrossing;
75
}
76
77
78
bool
79
GNECrossing::isNetworkElementValid() const {
80
return getNBCrossing()->valid;
81
}
82
83
84
std::string
85
GNECrossing::getNetworkElementProblem() const {
86
return TL("Crossing's edges don't support pedestrians");
87
}
88
89
90
const PositionVector&
91
GNECrossing::getCrossingShape() const {
92
const auto crossing = getNBCrossing();
93
return (crossing->customShape.size() > 0) ? crossing->customShape : crossing->shape;
94
}
95
96
97
void
98
GNECrossing::updateGeometry() {
99
const auto crossing = getNBCrossing();
100
// update crossing geometry
101
myCrossingGeometry.updateGeometry(crossing->customShape.size() > 0 ? crossing->customShape : crossing->shape);
102
}
103
104
105
Position
106
GNECrossing::getPositionInView() const {
107
// currently unused
108
return Position(0, 0);
109
}
110
111
112
bool
113
GNECrossing::checkDrawFromContour() const {
114
return false;
115
}
116
117
118
bool
119
GNECrossing::checkDrawToContour() const {
120
return false;
121
}
122
123
124
bool
125
GNECrossing::checkDrawRelatedContour() const {
126
// check opened popup
127
if (myNet->getViewNet()->getPopup()) {
128
return myNet->getViewNet()->getPopup()->getGLObject() == this;
129
}
130
return false;
131
}
132
133
134
bool
135
GNECrossing::checkDrawOverContour() const {
136
return false;
137
}
138
139
140
bool
141
GNECrossing::checkDrawDeleteContour() const {
142
// get edit modes
143
const auto& editModes = myNet->getViewNet()->getEditModes();
144
// check if we're in select mode
145
if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_DELETE)) {
146
return myNet->getViewNet()->checkOverLockedElement(this, mySelected);
147
} else {
148
return false;
149
}
150
}
151
152
153
bool
154
GNECrossing::checkDrawDeleteContourSmall() const {
155
return false;
156
}
157
158
159
bool
160
GNECrossing::checkDrawSelectContour() const {
161
// get edit modes
162
const auto& editModes = myNet->getViewNet()->getEditModes();
163
// check if we're in select mode
164
if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_SELECT)) {
165
return myNet->getViewNet()->checkOverLockedElement(this, mySelected);
166
} else {
167
return false;
168
}
169
}
170
171
172
bool
173
GNECrossing::checkDrawMoveContour() const {
174
// get edit modes
175
const auto& editModes = myNet->getViewNet()->getEditModes();
176
// check if we're in move mode
177
if (!myNet->getViewNet()->isCurrentlyMovingElements() && editModes.isCurrentSupermodeNetwork() &&
178
(editModes.networkEditMode == NetworkEditMode::NETWORK_MOVE) && myNet->getViewNet()->checkOverLockedElement(this, mySelected)) {
179
// check if we're editing this network element
180
const GNENetworkElement* editedNetworkElement = myNet->getViewNet()->getEditNetworkElementShapes().getEditedNetworkElement();
181
if (editedNetworkElement) {
182
return editedNetworkElement == this;
183
} else {
184
// only move the first element
185
return myNet->getViewNet()->getViewObjectsSelector().getGUIGlObjectFront() == this;
186
}
187
} else {
188
return false;
189
}
190
}
191
192
193
const std::vector<NBEdge*>&
194
GNECrossing::getCrossingEdges() const {
195
return myCrossingEdges;
196
}
197
198
199
NBNode::Crossing*
200
GNECrossing::getNBCrossing() const {
201
if (myTemplateNBCrossing) {
202
return myTemplateNBCrossing;
203
} else {
204
return getParentJunctions().front()->getNBNode()->getCrossing(myCrossingEdges);
205
}
206
}
207
208
209
void
210
GNECrossing::drawGL(const GUIVisualizationSettings& s) const {
211
// continue depending of drawCrossing flag
212
if (checkDrawCrossing(s)) {
213
// get NBCrossing
214
const auto NBCrossing = getNBCrossing();
215
// get scaling depending if attribute carrier is selected
216
const double crossingExaggeration = isAttributeCarrierSelected() ? s.selectorFrameScale : 1;
217
// get width
218
const double crossingWidth = NBCrossing->width * 0.5 * crossingExaggeration;
219
// get detail level
220
const auto d = s.getDetailLevel(crossingExaggeration);
221
// check if draw geometry
222
if (!s.drawForViewObjectsHandler) {
223
// draw crossing
224
drawCrossing(s, d, NBCrossing, crossingWidth, crossingExaggeration);
225
// draw TLS Links No
226
drawTLSLinkNo(s, NBCrossing);
227
// draw crossing name
228
if (s.cwaEdgeName.show(this)) {
229
drawName(myCrossingGeometry.getShape().getCentroid(), s.scale, s.edgeName, 0, true);
230
}
231
// draw lock icon
232
GNEViewNetHelper::LockIcon::drawLockIcon(d, this, getType(), getPositionInView(), 1);
233
// draw dotted contour depending if we're editing the custom shape
234
const GNENetworkElement* editedNetworkElement = myNet->getViewNet()->getEditNetworkElementShapes().getEditedNetworkElement();
235
if (editedNetworkElement && (editedNetworkElement == this)) {
236
// draw dotted contour geometry points
237
myNetworkElementContour.drawDottedContourGeometryPoints(s, d, this, myCrossingGeometry.getShape(), s.neteditSizeSettings.crossingGeometryPointRadius,
238
crossingExaggeration, s.dottedContourSettings.segmentWidthSmall);
239
} else {
240
// draw dotted contour
241
myNetworkElementContour.drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidth, true);
242
}
243
}
244
// calculate contour
245
calculateCrossingContour(s, d, crossingWidth, crossingExaggeration);
246
}
247
}
248
249
250
void GNECrossing::deleteGLObject() {
251
myNet->deleteNetworkElement(this, myNet->getUndoList());
252
}
253
254
255
void
256
GNECrossing::updateGLObject() {
257
updateGeometry();
258
}
259
260
261
void
262
GNECrossing::drawTLSLinkNo(const GUIVisualizationSettings& s, const NBNode::Crossing* crossing) const {
263
// check if draw
264
if (s.drawLinkTLIndex.show(getParentJunctions().front())) {
265
// push matrix
266
GLHelper::pushMatrix();
267
// move to GLO_Crossing
268
glTranslated(0, 0, GLO_CROSSING + 0.5);
269
// make a copy of shape
270
PositionVector shape = crossing->shape;
271
// extrapolate
272
shape.extrapolate(0.5); // draw on top of the walking area
273
// get link indexes
274
const int linkNo = crossing->tlLinkIndex;
275
const int linkNo2 = crossing->tlLinkIndex2 > 0 ? crossing->tlLinkIndex2 : linkNo;
276
// draw link indexes
277
GLHelper::drawTextAtEnd(toString(linkNo2), shape, 0, s.drawLinkTLIndex, s.scale);
278
GLHelper::drawTextAtEnd(toString(linkNo), shape.reverse(), 0, s.drawLinkTLIndex, s.scale);
279
// push matrix
280
GLHelper::popMatrix();
281
}
282
}
283
284
285
GUIGLObjectPopupMenu*
286
GNECrossing::getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) {
287
if (myShapeEdited) {
288
return getShapeEditedPopUpMenu(app, parent, getNBCrossing()->customShape);
289
} else {
290
GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
291
// build common options
292
buildPopUpMenuCommonOptions(ret, app, myNet->getViewNet(), myTagProperty->getTag(), mySelected);
293
// check if we're in supermode network
294
if (myNet->getViewNet()->getEditModes().isCurrentSupermodeNetwork()) {
295
// create menu commands
296
FXMenuCommand* mcCustomShape = GUIDesigns::buildFXMenuCommand(ret, TL("Set custom crossing shape"), nullptr, &parent, MID_GNE_CROSSING_EDIT_SHAPE);
297
// check if menu commands has to be disabled
298
NetworkEditMode editMode = myNet->getViewNet()->getEditModes().networkEditMode;
299
if ((editMode == NetworkEditMode::NETWORK_CONNECT) || (editMode == NetworkEditMode::NETWORK_TLS) || (editMode == NetworkEditMode::NETWORK_CREATE_EDGE)) {
300
mcCustomShape->disable();
301
}
302
}
303
return ret;
304
}
305
}
306
307
308
Boundary
309
GNECrossing::getCenteringBoundary() const {
310
return myNetworkElementContour.getContourBoundary();
311
}
312
313
314
void
315
GNECrossing::updateCenteringBoundary(const bool /*updateGrid*/) {
316
// nothing to update
317
}
318
319
320
std::string
321
GNECrossing::getAttribute(SumoXMLAttr key) const {
322
const auto crossing = getNBCrossing();
323
switch (key) {
324
case SUMO_ATTR_ID:
325
// get attribute requires a special case
326
if (crossing) {
327
return crossing->id;
328
} else {
329
return "Temporal Unreferenced";
330
}
331
case SUMO_ATTR_WIDTH:
332
return toString(crossing->customWidth);
333
case SUMO_ATTR_PRIORITY:
334
return crossing->priority ? "true" : "false";
335
case SUMO_ATTR_EDGES:
336
return toString(crossing->edges);
337
case SUMO_ATTR_TLLINKINDEX:
338
return toString(crossing->customTLIndex < 0 ? crossing->tlLinkIndex : crossing->customTLIndex);
339
case SUMO_ATTR_TLLINKINDEX2:
340
return toString(crossing->customTLIndex2 < 0 ? crossing->tlLinkIndex2 : crossing->customTLIndex2);
341
case SUMO_ATTR_SHAPE:
342
case SUMO_ATTR_CUSTOMSHAPE:
343
return toString(crossing->customShape);
344
default:
345
return getCommonAttribute(key);
346
}
347
}
348
349
350
double
351
GNECrossing::getAttributeDouble(SumoXMLAttr key) const {
352
return getCommonAttributeDouble(key);
353
}
354
355
356
Position
357
GNECrossing::getAttributePosition(SumoXMLAttr key) const {
358
return getCommonAttributePosition(key);
359
}
360
361
362
PositionVector
363
GNECrossing::getAttributePositionVector(SumoXMLAttr key) const {
364
switch (key) {
365
case SUMO_ATTR_SHAPE:
366
case SUMO_ATTR_CUSTOMSHAPE:
367
return getNBCrossing()->customShape;
368
default:
369
return getCommonAttributePositionVector(key);
370
}
371
}
372
373
374
void
375
GNECrossing::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
376
if (value == getAttribute(key)) {
377
return; //avoid needless changes, later logic relies on the fact that attributes have changed
378
}
379
switch (key) {
380
case SUMO_ATTR_ID:
381
throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + getTagStr() + " isn't allowed");
382
case SUMO_ATTR_EDGES:
383
case SUMO_ATTR_WIDTH:
384
case SUMO_ATTR_PRIORITY:
385
case SUMO_ATTR_TLLINKINDEX:
386
case SUMO_ATTR_TLLINKINDEX2:
387
case SUMO_ATTR_SHAPE:
388
case SUMO_ATTR_CUSTOMSHAPE:
389
GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);
390
break;
391
default:
392
setCommonAttribute(key, value, undoList);
393
break;
394
}
395
}
396
397
398
bool
399
GNECrossing::isAttributeEnabled(SumoXMLAttr key) const {
400
switch (key) {
401
case SUMO_ATTR_ID:
402
// id isn't editable
403
return false;
404
case SUMO_ATTR_TLLINKINDEX:
405
case SUMO_ATTR_TLLINKINDEX2:
406
return (getNBCrossing()->tlID != "");
407
default:
408
return true;
409
}
410
}
411
412
413
bool
414
GNECrossing::isValid(SumoXMLAttr key, const std::string& value) {
415
const auto crossing = getNBCrossing();
416
switch (key) {
417
case SUMO_ATTR_ID:
418
return false;
419
case SUMO_ATTR_EDGES:
420
if (canParse<std::vector<GNEEdge*> >(myNet, value, false)) {
421
// parse edges and save their IDs in a set
422
std::vector<GNEEdge*> parsedEdges = parse<std::vector<GNEEdge*> >(myNet, value);
423
EdgeVector nbEdges;
424
for (const auto& edge : parsedEdges) {
425
nbEdges.push_back(edge->getNBEdge());
426
}
427
std::sort(nbEdges.begin(), nbEdges.end());
428
//
429
EdgeVector originalEdges = crossing->edges;
430
std::sort(originalEdges.begin(), originalEdges.end());
431
// return true if we're setting the same edges
432
if (toString(nbEdges) == toString(originalEdges)) {
433
return true;
434
} else {
435
return !getParentJunctions().front()->getNBNode()->checkCrossingDuplicated(nbEdges);
436
}
437
} else {
438
return false;
439
}
440
case SUMO_ATTR_WIDTH:
441
return canParse<double>(value) && ((parse<double>(value) > 0) || (parse<double>(value) == -1)); // can not be 0, or -1 (it means default)
442
case SUMO_ATTR_PRIORITY:
443
return canParse<bool>(value);
444
case SUMO_ATTR_TLLINKINDEX:
445
case SUMO_ATTR_TLLINKINDEX2:
446
// -1 means that tlLinkIndex2 takes on the same value as tlLinkIndex when setting indices
447
return (isAttributeEnabled(key) &&
448
canParse<int>(value)
449
&& (parse<double>(value) >= 0 || parse<double>(value) == -1)
450
&& getParentJunctions().front()->getNBNode()->getControllingTLS().size() > 0
451
&& (*getParentJunctions().front()->getNBNode()->getControllingTLS().begin())->getMaxValidIndex() >= parse<int>(value));
452
case SUMO_ATTR_SHAPE:
453
case SUMO_ATTR_CUSTOMSHAPE:
454
// empty shapes are allowed
455
return canParse<PositionVector>(value);
456
default:
457
return isValid(key, value);
458
}
459
}
460
461
462
bool
463
GNECrossing::checkEdgeBelong(GNEEdge* edge) const {
464
const auto crossing = getNBCrossing();
465
if (std::find(crossing->edges.begin(), crossing->edges.end(), edge->getNBEdge()) != crossing->edges.end()) {
466
return true;
467
} else {
468
return false;
469
}
470
}
471
472
473
bool
474
GNECrossing::checkEdgeBelong(const std::vector<GNEEdge*>& edges) const {
475
for (auto i : edges) {
476
if (checkEdgeBelong(i)) {
477
return true;
478
}
479
}
480
return false;
481
}
482
483
// ===========================================================================
484
// private
485
// ===========================================================================
486
487
bool
488
GNECrossing::checkDrawCrossing(const GUIVisualizationSettings& s) const {
489
// don't draw in supermode data
490
if (myNet->getViewNet()->getEditModes().isCurrentSupermodeData()) {
491
return false;
492
}
493
// check shape rotations
494
if (myCrossingGeometry.getShapeRotations().empty()) {
495
return false;
496
}
497
// check shape lengths
498
if (myCrossingGeometry.getShapeLengths().empty()) {
499
return false;
500
}
501
return s.drawCrossingsAndWalkingareas;
502
}
503
504
505
void
506
GNECrossing::drawCrossing(const GUIVisualizationSettings& s, const GUIVisualizationSettings::Detail d,
507
const NBNode::Crossing* crossing, const double width, const double exaggeration) const {
508
// don't draw crossing in TLS Mode
509
if (myNet->getViewNet()->getEditModes().networkEditMode != NetworkEditMode::NETWORK_TLS) {
510
// get color
511
RGBColor crossingColor = getCrossingColor(s, crossing);
512
// push layer matrix
513
GLHelper::pushMatrix();
514
// translate to front
515
drawInLayer(GLO_CROSSING);
516
// set color
517
GLHelper::setColor(crossingColor);
518
// draw depending of level of detail
519
if (d <= GUIVisualizationSettings::Detail::JunctionElementDetails) {
520
drawCrossingDetailed(width, exaggeration);
521
} else {
522
GUIGeometry::drawGeometry(d, myCrossingGeometry, width);
523
}
524
// draw shape points only in Network supermode
525
if (myShapeEdited && myNet->getViewNet()->getEditModes().isCurrentSupermodeNetwork() &&
526
s.drawMovingGeometryPoint(exaggeration, s.neteditSizeSettings.crossingGeometryPointRadius)) {
527
// color
528
const RGBColor darkerColor = crossingColor.changedBrightness(-32);
529
// draw on top of of the white area between the rails
530
glTranslated(0, 0, 0.2);
531
// set color
532
GLHelper::setColor(darkerColor);
533
// draw shape
534
GUIGeometry::drawGeometry(d, myCrossingGeometry.getShape(), s.neteditSizeSettings.crossingGeometryPointRadius * 0.4);
535
// draw geometry points
536
GUIGeometry::drawGeometryPoints(d, myCrossingGeometry.getShape(), darkerColor,
537
s.neteditSizeSettings.crossingGeometryPointRadius, exaggeration,
538
myNet->getViewNet()->getNetworkViewOptions().editingElevation());
539
}
540
// pop layer matrix
541
GLHelper::popMatrix();
542
}
543
}
544
545
546
RGBColor
547
GNECrossing::getCrossingColor(const GUIVisualizationSettings& s, const NBNode::Crossing* crossing) const {
548
if (myShapeEdited) {
549
return s.colorSettings.editShapeColor;
550
} else if (drawUsingSelectColor()) {
551
return s.colorSettings.selectedCrossingColor;
552
} else if (!crossing->valid) {
553
return s.colorSettings.crossingInvalidColor;
554
} else if (crossing->priority) {
555
return s.colorSettings.crossingPriorityColor;
556
} else if (myNet->getViewNet()->getEditModes().isCurrentSupermodeData()) {
557
return s.laneColorer.getSchemes()[0].getColor(8);
558
} else {
559
return s.colorSettings.crossingColor;
560
}
561
}
562
563
564
void
565
GNECrossing::drawCrossingDetailed(const double width, const double exaggeration) const {
566
// get length and spacing
567
const double length = 0.5 * exaggeration;
568
const double spacing = 1.0 * exaggeration;
569
// push rail matrix
570
GLHelper::pushMatrix();
571
// draw on top of of the white area between the rails
572
glTranslated(0, 0, 0.1);
573
for (int i = 0; i < (int)myCrossingGeometry.getShape().size() - 1; i++) {
574
// push draw matrix
575
GLHelper::pushMatrix();
576
// translate and rotate
577
glTranslated(myCrossingGeometry.getShape()[i].x(), myCrossingGeometry.getShape()[i].y(), 0.0);
578
glRotated(myCrossingGeometry.getShapeRotations()[i], 0, 0, 1);
579
// draw crossing depending if isn't being drawn for selecting
580
for (double t = 0; t < myCrossingGeometry.getShapeLengths()[i]; t += spacing) {
581
glBegin(GL_QUADS);
582
glVertex2d(-width, -t);
583
glVertex2d(-width, -t - length);
584
glVertex2d(width, -t - length);
585
glVertex2d(width, -t);
586
glEnd();
587
}
588
// pop draw matrix
589
GLHelper::popMatrix();
590
}
591
// pop rail matrix
592
GLHelper::popMatrix();
593
}
594
595
596
void
597
GNECrossing::calculateCrossingContour(const GUIVisualizationSettings& s, const GUIVisualizationSettings::Detail d,
598
const double width, const double exaggeration) const {
599
// first check if junction parent was inserted with full boundary
600
if (!gViewObjectsHandler.checkBoundaryParentObject(this, getType(), getParentJunctions().front())) {
601
// check if calculate contour for geometry points
602
if (myShapeEdited) {
603
myNetworkElementContour.calculateContourAllGeometryPoints(s, d, this, myCrossingGeometry.getShape(),
604
getType(), s.neteditSizeSettings.crossingGeometryPointRadius, exaggeration, true);
605
} else {
606
// in move mode, add to selected object if this is the edited element
607
const auto& editModes = myNet->getViewNet()->getEditModes();
608
const bool addToSelectedObjects = (editModes.isCurrentSupermodeNetwork() && editModes.networkEditMode == NetworkEditMode::NETWORK_MOVE) ?
609
(myNet->getViewNet()->getEditNetworkElementShapes().getEditedNetworkElement() == this) : true;
610
// calculate contour and
611
myNetworkElementContour.calculateContourExtrudedShape(s, d, this, myCrossingGeometry.getShape(), getType(),
612
width, exaggeration, true, true, 0, nullptr, getParentJunctions().front(), addToSelectedObjects);
613
}
614
}
615
}
616
617
618
void
619
GNECrossing::setAttribute(SumoXMLAttr key, const std::string& value) {
620
const auto crossing = getNBCrossing();
621
switch (key) {
622
case SUMO_ATTR_ID:
623
throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + getTagStr() + " isn't allowed");
624
case SUMO_ATTR_EDGES: {
625
// obtain GNEEdges
626
std::vector<GNEEdge*> edges = parse<std::vector<GNEEdge*> >(myNet, value);
627
// remove NBEdges of crossing
628
crossing->edges.clear();
629
// set NBEdge of every GNEEdge into Crossing Edges
630
for (auto i : edges) {
631
crossing->edges.push_back(i->getNBEdge());
632
}
633
// sort new edges
634
std::sort(crossing->edges.begin(), crossing->edges.end());
635
// change myCrossingEdges by the new edges
636
myCrossingEdges = crossing->edges;
637
// update geometry of parent junction
638
getParentJunctions().front()->updateGeometry();
639
break;
640
}
641
case SUMO_ATTR_WIDTH:
642
// Change width an refresh element
643
crossing->customWidth = parse<double>(value);
644
break;
645
case SUMO_ATTR_PRIORITY:
646
crossing->priority = parse<bool>(value);
647
break;
648
case SUMO_ATTR_TLLINKINDEX:
649
crossing->customTLIndex = parse<int>(value);
650
// make new value visible immediately
651
crossing->tlLinkIndex = crossing->customTLIndex;
652
break;
653
case SUMO_ATTR_TLLINKINDEX2:
654
crossing->customTLIndex2 = parse<int>(value);
655
// make new value visible immediately
656
crossing->tlLinkIndex2 = crossing->customTLIndex2;
657
break;
658
case SUMO_ATTR_SHAPE:
659
case SUMO_ATTR_CUSTOMSHAPE:
660
// set custom shape
661
crossing->customShape = parse<PositionVector>(value);
662
break;
663
default:
664
setCommonAttribute(key, value);
665
break;
666
}
667
// Crossing are a special case and we need ot update geometry of junction instead of crossing
668
if ((getParentJunctions().size() > 0) && (key != SUMO_ATTR_ID) && (key != GNE_ATTR_PARAMETERS) && (key != GNE_ATTR_SELECTED)) {
669
getParentJunctions().front()->updateGeometry();
670
}
671
// invalidate demand path calculator
672
myNet->getDemandPathManager()->getPathCalculator()->invalidatePathCalculator();
673
}
674
675
/****************************************************************************/
676
677