Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNEJunction.cpp
Go to the documentation of this file.
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/****************************************************************************/
18// A class for visualizing and editing junctions in netedit (adapted from
19// GUIJunctionWrapper)
20/****************************************************************************/
21#include <config.h>
22
26#include <netbuild/NBOwnTLDef.h>
37#include <netedit/GNENet.h>
38#include <netedit/GNEUndoList.h>
39#include <netedit/GNEViewNet.h>
53
54#include "GNEConnection.h"
55#include "GNEJunction.h"
56#include "GNECrossing.h"
57#include "GNEWalkingArea.h"
58#include "GNEInternalLane.h"
59
60
61// ===========================================================================
62// method definitions
63// ===========================================================================
64
65GNEJunction::GNEJunction(GNENet* net, NBNode* nbn, bool loaded) :
67 GUIIconSubSys::getIcon(GUIIcon::JUNCTION), {}, {}, {}, {}, {}, {}),
68 myNBNode(nbn),
69 myDrawingToggle(new int),
70 myLogicStatus(loaded ? FEATURE_LOADED : FEATURE_GUESSED),
71 myHasValidLogic(loaded),
72myTesselation(nbn->getID(), "", RGBColor::MAGENTA, nbn->getShape(), false, true, 0) {
73 // update centering boundary without updating grid
74 updateCenteringBoundary(false);
75}
76
77
79 // delete drawing toggle
80 delete myDrawingToggle;
81 // delete all GNECrossing
82 for (const auto& crossing : myGNECrossings) {
83 crossing->decRef();
84 if (crossing->unreferenced()) {
85 // check if remove it from Attribute Carriers
86 if (myNet->getAttributeCarriers()->getCrossings().count(crossing) > 0) {
88 }
89 // show extra information for tests
90 WRITE_DEBUG("Deleting unreferenced " + crossing->getTagStr() + " '" + crossing->getID() + "' in GNEJunction destructor");
91 delete crossing;
92 }
93 }
94 // delete all GNEWalkingArea
95 for (const auto& walkingArea : myGNEWalkingAreas) {
96 walkingArea->decRef();
97 if (walkingArea->unreferenced()) {
98 // check if remove it from Attribute Carriers
99 if (myNet->getAttributeCarriers()->getWalkingAreas().count(walkingArea) > 0) {
101 }
102 // show extra information for tests
103 WRITE_DEBUG("Deleting unreferenced " + walkingArea->getTagStr() + " '" + walkingArea->getID() + "' in GNEJunction destructor");
104 delete walkingArea;
105 }
106 }
107 if (myAmResponsible) {
108 // show extra information for tests
109 WRITE_DEBUG("Deleting NBNode of '" + getID() + "' in GNEJunction destructor");
110 delete myNBNode;
111 }
112}
113
114
115const PositionVector&
117 return myNBNode->getShape();
118}
119
120
121void
124 // trigger rebuilding tesselation
125 myExaggeration = 2;
126}
127
128
129void
130GNEJunction::updateGeometryAfterNetbuild(bool rebuildNBNodeCrossings) {
131 // rebuild crossings
132 rebuildGNECrossings(rebuildNBNodeCrossings);
133 // clear walking areas
135 // clear missing connections
137}
138
139
144
145
146bool
148 // get modes and viewParent (for code legibility)
149 const auto& modes = myNet->getViewNet()->getEditModes();
150 const auto& viewParent = myNet->getViewNet()->getViewParent();
151 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
152 // continue depending of current status
153 if (inspectedElements.isInspectingSingleElement()) {
154 // check if starts in this junction
155 if (inspectedElements.getFirstAC()->hasAttribute(SUMO_ATTR_FROM_JUNCTION) &&
156 (inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_FROM_JUNCTION) == getID())) {
157 return true;
158 }
159 } else if (modes.isCurrentSupermodeNetwork()) {
160 if (modes.networkEditMode == NetworkEditMode::NETWORK_CREATE_EDGE) {
161 if (viewParent->getCreateEdgeFrame()->getJunctionSource()) {
162 return viewParent->getCreateEdgeFrame()->getJunctionSource() == this;
163 } else {
165 }
166 }
167 } else if (modes.isCurrentSupermodeDemand()) {
168 // get current GNEPlanCreator
169 GNEPlanCreator* planCreator = nullptr;
170 if (modes.demandEditMode == DemandEditMode::DEMAND_PERSON) {
171 planCreator = viewParent->getPersonFrame()->getPlanCreator();
172 } else if (modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) {
173 planCreator = viewParent->getPersonPlanFrame()->getPlanCreator();
174 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) {
175 planCreator = viewParent->getContainerFrame()->getPlanCreator();
176 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) {
177 planCreator = viewParent->getContainerPlanFrame()->getPlanCreator();
178 }
179 // continue depending of planCreator
180 if (planCreator) {
181 if (planCreator->getPlanParameteres().fromJunction == getID()) {
182 return true;
183 }
184 } else if (modes.demandEditMode == DemandEditMode::DEMAND_VEHICLE) {
185 const auto& selectedJunctions = viewParent->getVehicleFrame()->getPathCreator()->getSelectedJunctions();
186 // check if this is the first selected junction
187 if ((selectedJunctions.size() > 0) && (selectedJunctions.front() == this)) {
188 return true;
189 }
190 }
191 }
192 // nothing to draw
193 return false;
194}
195
196
197bool
199 // get modes and viewParent (for code legibility)
200 const auto& modes = myNet->getViewNet()->getEditModes();
201 const auto& viewParent = myNet->getViewNet()->getViewParent();
202 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
203 // continue depending of current status
204 if (inspectedElements.isInspectingSingleElement()) {
205 // check if ends in this junction
206 if (inspectedElements.getFirstAC()->getTagProperty().vehicleJunctions() &&
207 (inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_TO_JUNCTION) == getID())) {
208 return true;
209 }
210 } else if (modes.isCurrentSupermodeNetwork()) {
211 if (modes.networkEditMode == NetworkEditMode::NETWORK_CREATE_EDGE) {
212 if (viewParent->getCreateEdgeFrame()->getJunctionSource() &&
213 (viewParent->getCreateEdgeFrame()->getJunctionSource() != this)) {
215 }
216 } else if (modes.networkEditMode == NetworkEditMode::NETWORK_MOVE) {
217 // check if we're moving a junction
218 const auto movedJunction = dynamic_cast<GNEJunction*>(myNet->getViewNet()->getMoveSingleElementValues().getMovedElement());
219 if (movedJunction && (movedJunction != this)) {
220 // continue depending of junction shape
221 if (myNBNode->getShape().area() < 4) {
222 // calculate distance between both centers
223 const double junctionBubbleRadius = myNet->getViewNet()->getVisualisationSettings().neteditSizeSettings.junctionBubbleRadius;
224 const double radiusTo = getExaggeration(myNet->getViewNet()->getVisualisationSettings()) * junctionBubbleRadius;
225 if (myNBNode->getPosition().distanceSquaredTo2D(movedJunction->getPositionInView()) < (radiusTo * radiusTo)) {
226 // add it in the list of merging junction (first the moved junction)
229 return true;
230 }
231 } else if (myNBNode->getShape().around(movedJunction->getNBNode()->getPosition())) {
232 // add it in the list of merging junction (first the moved junction)
235 return true;
236 }
237 }
238 }
239 } else if (modes.isCurrentSupermodeDemand()) {
240 // get current GNEPlanCreator
241 GNEPlanCreator* planCreator = nullptr;
242 if (modes.demandEditMode == DemandEditMode::DEMAND_PERSON) {
243 planCreator = viewParent->getPersonFrame()->getPlanCreator();
244 } else if (modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) {
245 planCreator = viewParent->getPersonPlanFrame()->getPlanCreator();
246 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) {
247 planCreator = viewParent->getContainerFrame()->getPlanCreator();
248 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) {
249 planCreator = viewParent->getContainerPlanFrame()->getPlanCreator();
250 }
251 // continue depending of planCreator
252 if (planCreator) {
253 if (planCreator->getPlanParameteres().toJunction == getID()) {
254 return true;
255 }
256 } else if (modes.demandEditMode == DemandEditMode::DEMAND_VEHICLE) {
257 const auto& selectedJunctions = viewParent->getVehicleFrame()->getPathCreator()->getSelectedJunctions();
258 // check if this is the first selected junction
259 if ((selectedJunctions.size() > 1) && (selectedJunctions.back() == this)) {
260 return true;
261 }
262 }
263 }
264 // nothing to draw
265 return false;
266}
267
268
269bool
273
274
275bool
277 // get modes and viewParent (for code legibility)
278 const auto& modes = myNet->getViewNet()->getEditModes();
279 const auto& viewParent = myNet->getViewNet()->getViewParent();
280 const auto& viewObjectsSelector = myNet->getViewNet()->getViewObjectsSelector();
281 if (viewObjectsSelector.getJunctionFront() != this) {
282 return false;
283 } else {
284 if (modes.isCurrentSupermodeNetwork()) {
285 if (modes.networkEditMode == NetworkEditMode::NETWORK_CROSSING) {
286 return (viewObjectsSelector.getJunctionFront() == this);
287 }
288 } else if (modes.isCurrentSupermodeDemand()) {
289 // get current plan selector
290 GNEPlanSelector* planSelector = nullptr;
291 if (modes.demandEditMode == DemandEditMode::DEMAND_PERSON) {
292 planSelector = viewParent->getPersonFrame()->getPlanSelector();
293 } else if (modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) {
294 planSelector = viewParent->getPersonPlanFrame()->getPlanSelector();
295 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) {
296 planSelector = viewParent->getContainerFrame()->getPlanSelector();
297 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) {
298 planSelector = viewParent->getContainerPlanFrame()->getPlanSelector();
299 }
300 // continue depending of plan selector
301 if (planSelector && planSelector->markJunctions()) {
302 return (viewObjectsSelector.getAttributeCarrierFront() == viewObjectsSelector.getJunctionFront());
303 } else if (modes.demandEditMode == DemandEditMode::DEMAND_VEHICLE) {
304 // get current vehicle template
305 const auto& vehicleTemplate = viewParent->getVehicleFrame()->getVehicleTagSelector()->getCurrentTemplateAC();
306 // check if vehicle can be placed over from-to TAZs
307 if (vehicleTemplate && vehicleTemplate->getTagProperty().vehicleJunctions()) {
308 return (viewObjectsSelector.getAttributeCarrierFront() == viewObjectsSelector.getJunctionFront());
309 }
310 }
311 }
312 return false;
313 }
314}
315
316
317bool
319 // get edit modes
320 const auto& editModes = myNet->getViewNet()->getEditModes();
321 // check if we're in delete mode
322 if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_DELETE)) {
324 } else {
325 return false;
326 }
327}
328
329
330bool
332 // get edit modes
333 const auto& editModes = myNet->getViewNet()->getEditModes();
334 // check if we're in select mode
335 if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_SELECT)) {
337 } else {
338 return false;
339 }
340}
341
342
343bool
345 // get edit modes
346 const auto& editModes = myNet->getViewNet()->getEditModes();
347 // check if we're in move mode
348 if (!myNet->getViewNet()->isCurrentlyMovingElements() && editModes.isCurrentSupermodeNetwork() &&
349 (editModes.networkEditMode == NetworkEditMode::NETWORK_MOVE) && myNet->getViewNet()->checkOverLockedElement(this, mySelected)) {
350 // check if we're editing this network element
352 if (editedNetworkElement) {
353 return editedNetworkElement == this;
354 } else {
355 // only move the first element
357 }
358 } else {
359 return false;
360 }
361}
362
363
366 // edit depending if shape is being edited
367 if (isShapeEdited()) {
368 // calculate move shape operation
369 return calculateMoveShapeOperation(this, myNBNode->getShape(), false);
370 } else {
371 // return move junction position
372 return new GNEMoveOperation(this, myNBNode->getPosition());
373 }
374}
375
376
377void
378GNEJunction::removeGeometryPoint(const Position clickedPosition, GNEUndoList* undoList) {
379 // edit depending if shape is being edited
380 if (isShapeEdited()) {
381 // get original shape
383 // check shape size
384 if (shape.size() > 2) {
385 // obtain index
386 int index = shape.indexOfClosest(clickedPosition);
387 // get snap radius
389 // check if we have to create a new index
390 if ((index != -1) && shape[index].distanceSquaredTo2D(clickedPosition) < (snap_radius * snap_radius)) {
391 // remove geometry point
392 shape.erase(shape.begin() + index);
393 // commit new shape
394 undoList->begin(this, "remove geometry point of " + getTagStr());
396 undoList->end();
397 }
398 }
399 }
400}
401
402
403void
404GNEJunction::rebuildGNECrossings(bool rebuildNBNodeCrossings) {
405 // rebuild GNECrossings only if create crossings and walkingAreas in net is enabled
407 if (rebuildNBNodeCrossings) {
408 // build new NBNode::Crossings and walking areas
412 }
413 // create a vector to keep retrieved and created crossings
414 std::vector<GNECrossing*> retrievedCrossings;
415 // iterate over NBNode::Crossings of GNEJunction
416 for (const auto& crossing : myNBNode->getCrossingsIncludingInvalid()) {
417 // retrieve existent GNECrossing, or create it
418 GNECrossing* retrievedGNECrossing = retrieveGNECrossing(crossing.get());
419 retrievedCrossings.push_back(retrievedGNECrossing);
420 // check if previously this GNECrossings exists, and if true, remove it from myGNECrossings and insert in tree again
421 std::vector<GNECrossing*>::iterator retrievedExists = std::find(myGNECrossings.begin(), myGNECrossings.end(), retrievedGNECrossing);
422 if (retrievedExists != myGNECrossings.end()) {
423 myGNECrossings.erase(retrievedExists);
424 // update geometry of retrieved crossing
425 retrievedGNECrossing->updateGeometry();
426 // update boundary
427 retrievedGNECrossing->updateCenteringBoundary(false);
428 } else {
429 // include reference to created GNECrossing
430 retrievedGNECrossing->incRef();
431 }
432 }
433 // delete non retrieved GNECrossings (we don't need to extract if from Tree two times)
434 for (const auto& crossing : myGNECrossings) {
435 crossing->decRef();
436 // check if crossing is selected
437 if (crossing->isAttributeCarrierSelected()) {
438 crossing->unselectAttributeCarrier();
439 }
440 // remove it from inspected ACS
442 // remove it from net
443 myNet->removeGLObjectFromGrid(crossing);
444 // remove it from attributeCarriers
446 if (crossing->unreferenced()) {
447 // show extra information for tests
448 WRITE_DEBUG("Deleting unreferenced " + crossing->getTagStr() + " in rebuildGNECrossings()");
449 delete crossing;
450 }
451 }
452 // copy retrieved (existent and created) GNECrossings to myGNECrossings
453 myGNECrossings = retrievedCrossings;
454 }
455}
456
457
458void
460 if (OptionsCont::getOptions().getBool("lefthand")) {
461 myNBNode->mirrorX();
462 for (NBEdge* e : myNBNode->getEdges()) {
463 e->mirrorX();
464
465 }
466 }
467}
468
469
470void
471GNEJunction::buildTLSOperations(GUISUMOAbstractView& parent, GUIGLObjectPopupMenu* ret, const int numSelectedJunctions) {
472 // create menu pane for edge operations
473 FXMenuPane* TLSOperations = new FXMenuPane(ret);
474 ret->insertMenuPaneChild(TLSOperations);
475 new FXMenuCascade(ret, TL("TLS operations"), GUIIconSubSys::getIcon(GUIIcon::MODETLS), TLSOperations);
476 // create menu commands for all TLS operations
477 FXMenuCommand* mcAddTLS = GUIDesigns::buildFXMenuCommand(TLSOperations, TL("Add TLS"), nullptr, &parent, MID_GNE_JUNCTION_ADDTLS);
478 FXMenuCommand* mcAddJoinedTLS = GUIDesigns::buildFXMenuCommand(TLSOperations, TL("Add joined TLS"), nullptr, &parent, MID_GNE_JUNCTION_ADDJOINTLS);
479 // check if disable create TLS
480 if (myNBNode->getControllingTLS().size() > 0) {
481 mcAddTLS->disable();
482 mcAddJoinedTLS->disable();
483 } else {
484 mcAddTLS->enable();
485 // check if add joined TLS
486 if (isAttributeCarrierSelected() && (numSelectedJunctions > 1)) {
487 mcAddJoinedTLS->enable();
488 } else {
489 mcAddJoinedTLS->disable();
490 }
491 }
492}
493
494
497 if (myShapeEdited) {
498 return getShapeEditedPopUpMenu(app, parent, myNBNode->getShape());
499 } else {
500 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
501 // build common commands
502 buildPopupHeader(ret, app);
505 // build selection and show parameters menu
508 buildPositionCopyEntry(ret, app);
509 // add separator
510 new FXMenuSeparator(ret);
511 // check if we're in supermode network
513 const int numSelectedJunctions = myNet->getAttributeCarriers()->getNumberOfSelectedJunctions();
514 const int numEndpoints = (int)myNBNode->getEndPoints().size();
515 // check if we're handling a selection
516 bool handlingSelection = isAttributeCarrierSelected() && (numSelectedJunctions > 1);
517 // check if menu commands has to be disabled
521 // build TLS operation
522 if (!invalidMode) {
523 buildTLSOperations(parent, ret, numSelectedJunctions);
524 }
525 // create menu commands
526 GUIDesigns::buildFXMenuCommand(ret, TL("Reset edge endpoints"), nullptr, &parent, MID_GNE_JUNCTION_RESET_EDGE_ENDPOINTS);
527 FXMenuCommand* mcCustomShape = GUIDesigns::buildFXMenuCommand(ret, TL("Set custom junction shape"), nullptr, &parent, MID_GNE_JUNCTION_EDIT_SHAPE);
528 FXMenuCommand* mcResetCustomShape = GUIDesigns::buildFXMenuCommand(ret, TL("Reset junction shape"), nullptr, &parent, MID_GNE_JUNCTION_RESET_SHAPE);
529 FXMenuCommand* mcReplaceByGeometryPoint = GUIDesigns::buildFXMenuCommand(ret, TL("Replace junction by geometry point"), nullptr, &parent, MID_GNE_JUNCTION_REPLACE);
530 FXMenuCommand* mcSplitJunction = GUIDesigns::buildFXMenuCommand(ret, TLF("Split junction (% end points)", numEndpoints), nullptr, &parent, MID_GNE_JUNCTION_SPLIT);
531 FXMenuCommand* mcSplitJunctionAndReconnect = GUIDesigns::buildFXMenuCommand(ret, TL("Split junction and reconnect"), nullptr, &parent, MID_GNE_JUNCTION_SPLIT_RECONNECT);
532 // check if is a roundabout
533 if (myNBNode->isRoundabout()) {
534 GUIDesigns::buildFXMenuCommand(ret, TL("Select roundabout"), nullptr, &parent, MID_GNE_JUNCTION_SELECT_ROUNDABOUT);
535 } else {
536 // get radius
537 const double radius = (myNBNode->getRadius() == NBNode::UNSPECIFIED_RADIUS) ? OptionsCont::getOptions().getFloat("default.junctions.radius") : myNBNode->getRadius();
538 const std::string menuEntryInfo = TLF("Convert to roundabout (using junction attribute radius %)", toString(radius));
539 FXMenuCommand* mcRoundabout = GUIDesigns::buildFXMenuCommand(ret, menuEntryInfo.c_str(), nullptr, &parent, MID_GNE_JUNCTION_CONVERT_ROUNDABOUT);
540 // check if disable depending of number of edges
541 if ((getChildEdges().size() < 2) ||
542 ((myGNEIncomingEdges.size() == 1) && (myGNEOutgoingEdges.size() == 1) && (myGNEIncomingEdges[0]->getFromJunction() == myGNEOutgoingEdges[0]->getToJunction()))) {
543 mcRoundabout->disable();
544 }
545 }
546 // check multijunctions
547 const std::string multi = ((numSelectedJunctions > 1) && isAttributeCarrierSelected()) ? TLF(" of % junctions", numSelectedJunctions) : "";
548 FXMenuCommand* mcClearConnections = GUIDesigns::buildFXMenuCommand(ret, TL("Clear connections") + multi, nullptr, &parent, MID_GNE_JUNCTION_CLEAR_CONNECTIONS);
549 FXMenuCommand* mcResetConnections = GUIDesigns::buildFXMenuCommand(ret, TL("Reset connections") + multi, nullptr, &parent, MID_GNE_JUNCTION_RESET_CONNECTIONS);
550 // check if current mode is correct
551 if (invalidMode) {
552 mcCustomShape->disable();
553 mcClearConnections->disable();
554 mcResetConnections->disable();
555 }
556 // check if we're handling a selection
557 if (handlingSelection) {
558 mcResetCustomShape->setText(TL("Reset junction shapes"));
559 }
560 // disable mcClearConnections if junction hasn't connections
561 if (getGNEConnections().empty()) {
562 mcClearConnections->disable();
563 }
564 // disable mcResetCustomShape if junction doesn't have a custom shape
565 if (myNBNode->getShape().size() == 0) {
566 mcResetCustomShape->disable();
567 }
568 // checkIsRemovable requires turnarounds to be computed. This is ugly
569 if ((myNBNode->getIncomingEdges().size() == 2) && (myNBNode->getOutgoingEdges().size() == 2)) {
571 }
572 std::string reason = TL("wrong edit mode");
573 if (invalidMode || !myNBNode->checkIsRemovableReporting(reason)) {
574 mcReplaceByGeometryPoint->setText(mcReplaceByGeometryPoint->getText() + " (" + reason.c_str() + ")");
575 mcReplaceByGeometryPoint->disable();
576 }
577 // check if disable split junctions
578 if (numEndpoints == 1) {
579 mcSplitJunction->disable();
580 mcSplitJunctionAndReconnect->disable();
581 }
582 }
583 return ret;
584 }
585}
586
587
588double
592
593
598
599
600void
602 // Remove object from grid
603 if (updateGrid) {
605 }
606 // calculate boundary using a radius bigger than geometry point
608 myNBNode->getPosition().x() + 1, myNBNode->getPosition().y() + 1);
610 // add shape
611 if (myNBNode->getShape().size() > 0) {
614 }
615 // add boundaries of all connections, walking areas and crossings
616 for (const auto& edge : myGNEIncomingEdges) {
617 for (const auto& connection : edge->getGNEConnections()) {
618 const auto boundary = connection->getCenteringBoundary();
619 if (boundary.isInitialised()) {
620 myJunctionBoundary.add(boundary);
621 }
622 }
623 }
624 for (const auto& crossing : myGNECrossings) {
625 const auto boundary = crossing->getCenteringBoundary();
626 if (boundary.isInitialised()) {
627 myJunctionBoundary.add(boundary);
628 }
629 }
630 for (const auto& walkingArea : myGNEWalkingAreas) {
631 const auto boundary = walkingArea->getCenteringBoundary();
632 if (boundary.isInitialised()) {
633 myJunctionBoundary.add(boundary);
634 }
635 }
636
637 // add object into grid
638 if (updateGrid) {
639 // if junction has at least one edge, then don't add in grid (because uses the edge's grid)
640 if (myGNEIncomingEdges.size() + myGNEOutgoingEdges.size() == 0) {
642 }
643 }
644 // trigger rebuilding tesselation
645 myExaggeration = 2;
646}
647
648
649void
651 // first check drawing toggle and boundary selection
653 // draw boundaries
654 if (inGrid()) {
656 }
657 // get junction exaggeration
658 const double junctionExaggeration = getExaggeration(s);
659 // only continue if exaggeration is greater than 0
660 if (junctionExaggeration > 0) {
661 // get detail level
662 const auto d = s.getDetailLevel(junctionExaggeration);
663 // get shape area
664 const double junctionShapeArea = myNBNode->getShape().area();
665 // check if draw junction as shape
666 const bool drawBubble = drawAsBubble(s, junctionShapeArea);
667 // draw geometry only if we'rent in drawForObjectUnderCursor mode
669 // push layer matrix
671 // translate to front
673 // draw junction as shape
674 drawJunctionAsShape(s, d, junctionExaggeration);
675 // draw junction as bubble
676 if (drawBubble) {
677 drawJunctionAsBubble(s, d, junctionExaggeration);
678 }
679 // draw TLS
680 drawTLSIcon(s, d);
681 // draw elevation
682 drawElevation(s, d);
683 // pop layer Matrix
685 // draw lock icon
687 // draw junction name
689 // draw dotted contour depending if we're editing the custom shape
691 if (editedNetworkElement && (editedNetworkElement == this)) {
692 // draw dotted contour geometry points
694 junctionExaggeration, s.dottedContourSettings.segmentWidthSmall);
695 } else {
696 // draw dotted contour for shape
697 if (junctionShapeArea >= 4) {
699 }
700 // draw dotted contour for bubble
701 if (drawBubble) {
703 }
704 }
705 }
706 // calculate junction contour (always before children)
707 calculateJunctioncontour(s, d, junctionExaggeration, drawBubble);
708 // draw Junction childs
710 }
711 // update drawing toggle
713 }
714}
715
716
717void
719 // Check if edge can be deleted
722 }
723}
724
725
726void
730
731
732NBNode*
734 return myNBNode;
735}
736
737
738std::vector<GNEJunction*>
740 // use set to avoid duplicates junctions
741 std::set<GNEJunction*> junctions;
742 for (const auto& incomingEdge : myGNEIncomingEdges) {
743 junctions.insert(incomingEdge->getFromJunction());
744 }
745 for (const auto& outgoingEdge : myGNEOutgoingEdges) {
746 junctions.insert(outgoingEdge->getToJunction());
747 }
748 return std::vector<GNEJunction*>(junctions.begin(), junctions.end());
749}
750
751
752void
754 // Check if incoming edge was already inserted
755 std::vector<GNEEdge*>::iterator i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
756 if (i != myGNEIncomingEdges.end()) {
757 throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + getTagStr() + " with ID " + getID() + "'");
758 } else {
759 // Add edge into containers
760 myGNEIncomingEdges.push_back(edge);
761 }
762}
763
764
765
766void
768 // Check if outgoing edge was already inserted
769 std::vector<GNEEdge*>::iterator i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
770 if (i != myGNEOutgoingEdges.end()) {
771 throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + getTagStr() + " with ID " + getID() + "'");
772 } else {
773 // Add edge into containers
774 myGNEOutgoingEdges.push_back(edge);
775 }
776}
777
778
779void
781 // Check if incoming edge was already inserted
782 std::vector<GNEEdge*>::iterator i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
783 if (i == myGNEIncomingEdges.end()) {
784 throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + getTagStr() + " with ID " + getID() + "'");
785 } else {
786 // remove edge from containers
787 myGNEIncomingEdges.erase(i);
788 }
789}
790
791
792void
794 // Check if outgoing edge was already inserted
795 std::vector<GNEEdge*>::iterator i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
796 if (i == myGNEOutgoingEdges.end()) {
797 throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + getTagStr() + " with ID " + getID() + "'");
798 } else {
799 // remove edge from containers
800 myGNEOutgoingEdges.erase(i);
801 }
802}
803
804
805const std::vector<GNEEdge*>&
809
810
811const std::vector<GNEEdge*>&
815
816
817const std::vector<GNECrossing*>&
821
822
823const std::vector<GNEWalkingArea*>&
827
828
829std::vector<GNEConnection*>
831 std::vector<GNEConnection*> connections;
832 for (const auto& incomingEdge : myGNEIncomingEdges) {
833 for (const auto& connection : incomingEdge->getGNEConnections()) {
834 connections.push_back(connection);
835 }
836 }
837 return connections;
838}
839
840
841void
845
846
847void
851
852
853void
855 myAmTLSSelected = selected;
856}
857
858
859void
861 if (!myNBNode->hasCustomShape()) {
862 if (myNBNode->myPoly.size() > 0) {
863 // write GL Debug
864 WRITE_GLDEBUG("<-- Invalidating shape of junction '" + getID() + "' -->");
865 // clear poly
866 myNBNode->myPoly.clear();
867 // update centering boundary
869 }
871 }
872}
873
874
875void
876GNEJunction::setLogicValid(bool valid, GNEUndoList* undoList, const std::string& status) {
877 myHasValidLogic = valid;
878 if (!valid) {
879 assert(undoList != 0);
880 assert(undoList->hasCommandGroup());
883 for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
884 GNEEdge* srcEdge = myNet->getAttributeCarriers()->retrieveEdge((*it)->getID());
885 removeConnectionsFrom(srcEdge, undoList, false); // false, because the whole tls will be invalidated at the end
887 }
889 invalidateTLS(undoList);
890 } else {
891 // logic valed, then rebuild GNECrossings to adapt it to the new logic
892 // (but don't rebuild the crossings in NBNode because they are already finished)
893 rebuildGNECrossings(false);
894 }
895}
896
897
898void
899GNEJunction::removeConnectionsFrom(GNEEdge* edge, GNEUndoList* undoList, bool updateTLS, int lane) {
900 NBEdge* srcNBE = edge->getNBEdge();
901 NBEdge* turnEdge = srcNBE->getTurnDestination();
902 // Make a copy of connections
903 std::vector<NBEdge::Connection> connections = srcNBE->getConnections();
904 // delete in reverse so that undoing will add connections in the original order
905 for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) {
906 if (lane >= 0 && (*con_it).fromLane != lane) {
907 continue;
908 }
909 bool hasTurn = con_it->toEdge == turnEdge;
910 undoList->add(new GNEChange_Connection(edge, *con_it, false, false), true);
911 // needs to come after GNEChange_Connection
912 // XXX bug: this code path will not be used on a redo!
913 if (hasTurn) {
915 }
916 }
917 if (updateTLS) {
918 std::vector<NBConnection> removeConnections;
919 for (NBEdge::Connection con : connections) {
920 removeConnections.push_back(NBConnection(srcNBE, con.fromLane, con.toEdge, con.toLane));
921 }
922 removeTLSConnections(removeConnections, undoList);
923 }
924}
925
926
927void
928GNEJunction::removeConnectionsTo(GNEEdge* edge, GNEUndoList* undoList, bool updateTLS, int lane) {
929 NBEdge* destNBE = edge->getNBEdge();
930 std::vector<NBConnection> removeConnections;
931 for (NBEdge* srcNBE : myNBNode->getIncomingEdges()) {
932 GNEEdge* srcEdge = myNet->getAttributeCarriers()->retrieveEdge(srcNBE->getID());
933 std::vector<NBEdge::Connection> connections = srcNBE->getConnections();
934 for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) {
935 if ((*con_it).toEdge == destNBE) {
936 if (lane >= 0 && (*con_it).toLane != lane) {
937 continue;
938 }
939 bool hasTurn = srcNBE->getTurnDestination() == destNBE;
940 undoList->add(new GNEChange_Connection(srcEdge, *con_it, false, false), true);
941 // needs to come after GNEChange_Connection
942 // XXX bug: this code path will not be used on a redo!
943 if (hasTurn) {
944 myNet->addExplicitTurnaround(srcNBE->getID());
945 }
946 removeConnections.push_back(NBConnection(srcNBE, (*con_it).fromLane, destNBE, (*con_it).toLane));
947 }
948 }
949 }
950 if (updateTLS) {
951 removeTLSConnections(removeConnections, undoList);
952 }
953}
954
955
956void
957GNEJunction::removeTLSConnections(std::vector<NBConnection>& connections, GNEUndoList* undoList) {
958 if (connections.size() > 0) {
959 const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode->getControllingTLS(); // make a copy!
960 for (const auto& TLS : coypOfTls) {
961 NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
962 // guessed TLS (NBOwnTLDef) do not need to be updated
963 if (tlDef != nullptr) {
964 std::string newID = tlDef->getID();
965 // create replacement before deleting the original because deletion will mess up saving original nodes
966 NBLoadedSUMOTLDef* replacementDef = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
967 for (NBConnection& con : connections) {
968 replacementDef->removeConnection(con);
969 }
970 undoList->add(new GNEChange_TLS(this, tlDef, false), true);
971 undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
972 // the removed traffic light may have controlled more than one junction. These too have become invalid now
973 const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
974 for (const auto& node : copyOfNodes) {
975 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
976 undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
977 undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
978 }
979 }
980 }
981 }
982}
983
984
985void
987 // remap connections of the edge
988 assert(which->getLanes().size() == by->getLanes().size());
989 std::vector<NBEdge::Connection> connections = which->getNBEdge()->getConnections();
990 for (NBEdge::Connection& c : connections) {
991 undoList->add(new GNEChange_Connection(which, c, false, false), true);
992 undoList->add(new GNEChange_Connection(by, c, false, true), true);
993 }
994 // also remap tls connections
995 const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode->getControllingTLS(); // make a copy!
996 for (const auto& TLS : coypOfTls) {
997 NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
998 // guessed TLS (NBOwnTLDef) do not need to be updated
999 if (tlDef != nullptr) {
1000 std::string newID = tlDef->getID();
1001 // create replacement before deleting the original because deletion will mess up saving original nodes
1002 NBLoadedSUMOTLDef* replacementDef = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
1003 for (int i = 0; i < (int)which->getLanes().size(); ++i) {
1004 replacementDef->replaceRemoved(which->getNBEdge(), i, by->getNBEdge(), i, true);
1005 }
1006 undoList->add(new GNEChange_TLS(this, tlDef, false), true);
1007 undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
1008 // the removed traffic light may have controlled more than one junction. These too have become invalid now
1009 const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
1010 for (const auto& node : copyOfNodes) {
1011 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1012 undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
1013 undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
1014 }
1015 }
1016 }
1017}
1018
1019
1020void
1022 EdgeVector incoming = myNBNode->getIncomingEdges();
1023 for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
1024 NBEdge* srcNBE = *it;
1025 GNEEdge* srcEdge = myNet->getAttributeCarriers()->retrieveEdge(srcNBE->getID());
1027 }
1028}
1029
1030
1031void
1032GNEJunction::invalidateTLS(GNEUndoList* undoList, const NBConnection& deletedConnection, const NBConnection& addedConnection) {
1033 assert(undoList->hasCommandGroup());
1034 // NBLoadedSUMOTLDef becomes invalid, replace with NBOwnTLDef which will be dynamically recomputed
1035 const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode->getControllingTLS(); // make a copy!
1036 for (const auto& TLS : coypOfTls) {
1037 NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
1038 if (tlDef != nullptr) {
1039 // the removed traffic light may have controlled more than one junction. These too have become invalid now
1040 const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
1041 if (myGNECrossings.size() == 0 && getNBNode()->getCrossings().size() != 0) {
1042 // crossings were not computed yet. We need them as netedit elements to manage tlIndex resetting
1045 for (const auto& node : copyOfNodes) {
1046 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1047 if (sharing != this) {
1048 sharing->rebuildGNECrossings();
1049 }
1050 }
1051 }
1052 NBTrafficLightDefinition* replacementDef = nullptr;
1053 std::string newID = tlDef->getID(); // + "_reguessed"; // changes due to reguessing will be visible in diff
1054 if (deletedConnection != NBConnection::InvalidConnection) {
1055 // create replacement before deleting the original because deletion will mess up saving original nodes
1056 NBLoadedSUMOTLDef* repl = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
1057 repl->removeConnection(deletedConnection);
1058 replacementDef = repl;
1059 } else if (addedConnection != NBConnection::InvalidConnection) {
1060 if (addedConnection.getTLIndex() == NBConnection::InvalidTlIndex) {
1061 // custom tl indices of crossings might become invalid upon recomputation so we must save them
1062 // however, they could remain valid so we register a change but keep them at their old value
1063 for (const auto& crossing : myGNECrossings) {
1064 const std::string oldValue = crossing->getAttribute(SUMO_ATTR_TLLINKINDEX);
1066 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX, oldValue, undoList, true);
1067 const std::string oldValue2 = crossing->getAttribute(SUMO_ATTR_TLLINKINDEX2);
1069 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX2, oldValue2, undoList, true);
1070 }
1071 }
1072 NBLoadedSUMOTLDef* repl = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
1073 repl->addConnection(addedConnection.getFrom(), addedConnection.getTo(),
1074 addedConnection.getFromLane(), addedConnection.getToLane(), addedConnection.getTLIndex(), addedConnection.getTLIndex2());
1075 replacementDef = repl;
1076 } else {
1077 // recompute crossing indices along with everything else
1078 for (const auto& crossing : myGNECrossings) {
1081 }
1082 replacementDef = new NBOwnTLDef(newID, tlDef->getOffset(), tlDef->getType());
1083 replacementDef->setProgramID(tlDef->getProgramID());
1084 }
1085 undoList->add(new GNEChange_TLS(this, tlDef, false), true);
1086 undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
1087 // reset nodes of joint tls
1088 for (const auto& node : copyOfNodes) {
1089 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1090 if (sharing != this) {
1091 if (deletedConnection == NBConnection::InvalidConnection && addedConnection == NBConnection::InvalidConnection) {
1092 // recompute crossing indices for shared
1093 // (they won't do this on subsequent call to invalidateTLS if they received an NBOwnTLDef)
1094 for (const auto& crossing : sharing->getGNECrossings()) {
1097 }
1098 }
1099 undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
1100 undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
1101 }
1102 }
1103 }
1104 }
1105}
1106
1107void
1109 // obtain a copy of GNECrossing of junctions
1110 const auto copyOfGNECrossings = myGNECrossings;
1111 // iterate over copy of GNECrossings
1112 for (const auto& crossing : copyOfGNECrossings) {
1113 // obtain the set of edges vinculated with the crossing (due it works as ID)
1114 EdgeSet edgeSet(crossing->getCrossingEdges().begin(), crossing->getCrossingEdges().end());
1115 // If this edge is part of the set of edges of crossing
1116 if (edgeSet.count(edge->getNBEdge()) == 1) {
1117 // delete crossing if this is their last edge
1118 if ((crossing->getCrossingEdges().size() == 1) && (crossing->getCrossingEdges().front() == edge->getNBEdge())) {
1119 myNet->deleteCrossing(crossing, undoList);
1120 } else {
1121 // remove this edge of the edge's attribute of crossing (note: This can invalidate the crossing)
1122 std::vector<std::string> edges = GNEAttributeCarrier::parse<std::vector<std::string>>(crossing->getAttribute(SUMO_ATTR_EDGES));
1123 edges.erase(std::find(edges.begin(), edges.end(), edge->getID()));
1124 crossing->setAttribute(SUMO_ATTR_EDGES, joinToString(edges, " "), undoList);
1125 }
1126 }
1127 }
1128}
1129
1130
1131bool
1135
1136
1138GNEJunction::retrieveGNECrossing(NBNode::Crossing* NBNodeCrossing, bool createIfNoExist) {
1139 // iterate over all crossing
1140 for (const auto& crossing : myGNECrossings) {
1141 // if found, return it
1142 if (crossing->getCrossingEdges() == NBNodeCrossing->edges) {
1143 return crossing;
1144 }
1145 }
1146 if (createIfNoExist) {
1147 // create new GNECrossing
1148 GNECrossing* createdGNECrossing = new GNECrossing(this, NBNodeCrossing->edges);
1149 // show extra information for tests
1150 WRITE_DEBUG("Created " + createdGNECrossing->getTagStr() + " '" + createdGNECrossing->getID() + "' in retrieveGNECrossing()");
1151 // update geometry after creating
1152 createdGNECrossing->updateGeometry();
1153 // add it in Network
1154 myNet->addGLObjectIntoGrid(createdGNECrossing);
1155 // add it in attributeCarriers
1156 myNet->getAttributeCarriers()->insertCrossing(createdGNECrossing);
1157 return createdGNECrossing;
1158 } else {
1159 return nullptr;
1160 }
1161}
1162
1163
1165GNEJunction::retrieveGNEWalkingArea(const std::string& NBNodeWalkingAreaID, bool createIfNoExist) {
1166 // iterate over all walkingArea
1167 for (const auto& walkingArea : myGNEWalkingAreas) {
1168 // if found, return it
1169 if (walkingArea->getID() == NBNodeWalkingAreaID) {
1170 return walkingArea;
1171 }
1172 }
1173 if (createIfNoExist) {
1174 // create new GNEWalkingArea
1175 GNEWalkingArea* createdGNEWalkingArea = new GNEWalkingArea(this, NBNodeWalkingAreaID);
1176 // show extra information for tests
1177 WRITE_DEBUG("Created " + createdGNEWalkingArea->getTagStr() + " '" + createdGNEWalkingArea->getID() + "' in retrieveGNEWalkingArea()");
1178 // update geometry after creating
1179 createdGNEWalkingArea->updateGeometry();
1180 // add it in Network
1181 myNet->addGLObjectIntoGrid(createdGNEWalkingArea);
1182 // add it in attributeCarriers
1183 myNet->getAttributeCarriers()->insertWalkingArea(createdGNEWalkingArea);
1184 return createdGNEWalkingArea;
1185 } else {
1186 return nullptr;
1187 }
1188}
1189
1190
1191void
1193 // only it's needed to mark the connections of incoming edges
1194 for (const auto& i : myGNEIncomingEdges) {
1195 for (const auto& j : i->getGNEConnections()) {
1196 j->markConnectionGeometryDeprecated();
1197 }
1198 if (includingNeighbours) {
1199 i->getFromJunction()->markConnectionsDeprecated(false);
1200 }
1201 }
1202}
1203
1204
1205void
1206GNEJunction::setJunctionType(const std::string& value, GNEUndoList* undoList) {
1207 undoList->begin(this, "change " + getTagStr() + " type");
1209 if (getNBNode()->isTLControlled() &&
1210 // if switching changing from or to traffic_light_right_on_red we need to remove the old plan
1213 ) {
1214 // make a copy because we will modify the original
1215 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1216 for (const auto& TLS : copyOfTls) {
1217 undoList->add(new GNEChange_TLS(this, TLS, false), true);
1218 }
1219 }
1220 if (!getNBNode()->isTLControlled()) {
1221 // create new traffic light
1222 undoList->add(new GNEChange_TLS(this, nullptr, true), true);
1223 }
1224 } else if (getNBNode()->isTLControlled()) {
1225 // delete old traffic light
1226 // make a copy because we will modify the original
1227 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1228 for (const auto& TLS : copyOfTls) {
1229 undoList->add(new GNEChange_TLS(this, TLS, false, false), true);
1230 const std::vector<NBNode*> copyOfNodes = TLS->getNodes(); // make a copy!
1231 for (const auto& node : copyOfNodes) {
1232 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1233 sharing->invalidateTLS(undoList);
1234 }
1235 }
1236 }
1237 // must be the final step, otherwise we do not know which traffic lights to remove via GNEChange_TLS
1238 GNEChange_Attribute::changeAttribute(this, SUMO_ATTR_TYPE, value, undoList, true);
1239 for (const auto& crossing : myGNECrossings) {
1240 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX, "-1", undoList, true);
1241 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX2, "-1", undoList, true);
1242 }
1243 undoList->end();
1244}
1245
1246
1247void
1249 // delete non retrieved GNEWalkingAreas (we don't need to extract if from Tree two times)
1250 for (const auto& walkingArea : myGNEWalkingAreas) {
1251 walkingArea->decRef();
1252 // check if walkingArea is selected
1253 if (walkingArea->isAttributeCarrierSelected()) {
1254 walkingArea->unselectAttributeCarrier();
1255 }
1256 // remove it from inspected ACS
1258 // remove it from net
1259 myNet->removeGLObjectFromGrid(walkingArea);
1260 // remove it from attributeCarriers
1262 if (walkingArea->unreferenced()) {
1263 // show extra information for tests
1264 WRITE_DEBUG("Deleting unreferenced " + walkingArea->getTagStr() + " in rebuildGNEWalkingAreas()");
1265 delete walkingArea;
1266 }
1267 }
1268 myGNEWalkingAreas.clear();
1269}
1270
1271
1272void
1274 // first clear GNEWalkingAreas
1276 // iterate over NBNode::WalkingAreas of GNEJunction
1277 for (const auto& walkingArea : myNBNode->getWalkingAreas()) {
1278 // retrieve existent GNEWalkingArea, or create it
1279 GNEWalkingArea* retrievedGNEWalkingArea = retrieveGNEWalkingArea(walkingArea.id, true);
1280 // include reference to created GNEWalkingArea
1281 retrievedGNEWalkingArea->incRef();
1282 // update geometry of retrieved walkingArea
1283 retrievedGNEWalkingArea->updateGeometry();
1284 // update boundary
1285 retrievedGNEWalkingArea->updateCenteringBoundary(false);
1286 // add in walkingAreas
1287 myGNEWalkingAreas.push_back(retrievedGNEWalkingArea);
1288 }
1289}
1290
1291
1292
1293void
1295 if (std::find(myInternalLanes.begin(), myInternalLanes.end(), internalLane) != myInternalLanes.end()) {
1296 throw ProcessError(internalLane->getTagStr() + " with ID='" + internalLane->getID() + "' already exist");
1297 } else {
1298 myInternalLanes.push_back(internalLane);
1299 }
1300}
1301
1302
1303void
1305 const auto finder = std::find(myInternalLanes.begin(), myInternalLanes.end(), internalLane);
1306 if (finder == myInternalLanes.end()) {
1307 throw ProcessError(internalLane->getTagStr() + " with ID='" + internalLane->getID() + "' wasn't previously inserted");
1308 } else {
1309 myInternalLanes.erase(finder);
1310 }
1311}
1312
1313
1314std::string
1316 switch (key) {
1317 case SUMO_ATTR_ID:
1318 return getMicrosimID();
1319 case SUMO_ATTR_POSITION:
1320 return toString(myNBNode->getPosition());
1321 case SUMO_ATTR_TYPE:
1322 return toString(myNBNode->getType());
1324 return myLogicStatus;
1325 case SUMO_ATTR_SHAPE:
1326 return toString(myNBNode->getShape());
1327 case SUMO_ATTR_RADIUS:
1328 if (myNBNode->getRadius() < 0) {
1329 return "default";
1330 } else {
1331 return toString(myNBNode->getRadius());
1332 }
1333 case SUMO_ATTR_TLTYPE:
1335 // @todo this causes problems if the node were to have multiple programs of different type (plausible)
1336 return toString((*myNBNode->getControllingTLS().begin())->getType());
1337 } else {
1338 return "No TLS";
1339 }
1340 case SUMO_ATTR_TLLAYOUT:
1342 return toString((*myNBNode->getControllingTLS().begin())->getLayout());
1343 } else {
1344 return "No TLS";
1345 }
1346 case SUMO_ATTR_TLID:
1348 return toString((*myNBNode->getControllingTLS().begin())->getID());
1349 } else {
1350 return "No TLS";
1351 }
1353 return myNBNode->isRoundabout() ? True : False;
1355 // keep clear is only used as a convenience feature in plain xml
1356 // input. When saving to .net.xml the status is saved only for the connections
1357 // to show the correct state we must check all connections
1358 for (const auto& i : myGNEIncomingEdges) {
1359 for (const auto& j : i->getGNEConnections()) {
1360 if (j->getNBEdgeConnection().keepClear) {
1361 return True;
1362 }
1363 }
1364 }
1365 return False;
1368 case SUMO_ATTR_FRINGE:
1370 case SUMO_ATTR_NAME:
1371 return myNBNode->getName();
1373 return myNBNode->getParametersStr();
1374 default:
1375 return getCommonAttribute(key);
1376 }
1377}
1378
1379
1382 switch (key) {
1383 case SUMO_ATTR_SHAPE:
1384 return myNBNode->getShape();
1385 default:
1386 throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1387 }
1388}
1389
1390
1391void
1392GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
1393 if (value == getAttribute(key)) {
1394 return; //avoid needless changes, later logic relies on the fact that attributes have changed
1395 }
1396 switch (key) {
1397 case SUMO_ATTR_ID:
1399 case SUMO_ATTR_SHAPE:
1400 case SUMO_ATTR_RADIUS:
1402 case SUMO_ATTR_FRINGE:
1403 case SUMO_ATTR_NAME:
1405 GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);
1406 break;
1407 case SUMO_ATTR_POSITION: {
1408 // change Keep Clear attribute in all connections
1409 undoList->begin(this, TL("change junction position"));
1410 // obtain NBNode position
1411 const Position orig = myNBNode->getPosition();
1412 // change junction position
1413 GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);
1414 // calculate delta using new position
1415 const Position delta = myNBNode->getPosition() - orig;
1416 // set new position of adjacent edges
1417 for (const auto& edge : myGNEIncomingEdges) {
1418 const Position newEnd = edge->getNBEdge()->getGeometry().back() + delta;
1420 }
1421 for (const auto& edge : myGNEOutgoingEdges) {
1422 const Position newStart = edge->getNBEdge()->getGeometry().front() + delta;
1423 GNEChange_Attribute::changeAttribute(edge, GNE_ATTR_SHAPE_START, toString(newStart), undoList, true);
1424 }
1425 undoList->end();
1426 break;
1427 }
1429 // change Keep Clear attribute in all connections
1430 undoList->begin(this, TL("change keepClear for whole junction"));
1431 for (const auto& incomingEdge : myGNEIncomingEdges) {
1432 for (const auto& junction : incomingEdge->getGNEConnections()) {
1433 GNEChange_Attribute::changeAttribute(junction, key, value, undoList, true);
1434 }
1435 }
1436 undoList->end();
1437 break;
1438 case SUMO_ATTR_TYPE: {
1439 // set junction type
1440 setJunctionType(value, undoList);
1441 break;
1442 }
1443 case SUMO_ATTR_TLTYPE: {
1444 undoList->begin(this, "change " + getTagStr() + " tl-type");
1445 // make a copy because we will modify the original
1446 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1447 for (const auto& TLS : copyOfTls) {
1448 NBLoadedSUMOTLDef* oldLoaded = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
1449 if (oldLoaded != nullptr) {
1450 NBTrafficLightDefinition* newDef = nullptr;
1451 if (value == toString(TrafficLightType::NEMA) || oldLoaded->getType() == TrafficLightType::NEMA) {
1452 // rebuild the program because the old and new ones are incompatible
1453 newDef = new NBOwnTLDef(oldLoaded->getID(), oldLoaded->getOffset(), TrafficLightType::NEMA);
1454 newDef->setProgramID(oldLoaded->getProgramID());
1455 } else {
1456 NBLoadedSUMOTLDef* newLDef = new NBLoadedSUMOTLDef(*oldLoaded, *oldLoaded->getLogic());
1457 newLDef->guessMinMaxDuration(); // minDur and maxDur are never written for a static tls
1458 newDef = newLDef;
1459 }
1460 std::vector<NBNode*> nodes = TLS->getNodes();
1461 for (const auto& node : nodes) {
1462 GNEJunction* junction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1463 undoList->add(new GNEChange_TLS(junction, TLS, false), true);
1464 undoList->add(new GNEChange_TLS(junction, newDef, true), true);
1465 }
1466 }
1467 }
1468 GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);
1469 undoList->end();
1470 break;
1471 }
1472 case SUMO_ATTR_TLLAYOUT: {
1473 undoList->begin(this, "change " + getTagStr() + " tlLayout");
1474 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1475 for (const auto& oldTLS : copyOfTls) {
1476 std::vector<NBNode*> copyOfNodes = oldTLS->getNodes();
1477 NBOwnTLDef* newTLS = new NBOwnTLDef(oldTLS->getID(), oldTLS->getOffset(), oldTLS->getType());
1479 newTLS->setProgramID(oldTLS->getProgramID());
1480 for (const auto& node : copyOfNodes) {
1481 GNEJunction* oldJunction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1482 undoList->add(new GNEChange_TLS(oldJunction, oldTLS, false), true);
1483 }
1484 for (const auto& node : copyOfNodes) {
1485 GNEJunction* oldJunction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1486 undoList->add(new GNEChange_TLS(oldJunction, newTLS, true), true);
1487 }
1488 }
1489 undoList->end();
1490 break;
1491 }
1492 case SUMO_ATTR_TLID: {
1493 undoList->begin(this, "change " + toString(SUMO_TAG_TRAFFIC_LIGHT) + " id");
1494 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1495 assert(copyOfTls.size() > 0);
1496 NBTrafficLightDefinition* currentTLS = *copyOfTls.begin();
1497 NBTrafficLightDefinition* currentTLSCopy = nullptr;
1498 const bool currentIsSingle = currentTLS->getNodes().size() == 1;
1499 const bool currentIsLoaded = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS) != nullptr;
1500 if (currentIsLoaded) {
1501 currentTLSCopy = new NBLoadedSUMOTLDef(*currentTLS,
1502 *dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS)->getLogic());
1503 }
1504 // remove from previous tls
1505 for (const auto& TLS : copyOfTls) {
1506 undoList->add(new GNEChange_TLS(this, TLS, false), true);
1507 }
1509 // programs to which the current node shall be added
1510 const std::map<std::string, NBTrafficLightDefinition*> programs = tlCont.getPrograms(value);
1511 if (programs.size() > 0) {
1512 for (const auto& TLSProgram : programs) {
1513 NBTrafficLightDefinition* oldTLS = TLSProgram.second;
1514 if (dynamic_cast<NBOwnTLDef*>(oldTLS) != nullptr) {
1515 undoList->add(new GNEChange_TLS(this, oldTLS, true), true);
1516 } else {
1517 // delete and re-create the definition because the loaded phases are now invalid
1518 if (dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS) != nullptr &&
1519 dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->usingSignalGroups()) {
1520 // keep the old program and add all-red state for the added links
1521 NBLoadedSUMOTLDef* newTLSJoined = new NBLoadedSUMOTLDef(*oldTLS, *dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->getLogic());
1522 newTLSJoined->joinLogic(currentTLSCopy);
1523 undoList->add(new GNEChange_TLS(this, newTLSJoined, true, true), true);
1524 } else {
1525 undoList->add(new GNEChange_TLS(this, nullptr, true, false, value), true);
1526 }
1528 // switch from old to new definition
1529 std::vector<NBNode*> copyOfNodes = oldTLS->getNodes();
1530 for (const auto& node : copyOfNodes) {
1531 GNEJunction* oldJunction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1532 undoList->add(new GNEChange_TLS(oldJunction, oldTLS, false), true);
1533 undoList->add(new GNEChange_TLS(oldJunction, newTLS, true), true);
1534 }
1535 }
1536 }
1537 } else {
1538 if (currentIsSingle && currentIsLoaded) {
1539 // rename the traffic light but keep everything else
1540 NBTrafficLightLogic* renamedLogic = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLSCopy)->getLogic();
1541 renamedLogic->setID(value);
1542 NBLoadedSUMOTLDef* renamedTLS = new NBLoadedSUMOTLDef(*currentTLSCopy, *renamedLogic);
1543 renamedTLS->setID(value);
1544 undoList->add(new GNEChange_TLS(this, renamedTLS, true, true), true);
1545 } else {
1546 // create new traffic light
1547 undoList->add(new GNEChange_TLS(this, nullptr, true, false, value), true);
1548 }
1549 }
1550 delete currentTLSCopy;
1551 undoList->end();
1552 break;
1553 }
1554 default:
1555 setCommonAttribute(key, value, undoList);
1556 break;
1557 }
1558}
1559
1560
1561bool
1562GNEJunction::isValid(SumoXMLAttr key, const std::string& value) {
1563 switch (key) {
1564 case SUMO_ATTR_ID:
1565 return SUMOXMLDefinitions::isValidNetID(value) && (myNet->getAttributeCarriers()->retrieveJunction(value, false) == nullptr);
1566 case SUMO_ATTR_TYPE:
1568 case SUMO_ATTR_POSITION:
1569 return canParse<Position>(value);
1570 case SUMO_ATTR_SHAPE:
1571 // empty shapes are allowed
1572 return canParse<PositionVector>(value);
1573 case SUMO_ATTR_RADIUS:
1574 if (value.empty() || (value == "default")) {
1575 return true;
1576 } else {
1577 return canParse<double>(value) && ((parse<double>(value) >= 0) || (parse<double>(value) == -1));
1578 }
1579 case SUMO_ATTR_TLTYPE:
1581 case SUMO_ATTR_TLLAYOUT:
1583 case SUMO_ATTR_TLID:
1584 return myNBNode->isTLControlled() && (value != "");
1586 return canParse<bool>(value);
1589 case SUMO_ATTR_FRINGE:
1591 case SUMO_ATTR_NAME:
1592 return true;
1595 default:
1596 return isCommonValid(key, value);
1597 }
1598}
1599
1600
1601bool
1603 switch (key) {
1604 case SUMO_ATTR_TLTYPE:
1605 case SUMO_ATTR_TLLAYOUT:
1606 case SUMO_ATTR_TLID:
1607 return myNBNode->isTLControlled();
1608 case SUMO_ATTR_KEEP_CLEAR: {
1609 // check if at least there is an incoming connection
1610 for (const auto& incomingEdge : myGNEIncomingEdges) {
1611 if (incomingEdge->getGNEConnections().size() > 0) {
1612 return true;
1613 }
1614 }
1615 return false;
1616 }
1618 return false;
1619 default:
1620 return true;
1621 }
1622}
1623
1624
1625bool
1627 switch (key) {
1628 case SUMO_ATTR_SHAPE:
1629 return !myNBNode->hasCustomShape();
1630 default:
1631 return false;
1632 }
1633}
1634
1635
1636const Parameterised::Map&
1640
1641
1642void
1644 myAmResponsible = newVal;
1645}
1646
1647// ===========================================================================
1648// private
1649// ===========================================================================
1650
1651bool
1652GNEJunction::drawAsBubble(const GUIVisualizationSettings& s, const double junctionShapeArea) const {
1653 const auto& editModes = myNet->getViewNet()->getEditModes();
1654 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
1655 // check conditions
1656 if (junctionShapeArea < 4) {
1657 // force draw if this junction is a candidate
1660 return true;
1661 }
1662 // force draw if we're in person/container plan mode
1663 if (editModes.isCurrentSupermodeDemand() &&
1664 ((editModes.demandEditMode == DemandEditMode::DEMAND_PERSON) ||
1665 (editModes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) ||
1666 (editModes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) ||
1667 (editModes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN))) {
1668 return true;
1669 }
1670 // force draw if we're inspecting a vehicle that start or ends in a junction
1671 if (inspectedElements.isInspectingSingleElement()) {
1672 // check if starts or ends in this junction
1673 if ((inspectedElements.getFirstAC()->hasAttribute(SUMO_ATTR_FROM_JUNCTION) &&
1674 (inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_FROM_JUNCTION) == getID())) ||
1675 (inspectedElements.getFirstAC()->hasAttribute(SUMO_ATTR_TO_JUNCTION) &&
1676 (inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_TO_JUNCTION) == getID()))) {
1677 return true;
1678 }
1679 }
1680 }
1681 if (!s.drawJunctionShape) {
1682 // don't draw bubble if it was disabled in GUIVisualizationSettings
1683 return false;
1684 }
1686 // force draw bubbles if we enabled option in checkbox of viewNet
1687 return true;
1688 }
1689 if (junctionShapeArea >= 4) {
1690 // don't draw if shape area is greater than 4
1691 return false;
1692 }
1693 if (!editModes.isCurrentSupermodeNetwork()) {
1694 // only draw bubbles in network mode
1695 return false;
1696 }
1697 return true;
1698}
1699
1700
1701void
1703 const double exaggeration) const {
1704 // calculate bubble radius
1705 const double bubbleRadius = s.neteditSizeSettings.junctionBubbleRadius * exaggeration;
1706 // set bubble color
1707 const RGBColor bubbleColor = setColor(s, true);
1708 // push matrix
1710 // set color
1711 GLHelper::setColor(bubbleColor);
1712 // move matrix junction center
1713 glTranslated(myNBNode->getPosition().x(), myNBNode->getPosition().y(), 1.5);
1714 // draw filled circle
1715 GLHelper::drawFilledCircleDetailled(d, bubbleRadius);
1716 // pop matrix
1718}
1719
1720
1721void
1723 // first check drawing conditions
1724 if (s.drawJunctionShape && (myNBNode->getShape().size() > 0)) {
1725 // set shape color
1726 const RGBColor junctionShapeColor = setColor(s, false);
1727 // set color
1728 GLHelper::setColor(junctionShapeColor);
1729 // adjust shape to exaggeration (check)
1730 if ((exaggeration > 1 || myExaggeration > 1) && exaggeration != myExaggeration) {
1731 myExaggeration = exaggeration;
1734 myTesselation.getShapeRef().scaleRelative(exaggeration);
1736 }
1737 // check if draw tesselation or or polygon
1739 // draw shape with high detail
1741 } else {
1742 // draw shape
1744 }
1745 // draw shape points only in Network supermode
1748 // set color
1749 const RGBColor darkerColor = junctionShapeColor.changedBrightness(-32);
1750 // calculate geometry
1751 GUIGeometry junctionGeometry;
1752 // obtain junction Shape
1753 PositionVector junctionOpenShape = myNBNode->getShape();
1754 // adjust shape to exaggeration
1755 if (exaggeration > 1) {
1756 junctionOpenShape.scaleRelative(exaggeration);
1757 }
1758 // update geometry
1759 junctionGeometry.updateGeometry(junctionOpenShape);
1760 // set color
1761 GLHelper::setColor(darkerColor);
1762 // draw shape
1764 // draw geometry points
1765 GUIGeometry::drawGeometryPoints(d, junctionOpenShape, darkerColor,
1768 }
1769 }
1770}
1771
1772
1773void
1775 // draw TLS icon if isn't being drawn for selecting
1779 const Position pos = myNBNode->getPosition();
1780 glTranslated(pos.x(), pos.y(), 2.2);
1781 glColor3d(1, 1, 1);
1782 const double halfWidth = 32 / s.scale;
1783 const double halfHeight = 64 / s.scale;
1784 GUITexturesHelper::drawTexturedBox(GUITextureSubSys::getTexture(GUITexture::TLS), -halfWidth, -halfHeight, halfWidth, halfHeight);
1786 }
1787}
1788
1789
1790void
1792 // check if draw elevation
1795 // Translate to center of junction
1796 glTranslated(myNBNode->getPosition().x(), myNBNode->getPosition().y(), 0.1);
1797 // draw Z value
1800 }
1801}
1802
1803
1804void
1811
1812
1813void
1815 // check if draw junction elements
1817 // draw crossings
1818 for (const auto& crossing : myGNECrossings) {
1819 crossing->drawGL(s);
1820 }
1821 // draw walking areas
1822 for (const auto& walkingArea : myGNEWalkingAreas) {
1823 walkingArea->drawGL(s);
1824 }
1825 // draw internalLanes
1826 for (const auto& internalLanes : myInternalLanes) {
1827 internalLanes->drawGL(s);
1828 }
1829 // draw connections
1830 for (const auto& incomingEdge : myGNEIncomingEdges) {
1831 for (const auto& connection : incomingEdge->getGNEConnections()) {
1832 connection->drawGL(s);
1833 }
1834 }
1835 // draw child demand elements
1836 for (const auto& demandElement : getChildDemandElements()) {
1837 demandElement->drawGL(s);
1838 }
1839 // draw child demand elements
1840 for (const auto& demandElement : getChildDemandElements()) {
1841 demandElement->drawGL(s);
1842 }
1843 // draw path additional elements
1847 }
1848}
1849
1850
1851void
1853 const double exaggeration, const bool drawBubble) const {
1854 // if we're selecting using a boundary, first don't calculate contour bt check if edge boundary is within selection boundary
1856 // simply add object in ViewObjectsHandler with full boundary
1857 gViewObjectsHandler.selectObject(this, getType(), false, true, nullptr);
1858 } else {
1859 // always calculate for shape
1860 myNetworkElementContour.calculateContourClosedShape(s, d, this, myNBNode->getShape(), getType(), exaggeration, this);
1861 // check if calculate contour for bubble
1862 if (drawBubble) {
1864 }
1865 // check geometry points if we're editing shape
1866 if (myShapeEdited) {
1868 exaggeration, true);
1869 }
1870 }
1871}
1872
1873
1874void
1875GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value) {
1876 switch (key) {
1877 case SUMO_ATTR_KEEP_CLEAR: {
1878 throw InvalidArgument(toString(key) + " cannot be edited");
1879 }
1880 case SUMO_ATTR_ID: {
1882 break;
1883 }
1884 case SUMO_ATTR_TYPE: {
1889 }
1891 break;
1892 }
1893 case SUMO_ATTR_POSITION: {
1894 // set new position in NBNode updating edge boundaries
1895 moveJunctionGeometry(parse<Position>(value), true);
1896 // mark this connections and all of the junction's Neighbours as deprecated
1898 // update centering boundary and grid
1900 break;
1901 }
1903 if (myLogicStatus == FEATURE_GUESSED && value != FEATURE_GUESSED) {
1904 // clear guessed connections. previous connections will be restored
1906 // Clear GNEConnections of incoming edges
1907 for (const auto& i : myGNEIncomingEdges) {
1908 i->clearGNEConnections();
1909 }
1910 }
1911 myLogicStatus = value;
1912 break;
1913 case SUMO_ATTR_SHAPE: {
1914 // set new shape (without updating grid)
1915 myNBNode->setCustomShape(parse<PositionVector>(value));
1916 // mark this connections and all of the junction's neighbors as deprecated
1918 // update centering boundary and grid
1920 break;
1921 }
1922 case SUMO_ATTR_RADIUS: {
1923 if (value.empty() || (value == "default")) {
1924 myNBNode->setRadius(-1);
1925 } else {
1926 myNBNode->setRadius(parse<double>(value));
1927 }
1928 break;
1929 }
1930 case SUMO_ATTR_TLTYPE: {
1931 // we need to make a copy of controlling TLS (because original will be updated)
1932 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1933 for (const auto& TLS : copyOfTls) {
1934 TLS->setType(SUMOXMLDefinitions::TrafficLightTypes.get(value));
1935 }
1936 break;
1937 }
1938 case SUMO_ATTR_TLLAYOUT:
1939 // should not be triggered (handled via GNEChange_TLS)
1940 break;
1943 break;
1944 case SUMO_ATTR_FRINGE:
1946 break;
1947 case SUMO_ATTR_NAME:
1948 myNBNode->setName(value);
1949 break;
1951 myNBNode->setParametersStr(value);
1952 break;
1953 default:
1954 setCommonAttribute(key, value);
1955 break;
1956 }
1957 // invalidate demand path calculator
1959}
1960
1961
1962void
1964 // clear contour
1966 // set new position in NBNode without updating grid
1967 if (isShapeEdited()) {
1968 // set new shape
1970 } else if (moveResult.shapeToUpdate.size() > 0) {
1971 // obtain NBNode position
1972 const Position orig = myNBNode->getPosition();
1973 // move geometry
1974 moveJunctionGeometry(moveResult.shapeToUpdate.front(), false);
1975 // set new position of adjacent edges depending if we're moving a selection
1976 for (const auto& NBEdge : getNBNode()->getEdges()) {
1977 myNet->getAttributeCarriers()->retrieveEdge(NBEdge->getID())->updateJunctionPosition(this, orig);
1978 }
1979 }
1981}
1982
1983
1984void
1986 // make sure that newShape isn't empty
1987 if (moveResult.shapeToUpdate.size() > 0) {
1988 // check if we're editing a shape
1989 if (isShapeEdited()) {
1990 // commit new shape
1991 undoList->begin(this, "moving " + toString(SUMO_ATTR_SHAPE) + " of " + getTagStr());
1992 setAttribute(SUMO_ATTR_SHAPE, toString(moveResult.shapeToUpdate), undoList);
1993 undoList->end();
1994 } else if (myNBNode->hasCustomShape()) {
1995 // commit new shape
1996 undoList->begin(this, "moving custom " + toString(SUMO_ATTR_SHAPE) + " of " + getTagStr());
1997 setAttribute(SUMO_ATTR_POSITION, toString(moveResult.shapeToUpdate.front()), undoList);
1998 // calculate offset and apply to custom shape
1999 const auto customShapeOffset = moveResult.shapeToUpdate.front() - myNBNode->getCenter();
2000 const auto customShapeMoved = myNBNode->getShape().added(customShapeOffset);
2001 setAttribute(SUMO_ATTR_SHAPE, toString(customShapeMoved), undoList);
2002 undoList->end();
2003 } else {
2004 setAttribute(SUMO_ATTR_POSITION, toString(moveResult.shapeToUpdate.front()), undoList);
2005 }
2006 // check merge junctions
2008 }
2009}
2010
2011
2012double
2013GNEJunction::getColorValue(const GUIVisualizationSettings& /* s */, int activeScheme) const {
2014 switch (activeScheme) {
2015 case 0:
2017 return 3;
2018 } else {
2019 return 0;
2020 }
2021 case 1:
2023 case 2:
2024 switch (myNBNode->getType()) {
2026 return 0;
2028 return 1;
2030 return 2;
2032 return 3;
2034 return 4;
2036 return 5;
2038 return 6;
2040 return 7;
2043 return 8;
2045 return 8; // may happen before first network computation
2047 assert(false);
2048 return 8;
2050 return 9;
2052 return 10;
2054 return 11;
2056 return 12;
2058 return 13;
2059 default:
2060 assert(false);
2061 return 0;
2062 }
2063 case 3:
2064 return myNBNode->getPosition().z();
2065 default:
2066 assert(false);
2067 return 0;
2068 }
2069}
2070
2071void
2073 for (auto edge : myGNEIncomingEdges) {
2074 if (edge->getGNEConnections().size() > 0) {
2076 return;
2077 }
2078 }
2079 // no connections. Use normal color for border edges and cul-de-sac
2080 if (myGNEIncomingEdges.size() == 0 || myGNEOutgoingEdges.size() == 0) {
2082 return;
2083 } else if (myGNEIncomingEdges.size() == 1 && myGNEOutgoingEdges.size() == 1) {
2084 NBEdge* in = myGNEIncomingEdges[0]->getNBEdge();
2085 NBEdge* out = myGNEOutgoingEdges[0]->getNBEdge();
2086 if (in->isTurningDirectionAt(out)) {
2088 return;
2089 }
2090 }
2092}
2093
2094
2095void
2096GNEJunction::moveJunctionGeometry(const Position& pos, const bool updateEdgeBoundaries) {
2097 // reinit NBNode
2098 myNBNode->reinit(pos, myNBNode->getType());
2099 // declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
2100 std::set<GNEJunction*> affectedJunctions;
2101 std::set<GNEEdge*> affectedEdges;
2102 // Iterate over GNEEdges
2103 for (const auto& edge : getChildEdges()) {
2104 // Add source and destination junctions
2105 affectedJunctions.insert(edge->getFromJunction());
2106 affectedJunctions.insert(edge->getToJunction());
2107 // Obtain neighbors of Junction source
2108 for (const auto& junctionSourceEdge : edge->getFromJunction()->getChildEdges()) {
2109 affectedEdges.insert(junctionSourceEdge);
2110 }
2111 // Obtain neighbors of Junction destination
2112 for (const auto& junctionDestinationEdge : edge->getToJunction()->getChildEdges()) {
2113 affectedEdges.insert(junctionDestinationEdge);
2114 }
2115 }
2116 // reset walking areas of affected edges
2117 for (const auto& affectedJunction : affectedJunctions) {
2118 affectedJunction->clearWalkingAreas();
2119 }
2120 // Iterate over affected Edges
2121 for (const auto& affectedEdge : affectedEdges) {
2122 // update edge boundaries
2123 if (updateEdgeBoundaries) {
2124 affectedEdge->updateCenteringBoundary(true);
2125 }
2126 // Update edge geometry
2127 affectedEdge->updateGeometry();
2128 }
2129}
2130
2131
2134 // get active scheme
2135 const int scheme = s.junctionColorer.getActive();
2136 // first check if we're editing shape
2137 if (myShapeEdited) {
2139 }
2140 // set default color
2142 // set special bubble color
2143 if (bubble && (scheme == 0) && !myColorForMissingConnections) {
2144 color = s.junctionColorer.getScheme().getColor(1);
2145 }
2146 // override with special colors (unless the color scheme is based on selection)
2147 if (drawUsingSelectColor() && scheme != 1) {
2148 color = s.colorSettings.selectionColor;
2149 }
2150 // overwrite color if we're in data mode
2152 color = s.junctionColorer.getScheme().getColor(6);
2153 }
2154 // special color for source candidate junction
2155 if (mySourceCandidate) {
2157 }
2158 // special color for target candidate junction
2159 if (myTargetCandidate) {
2161 }
2162 // special color for special candidate junction
2163 if (mySpecialCandidate) {
2165 }
2166 // special color for possible candidate junction
2167 if (myPossibleCandidate) {
2169 }
2170 // special color for conflicted candidate junction
2173 }
2174 // return color
2175 return color;
2176}
2177
2178
2179void
2182 tlCont.insert(tlDef, forceInsert); // may return false for tlDef which controls multiple junctions
2183 tlDef->addNode(myNBNode);
2184}
2185
2186
2187void
2190 if (tlDef->getNodes().size() == 1) {
2191 tlCont.extract(tlDef);
2192 }
2194}
2195
2196
2197/****************************************************************************/
@ NETWORK_DELETE
mode for deleting network elements
@ NETWORK_MOVE
mode for moving network elements
@ NETWORK_CREATE_EDGE
mode for creating new edges
@ NETWORK_TLS
mode for editing tls
@ NETWORK_CROSSING
Mode for editing crossing.
@ NETWORK_SELECT
mode for selecting network elements
@ NETWORK_CONNECT
mode for connecting lanes
@ DEMAND_PERSONPLAN
Mode for editing person plan.
@ DEMAND_CONTAINER
Mode for editing container.
@ DEMAND_PERSON
Mode for editing person.
@ DEMAND_VEHICLE
Mode for editing vehicles.
@ DEMAND_CONTAINERPLAN
Mode for editing container plan.
@ MID_GNE_JUNCTION_ADDTLS
Add TLS into junction.
@ MID_GNE_JUNCTION_RESET_EDGE_ENDPOINTS
reset edge endpoints
@ MID_GNE_JUNCTION_CLEAR_CONNECTIONS
clear junction's connections
@ MID_GNE_JUNCTION_SELECT_ROUNDABOUT
select all roundabout nodes and edges of the current roundabout
@ MID_GNE_JUNCTION_RESET_SHAPE
reset junction shape
@ MID_GNE_JUNCTION_RESET_CONNECTIONS
reset junction's connections
@ MID_GNE_JUNCTION_SPLIT
turn junction into multiple junctions
@ MID_GNE_JUNCTION_REPLACE
turn junction into geometry node
@ MID_GNE_JUNCTION_CONVERT_ROUNDABOUT
convert junction to roundabout
@ MID_GNE_JUNCTION_SPLIT_RECONNECT
turn junction into multiple junctions and reconnect them heuristically
@ MID_GNE_JUNCTION_EDIT_SHAPE
edit junction shape
@ MID_GNE_JUNCTION_ADDJOINTLS
Add join TLS into junctions.
@ GLO_MAX
empty max
@ GLO_JUNCTION
a junction
GUIViewObjectsHandler gViewObjectsHandler
GUIIcon
An enumeration of icons used by the gui applications.
Definition GUIIcons.h:33
#define WRITE_DEBUG(msg)
Definition MsgHandler.h:306
#define TL(string)
Definition MsgHandler.h:315
#define TLF(string,...)
Definition MsgHandler.h:317
#define WRITE_GLDEBUG(msg)
Definition MsgHandler.h:307
std::set< NBEdge * > EdgeSet
container for unique edges
Definition NBCont.h:50
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition NBCont.h:42
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_TRAFFIC_LIGHT
a traffic light
@ SUMO_TAG_EDGE
begin/end of the description of an edge
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_TLLINKINDEX2
link: the index of the opposite direction link of a pedestrian crossing
@ SUMO_ATTR_FROM_JUNCTION
@ SUMO_ATTR_RADIUS
The turning radius at an intersection in m.
@ SUMO_ATTR_TO_JUNCTION
@ SUMO_ATTR_TLLAYOUT
node: the layout of the traffic light program
@ SUMO_ATTR_EDGES
the edges of a route
@ GNE_ATTR_PARAMETERS
parameters "key1=value1|key2=value2|...|keyN=valueN"
@ SUMO_ATTR_FRINGE
Fringe type of node.
@ GNE_ATTR_MODIFICATION_STATUS
whether a feature has been loaded,guessed,modified or approved
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_TLTYPE
node: the type of traffic light
@ SUMO_ATTR_NAME
@ GNE_ATTR_IS_ROUNDABOUT
@ GNE_ATTR_SHAPE_END
last coordinate of edge shape
@ SUMO_ATTR_TLID
link,node: the traffic light id responsible for this link
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_ID
@ SUMO_ATTR_RIGHT_OF_WAY
How to compute right of way.
@ GNE_ATTR_SHAPE_START
first coordinate of edge shape
@ SUMO_ATTR_TLLINKINDEX
link: the index of the link within the traffic light
@ SUMO_ATTR_KEEP_CLEAR
Whether vehicles must keep the junction clear.
@ SUMO_ATTR_POSITION
const unsigned char TLS[]
Definition TLS.cpp:22
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition ToString.h:283
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition Boundary.cpp:78
bool isInitialised() const
check if Boundary is Initialised
Definition Boundary.cpp:259
Boundary & grow(double by)
extends the boundary by the given amount
Definition Boundary.cpp:343
bool contains2D(const Boundary &b) const
return true if this boundary contains the given boundary (only X-Y)
Definition Boundary.cpp:232
std::string fromJunction
from junction
static void drawFilledPoly(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition GLHelper.cpp:204
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition GLHelper.cpp:649
static void popMatrix()
pop matrix
Definition GLHelper.cpp:131
static void drawBoundary(const GUIVisualizationSettings &s, const Boundary &b)
Draw a boundary (used for debugging)
Definition GLHelper.cpp:961
static void drawFilledCircleDetailled(const GUIVisualizationSettings::Detail d, const double radius)
Draws a filled circle around (0,0) depending of level of detail.
Definition GLHelper.cpp:534
static void pushMatrix()
push matrix
Definition GLHelper.cpp:118
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0, const int align=0, double width=-1)
Definition GLHelper.cpp:751
static void drawTextSettings(const GUIVisualizationTextSettings &settings, const std::string &text, const Position &pos, const double scale, const double angle=0, const double layer=2048, const int align=0)
Definition GLHelper.cpp:782
const std::string getID() const
get ID (all Attribute Carriers have one)
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
bool mySelected
boolean to check if this AC is selected (more quickly as checking GUIGlObjectStorage)
static const std::string True
true value in string format (used for comparing boolean values in getAttribute(......
void setCommonAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
const std::string & getTagStr() const
get tag assigned to this object in string format
static const std::string FEATURE_GUESSED
feature has been reguessed (may still be unchanged be we can't tell (yet)
bool drawUsingSelectColor() const
check if attribute carrier must be drawn using selecting color.
bool isCommonValid(SumoXMLAttr key, const std::string &value)
void drawInLayer(const double typeOrLayer, const double extraOffset=0) const
draw element in the given layer, or in front if corresponding flag is enabled
GNENet * myNet
pointer to net
bool inGrid() const
check if this AC was inserted in grid
static const std::string FEATURE_MODIFIED
feature has been manually modified (implies approval)
static const std::string False
true value in string format(used for comparing boolean values in getAttribute(...))
std::string getCommonAttribute(SumoXMLAttr key) const
bool myPossibleCandidate
flag to mark this element as possible candidate
bool mySpecialCandidate
flag to mark this element as special candidate
bool myTargetCandidate
flag to mark this element as target candidate
bool myConflictedCandidate
flag to mark this element as conflicted candidate
bool mySourceCandidate
flag to mark this element as source candidate
static void changeAttribute(GNEAttributeCarrier *AC, SumoXMLAttr key, const std::string &value, GNEUndoList *undoList, const bool force=false)
change attribute
void clearContour() const
void clear contour
void drawDottedContourGeometryPoints(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GNEAttributeCarrier *AC, const PositionVector &shape, const double radius, const double scale, const double lineWidth) const
draw dotted contour for geometry points
void calculateContourCircleShape(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GUIGlObject *glObject, const Position &pos, double radius, const double layer, const double scale, const GUIGlObject *boundaryParent) const
calculate contour (circle elements)
void calculateContourClosedShape(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GUIGlObject *glObject, const PositionVector &shape, const double layer, const double scale, const GUIGlObject *boundaryParent, const bool addToSelectedObjects=true) const
calculate contours
bool drawDottedContours(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GNEAttributeCarrier *AC, const double lineWidth, const bool addOffset) const
draw dotted contours (basics, select, delete, inspect...)
void calculateContourAllGeometryPoints(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GUIGlObject *glObject, const PositionVector &shape, const double layer, const double radius, const double scale, const bool calculatePosOverShape) const
calculate contour for all geometry points
GNEJunction * getCurrentJunction() const
get current junction
GNECrossingFrame::EdgesSelector * getEdgesSelector() const
get edge selector modul
This object is responsible for drawing a shape and for supplying a a popup menu. Messages are routete...
Definition GNECrossing.h:44
void updateCenteringBoundary(const bool updateGrid)
update centering boundary (implies change in RTREE)
void updateGeometry()
update pre-computed geometry information
struct for saving subordinated elements (Junction->Edge->Lane->(Additional | DemandElement)
ProtectElements * getProtectElements() const
get protect elements modul
A road/street connecting two junctions (netedit-version)
Definition GNEEdge.h:53
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition GNEEdge.cpp:781
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition GNEEdge.cpp:1118
const std::vector< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
const std::vector< GNEEdge * > & getChildEdges() const
get child edges
This object is responsible for drawing a shape and for supplying a a popup menu. Messages are routete...
void removeTLSConnections(std::vector< NBConnection > &connections, GNEUndoList *undoList)
remove the given connections from all traffic light definitions of this junction
bool checkDrawRelatedContour() const
check if draw related contour (cyan)
void updateGLObject()
update GLObject (geometry, ID, etc.)
void markAsCreateEdgeSource()
marks as first junction in createEdge-mode
void addTrafficLight(NBTrafficLightDefinition *tlDef, bool forceInsert)
adds a traffic light
const std::vector< GNEEdge * > & getGNEIncomingEdges() const
Returns incoming GNEEdges.
void rebuildGNEWalkingAreas()
rebuilds WalkingAreas objects for this junction
void updateGeometryAfterNetbuild(bool rebuildNBNodeCrossings=false)
update pre-computed geometry information without modifying netbuild structures
bool myAmResponsible
whether we are responsible for deleting myNBNode
void removeGeometryPoint(const Position clickedPosition, GNEUndoList *undoList)
remove geometry point in the clicked position
const std::vector< GNECrossing * > & getGNECrossings() const
Returns GNECrossings.
friend class GNEChange_TLS
Declare friend class.
Definition GNEJunction.h:53
TesselatedPolygon myTesselation
An object that stores the shape and its tesselation.
const std::vector< GNEWalkingArea * > & getGNEWalkingAreas() const
Returns GNEWalkingAreas.
std::string getAttribute(SumoXMLAttr key) const
void setResponsible(bool newVal)
set responsibility for deleting internal structures
void deleteGLObject()
delete element
bool myColorForMissingConnections
whether this junction probably should have some connections but doesn't
std::vector< const GNEInternalLane * > myInternalLanes
internal lanes related placed in this junction
GNEJunction(GNENet *net, NBNode *nbn, bool loaded=false)
Constructor.
void unMarkAsCreateEdgeSource()
removes mark as first junction in createEdge-mode
void moveJunctionGeometry(const Position &pos, const bool updateEdgeBoundaries)
reposition the node at pos without updating GRID and informs the edges
double getExaggeration(const GUIVisualizationSettings &s) const
return exaggeration associated with this GLObject
void invalidateShape()
GNEContour myCircleContour
variable used for draw circle contours
void updateGeometry()
update pre-computed geometry information (including crossings)
void drawTLSIcon(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d) const
draw TLS icon
bool isLogicValid()
whether this junction has a valid logic
std::vector< GNEEdge * > myGNEOutgoingEdges
vector with the (child) outgoings GNEEdges vinculated with this junction
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const
determines color value
void commitMoveShape(const GNEMoveResult &moveResult, GNEUndoList *undoList)
commit move shape
void selectTLS(bool selected)
notify the junction of being selected in tls-mode. (used to control drawing)
void replaceIncomingConnections(GNEEdge *which, GNEEdge *by, GNEUndoList *undoList)
replace one edge by another in all tls connections
void removeOutgoingGNEEdge(GNEEdge *edge)
remove outgoing GNEEdge
void markAsModified(GNEUndoList *undoList)
prevent re-guessing connections at this junction
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
std::vector< GNECrossing * > myGNECrossings
the built crossing objects
bool checkDrawMoveContour() const
check if draw move contour (red)
void invalidateTLS(GNEUndoList *undoList, const NBConnection &deletedConnection=NBConnection::InvalidConnection, const NBConnection &addedConnection=NBConnection::InvalidConnection)
PositionVector getAttributePositionVector(SumoXMLAttr key) const
void clearWalkingAreas()
clear walking areas
void removeIncomingGNEEdge(GNEEdge *edge)
remove incoming GNEEdge
std::vector< GNEConnection * > getGNEConnections() const
Returns all GNEConnections vinculated with this junction.
bool checkDrawSelectContour() const
check if draw select contour (blue)
GNEWalkingArea * retrieveGNEWalkingArea(const std::string &NBNodeWalkingAreaID, bool createIfNoExist=true)
get GNEWalkingArea if exist, and if not create it if create is enabled
GNEMoveOperation * getMoveOperation()
get move operation
bool checkDrawFromContour() const
check if draw from contour (green)
bool checkDrawOverContour() const
check if draw over contour (orange)
GNECrossing * retrieveGNECrossing(NBNode::Crossing *NBNodeCrossing, bool createIfNoExist=true)
get GNECrossing if exist, and if not create it if create is enabled
std::vector< GNEEdge * > myGNEIncomingEdges
vector with the (child) incomings GNEEdges vinculated with this junction
Boundary myJunctionBoundary
edge boundary
void calculateJunctioncontour(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const double exaggeration, const bool drawBubble) const
calculate contour
void addInternalLane(const GNEInternalLane *internalLane)
add internal lane
const PositionVector & getJunctionShape() const
void setMoveShape(const GNEMoveResult &moveResult)
set move shape
void drawJunctionName(const GUIVisualizationSettings &s) const
draw junction name
void markConnectionsDeprecated(bool includingNeighbours)
mark connections as deprecated
bool checkDrawToContour() const
check if draw from contour (magenta)
const Parameterised::Map & getACParametersMap() const
get parameters map
void mirrorXLeftHand()
temporarily mirror coordinates in lefthand network to compute correct crossing geometries
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Position getPositionInView() const
Returns position of hierarchical element in view.
void drawJunctionAsBubble(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const double exaggeration) const
draw junction as bubble
bool isAttributeComputed(SumoXMLAttr key) const
void removeInternalLane(const GNEInternalLane *internalLane)
remove internal lane
bool myAmTLSSelected
whether this junction is selected in tls-mode
void removeConnectionsFrom(GNEEdge *edge, GNEUndoList *undoList, bool updateTLS, int lane=-1)
remove all connections from the given edge
bool isValid(SumoXMLAttr key, const std::string &value)
void addIncomingGNEEdge(GNEEdge *edge)
add incoming GNEEdge
RGBColor setColor(const GUIVisualizationSettings &s, bool bubble) const
sets junction color depending on circumstances
bool myHasValidLogic
whether this junctions logic is valid
std::string myLogicStatus
modification status of the junction logic (all connections across this junction)
void updateCenteringBoundary(const bool updateGrid)
update centering boundary (implies change in RTREE)
const std::vector< GNEEdge * > & getGNEOutgoingEdges() const
Returns incoming GNEEdges.
void removeEdgeFromCrossings(GNEEdge *edge, GNEUndoList *undoList)
removes the given edge from all pedestrian crossings
void drawJunctionChildren(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d) const
draw junction childs
bool drawAsBubble(const GUIVisualizationSettings &s, const double junctionShapeArea) const
check if draw junction as bubble
NBNode * getNBNode() const
Return net build node.
NBNode * myNBNode
A reference to the represented junction.
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
int * myDrawingToggle
drawing toggle (used to avoid double draws)
void checkMissingConnections()
compute whether this junction probably should have some connections but doesn't
std::vector< GNEJunction * > getJunctionNeighbours() const
return GNEJunction neighbours
void setJunctionType(const std::string &value, GNEUndoList *undoList)
set junction Type (using undo/redo)
bool checkDrawDeleteContour() const
check if draw delete contour (pink/white)
void drawJunctionAsShape(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const double exaggeration) const
draw junction as bubble
double myExaggeration
exaggeration used in tesselation
void drawElevation(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d) const
draw elevation
~GNEJunction()
Destructor.
void setLogicValid(bool valid, GNEUndoList *undoList, const std::string &status=FEATURE_GUESSED)
std::vector< GNEWalkingArea * > myGNEWalkingAreas
the built walkingArea objects
void removeConnectionsTo(GNEEdge *edge, GNEUndoList *undoList, bool updateTLS, int lane=-1)
remove all connections to the given edge
bool myAmCreateEdgeSource
whether this junction is the first junction for a newly creatededge
void buildTLSOperations(GUISUMOAbstractView &parent, GUIGLObjectPopupMenu *ret, const int numSelectedJunctions)
build TLS operations contextual menu
void addOutgoingGNEEdge(GNEEdge *edge)
add outgoing GNEEdge
void rebuildGNECrossings(bool rebuildNBNodeCrossings=true)
rebuilds crossing objects for this junction
bool isAttributeEnabled(SumoXMLAttr key) const
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
removes a traffic light
GNEMoveOperation * calculateMoveShapeOperation(const GUIGlObject *obj, const PositionVector originalShape, const bool maintainShapeClosed)
calculate move shape operation
move operation
move result
PositionVector shapeToUpdate
shape to update (edited in moveElement)
void insertWalkingArea(GNEWalkingArea *walkingArea)
insert walkingArea in container
const std::unordered_map< const GUIGlObject *, GNECrossing * > & getCrossings() const
get crossings
GNEJunction * retrieveJunction(const std::string &id, bool hardFail=true) const
get junction by id
void updateJunctionID(GNEJunction *junction, const std::string &newID)
update junction ID in container
void insertCrossing(GNECrossing *crossing)
insert crossing in container
void deleteWalkingArea(GNEWalkingArea *walkingArea)
delete walkingArea from container
int getNumberOfSelectedJunctions() const
get number of selected junctions
GNEEdge * retrieveEdge(const std::string &id, bool hardFail=true) const
get edge by id
const std::unordered_map< const GUIGlObject *, GNEWalkingArea * > & getWalkingAreas() const
get walkingAreas
void deleteCrossing(GNECrossing *crossing)
delete crossing from container
A NBNetBuilder extended by visualisation and editing capabilities.
Definition GNENet.h:42
void deleteCrossing(GNECrossing *crossing, GNEUndoList *undoList)
remove crossing
Definition GNENet.cpp:658
NBNetBuilder * getNetBuilder() const
get net builder
Definition GNENet.cpp:1563
void addGLObjectIntoGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition GNENet.cpp:1390
GNEPathManager * getDataPathManager()
get data path manager
Definition GNENet.cpp:151
void removeGLObjectFromGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition GNENet.cpp:1400
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition GNENet.cpp:2169
GNEPathManager * getDemandPathManager()
get demand path manager
Definition GNENet.cpp:145
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:127
GNEPathManager * getNetworkPathManager()
get network path manager
Definition GNENet.cpp:139
void requireRecompute()
inform the net about the need for recomputation
Definition GNENet.cpp:1545
void addExplicitTurnaround(std::string id)
add edge id to the list of explicit turnarounds
Definition GNENet.cpp:2181
void deleteJunction(GNEJunction *junction, GNEUndoList *undoList)
removes junction and all incident edges
Definition GNENet.cpp:386
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2163
bool checkDrawingBoundarySelection() const
GNEContour myNetworkElementContour
network element contour
bool myShapeEdited
flag to check if element shape is being edited
GUIGLObjectPopupMenu * getShapeEditedPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent, const PositionVector &shape)
get shape edited popup menu
bool isShapeEdited() const
check if shape is being edited
void invalidatePathCalculator()
invalidate pathCalculator
PathCalculator * getPathCalculator()
obtain instance of PathCalculator
void drawJunctionPathElements(const GUIVisualizationSettings &s, const GNEJunction *junction) const
draw junction path elements
const CommonXMLStructure::PlanParameters & getPlanParameteres() const
get plan parameters
bool markJunctions() const
check if mark junctions with dotted contours
void incRef(const std::string &debugMsg="")
Increase reference.
void end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
bool hasCommandGroup() const
Check if undoList has command group.
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
void add(GNEChange *command, bool doit=false, bool merge=true)
Add new command, executing it if desired. The new command will be merged with the previous command if...
void uninspectAC(GNEAttributeCarrier *AC)
uninspect AC
const GUIGlObject * getGUIGlObjectFront() const
get front GUIGLObject or a pointer to nullptr
GNEJunction * getJunctionFront() const
get front junction or a pointer to nullptr
bool isCurrentlyMovingElements() const
check if an element is being moved
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
const GNEViewNetHelper::EditNetworkElementShapes & getEditNetworkElementShapes() const
get Edit Shape module
GNEViewNetHelper::InspectedElements & getInspectedElements()
get inspected elements
const GNEViewNetHelper::MoveSingleElementModul & getMoveSingleElementValues() const
get move single element values
bool showJunctionAsBubbles() const
return true if junction must be showed as bubbles
const GNEViewNetHelper::NetworkViewOptions & getNetworkViewOptions() const
get network view options
int getDrawingToggle() const
get draw toggle (used to avoid drawing junctions twice)
GNEViewParent * getViewParent() const
get the net object
bool checkOverLockedElement(const GUIGlObject *GLObject, const bool isSelected) const
check if given element is locked (used for drawing select and delete contour)
GNEUndoList * getUndoList() const
get the undoList object
const GNEViewNetHelper::ViewObjectsSelector & getViewObjectsSelector() const
get objects under cursor
bool checkMergeJunctions()
try to merge moved junction with another junction in that spot return true if merging did take place
void buildSelectionACPopupEntry(GUIGLObjectPopupMenu *ret, GNEAttributeCarrier *AC)
Builds an entry which allows to (de)select the object.
GNECrossingFrame * getCrossingFrame() const
get frame for NETWORK_CROSSING
GNEDeleteFrame * getDeleteFrame() const
get frame for delete elements
This object is responsible for drawing a shape and for supplying a a popup menu. Messages are routete...
void updateCenteringBoundary(const bool updateGrid)
update centering boundary (implies change in RTREE)
void updateGeometry()
update pre-computed geometry information
static FXMenuCommand * buildFXMenuCommand(FXComposite *p, const std::string &text, FXIcon *icon, FXObject *tgt, FXSelector sel, const bool disable=false)
build menu command
The popup menu of a globject.
void insertMenuPaneChild(FXMenuPane *child)
Insert a sub-menu pane in this GUIGLObjectPopupMenu.
static void drawGeometryPoints(const GUIVisualizationSettings::Detail d, const PositionVector &shape, const RGBColor &color, const double radius, const double exaggeration, const bool editingElevation)
draw geometry points
static void drawGeometry(const GUIVisualizationSettings::Detail d, const GUIGeometry &geometry, const double width, double offset=0)
draw geometry
void updateGeometry(const PositionVector &shape)
update entire geometry
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, const GUIMainWindow &app) const
Builds an entry which allows to copy the cursor position if geo projection is used,...
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0, bool forceShow=false) const
draw name of item
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
T getColor(const double value) const
const GUIVisualizationSettings & getVisualisationSettings() const
get visualization settings (read only)
static GUIGlID getTexture(GUITexture which)
returns a texture previously defined in the enum GUITexture
static void drawTexturedBox(int which, double size)
Draws a named texture as a box with the given size.
const Boundary & getSelectionBoundary() const
get selection boundary
bool selectObject(const GUIGlObject *GLObject, const double layer, const bool checkDuplicated, const bool fullBoundary, const GNESegment *segment)
bool addMergingJunctions(const GNEJunction *junction)
add to merging junctions (used for marking junctions to merge)
Stores the information about how to visualize structures.
GUIVisualizationTextSettings junctionName
GUIVisualizationSizeSettings junctionSize
bool drawJunctionShape
whether the shape of the junction should be drawn
Detail getDetailLevel(const double exaggeration) const
return the detail level
GUIVisualizationCandidateColorSettings candidateColorSettings
candidate color settings
GUIVisualizationTextSettings junctionID
bool drawMovingGeometryPoint(const double exaggeration, const double radius) const
check if moving geometry point can be draw
GUIVisualizationColorSettings colorSettings
color settings
GUIVisualizationDottedContourSettings dottedContourSettings
dotted contour settings
double scale
information about a lane's width (temporary, used for a single view)
bool drawForViewObjectsHandler
whether drawing is performed for the purpose of selecting objects in view using ViewObjectsHandler
GUIColorer junctionColorer
The junction colorer.
GUIVisualizationNeteditSizeSettings neteditSizeSettings
netedit size settings
double angle
The current view rotation angle.
NBEdge * getFrom() const
returns the from-edge (start of the connection)
int getFromLane() const
returns the from-lane
int getTLIndex2() const
int getTLIndex() const
returns the index within the controlling tls or InvalidTLIndex if this link is unontrolled
static const int InvalidTlIndex
int getToLane() const
returns the to-lane
NBEdge * getTo() const
returns the to-edge (end of the connection)
static const NBConnection InvalidConnection
void removeRoundabout(const NBNode *node)
remove roundabout that contains the given node
The representation of a single edge during network building.
Definition NBEdge.h:92
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition NBEdge.h:1041
const std::string & getID() const
Definition NBEdge.h:1528
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
Definition NBEdge.cpp:3665
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition NBEdge.cpp:4008
A loaded (complete) traffic light logic.
void setID(const std::string &newID)
resets the id
NBTrafficLightLogic * getLogic()
Returns the internal logic.
void removeConnection(const NBConnection &conn, bool reconstruct=true)
removes the given connection from the traffic light if recontruct=true, reconstructs the logic and in...
void joinLogic(NBTrafficLightDefinition *def)
join nodes and states from the given logic (append red state)
void addConnection(NBEdge *from, NBEdge *to, int fromLane, int toLane, int linkIndex, int linkIndex2, bool reconstruct=true)
Adds a connection and immediately informs the edges.
void guessMinMaxDuration()
heuristically add minDur and maxDur when switching from tlType fixed to actuated
void replaceRemoved(NBEdge *removed, int removedLane, NBEdge *by, int byLane, bool incoming)
Replaces a removed edge/lane.
bool haveNetworkCrossings()
notify about style of loaded network (Without Crossings)
void setHaveNetworkCrossings(bool value)
enable crossing in networks
NBEdgeCont & getEdgeCont()
A definition of a pedestrian crossing.
Definition NBNode.h:135
EdgeVector edges
The edges being crossed.
Definition NBNode.h:142
Represents a single node (junction) during network building.
Definition NBNode.h:66
RightOfWay getRightOfWay() const
Returns hint on how to compute right of way.
Definition NBNode.h:300
Position getCenter() const
Returns a position that is guaranteed to lie within the node shape.
Definition NBNode.cpp:4019
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node (The set of tls that control this node)
Definition NBNode.h:336
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
Definition NBNode.cpp:338
static const double UNSPECIFIED_RADIUS
unspecified lane width
Definition NBNode.h:220
FringeType getFringeType() const
Returns fringe type.
Definition NBNode.h:305
void buildCrossingsAndWalkingAreas()
build crossings, and walkingareas. Also removes invalid loaded crossings if wished
Definition NBNode.cpp:2933
SumoXMLNodeType getType() const
Returns the type of this node.
Definition NBNode.h:285
bool isTrafficLight() const
Definition NBNode.h:822
void setRightOfWay(RightOfWay rightOfWay)
set method for computing right-of-way
Definition NBNode.h:569
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition NBNode.cpp:2673
void invalidateIncomingConnections(bool reallowSetting=false)
invalidate incoming connections
Definition NBNode.cpp:2041
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
Definition NBNode.h:268
void mirrorX()
mirror coordinates along the x-axis
Definition NBNode.cpp:377
std::vector< std::pair< Position, std::string > > getEndPoints() const
return list of unique endpoint coordinates of all edges at this node
Definition NBNode.cpp:4175
const std::vector< std::unique_ptr< Crossing > > & getCrossingsIncludingInvalid() const
Definition NBNode.h:742
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
Definition NBNode.h:273
bool hasCustomShape() const
return whether the shape was set by the user
Definition NBNode.h:584
std::vector< Crossing * > getCrossings() const
return this junctions pedestrian crossings
Definition NBNode.cpp:2982
const std::string & getName() const
Returns intersection name.
Definition NBNode.h:310
void setRadius(double radius)
set the turning radius
Definition NBNode.h:559
void setName(const std::string &name)
set intersection name
Definition NBNode.h:579
const Position & getPosition() const
Definition NBNode.h:260
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
Definition NBNode.cpp:406
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node)
Definition NBNode.h:278
const PositionVector & getShape() const
retrieve the junction shape
Definition NBNode.cpp:2667
double getRadius() const
Returns the turning radius of this node.
Definition NBNode.h:290
bool isRoundabout() const
return whether this node is part of a roundabout
Definition NBNode.cpp:3882
bool checkIsRemovableReporting(std::string &reason) const
check if node is removable and return reason if not
Definition NBNode.cpp:2554
const std::vector< WalkingArea > & getWalkingAreas() const
return this junctions pedestrian walking areas
Definition NBNode.h:747
PositionVector myPoly
the (outer) shape of the junction
Definition NBNode.h:940
void setFringeType(FringeType fringeType)
set method for computing right-of-way
Definition NBNode.h:574
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition NBNode.h:331
A traffic light logics which must be computed (only nodes/edges are given)
Definition NBOwnTLDef.h:44
void setLayout(TrafficLightLayout layout)
sets the layout for the generated signal plan
Definition NBOwnTLDef.h:143
The base class for traffic light logic definitions.
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
const std::string & getProgramID() const
Returns the ProgramID.
TrafficLightType getType() const
get the algorithm type (static etc..)
virtual void setProgramID(const std::string &programID)
Sets the programID.
virtual void addNode(NBNode *node)
Adds a node to the traffic light logic.
SUMOTime getOffset()
Returns the offset.
A container for traffic light definitions and built programs.
const std::map< std::string, NBTrafficLightDefinition * > & getPrograms(const std::string &id) const
Returns all programs for the given tl-id.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
void extract(NBTrafficLightDefinition *definition)
Extracts a traffic light definition from myDefinitions but keeps it in myExtracted for eventual * del...
A SUMO-compliant built logic for a traffic light.
static void computeTurnDirectionsForNode(NBNode *node, bool warn)
Computes turnaround destinations for all incoming edges of the given nodes (if any)
virtual void setID(const std::string &newID)
resets the id
Definition Named.h:82
const std::string & getID() const
Returns the id.
Definition Named.h:74
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
static OptionsCont & getOptions()
Retrieves the options.
static bool areParametersValid(const std::string &value, bool report=false, const std::string kvsep="=", const std::string sep="|")
check if given string can be parsed to a parameters map "key1=value1|key2=value2|....
std::map< std::string, std::string > Map
parameters map
void setParametersStr(const std::string &paramsString, const std::string kvsep="=", const std::string sep="|")
set the inner key/value map in string format "key1=value1|key2=value2|...|keyN=valueN"
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
std::string getParametersStr(const std::string kvsep="=", const std::string sep="|") const
Returns the inner key/value map in string format "key1=value1|key2=value2|...|keyN=valueN".
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
double distanceSquaredTo2D(const Position &p2) const
returns the square of the distance to another position (Only using x and y positions)
Definition Position.h:281
double x() const
Returns the x-position.
Definition Position.h:55
double z() const
Returns the z-position.
Definition Position.h:65
double y() const
Returns the y-position.
Definition Position.h:60
A list of positions.
PositionVector added(const Position &offset) const
void closePolygon()
ensures that the last position equals the first
int indexOfClosest(const Position &p, bool twoD=false) const
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
void scaleRelative(double factor)
enlarges/shrinks the polygon by a factor based at the centroid
double area() const
Returns the area (0 for non-closed)
bool around(const Position &p, double offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point.
RGBColor changedBrightness(int change, int toChange=3) const
Returns a new color with altered brightness.
Definition RGBColor.cpp:200
const PositionVector & getShape() const
Returns the shape of the polygon.
virtual void setShape(const PositionVector &shape)
Sets the shape of the polygon.
PositionVector & getShapeRef()
Return the exterior shape of the polygon.
static StringBijection< SumoXMLNodeType > NodeTypes
node types
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
static StringBijection< TrafficLightLayout > TrafficLightLayouts
traffic light layouts
static bool isValidNetID(const std::string &value)
whether the given string is a valid id for a network element
static StringBijection< RightOfWay > RightOfWayValues
righ of way algorithms
static StringBijection< FringeType > FringeTypeValues
fringe types
const std::string & getString(const T key) const
bool hasString(const std::string &str) const
T get(const std::string &str) const
std::vector< GLPrimitive > myTesselation
id of the display list for the cached tesselation
Definition GUIPolygon.h:74
void drawTesselation(const PositionVector &shape) const
perform the tesselation / drawing
NetworkEditMode networkEditMode
the current Network edit mode
bool isCurrentSupermodeData() const
@check if current supermode is Data
bool isCurrentSupermodeNetwork() const
@check if current supermode is Network
GNENetworkElement * getEditedNetworkElement() const
pointer to edited network element
static void drawLockIcon(const GUIVisualizationSettings::Detail d, const GNEAttributeCarrier *AC, GUIGlObjectType type, const Position position, const double exaggeration, const double size=0.5, const double offsetx=0, const double offsety=0)
draw lock icon
GNEMoveElement * getMovedElement() const
get moved element
bool editingElevation() const
check if we're editing elevation
static const RGBColor special
color for selected special candidate element (Usually selected using shift+click)
static const RGBColor conflict
color for selected conflict candidate element (Usually selected using ctrl+click)
static const RGBColor target
color for selected candidate target
static const RGBColor possible
color for possible candidate element
static const RGBColor source
color for selected candidate source
RGBColor selectionColor
basic selection color
static const RGBColor editShapeColor
color for edited shapes (Junctions, crossings and connections)
static const double segmentWidthSmall
width of small dotted contour segments
static const double segmentWidth
width of dotted contour segments
static const double junctionGeometryPointRadius
moving junction geometry point radius
static const double junctionBubbleRadius
junction bubble radius
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values
bool show(const GUIGlObject *o) const
whether to show the text
double scaledSize(double scale, double constFactor=0.1) const
get scale size
A structure which describes a connection between edges or lanes.
Definition NBEdge.h:201