Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNEJunction.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
18// A class for visualizing and editing junctions in netedit (adapted from
19// GUIJunctionWrapper)
20/****************************************************************************/
21
25#include <netbuild/NBOwnTLDef.h>
41#include <netedit/GNENet.h>
43#include <netedit/GNEUndoList.h>
51
52#include "GNEConnection.h"
53#include "GNEJunction.h"
54#include "GNECrossing.h"
55#include "GNEWalkingArea.h"
56#include "GNEInternalLane.h"
57
58// ===========================================================================
59// method definitions
60// ===========================================================================
61
62#ifdef _MSC_VER
63#pragma warning(push)
64#pragma warning(disable: 4355) // mask warning about "this" in initializers
65#endif
66GNEJunction::GNEJunction(GNENet* net, NBNode* nbn, bool loaded) :
67 GNENetworkElement(net, nbn->getID(), SUMO_TAG_JUNCTION),
68 myMoveElementJunction(new GNEMoveElementJunction(this)),
69 myNBNode(nbn),
70 myDrawingToggle(new int),
71 myLogicStatus(loaded ? FEATURE_LOADED : FEATURE_GUESSED),
72 myHasValidLogic(loaded),
73 myTesselation(nbn->getID(), "", RGBColor::MAGENTA, nbn->getShape(), false, true, 0) {
74 // update centering boundary without updating grid
76}
77#ifdef _MSC_VER
78#pragma warning(pop)
79#endif
80
81
83 // delete drawing toggle
84 delete myDrawingToggle;
85 // delete all GNECrossing
86 for (const auto& crossing : myGNECrossings) {
87 crossing->decRef();
88 if (crossing->unreferenced()) {
89 // check if remove it from Attribute Carriers
90 if (myNet->getAttributeCarriers()->getCrossings().count(crossing) > 0) {
92 }
93 delete crossing;
94 }
95 }
96 // delete all GNEWalkingArea
97 for (const auto& walkingArea : myGNEWalkingAreas) {
98 walkingArea->decRef();
99 if (walkingArea->unreferenced()) {
100 // check if remove it from Attribute Carriers
101 if (myNet->getAttributeCarriers()->getWalkingAreas().count(walkingArea) > 0) {
103 }
104 delete walkingArea;
105 }
106 }
107 if (myAmResponsible) {
108 delete myNBNode;
109 }
110}
111
112
117
118
123
124
125const Parameterised*
127 return myNBNode;
128}
129
130
131const PositionVector&
133 return myNBNode->getShape();
134}
135
136
137void
140 // trigger rebuilding tesselation
141 myExaggeration = 2;
142}
143
144
145void
146GNEJunction::updateGeometryAfterNetbuild(bool rebuildNBNodeCrossings) {
147 // rebuild crossings
148 rebuildGNECrossings(rebuildNBNodeCrossings);
149 // clear walking areas
151 // clear missing connections
153}
154
155
160
161
162bool
164 // get modes and viewParent (for code legibility)
165 const auto& modes = myNet->getViewNet()->getEditModes();
166 const auto& viewParent = myNet->getViewParent();
167 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
168 // continue depending of current status
169 if (inspectedElements.isInspectingSingleElement()) {
170 const auto inspectedAC = inspectedElements.getFirstAC();
171 // check if starts in this junction
172 if (inspectedAC->hasAttribute(SUMO_ATTR_FROM_JUNCTION) &&
173 (inspectedAC->getAttribute(SUMO_ATTR_FROM_JUNCTION) == getID())) {
174 return true;
175 } else if ((inspectedAC->getTagProperty()->getTag() == SUMO_TAG_EDGE) &&
176 (inspectedAC->getAttribute(SUMO_ATTR_FROM) == getID())) {
177 return true;
178 } else if ((inspectedAC->getTagProperty()->getTag() == SUMO_TAG_LANE) &&
179 (inspectedAC->getAttribute(SUMO_ATTR_FROM_JUNCTION) == getID())) {
180 return true;
181 }
182 } else if (modes.isCurrentSupermodeNetwork()) {
183 if (modes.networkEditMode == NetworkEditMode::NETWORK_CREATE_EDGE) {
184 if (viewParent->getCreateEdgeFrame()->getJunctionSource()) {
185 return viewParent->getCreateEdgeFrame()->getJunctionSource() == this;
186 } else {
188 }
189 } else if ((modes.networkEditMode == NetworkEditMode::NETWORK_TLS) &&
190 viewParent->getTLSEditorFrame()->getTLSJunction()->isJoiningJunctions()) {
191 for (const auto& id : viewParent->getTLSEditorFrame()->getTLSJunction()->getSelectedJunctionIDs()) {
192 if (id == getMicrosimID()) {
193 return true;
194 }
195 }
196 }
197 } else if (modes.isCurrentSupermodeDemand()) {
198 // get current GNEPlanCreator
199 GNEPlanCreator* planCreator = nullptr;
200 if (modes.demandEditMode == DemandEditMode::DEMAND_PERSON) {
201 planCreator = viewParent->getPersonFrame()->getPlanCreator();
202 } else if (modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) {
203 planCreator = viewParent->getPersonPlanFrame()->getPlanCreator();
204 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) {
205 planCreator = viewParent->getContainerFrame()->getPlanCreator();
206 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) {
207 planCreator = viewParent->getContainerPlanFrame()->getPlanCreator();
208 }
209 // continue depending of planCreator
210 if (planCreator) {
211 if (planCreator->getPlanParameteres().fromJunction == getID()) {
212 return true;
213 }
214 } else if (modes.demandEditMode == DemandEditMode::DEMAND_VEHICLE) {
215 const auto& selectedJunctions = viewParent->getVehicleFrame()->getPathCreator()->getSelectedJunctions();
216 // check if this is the first selected junction
217 if ((selectedJunctions.size() > 0) && (selectedJunctions.front() == this)) {
218 return true;
219 }
220 }
221 }
222 // nothing to draw
223 return false;
224}
225
226
227bool
229 // get modes and viewParent (for code legibility)
230 const auto& modes = myNet->getViewNet()->getEditModes();
231 const auto& viewParent = myNet->getViewParent();
232 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
233 // continue depending of current status
234 if (inspectedElements.isInspectingSingleElement()) {
235 const auto inspectedAC = inspectedElements.getFirstAC();
236 // check if ends in this junction
237 if (inspectedAC->getTagProperty()->vehicleJunctions() &&
238 (inspectedAC->getAttribute(SUMO_ATTR_TO_JUNCTION) == getID())) {
239 return true;
240 } else if ((inspectedAC->getTagProperty()->getTag() == SUMO_TAG_EDGE) &&
241 (inspectedAC->getAttribute(SUMO_ATTR_TO) == getID())) {
242 return true;
243 } else if ((inspectedAC->getTagProperty()->getTag() == SUMO_TAG_LANE) &&
244 (inspectedAC->getAttribute(SUMO_ATTR_TO_JUNCTION) == getID())) {
245 return true;
246 }
247 } else if (modes.isCurrentSupermodeNetwork()) {
248 if (modes.networkEditMode == NetworkEditMode::NETWORK_CREATE_EDGE) {
249 if (viewParent->getCreateEdgeFrame()->getJunctionSource() &&
250 (viewParent->getCreateEdgeFrame()->getJunctionSource() != this)) {
252 }
253 } else if (modes.networkEditMode == NetworkEditMode::NETWORK_MOVE) {
254 // check if we're moving a junction
255 const auto moveElementJunction = dynamic_cast<GNEMoveElementJunction*>(myNet->getViewNet()->getMoveSingleElementValues().getMovedElement());
256 if (moveElementJunction && (moveElementJunction->getJunction() != this)) {
257 // continue depending of junction shape
258 if (myNBNode->getShape().area() < 4) {
259 // calculate distance between both centers
260 const double junctionBubbleRadius = myNet->getViewNet()->getVisualisationSettings().neteditSizeSettings.junctionBubbleRadius;
261 const double radiusTo = getExaggeration(myNet->getViewNet()->getVisualisationSettings()) * junctionBubbleRadius;
262 if (myNBNode->getPosition().distanceSquaredTo2D(moveElementJunction->getJunction()->getPositionInView()) < (radiusTo * radiusTo)) {
263 // add both it in the list of merging junction
264 gViewObjectsHandler.addMergingJunctions(moveElementJunction->getJunction());
266 return true;
267 }
268 } else if (myNBNode->getShape().around(moveElementJunction->getJunction()->getNBNode()->getPosition())) {
269 // add both it in the list of merging junction
270 gViewObjectsHandler.addMergingJunctions(moveElementJunction->getJunction());
272 return true;
273 }
274 }
275 }
276 } else if (modes.isCurrentSupermodeDemand()) {
277 // get current GNEPlanCreator
278 GNEPlanCreator* planCreator = nullptr;
279 if (modes.demandEditMode == DemandEditMode::DEMAND_PERSON) {
280 planCreator = viewParent->getPersonFrame()->getPlanCreator();
281 } else if (modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) {
282 planCreator = viewParent->getPersonPlanFrame()->getPlanCreator();
283 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) {
284 planCreator = viewParent->getContainerFrame()->getPlanCreator();
285 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) {
286 planCreator = viewParent->getContainerPlanFrame()->getPlanCreator();
287 }
288 // continue depending of planCreator
289 if (planCreator) {
290 if (planCreator->getPlanParameteres().toJunction == getID()) {
291 return true;
292 }
293 } else if (modes.demandEditMode == DemandEditMode::DEMAND_VEHICLE) {
294 const auto& selectedJunctions = viewParent->getVehicleFrame()->getPathCreator()->getSelectedJunctions();
295 // check if this is the first selected junction
296 if ((selectedJunctions.size() > 1) && (selectedJunctions.back() == this)) {
297 return true;
298 }
299 }
300 }
301 // nothing to draw
302 return false;
303}
304
305
306bool
309 return true;
310 }
311 // check opened popup
312 if (myNet->getViewNet()->getPopup()) {
313 return myNet->getViewNet()->getPopup()->getGLObject() == this;
314 }
315 return false;
316}
317
318
319bool
321 // get modes and viewParent (for code legibility)
322 const auto& modes = myNet->getViewNet()->getEditModes();
323 const auto& viewParent = myNet->getViewParent();
324 const auto& viewObjectsSelector = myNet->getViewNet()->getViewObjectsSelector();
325 if (viewObjectsSelector.getJunctionFront() != this) {
326 return false;
327 } else {
328 if (modes.isCurrentSupermodeNetwork()) {
329 if (modes.networkEditMode == NetworkEditMode::NETWORK_CROSSING) {
330 return (viewObjectsSelector.getJunctionFront() == this);
331 }
332 } else if (modes.isCurrentSupermodeDemand()) {
333 // get current plan selector
334 GNEPlanSelector* planSelector = nullptr;
335 if (modes.demandEditMode == DemandEditMode::DEMAND_PERSON) {
336 planSelector = viewParent->getPersonFrame()->getPlanSelector();
337 } else if (modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) {
338 planSelector = viewParent->getPersonPlanFrame()->getPlanSelector();
339 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) {
340 planSelector = viewParent->getContainerFrame()->getPlanSelector();
341 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) {
342 planSelector = viewParent->getContainerPlanFrame()->getPlanSelector();
343 }
344 // continue depending of plan selector
345 if (planSelector && planSelector->markJunctions()) {
346 return (viewObjectsSelector.getAttributeCarrierFront() == viewObjectsSelector.getJunctionFront());
347 } else if (modes.demandEditMode == DemandEditMode::DEMAND_VEHICLE) {
348 // get current vehicle template
349 const auto& vehicleTemplate = viewParent->getVehicleFrame()->getVehicleTagSelector()->getCurrentTemplateAC();
350 // check if vehicle can be placed over from-to TAZs
351 if (vehicleTemplate && vehicleTemplate->getTagProperty()->vehicleJunctions()) {
352 return (viewObjectsSelector.getAttributeCarrierFront() == viewObjectsSelector.getJunctionFront());
353 }
354 }
355 }
356 return false;
357 }
358}
359
360
361bool
363 // get edit modes
364 const auto& editModes = myNet->getViewNet()->getEditModes();
365 // check if we're in delete mode
366 if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_DELETE)) {
368 } else {
369 return false;
370 }
371}
372
373
374bool
376 return false;
377}
378
379
380bool
382 // get edit modes
383 const auto& editModes = myNet->getViewNet()->getEditModes();
384 // check if we're in select mode
385 if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_SELECT)) {
387 } else {
388 return false;
389 }
390}
391
392
393bool
395 // get edit modes
396 const auto& editModes = myNet->getViewNet()->getEditModes();
397 // check if we're in move mode
398 if (!myNet->getViewNet()->isCurrentlyMovingElements() && editModes.isCurrentSupermodeNetwork() &&
399 (editModes.networkEditMode == NetworkEditMode::NETWORK_MOVE) && myNet->getViewNet()->checkOverLockedElement(this, mySelected)) {
400 // check if we're editing this network element
402 if (editedNetworkElement) {
403 return editedNetworkElement == this;
404 } else {
405 // only move the first element
407 }
408 } else {
409 return false;
410 }
411}
412
413
414void
415GNEJunction::rebuildGNECrossings(bool rebuildNBNodeCrossings) {
416 // rebuild GNECrossings only if create crossings and walkingAreas in net is enabled
418 if (rebuildNBNodeCrossings) {
419 // build new NBNode::Crossings and walking areas
423 }
424 // create a vector to keep retrieved and created crossings
425 std::vector<GNECrossing*> retrievedCrossings;
426 // iterate over NBNode::Crossings of GNEJunction
427 for (const auto& crossing : myNBNode->getCrossingsIncludingInvalid()) {
428 // retrieve existent GNECrossing, or create it
429 GNECrossing* retrievedGNECrossing = retrieveGNECrossing(crossing.get());
430 retrievedCrossings.push_back(retrievedGNECrossing);
431 // check if previously this GNECrossings exists, and if true, remove it from myGNECrossings and insert in tree again
432 std::vector<GNECrossing*>::iterator retrievedExists = std::find(myGNECrossings.begin(), myGNECrossings.end(), retrievedGNECrossing);
433 if (retrievedExists != myGNECrossings.end()) {
434 myGNECrossings.erase(retrievedExists);
435 // update geometry of retrieved crossing
436 retrievedGNECrossing->updateGeometry();
437 // update boundary
438 retrievedGNECrossing->updateCenteringBoundary(false);
439 } else {
440 // include reference to created GNECrossing
441 retrievedGNECrossing->incRef();
442 }
443 }
444 // delete non retrieved GNECrossings (we don't need to extract if from Tree two times)
445 for (const auto& crossing : myGNECrossings) {
446 crossing->decRef();
447 // check if crossing is selected
448 if (crossing->isAttributeCarrierSelected()) {
449 crossing->unselectAttributeCarrier();
450 }
451 // remove it from inspected ACS
452 if (myNet->getViewNet()) {
454 }
455 // remove it from net
456 myNet->removeGLObjectFromGrid(crossing);
457 // remove it from attributeCarriers
459 if (crossing->unreferenced()) {
460 delete crossing;
461 }
462 }
463 // copy retrieved (existent and created) GNECrossings to myGNECrossings
464 myGNECrossings = retrievedCrossings;
465 }
466}
467
468
469void
471 if (OptionsCont::getOptions().getBool("lefthand")) {
472 myNBNode->mirrorX();
473 for (NBEdge* e : myNBNode->getEdges()) {
474 e->mirrorX();
475
476 }
477 }
478}
479
480
481void
482GNEJunction::buildTLSOperations(GUISUMOAbstractView& parent, GUIGLObjectPopupMenu* ret, const int numSelectedJunctions) {
483 // create menu pane for edge operations
484 FXMenuPane* TLSOperations = new FXMenuPane(ret);
485 ret->insertMenuPaneChild(TLSOperations);
486 new FXMenuCascade(ret, TL("TLS operations"), GUIIconSubSys::getIcon(GUIIcon::MODETLS), TLSOperations);
487 // create menu commands for all TLS operations
488 FXMenuCommand* mcAddTLS = GUIDesigns::buildFXMenuCommand(TLSOperations, TL("Add TLS"), nullptr, &parent, MID_GNE_JUNCTION_ADDTLS);
489 FXMenuCommand* mcAddJoinedTLS = GUIDesigns::buildFXMenuCommand(TLSOperations, TL("Add joined TLS"), nullptr, &parent, MID_GNE_JUNCTION_ADDJOINTLS);
490 // check if disable create TLS
491 if (myNBNode->getControllingTLS().size() > 0) {
492 mcAddTLS->disable();
493 mcAddJoinedTLS->disable();
494 } else {
495 mcAddTLS->enable();
496 // check if add joined TLS
497 if (isAttributeCarrierSelected() && (numSelectedJunctions > 1)) {
498 mcAddJoinedTLS->enable();
499 } else {
500 mcAddJoinedTLS->disable();
501 }
502 }
503}
504
505
508 if (myShapeEdited) {
509 return getShapeEditedPopUpMenu(app, parent, myNBNode->getShape());
510 } else {
511 // create popup
512 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
513 // build common options
515 // check if we're in supermode network
517 const int numSelectedJunctions = myNet->getAttributeCarriers()->getNumberOfSelectedJunctions();
518 const int numEndpoints = (int)myNBNode->getEndPoints().size();
519 // check if we're handling a selection
520 bool handlingSelection = isAttributeCarrierSelected() && (numSelectedJunctions > 1);
521 // check if menu commands has to be disabled
525 // build TLS operation
526 if (!invalidMode) {
527 buildTLSOperations(parent, ret, numSelectedJunctions);
528 }
529 // create menu commands
530 GUIDesigns::buildFXMenuCommand(ret, TL("Reset edge endpoints"), nullptr, &parent, MID_GNE_JUNCTION_RESET_EDGE_ENDPOINTS);
531 FXMenuCommand* mcCustomShape = GUIDesigns::buildFXMenuCommand(ret, TL("Set custom junction shape"), nullptr, &parent, MID_GNE_JUNCTION_EDIT_SHAPE);
532 FXMenuCommand* mcResetCustomShape = GUIDesigns::buildFXMenuCommand(ret, TL("Reset junction shape"), nullptr, &parent, MID_GNE_JUNCTION_RESET_SHAPE);
533 FXMenuCommand* mcReplaceByGeometryPoint = GUIDesigns::buildFXMenuCommand(ret, TL("Replace junction by geometry point"), nullptr, &parent, MID_GNE_JUNCTION_REPLACE);
534 FXMenuCommand* mcSplitJunction = GUIDesigns::buildFXMenuCommand(ret, TLF("Split junction (% end points)", numEndpoints), nullptr, &parent, MID_GNE_JUNCTION_SPLIT);
535 FXMenuCommand* mcSplitJunctionAndReconnect = GUIDesigns::buildFXMenuCommand(ret, TL("Split junction and reconnect"), nullptr, &parent, MID_GNE_JUNCTION_SPLIT_RECONNECT);
536 // check if is a roundabout
537 if (myNBNode->isRoundabout()) {
538 GUIDesigns::buildFXMenuCommand(ret, TL("Select roundabout"), nullptr, &parent, MID_GNE_JUNCTION_SELECT_ROUNDABOUT);
539 } else {
540 // get radius
541 const double radius = (myNBNode->getRadius() == NBNode::UNSPECIFIED_RADIUS) ? OptionsCont::getOptions().getFloat("default.junctions.radius") : myNBNode->getRadius();
542 const std::string menuEntryInfo = TLF("Convert to roundabout (using junction attribute radius %)", toString(radius));
543 FXMenuCommand* mcRoundabout = GUIDesigns::buildFXMenuCommand(ret, menuEntryInfo.c_str(), nullptr, &parent, MID_GNE_JUNCTION_CONVERT_ROUNDABOUT);
544 // check if disable depending of number of edges
545 if ((getChildEdges().size() < 2) ||
546 ((myGNEIncomingEdges.size() == 1) && (myGNEOutgoingEdges.size() == 1) && (myGNEIncomingEdges[0]->getFromJunction() == myGNEOutgoingEdges[0]->getToJunction()))) {
547 mcRoundabout->disable();
548 }
549 }
550 // check multijunctions
551 const std::string multi = ((numSelectedJunctions > 1) && isAttributeCarrierSelected()) ? TLF(" of % junctions", numSelectedJunctions) : "";
552 FXMenuCommand* mcClearConnections = GUIDesigns::buildFXMenuCommand(ret, TL("Clear connections") + multi, nullptr, &parent, MID_GNE_JUNCTION_CLEAR_CONNECTIONS);
553 FXMenuCommand* mcResetConnections = GUIDesigns::buildFXMenuCommand(ret, TL("Reset connections") + multi, nullptr, &parent, MID_GNE_JUNCTION_RESET_CONNECTIONS);
554 // check if current mode is correct
555 if (invalidMode) {
556 mcCustomShape->disable();
557 mcClearConnections->disable();
558 mcResetConnections->disable();
559 }
560 // check if we're handling a selection
561 if (handlingSelection) {
562 mcResetCustomShape->setText(TL("Reset junction shapes"));
563 }
564 // disable mcClearConnections if junction hasn't connections
565 if (getGNEConnections().empty()) {
566 mcClearConnections->disable();
567 }
568 // disable mcResetCustomShape if junction doesn't have a custom shape
569 if (myNBNode->getShape().size() == 0) {
570 mcResetCustomShape->disable();
571 }
572 // checkIsRemovable requires turnarounds to be computed. This is ugly
573 if ((myNBNode->getIncomingEdges().size() == 2) && (myNBNode->getOutgoingEdges().size() == 2)) {
575 }
576 std::string reason = TL("wrong edit mode");
577 if (invalidMode || !myNBNode->checkIsRemovableReporting(reason)) {
578 mcReplaceByGeometryPoint->setText(mcReplaceByGeometryPoint->getText() + " (" + reason.c_str() + ")");
579 mcReplaceByGeometryPoint->disable();
580 }
581 // check if disable split junctions
582 if (numEndpoints == 1) {
583 mcSplitJunction->disable();
584 mcSplitJunctionAndReconnect->disable();
585 }
586 }
587 return ret;
588 }
589}
590
591
592double
596
597
602
603
604void
606 // Remove object from grid
607 if (updateGrid) {
609 }
610 // calculate boundary using a radius bigger than geometry point
612 myNBNode->getPosition().x() + 1, myNBNode->getPosition().y() + 1);
614 // add shape
615 if (myNBNode->getShape().size() > 0) {
618 }
619 // add boundaries of all connections, walking areas and crossings
620 for (const auto& edge : myGNEIncomingEdges) {
621 for (const auto& connection : edge->getGNEConnections()) {
622 const auto boundary = connection->getCenteringBoundary();
623 if (boundary.isInitialised()) {
624 myJunctionBoundary.add(boundary);
625 }
626 }
627 }
628 for (const auto& crossing : myGNECrossings) {
629 const auto boundary = crossing->getCenteringBoundary();
630 if (boundary.isInitialised()) {
631 myJunctionBoundary.add(boundary);
632 }
633 }
634 for (const auto& walkingArea : myGNEWalkingAreas) {
635 const auto boundary = walkingArea->getCenteringBoundary();
636 if (boundary.isInitialised()) {
637 myJunctionBoundary.add(boundary);
638 }
639 }
640
641 // add object into grid
642 if (updateGrid) {
643 // if junction has at least one edge, then don't add in grid (because uses the edge's grid)
644 if (myGNEIncomingEdges.size() + myGNEOutgoingEdges.size() == 0) {
646 }
647 }
648 // trigger rebuilding tesselation
649 myExaggeration = 2;
650}
651
652
653void
655 // first check drawing toggle and boundary selection
657 // draw boundaries
658 if (inGrid()) {
660 }
661 // get junction exaggeration
662 const double junctionExaggeration = getExaggeration(s);
663 // only continue if exaggeration is greater than 0
664 if (junctionExaggeration > 0) {
665 // get detail level
666 const auto d = s.getDetailLevel(junctionExaggeration);
667 // get shape area
668 const double junctionShapeArea = myNBNode->getShape().area();
669 // check if draw junction as shape
670 const bool drawBubble = drawAsBubble(s, junctionShapeArea);
671 // draw geometry only if we'rent in drawForObjectUnderCursor mode
673 // push layer matrix
675 // translate to front
677 if (drawBubble) {
678 // draw junction as bubble
679 drawJunctionAsBubble(s, d, junctionExaggeration);
680 } else {
681 // draw junction as shape
682 drawJunctionAsShape(s, d, junctionExaggeration);
683 }
684 // draw junction center (only in move mode)
685 drawJunctionCenter(s, d);
686 // draw TLS
687 drawTLSIcon(s);
688 // draw elevation
689 drawElevation(s);
690 // pop layer Matrix
692 // draw lock icon
694 // draw junction name
696 // draw dotted contour depending if we're editing the custom shape
698 if (editedNetworkElement && (editedNetworkElement == this)) {
699 // draw dotted contour geometry points
701 junctionExaggeration, s.dottedContourSettings.segmentWidthSmall);
702 } else {
703 if (drawBubble) {
704 // draw dotted contour for bubble
706 } else {
707 // draw dotted contour for shape
708 if (junctionShapeArea >= 4) {
710 }
711 }
712 }
713 }
714 // calculate junction contour (always before children)
715 calculateJunctioncontour(s, d, junctionExaggeration, drawBubble);
716 // draw Junction childs
718 }
719 // update drawing toggle
721 }
722}
723
724
725void
727 // Check if edge can be deleted
730 }
731}
732
733
734void
738
739
740NBNode*
742 return myNBNode;
743}
744
745
746std::vector<GNEJunction*>
748 // use set to avoid duplicates junctions
749 std::set<GNEJunction*> junctions;
750 for (const auto& incomingEdge : myGNEIncomingEdges) {
751 junctions.insert(incomingEdge->getFromJunction());
752 }
753 for (const auto& outgoingEdge : myGNEOutgoingEdges) {
754 junctions.insert(outgoingEdge->getToJunction());
755 }
756 return std::vector<GNEJunction*>(junctions.begin(), junctions.end());
757}
758
759
760void
762 // Check if incoming edge was already inserted
763 std::vector<GNEEdge*>::iterator i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
764 if (i != myGNEIncomingEdges.end()) {
765 throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + getTagStr() + " with ID " + getID() + "'");
766 } else {
767 // Add edge into containers
768 myGNEIncomingEdges.push_back(edge);
769 }
770}
771
772
773
774void
776 // Check if outgoing edge was already inserted
777 const auto i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
778 if (i != myGNEOutgoingEdges.end()) {
779 throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + getTagStr() + " with ID " + getID() + "'");
780 } else {
781 // Add edge into containers
782 myGNEOutgoingEdges.push_back(edge);
783 }
784 // update centering boundary and grid
786}
787
788
789void
791 // Check if incoming edge was already inserted
792 auto i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
793 if (i == myGNEIncomingEdges.end()) {
794 throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + getTagStr() + " with ID " + getID() + "'");
795 } else {
796 // remove edge from containers
797 myGNEIncomingEdges.erase(i);
798 }
799 // update centering boundary and grid
801}
802
803
804void
806 // Check if outgoing edge was already inserted
807 std::vector<GNEEdge*>::iterator i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
808 if (i == myGNEOutgoingEdges.end()) {
809 throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + getTagStr() + " with ID " + getID() + "'");
810 } else {
811 // remove edge from containers
812 myGNEOutgoingEdges.erase(i);
813 }
814}
815
816
817const std::vector<GNEEdge*>&
821
822
823const std::vector<GNEEdge*>&
827
828
829const std::vector<GNECrossing*>&
833
834
835const std::vector<GNEWalkingArea*>&
839
840
841std::vector<GNEConnection*>
843 std::vector<GNEConnection*> connections;
844 for (const auto& incomingEdge : myGNEIncomingEdges) {
845 for (const auto& connection : incomingEdge->getGNEConnections()) {
846 connections.push_back(connection);
847 }
848 }
849 return connections;
850}
851
852
853void
857
858
859void
863
864
865void
867 myAmTLSSelected = selected;
868}
869
870
871void
873 if (!myNBNode->hasCustomShape()) {
874 if (myNBNode->myPoly.size() > 0) {
875 // clear poly
876 myNBNode->myPoly.clear();
877 // update centering boundary
879 }
881 }
882}
883
884
885void
886GNEJunction::setLogicValid(bool valid, GNEUndoList* undoList, const std::string& status) {
887 myHasValidLogic = valid;
888 if (!valid) {
889 assert(undoList != 0);
890 assert(undoList->hasCommandGroup());
893 for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
894 GNEEdge* srcEdge = myNet->getAttributeCarriers()->retrieveEdge((*it)->getID());
895 removeConnectionsFrom(srcEdge, undoList, false); // false, because the whole tls will be invalidated at the end
897 }
899 invalidateTLS(undoList);
900 } else {
901 // logic valed, then rebuild GNECrossings to adapt it to the new logic
902 // (but don't rebuild the crossings in NBNode because they are already finished)
903 rebuildGNECrossings(false);
904 }
905}
906
907
908void
909GNEJunction::removeConnectionsFrom(GNEEdge* edge, GNEUndoList* undoList, bool updateTLS, int lane) {
910 NBEdge* srcNBE = edge->getNBEdge();
911 NBEdge* turnEdge = srcNBE->getTurnDestination();
912 // Make a copy of connections
913 std::vector<NBEdge::Connection> connections = srcNBE->getConnections();
914 // delete in reverse so that undoing will add connections in the original order
915 for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) {
916 if (lane >= 0 && (*con_it).fromLane != lane) {
917 continue;
918 }
919 bool hasTurn = con_it->toEdge == turnEdge;
920 undoList->add(new GNEChange_Connection(edge, *con_it, false, false), true);
921 // needs to come after GNEChange_Connection
922 // XXX bug: this code path will not be used on a redo!
923 if (hasTurn) {
925 }
926 }
927 if (updateTLS) {
928 std::vector<NBConnection> removeConnections;
929 for (NBEdge::Connection con : connections) {
930 removeConnections.push_back(NBConnection(srcNBE, con.fromLane, con.toEdge, con.toLane));
931 }
932 removeTLSConnections(removeConnections, undoList);
933 }
934}
935
936
937void
938GNEJunction::removeConnectionsTo(GNEEdge* edge, GNEUndoList* undoList, bool updateTLS, int lane) {
939 NBEdge* destNBE = edge->getNBEdge();
940 std::vector<NBConnection> removeConnections;
941 for (NBEdge* srcNBE : myNBNode->getIncomingEdges()) {
942 GNEEdge* srcEdge = myNet->getAttributeCarriers()->retrieveEdge(srcNBE->getID());
943 std::vector<NBEdge::Connection> connections = srcNBE->getConnections();
944 for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) {
945 if ((*con_it).toEdge == destNBE) {
946 if (lane >= 0 && (*con_it).toLane != lane) {
947 continue;
948 }
949 bool hasTurn = srcNBE->getTurnDestination() == destNBE;
950 undoList->add(new GNEChange_Connection(srcEdge, *con_it, false, false), true);
951 // needs to come after GNEChange_Connection
952 // XXX bug: this code path will not be used on a redo!
953 if (hasTurn) {
954 myNet->addExplicitTurnaround(srcNBE->getID());
955 }
956 removeConnections.push_back(NBConnection(srcNBE, (*con_it).fromLane, destNBE, (*con_it).toLane));
957 }
958 }
959 }
960 if (updateTLS) {
961 removeTLSConnections(removeConnections, undoList);
962 }
963}
964
965
966void
967GNEJunction::removeTLSConnections(std::vector<NBConnection>& connections, GNEUndoList* undoList) {
968 if (connections.size() > 0) {
969 const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode->getControllingTLS(); // make a copy!
970 for (const auto& TLS : coypOfTls) {
971 NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
972 // guessed TLS (NBOwnTLDef) do not need to be updated
973 if (tlDef != nullptr) {
974 std::string newID = tlDef->getID();
975 // create replacement before deleting the original because deletion will mess up saving original nodes
976 NBLoadedSUMOTLDef* replacementDef = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
977 for (NBConnection& con : connections) {
978 replacementDef->removeConnection(con);
979 }
980 undoList->add(new GNEChange_TLS(this, tlDef, false), true);
981 undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
982 // the removed traffic light may have controlled more than one junction. These too have become invalid now
983 const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
984 for (const auto& node : copyOfNodes) {
985 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
986 undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
987 undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
988 }
989 }
990 }
991 }
992}
993
994
995void
997 // remap connections of the edge
998 assert(which->getChildLanes().size() == by->getChildLanes().size());
999 std::vector<NBEdge::Connection> connections = which->getNBEdge()->getConnections();
1000 for (NBEdge::Connection& c : connections) {
1001 undoList->add(new GNEChange_Connection(which, c, false, false), true);
1002 undoList->add(new GNEChange_Connection(by, c, false, true), true);
1003 }
1004 // also remap tls connections
1005 const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode->getControllingTLS(); // make a copy!
1006 for (const auto& TLS : coypOfTls) {
1007 NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
1008 // guessed TLS (NBOwnTLDef) do not need to be updated
1009 if (tlDef != nullptr) {
1010 std::string newID = tlDef->getID();
1011 // create replacement before deleting the original because deletion will mess up saving original nodes
1012 NBLoadedSUMOTLDef* replacementDef = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
1013 for (int i = 0; i < (int)which->getChildLanes().size(); ++i) {
1014 replacementDef->replaceRemoved(which->getNBEdge(), i, by->getNBEdge(), i, true);
1015 }
1016 undoList->add(new GNEChange_TLS(this, tlDef, false), true);
1017 undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
1018 // the removed traffic light may have controlled more than one junction. These too have become invalid now
1019 const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
1020 for (const auto& node : copyOfNodes) {
1021 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1022 undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
1023 undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
1024 }
1025 }
1026 }
1027}
1028
1029
1030void
1032 EdgeVector incoming = myNBNode->getIncomingEdges();
1033 for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
1034 NBEdge* srcNBE = *it;
1035 GNEEdge* srcEdge = myNet->getAttributeCarriers()->retrieveEdge(srcNBE->getID());
1037 }
1038}
1039
1040
1041void
1042GNEJunction::invalidateTLS(GNEUndoList* undoList, const NBConnection& deletedConnection, const NBConnection& addedConnection) {
1043 assert(undoList->hasCommandGroup());
1044 // NBLoadedSUMOTLDef becomes invalid, replace with NBOwnTLDef which will be dynamically recomputed
1045 const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode->getControllingTLS(); // make a copy!
1046 for (const auto& TLS : coypOfTls) {
1047 NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
1048 if (tlDef != nullptr) {
1049 // the removed traffic light may have controlled more than one junction. These too have become invalid now
1050 const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
1051 if (myGNECrossings.size() == 0 && getNBNode()->getCrossings().size() != 0) {
1052 // crossings were not computed yet. We need them as netedit elements to manage tlIndex resetting
1055 for (const auto& node : copyOfNodes) {
1056 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1057 if (sharing != this) {
1058 sharing->rebuildGNECrossings();
1059 }
1060 }
1061 }
1062 NBTrafficLightDefinition* replacementDef = nullptr;
1063 std::string newID = tlDef->getID(); // + "_reguessed"; // changes due to reguessing will be visible in diff
1064 if (deletedConnection != NBConnection::InvalidConnection) {
1065 // create replacement before deleting the original because deletion will mess up saving original nodes
1066 NBLoadedSUMOTLDef* repl = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
1067 repl->removeConnection(deletedConnection);
1068 replacementDef = repl;
1069 } else if (addedConnection != NBConnection::InvalidConnection) {
1070 if (addedConnection.getTLIndex() == NBConnection::InvalidTlIndex) {
1071 // custom tl indices of crossings might become invalid upon recomputation so we must save them
1072 // however, they could remain valid so we register a change but keep them at their old value
1073 for (const auto& crossing : myGNECrossings) {
1074 const std::string oldValue = crossing->getAttribute(SUMO_ATTR_TLLINKINDEX);
1076 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX, oldValue, undoList, true);
1077 const std::string oldValue2 = crossing->getAttribute(SUMO_ATTR_TLLINKINDEX2);
1079 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX2, oldValue2, undoList, true);
1080 }
1081 }
1082 NBLoadedSUMOTLDef* repl = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
1083 repl->addConnection(addedConnection.getFrom(), addedConnection.getTo(),
1084 addedConnection.getFromLane(), addedConnection.getToLane(), addedConnection.getTLIndex(), addedConnection.getTLIndex2());
1085 replacementDef = repl;
1086 } else {
1087 // recompute crossing indices along with everything else
1088 for (const auto& crossing : myGNECrossings) {
1091 }
1092 replacementDef = new NBOwnTLDef(newID, tlDef->getOffset(), tlDef->getType());
1093 replacementDef->setProgramID(tlDef->getProgramID());
1094 }
1095 undoList->add(new GNEChange_TLS(this, tlDef, false), true);
1096 undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
1097 // reset nodes of joint tls
1098 for (const auto& node : copyOfNodes) {
1099 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1100 if (sharing != this) {
1101 if (deletedConnection == NBConnection::InvalidConnection && addedConnection == NBConnection::InvalidConnection) {
1102 // recompute crossing indices for shared
1103 // (they won't do this on subsequent call to invalidateTLS if they received an NBOwnTLDef)
1104 for (const auto& crossing : sharing->getGNECrossings()) {
1107 }
1108 }
1109 undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
1110 undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
1111 }
1112 }
1113 }
1114 }
1115}
1116
1117void
1119 // obtain a copy of GNECrossing of junctions
1120 const auto copyOfGNECrossings = myGNECrossings;
1121 // iterate over copy of GNECrossings
1122 for (const auto& crossing : copyOfGNECrossings) {
1123 // obtain the set of edges vinculated with the crossing (due it works as ID)
1124 EdgeSet edgeSet(crossing->getCrossingEdges().begin(), crossing->getCrossingEdges().end());
1125 // If this edge is part of the set of edges of crossing
1126 if (edgeSet.count(edge->getNBEdge()) == 1) {
1127 // delete crossing if this is their last edge
1128 if ((crossing->getCrossingEdges().size() == 1) && (crossing->getCrossingEdges().front() == edge->getNBEdge())) {
1129 myNet->deleteCrossing(crossing, undoList);
1130 } else {
1131 // remove this edge of the edge's attribute of crossing (note: This can invalidate the crossing)
1132 std::vector<std::string> edges = GNEAttributeCarrier::parse<std::vector<std::string>>(crossing->getAttribute(SUMO_ATTR_EDGES));
1133 edges.erase(std::find(edges.begin(), edges.end(), edge->getID()));
1134 crossing->setAttribute(SUMO_ATTR_EDGES, joinToString(edges, " "), undoList);
1135 }
1136 }
1137 }
1138}
1139
1140
1141bool
1145
1146
1148GNEJunction::retrieveGNECrossing(NBNode::Crossing* NBNodeCrossing, bool createIfNoExist) {
1149 // iterate over all crossing
1150 for (const auto& crossing : myGNECrossings) {
1151 // if found, return it
1152 if (crossing->getCrossingEdges() == NBNodeCrossing->edges) {
1153 return crossing;
1154 }
1155 }
1156 if (createIfNoExist) {
1157 // create new GNECrossing
1158 GNECrossing* createdGNECrossing = new GNECrossing(this, NBNodeCrossing->edges);
1159 // update geometry after creating
1160 createdGNECrossing->updateGeometry();
1161 // add it in Network
1162 myNet->addGLObjectIntoGrid(createdGNECrossing);
1163 // add it in attributeCarriers
1164 myNet->getAttributeCarriers()->insertCrossing(createdGNECrossing);
1165 return createdGNECrossing;
1166 } else {
1167 return nullptr;
1168 }
1169}
1170
1171
1173GNEJunction::retrieveGNEWalkingArea(const std::string& NBNodeWalkingAreaID, bool createIfNoExist) {
1174 // iterate over all walkingArea
1175 for (const auto& walkingArea : myGNEWalkingAreas) {
1176 // if found, return it
1177 if (walkingArea->getID() == NBNodeWalkingAreaID) {
1178 return walkingArea;
1179 }
1180 }
1181 if (createIfNoExist) {
1182 // create new GNEWalkingArea
1183 GNEWalkingArea* createdGNEWalkingArea = new GNEWalkingArea(this, NBNodeWalkingAreaID);
1184 // update geometry after creating
1185 createdGNEWalkingArea->updateGeometry();
1186 // add it in Network
1187 myNet->addGLObjectIntoGrid(createdGNEWalkingArea);
1188 // add it in attributeCarriers
1189 myNet->getAttributeCarriers()->insertWalkingArea(createdGNEWalkingArea);
1190 return createdGNEWalkingArea;
1191 } else {
1192 return nullptr;
1193 }
1194}
1195
1196
1197void
1199 // only it's needed to mark the connections of incoming edges
1200 for (const auto& i : myGNEIncomingEdges) {
1201 for (const auto& j : i->getGNEConnections()) {
1202 j->markConnectionGeometryDeprecated();
1203 }
1204 if (includingNeighbours) {
1205 i->getFromJunction()->markConnectionsDeprecated(false);
1206 }
1207 }
1208}
1209
1210
1211void
1212GNEJunction::setJunctionType(const std::string& value, GNEUndoList* undoList) {
1213 undoList->begin(this, "change " + getTagStr() + " type");
1215 if (getNBNode()->isTLControlled() &&
1216 // if switching changing from or to traffic_light_right_on_red we need to remove the old plan
1219 ) {
1220 // make a copy because we will modify the original
1221 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1222 for (const auto& TLS : copyOfTls) {
1223 undoList->add(new GNEChange_TLS(this, TLS, false), true);
1224 }
1225 }
1226 if (!getNBNode()->isTLControlled()) {
1227 // create new traffic light
1228 undoList->add(new GNEChange_TLS(this, nullptr, true), true);
1229 }
1230 } else if (getNBNode()->isTLControlled()) {
1231 // delete old traffic light
1232 // make a copy because we will modify the original
1233 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1234 for (const auto& TLS : copyOfTls) {
1235 undoList->add(new GNEChange_TLS(this, TLS, false, false), true);
1236 const std::vector<NBNode*> copyOfNodes = TLS->getNodes(); // make a copy!
1237 for (const auto& node : copyOfNodes) {
1238 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1239 sharing->invalidateTLS(undoList);
1240 }
1241 }
1242 }
1243 // must be the final step, otherwise we do not know which traffic lights to remove via GNEChange_TLS
1244 GNEChange_Attribute::changeAttribute(this, SUMO_ATTR_TYPE, value, undoList, true);
1245 for (const auto& crossing : myGNECrossings) {
1246 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX, "-1", undoList, true);
1247 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX2, "-1", undoList, true);
1248 }
1249 undoList->end();
1250}
1251
1252
1253void
1255 // delete non retrieved GNEWalkingAreas (we don't need to extract if from Tree two times)
1256 for (const auto& walkingArea : myGNEWalkingAreas) {
1257 walkingArea->decRef();
1258 // check if walkingArea is selected
1259 if (walkingArea->isAttributeCarrierSelected()) {
1260 walkingArea->unselectAttributeCarrier();
1261 }
1262 // remove it from inspected ACS
1264 // remove it from net
1265 myNet->removeGLObjectFromGrid(walkingArea);
1266 // remove it from attributeCarriers
1268 if (walkingArea->unreferenced()) {
1269 delete walkingArea;
1270 }
1271 }
1272 myGNEWalkingAreas.clear();
1273}
1274
1275
1276void
1278 // first clear GNEWalkingAreas
1280 // iterate over NBNode::WalkingAreas of GNEJunction
1281 for (const auto& walkingArea : myNBNode->getWalkingAreas()) {
1282 // retrieve existent GNEWalkingArea, or create it
1283 GNEWalkingArea* retrievedGNEWalkingArea = retrieveGNEWalkingArea(walkingArea.id, true);
1284 // include reference to created GNEWalkingArea
1285 retrievedGNEWalkingArea->incRef();
1286 // update geometry of retrieved walkingArea
1287 retrievedGNEWalkingArea->updateGeometry();
1288 // update boundary
1289 retrievedGNEWalkingArea->updateCenteringBoundary(false);
1290 // add in walkingAreas
1291 myGNEWalkingAreas.push_back(retrievedGNEWalkingArea);
1292 }
1293}
1294
1295
1296
1297void
1299 if (std::find(myInternalLanes.begin(), myInternalLanes.end(), internalLane) != myInternalLanes.end()) {
1300 throw ProcessError(internalLane->getTagStr() + " with ID='" + internalLane->getID() + "' already exist");
1301 } else {
1302 myInternalLanes.push_back(internalLane);
1303 }
1304}
1305
1306
1307void
1309 const auto finder = std::find(myInternalLanes.begin(), myInternalLanes.end(), internalLane);
1310 if (finder == myInternalLanes.end()) {
1311 throw ProcessError(internalLane->getTagStr() + " with ID='" + internalLane->getID() + "' wasn't previously inserted");
1312 } else {
1313 myInternalLanes.erase(finder);
1314 }
1315}
1316
1317
1318std::string
1320 switch (key) {
1321 case SUMO_ATTR_ID:
1322 return getMicrosimID();
1323 case SUMO_ATTR_POSITION:
1324 return toString(myNBNode->getPosition());
1325 case SUMO_ATTR_TYPE:
1326 return toString(myNBNode->getType());
1328 return myLogicStatus;
1329 case SUMO_ATTR_SHAPE:
1330 return toString(myNBNode->getShape());
1331 case SUMO_ATTR_RADIUS:
1332 if (myNBNode->getRadius() < 0) {
1333 return "default";
1334 } else {
1335 return toString(myNBNode->getRadius());
1336 }
1337 case SUMO_ATTR_TLTYPE:
1339 // @todo this causes problems if the node were to have multiple programs of different type (plausible)
1340 return toString((*myNBNode->getControllingTLS().begin())->getType());
1341 } else {
1342 return "No TLS";
1343 }
1344 case SUMO_ATTR_TLLAYOUT:
1346 return toString((*myNBNode->getControllingTLS().begin())->getLayout());
1347 } else {
1348 return "No TLS";
1349 }
1350 case SUMO_ATTR_TLID:
1352 return toString((*myNBNode->getControllingTLS().begin())->getID());
1353 } else {
1354 return "No TLS";
1355 }
1359 // keep clear is only used as a convenience feature in plain xml
1360 // input. When saving to .net.xml the status is saved only for the connections
1361 // to show the correct state we must check all connections
1362 for (const auto& i : myGNEIncomingEdges) {
1363 for (const auto& j : i->getGNEConnections()) {
1364 if (j->getNBEdgeConnection().keepClear) {
1365 return TRUE_STR;
1366 }
1367 }
1368 }
1369 return FALSE_STR;
1372 case SUMO_ATTR_FRINGE:
1376 case SUMO_ATTR_NAME:
1377 return myNBNode->getName();
1378 default:
1379 return getCommonAttribute(key);
1380 }
1381}
1382
1383
1384double
1388
1389
1394
1395
1398 switch (key) {
1399 case SUMO_ATTR_SHAPE:
1400 return myNBNode->getShape();
1401 default:
1403 }
1404}
1405
1406
1407void
1408GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
1409 if (value == getAttribute(key)) {
1410 return; //avoid needless changes, later logic relies on the fact that attributes have changed
1411 }
1412 switch (key) {
1413 case SUMO_ATTR_ID:
1415 case SUMO_ATTR_SHAPE:
1416 case SUMO_ATTR_RADIUS:
1418 case SUMO_ATTR_FRINGE:
1420 case SUMO_ATTR_NAME:
1421 GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);
1422 break;
1423 case SUMO_ATTR_POSITION: {
1424 const GNEJunction* junctionToMerge = nullptr;
1425 bool alreadyAsked = false;
1426 // parse position
1427 Position newPosition = GNEAttributeCarrier::parse<Position>(value);
1428 // check if caculate new position based in edges
1429 if (newPosition == Position::INVALID) {
1430 Boundary b;
1431 // set new position of adjacent edges
1432 for (const auto& edge : myGNEIncomingEdges) {
1433 b.add(edge->getNBEdge()->getGeometry().back());
1434 }
1435 for (const auto& edge : myGNEOutgoingEdges) {
1436 b.add(edge->getNBEdge()->getGeometry().front());
1437 }
1438 newPosition = b.getCenter();
1439 }
1440 // retrieve all junctions placed in this position
1441 myNet->getViewNet()->updateObjectsInPosition(newPosition);
1442 for (const auto& junction : myNet->getViewNet()->getViewObjectsSelector().getJunctions()) {
1443 // check distance position
1444 if ((junctionToMerge == nullptr) && (junction != this) &&
1445 (junction->getPositionInView().distanceTo2D(newPosition) < myNet->getViewNet()->getVisualisationSettings().neteditSizeSettings.junctionBubbleRadius) &&
1446 myNet->getViewNet()->askMergeJunctions(this, junction, alreadyAsked)) {
1447 junctionToMerge = junction;
1448 }
1449 }
1450 // also check the merging junctions located during drawGL
1451 for (const auto& junction : myNet->getViewNet()->getViewObjectsSelector().getMergingJunctions()) {
1452 // check distance position
1453 if ((junctionToMerge == nullptr) && (junction != this) && myNet->getViewNet()->askMergeJunctions(this, junction, alreadyAsked)) {
1454 junctionToMerge = junction;
1455 }
1456 }
1457 // if we merge the junction, this junction will be removed, therefore we don't have to change the position
1458 if (junctionToMerge) {
1459 myNet->mergeJunctions(this, junctionToMerge, undoList);
1460 } else {
1461 // change Keep Clear attribute in all connections
1462 undoList->begin(this, TL("change junction position"));
1463 // obtain NBNode position
1464 const Position orig = myNBNode->getPosition();
1465 // change junction position
1466 GNEChange_Attribute::changeAttribute(this, key, toString(newPosition), undoList, true);
1467 // calculate delta using new position
1468 const bool moveOnlyCenter = myNet->getViewParent()->getMoveFrame()->getNetworkMoveOptions()->getMoveOnlyJunctionCenter();
1469 const Position delta = myNBNode->getPosition() - (moveOnlyCenter ? myNBNode->getPosition() : orig);
1470 // set new position of adjacent edges
1471 for (const auto& edge : myGNEIncomingEdges) {
1472 const Position newEnd = edge->getNBEdge()->getGeometry().back() + delta;
1474 }
1475 for (const auto& edge : myGNEOutgoingEdges) {
1476 const Position newStart = edge->getNBEdge()->getGeometry().front() + delta;
1477 GNEChange_Attribute::changeAttribute(edge, GNE_ATTR_SHAPE_START, toString(newStart), undoList, true);
1478 }
1479 undoList->end();
1480 }
1481 break;
1482 }
1484 // change Keep Clear attribute in all connections
1485 undoList->begin(this, TL("change keepClear for whole junction"));
1486 for (const auto& incomingEdge : myGNEIncomingEdges) {
1487 for (const auto& junction : incomingEdge->getGNEConnections()) {
1488 GNEChange_Attribute::changeAttribute(junction, key, value, undoList, true);
1489 }
1490 }
1491 undoList->end();
1492 break;
1493 case SUMO_ATTR_TYPE: {
1494 // set junction type
1495 setJunctionType(value, undoList);
1496 break;
1497 }
1498 case SUMO_ATTR_TLTYPE: {
1499 undoList->begin(this, "change " + getTagStr() + " tl-type");
1500 // make a copy because we will modify the original
1501 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1502 for (const auto& TLS : copyOfTls) {
1503 NBLoadedSUMOTLDef* oldLoaded = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
1504 if (oldLoaded != nullptr) {
1505 NBTrafficLightDefinition* newDef = nullptr;
1506 if (value == toString(TrafficLightType::NEMA) || oldLoaded->getType() == TrafficLightType::NEMA) {
1507 // rebuild the program because the old and new ones are incompatible
1508 newDef = new NBOwnTLDef(oldLoaded->getID(), oldLoaded->getOffset(), TrafficLightType::NEMA);
1509 newDef->setProgramID(oldLoaded->getProgramID());
1510 } else {
1511 NBLoadedSUMOTLDef* newLDef = new NBLoadedSUMOTLDef(*oldLoaded, *oldLoaded->getLogic());
1512 newLDef->guessMinMaxDuration(); // minDur and maxDur are never written for a static tls
1513 newDef = newLDef;
1514 }
1515 std::vector<NBNode*> nodes = TLS->getNodes();
1516 for (const auto& node : nodes) {
1517 GNEJunction* junction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1518 undoList->add(new GNEChange_TLS(junction, TLS, false), true);
1519 undoList->add(new GNEChange_TLS(junction, newDef, true), true);
1520 }
1521 }
1522 }
1523 GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);
1524 undoList->end();
1525 break;
1526 }
1527 case SUMO_ATTR_TLLAYOUT: {
1528 undoList->begin(this, "change " + getTagStr() + " tlLayout");
1529 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1530 for (const auto& oldTLS : copyOfTls) {
1531 std::vector<NBNode*> copyOfNodes = oldTLS->getNodes();
1532 NBOwnTLDef* newTLS = new NBOwnTLDef(oldTLS->getID(), oldTLS->getOffset(), oldTLS->getType());
1534 newTLS->setProgramID(oldTLS->getProgramID());
1535 for (const auto& node : copyOfNodes) {
1536 GNEJunction* oldJunction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1537 undoList->add(new GNEChange_TLS(oldJunction, oldTLS, false), true);
1538 }
1539 for (const auto& node : copyOfNodes) {
1540 GNEJunction* oldJunction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1541 undoList->add(new GNEChange_TLS(oldJunction, newTLS, true), true);
1542 }
1543 }
1544 undoList->end();
1545 break;
1546 }
1547 case SUMO_ATTR_TLID: {
1548 undoList->begin(this, "change " + toString(SUMO_TAG_TRAFFIC_LIGHT) + " id");
1549 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1550 assert(copyOfTls.size() > 0);
1551 NBTrafficLightDefinition* currentTLS = *copyOfTls.begin();
1552 NBTrafficLightDefinition* currentTLSCopy = nullptr;
1553 const bool currentIsSingle = currentTLS->getNodes().size() == 1;
1554 const bool currentIsLoaded = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS) != nullptr;
1555 if (currentIsLoaded) {
1556 currentTLSCopy = new NBLoadedSUMOTLDef(*currentTLS,
1557 *dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS)->getLogic());
1558 }
1559 // remove from previous tls
1560 for (const auto& TLS : copyOfTls) {
1561 undoList->add(new GNEChange_TLS(this, TLS, false), true);
1562 }
1564 // programs to which the current node shall be added
1565 const std::map<std::string, NBTrafficLightDefinition*> programs = tlCont.getPrograms(value);
1566 if (programs.size() > 0) {
1567 for (const auto& TLSProgram : programs) {
1568 NBTrafficLightDefinition* oldTLS = TLSProgram.second;
1569 if (dynamic_cast<NBOwnTLDef*>(oldTLS) != nullptr) {
1570 undoList->add(new GNEChange_TLS(this, oldTLS, true), true);
1571 } else {
1572 // delete and re-create the definition because the loaded phases are now invalid
1573 if (dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS) != nullptr &&
1574 dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->usingSignalGroups()) {
1575 // keep the old program and add all-red state for the added links
1576 NBLoadedSUMOTLDef* newTLSJoined = new NBLoadedSUMOTLDef(*oldTLS, *dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->getLogic());
1577 newTLSJoined->joinLogic(currentTLSCopy);
1578 undoList->add(new GNEChange_TLS(this, newTLSJoined, true, true), true);
1579 } else {
1580 undoList->add(new GNEChange_TLS(this, nullptr, true, false, value), true);
1581 }
1583 // switch from old to new definition
1584 std::vector<NBNode*> copyOfNodes = oldTLS->getNodes();
1585 for (const auto& node : copyOfNodes) {
1586 GNEJunction* oldJunction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1587 undoList->add(new GNEChange_TLS(oldJunction, oldTLS, false), true);
1588 undoList->add(new GNEChange_TLS(oldJunction, newTLS, true), true);
1589 }
1590 }
1591 }
1592 } else {
1593 if (currentIsSingle && currentIsLoaded) {
1594 // rename the traffic light but keep everything else
1595 NBTrafficLightLogic* renamedLogic = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLSCopy)->getLogic();
1596 renamedLogic->setID(value);
1597 NBLoadedSUMOTLDef* renamedTLS = new NBLoadedSUMOTLDef(*currentTLSCopy, *renamedLogic);
1598 renamedTLS->setID(value);
1599 undoList->add(new GNEChange_TLS(this, renamedTLS, true, true), true);
1600 } else {
1601 // create new traffic light
1602 undoList->add(new GNEChange_TLS(this, nullptr, true, false, value), true);
1603 }
1604 }
1605 delete currentTLSCopy;
1606 undoList->end();
1607 break;
1608 }
1609 default:
1610 setCommonAttribute(key, value, undoList);
1611 break;
1612 }
1613}
1614
1615
1616bool
1617GNEJunction::isValid(SumoXMLAttr key, const std::string& value) {
1618 switch (key) {
1619 case SUMO_ATTR_ID:
1620 return SUMOXMLDefinitions::isValidNetID(value) && (myNet->getAttributeCarriers()->retrieveJunction(value, false) == nullptr);
1621 case SUMO_ATTR_TYPE:
1623 case SUMO_ATTR_POSITION:
1624 if (value.empty()) {
1625 return (myGNEIncomingEdges.size() + myGNEOutgoingEdges.size()) > 0;
1626 } else {
1627 return canParse<Position>(value);
1628 }
1629 case SUMO_ATTR_SHAPE:
1630 // empty shapes are allowed
1631 return canParse<PositionVector>(value);
1632 case SUMO_ATTR_RADIUS:
1633 if (value.empty() || (value == "default")) {
1634 return true;
1635 } else {
1636 return canParse<double>(value) && ((parse<double>(value) >= 0) || (parse<double>(value) == -1));
1637 }
1638 case SUMO_ATTR_TLTYPE:
1640 case SUMO_ATTR_TLLAYOUT:
1642 case SUMO_ATTR_TLID:
1643 return myNBNode->isTLControlled() && (value != "");
1645 return canParse<bool>(value);
1648 case SUMO_ATTR_FRINGE:
1652 case SUMO_ATTR_NAME:
1653 return true;
1654 default:
1655 return isCommonAttributeValid(key, value);
1656 }
1657}
1658
1659
1660bool
1662 switch (key) {
1663 case SUMO_ATTR_TLTYPE:
1664 case SUMO_ATTR_TLLAYOUT:
1665 case SUMO_ATTR_TLID:
1666 return myNBNode->isTLControlled();
1667 case SUMO_ATTR_KEEP_CLEAR: {
1668 // check if at least there is an incoming connection
1669 for (const auto& incomingEdge : myGNEIncomingEdges) {
1670 if (incomingEdge->getGNEConnections().size() > 0) {
1671 return true;
1672 }
1673 }
1674 return false;
1675 }
1677 return false;
1678 default:
1679 return true;
1680 }
1681}
1682
1683
1684bool
1686 switch (key) {
1687 case SUMO_ATTR_SHAPE:
1688 return !myNBNode->hasCustomShape();
1689 default:
1690 return false;
1691 }
1692}
1693
1694
1695void
1697 myAmResponsible = newVal;
1698}
1699
1700// ===========================================================================
1701// private
1702// ===========================================================================
1703
1704bool
1705GNEJunction::drawAsBubble(const GUIVisualizationSettings& s, const double junctionShapeArea) const {
1706 const auto& editModes = myNet->getViewNet()->getEditModes();
1707 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
1708 // check conditions
1709 if (junctionShapeArea < 4) {
1710 // force draw if this junction is a candidate
1713 return true;
1714 }
1715 // force draw if we're in person/container plan mode
1716 if (editModes.isCurrentSupermodeDemand() &&
1717 ((editModes.demandEditMode == DemandEditMode::DEMAND_PERSON) ||
1718 (editModes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) ||
1719 (editModes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) ||
1720 (editModes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN))) {
1721 return true;
1722 }
1723 // force draw if we're inspecting a vehicle that start or ends in a junction
1724 if (inspectedElements.isInspectingSingleElement()) {
1725 // check if starts or ends in this junction
1726 if ((inspectedElements.getFirstAC()->hasAttribute(SUMO_ATTR_FROM_JUNCTION) &&
1727 (inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_FROM_JUNCTION) == getID())) ||
1728 (inspectedElements.getFirstAC()->hasAttribute(SUMO_ATTR_TO_JUNCTION) &&
1729 (inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_TO_JUNCTION) == getID()))) {
1730 return true;
1731 }
1732 }
1733 }
1734 if (!s.drawJunctionShape) {
1735 // don't draw bubble if it was disabled in GUIVisualizationSettings
1736 return false;
1737 }
1739 // force draw bubbles if we enabled option in checkbox of viewNet
1740 return true;
1741 }
1742 if (junctionShapeArea >= 4) {
1743 // don't draw if shape area is greater than 4
1744 return false;
1745 }
1746 if (!editModes.isCurrentSupermodeNetwork()) {
1747 // only draw bubbles in network mode
1748 return false;
1749 }
1750 return true;
1751}
1752
1753
1754void
1756 const double exaggeration) const {
1757 // calculate bubble radius
1758 const double bubbleRadius = s.neteditSizeSettings.junctionBubbleRadius * exaggeration;
1759 // set bubble color
1760 const RGBColor bubbleColor = setColor(s, true);
1761 if (bubbleColor.alpha() == 0) {
1762 // never draw when at full transparency (make sure no matrices have been pushed before return)
1763 return;
1764 }
1765 // push matrix
1767 // set color
1768 GLHelper::setColor(bubbleColor);
1769 // move matrix junction center
1770 glTranslated(myNBNode->getPosition().x(), myNBNode->getPosition().y(), 1.5);
1771 // draw filled circle
1772 GLHelper::drawFilledCircleDetailled(d, bubbleRadius);
1773 // pop matrix
1775}
1776
1777
1778void
1780 // first check drawing conditions
1781 if (s.drawJunctionShape && (myNBNode->getShape().size() > 0)) {
1782 // set shape color
1783 const RGBColor junctionShapeColor = setColor(s, false);
1784 if (junctionShapeColor.alpha() == 0) {
1785 // never draw when at full transparency (make sure no matrices have been pushed before return)
1786 return;
1787 }
1788 // set color
1789 GLHelper::setColor(junctionShapeColor);
1790 // adjust shape to exaggeration (check)
1791 if ((exaggeration > 1 || myExaggeration > 1) && exaggeration != myExaggeration) {
1792 myExaggeration = exaggeration;
1795 myTesselation.getShapeRef().scaleRelative(exaggeration);
1797 }
1798 // check if draw tesselation or or polygon
1800 // draw shape with high detail
1802 } else {
1803 // draw shape
1805 }
1806 // draw shape points only in Network supermode
1809 // set color
1810 const RGBColor darkerColor = junctionShapeColor.changedBrightness(-32);
1811 // calculate geometry
1812 GUIGeometry junctionGeometry;
1813 // obtain junction Shape
1814 PositionVector junctionOpenShape = myNBNode->getShape();
1815 // adjust shape to exaggeration
1816 if (exaggeration > 1) {
1817 junctionOpenShape.scaleRelative(exaggeration);
1818 }
1819 // update geometry
1820 junctionGeometry.updateGeometry(junctionOpenShape);
1821 // set color
1822 GLHelper::setColor(darkerColor);
1823 // draw shape
1825 // draw geometry points
1826 GUIGeometry::drawGeometryPoints(d, junctionOpenShape, darkerColor,
1829 }
1830 }
1831}
1832
1833
1834void
1837 // push matrix
1839 // set color
1840 GLHelper::setColor(setColor(s, true).changedBrightness(-20));
1841 // move matrix junction center
1842 glTranslated(myNBNode->getPosition().x(), myNBNode->getPosition().y(), 1.7);
1843 // draw filled circle
1845 // pop matrix
1847 }
1848}
1849
1850
1851void
1853 // draw TLS icon if isn't being drawn for selecting
1857 const Position pos = myNBNode->getPosition();
1858 glTranslated(pos.x(), pos.y(), 2.2);
1859 glColor3d(1, 1, 1);
1860 const double halfWidth = 32 / s.scale;
1861 const double halfHeight = 64 / s.scale;
1862 GUITexturesHelper::drawTexturedBox(GUITextureSubSys::getTexture(GUITexture::TLS), -halfWidth, -halfHeight, halfWidth, halfHeight);
1864 }
1865}
1866
1867
1868void
1870 // check if draw elevation
1873 // Translate to center of junction
1874 glTranslated(myNBNode->getPosition().x(), myNBNode->getPosition().y(), 0.1);
1875 // draw Z value
1878 }
1879}
1880
1881
1882void
1889
1890
1891void
1893 // draw crossings
1894 for (const auto& crossing : myGNECrossings) {
1895 crossing->drawGL(s);
1896 }
1897 // draw walking areas
1898 for (const auto& walkingArea : myGNEWalkingAreas) {
1899 walkingArea->drawGL(s);
1900 }
1901 // draw internalLanes
1902 for (const auto& internalLanes : myInternalLanes) {
1903 internalLanes->drawGL(s);
1904 }
1905 // draw connections
1906 for (const auto& incomingEdge : myGNEIncomingEdges) {
1907 for (const auto& connection : incomingEdge->getGNEConnections()) {
1908 connection->drawGL(s);
1909 }
1910 }
1911 // draw child demand elements
1912 for (const auto& demandElement : getChildDemandElements()) {
1913 demandElement->drawGL(s);
1914 }
1915 // draw child demand elements
1916 for (const auto& demandElement : getChildDemandElements()) {
1917 demandElement->drawGL(s);
1918 }
1919 // draw path additional elements
1923}
1924
1925
1926void
1928 const double exaggeration, const bool drawBubble) const {
1929 // if we're selecting using a boundary, first don't calculate contour bt check if edge boundary is within selection boundary
1931 // simply add object in ViewObjectsHandler with full boundary
1932 gViewObjectsHandler.selectObject(s, this, getType(), false, nullptr);
1933 } else {
1934 // always calculate for shape
1935 myNetworkElementContour.calculateContourClosedShape(s, d, this, myNBNode->getShape(), getType(), exaggeration, this);
1936 // check if calculate contour for bubble
1937 if (drawBubble) {
1939 }
1940 // check geometry points if we're editing shape
1941 if (myShapeEdited) {
1943 exaggeration, true);
1944 }
1945 }
1946}
1947
1948
1949void
1950GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value) {
1951 switch (key) {
1952 case SUMO_ATTR_KEEP_CLEAR: {
1953 throw InvalidArgument(toString(key) + " cannot be edited");
1954 }
1955 case SUMO_ATTR_ID: {
1957 break;
1958 }
1959 case SUMO_ATTR_TYPE: {
1964 }
1966 break;
1967 }
1968 case SUMO_ATTR_POSITION: {
1969 // set new position in NBNode updating edge boundaries
1970 moveJunctionGeometry(parse<Position>(value), true);
1971 // mark this connections and all of the junction's Neighbours as deprecated
1973 // update centering boundary and grid
1974 if (myGNEIncomingEdges.size() + myGNEOutgoingEdges.size() > 0) {
1976 } else {
1978 }
1979 break;
1980 }
1982 if (myLogicStatus == FEATURE_GUESSED && value != FEATURE_GUESSED) {
1983 // clear guessed connections. previous connections will be restored
1985 // Clear GNEConnections of incoming edges
1986 for (const auto& i : myGNEIncomingEdges) {
1987 i->clearGNEConnections();
1988 }
1989 }
1990 myLogicStatus = value;
1991 break;
1992 case SUMO_ATTR_SHAPE: {
1993 // set new shape (without updating grid)
1994 myNBNode->setCustomShape(parse<PositionVector>(value));
1995 // mark this connections and all of the junction's neighbors as deprecated
1997 // update centering boundary and grid
1999 break;
2000 }
2001 case SUMO_ATTR_RADIUS: {
2002 if (value.empty() || (value == "default")) {
2003 myNBNode->setRadius(-1);
2004 } else {
2005 myNBNode->setRadius(parse<double>(value));
2006 }
2007 break;
2008 }
2009 case SUMO_ATTR_TLTYPE: {
2010 // we need to make a copy of controlling TLS (because original will be updated)
2011 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
2012 for (const auto& TLS : copyOfTls) {
2013 TLS->setType(SUMOXMLDefinitions::TrafficLightTypes.get(value));
2014 }
2015 break;
2016 }
2017 case SUMO_ATTR_TLLAYOUT:
2018 // should not be triggered (handled via GNEChange_TLS)
2019 break;
2022 break;
2023 case SUMO_ATTR_FRINGE:
2025 break;
2028 break;
2029 case SUMO_ATTR_NAME:
2030 myNBNode->setName(value);
2031 break;
2032 default:
2033 setCommonAttribute(key, value);
2034 break;
2035 }
2036 // invalidate demand path calculator
2038}
2039
2040
2041double
2042GNEJunction::getColorValue(const GUIVisualizationSettings& /* s */, int activeScheme) const {
2043 switch (activeScheme) {
2044 case 0:
2046 return 3;
2047 } else {
2048 return 0;
2049 }
2050 case 1:
2052 case 2:
2053 switch (myNBNode->getType()) {
2055 return 0;
2057 return 1;
2059 return 2;
2061 return 3;
2063 return 4;
2065 return 5;
2067 return 6;
2069 return 7;
2072 return 8;
2074 return 8; // may happen before first network computation
2076 assert(false);
2077 return 8;
2079 return 9;
2081 return 10;
2083 return 11;
2085 return 12;
2087 return 13;
2088 default:
2089 assert(false);
2090 return 0;
2091 }
2092 case 3:
2093 return myNBNode->getPosition().z();
2094 default:
2095 assert(false);
2096 return 0;
2097 }
2098}
2099
2100void
2102 for (auto edge : myGNEIncomingEdges) {
2103 if (edge->getGNEConnections().size() > 0) {
2105 return;
2106 }
2107 }
2108 // no connections. Use normal color for border edges and cul-de-sac
2109 if (myGNEIncomingEdges.size() == 0 || myGNEOutgoingEdges.size() == 0) {
2111 return;
2112 } else if (myGNEIncomingEdges.size() == 1 && myGNEOutgoingEdges.size() == 1) {
2113 NBEdge* in = myGNEIncomingEdges[0]->getNBEdge();
2114 NBEdge* out = myGNEOutgoingEdges[0]->getNBEdge();
2115 if (in->isTurningDirectionAt(out)) {
2117 return;
2118 }
2119 }
2121}
2122
2123
2124void
2125GNEJunction::moveJunctionGeometry(const Position& pos, const bool updateEdgeBoundaries) {
2126 // reinit NBNode
2127 myNBNode->reinit(pos, myNBNode->getType());
2128 // declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
2129 std::set<GNEJunction*> affectedJunctions;
2130 std::set<GNEEdge*> affectedEdges;
2131 // Iterate over GNEEdges
2132 for (const auto& edge : getChildEdges()) {
2133 // Add source and destination junctions
2134 affectedJunctions.insert(edge->getFromJunction());
2135 affectedJunctions.insert(edge->getToJunction());
2136 // Obtain neighbors of Junction source
2137 for (const auto& junctionSourceEdge : edge->getFromJunction()->getChildEdges()) {
2138 affectedEdges.insert(junctionSourceEdge);
2139 }
2140 // Obtain neighbors of Junction destination
2141 for (const auto& junctionDestinationEdge : edge->getToJunction()->getChildEdges()) {
2142 affectedEdges.insert(junctionDestinationEdge);
2143 }
2144 }
2145 // reset walking areas of affected edges
2146 for (const auto& affectedJunction : affectedJunctions) {
2147 affectedJunction->clearWalkingAreas();
2148 }
2149 // Iterate over affected Edges
2150 for (const auto& affectedEdge : affectedEdges) {
2151 // update edge boundaries
2152 if (updateEdgeBoundaries) {
2153 affectedEdge->updateCenteringBoundary(true);
2154 }
2155 // Update edge geometry
2156 affectedEdge->updateGeometry();
2157 }
2158}
2159
2160
2163 // get active scheme
2164 const int scheme = s.junctionColorer.getActive();
2165 // first check if we're editing shape
2166 if (myShapeEdited) {
2167 return s.junctionColorer.getScheme().getColor(4);
2168 }
2169 // set default color
2171 // set special bubble color
2172 if (bubble && (scheme == 0) && !myColorForMissingConnections) {
2173 color = s.junctionColorer.getScheme().getColor(1);
2174 }
2175 // override with special colors (unless the color scheme is based on selection)
2176 if (drawUsingSelectColor() && scheme != 1) {
2177 color = s.colorSettings.selectionColor;
2178 }
2179 // overwrite color if we're in data mode
2181 color = s.junctionColorer.getScheme().getColor(6);
2182 }
2183 // special color for source candidate junction
2184 if (mySourceCandidate) {
2186 }
2187 // special color for target candidate junction
2188 if (myTargetCandidate) {
2190 }
2191 // special color for special candidate junction
2192 if (mySpecialCandidate) {
2194 }
2195 // special color for possible candidate junction
2196 if (myPossibleCandidate) {
2198 }
2199 // special color for conflicted candidate junction
2202 }
2203 // return color
2204 return color;
2205}
2206
2207
2208void
2211 tlCont.insert(tlDef, forceInsert); // may return false for tlDef which controls multiple junctions
2212 tlDef->addNode(myNBNode);
2213}
2214
2215
2216void
2219 if (tlDef->getNodes().size() == 1) {
2220 tlCont.extract(tlDef);
2221 }
2223}
2224
2225
2226/****************************************************************************/
@ NETWORK_DELETE
mode for deleting network elements
@ NETWORK_MOVE
mode for moving network elements
@ NETWORK_CREATE_EDGE
mode for creating new edges
@ NETWORK_TLS
mode for editing tls
@ NETWORK_CROSSING
Mode for editing crossing.
@ NETWORK_SELECT
mode for selecting network elements
@ NETWORK_CONNECT
mode for connecting lanes
@ DEMAND_PERSONPLAN
Mode for editing person plan.
@ DEMAND_CONTAINER
Mode for editing container.
@ DEMAND_PERSON
Mode for editing person.
@ DEMAND_VEHICLE
Mode for editing vehicles.
@ DEMAND_CONTAINERPLAN
Mode for editing container plan.
@ MID_GNE_JUNCTION_ADDTLS
Add TLS into junction.
@ MID_GNE_JUNCTION_RESET_EDGE_ENDPOINTS
reset edge endpoints
@ MID_GNE_JUNCTION_CLEAR_CONNECTIONS
clear junction's connections
@ MID_GNE_JUNCTION_SELECT_ROUNDABOUT
select all roundabout nodes and edges of the current roundabout
@ MID_GNE_JUNCTION_RESET_SHAPE
reset junction shape
@ MID_GNE_JUNCTION_RESET_CONNECTIONS
reset junction's connections
@ MID_GNE_JUNCTION_SPLIT
turn junction into multiple junctions
@ MID_GNE_JUNCTION_REPLACE
turn junction into geometry node
@ MID_GNE_JUNCTION_CONVERT_ROUNDABOUT
convert junction to roundabout
@ MID_GNE_JUNCTION_SPLIT_RECONNECT
turn junction into multiple junctions and reconnect them heuristically
@ MID_GNE_JUNCTION_EDIT_SHAPE
edit junction shape
@ MID_GNE_JUNCTION_ADDJOINTLS
Add join TLS into junctions.
@ GLO_MAX
empty max
@ GLO_JUNCTION
a junction
GUIViewObjectsHandler gViewObjectsHandler
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
std::set< NBEdge * > EdgeSet
container for unique edges
Definition NBCont.h:50
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition NBCont.h:42
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ SUMO_TAG_TRAFFIC_LIGHT
a traffic light
@ SUMO_TAG_EDGE
begin/end of the description of an edge
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_TLLINKINDEX2
link: the index of the opposite direction link of a pedestrian crossing
@ SUMO_ATTR_FROM_JUNCTION
@ SUMO_ATTR_RADIUS
The turning radius at an intersection in m.
@ SUMO_ATTR_TO_JUNCTION
@ SUMO_ATTR_TLLAYOUT
node: the layout of the traffic light program
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_FRINGE
Fringe type of node.
@ GNE_ATTR_MODIFICATION_STATUS
whether a feature has been loaded,guessed,modified or approved
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_TLTYPE
node: the type of traffic light
@ SUMO_ATTR_NAME
@ GNE_ATTR_IS_ROUNDABOUT
@ GNE_ATTR_SHAPE_END
last coordinate of edge shape
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_ROUNDABOUT
Roundabout type of node.
@ SUMO_ATTR_TLID
link,node: the traffic light id responsible for this link
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_ID
@ SUMO_ATTR_RIGHT_OF_WAY
How to compute right of way.
@ GNE_ATTR_SHAPE_START
first coordinate of edge shape
@ SUMO_ATTR_TLLINKINDEX
link: the index of the link within the traffic light
@ SUMO_ATTR_KEEP_CLEAR
Whether vehicles must keep the junction clear.
@ SUMO_ATTR_POSITION
const unsigned char TLS[]
Definition TLS.cpp:22
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition ToString.h:314
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
Position getCenter() const
Returns the center of the boundary.
Definition Boundary.cpp:109
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition Boundary.cpp:75
Boundary & grow(double by)
extends the boundary by the given amount
Definition Boundary.cpp:340
std::string fromJunction
from junction
static void drawFilledPoly(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition GLHelper.cpp:204
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition GLHelper.cpp:649
static void popMatrix()
pop matrix
Definition GLHelper.cpp:131
static void drawBoundary(const GUIVisualizationSettings &s, const Boundary &b)
Draw a boundary (used for debugging)
Definition GLHelper.cpp:952
static void drawFilledCircleDetailled(const GUIVisualizationSettings::Detail d, const double radius)
Draws a filled circle around (0,0) depending of level of detail.
Definition GLHelper.cpp:534
static void pushMatrix()
push matrix
Definition GLHelper.cpp:118
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0, const int align=0, double width=-1)
Definition GLHelper.cpp:742
static void drawTextSettings(const GUIVisualizationTextSettings &settings, const std::string &text, const Position &pos, const double scale, const double angle=0, const double layer=2048, const int align=0)
Definition GLHelper.cpp:773
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
double getCommonAttributeDouble(SumoXMLAttr key) const
bool mySelected
boolean to check if this AC is selected (more quickly as checking GUIGlObjectStorage)
static const std::string FALSE_STR
true value in string format(used for comparing boolean values in getAttribute(...))
static const std::string TRUE_STR
true value in string format (used for comparing boolean values in getAttribute(......
const std::string getID() const override
get ID (all Attribute Carriers have one)
PositionVector getCommonAttributePositionVector(SumoXMLAttr key) const
void setCommonAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
const std::string & getTagStr() const
get tag assigned to this object in string format
static const std::string FEATURE_GUESSED
feature has been reguessed (may still be unchanged be we can't tell (yet)
bool drawUsingSelectColor() const
check if attribute carrier must be drawn using selecting color.
void drawInLayer(const double typeOrLayer, const double extraOffset=0) const
draw element in the given layer, or in front if corresponding flag is enabled
Position getCommonAttributePosition(SumoXMLAttr key) const
GNENet * myNet
pointer to net
bool inGrid() const
check if this AC was inserted in grid
static const std::string FEATURE_MODIFIED
feature has been manually modified (implies approval)
bool isCommonAttributeValid(SumoXMLAttr key, const std::string &value) const
std::string getCommonAttribute(SumoXMLAttr key) const
const GNETagProperties * myTagProperty
reference to tagProperty associated with this attribute carrier
bool myPossibleCandidate
flag to mark this element as possible candidate
bool mySpecialCandidate
flag to mark this element as special candidate
bool myTargetCandidate
flag to mark this element as target candidate
bool myConflictedCandidate
flag to mark this element as conflicted candidate
bool mySourceCandidate
flag to mark this element as source candidate
static void changeAttribute(GNEAttributeCarrier *AC, SumoXMLAttr key, const std::string &value, GNEUndoList *undoList, const bool force=false)
change attribute
void drawDottedContourGeometryPoints(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GNEAttributeCarrier *AC, const PositionVector &shape, const double radius, const double scale, const double lineWidth) const
draw dotted contour for geometry points
void calculateContourCircleShape(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GUIGlObject *glObject, const Position &pos, double radius, const double layer, const double scale, const GUIGlObject *boundaryParent) const
calculate contour (circle elements)
void calculateContourClosedShape(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GUIGlObject *glObject, const PositionVector &shape, const double layer, const double scale, const GUIGlObject *boundaryParent, const bool addToSelectedObjects=true) const
calculate contours
bool drawDottedContours(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GNEAttributeCarrier *AC, const double lineWidth, const bool addOffset) const
draw dotted contours (basics, select, delete, inspect...)
void calculateContourAllGeometryPoints(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GUIGlObject *glObject, const PositionVector &shape, const double layer, const double radius, const double scale, const bool calculatePosOverShape) const
calculate contour for all geometry points
GNEJunction * getCurrentJunction() const
get current junction
GNECrossingFrame::EdgesSelector * getEdgesSelector() const
get edge selector modul
void updateCenteringBoundary(const bool updateGrid)
update centering boundary (implies change in RTREE)
void updateGeometry() override
update pre-computed geometry information
struct for saving subordinated elements (Junction->Edge->Lane->(Additional | DemandElement)
ProtectElements * getProtectElements() const
get protect elements modul
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition GNEEdge.cpp:773
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 drawJunctionChildren(const GUIVisualizationSettings &s) const
draw junction childs
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
bool drawAsBubble(const GUIVisualizationSettings &s, const double junctionShapeArea) const
check if draw junction as bubble
NBNode * getNBNode() const
Return net build node.
void drawJunctionCenter(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d) const
draw junction center (only in move mode)
void drawElevation(const GUIVisualizationSettings &s) const
draw elevation
NBNode * myNBNode
A reference to the represented junction.
Parameterised * getParameters() override
get parameters associated with this junction
GNEMoveElement * getMoveElement() const override
methods to retrieve the elements linked to this junction
int * myDrawingToggle
drawing toggle (used to avoid double draws)
void checkMissingConnections()
compute whether this junction probably should have some connections but doesn't
std::vector< GNEJunction * > getJunctionNeighbours() const
return GNEJunction neighbours
double getAttributeDouble(SumoXMLAttr key) const override
void setJunctionType(const std::string &value, GNEUndoList *undoList)
set junction Type (using undo/redo)
void drawJunctionAsShape(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const double exaggeration) const
draw junction as bubble
double myExaggeration
exaggeration used in tesselation
~GNEJunction()
Destructor.
void setLogicValid(bool valid, GNEUndoList *undoList, const std::string &status=FEATURE_GUESSED)
std::vector< GNEWalkingArea * > myGNEWalkingAreas
the built walkingArea objects
void removeConnectionsTo(GNEEdge *edge, GNEUndoList *undoList, bool updateTLS, int lane=-1)
remove all connections to the given edge
bool myAmCreateEdgeSource
whether this junction is the first junction for a newly creatededge
void buildTLSOperations(GUISUMOAbstractView &parent, GUIGLObjectPopupMenu *ret, const int numSelectedJunctions)
build TLS operations contextual menu
void addOutgoingGNEEdge(GNEEdge *edge)
add outgoing GNEEdge
void rebuildGNECrossings(bool rebuildNBNodeCrossings=true)
rebuilds crossing objects for this junction
void deleteGLObject() override
delete element
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
removes a traffic light
bool getMoveOnlyJunctionCenter() const
check if option "move only junction center" is enabled
NetworkMoveOptions * getNetworkMoveOptions() const
get network mode options
void insertWalkingArea(GNEWalkingArea *walkingArea)
insert walkingArea in container
const std::unordered_map< const GUIGlObject *, GNECrossing * > & getCrossings() const
get crossings
GNEJunction * retrieveJunction(const std::string &id, bool hardFail=true) const
get junction by id
void updateJunctionID(GNEJunction *junction, const std::string &newID)
update junction ID in container
void insertCrossing(GNECrossing *crossing)
insert crossing in container
void deleteWalkingArea(GNEWalkingArea *walkingArea)
delete walkingArea from container
int getNumberOfSelectedJunctions() const
get number of selected junctions
GNEEdge * retrieveEdge(const std::string &id, bool hardFail=true) const
get edge by id
const std::unordered_map< const GUIGlObject *, GNEWalkingArea * > & getWalkingAreas() const
get walkingAreas
void deleteCrossing(GNECrossing *crossing)
delete crossing from container
void deleteCrossing(GNECrossing *crossing, GNEUndoList *undoList)
remove crossing
Definition GNENet.cpp:721
NBNetBuilder * getNetBuilder() const
get net builder
Definition GNENet.cpp:168
void addGLObjectIntoGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition GNENet.cpp:1449
GNEPathManager * getDataPathManager()
get data path manager
Definition GNENet.cpp:204
void removeGLObjectFromGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition GNENet.cpp:1459
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition GNENet.cpp:2203
void mergeJunctions(GNEJunction *moved, const GNEJunction *target, GNEUndoList *undoList)
merge the given junctions edges between the given junctions will be deleted
Definition GNENet.cpp:1195
GNEPathManager * getDemandPathManager()
get demand path manager
Definition GNENet.cpp:198
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:174
GNEPathManager * getNetworkPathManager()
get network path manager
Definition GNENet.cpp:192
void requireRecompute()
inform the net about the need for recomputation
Definition GNENet.cpp:1619
GNEViewParent * getViewParent() const
get view parent (used for simplify code)
Definition GNENet.cpp:150
void addExplicitTurnaround(std::string id)
add edge id to the list of explicit turnarounds
Definition GNENet.cpp:2215
void deleteJunction(GNEJunction *junction, GNEUndoList *undoList)
removes junction and all incident edges
Definition GNENet.cpp:438
GNEUndoList * getUndoList() const
get undo list(used for simplify code)
Definition GNENet.cpp:156
GNEViewNet * getViewNet() const
get view net (used for simplify code)
Definition GNENet.cpp:144
bool checkDrawingBoundarySelection() const
GNEContour myNetworkElementContour
network element contour
bool myShapeEdited
flag to check if element shape is being edited
GUIGLObjectPopupMenu * getShapeEditedPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent, const PositionVector &shape)
get shape edited popup menu
void invalidatePathCalculator()
invalidate pathCalculator
PathCalculator * getPathCalculator()
obtain instance of PathCalculator
void drawJunctionPathElements(const GUIVisualizationSettings &s, const GNEJunction *junction) const
draw junction path elements
const CommonXMLStructure::PlanParameters & getPlanParameteres() const
get plan parameters
bool markJunctions() const
check if mark junctions with dotted contours
void incRef(const std::string &debugMsg="")
Increase reference.
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
void end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
bool hasCommandGroup() const
Check if undoList has command group.
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
void add(GNEChange *command, bool doit=false, bool merge=true)
Add new command, executing it if desired. The new command will be merged with the previous command if...
GNEAttributeCarrier * getFirstAC() const
void uninspectAC(GNEAttributeCarrier *AC)
uninspect AC
const std::vector< const GNEJunction * > & getMergingJunctions() const
get merging junctions
const GUIGlObject * getGUIGlObjectFront() const
get front GUIGLObject or a pointer to nullptr
GNEJunction * getJunctionFront() const
get front junction or a pointer to nullptr
const std::vector< GNEJunction * > & getJunctions() const
get vector with junctions
bool isCurrentlyMovingElements() const
check if an element is being moved
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
const GNEViewNetHelper::EditNetworkElementShapes & getEditNetworkElementShapes() const
get Edit Shape module
void updateObjectsInPosition(const Position &pos)
update objects and boundaries in position
GNEViewNetHelper::InspectedElements & getInspectedElements()
get inspected elements
const GNEViewNetHelper::MoveSingleElementModul & getMoveSingleElementValues() const
get move single element values
bool askMergeJunctions(const GNEJunction *movedJunction, const GNEJunction *targetJunction, bool &alreadyAsked)
ask merge junctions
bool showJunctionAsBubbles() const
return true if junction must be showed as bubbles
const GNEViewNetHelper::NetworkViewOptions & getNetworkViewOptions() const
get network view options
int getDrawingToggle() const
get draw toggle (used to avoid drawing junctions twice)
bool checkOverLockedElement(const GUIGlObject *GLObject, const bool isSelected) const
check if given element is locked (used for drawing select and delete contour)
const GNEViewNetHelper::ViewObjectsSelector & getViewObjectsSelector() const
get objects under cursor
GNECrossingFrame * getCrossingFrame() const
get frame for NETWORK_CROSSING
GNEMoveFrame * getMoveFrame() const
get frame for move elements
GNEDeleteFrame * getDeleteFrame() const
get frame for delete elements
void updateCenteringBoundary(const bool updateGrid)
update centering boundary (implies change in RTREE)
void updateGeometry() override
update pre-computed geometry information
static FXMenuCommand * buildFXMenuCommand(FXComposite *p, const std::string &text, FXIcon *icon, FXObject *tgt, FXSelector sel, const bool disable=false)
build menu command
The popup menu of a globject.
void insertMenuPaneChild(FXMenuPane *child)
Insert a sub-menu pane in this GUIGLObjectPopupMenu.
GUIGlObject * getGLObject() const
The object that belongs to this popup-menu.
static void drawGeometryPoints(const GUIVisualizationSettings::Detail d, const PositionVector &shape, const RGBColor &color, const double radius, const double exaggeration, const bool editingElevation)
draw geometry points
static void drawGeometry(const GUIVisualizationSettings::Detail d, const GUIGeometry &geometry, const double width, double offset=0)
draw geometry
void updateGeometry(const PositionVector &shape)
update entire geometry
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
void buildPopUpMenuCommonOptions(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, GUISUMOAbstractView *parent, const SumoXMLTag tag, const bool selected, bool addSeparator=true)
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0, bool forceShow=false) const
draw name of item
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
T getColor(const double value) const
const GUIVisualizationSettings & getVisualisationSettings() const
get visualization settings (read only)
GUIGLObjectPopupMenu * getPopup() const
ge the current popup-menu
static GUIGlID getTexture(GUITexture which)
returns a texture previously defined in the enum GUITexture
static void drawTexturedBox(int which, double size)
Draws a named texture as a box with the given size.
bool selectObject(const GUIVisualizationSettings &s, const GUIGlObject *GLObject, const double layer, const bool checkDuplicated, const GNESegment *segment)
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
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:3808
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition NBEdge.cpp:4170
A loaded (complete) traffic light logic.
void setID(const std::string &newID)
resets the id
NBTrafficLightLogic * getLogic()
Returns the internal logic.
void removeConnection(const NBConnection &conn, bool reconstruct=true)
removes the given connection from the traffic light if recontruct=true, reconstructs the logic and in...
void joinLogic(NBTrafficLightDefinition *def)
join nodes and states from the given logic (append red state)
void addConnection(NBEdge *from, NBEdge *to, int fromLane, int toLane, int linkIndex, int linkIndex2, bool reconstruct=true)
Adds a connection and immediately informs the edges.
void guessMinMaxDuration()
heuristically add minDur and maxDur when switching from tlType fixed to actuated
void replaceRemoved(NBEdge *removed, int removedLane, NBEdge *by, int byLane, bool incoming)
Replaces a removed edge/lane.
bool haveNetworkCrossings()
notify about style of loaded network (Without Crossings)
void setHaveNetworkCrossings(bool value)
enable crossing in networks
NBEdgeCont & getEdgeCont()
A definition of a pedestrian crossing.
Definition NBNode.h:135
EdgeVector edges
The edges being crossed.
Definition NBNode.h:142
Represents a single node (junction) during network building.
Definition NBNode.h:66
RightOfWay getRightOfWay() const
Returns hint on how to compute right of way.
Definition NBNode.h:300
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node (The set of tls that control this node)
Definition NBNode.h:345
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
Definition NBNode.cpp:353
static const double UNSPECIFIED_RADIUS
unspecified lane width
Definition NBNode.h:220
FringeType getFringeType() const
Returns fringe type.
Definition NBNode.h:305
void buildCrossingsAndWalkingAreas()
build crossings, and walkingareas. Also removes invalid loaded crossings if wished
Definition NBNode.cpp:3050
SumoXMLNodeType getType() const
Returns the type of this node.
Definition NBNode.h:285
bool isTrafficLight() const
Definition NBNode.h:839
void setRoundaboutType(RoundaboutType roundaboutType)
set roundabout type
Definition NBNode.h:591
void setRightOfWay(RightOfWay rightOfWay)
set method for computing right-of-way
Definition NBNode.h:581
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition NBNode.cpp:2790
void invalidateIncomingConnections(bool reallowSetting=false)
invalidate incoming connections
Definition NBNode.cpp:2129
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
Definition NBNode.h:268
void mirrorX()
mirror coordinates along the x-axis
Definition NBNode.cpp:410
std::vector< std::pair< Position, std::string > > getEndPoints() const
return list of unique endpoint coordinates of all edges at this node
Definition NBNode.cpp:4373
const std::vector< std::unique_ptr< Crossing > > & getCrossingsIncludingInvalid() const
Definition NBNode.h:759
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
Definition NBNode.h:273
bool hasCustomShape() const
return whether the shape was set by the user
Definition NBNode.h:601
std::vector< Crossing * > getCrossings() const
return this junctions pedestrian crossings
Definition NBNode.cpp:3099
const std::string & getName() const
Returns intersection name.
Definition NBNode.h:315
void setRadius(double radius)
set the turning radius
Definition NBNode.h:571
void setName(const std::string &name)
set intersection name
Definition NBNode.h:596
const Position & getPosition() const
Definition NBNode.h:260
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
Definition NBNode.cpp:439
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node)
Definition NBNode.h:278
const PositionVector & getShape() const
retrieve the junction shape
Definition NBNode.cpp:2784
RoundaboutType getRoundaboutType() const
Returns roundabout type.
Definition NBNode.h:310
double getRadius() const
Returns the turning radius of this node.
Definition NBNode.h:290
bool isRoundabout() const
return whether this node is part of a roundabout
Definition NBNode.cpp:4073
bool checkIsRemovableReporting(std::string &reason) const
check if node is removable and return reason if not
Definition NBNode.cpp:2671
const std::vector< WalkingArea > & getWalkingAreas() const
return this junctions pedestrian walking areas
Definition NBNode.h:764
PositionVector myPoly
the (outer) shape of the junction
Definition NBNode.h:972
void setFringeType(FringeType fringeType)
set fringe type
Definition NBNode.h:586
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition NBNode.h:336
A traffic light logics which must be computed (only nodes/edges are given)
Definition NBOwnTLDef.h:44
void setLayout(TrafficLightLayout layout)
sets the layout for the generated signal plan
Definition NBOwnTLDef.h:143
The base class for traffic light logic definitions.
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
const std::string & getProgramID() const
Returns the ProgramID.
TrafficLightType getType() const
get the algorithm type (static etc..)
virtual void setProgramID(const std::string &programID)
Sets the programID.
virtual void addNode(NBNode *node)
Adds a node to the traffic light logic.
SUMOTime getOffset()
Returns the offset.
A container for traffic light definitions and built programs.
const std::map< std::string, NBTrafficLightDefinition * > & getPrograms(const std::string &id) const
Returns all programs for the given tl-id.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
void extract(NBTrafficLightDefinition *definition)
Extracts a traffic light definition from myDefinitions but keeps it in myExtracted for eventual * del...
A SUMO-compliant built logic for a traffic light.
static void computeTurnDirectionsForNode(NBNode *node, bool warn)
Computes turnaround destinations for all incoming edges of the given nodes (if any)
virtual void setID(const std::string &newID)
resets the id
Definition Named.h:81
const std::string & getID() const
Returns the id.
Definition Named.h:73
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.
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition RGBColor.cpp:92
RGBColor changedBrightness(int change, int toChange=3) const
Returns a new color with altered brightness.
Definition RGBColor.cpp:200
const PositionVector & getShape() const
Returns the shape of the polygon.
virtual void setShape(const PositionVector &shape)
Sets the shape of the polygon.
PositionVector & getShapeRef()
Return the exterior shape of the polygon.
static StringBijection< SumoXMLNodeType > NodeTypes
node types
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
static StringBijection< TrafficLightLayout > TrafficLightLayouts
traffic light layouts
static bool isValidNetID(const std::string &value)
whether the given string is a valid id for a network element
static StringBijection< RightOfWay > RightOfWayValues
righ of way algorithms
static StringBijection< RoundaboutType > RoundaboutTypeValues
fringe types
static StringBijection< FringeType > FringeTypeValues
fringe types
const std::string & getString(const T key) const
get string
bool hasString(const std::string &str) const
check if the given string exist
T get(const std::string &str) const
get key
std::vector< GLPrimitive > myTesselation
id of the display list for the cached tesselation
Definition GUIPolygon.h:72
void drawTesselation(const PositionVector &shape) const
perform the tesselation / drawing
bool isBoundaryFullWithin(const Boundary &boundary) const
check if the given position is FULL within this triangle
Definition Triangle.cpp:60
NetworkEditMode networkEditMode
the current Network edit mode
bool isCurrentSupermodeData() const
@check if current supermode is Data
bool isCurrentSupermodeNetwork() const
@check if current supermode is Network
GNENetworkElement * getEditedNetworkElement() const
pointer to edited network element
static void drawLockIcon(const GUIVisualizationSettings::Detail d, const GNEAttributeCarrier *AC, GUIGlObjectType type, const Position position, const double exaggeration, const double size=0.5, const double offsetx=0, const double offsety=0)
draw lock icon
GNEMoveElement * getMovedElement() const
get moved element
bool editingElevation() const
check if we're editing elevation
static const RGBColor special
color for selected special candidate element (Usually selected using shift+click)
static const RGBColor conflict
color for selected conflict candidate element (Usually selected using ctrl+click)
static const RGBColor target
color for selected candidate target
static const RGBColor possible
color for possible candidate element
static const RGBColor source
color for selected candidate source
RGBColor selectionColor
basic selection color
static const 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