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-2025 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
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>
42#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->getViewNet()->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->getViewNet()->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 movedJunction = dynamic_cast<GNEJunction*>(myNet->getViewNet()->getMoveSingleElementValues().getMovedElement());
249 if (movedJunction && (movedJunction != 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(movedJunction->getPositionInView()) < (radiusTo * radiusTo)) {
256 // add both it in the list of merging junction
259 return true;
260 }
261 } else if (myNBNode->getShape().around(movedJunction->getNBNode()->getPosition())) {
262 // add both it in the list of merging junction
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->getViewNet()->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:
1367 case SUMO_ATTR_NAME:
1368 return myNBNode->getName();
1369 default:
1370 return getCommonAttribute(key);
1371 }
1372}
1373
1374
1375double
1379
1380
1385
1386
1389 switch (key) {
1390 case SUMO_ATTR_SHAPE:
1391 return myNBNode->getShape();
1392 default:
1394 }
1395}
1396
1397
1398void
1399GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
1400 if (value == getAttribute(key)) {
1401 return; //avoid needless changes, later logic relies on the fact that attributes have changed
1402 }
1403 switch (key) {
1404 case SUMO_ATTR_ID:
1406 case SUMO_ATTR_SHAPE:
1407 case SUMO_ATTR_RADIUS:
1409 case SUMO_ATTR_FRINGE:
1410 case SUMO_ATTR_NAME:
1411 GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);
1412 break;
1413 case SUMO_ATTR_POSITION: {
1414 const GNEJunction* junctionToMerge = nullptr;
1415 bool alreadyAsked = false;
1416 // parse position
1417 Position newPosition = GNEAttributeCarrier::parse<Position>(value);
1418 // check if caculate new position based in edges
1419 if (newPosition == Position::INVALID) {
1420 Boundary b;
1421 // set new position of adjacent edges
1422 for (const auto& edge : myGNEIncomingEdges) {
1423 b.add(edge->getNBEdge()->getGeometry().back());
1424 }
1425 for (const auto& edge : myGNEOutgoingEdges) {
1426 b.add(edge->getNBEdge()->getGeometry().front());
1427 }
1428 newPosition = b.getCenter();
1429 }
1430 // retrieve all junctions placed in this position
1431 myNet->getViewNet()->updateObjectsInPosition(newPosition);
1432 for (const auto& junction : myNet->getViewNet()->getViewObjectsSelector().getJunctions()) {
1433 // check distance position
1434 if ((junctionToMerge == nullptr) && (junction != this) && (junction->getPositionInView().distanceTo2D(newPosition) < POSITION_EPS) &&
1435 myNet->getViewNet()->askMergeJunctions(this, junction, alreadyAsked)) {
1436 junctionToMerge = junction;
1437 }
1438 }
1439 // also check the merging junctions located during drawGL
1440 for (const auto& junction : myNet->getViewNet()->getViewObjectsSelector().getMergingJunctions()) {
1441 // check distance position
1442 if ((junctionToMerge == nullptr) && (junction != this) && myNet->getViewNet()->askMergeJunctions(this, junction, alreadyAsked)) {
1443 junctionToMerge = junction;
1444 }
1445 }
1446 // if we merge the junction, this junction will be removed, therefore we don't have to change the position
1447 if (junctionToMerge) {
1448 myNet->mergeJunctions(this, junctionToMerge, undoList);
1449 } else {
1450 // change Keep Clear attribute in all connections
1451 undoList->begin(this, TL("change junction position"));
1452 // obtain NBNode position
1453 const Position orig = myNBNode->getPosition();
1454 // change junction position
1455 GNEChange_Attribute::changeAttribute(this, key, toString(newPosition), undoList, true);
1456 // calculate delta using new position
1458 const Position delta = myNBNode->getPosition() - (moveOnlyCenter ? myNBNode->getPosition() : orig);
1459 // set new position of adjacent edges
1460 for (const auto& edge : myGNEIncomingEdges) {
1461 const Position newEnd = edge->getNBEdge()->getGeometry().back() + delta;
1463 }
1464 for (const auto& edge : myGNEOutgoingEdges) {
1465 const Position newStart = edge->getNBEdge()->getGeometry().front() + delta;
1466 GNEChange_Attribute::changeAttribute(edge, GNE_ATTR_SHAPE_START, toString(newStart), undoList, true);
1467 }
1468 undoList->end();
1469 }
1470 break;
1471 }
1473 // change Keep Clear attribute in all connections
1474 undoList->begin(this, TL("change keepClear for whole junction"));
1475 for (const auto& incomingEdge : myGNEIncomingEdges) {
1476 for (const auto& junction : incomingEdge->getGNEConnections()) {
1477 GNEChange_Attribute::changeAttribute(junction, key, value, undoList, true);
1478 }
1479 }
1480 undoList->end();
1481 break;
1482 case SUMO_ATTR_TYPE: {
1483 // set junction type
1484 setJunctionType(value, undoList);
1485 break;
1486 }
1487 case SUMO_ATTR_TLTYPE: {
1488 undoList->begin(this, "change " + getTagStr() + " tl-type");
1489 // make a copy because we will modify the original
1490 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1491 for (const auto& TLS : copyOfTls) {
1492 NBLoadedSUMOTLDef* oldLoaded = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
1493 if (oldLoaded != nullptr) {
1494 NBTrafficLightDefinition* newDef = nullptr;
1495 if (value == toString(TrafficLightType::NEMA) || oldLoaded->getType() == TrafficLightType::NEMA) {
1496 // rebuild the program because the old and new ones are incompatible
1497 newDef = new NBOwnTLDef(oldLoaded->getID(), oldLoaded->getOffset(), TrafficLightType::NEMA);
1498 newDef->setProgramID(oldLoaded->getProgramID());
1499 } else {
1500 NBLoadedSUMOTLDef* newLDef = new NBLoadedSUMOTLDef(*oldLoaded, *oldLoaded->getLogic());
1501 newLDef->guessMinMaxDuration(); // minDur and maxDur are never written for a static tls
1502 newDef = newLDef;
1503 }
1504 std::vector<NBNode*> nodes = TLS->getNodes();
1505 for (const auto& node : nodes) {
1506 GNEJunction* junction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1507 undoList->add(new GNEChange_TLS(junction, TLS, false), true);
1508 undoList->add(new GNEChange_TLS(junction, newDef, true), true);
1509 }
1510 }
1511 }
1512 GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);
1513 undoList->end();
1514 break;
1515 }
1516 case SUMO_ATTR_TLLAYOUT: {
1517 undoList->begin(this, "change " + getTagStr() + " tlLayout");
1518 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1519 for (const auto& oldTLS : copyOfTls) {
1520 std::vector<NBNode*> copyOfNodes = oldTLS->getNodes();
1521 NBOwnTLDef* newTLS = new NBOwnTLDef(oldTLS->getID(), oldTLS->getOffset(), oldTLS->getType());
1523 newTLS->setProgramID(oldTLS->getProgramID());
1524 for (const auto& node : copyOfNodes) {
1525 GNEJunction* oldJunction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1526 undoList->add(new GNEChange_TLS(oldJunction, oldTLS, false), true);
1527 }
1528 for (const auto& node : copyOfNodes) {
1529 GNEJunction* oldJunction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1530 undoList->add(new GNEChange_TLS(oldJunction, newTLS, true), true);
1531 }
1532 }
1533 undoList->end();
1534 break;
1535 }
1536 case SUMO_ATTR_TLID: {
1537 undoList->begin(this, "change " + toString(SUMO_TAG_TRAFFIC_LIGHT) + " id");
1538 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1539 assert(copyOfTls.size() > 0);
1540 NBTrafficLightDefinition* currentTLS = *copyOfTls.begin();
1541 NBTrafficLightDefinition* currentTLSCopy = nullptr;
1542 const bool currentIsSingle = currentTLS->getNodes().size() == 1;
1543 const bool currentIsLoaded = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS) != nullptr;
1544 if (currentIsLoaded) {
1545 currentTLSCopy = new NBLoadedSUMOTLDef(*currentTLS,
1546 *dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS)->getLogic());
1547 }
1548 // remove from previous tls
1549 for (const auto& TLS : copyOfTls) {
1550 undoList->add(new GNEChange_TLS(this, TLS, false), true);
1551 }
1553 // programs to which the current node shall be added
1554 const std::map<std::string, NBTrafficLightDefinition*> programs = tlCont.getPrograms(value);
1555 if (programs.size() > 0) {
1556 for (const auto& TLSProgram : programs) {
1557 NBTrafficLightDefinition* oldTLS = TLSProgram.second;
1558 if (dynamic_cast<NBOwnTLDef*>(oldTLS) != nullptr) {
1559 undoList->add(new GNEChange_TLS(this, oldTLS, true), true);
1560 } else {
1561 // delete and re-create the definition because the loaded phases are now invalid
1562 if (dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS) != nullptr &&
1563 dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->usingSignalGroups()) {
1564 // keep the old program and add all-red state for the added links
1565 NBLoadedSUMOTLDef* newTLSJoined = new NBLoadedSUMOTLDef(*oldTLS, *dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->getLogic());
1566 newTLSJoined->joinLogic(currentTLSCopy);
1567 undoList->add(new GNEChange_TLS(this, newTLSJoined, true, true), true);
1568 } else {
1569 undoList->add(new GNEChange_TLS(this, nullptr, true, false, value), true);
1570 }
1572 // switch from old to new definition
1573 std::vector<NBNode*> copyOfNodes = oldTLS->getNodes();
1574 for (const auto& node : copyOfNodes) {
1575 GNEJunction* oldJunction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1576 undoList->add(new GNEChange_TLS(oldJunction, oldTLS, false), true);
1577 undoList->add(new GNEChange_TLS(oldJunction, newTLS, true), true);
1578 }
1579 }
1580 }
1581 } else {
1582 if (currentIsSingle && currentIsLoaded) {
1583 // rename the traffic light but keep everything else
1584 NBTrafficLightLogic* renamedLogic = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLSCopy)->getLogic();
1585 renamedLogic->setID(value);
1586 NBLoadedSUMOTLDef* renamedTLS = new NBLoadedSUMOTLDef(*currentTLSCopy, *renamedLogic);
1587 renamedTLS->setID(value);
1588 undoList->add(new GNEChange_TLS(this, renamedTLS, true, true), true);
1589 } else {
1590 // create new traffic light
1591 undoList->add(new GNEChange_TLS(this, nullptr, true, false, value), true);
1592 }
1593 }
1594 delete currentTLSCopy;
1595 undoList->end();
1596 break;
1597 }
1598 default:
1599 setCommonAttribute(key, value, undoList);
1600 break;
1601 }
1602}
1603
1604
1605bool
1606GNEJunction::isValid(SumoXMLAttr key, const std::string& value) {
1607 switch (key) {
1608 case SUMO_ATTR_ID:
1609 return SUMOXMLDefinitions::isValidNetID(value) && (myNet->getAttributeCarriers()->retrieveJunction(value, false) == nullptr);
1610 case SUMO_ATTR_TYPE:
1612 case SUMO_ATTR_POSITION:
1613 if (value.empty()) {
1614 return (myGNEIncomingEdges.size() + myGNEOutgoingEdges.size()) > 0;
1615 } else {
1616 return canParse<Position>(value);
1617 }
1618 case SUMO_ATTR_SHAPE:
1619 // empty shapes are allowed
1620 return canParse<PositionVector>(value);
1621 case SUMO_ATTR_RADIUS:
1622 if (value.empty() || (value == "default")) {
1623 return true;
1624 } else {
1625 return canParse<double>(value) && ((parse<double>(value) >= 0) || (parse<double>(value) == -1));
1626 }
1627 case SUMO_ATTR_TLTYPE:
1629 case SUMO_ATTR_TLLAYOUT:
1631 case SUMO_ATTR_TLID:
1632 return myNBNode->isTLControlled() && (value != "");
1634 return canParse<bool>(value);
1637 case SUMO_ATTR_FRINGE:
1639 case SUMO_ATTR_NAME:
1640 return true;
1641 default:
1642 return isCommonAttributeValid(key, value);
1643 }
1644}
1645
1646
1647bool
1649 switch (key) {
1650 case SUMO_ATTR_TLTYPE:
1651 case SUMO_ATTR_TLLAYOUT:
1652 case SUMO_ATTR_TLID:
1653 return myNBNode->isTLControlled();
1654 case SUMO_ATTR_KEEP_CLEAR: {
1655 // check if at least there is an incoming connection
1656 for (const auto& incomingEdge : myGNEIncomingEdges) {
1657 if (incomingEdge->getGNEConnections().size() > 0) {
1658 return true;
1659 }
1660 }
1661 return false;
1662 }
1664 return false;
1665 default:
1666 return true;
1667 }
1668}
1669
1670
1671bool
1673 switch (key) {
1674 case SUMO_ATTR_SHAPE:
1675 return !myNBNode->hasCustomShape();
1676 default:
1677 return false;
1678 }
1679}
1680
1681
1682void
1684 myAmResponsible = newVal;
1685}
1686
1687// ===========================================================================
1688// private
1689// ===========================================================================
1690
1691bool
1692GNEJunction::drawAsBubble(const GUIVisualizationSettings& s, const double junctionShapeArea) const {
1693 const auto& editModes = myNet->getViewNet()->getEditModes();
1694 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
1695 // check conditions
1696 if (junctionShapeArea < 4) {
1697 // force draw if this junction is a candidate
1700 return true;
1701 }
1702 // force draw if we're in person/container plan mode
1703 if (editModes.isCurrentSupermodeDemand() &&
1704 ((editModes.demandEditMode == DemandEditMode::DEMAND_PERSON) ||
1705 (editModes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) ||
1706 (editModes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) ||
1707 (editModes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN))) {
1708 return true;
1709 }
1710 // force draw if we're inspecting a vehicle that start or ends in a junction
1711 if (inspectedElements.isInspectingSingleElement()) {
1712 // check if starts or ends in this junction
1713 if ((inspectedElements.getFirstAC()->hasAttribute(SUMO_ATTR_FROM_JUNCTION) &&
1714 (inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_FROM_JUNCTION) == getID())) ||
1715 (inspectedElements.getFirstAC()->hasAttribute(SUMO_ATTR_TO_JUNCTION) &&
1716 (inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_TO_JUNCTION) == getID()))) {
1717 return true;
1718 }
1719 }
1720 }
1721 if (!s.drawJunctionShape) {
1722 // don't draw bubble if it was disabled in GUIVisualizationSettings
1723 return false;
1724 }
1726 // force draw bubbles if we enabled option in checkbox of viewNet
1727 return true;
1728 }
1729 if (junctionShapeArea >= 4) {
1730 // don't draw if shape area is greater than 4
1731 return false;
1732 }
1733 if (!editModes.isCurrentSupermodeNetwork()) {
1734 // only draw bubbles in network mode
1735 return false;
1736 }
1737 return true;
1738}
1739
1740
1741void
1743 const double exaggeration) const {
1744 // calculate bubble radius
1745 const double bubbleRadius = s.neteditSizeSettings.junctionBubbleRadius * exaggeration;
1746 // set bubble color
1747 const RGBColor bubbleColor = setColor(s, true);
1748 // push matrix
1750 // set color
1751 GLHelper::setColor(bubbleColor);
1752 // move matrix junction center
1753 glTranslated(myNBNode->getPosition().x(), myNBNode->getPosition().y(), 1.5);
1754 // draw filled circle
1755 GLHelper::drawFilledCircleDetailled(d, bubbleRadius);
1756 // pop matrix
1758}
1759
1760
1761void
1763 // first check drawing conditions
1764 if (s.drawJunctionShape && (myNBNode->getShape().size() > 0)) {
1765 // set shape color
1766 const RGBColor junctionShapeColor = setColor(s, false);
1767 // set color
1768 GLHelper::setColor(junctionShapeColor);
1769 // adjust shape to exaggeration (check)
1770 if ((exaggeration > 1 || myExaggeration > 1) && exaggeration != myExaggeration) {
1771 myExaggeration = exaggeration;
1774 myTesselation.getShapeRef().scaleRelative(exaggeration);
1776 }
1777 // check if draw tesselation or or polygon
1779 // draw shape with high detail
1781 } else {
1782 // draw shape
1784 }
1785 // draw shape points only in Network supermode
1788 // set color
1789 const RGBColor darkerColor = junctionShapeColor.changedBrightness(-32);
1790 // calculate geometry
1791 GUIGeometry junctionGeometry;
1792 // obtain junction Shape
1793 PositionVector junctionOpenShape = myNBNode->getShape();
1794 // adjust shape to exaggeration
1795 if (exaggeration > 1) {
1796 junctionOpenShape.scaleRelative(exaggeration);
1797 }
1798 // update geometry
1799 junctionGeometry.updateGeometry(junctionOpenShape);
1800 // set color
1801 GLHelper::setColor(darkerColor);
1802 // draw shape
1804 // draw geometry points
1805 GUIGeometry::drawGeometryPoints(d, junctionOpenShape, darkerColor,
1808 }
1809 }
1810}
1811
1812
1813void
1816 // push matrix
1818 // set color
1819 GLHelper::setColor(setColor(s, true).changedBrightness(-20));
1820 // move matrix junction center
1821 glTranslated(myNBNode->getPosition().x(), myNBNode->getPosition().y(), 1.7);
1822 // draw filled circle
1824 // pop matrix
1826 }
1827}
1828
1829
1830void
1832 // draw TLS icon if isn't being drawn for selecting
1836 const Position pos = myNBNode->getPosition();
1837 glTranslated(pos.x(), pos.y(), 2.2);
1838 glColor3d(1, 1, 1);
1839 const double halfWidth = 32 / s.scale;
1840 const double halfHeight = 64 / s.scale;
1841 GUITexturesHelper::drawTexturedBox(GUITextureSubSys::getTexture(GUITexture::TLS), -halfWidth, -halfHeight, halfWidth, halfHeight);
1843 }
1844}
1845
1846
1847void
1849 // check if draw elevation
1852 // Translate to center of junction
1853 glTranslated(myNBNode->getPosition().x(), myNBNode->getPosition().y(), 0.1);
1854 // draw Z value
1857 }
1858}
1859
1860
1861void
1868
1869
1870void
1872 // check if draw junction elements
1874 // draw crossings
1875 for (const auto& crossing : myGNECrossings) {
1876 crossing->drawGL(s);
1877 }
1878 // draw walking areas
1879 for (const auto& walkingArea : myGNEWalkingAreas) {
1880 walkingArea->drawGL(s);
1881 }
1882 // draw internalLanes
1883 for (const auto& internalLanes : myInternalLanes) {
1884 internalLanes->drawGL(s);
1885 }
1886 // draw connections
1887 for (const auto& incomingEdge : myGNEIncomingEdges) {
1888 for (const auto& connection : incomingEdge->getGNEConnections()) {
1889 connection->drawGL(s);
1890 }
1891 }
1892 // draw child demand elements
1893 for (const auto& demandElement : getChildDemandElements()) {
1894 demandElement->drawGL(s);
1895 }
1896 // draw child demand elements
1897 for (const auto& demandElement : getChildDemandElements()) {
1898 demandElement->drawGL(s);
1899 }
1900 // draw path additional elements
1904 }
1905}
1906
1907
1908void
1910 const double exaggeration, const bool drawBubble) const {
1911 // if we're selecting using a boundary, first don't calculate contour bt check if edge boundary is within selection boundary
1913 // simply add object in ViewObjectsHandler with full boundary
1914 gViewObjectsHandler.selectObject(this, getType(), false, nullptr);
1915 } else {
1916 // always calculate for shape
1917 myNetworkElementContour.calculateContourClosedShape(s, d, this, myNBNode->getShape(), getType(), exaggeration, this);
1918 // check if calculate contour for bubble
1919 if (drawBubble) {
1921 }
1922 // check geometry points if we're editing shape
1923 if (myShapeEdited) {
1925 exaggeration, true);
1926 }
1927 }
1928}
1929
1930
1931void
1932GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value) {
1933 switch (key) {
1934 case SUMO_ATTR_KEEP_CLEAR: {
1935 throw InvalidArgument(toString(key) + " cannot be edited");
1936 }
1937 case SUMO_ATTR_ID: {
1939 break;
1940 }
1941 case SUMO_ATTR_TYPE: {
1946 }
1948 break;
1949 }
1950 case SUMO_ATTR_POSITION: {
1951 // set new position in NBNode updating edge boundaries
1952 moveJunctionGeometry(parse<Position>(value), true);
1953 // mark this connections and all of the junction's Neighbours as deprecated
1955 // update centering boundary and grid
1956 if (myGNEIncomingEdges.size() + myGNEOutgoingEdges.size() > 0) {
1958 } else {
1960 }
1961 break;
1962 }
1964 if (myLogicStatus == FEATURE_GUESSED && value != FEATURE_GUESSED) {
1965 // clear guessed connections. previous connections will be restored
1967 // Clear GNEConnections of incoming edges
1968 for (const auto& i : myGNEIncomingEdges) {
1969 i->clearGNEConnections();
1970 }
1971 }
1972 myLogicStatus = value;
1973 break;
1974 case SUMO_ATTR_SHAPE: {
1975 // set new shape (without updating grid)
1976 myNBNode->setCustomShape(parse<PositionVector>(value));
1977 // mark this connections and all of the junction's neighbors as deprecated
1979 // update centering boundary and grid
1981 break;
1982 }
1983 case SUMO_ATTR_RADIUS: {
1984 if (value.empty() || (value == "default")) {
1985 myNBNode->setRadius(-1);
1986 } else {
1987 myNBNode->setRadius(parse<double>(value));
1988 }
1989 break;
1990 }
1991 case SUMO_ATTR_TLTYPE: {
1992 // we need to make a copy of controlling TLS (because original will be updated)
1993 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1994 for (const auto& TLS : copyOfTls) {
1995 TLS->setType(SUMOXMLDefinitions::TrafficLightTypes.get(value));
1996 }
1997 break;
1998 }
1999 case SUMO_ATTR_TLLAYOUT:
2000 // should not be triggered (handled via GNEChange_TLS)
2001 break;
2004 break;
2005 case SUMO_ATTR_FRINGE:
2007 break;
2008 case SUMO_ATTR_NAME:
2009 myNBNode->setName(value);
2010 break;
2011 default:
2012 setCommonAttribute(key, value);
2013 break;
2014 }
2015 // invalidate demand path calculator
2017}
2018
2019
2020double
2021GNEJunction::getColorValue(const GUIVisualizationSettings& /* s */, int activeScheme) const {
2022 switch (activeScheme) {
2023 case 0:
2025 return 3;
2026 } else {
2027 return 0;
2028 }
2029 case 1:
2031 case 2:
2032 switch (myNBNode->getType()) {
2034 return 0;
2036 return 1;
2038 return 2;
2040 return 3;
2042 return 4;
2044 return 5;
2046 return 6;
2048 return 7;
2051 return 8;
2053 return 8; // may happen before first network computation
2055 assert(false);
2056 return 8;
2058 return 9;
2060 return 10;
2062 return 11;
2064 return 12;
2066 return 13;
2067 default:
2068 assert(false);
2069 return 0;
2070 }
2071 case 3:
2072 return myNBNode->getPosition().z();
2073 default:
2074 assert(false);
2075 return 0;
2076 }
2077}
2078
2079void
2081 for (auto edge : myGNEIncomingEdges) {
2082 if (edge->getGNEConnections().size() > 0) {
2084 return;
2085 }
2086 }
2087 // no connections. Use normal color for border edges and cul-de-sac
2088 if (myGNEIncomingEdges.size() == 0 || myGNEOutgoingEdges.size() == 0) {
2090 return;
2091 } else if (myGNEIncomingEdges.size() == 1 && myGNEOutgoingEdges.size() == 1) {
2092 NBEdge* in = myGNEIncomingEdges[0]->getNBEdge();
2093 NBEdge* out = myGNEOutgoingEdges[0]->getNBEdge();
2094 if (in->isTurningDirectionAt(out)) {
2096 return;
2097 }
2098 }
2100}
2101
2102
2103void
2104GNEJunction::moveJunctionGeometry(const Position& pos, const bool updateEdgeBoundaries) {
2105 // reinit NBNode
2106 myNBNode->reinit(pos, myNBNode->getType());
2107 // declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
2108 std::set<GNEJunction*> affectedJunctions;
2109 std::set<GNEEdge*> affectedEdges;
2110 // Iterate over GNEEdges
2111 for (const auto& edge : getChildEdges()) {
2112 // Add source and destination junctions
2113 affectedJunctions.insert(edge->getFromJunction());
2114 affectedJunctions.insert(edge->getToJunction());
2115 // Obtain neighbors of Junction source
2116 for (const auto& junctionSourceEdge : edge->getFromJunction()->getChildEdges()) {
2117 affectedEdges.insert(junctionSourceEdge);
2118 }
2119 // Obtain neighbors of Junction destination
2120 for (const auto& junctionDestinationEdge : edge->getToJunction()->getChildEdges()) {
2121 affectedEdges.insert(junctionDestinationEdge);
2122 }
2123 }
2124 // reset walking areas of affected edges
2125 for (const auto& affectedJunction : affectedJunctions) {
2126 affectedJunction->clearWalkingAreas();
2127 }
2128 // Iterate over affected Edges
2129 for (const auto& affectedEdge : affectedEdges) {
2130 // update edge boundaries
2131 if (updateEdgeBoundaries) {
2132 affectedEdge->updateCenteringBoundary(true);
2133 }
2134 // Update edge geometry
2135 affectedEdge->updateGeometry();
2136 }
2137}
2138
2139
2142 // get active scheme
2143 const int scheme = s.junctionColorer.getActive();
2144 // first check if we're editing shape
2145 if (myShapeEdited) {
2147 }
2148 // set default color
2150 // set special bubble color
2151 if (bubble && (scheme == 0) && !myColorForMissingConnections) {
2152 color = s.junctionColorer.getScheme().getColor(1);
2153 }
2154 // override with special colors (unless the color scheme is based on selection)
2155 if (drawUsingSelectColor() && scheme != 1) {
2156 color = s.colorSettings.selectionColor;
2157 }
2158 // overwrite color if we're in data mode
2160 color = s.junctionColorer.getScheme().getColor(6);
2161 }
2162 // special color for source candidate junction
2163 if (mySourceCandidate) {
2165 }
2166 // special color for target candidate junction
2167 if (myTargetCandidate) {
2169 }
2170 // special color for special candidate junction
2171 if (mySpecialCandidate) {
2173 }
2174 // special color for possible candidate junction
2175 if (myPossibleCandidate) {
2177 }
2178 // special color for conflicted candidate junction
2181 }
2182 // return color
2183 return color;
2184}
2185
2186
2187void
2190 tlCont.insert(tlDef, forceInsert); // may return false for tlDef which controls multiple junctions
2191 tlDef->addNode(myNBNode);
2192}
2193
2194
2195void
2198 if (tlDef->getNodes().size() == 1) {
2199 tlCont.extract(tlDef);
2200 }
2202}
2203
2204
2205/****************************************************************************/
@ 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_TLID
link,node: the traffic light id responsible for this link
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_ID
@ SUMO_ATTR_RIGHT_OF_WAY
How to compute right of way.
@ GNE_ATTR_SHAPE_START
first coordinate of edge shape
@ SUMO_ATTR_TLLINKINDEX
link: the index of the link within the traffic light
@ SUMO_ATTR_KEEP_CLEAR
Whether vehicles must keep the junction clear.
@ SUMO_ATTR_POSITION
const unsigned char TLS[]
Definition TLS.cpp:22
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition ToString.h:283
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
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
const std::string getID() const
get ID (all Attribute Carriers have one)
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(......
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:753
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
A NBNetBuilder extended by visualisation and editing capabilities.
Definition GNENet.h:42
void deleteCrossing(GNECrossing *crossing, GNEUndoList *undoList)
remove crossing
Definition GNENet.cpp:694
NBNetBuilder * getNetBuilder() const
get net builder
Definition GNENet.cpp:1616
void addGLObjectIntoGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition GNENet.cpp:1440
GNEPathManager * getDataPathManager()
get data path manager
Definition GNENet.cpp:180
void removeGLObjectFromGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition GNENet.cpp:1450
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition GNENet.cpp:2199
void mergeJunctions(GNEJunction *moved, const GNEJunction *target, GNEUndoList *undoList)
merge the given junctions edges between the given junctions will be deleted
Definition GNENet.cpp:1168
GNEPathManager * getDemandPathManager()
get demand path manager
Definition GNENet.cpp:174
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:144
GNEPathManager * getNetworkPathManager()
get network path manager
Definition GNENet.cpp:168
void requireRecompute()
inform the net about the need for recomputation
Definition GNENet.cpp:1598
void addExplicitTurnaround(std::string id)
add edge id to the list of explicit turnarounds
Definition GNENet.cpp:2211
void deleteJunction(GNEJunction *junction, GNEUndoList *undoList)
removes junction and all incident edges
Definition GNENet.cpp:411
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2193
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)
GNEViewParent * getViewParent() const
get the net object
bool checkOverLockedElement(const GUIGlObject *GLObject, const bool isSelected) const
check if given element is locked (used for drawing select and delete contour)
GNEUndoList * getUndoList() const
get the undoList object
const GNEViewNetHelper::ViewObjectsSelector & getViewObjectsSelector() const
get objects under cursor
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:340
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
Definition NBNode.cpp:351
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:3047
SumoXMLNodeType getType() const
Returns the type of this node.
Definition NBNode.h:285
bool isTrafficLight() const
Definition NBNode.h:829
void setRightOfWay(RightOfWay rightOfWay)
set method for computing right-of-way
Definition NBNode.h:576
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition NBNode.cpp:2787
void invalidateIncomingConnections(bool reallowSetting=false)
invalidate incoming connections
Definition NBNode.cpp:2126
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:408
std::vector< std::pair< Position, std::string > > getEndPoints() const
return list of unique endpoint coordinates of all edges at this node
Definition NBNode.cpp:4381
const std::vector< std::unique_ptr< Crossing > > & getCrossingsIncludingInvalid() const
Definition NBNode.h:749
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:591
std::vector< Crossing * > getCrossings() const
return this junctions pedestrian crossings
Definition NBNode.cpp:3096
const std::string & getName() const
Returns intersection name.
Definition NBNode.h:310
void setRadius(double radius)
set the turning radius
Definition NBNode.h:566
void setName(const std::string &name)
set intersection name
Definition NBNode.h:586
const Position & getPosition() const
Definition NBNode.h:260
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
Definition NBNode.cpp:437
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:2781
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:4081
bool checkIsRemovableReporting(std::string &reason) const
check if node is removable and return reason if not
Definition NBNode.cpp:2668
const std::vector< WalkingArea > & getWalkingAreas() const
return this junctions pedestrian walking areas
Definition NBNode.h:754
PositionVector myPoly
the (outer) shape of the junction
Definition NBNode.h:962
void setFringeType(FringeType fringeType)
set method for computing right-of-way
Definition NBNode.h:581
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition NBNode.h:331
A traffic light logics which must be computed (only nodes/edges are given)
Definition NBOwnTLDef.h:44
void setLayout(TrafficLightLayout layout)
sets the layout for the generated signal plan
Definition NBOwnTLDef.h:143
The base class for traffic light logic definitions.
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
const std::string & getProgramID() const
Returns the ProgramID.
TrafficLightType getType() const
get the algorithm type (static etc..)
virtual void setProgramID(const std::string &programID)
Sets the programID.
virtual void addNode(NBNode *node)
Adds a node to the traffic light logic.
SUMOTime getOffset()
Returns the offset.
A container for traffic light definitions and built programs.
const std::map< std::string, NBTrafficLightDefinition * > & getPrograms(const std::string &id) const
Returns all programs for the given tl-id.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
void extract(NBTrafficLightDefinition *definition)
Extracts a traffic light definition from myDefinitions but keeps it in myExtracted for eventual * del...
A SUMO-compliant built logic for a traffic light.
static void computeTurnDirectionsForNode(NBNode *node, bool warn)
Computes turnaround destinations for all incoming edges of the given nodes (if any)
virtual void setID(const std::string &newID)
resets the id
Definition Named.h:82
const std::string & getID() const
Returns the id.
Definition Named.h:74
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
static OptionsCont & getOptions()
Retrieves the options.
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< 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:59
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