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-2026 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
25#include <netbuild/NBOwnTLDef.h>
41#include <netedit/GNENet.h>
43#include <netedit/GNEUndoList.h>
51
52#include "GNEConnection.h"
53#include "GNEJunction.h"
54#include "GNECrossing.h"
55#include "GNEWalkingArea.h"
56#include "GNEInternalLane.h"
57
58// ===========================================================================
59// method definitions
60// ===========================================================================
61
62GNEJunction::GNEJunction(GNENet* net, NBNode* nbn, bool loaded) :
63 GNENetworkElement(net, nbn->getID(), SUMO_TAG_JUNCTION),
64 myMoveElementJunction(new GNEMoveElementJunction(this)),
65 myNBNode(nbn),
66 myDrawingToggle(new int),
67 myLogicStatus(loaded ? FEATURE_LOADED : FEATURE_GUESSED),
68 myHasValidLogic(loaded),
69 myTesselation(nbn->getID(), "", RGBColor::MAGENTA, nbn->getShape(), false, true, 0) {
70 // update centering boundary without updating grid
72}
73
74
76 // delete drawing toggle
77 delete myDrawingToggle;
78 // delete all GNECrossing
79 for (const auto& crossing : myGNECrossings) {
80 crossing->decRef();
81 if (crossing->unreferenced()) {
82 // check if remove it from Attribute Carriers
83 if (myNet->getAttributeCarriers()->getCrossings().count(crossing) > 0) {
85 }
86 delete crossing;
87 }
88 }
89 // delete all GNEWalkingArea
90 for (const auto& walkingArea : myGNEWalkingAreas) {
91 walkingArea->decRef();
92 if (walkingArea->unreferenced()) {
93 // check if remove it from Attribute Carriers
94 if (myNet->getAttributeCarriers()->getWalkingAreas().count(walkingArea) > 0) {
96 }
97 delete walkingArea;
98 }
99 }
100 if (myAmResponsible) {
101 delete myNBNode;
102 }
103}
104
105
110
111
116
117
118const Parameterised*
120 return myNBNode;
121}
122
123
124const PositionVector&
126 return myNBNode->getShape();
127}
128
129
130void
133 // trigger rebuilding tesselation
134 myExaggeration = 2;
135}
136
137
138void
139GNEJunction::updateGeometryAfterNetbuild(bool rebuildNBNodeCrossings) {
140 // rebuild crossings
141 rebuildGNECrossings(rebuildNBNodeCrossings);
142 // clear walking areas
144 // clear missing connections
146}
147
148
153
154
155bool
157 // get modes and viewParent (for code legibility)
158 const auto& modes = myNet->getViewNet()->getEditModes();
159 const auto& viewParent = myNet->getViewParent();
160 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
161 // continue depending of current status
162 if (inspectedElements.isInspectingSingleElement()) {
163 const auto inspectedAC = inspectedElements.getFirstAC();
164 // check if starts in this junction
165 if (inspectedAC->hasAttribute(SUMO_ATTR_FROM_JUNCTION) &&
166 (inspectedAC->getAttribute(SUMO_ATTR_FROM_JUNCTION) == getID())) {
167 return true;
168 } else if ((inspectedAC->getTagProperty()->getTag() == SUMO_TAG_EDGE) &&
169 (inspectedAC->getAttribute(SUMO_ATTR_FROM) == getID())) {
170 return true;
171 } else if ((inspectedAC->getTagProperty()->getTag() == SUMO_TAG_LANE) &&
172 (inspectedAC->getAttribute(SUMO_ATTR_FROM_JUNCTION) == getID())) {
173 return true;
174 }
175 } else if (modes.isCurrentSupermodeNetwork()) {
176 if (modes.networkEditMode == NetworkEditMode::NETWORK_CREATE_EDGE) {
177 if (viewParent->getCreateEdgeFrame()->getJunctionSource()) {
178 return viewParent->getCreateEdgeFrame()->getJunctionSource() == this;
179 } else {
181 }
182 } else if ((modes.networkEditMode == NetworkEditMode::NETWORK_TLS) &&
183 viewParent->getTLSEditorFrame()->getTLSJunction()->isJoiningJunctions()) {
184 for (const auto& id : viewParent->getTLSEditorFrame()->getTLSJunction()->getSelectedJunctionIDs()) {
185 if (id == getMicrosimID()) {
186 return true;
187 }
188 }
189 }
190 } else if (modes.isCurrentSupermodeDemand()) {
191 // get current GNEPlanCreator
192 GNEPlanCreator* planCreator = nullptr;
193 if (modes.demandEditMode == DemandEditMode::DEMAND_PERSON) {
194 planCreator = viewParent->getPersonFrame()->getPlanCreator();
195 } else if (modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) {
196 planCreator = viewParent->getPersonPlanFrame()->getPlanCreator();
197 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) {
198 planCreator = viewParent->getContainerFrame()->getPlanCreator();
199 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) {
200 planCreator = viewParent->getContainerPlanFrame()->getPlanCreator();
201 }
202 // continue depending of planCreator
203 if (planCreator) {
204 if (planCreator->getPlanParameteres().fromJunction == getID()) {
205 return true;
206 }
207 } else if (modes.demandEditMode == DemandEditMode::DEMAND_VEHICLE) {
208 const auto& selectedJunctions = viewParent->getVehicleFrame()->getPathCreator()->getSelectedJunctions();
209 // check if this is the first selected junction
210 if ((selectedJunctions.size() > 0) && (selectedJunctions.front() == this)) {
211 return true;
212 }
213 }
214 }
215 // nothing to draw
216 return false;
217}
218
219
220bool
222 // get modes and viewParent (for code legibility)
223 const auto& modes = myNet->getViewNet()->getEditModes();
224 const auto& viewParent = myNet->getViewParent();
225 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
226 // continue depending of current status
227 if (inspectedElements.isInspectingSingleElement()) {
228 const auto inspectedAC = inspectedElements.getFirstAC();
229 // check if ends in this junction
230 if (inspectedAC->getTagProperty()->vehicleJunctions() &&
231 (inspectedAC->getAttribute(SUMO_ATTR_TO_JUNCTION) == getID())) {
232 return true;
233 } else if ((inspectedAC->getTagProperty()->getTag() == SUMO_TAG_EDGE) &&
234 (inspectedAC->getAttribute(SUMO_ATTR_TO) == getID())) {
235 return true;
236 } else if ((inspectedAC->getTagProperty()->getTag() == SUMO_TAG_LANE) &&
237 (inspectedAC->getAttribute(SUMO_ATTR_TO_JUNCTION) == getID())) {
238 return true;
239 }
240 } else if (modes.isCurrentSupermodeNetwork()) {
241 if (modes.networkEditMode == NetworkEditMode::NETWORK_CREATE_EDGE) {
242 if (viewParent->getCreateEdgeFrame()->getJunctionSource() &&
243 (viewParent->getCreateEdgeFrame()->getJunctionSource() != this)) {
245 }
246 } else if (modes.networkEditMode == NetworkEditMode::NETWORK_MOVE) {
247 // check if we're moving a junction
248 const auto moveElementJunction = dynamic_cast<GNEMoveElementJunction*>(myNet->getViewNet()->getMoveSingleElementValues().getMovedElement());
249 if (moveElementJunction && (moveElementJunction->getJunction() != this)) {
250 // continue depending of junction shape
251 if (myNBNode->getShape().area() < 4) {
252 // calculate distance between both centers
253 const double junctionBubbleRadius = myNet->getViewNet()->getVisualisationSettings().neteditSizeSettings.junctionBubbleRadius;
254 const double radiusTo = getExaggeration(myNet->getViewNet()->getVisualisationSettings()) * junctionBubbleRadius;
255 if (myNBNode->getPosition().distanceSquaredTo2D(moveElementJunction->getJunction()->getPositionInView()) < (radiusTo * radiusTo)) {
256 // add both it in the list of merging junction
257 gViewObjectsHandler.addMergingJunctions(moveElementJunction->getJunction());
259 return true;
260 }
261 } else if (myNBNode->getShape().around(moveElementJunction->getJunction()->getNBNode()->getPosition())) {
262 // add both it in the list of merging junction
263 gViewObjectsHandler.addMergingJunctions(moveElementJunction->getJunction());
265 return true;
266 }
267 }
268 }
269 } else if (modes.isCurrentSupermodeDemand()) {
270 // get current GNEPlanCreator
271 GNEPlanCreator* planCreator = nullptr;
272 if (modes.demandEditMode == DemandEditMode::DEMAND_PERSON) {
273 planCreator = viewParent->getPersonFrame()->getPlanCreator();
274 } else if (modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) {
275 planCreator = viewParent->getPersonPlanFrame()->getPlanCreator();
276 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) {
277 planCreator = viewParent->getContainerFrame()->getPlanCreator();
278 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) {
279 planCreator = viewParent->getContainerPlanFrame()->getPlanCreator();
280 }
281 // continue depending of planCreator
282 if (planCreator) {
283 if (planCreator->getPlanParameteres().toJunction == getID()) {
284 return true;
285 }
286 } else if (modes.demandEditMode == DemandEditMode::DEMAND_VEHICLE) {
287 const auto& selectedJunctions = viewParent->getVehicleFrame()->getPathCreator()->getSelectedJunctions();
288 // check if this is the first selected junction
289 if ((selectedJunctions.size() > 1) && (selectedJunctions.back() == this)) {
290 return true;
291 }
292 }
293 }
294 // nothing to draw
295 return false;
296}
297
298
299bool
302 return true;
303 }
304 // check opened popup
305 if (myNet->getViewNet()->getPopup()) {
306 return myNet->getViewNet()->getPopup()->getGLObject() == this;
307 }
308 return false;
309}
310
311
312bool
314 // get modes and viewParent (for code legibility)
315 const auto& modes = myNet->getViewNet()->getEditModes();
316 const auto& viewParent = myNet->getViewParent();
317 const auto& viewObjectsSelector = myNet->getViewNet()->getViewObjectsSelector();
318 if (viewObjectsSelector.getJunctionFront() != this) {
319 return false;
320 } else {
321 if (modes.isCurrentSupermodeNetwork()) {
322 if (modes.networkEditMode == NetworkEditMode::NETWORK_CROSSING) {
323 return (viewObjectsSelector.getJunctionFront() == this);
324 }
325 } else if (modes.isCurrentSupermodeDemand()) {
326 // get current plan selector
327 GNEPlanSelector* planSelector = nullptr;
328 if (modes.demandEditMode == DemandEditMode::DEMAND_PERSON) {
329 planSelector = viewParent->getPersonFrame()->getPlanSelector();
330 } else if (modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) {
331 planSelector = viewParent->getPersonPlanFrame()->getPlanSelector();
332 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) {
333 planSelector = viewParent->getContainerFrame()->getPlanSelector();
334 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) {
335 planSelector = viewParent->getContainerPlanFrame()->getPlanSelector();
336 }
337 // continue depending of plan selector
338 if (planSelector && planSelector->markJunctions()) {
339 return (viewObjectsSelector.getAttributeCarrierFront() == viewObjectsSelector.getJunctionFront());
340 } else if (modes.demandEditMode == DemandEditMode::DEMAND_VEHICLE) {
341 // get current vehicle template
342 const auto& vehicleTemplate = viewParent->getVehicleFrame()->getVehicleTagSelector()->getCurrentTemplateAC();
343 // check if vehicle can be placed over from-to TAZs
344 if (vehicleTemplate && vehicleTemplate->getTagProperty()->vehicleJunctions()) {
345 return (viewObjectsSelector.getAttributeCarrierFront() == viewObjectsSelector.getJunctionFront());
346 }
347 }
348 }
349 return false;
350 }
351}
352
353
354bool
356 // get edit modes
357 const auto& editModes = myNet->getViewNet()->getEditModes();
358 // check if we're in delete mode
359 if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_DELETE)) {
361 } else {
362 return false;
363 }
364}
365
366
367bool
369 return false;
370}
371
372
373bool
375 // get edit modes
376 const auto& editModes = myNet->getViewNet()->getEditModes();
377 // check if we're in select mode
378 if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_SELECT)) {
380 } else {
381 return false;
382 }
383}
384
385
386bool
388 // get edit modes
389 const auto& editModes = myNet->getViewNet()->getEditModes();
390 // check if we're in move mode
391 if (!myNet->getViewNet()->isCurrentlyMovingElements() && editModes.isCurrentSupermodeNetwork() &&
392 (editModes.networkEditMode == NetworkEditMode::NETWORK_MOVE) && myNet->getViewNet()->checkOverLockedElement(this, mySelected)) {
393 // check if we're editing this network element
395 if (editedNetworkElement) {
396 return editedNetworkElement == this;
397 } else {
398 // only move the first element
400 }
401 } else {
402 return false;
403 }
404}
405
406
407void
408GNEJunction::rebuildGNECrossings(bool rebuildNBNodeCrossings) {
409 // rebuild GNECrossings only if create crossings and walkingAreas in net is enabled
411 if (rebuildNBNodeCrossings) {
412 // build new NBNode::Crossings and walking areas
416 }
417 // create a vector to keep retrieved and created crossings
418 std::vector<GNECrossing*> retrievedCrossings;
419 // iterate over NBNode::Crossings of GNEJunction
420 for (const auto& crossing : myNBNode->getCrossingsIncludingInvalid()) {
421 // retrieve existent GNECrossing, or create it
422 GNECrossing* retrievedGNECrossing = retrieveGNECrossing(crossing.get());
423 retrievedCrossings.push_back(retrievedGNECrossing);
424 // check if previously this GNECrossings exists, and if true, remove it from myGNECrossings and insert in tree again
425 std::vector<GNECrossing*>::iterator retrievedExists = std::find(myGNECrossings.begin(), myGNECrossings.end(), retrievedGNECrossing);
426 if (retrievedExists != myGNECrossings.end()) {
427 myGNECrossings.erase(retrievedExists);
428 // update geometry of retrieved crossing
429 retrievedGNECrossing->updateGeometry();
430 // update boundary
431 retrievedGNECrossing->updateCenteringBoundary(false);
432 } else {
433 // include reference to created GNECrossing
434 retrievedGNECrossing->incRef();
435 }
436 }
437 // delete non retrieved GNECrossings (we don't need to extract if from Tree two times)
438 for (const auto& crossing : myGNECrossings) {
439 crossing->decRef();
440 // check if crossing is selected
441 if (crossing->isAttributeCarrierSelected()) {
442 crossing->unselectAttributeCarrier();
443 }
444 // remove it from inspected ACS
445 if (myNet->getViewNet()) {
447 }
448 // remove it from net
449 myNet->removeGLObjectFromGrid(crossing);
450 // remove it from attributeCarriers
452 if (crossing->unreferenced()) {
453 delete crossing;
454 }
455 }
456 // copy retrieved (existent and created) GNECrossings to myGNECrossings
457 myGNECrossings = retrievedCrossings;
458 }
459}
460
461
462void
464 if (OptionsCont::getOptions().getBool("lefthand")) {
465 myNBNode->mirrorX();
466 for (NBEdge* e : myNBNode->getEdges()) {
467 e->mirrorX();
468
469 }
470 }
471}
472
473
474void
475GNEJunction::buildTLSOperations(GUISUMOAbstractView& parent, GUIGLObjectPopupMenu* ret, const int numSelectedJunctions) {
476 // create menu pane for edge operations
477 FXMenuPane* TLSOperations = new FXMenuPane(ret);
478 ret->insertMenuPaneChild(TLSOperations);
479 new FXMenuCascade(ret, TL("TLS operations"), GUIIconSubSys::getIcon(GUIIcon::MODETLS), TLSOperations);
480 // create menu commands for all TLS operations
481 FXMenuCommand* mcAddTLS = GUIDesigns::buildFXMenuCommand(TLSOperations, TL("Add TLS"), nullptr, &parent, MID_GNE_JUNCTION_ADDTLS);
482 FXMenuCommand* mcAddJoinedTLS = GUIDesigns::buildFXMenuCommand(TLSOperations, TL("Add joined TLS"), nullptr, &parent, MID_GNE_JUNCTION_ADDJOINTLS);
483 // check if disable create TLS
484 if (myNBNode->getControllingTLS().size() > 0) {
485 mcAddTLS->disable();
486 mcAddJoinedTLS->disable();
487 } else {
488 mcAddTLS->enable();
489 // check if add joined TLS
490 if (isAttributeCarrierSelected() && (numSelectedJunctions > 1)) {
491 mcAddJoinedTLS->enable();
492 } else {
493 mcAddJoinedTLS->disable();
494 }
495 }
496}
497
498
501 if (myShapeEdited) {
502 return getShapeEditedPopUpMenu(app, parent, myNBNode->getShape());
503 } else {
504 // create popup
505 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
506 // build common options
508 // check if we're in supermode network
510 const int numSelectedJunctions = myNet->getAttributeCarriers()->getNumberOfSelectedJunctions();
511 const int numEndpoints = (int)myNBNode->getEndPoints().size();
512 // check if we're handling a selection
513 bool handlingSelection = isAttributeCarrierSelected() && (numSelectedJunctions > 1);
514 // check if menu commands has to be disabled
518 // build TLS operation
519 if (!invalidMode) {
520 buildTLSOperations(parent, ret, numSelectedJunctions);
521 }
522 // create menu commands
523 GUIDesigns::buildFXMenuCommand(ret, TL("Reset edge endpoints"), nullptr, &parent, MID_GNE_JUNCTION_RESET_EDGE_ENDPOINTS);
524 FXMenuCommand* mcCustomShape = GUIDesigns::buildFXMenuCommand(ret, TL("Set custom junction shape"), nullptr, &parent, MID_GNE_JUNCTION_EDIT_SHAPE);
525 FXMenuCommand* mcResetCustomShape = GUIDesigns::buildFXMenuCommand(ret, TL("Reset junction shape"), nullptr, &parent, MID_GNE_JUNCTION_RESET_SHAPE);
526 FXMenuCommand* mcReplaceByGeometryPoint = GUIDesigns::buildFXMenuCommand(ret, TL("Replace junction by geometry point"), nullptr, &parent, MID_GNE_JUNCTION_REPLACE);
527 FXMenuCommand* mcSplitJunction = GUIDesigns::buildFXMenuCommand(ret, TLF("Split junction (% end points)", numEndpoints), nullptr, &parent, MID_GNE_JUNCTION_SPLIT);
528 FXMenuCommand* mcSplitJunctionAndReconnect = GUIDesigns::buildFXMenuCommand(ret, TL("Split junction and reconnect"), nullptr, &parent, MID_GNE_JUNCTION_SPLIT_RECONNECT);
529 // check if is a roundabout
530 if (myNBNode->isRoundabout()) {
531 GUIDesigns::buildFXMenuCommand(ret, TL("Select roundabout"), nullptr, &parent, MID_GNE_JUNCTION_SELECT_ROUNDABOUT);
532 } else {
533 // get radius
534 const double radius = (myNBNode->getRadius() == NBNode::UNSPECIFIED_RADIUS) ? OptionsCont::getOptions().getFloat("default.junctions.radius") : myNBNode->getRadius();
535 const std::string menuEntryInfo = TLF("Convert to roundabout (using junction attribute radius %)", toString(radius));
536 FXMenuCommand* mcRoundabout = GUIDesigns::buildFXMenuCommand(ret, menuEntryInfo.c_str(), nullptr, &parent, MID_GNE_JUNCTION_CONVERT_ROUNDABOUT);
537 // check if disable depending of number of edges
538 if ((getChildEdges().size() < 2) ||
539 ((myGNEIncomingEdges.size() == 1) && (myGNEOutgoingEdges.size() == 1) && (myGNEIncomingEdges[0]->getFromJunction() == myGNEOutgoingEdges[0]->getToJunction()))) {
540 mcRoundabout->disable();
541 }
542 }
543 // check multijunctions
544 const std::string multi = ((numSelectedJunctions > 1) && isAttributeCarrierSelected()) ? TLF(" of % junctions", numSelectedJunctions) : "";
545 FXMenuCommand* mcClearConnections = GUIDesigns::buildFXMenuCommand(ret, TL("Clear connections") + multi, nullptr, &parent, MID_GNE_JUNCTION_CLEAR_CONNECTIONS);
546 FXMenuCommand* mcResetConnections = GUIDesigns::buildFXMenuCommand(ret, TL("Reset connections") + multi, nullptr, &parent, MID_GNE_JUNCTION_RESET_CONNECTIONS);
547 // check if current mode is correct
548 if (invalidMode) {
549 mcCustomShape->disable();
550 mcClearConnections->disable();
551 mcResetConnections->disable();
552 }
553 // check if we're handling a selection
554 if (handlingSelection) {
555 mcResetCustomShape->setText(TL("Reset junction shapes"));
556 }
557 // disable mcClearConnections if junction hasn't connections
558 if (getGNEConnections().empty()) {
559 mcClearConnections->disable();
560 }
561 // disable mcResetCustomShape if junction doesn't have a custom shape
562 if (myNBNode->getShape().size() == 0) {
563 mcResetCustomShape->disable();
564 }
565 // checkIsRemovable requires turnarounds to be computed. This is ugly
566 if ((myNBNode->getIncomingEdges().size() == 2) && (myNBNode->getOutgoingEdges().size() == 2)) {
568 }
569 std::string reason = TL("wrong edit mode");
570 if (invalidMode || !myNBNode->checkIsRemovableReporting(reason)) {
571 mcReplaceByGeometryPoint->setText(mcReplaceByGeometryPoint->getText() + " (" + reason.c_str() + ")");
572 mcReplaceByGeometryPoint->disable();
573 }
574 // check if disable split junctions
575 if (numEndpoints == 1) {
576 mcSplitJunction->disable();
577 mcSplitJunctionAndReconnect->disable();
578 }
579 }
580 return ret;
581 }
582}
583
584
585double
589
590
595
596
597void
599 // Remove object from grid
600 if (updateGrid) {
602 }
603 // calculate boundary using a radius bigger than geometry point
605 myNBNode->getPosition().x() + 1, myNBNode->getPosition().y() + 1);
607 // add shape
608 if (myNBNode->getShape().size() > 0) {
611 }
612 // add boundaries of all connections, walking areas and crossings
613 for (const auto& edge : myGNEIncomingEdges) {
614 for (const auto& connection : edge->getGNEConnections()) {
615 const auto boundary = connection->getCenteringBoundary();
616 if (boundary.isInitialised()) {
617 myJunctionBoundary.add(boundary);
618 }
619 }
620 }
621 for (const auto& crossing : myGNECrossings) {
622 const auto boundary = crossing->getCenteringBoundary();
623 if (boundary.isInitialised()) {
624 myJunctionBoundary.add(boundary);
625 }
626 }
627 for (const auto& walkingArea : myGNEWalkingAreas) {
628 const auto boundary = walkingArea->getCenteringBoundary();
629 if (boundary.isInitialised()) {
630 myJunctionBoundary.add(boundary);
631 }
632 }
633
634 // add object into grid
635 if (updateGrid) {
636 // if junction has at least one edge, then don't add in grid (because uses the edge's grid)
637 if (myGNEIncomingEdges.size() + myGNEOutgoingEdges.size() == 0) {
639 }
640 }
641 // trigger rebuilding tesselation
642 myExaggeration = 2;
643}
644
645
646void
648 // first check drawing toggle and boundary selection
650 // draw boundaries
651 if (inGrid()) {
653 }
654 // get junction exaggeration
655 const double junctionExaggeration = getExaggeration(s);
656 // only continue if exaggeration is greater than 0
657 if (junctionExaggeration > 0) {
658 // get detail level
659 const auto d = s.getDetailLevel(junctionExaggeration);
660 // get shape area
661 const double junctionShapeArea = myNBNode->getShape().area();
662 // check if draw junction as shape
663 const bool drawBubble = drawAsBubble(s, junctionShapeArea);
664 // draw geometry only if we'rent in drawForObjectUnderCursor mode
666 // push layer matrix
668 // translate to front
670 if (drawBubble) {
671 // draw junction as bubble
672 drawJunctionAsBubble(s, d, junctionExaggeration);
673 } else {
674 // draw junction as shape
675 drawJunctionAsShape(s, d, junctionExaggeration);
676 }
677 // draw junction center (only in move mode)
678 drawJunctionCenter(s, d);
679 // draw TLS
680 drawTLSIcon(s);
681 // draw elevation
682 drawElevation(s);
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 if (drawBubble) {
697 // draw dotted contour for bubble
699 } else {
700 // draw dotted contour for shape
701 if (junctionShapeArea >= 4) {
703 }
704 }
705 }
706 }
707 // calculate junction contour (always before children)
708 calculateJunctioncontour(s, d, junctionExaggeration, drawBubble);
709 // draw Junction childs
711 }
712 // update drawing toggle
714 }
715}
716
717
718void
720 // Check if edge can be deleted
723 }
724}
725
726
727void
731
732
733NBNode*
735 return myNBNode;
736}
737
738
739std::vector<GNEJunction*>
741 // use set to avoid duplicates junctions
742 std::set<GNEJunction*> junctions;
743 for (const auto& incomingEdge : myGNEIncomingEdges) {
744 junctions.insert(incomingEdge->getFromJunction());
745 }
746 for (const auto& outgoingEdge : myGNEOutgoingEdges) {
747 junctions.insert(outgoingEdge->getToJunction());
748 }
749 return std::vector<GNEJunction*>(junctions.begin(), junctions.end());
750}
751
752
753void
755 // Check if incoming edge was already inserted
756 std::vector<GNEEdge*>::iterator i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
757 if (i != myGNEIncomingEdges.end()) {
758 throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + getTagStr() + " with ID " + getID() + "'");
759 } else {
760 // Add edge into containers
761 myGNEIncomingEdges.push_back(edge);
762 }
763}
764
765
766
767void
769 // Check if outgoing edge was already inserted
770 const auto i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
771 if (i != myGNEOutgoingEdges.end()) {
772 throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + getTagStr() + " with ID " + getID() + "'");
773 } else {
774 // Add edge into containers
775 myGNEOutgoingEdges.push_back(edge);
776 }
777 // update centering boundary and grid
779}
780
781
782void
784 // Check if incoming edge was already inserted
785 auto i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
786 if (i == myGNEIncomingEdges.end()) {
787 throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + getTagStr() + " with ID " + getID() + "'");
788 } else {
789 // remove edge from containers
790 myGNEIncomingEdges.erase(i);
791 }
792 // update centering boundary and grid
794}
795
796
797void
799 // Check if outgoing edge was already inserted
800 std::vector<GNEEdge*>::iterator i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
801 if (i == myGNEOutgoingEdges.end()) {
802 throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + getTagStr() + " with ID " + getID() + "'");
803 } else {
804 // remove edge from containers
805 myGNEOutgoingEdges.erase(i);
806 }
807}
808
809
810const std::vector<GNEEdge*>&
814
815
816const std::vector<GNEEdge*>&
820
821
822const std::vector<GNECrossing*>&
826
827
828const std::vector<GNEWalkingArea*>&
832
833
834std::vector<GNEConnection*>
836 std::vector<GNEConnection*> connections;
837 for (const auto& incomingEdge : myGNEIncomingEdges) {
838 for (const auto& connection : incomingEdge->getGNEConnections()) {
839 connections.push_back(connection);
840 }
841 }
842 return connections;
843}
844
845
846void
850
851
852void
856
857
858void
860 myAmTLSSelected = selected;
861}
862
863
864void
866 if (!myNBNode->hasCustomShape()) {
867 if (myNBNode->myPoly.size() > 0) {
868 // clear poly
869 myNBNode->myPoly.clear();
870 // update centering boundary
872 }
874 }
875}
876
877
878void
879GNEJunction::setLogicValid(bool valid, GNEUndoList* undoList, const std::string& status) {
880 myHasValidLogic = valid;
881 if (!valid) {
882 assert(undoList != 0);
883 assert(undoList->hasCommandGroup());
886 for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
887 GNEEdge* srcEdge = myNet->getAttributeCarriers()->retrieveEdge((*it)->getID());
888 removeConnectionsFrom(srcEdge, undoList, false); // false, because the whole tls will be invalidated at the end
890 }
892 invalidateTLS(undoList);
893 } else {
894 // logic valed, then rebuild GNECrossings to adapt it to the new logic
895 // (but don't rebuild the crossings in NBNode because they are already finished)
896 rebuildGNECrossings(false);
897 }
898}
899
900
901void
902GNEJunction::removeConnectionsFrom(GNEEdge* edge, GNEUndoList* undoList, bool updateTLS, int lane) {
903 NBEdge* srcNBE = edge->getNBEdge();
904 NBEdge* turnEdge = srcNBE->getTurnDestination();
905 // Make a copy of connections
906 std::vector<NBEdge::Connection> connections = srcNBE->getConnections();
907 // delete in reverse so that undoing will add connections in the original order
908 for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) {
909 if (lane >= 0 && (*con_it).fromLane != lane) {
910 continue;
911 }
912 bool hasTurn = con_it->toEdge == turnEdge;
913 undoList->add(new GNEChange_Connection(edge, *con_it, false, false), true);
914 // needs to come after GNEChange_Connection
915 // XXX bug: this code path will not be used on a redo!
916 if (hasTurn) {
918 }
919 }
920 if (updateTLS) {
921 std::vector<NBConnection> removeConnections;
922 for (NBEdge::Connection con : connections) {
923 removeConnections.push_back(NBConnection(srcNBE, con.fromLane, con.toEdge, con.toLane));
924 }
925 removeTLSConnections(removeConnections, undoList);
926 }
927}
928
929
930void
931GNEJunction::removeConnectionsTo(GNEEdge* edge, GNEUndoList* undoList, bool updateTLS, int lane) {
932 NBEdge* destNBE = edge->getNBEdge();
933 std::vector<NBConnection> removeConnections;
934 for (NBEdge* srcNBE : myNBNode->getIncomingEdges()) {
935 GNEEdge* srcEdge = myNet->getAttributeCarriers()->retrieveEdge(srcNBE->getID());
936 std::vector<NBEdge::Connection> connections = srcNBE->getConnections();
937 for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) {
938 if ((*con_it).toEdge == destNBE) {
939 if (lane >= 0 && (*con_it).toLane != lane) {
940 continue;
941 }
942 bool hasTurn = srcNBE->getTurnDestination() == destNBE;
943 undoList->add(new GNEChange_Connection(srcEdge, *con_it, false, false), true);
944 // needs to come after GNEChange_Connection
945 // XXX bug: this code path will not be used on a redo!
946 if (hasTurn) {
947 myNet->addExplicitTurnaround(srcNBE->getID());
948 }
949 removeConnections.push_back(NBConnection(srcNBE, (*con_it).fromLane, destNBE, (*con_it).toLane));
950 }
951 }
952 }
953 if (updateTLS) {
954 removeTLSConnections(removeConnections, undoList);
955 }
956}
957
958
959void
960GNEJunction::removeTLSConnections(std::vector<NBConnection>& connections, GNEUndoList* undoList) {
961 if (connections.size() > 0) {
962 const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode->getControllingTLS(); // make a copy!
963 for (const auto& TLS : coypOfTls) {
964 NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
965 // guessed TLS (NBOwnTLDef) do not need to be updated
966 if (tlDef != nullptr) {
967 std::string newID = tlDef->getID();
968 // create replacement before deleting the original because deletion will mess up saving original nodes
969 NBLoadedSUMOTLDef* replacementDef = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
970 for (NBConnection& con : connections) {
971 replacementDef->removeConnection(con);
972 }
973 undoList->add(new GNEChange_TLS(this, tlDef, false), true);
974 undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
975 // the removed traffic light may have controlled more than one junction. These too have become invalid now
976 const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
977 for (const auto& node : copyOfNodes) {
978 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
979 undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
980 undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
981 }
982 }
983 }
984 }
985}
986
987
988void
990 // remap connections of the edge
991 assert(which->getChildLanes().size() == by->getChildLanes().size());
992 std::vector<NBEdge::Connection> connections = which->getNBEdge()->getConnections();
993 for (NBEdge::Connection& c : connections) {
994 undoList->add(new GNEChange_Connection(which, c, false, false), true);
995 undoList->add(new GNEChange_Connection(by, c, false, true), true);
996 }
997 // also remap tls connections
998 const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode->getControllingTLS(); // make a copy!
999 for (const auto& TLS : coypOfTls) {
1000 NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
1001 // guessed TLS (NBOwnTLDef) do not need to be updated
1002 if (tlDef != nullptr) {
1003 std::string newID = tlDef->getID();
1004 // create replacement before deleting the original because deletion will mess up saving original nodes
1005 NBLoadedSUMOTLDef* replacementDef = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
1006 for (int i = 0; i < (int)which->getChildLanes().size(); ++i) {
1007 replacementDef->replaceRemoved(which->getNBEdge(), i, by->getNBEdge(), i, true);
1008 }
1009 undoList->add(new GNEChange_TLS(this, tlDef, false), true);
1010 undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
1011 // the removed traffic light may have controlled more than one junction. These too have become invalid now
1012 const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
1013 for (const auto& node : copyOfNodes) {
1014 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1015 undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
1016 undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
1017 }
1018 }
1019 }
1020}
1021
1022
1023void
1025 EdgeVector incoming = myNBNode->getIncomingEdges();
1026 for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
1027 NBEdge* srcNBE = *it;
1028 GNEEdge* srcEdge = myNet->getAttributeCarriers()->retrieveEdge(srcNBE->getID());
1030 }
1031}
1032
1033
1034void
1035GNEJunction::invalidateTLS(GNEUndoList* undoList, const NBConnection& deletedConnection, const NBConnection& addedConnection) {
1036 assert(undoList->hasCommandGroup());
1037 // NBLoadedSUMOTLDef becomes invalid, replace with NBOwnTLDef which will be dynamically recomputed
1038 const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode->getControllingTLS(); // make a copy!
1039 for (const auto& TLS : coypOfTls) {
1040 NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
1041 if (tlDef != nullptr) {
1042 // the removed traffic light may have controlled more than one junction. These too have become invalid now
1043 const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
1044 if (myGNECrossings.size() == 0 && getNBNode()->getCrossings().size() != 0) {
1045 // crossings were not computed yet. We need them as netedit elements to manage tlIndex resetting
1048 for (const auto& node : copyOfNodes) {
1049 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1050 if (sharing != this) {
1051 sharing->rebuildGNECrossings();
1052 }
1053 }
1054 }
1055 NBTrafficLightDefinition* replacementDef = nullptr;
1056 std::string newID = tlDef->getID(); // + "_reguessed"; // changes due to reguessing will be visible in diff
1057 if (deletedConnection != NBConnection::InvalidConnection) {
1058 // create replacement before deleting the original because deletion will mess up saving original nodes
1059 NBLoadedSUMOTLDef* repl = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
1060 repl->removeConnection(deletedConnection);
1061 replacementDef = repl;
1062 } else if (addedConnection != NBConnection::InvalidConnection) {
1063 if (addedConnection.getTLIndex() == NBConnection::InvalidTlIndex) {
1064 // custom tl indices of crossings might become invalid upon recomputation so we must save them
1065 // however, they could remain valid so we register a change but keep them at their old value
1066 for (const auto& crossing : myGNECrossings) {
1067 const std::string oldValue = crossing->getAttribute(SUMO_ATTR_TLLINKINDEX);
1069 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX, oldValue, undoList, true);
1070 const std::string oldValue2 = crossing->getAttribute(SUMO_ATTR_TLLINKINDEX2);
1072 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX2, oldValue2, undoList, true);
1073 }
1074 }
1075 NBLoadedSUMOTLDef* repl = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
1076 repl->addConnection(addedConnection.getFrom(), addedConnection.getTo(),
1077 addedConnection.getFromLane(), addedConnection.getToLane(), addedConnection.getTLIndex(), addedConnection.getTLIndex2());
1078 replacementDef = repl;
1079 } else {
1080 // recompute crossing indices along with everything else
1081 for (const auto& crossing : myGNECrossings) {
1084 }
1085 replacementDef = new NBOwnTLDef(newID, tlDef->getOffset(), tlDef->getType());
1086 replacementDef->setProgramID(tlDef->getProgramID());
1087 }
1088 undoList->add(new GNEChange_TLS(this, tlDef, false), true);
1089 undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
1090 // reset nodes of joint tls
1091 for (const auto& node : copyOfNodes) {
1092 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1093 if (sharing != this) {
1094 if (deletedConnection == NBConnection::InvalidConnection && addedConnection == NBConnection::InvalidConnection) {
1095 // recompute crossing indices for shared
1096 // (they won't do this on subsequent call to invalidateTLS if they received an NBOwnTLDef)
1097 for (const auto& crossing : sharing->getGNECrossings()) {
1100 }
1101 }
1102 undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
1103 undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
1104 }
1105 }
1106 }
1107 }
1108}
1109
1110void
1112 // obtain a copy of GNECrossing of junctions
1113 const auto copyOfGNECrossings = myGNECrossings;
1114 // iterate over copy of GNECrossings
1115 for (const auto& crossing : copyOfGNECrossings) {
1116 // obtain the set of edges vinculated with the crossing (due it works as ID)
1117 EdgeSet edgeSet(crossing->getCrossingEdges().begin(), crossing->getCrossingEdges().end());
1118 // If this edge is part of the set of edges of crossing
1119 if (edgeSet.count(edge->getNBEdge()) == 1) {
1120 // delete crossing if this is their last edge
1121 if ((crossing->getCrossingEdges().size() == 1) && (crossing->getCrossingEdges().front() == edge->getNBEdge())) {
1122 myNet->deleteCrossing(crossing, undoList);
1123 } else {
1124 // remove this edge of the edge's attribute of crossing (note: This can invalidate the crossing)
1125 std::vector<std::string> edges = GNEAttributeCarrier::parse<std::vector<std::string>>(crossing->getAttribute(SUMO_ATTR_EDGES));
1126 edges.erase(std::find(edges.begin(), edges.end(), edge->getID()));
1127 crossing->setAttribute(SUMO_ATTR_EDGES, joinToString(edges, " "), undoList);
1128 }
1129 }
1130 }
1131}
1132
1133
1134bool
1138
1139
1141GNEJunction::retrieveGNECrossing(NBNode::Crossing* NBNodeCrossing, bool createIfNoExist) {
1142 // iterate over all crossing
1143 for (const auto& crossing : myGNECrossings) {
1144 // if found, return it
1145 if (crossing->getCrossingEdges() == NBNodeCrossing->edges) {
1146 return crossing;
1147 }
1148 }
1149 if (createIfNoExist) {
1150 // create new GNECrossing
1151 GNECrossing* createdGNECrossing = new GNECrossing(this, NBNodeCrossing->edges);
1152 // update geometry after creating
1153 createdGNECrossing->updateGeometry();
1154 // add it in Network
1155 myNet->addGLObjectIntoGrid(createdGNECrossing);
1156 // add it in attributeCarriers
1157 myNet->getAttributeCarriers()->insertCrossing(createdGNECrossing);
1158 return createdGNECrossing;
1159 } else {
1160 return nullptr;
1161 }
1162}
1163
1164
1166GNEJunction::retrieveGNEWalkingArea(const std::string& NBNodeWalkingAreaID, bool createIfNoExist) {
1167 // iterate over all walkingArea
1168 for (const auto& walkingArea : myGNEWalkingAreas) {
1169 // if found, return it
1170 if (walkingArea->getID() == NBNodeWalkingAreaID) {
1171 return walkingArea;
1172 }
1173 }
1174 if (createIfNoExist) {
1175 // create new GNEWalkingArea
1176 GNEWalkingArea* createdGNEWalkingArea = new GNEWalkingArea(this, NBNodeWalkingAreaID);
1177 // update geometry after creating
1178 createdGNEWalkingArea->updateGeometry();
1179 // add it in Network
1180 myNet->addGLObjectIntoGrid(createdGNEWalkingArea);
1181 // add it in attributeCarriers
1182 myNet->getAttributeCarriers()->insertWalkingArea(createdGNEWalkingArea);
1183 return createdGNEWalkingArea;
1184 } else {
1185 return nullptr;
1186 }
1187}
1188
1189
1190void
1192 // only it's needed to mark the connections of incoming edges
1193 for (const auto& i : myGNEIncomingEdges) {
1194 for (const auto& j : i->getGNEConnections()) {
1195 j->markConnectionGeometryDeprecated();
1196 }
1197 if (includingNeighbours) {
1198 i->getFromJunction()->markConnectionsDeprecated(false);
1199 }
1200 }
1201}
1202
1203
1204void
1205GNEJunction::setJunctionType(const std::string& value, GNEUndoList* undoList) {
1206 undoList->begin(this, "change " + getTagStr() + " type");
1208 if (getNBNode()->isTLControlled() &&
1209 // if switching changing from or to traffic_light_right_on_red we need to remove the old plan
1212 ) {
1213 // make a copy because we will modify the original
1214 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1215 for (const auto& TLS : copyOfTls) {
1216 undoList->add(new GNEChange_TLS(this, TLS, false), true);
1217 }
1218 }
1219 if (!getNBNode()->isTLControlled()) {
1220 // create new traffic light
1221 undoList->add(new GNEChange_TLS(this, nullptr, true), true);
1222 }
1223 } else if (getNBNode()->isTLControlled()) {
1224 // delete old traffic light
1225 // make a copy because we will modify the original
1226 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1227 for (const auto& TLS : copyOfTls) {
1228 undoList->add(new GNEChange_TLS(this, TLS, false, false), true);
1229 const std::vector<NBNode*> copyOfNodes = TLS->getNodes(); // make a copy!
1230 for (const auto& node : copyOfNodes) {
1231 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1232 sharing->invalidateTLS(undoList);
1233 }
1234 }
1235 }
1236 // must be the final step, otherwise we do not know which traffic lights to remove via GNEChange_TLS
1237 GNEChange_Attribute::changeAttribute(this, SUMO_ATTR_TYPE, value, undoList, true);
1238 for (const auto& crossing : myGNECrossings) {
1239 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX, "-1", undoList, true);
1240 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX2, "-1", undoList, true);
1241 }
1242 undoList->end();
1243}
1244
1245
1246void
1248 // delete non retrieved GNEWalkingAreas (we don't need to extract if from Tree two times)
1249 for (const auto& walkingArea : myGNEWalkingAreas) {
1250 walkingArea->decRef();
1251 // check if walkingArea is selected
1252 if (walkingArea->isAttributeCarrierSelected()) {
1253 walkingArea->unselectAttributeCarrier();
1254 }
1255 // remove it from inspected ACS
1257 // remove it from net
1258 myNet->removeGLObjectFromGrid(walkingArea);
1259 // remove it from attributeCarriers
1261 if (walkingArea->unreferenced()) {
1262 delete walkingArea;
1263 }
1264 }
1265 myGNEWalkingAreas.clear();
1266}
1267
1268
1269void
1271 // first clear GNEWalkingAreas
1273 // iterate over NBNode::WalkingAreas of GNEJunction
1274 for (const auto& walkingArea : myNBNode->getWalkingAreas()) {
1275 // retrieve existent GNEWalkingArea, or create it
1276 GNEWalkingArea* retrievedGNEWalkingArea = retrieveGNEWalkingArea(walkingArea.id, true);
1277 // include reference to created GNEWalkingArea
1278 retrievedGNEWalkingArea->incRef();
1279 // update geometry of retrieved walkingArea
1280 retrievedGNEWalkingArea->updateGeometry();
1281 // update boundary
1282 retrievedGNEWalkingArea->updateCenteringBoundary(false);
1283 // add in walkingAreas
1284 myGNEWalkingAreas.push_back(retrievedGNEWalkingArea);
1285 }
1286}
1287
1288
1289
1290void
1292 if (std::find(myInternalLanes.begin(), myInternalLanes.end(), internalLane) != myInternalLanes.end()) {
1293 throw ProcessError(internalLane->getTagStr() + " with ID='" + internalLane->getID() + "' already exist");
1294 } else {
1295 myInternalLanes.push_back(internalLane);
1296 }
1297}
1298
1299
1300void
1302 const auto finder = std::find(myInternalLanes.begin(), myInternalLanes.end(), internalLane);
1303 if (finder == myInternalLanes.end()) {
1304 throw ProcessError(internalLane->getTagStr() + " with ID='" + internalLane->getID() + "' wasn't previously inserted");
1305 } else {
1306 myInternalLanes.erase(finder);
1307 }
1308}
1309
1310
1311std::string
1313 switch (key) {
1314 case SUMO_ATTR_ID:
1315 return getMicrosimID();
1316 case SUMO_ATTR_POSITION:
1317 return toString(myNBNode->getPosition());
1318 case SUMO_ATTR_TYPE:
1319 return toString(myNBNode->getType());
1321 return myLogicStatus;
1322 case SUMO_ATTR_SHAPE:
1323 return toString(myNBNode->getShape());
1324 case SUMO_ATTR_RADIUS:
1325 if (myNBNode->getRadius() < 0) {
1326 return "default";
1327 } else {
1328 return toString(myNBNode->getRadius());
1329 }
1330 case SUMO_ATTR_TLTYPE:
1332 // @todo this causes problems if the node were to have multiple programs of different type (plausible)
1333 return toString((*myNBNode->getControllingTLS().begin())->getType());
1334 } else {
1335 return "No TLS";
1336 }
1337 case SUMO_ATTR_TLLAYOUT:
1339 return toString((*myNBNode->getControllingTLS().begin())->getLayout());
1340 } else {
1341 return "No TLS";
1342 }
1343 case SUMO_ATTR_TLID:
1345 return toString((*myNBNode->getControllingTLS().begin())->getID());
1346 } else {
1347 return "No TLS";
1348 }
1352 // keep clear is only used as a convenience feature in plain xml
1353 // input. When saving to .net.xml the status is saved only for the connections
1354 // to show the correct state we must check all connections
1355 for (const auto& i : myGNEIncomingEdges) {
1356 for (const auto& j : i->getGNEConnections()) {
1357 if (j->getNBEdgeConnection().keepClear) {
1358 return TRUE_STR;
1359 }
1360 }
1361 }
1362 return FALSE_STR;
1365 case SUMO_ATTR_FRINGE:
1369 case SUMO_ATTR_NAME:
1370 return myNBNode->getName();
1371 default:
1372 return getCommonAttribute(key);
1373 }
1374}
1375
1376
1377double
1381
1382
1387
1388
1391 switch (key) {
1392 case SUMO_ATTR_SHAPE:
1393 return myNBNode->getShape();
1394 default:
1396 }
1397}
1398
1399
1400void
1401GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
1402 if (value == getAttribute(key)) {
1403 return; //avoid needless changes, later logic relies on the fact that attributes have changed
1404 }
1405 switch (key) {
1406 case SUMO_ATTR_ID:
1408 case SUMO_ATTR_SHAPE:
1409 case SUMO_ATTR_RADIUS:
1411 case SUMO_ATTR_FRINGE:
1413 case SUMO_ATTR_NAME:
1414 GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);
1415 break;
1416 case SUMO_ATTR_POSITION: {
1417 const GNEJunction* junctionToMerge = nullptr;
1418 bool alreadyAsked = false;
1419 // parse position
1420 Position newPosition = GNEAttributeCarrier::parse<Position>(value);
1421 // check if caculate new position based in edges
1422 if (newPosition == Position::INVALID) {
1423 Boundary b;
1424 // set new position of adjacent edges
1425 for (const auto& edge : myGNEIncomingEdges) {
1426 b.add(edge->getNBEdge()->getGeometry().back());
1427 }
1428 for (const auto& edge : myGNEOutgoingEdges) {
1429 b.add(edge->getNBEdge()->getGeometry().front());
1430 }
1431 newPosition = b.getCenter();
1432 }
1433 // retrieve all junctions placed in this position
1434 myNet->getViewNet()->updateObjectsInPosition(newPosition);
1435 for (const auto& junction : myNet->getViewNet()->getViewObjectsSelector().getJunctions()) {
1436 // check distance position
1437 if ((junctionToMerge == nullptr) && (junction != this) &&
1438 (junction->getPositionInView().distanceTo2D(newPosition) < myNet->getViewNet()->getVisualisationSettings().neteditSizeSettings.junctionBubbleRadius) &&
1439 myNet->getViewNet()->askMergeJunctions(this, junction, alreadyAsked)) {
1440 junctionToMerge = junction;
1441 }
1442 }
1443 // also check the merging junctions located during drawGL
1444 for (const auto& junction : myNet->getViewNet()->getViewObjectsSelector().getMergingJunctions()) {
1445 // check distance position
1446 if ((junctionToMerge == nullptr) && (junction != this) && myNet->getViewNet()->askMergeJunctions(this, junction, alreadyAsked)) {
1447 junctionToMerge = junction;
1448 }
1449 }
1450 // if we merge the junction, this junction will be removed, therefore we don't have to change the position
1451 if (junctionToMerge) {
1452 myNet->mergeJunctions(this, junctionToMerge, undoList);
1453 } else {
1454 // change Keep Clear attribute in all connections
1455 undoList->begin(this, TL("change junction position"));
1456 // obtain NBNode position
1457 const Position orig = myNBNode->getPosition();
1458 // change junction position
1459 GNEChange_Attribute::changeAttribute(this, key, toString(newPosition), undoList, true);
1460 // calculate delta using new position
1461 const bool moveOnlyCenter = myNet->getViewParent()->getMoveFrame()->getNetworkMoveOptions()->getMoveOnlyJunctionCenter();
1462 const Position delta = myNBNode->getPosition() - (moveOnlyCenter ? myNBNode->getPosition() : orig);
1463 // set new position of adjacent edges
1464 for (const auto& edge : myGNEIncomingEdges) {
1465 const Position newEnd = edge->getNBEdge()->getGeometry().back() + delta;
1467 }
1468 for (const auto& edge : myGNEOutgoingEdges) {
1469 const Position newStart = edge->getNBEdge()->getGeometry().front() + delta;
1470 GNEChange_Attribute::changeAttribute(edge, GNE_ATTR_SHAPE_START, toString(newStart), undoList, true);
1471 }
1472 undoList->end();
1473 }
1474 break;
1475 }
1477 // change Keep Clear attribute in all connections
1478 undoList->begin(this, TL("change keepClear for whole junction"));
1479 for (const auto& incomingEdge : myGNEIncomingEdges) {
1480 for (const auto& junction : incomingEdge->getGNEConnections()) {
1481 GNEChange_Attribute::changeAttribute(junction, key, value, undoList, true);
1482 }
1483 }
1484 undoList->end();
1485 break;
1486 case SUMO_ATTR_TYPE: {
1487 // set junction type
1488 setJunctionType(value, undoList);
1489 break;
1490 }
1491 case SUMO_ATTR_TLTYPE: {
1492 undoList->begin(this, "change " + getTagStr() + " tl-type");
1493 // make a copy because we will modify the original
1494 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1495 for (const auto& TLS : copyOfTls) {
1496 NBLoadedSUMOTLDef* oldLoaded = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
1497 if (oldLoaded != nullptr) {
1498 NBTrafficLightDefinition* newDef = nullptr;
1499 if (value == toString(TrafficLightType::NEMA) || oldLoaded->getType() == TrafficLightType::NEMA) {
1500 // rebuild the program because the old and new ones are incompatible
1501 newDef = new NBOwnTLDef(oldLoaded->getID(), oldLoaded->getOffset(), TrafficLightType::NEMA);
1502 newDef->setProgramID(oldLoaded->getProgramID());
1503 } else {
1504 NBLoadedSUMOTLDef* newLDef = new NBLoadedSUMOTLDef(*oldLoaded, *oldLoaded->getLogic());
1505 newLDef->guessMinMaxDuration(); // minDur and maxDur are never written for a static tls
1506 newDef = newLDef;
1507 }
1508 std::vector<NBNode*> nodes = TLS->getNodes();
1509 for (const auto& node : nodes) {
1510 GNEJunction* junction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1511 undoList->add(new GNEChange_TLS(junction, TLS, false), true);
1512 undoList->add(new GNEChange_TLS(junction, newDef, true), true);
1513 }
1514 }
1515 }
1516 GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);
1517 undoList->end();
1518 break;
1519 }
1520 case SUMO_ATTR_TLLAYOUT: {
1521 undoList->begin(this, "change " + getTagStr() + " tlLayout");
1522 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1523 for (const auto& oldTLS : copyOfTls) {
1524 std::vector<NBNode*> copyOfNodes = oldTLS->getNodes();
1525 NBOwnTLDef* newTLS = new NBOwnTLDef(oldTLS->getID(), oldTLS->getOffset(), oldTLS->getType());
1527 newTLS->setProgramID(oldTLS->getProgramID());
1528 for (const auto& node : copyOfNodes) {
1529 GNEJunction* oldJunction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1530 undoList->add(new GNEChange_TLS(oldJunction, oldTLS, false), true);
1531 }
1532 for (const auto& node : copyOfNodes) {
1533 GNEJunction* oldJunction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1534 undoList->add(new GNEChange_TLS(oldJunction, newTLS, true), true);
1535 }
1536 }
1537 undoList->end();
1538 break;
1539 }
1540 case SUMO_ATTR_TLID: {
1541 undoList->begin(this, "change " + toString(SUMO_TAG_TRAFFIC_LIGHT) + " id");
1542 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1543 assert(copyOfTls.size() > 0);
1544 NBTrafficLightDefinition* currentTLS = *copyOfTls.begin();
1545 NBTrafficLightDefinition* currentTLSCopy = nullptr;
1546 const bool currentIsSingle = currentTLS->getNodes().size() == 1;
1547 const bool currentIsLoaded = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS) != nullptr;
1548 if (currentIsLoaded) {
1549 currentTLSCopy = new NBLoadedSUMOTLDef(*currentTLS,
1550 *dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS)->getLogic());
1551 }
1552 // remove from previous tls
1553 for (const auto& TLS : copyOfTls) {
1554 undoList->add(new GNEChange_TLS(this, TLS, false), true);
1555 }
1557 // programs to which the current node shall be added
1558 const std::map<std::string, NBTrafficLightDefinition*> programs = tlCont.getPrograms(value);
1559 if (programs.size() > 0) {
1560 for (const auto& TLSProgram : programs) {
1561 NBTrafficLightDefinition* oldTLS = TLSProgram.second;
1562 if (dynamic_cast<NBOwnTLDef*>(oldTLS) != nullptr) {
1563 undoList->add(new GNEChange_TLS(this, oldTLS, true), true);
1564 } else {
1565 // delete and re-create the definition because the loaded phases are now invalid
1566 if (dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS) != nullptr &&
1567 dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->usingSignalGroups()) {
1568 // keep the old program and add all-red state for the added links
1569 NBLoadedSUMOTLDef* newTLSJoined = new NBLoadedSUMOTLDef(*oldTLS, *dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->getLogic());
1570 newTLSJoined->joinLogic(currentTLSCopy);
1571 undoList->add(new GNEChange_TLS(this, newTLSJoined, true, true), true);
1572 } else {
1573 undoList->add(new GNEChange_TLS(this, nullptr, true, false, value), true);
1574 }
1576 // switch from old to new definition
1577 std::vector<NBNode*> copyOfNodes = oldTLS->getNodes();
1578 for (const auto& node : copyOfNodes) {
1579 GNEJunction* oldJunction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1580 undoList->add(new GNEChange_TLS(oldJunction, oldTLS, false), true);
1581 undoList->add(new GNEChange_TLS(oldJunction, newTLS, true), true);
1582 }
1583 }
1584 }
1585 } else {
1586 if (currentIsSingle && currentIsLoaded) {
1587 // rename the traffic light but keep everything else
1588 NBTrafficLightLogic* renamedLogic = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLSCopy)->getLogic();
1589 renamedLogic->setID(value);
1590 NBLoadedSUMOTLDef* renamedTLS = new NBLoadedSUMOTLDef(*currentTLSCopy, *renamedLogic);
1591 renamedTLS->setID(value);
1592 undoList->add(new GNEChange_TLS(this, renamedTLS, true, true), true);
1593 } else {
1594 // create new traffic light
1595 undoList->add(new GNEChange_TLS(this, nullptr, true, false, value), true);
1596 }
1597 }
1598 delete currentTLSCopy;
1599 undoList->end();
1600 break;
1601 }
1602 default:
1603 setCommonAttribute(key, value, undoList);
1604 break;
1605 }
1606}
1607
1608
1609bool
1610GNEJunction::isValid(SumoXMLAttr key, const std::string& value) {
1611 switch (key) {
1612 case SUMO_ATTR_ID:
1613 return SUMOXMLDefinitions::isValidNetID(value) && (myNet->getAttributeCarriers()->retrieveJunction(value, false) == nullptr);
1614 case SUMO_ATTR_TYPE:
1616 case SUMO_ATTR_POSITION:
1617 if (value.empty()) {
1618 return (myGNEIncomingEdges.size() + myGNEOutgoingEdges.size()) > 0;
1619 } else {
1620 return canParse<Position>(value);
1621 }
1622 case SUMO_ATTR_SHAPE:
1623 // empty shapes are allowed
1624 return canParse<PositionVector>(value);
1625 case SUMO_ATTR_RADIUS:
1626 if (value.empty() || (value == "default")) {
1627 return true;
1628 } else {
1629 return canParse<double>(value) && ((parse<double>(value) >= 0) || (parse<double>(value) == -1));
1630 }
1631 case SUMO_ATTR_TLTYPE:
1633 case SUMO_ATTR_TLLAYOUT:
1635 case SUMO_ATTR_TLID:
1636 return myNBNode->isTLControlled() && (value != "");
1638 return canParse<bool>(value);
1641 case SUMO_ATTR_FRINGE:
1645 case SUMO_ATTR_NAME:
1646 return true;
1647 default:
1648 return isCommonAttributeValid(key, value);
1649 }
1650}
1651
1652
1653bool
1655 switch (key) {
1656 case SUMO_ATTR_TLTYPE:
1657 case SUMO_ATTR_TLLAYOUT:
1658 case SUMO_ATTR_TLID:
1659 return myNBNode->isTLControlled();
1660 case SUMO_ATTR_KEEP_CLEAR: {
1661 // check if at least there is an incoming connection
1662 for (const auto& incomingEdge : myGNEIncomingEdges) {
1663 if (incomingEdge->getGNEConnections().size() > 0) {
1664 return true;
1665 }
1666 }
1667 return false;
1668 }
1670 return false;
1671 default:
1672 return true;
1673 }
1674}
1675
1676
1677bool
1679 switch (key) {
1680 case SUMO_ATTR_SHAPE:
1681 return !myNBNode->hasCustomShape();
1682 default:
1683 return false;
1684 }
1685}
1686
1687
1688void
1690 myAmResponsible = newVal;
1691}
1692
1693// ===========================================================================
1694// private
1695// ===========================================================================
1696
1697bool
1698GNEJunction::drawAsBubble(const GUIVisualizationSettings& s, const double junctionShapeArea) const {
1699 const auto& editModes = myNet->getViewNet()->getEditModes();
1700 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
1701 // check conditions
1702 if (junctionShapeArea < 4) {
1703 // force draw if this junction is a candidate
1706 return true;
1707 }
1708 // force draw if we're in person/container plan mode
1709 if (editModes.isCurrentSupermodeDemand() &&
1710 ((editModes.demandEditMode == DemandEditMode::DEMAND_PERSON) ||
1711 (editModes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) ||
1712 (editModes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) ||
1713 (editModes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN))) {
1714 return true;
1715 }
1716 // force draw if we're inspecting a vehicle that start or ends in a junction
1717 if (inspectedElements.isInspectingSingleElement()) {
1718 // check if starts or ends in this junction
1719 if ((inspectedElements.getFirstAC()->hasAttribute(SUMO_ATTR_FROM_JUNCTION) &&
1720 (inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_FROM_JUNCTION) == getID())) ||
1721 (inspectedElements.getFirstAC()->hasAttribute(SUMO_ATTR_TO_JUNCTION) &&
1722 (inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_TO_JUNCTION) == getID()))) {
1723 return true;
1724 }
1725 }
1726 }
1727 if (!s.drawJunctionShape) {
1728 // don't draw bubble if it was disabled in GUIVisualizationSettings
1729 return false;
1730 }
1732 // force draw bubbles if we enabled option in checkbox of viewNet
1733 return true;
1734 }
1735 if (junctionShapeArea >= 4) {
1736 // don't draw if shape area is greater than 4
1737 return false;
1738 }
1739 if (!editModes.isCurrentSupermodeNetwork()) {
1740 // only draw bubbles in network mode
1741 return false;
1742 }
1743 return true;
1744}
1745
1746
1747void
1749 const double exaggeration) const {
1750 // calculate bubble radius
1751 const double bubbleRadius = s.neteditSizeSettings.junctionBubbleRadius * exaggeration;
1752 // set bubble color
1753 const RGBColor bubbleColor = setColor(s, true);
1754 // push matrix
1756 // set color
1757 GLHelper::setColor(bubbleColor);
1758 // move matrix junction center
1759 glTranslated(myNBNode->getPosition().x(), myNBNode->getPosition().y(), 1.5);
1760 // draw filled circle
1761 GLHelper::drawFilledCircleDetailled(d, bubbleRadius);
1762 // pop matrix
1764}
1765
1766
1767void
1769 // first check drawing conditions
1770 if (s.drawJunctionShape && (myNBNode->getShape().size() > 0)) {
1771 // set shape color
1772 const RGBColor junctionShapeColor = setColor(s, false);
1773 // set color
1774 GLHelper::setColor(junctionShapeColor);
1775 // adjust shape to exaggeration (check)
1776 if ((exaggeration > 1 || myExaggeration > 1) && exaggeration != myExaggeration) {
1777 myExaggeration = exaggeration;
1780 myTesselation.getShapeRef().scaleRelative(exaggeration);
1782 }
1783 // check if draw tesselation or or polygon
1785 // draw shape with high detail
1787 } else {
1788 // draw shape
1790 }
1791 // draw shape points only in Network supermode
1794 // set color
1795 const RGBColor darkerColor = junctionShapeColor.changedBrightness(-32);
1796 // calculate geometry
1797 GUIGeometry junctionGeometry;
1798 // obtain junction Shape
1799 PositionVector junctionOpenShape = myNBNode->getShape();
1800 // adjust shape to exaggeration
1801 if (exaggeration > 1) {
1802 junctionOpenShape.scaleRelative(exaggeration);
1803 }
1804 // update geometry
1805 junctionGeometry.updateGeometry(junctionOpenShape);
1806 // set color
1807 GLHelper::setColor(darkerColor);
1808 // draw shape
1810 // draw geometry points
1811 GUIGeometry::drawGeometryPoints(d, junctionOpenShape, darkerColor,
1814 }
1815 }
1816}
1817
1818
1819void
1822 // push matrix
1824 // set color
1825 GLHelper::setColor(setColor(s, true).changedBrightness(-20));
1826 // move matrix junction center
1827 glTranslated(myNBNode->getPosition().x(), myNBNode->getPosition().y(), 1.7);
1828 // draw filled circle
1830 // pop matrix
1832 }
1833}
1834
1835
1836void
1838 // draw TLS icon if isn't being drawn for selecting
1842 const Position pos = myNBNode->getPosition();
1843 glTranslated(pos.x(), pos.y(), 2.2);
1844 glColor3d(1, 1, 1);
1845 const double halfWidth = 32 / s.scale;
1846 const double halfHeight = 64 / s.scale;
1847 GUITexturesHelper::drawTexturedBox(GUITextureSubSys::getTexture(GUITexture::TLS), -halfWidth, -halfHeight, halfWidth, halfHeight);
1849 }
1850}
1851
1852
1853void
1855 // check if draw elevation
1858 // Translate to center of junction
1859 glTranslated(myNBNode->getPosition().x(), myNBNode->getPosition().y(), 0.1);
1860 // draw Z value
1863 }
1864}
1865
1866
1867void
1874
1875
1876void
1878 // check if draw junction elements
1880 // draw crossings
1881 for (const auto& crossing : myGNECrossings) {
1882 crossing->drawGL(s);
1883 }
1884 // draw walking areas
1885 for (const auto& walkingArea : myGNEWalkingAreas) {
1886 walkingArea->drawGL(s);
1887 }
1888 // draw internalLanes
1889 for (const auto& internalLanes : myInternalLanes) {
1890 internalLanes->drawGL(s);
1891 }
1892 // draw connections
1893 for (const auto& incomingEdge : myGNEIncomingEdges) {
1894 for (const auto& connection : incomingEdge->getGNEConnections()) {
1895 connection->drawGL(s);
1896 }
1897 }
1898 // draw child demand elements
1899 for (const auto& demandElement : getChildDemandElements()) {
1900 demandElement->drawGL(s);
1901 }
1902 // draw child demand elements
1903 for (const auto& demandElement : getChildDemandElements()) {
1904 demandElement->drawGL(s);
1905 }
1906 // draw path additional elements
1910 }
1911}
1912
1913
1914void
1916 const double exaggeration, const bool drawBubble) const {
1917 // if we're selecting using a boundary, first don't calculate contour bt check if edge boundary is within selection boundary
1919 // simply add object in ViewObjectsHandler with full boundary
1920 gViewObjectsHandler.selectObject(this, getType(), false, nullptr);
1921 } else {
1922 // always calculate for shape
1923 myNetworkElementContour.calculateContourClosedShape(s, d, this, myNBNode->getShape(), getType(), exaggeration, this);
1924 // check if calculate contour for bubble
1925 if (drawBubble) {
1927 }
1928 // check geometry points if we're editing shape
1929 if (myShapeEdited) {
1931 exaggeration, true);
1932 }
1933 }
1934}
1935
1936
1937void
1938GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value) {
1939 switch (key) {
1940 case SUMO_ATTR_KEEP_CLEAR: {
1941 throw InvalidArgument(toString(key) + " cannot be edited");
1942 }
1943 case SUMO_ATTR_ID: {
1945 break;
1946 }
1947 case SUMO_ATTR_TYPE: {
1952 }
1954 break;
1955 }
1956 case SUMO_ATTR_POSITION: {
1957 // set new position in NBNode updating edge boundaries
1958 moveJunctionGeometry(parse<Position>(value), true);
1959 // mark this connections and all of the junction's Neighbours as deprecated
1961 // update centering boundary and grid
1962 if (myGNEIncomingEdges.size() + myGNEOutgoingEdges.size() > 0) {
1964 } else {
1966 }
1967 break;
1968 }
1970 if (myLogicStatus == FEATURE_GUESSED && value != FEATURE_GUESSED) {
1971 // clear guessed connections. previous connections will be restored
1973 // Clear GNEConnections of incoming edges
1974 for (const auto& i : myGNEIncomingEdges) {
1975 i->clearGNEConnections();
1976 }
1977 }
1978 myLogicStatus = value;
1979 break;
1980 case SUMO_ATTR_SHAPE: {
1981 // set new shape (without updating grid)
1982 myNBNode->setCustomShape(parse<PositionVector>(value));
1983 // mark this connections and all of the junction's neighbors as deprecated
1985 // update centering boundary and grid
1987 break;
1988 }
1989 case SUMO_ATTR_RADIUS: {
1990 if (value.empty() || (value == "default")) {
1991 myNBNode->setRadius(-1);
1992 } else {
1993 myNBNode->setRadius(parse<double>(value));
1994 }
1995 break;
1996 }
1997 case SUMO_ATTR_TLTYPE: {
1998 // we need to make a copy of controlling TLS (because original will be updated)
1999 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
2000 for (const auto& TLS : copyOfTls) {
2001 TLS->setType(SUMOXMLDefinitions::TrafficLightTypes.get(value));
2002 }
2003 break;
2004 }
2005 case SUMO_ATTR_TLLAYOUT:
2006 // should not be triggered (handled via GNEChange_TLS)
2007 break;
2010 break;
2011 case SUMO_ATTR_FRINGE:
2013 break;
2016 break;
2017 case SUMO_ATTR_NAME:
2018 myNBNode->setName(value);
2019 break;
2020 default:
2021 setCommonAttribute(key, value);
2022 break;
2023 }
2024 // invalidate demand path calculator
2026}
2027
2028
2029double
2030GNEJunction::getColorValue(const GUIVisualizationSettings& /* s */, int activeScheme) const {
2031 switch (activeScheme) {
2032 case 0:
2034 return 3;
2035 } else {
2036 return 0;
2037 }
2038 case 1:
2040 case 2:
2041 switch (myNBNode->getType()) {
2043 return 0;
2045 return 1;
2047 return 2;
2049 return 3;
2051 return 4;
2053 return 5;
2055 return 6;
2057 return 7;
2060 return 8;
2062 return 8; // may happen before first network computation
2064 assert(false);
2065 return 8;
2067 return 9;
2069 return 10;
2071 return 11;
2073 return 12;
2075 return 13;
2076 default:
2077 assert(false);
2078 return 0;
2079 }
2080 case 3:
2081 return myNBNode->getPosition().z();
2082 default:
2083 assert(false);
2084 return 0;
2085 }
2086}
2087
2088void
2090 for (auto edge : myGNEIncomingEdges) {
2091 if (edge->getGNEConnections().size() > 0) {
2093 return;
2094 }
2095 }
2096 // no connections. Use normal color for border edges and cul-de-sac
2097 if (myGNEIncomingEdges.size() == 0 || myGNEOutgoingEdges.size() == 0) {
2099 return;
2100 } else if (myGNEIncomingEdges.size() == 1 && myGNEOutgoingEdges.size() == 1) {
2101 NBEdge* in = myGNEIncomingEdges[0]->getNBEdge();
2102 NBEdge* out = myGNEOutgoingEdges[0]->getNBEdge();
2103 if (in->isTurningDirectionAt(out)) {
2105 return;
2106 }
2107 }
2109}
2110
2111
2112void
2113GNEJunction::moveJunctionGeometry(const Position& pos, const bool updateEdgeBoundaries) {
2114 // reinit NBNode
2115 myNBNode->reinit(pos, myNBNode->getType());
2116 // declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
2117 std::set<GNEJunction*> affectedJunctions;
2118 std::set<GNEEdge*> affectedEdges;
2119 // Iterate over GNEEdges
2120 for (const auto& edge : getChildEdges()) {
2121 // Add source and destination junctions
2122 affectedJunctions.insert(edge->getFromJunction());
2123 affectedJunctions.insert(edge->getToJunction());
2124 // Obtain neighbors of Junction source
2125 for (const auto& junctionSourceEdge : edge->getFromJunction()->getChildEdges()) {
2126 affectedEdges.insert(junctionSourceEdge);
2127 }
2128 // Obtain neighbors of Junction destination
2129 for (const auto& junctionDestinationEdge : edge->getToJunction()->getChildEdges()) {
2130 affectedEdges.insert(junctionDestinationEdge);
2131 }
2132 }
2133 // reset walking areas of affected edges
2134 for (const auto& affectedJunction : affectedJunctions) {
2135 affectedJunction->clearWalkingAreas();
2136 }
2137 // Iterate over affected Edges
2138 for (const auto& affectedEdge : affectedEdges) {
2139 // update edge boundaries
2140 if (updateEdgeBoundaries) {
2141 affectedEdge->updateCenteringBoundary(true);
2142 }
2143 // Update edge geometry
2144 affectedEdge->updateGeometry();
2145 }
2146}
2147
2148
2151 // get active scheme
2152 const int scheme = s.junctionColorer.getActive();
2153 // first check if we're editing shape
2154 if (myShapeEdited) {
2156 }
2157 // set default color
2159 // set special bubble color
2160 if (bubble && (scheme == 0) && !myColorForMissingConnections) {
2161 color = s.junctionColorer.getScheme().getColor(1);
2162 }
2163 // override with special colors (unless the color scheme is based on selection)
2164 if (drawUsingSelectColor() && scheme != 1) {
2165 color = s.colorSettings.selectionColor;
2166 }
2167 // overwrite color if we're in data mode
2169 color = s.junctionColorer.getScheme().getColor(6);
2170 }
2171 // special color for source candidate junction
2172 if (mySourceCandidate) {
2174 }
2175 // special color for target candidate junction
2176 if (myTargetCandidate) {
2178 }
2179 // special color for special candidate junction
2180 if (mySpecialCandidate) {
2182 }
2183 // special color for possible candidate junction
2184 if (myPossibleCandidate) {
2186 }
2187 // special color for conflicted candidate junction
2190 }
2191 // return color
2192 return color;
2193}
2194
2195
2196void
2199 tlCont.insert(tlDef, forceInsert); // may return false for tlDef which controls multiple junctions
2200 tlDef->addNode(myNBNode);
2201}
2202
2203
2204void
2207 if (tlDef->getNodes().size() == 1) {
2208 tlCont.extract(tlDef);
2209 }
2211}
2212
2213
2214/****************************************************************************/
@ 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
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
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_LANE
begin/end of the description of a single lane
@ 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
@ 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_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_ROUNDABOUT
Roundabout type of node.
@ 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:289
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
Position getCenter() const
Returns the center of the boundary.
Definition Boundary.cpp:109
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition Boundary.cpp:75
Boundary & grow(double by)
extends the boundary by the given amount
Definition Boundary.cpp:340
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:952
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:742
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:773
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
double getCommonAttributeDouble(SumoXMLAttr key) const
bool mySelected
boolean to check if this AC is selected (more quickly as checking GUIGlObjectStorage)
static const std::string FALSE_STR
true value in string format(used for comparing boolean values in getAttribute(...))
static const std::string TRUE_STR
true value in string format (used for comparing boolean values in getAttribute(......
const std::string getID() const override
get ID (all Attribute Carriers have one)
PositionVector getCommonAttributePositionVector(SumoXMLAttr key) const
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.
void drawInLayer(const double typeOrLayer, const double extraOffset=0) const
draw element in the given layer, or in front if corresponding flag is enabled
Position getCommonAttributePosition(SumoXMLAttr key) const
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)
bool isCommonAttributeValid(SumoXMLAttr key, const std::string &value) const
std::string getCommonAttribute(SumoXMLAttr key) const
const GNETagProperties * myTagProperty
reference to tagProperty associated with this attribute carrier
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 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
void updateCenteringBoundary(const bool updateGrid)
update centering boundary (implies change in RTREE)
void updateGeometry() override
update pre-computed geometry information
struct for saving subordinated elements (Junction->Edge->Lane->(Additional | DemandElement)
ProtectElements * getProtectElements() const
get protect elements modul
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition GNEEdge.cpp:755
const GNEHierarchicalContainerChildren< GNEEdge * > & getChildEdges() const
get child edges
const GNEHierarchicalContainerChildren< GNELane * > & getChildLanes() const
get child lanes
const GNEHierarchicalContainerChildren< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
void removeTLSConnections(std::vector< NBConnection > &connections, GNEUndoList *undoList)
remove the given connections from all traffic light definitions of this junction
void markAsCreateEdgeSource()
marks as first junction in createEdge-mode
bool checkDrawFromContour() const override
check if draw from contour (green)
void addTrafficLight(NBTrafficLightDefinition *tlDef, bool forceInsert)
adds a traffic light
bool isAttributeEnabled(SumoXMLAttr key) const override
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
const std::vector< GNECrossing * > & getGNECrossings() const
Returns GNECrossings.
friend class GNEChange_TLS
Declare friend class.
Definition GNEJunction.h:52
TesselatedPolygon myTesselation
An object that stores the shape and its tesselation.
const std::vector< GNEWalkingArea * > & getGNEWalkingAreas() const
Returns GNEWalkingAreas.
bool checkDrawDeleteContourSmall() const override
check if draw delete contour small (pink/white)
void setResponsible(bool newVal)
set responsibility for deleting internal structures
Position getAttributePosition(SumoXMLAttr key) const override
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
double getExaggeration(const GUIVisualizationSettings &s) const override
return exaggeration associated with this GLObject
std::string getAttribute(SumoXMLAttr key) const override
void moveJunctionGeometry(const Position &pos, const bool updateEdgeBoundaries)
reposition the node at pos without updating GRID and informs the edges
bool checkDrawSelectContour() const override
check if draw select contour (blue)
void invalidateShape()
GNEContour myCircleContour
variable used for draw circle contours
bool isAttributeComputed(SumoXMLAttr key) const override
bool isLogicValid()
whether this junction has a valid logic
void drawTLSIcon(const GUIVisualizationSettings &s) const
draw TLS icon
std::vector< GNEEdge * > myGNEOutgoingEdges
vector with the (child) outgoings GNEEdges vinculated with this junction
void updateGeometry() override
update pre-computed geometry information (including crossings)
bool checkDrawOverContour() const override
check if draw over contour (orange)
void selectTLS(bool selected)
notify the junction of being selected in tls-mode. (used to control drawing)
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const override
determines color value
Boundary getCenteringBoundary() const override
Returns the boundary to which the view shall be centered in order to show the object.
void replaceIncomingConnections(GNEEdge *which, GNEEdge *by, GNEUndoList *undoList)
replace one edge by another in all tls connections
bool checkDrawMoveContour() const override
check if draw move contour (red)
GNEMoveElementJunction * myMoveElementJunction
move element junction
PositionVector getAttributePositionVector(SumoXMLAttr key) const override
void removeOutgoingGNEEdge(GNEEdge *edge)
remove outgoing GNEEdge
void markAsModified(GNEUndoList *undoList)
prevent re-guessing connections at this junction
std::vector< GNECrossing * > myGNECrossings
the built crossing objects
void invalidateTLS(GNEUndoList *undoList, const NBConnection &deletedConnection=NBConnection::InvalidConnection, const NBConnection &addedConnection=NBConnection::InvalidConnection)
void clearWalkingAreas()
clear walking areas
void removeIncomingGNEEdge(GNEEdge *edge)
remove incoming GNEEdge
std::vector< GNEConnection * > getGNEConnections() const
Returns all GNEConnections vinculated with this junction.
GNEWalkingArea * retrieveGNEWalkingArea(const std::string &NBNodeWalkingAreaID, bool createIfNoExist=true)
get GNEWalkingArea if exist, and if not create it if create is enabled
void updateGLObject() override
update GLObject (geometry, ID, etc.)
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 setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList) override
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own popup-menu.
void addInternalLane(const GNEInternalLane *internalLane)
add internal lane
const PositionVector & getJunctionShape() const
void drawJunctionName(const GUIVisualizationSettings &s) const
draw junction name
void markConnectionsDeprecated(bool includingNeighbours)
mark connections as deprecated
bool checkDrawDeleteContour() const override
check if draw delete contour (pink/white)
void mirrorXLeftHand()
temporarily mirror coordinates in lefthand network to compute correct crossing geometries
void drawGL(const GUIVisualizationSettings &s) const override
Draws 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
void removeInternalLane(const GNEInternalLane *internalLane)
remove internal lane
bool checkDrawToContour() const override
check if draw from contour (magenta)
bool isValid(SumoXMLAttr key, const std::string &value) override
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
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)
bool checkDrawRelatedContour() const override
check if draw related contour (cyan)
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.
void drawJunctionCenter(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d) const
draw junction center (only in move mode)
void drawElevation(const GUIVisualizationSettings &s) const
draw elevation
NBNode * myNBNode
A reference to the represented junction.
Parameterised * getParameters() override
get parameters associated with this junction
GNEMoveElement * getMoveElement() const override
methods to retrieve the elements linked to this junction
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
double getAttributeDouble(SumoXMLAttr key) const override
void setJunctionType(const std::string &value, GNEUndoList *undoList)
set junction Type (using undo/redo)
void drawJunctionAsShape(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const double exaggeration) const
draw junction as bubble
double myExaggeration
exaggeration used in tesselation
~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
void deleteGLObject() override
delete element
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
removes a traffic light
bool getMoveOnlyJunctionCenter() const
check if option "move only junction center" is enabled
NetworkMoveOptions * getNetworkMoveOptions() const
get network mode options
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
void deleteCrossing(GNECrossing *crossing, GNEUndoList *undoList)
remove crossing
Definition GNENet.cpp:718
NBNetBuilder * getNetBuilder() const
get net builder
Definition GNENet.cpp:168
void addGLObjectIntoGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition GNENet.cpp:1444
GNEPathManager * getDataPathManager()
get data path manager
Definition GNENet.cpp:204
void removeGLObjectFromGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition GNENet.cpp:1454
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition GNENet.cpp:2197
void mergeJunctions(GNEJunction *moved, const GNEJunction *target, GNEUndoList *undoList)
merge the given junctions edges between the given junctions will be deleted
Definition GNENet.cpp:1192
GNEPathManager * getDemandPathManager()
get demand path manager
Definition GNENet.cpp:198
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:174
GNEPathManager * getNetworkPathManager()
get network path manager
Definition GNENet.cpp:192
void requireRecompute()
inform the net about the need for recomputation
Definition GNENet.cpp:1614
GNEViewParent * getViewParent() const
get view parent (used for simplify code)
Definition GNENet.cpp:150
void addExplicitTurnaround(std::string id)
add edge id to the list of explicit turnarounds
Definition GNENet.cpp:2209
void deleteJunction(GNEJunction *junction, GNEUndoList *undoList)
removes junction and all incident edges
Definition GNENet.cpp:435
GNEUndoList * getUndoList() const
get undo list(used for simplify code)
Definition GNENet.cpp:156
GNEViewNet * getViewNet() const
get view net (used for simplify code)
Definition GNENet.cpp:144
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
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.
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
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...
GNEAttributeCarrier * getFirstAC() const
void uninspectAC(GNEAttributeCarrier *AC)
uninspect AC
const std::vector< const GNEJunction * > & getMergingJunctions() const
get merging junctions
const GUIGlObject * getGUIGlObjectFront() const
get front GUIGLObject or a pointer to nullptr
GNEJunction * getJunctionFront() const
get front junction or a pointer to nullptr
const std::vector< GNEJunction * > & getJunctions() const
get vector with junctions
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
void updateObjectsInPosition(const Position &pos)
update objects and boundaries in position
GNEViewNetHelper::InspectedElements & getInspectedElements()
get inspected elements
const GNEViewNetHelper::MoveSingleElementModul & getMoveSingleElementValues() const
get move single element values
bool askMergeJunctions(const GNEJunction *movedJunction, const GNEJunction *targetJunction, bool &alreadyAsked)
ask merge junctions
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)
bool checkOverLockedElement(const GUIGlObject *GLObject, const bool isSelected) const
check if given element is locked (used for drawing select and delete contour)
const GNEViewNetHelper::ViewObjectsSelector & getViewObjectsSelector() const
get objects under cursor
GNECrossingFrame * getCrossingFrame() const
get frame for NETWORK_CROSSING
GNEMoveFrame * getMoveFrame() const
get frame for move elements
GNEDeleteFrame * getDeleteFrame() const
get frame for delete elements
void updateCenteringBoundary(const bool updateGrid)
update centering boundary (implies change in RTREE)
void updateGeometry() override
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.
GUIGlObject * getGLObject() const
The object that belongs to this popup-menu.
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.
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
void buildPopUpMenuCommonOptions(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, GUISUMOAbstractView *parent, const SumoXMLTag tag, const bool selected, bool addSeparator=true)
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)
GUIGLObjectPopupMenu * getPopup() const
ge the current popup-menu
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 Triangle & getSelectionTriangle() const
get selection triangle
bool addMergingJunctions(const GNEJunction *junction)
add to merging junctions (used for marking junctions to merge)
bool selectingUsingRectangle() const
return true if we're selecting using a triangle
bool selectObject(const GUIGlObject *GLObject, const double layer, const bool checkDuplicated, const GNESegment *segment)
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:1047
const std::string & getID() const
Definition NBEdge.h:1551
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
Definition NBEdge.cpp:3807
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition NBEdge.cpp:4169
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
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:345
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
Definition NBNode.cpp:353
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:3049
SumoXMLNodeType getType() const
Returns the type of this node.
Definition NBNode.h:285
bool isTrafficLight() const
Definition NBNode.h:839
void setRoundaboutType(RoundaboutType roundaboutType)
set roundabout type
Definition NBNode.h:591
void setRightOfWay(RightOfWay rightOfWay)
set method for computing right-of-way
Definition NBNode.h:581
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition NBNode.cpp:2789
void invalidateIncomingConnections(bool reallowSetting=false)
invalidate incoming connections
Definition NBNode.cpp:2128
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:410
std::vector< std::pair< Position, std::string > > getEndPoints() const
return list of unique endpoint coordinates of all edges at this node
Definition NBNode.cpp:4372
const std::vector< std::unique_ptr< Crossing > > & getCrossingsIncludingInvalid() const
Definition NBNode.h:759
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:601
std::vector< Crossing * > getCrossings() const
return this junctions pedestrian crossings
Definition NBNode.cpp:3098
const std::string & getName() const
Returns intersection name.
Definition NBNode.h:315
void setRadius(double radius)
set the turning radius
Definition NBNode.h:571
void setName(const std::string &name)
set intersection name
Definition NBNode.h:596
const Position & getPosition() const
Definition NBNode.h:260
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
Definition NBNode.cpp:439
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:2783
RoundaboutType getRoundaboutType() const
Returns roundabout type.
Definition NBNode.h:310
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:4072
bool checkIsRemovableReporting(std::string &reason) const
check if node is removable and return reason if not
Definition NBNode.cpp:2670
const std::vector< WalkingArea > & getWalkingAreas() const
return this junctions pedestrian walking areas
Definition NBNode.h:764
PositionVector myPoly
the (outer) shape of the junction
Definition NBNode.h:972
void setFringeType(FringeType fringeType)
set fringe type
Definition NBNode.h:586
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition NBNode.h:336
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.
An upper class for objects with additional parameters.
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:278
static const Position INVALID
used to indicate that a position is valid
Definition Position.h:323
double x() const
Returns the x-position.
Definition Position.h:52
double z() const
Returns the z-position.
Definition Position.h:62
double y() const
Returns the y-position.
Definition Position.h:57
A list of positions.
void closePolygon()
ensures that the last position equals the first
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< RoundaboutType > RoundaboutTypeValues
fringe types
static StringBijection< FringeType > FringeTypeValues
fringe types
const std::string & getString(const T key) const
get string
bool hasString(const std::string &str) const
check if the given string exist
T get(const std::string &str) const
get key
std::vector< GLPrimitive > myTesselation
id of the display list for the cached tesselation
Definition GUIPolygon.h:72
void drawTesselation(const PositionVector &shape) const
perform the tesselation / drawing
bool isBoundaryFullWithin(const Boundary &boundary) const
check if the given position is FULL within this triangle
Definition Triangle.cpp:60
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
static const double edgeGeometryPointRadius
moving edge geometry point 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