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 // supermode network
514 const bool supermodeNetwork = myNet->getViewNet()->getEditModes().isCurrentSupermodeNetwork();
515 // build common options
516 buildPopUpMenuCommonOptions(ret, app, myNet->getViewNet(), myTagProperty->getTag(), mySelected, supermodeNetwork, supermodeNetwork);
517 // check if we're in supermode network
518 if (supermodeNetwork) {
519 const int numSelectedJunctions = myNet->getAttributeCarriers()->getNumberOfSelectedJunctions();
520 const int numEndpoints = (int)myNBNode->getEndPoints().size();
521 // check if we're handling a selection
522 bool handlingSelection = isAttributeCarrierSelected() && (numSelectedJunctions > 1);
523 // check if menu commands has to be disabled
527 // build TLS operation
528 if (!invalidMode) {
529 buildTLSOperations(parent, ret, numSelectedJunctions);
530 }
531 // create menu commands
532 GUIDesigns::buildFXMenuCommand(ret, TL("Reset edge endpoints"), nullptr, &parent, MID_GNE_JUNCTION_RESET_EDGE_ENDPOINTS);
533 FXMenuCommand* mcCustomShape = GUIDesigns::buildFXMenuCommand(ret, TL("Set custom junction shape"), nullptr, &parent, MID_GNE_JUNCTION_EDIT_SHAPE);
534 FXMenuCommand* mcResetCustomShape = GUIDesigns::buildFXMenuCommand(ret, TL("Reset junction shape"), nullptr, &parent, MID_GNE_JUNCTION_RESET_SHAPE);
535 FXMenuCommand* mcReplaceByGeometryPoint = GUIDesigns::buildFXMenuCommand(ret, TL("Replace junction by geometry point"), nullptr, &parent, MID_GNE_JUNCTION_REPLACE);
536 FXMenuCommand* mcSplitJunction = GUIDesigns::buildFXMenuCommand(ret, TLF("Split junction (% end points)", numEndpoints), nullptr, &parent, MID_GNE_JUNCTION_SPLIT);
537 FXMenuCommand* mcSplitJunctionAndReconnect = GUIDesigns::buildFXMenuCommand(ret, TL("Split junction and reconnect"), nullptr, &parent, MID_GNE_JUNCTION_SPLIT_RECONNECT);
538 // check if is a roundabout
539 if (myNBNode->isRoundabout()) {
540 GUIDesigns::buildFXMenuCommand(ret, TL("Select roundabout"), nullptr, &parent, MID_GNE_JUNCTION_SELECT_ROUNDABOUT);
541 } else {
542 // get radius
543 const double radius = (myNBNode->getRadius() == NBNode::UNSPECIFIED_RADIUS) ? OptionsCont::getOptions().getFloat("default.junctions.radius") : myNBNode->getRadius();
544 const std::string menuEntryInfo = TLF("Convert to roundabout (using junction attribute radius %)", toString(radius));
545 FXMenuCommand* mcRoundabout = GUIDesigns::buildFXMenuCommand(ret, menuEntryInfo.c_str(), nullptr, &parent, MID_GNE_JUNCTION_CONVERT_ROUNDABOUT);
546 // check if disable depending of number of edges
547 if ((getChildEdges().size() < 2) ||
548 ((myGNEIncomingEdges.size() == 1) && (myGNEOutgoingEdges.size() == 1) && (myGNEIncomingEdges[0]->getFromJunction() == myGNEOutgoingEdges[0]->getToJunction()))) {
549 mcRoundabout->disable();
550 }
551 }
552 // check multijunctions
553 const std::string multi = ((numSelectedJunctions > 1) && isAttributeCarrierSelected()) ? TLF(" of % junctions", numSelectedJunctions) : "";
554 FXMenuCommand* mcClearConnections = GUIDesigns::buildFXMenuCommand(ret, TL("Clear connections") + multi, nullptr, &parent, MID_GNE_JUNCTION_CLEAR_CONNECTIONS);
555 FXMenuCommand* mcResetConnections = GUIDesigns::buildFXMenuCommand(ret, TL("Reset connections") + multi, nullptr, &parent, MID_GNE_JUNCTION_RESET_CONNECTIONS);
556 // check if current mode is correct
557 if (invalidMode) {
558 mcCustomShape->disable();
559 mcClearConnections->disable();
560 mcResetConnections->disable();
561 }
562 // check if we're handling a selection
563 if (handlingSelection) {
564 mcResetCustomShape->setText(TL("Reset junction shapes"));
565 }
566 // disable mcClearConnections if junction hasn't connections
567 if (getGNEConnections().empty()) {
568 mcClearConnections->disable();
569 }
570 // disable mcResetCustomShape if junction doesn't have a custom shape
571 if (myNBNode->getShape().size() == 0) {
572 mcResetCustomShape->disable();
573 }
574 // checkIsRemovable requires turnarounds to be computed. This is ugly
575 if ((myNBNode->getIncomingEdges().size() == 2) && (myNBNode->getOutgoingEdges().size() == 2)) {
577 }
578 std::string reason = TL("wrong edit mode");
579 if (invalidMode || !myNBNode->checkIsRemovableReporting(reason)) {
580 mcReplaceByGeometryPoint->setText(mcReplaceByGeometryPoint->getText() + " (" + reason.c_str() + ")");
581 mcReplaceByGeometryPoint->disable();
582 }
583 // check if disable split junctions
584 if (numEndpoints == 1) {
585 mcSplitJunction->disable();
586 mcSplitJunctionAndReconnect->disable();
587 }
588 }
589 return ret;
590 }
591}
592
593
594double
598
599
604
605
606void
608 // Remove object from grid
609 if (updateGrid) {
611 }
612 // calculate boundary using a radius bigger than geometry point
614 myNBNode->getPosition().x() + 1, myNBNode->getPosition().y() + 1);
616 // add shape
617 if (myNBNode->getShape().size() > 0) {
620 }
621 // add boundaries of all connections, walking areas and crossings
622 for (const auto& edge : myGNEIncomingEdges) {
623 for (const auto& connection : edge->getGNEConnections()) {
624 const auto boundary = connection->getCenteringBoundary();
625 if (boundary.isInitialised()) {
626 myJunctionBoundary.add(boundary);
627 }
628 }
629 }
630 for (const auto& crossing : myGNECrossings) {
631 const auto boundary = crossing->getCenteringBoundary();
632 if (boundary.isInitialised()) {
633 myJunctionBoundary.add(boundary);
634 }
635 }
636 for (const auto& walkingArea : myGNEWalkingAreas) {
637 const auto boundary = walkingArea->getCenteringBoundary();
638 if (boundary.isInitialised()) {
639 myJunctionBoundary.add(boundary);
640 }
641 }
642
643 // add object into grid
644 if (updateGrid) {
645 // if junction has at least one edge, then don't add in grid (because uses the edge's grid)
646 if (myGNEIncomingEdges.size() + myGNEOutgoingEdges.size() == 0) {
648 }
649 }
650 // trigger rebuilding tesselation
651 myExaggeration = 2;
652}
653
654
655void
657 // first check drawing toggle and boundary selection
659 // draw boundaries
660 if (inGrid()) {
662 }
663 // get junction exaggeration
664 const double junctionExaggeration = getExaggeration(s);
665 // only continue if exaggeration is greater than 0
666 if (junctionExaggeration > 0) {
667 // get detail level
668 const auto d = s.getDetailLevel(junctionExaggeration);
669 // get shape area
670 const double junctionShapeArea = myNBNode->getShape().area();
671 // check if draw junction as shape
672 const bool drawBubble = drawAsBubble(s, junctionShapeArea);
673 // draw geometry only if we'rent in drawForObjectUnderCursor mode
675 // push layer matrix
677 // translate to front
679 if (drawBubble) {
680 // draw junction as bubble
681 drawJunctionAsBubble(s, d, junctionExaggeration);
682 } else {
683 // draw junction as shape
684 drawJunctionAsShape(s, d, junctionExaggeration);
685 }
686 // draw junction center (only in move mode)
687 drawJunctionCenter(s, d);
688 // draw TLS
689 drawTLSIcon(s);
690 // draw elevation
691 drawElevation(s);
692 // pop layer Matrix
694 // draw lock icon
696 // draw junction name
698 // draw dotted contour depending if we're editing the custom shape
700 if (editedNetworkElement && (editedNetworkElement == this)) {
701 // draw dotted contour geometry points
703 junctionExaggeration, s.dottedContourSettings.segmentWidthSmall);
704 } else {
705 if (drawBubble) {
706 // draw dotted contour for bubble
708 } else {
709 // draw dotted contour for shape
710 if (junctionShapeArea >= 4) {
712 }
713 }
714 }
715 }
716 // calculate junction contour (always before children)
717 calculateJunctioncontour(s, d, junctionExaggeration, drawBubble);
718 // draw Junction childs
720 }
721 // update drawing toggle
723 }
724}
725
726
727void
729 // Check if edge can be deleted
732 }
733}
734
735
736void
740
741
742NBNode*
744 return myNBNode;
745}
746
747
748std::vector<GNEJunction*>
750 // use set to avoid duplicates junctions
751 std::set<GNEJunction*> junctions;
752 for (const auto& incomingEdge : myGNEIncomingEdges) {
753 junctions.insert(incomingEdge->getFromJunction());
754 }
755 for (const auto& outgoingEdge : myGNEOutgoingEdges) {
756 junctions.insert(outgoingEdge->getToJunction());
757 }
758 return std::vector<GNEJunction*>(junctions.begin(), junctions.end());
759}
760
761
762void
764 // Check if incoming edge was already inserted
765 std::vector<GNEEdge*>::iterator i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
766 if (i != myGNEIncomingEdges.end()) {
767 throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + getTagStr() + " with ID " + getID() + "'");
768 } else {
769 // Add edge into containers
770 myGNEIncomingEdges.push_back(edge);
771 }
772}
773
774
775
776void
778 // Check if outgoing edge was already inserted
779 const auto i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
780 if (i != myGNEOutgoingEdges.end()) {
781 throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + getTagStr() + " with ID " + getID() + "'");
782 } else {
783 // Add edge into containers
784 myGNEOutgoingEdges.push_back(edge);
785 }
786 // update centering boundary and grid
788}
789
790
791void
793 // Check if incoming edge was already inserted
794 auto i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
795 if (i == myGNEIncomingEdges.end()) {
796 throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + getTagStr() + " with ID " + getID() + "'");
797 } else {
798 // remove edge from containers
799 myGNEIncomingEdges.erase(i);
800 }
801 // update centering boundary and grid
803}
804
805
806void
808 // Check if outgoing edge was already inserted
809 std::vector<GNEEdge*>::iterator i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
810 if (i == myGNEOutgoingEdges.end()) {
811 throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + getTagStr() + " with ID " + getID() + "'");
812 } else {
813 // remove edge from containers
814 myGNEOutgoingEdges.erase(i);
815 }
816}
817
818
819const std::vector<GNEEdge*>&
823
824
825const std::vector<GNEEdge*>&
829
830
831const std::vector<GNECrossing*>&
835
836
837const std::vector<GNEWalkingArea*>&
841
842
843std::vector<GNEConnection*>
845 std::vector<GNEConnection*> connections;
846 for (const auto& incomingEdge : myGNEIncomingEdges) {
847 for (const auto& connection : incomingEdge->getGNEConnections()) {
848 connections.push_back(connection);
849 }
850 }
851 return connections;
852}
853
854
855void
859
860
861void
865
866
867void
869 myAmTLSSelected = selected;
870}
871
872
873void
875 if (!myNBNode->hasCustomShape()) {
876 if (myNBNode->myPoly.size() > 0) {
877 // clear poly
878 myNBNode->myPoly.clear();
879 // update centering boundary
881 }
883 }
884}
885
886
887void
888GNEJunction::setLogicValid(bool valid, GNEUndoList* undoList, const std::string& status) {
889 myHasValidLogic = valid;
890 if (!valid) {
891 assert(undoList != 0);
892 assert(undoList->hasCommandGroup());
895 for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
896 GNEEdge* srcEdge = myNet->getAttributeCarriers()->retrieveEdge((*it)->getID());
897 removeConnectionsFrom(srcEdge, undoList, false); // false, because the whole tls will be invalidated at the end
899 }
901 invalidateTLS(undoList);
902 } else {
903 // logic valed, then rebuild GNECrossings to adapt it to the new logic
904 // (but don't rebuild the crossings in NBNode because they are already finished)
905 rebuildGNECrossings(false);
906 }
907}
908
909
910void
911GNEJunction::removeConnectionsFrom(GNEEdge* edge, GNEUndoList* undoList, bool updateTLS, int lane) {
912 NBEdge* srcNBE = edge->getNBEdge();
913 NBEdge* turnEdge = srcNBE->getTurnDestination();
914 // Make a copy of connections
915 std::vector<NBEdge::Connection> connections = srcNBE->getConnections();
916 // delete in reverse so that undoing will add connections in the original order
917 for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) {
918 if (lane >= 0 && (*con_it).fromLane != lane) {
919 continue;
920 }
921 bool hasTurn = con_it->toEdge == turnEdge;
922 undoList->add(new GNEChange_Connection(edge, *con_it, false, false), true);
923 // needs to come after GNEChange_Connection
924 // XXX bug: this code path will not be used on a redo!
925 if (hasTurn) {
927 }
928 }
929 if (updateTLS) {
930 std::vector<NBConnection> removeConnections;
931 for (NBEdge::Connection con : connections) {
932 removeConnections.push_back(NBConnection(srcNBE, con.fromLane, con.toEdge, con.toLane));
933 }
934 removeTLSConnections(removeConnections, undoList);
935 }
936}
937
938
939void
940GNEJunction::removeConnectionsTo(GNEEdge* edge, GNEUndoList* undoList, bool updateTLS, int lane) {
941 NBEdge* destNBE = edge->getNBEdge();
942 std::vector<NBConnection> removeConnections;
943 for (NBEdge* srcNBE : myNBNode->getIncomingEdges()) {
944 GNEEdge* srcEdge = myNet->getAttributeCarriers()->retrieveEdge(srcNBE->getID());
945 std::vector<NBEdge::Connection> connections = srcNBE->getConnections();
946 for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) {
947 if ((*con_it).toEdge == destNBE) {
948 if (lane >= 0 && (*con_it).toLane != lane) {
949 continue;
950 }
951 bool hasTurn = srcNBE->getTurnDestination() == destNBE;
952 undoList->add(new GNEChange_Connection(srcEdge, *con_it, false, false), true);
953 // needs to come after GNEChange_Connection
954 // XXX bug: this code path will not be used on a redo!
955 if (hasTurn) {
956 myNet->addExplicitTurnaround(srcNBE->getID());
957 }
958 removeConnections.push_back(NBConnection(srcNBE, (*con_it).fromLane, destNBE, (*con_it).toLane));
959 }
960 }
961 }
962 if (updateTLS) {
963 removeTLSConnections(removeConnections, undoList);
964 }
965}
966
967
968void
969GNEJunction::removeTLSConnections(std::vector<NBConnection>& connections, GNEUndoList* undoList) {
970 if (connections.size() > 0) {
971 const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode->getControllingTLS(); // make a copy!
972 for (const auto& TLS : coypOfTls) {
973 NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
974 // guessed TLS (NBOwnTLDef) do not need to be updated
975 if (tlDef != nullptr) {
976 std::string newID = tlDef->getID();
977 // create replacement before deleting the original because deletion will mess up saving original nodes
978 NBLoadedSUMOTLDef* replacementDef = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
979 for (NBConnection& con : connections) {
980 replacementDef->removeConnection(con);
981 }
982 undoList->add(new GNEChange_TLS(this, tlDef, false), true);
983 undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
984 // the removed traffic light may have controlled more than one junction. These too have become invalid now
985 const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
986 for (const auto& node : copyOfNodes) {
987 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
988 undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
989 undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
990 }
991 }
992 }
993 }
994}
995
996
997void
999 // remap connections of the edge
1000 assert(which->getChildLanes().size() == by->getChildLanes().size());
1001 std::vector<NBEdge::Connection> connections = which->getNBEdge()->getConnections();
1002 for (NBEdge::Connection& c : connections) {
1003 undoList->add(new GNEChange_Connection(which, c, false, false), true);
1004 undoList->add(new GNEChange_Connection(by, c, false, true), true);
1005 }
1006 // also remap tls connections
1007 const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode->getControllingTLS(); // make a copy!
1008 for (const auto& TLS : coypOfTls) {
1009 NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
1010 // guessed TLS (NBOwnTLDef) do not need to be updated
1011 if (tlDef != nullptr) {
1012 std::string newID = tlDef->getID();
1013 // create replacement before deleting the original because deletion will mess up saving original nodes
1014 NBLoadedSUMOTLDef* replacementDef = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
1015 for (int i = 0; i < (int)which->getChildLanes().size(); ++i) {
1016 replacementDef->replaceRemoved(which->getNBEdge(), i, by->getNBEdge(), i, true);
1017 }
1018 undoList->add(new GNEChange_TLS(this, tlDef, false), true);
1019 undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
1020 // the removed traffic light may have controlled more than one junction. These too have become invalid now
1021 const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
1022 for (const auto& node : copyOfNodes) {
1023 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1024 undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
1025 undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
1026 }
1027 }
1028 }
1029}
1030
1031
1032void
1034 EdgeVector incoming = myNBNode->getIncomingEdges();
1035 for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
1036 NBEdge* srcNBE = *it;
1037 GNEEdge* srcEdge = myNet->getAttributeCarriers()->retrieveEdge(srcNBE->getID());
1039 }
1040}
1041
1042
1043void
1044GNEJunction::invalidateTLS(GNEUndoList* undoList, const NBConnection& deletedConnection, const NBConnection& addedConnection) {
1045 assert(undoList->hasCommandGroup());
1046 // NBLoadedSUMOTLDef becomes invalid, replace with NBOwnTLDef which will be dynamically recomputed
1047 const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode->getControllingTLS(); // make a copy!
1048 for (const auto& TLS : coypOfTls) {
1049 NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
1050 if (tlDef != nullptr) {
1051 // the removed traffic light may have controlled more than one junction. These too have become invalid now
1052 const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
1053 if (myGNECrossings.size() == 0 && getNBNode()->getCrossings().size() != 0) {
1054 // crossings were not computed yet. We need them as netedit elements to manage tlIndex resetting
1057 for (const auto& node : copyOfNodes) {
1058 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1059 if (sharing != this) {
1060 sharing->rebuildGNECrossings();
1061 }
1062 }
1063 }
1064 NBTrafficLightDefinition* replacementDef = nullptr;
1065 std::string newID = tlDef->getID(); // + "_reguessed"; // changes due to reguessing will be visible in diff
1066 if (deletedConnection != NBConnection::InvalidConnection) {
1067 // create replacement before deleting the original because deletion will mess up saving original nodes
1068 NBLoadedSUMOTLDef* repl = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
1069 repl->removeConnection(deletedConnection);
1070 replacementDef = repl;
1071 } else if (addedConnection != NBConnection::InvalidConnection) {
1072 if (addedConnection.getTLIndex() == NBConnection::InvalidTlIndex) {
1073 // custom tl indices of crossings might become invalid upon recomputation so we must save them
1074 // however, they could remain valid so we register a change but keep them at their old value
1075 for (const auto& crossing : myGNECrossings) {
1076 const std::string oldValue = crossing->getAttribute(SUMO_ATTR_TLLINKINDEX);
1078 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX, oldValue, undoList, true);
1079 const std::string oldValue2 = crossing->getAttribute(SUMO_ATTR_TLLINKINDEX2);
1081 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX2, oldValue2, undoList, true);
1082 }
1083 }
1084 NBLoadedSUMOTLDef* repl = new NBLoadedSUMOTLDef(*tlDef, *tlDef->getLogic());
1085 repl->addConnection(addedConnection.getFrom(), addedConnection.getTo(),
1086 addedConnection.getFromLane(), addedConnection.getToLane(), addedConnection.getTLIndex(), addedConnection.getTLIndex2());
1087 replacementDef = repl;
1088 } else {
1089 // recompute crossing indices along with everything else
1090 for (const auto& crossing : myGNECrossings) {
1093 }
1094 replacementDef = new NBOwnTLDef(newID, tlDef->getOffset(), tlDef->getType());
1095 replacementDef->setProgramID(tlDef->getProgramID());
1096 }
1097 undoList->add(new GNEChange_TLS(this, tlDef, false), true);
1098 undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
1099 // reset nodes of joint tls
1100 for (const auto& node : copyOfNodes) {
1101 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1102 if (sharing != this) {
1103 if (deletedConnection == NBConnection::InvalidConnection && addedConnection == NBConnection::InvalidConnection) {
1104 // recompute crossing indices for shared
1105 // (they won't do this on subsequent call to invalidateTLS if they received an NBOwnTLDef)
1106 for (const auto& crossing : sharing->getGNECrossings()) {
1109 }
1110 }
1111 undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
1112 undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
1113 }
1114 }
1115 }
1116 }
1117}
1118
1119void
1121 // obtain a copy of GNECrossing of junctions
1122 const auto copyOfGNECrossings = myGNECrossings;
1123 // iterate over copy of GNECrossings
1124 for (const auto& crossing : copyOfGNECrossings) {
1125 // obtain the set of edges vinculated with the crossing (due it works as ID)
1126 EdgeSet edgeSet(crossing->getCrossingEdges().begin(), crossing->getCrossingEdges().end());
1127 // If this edge is part of the set of edges of crossing
1128 if (edgeSet.count(edge->getNBEdge()) == 1) {
1129 // delete crossing if this is their last edge
1130 if ((crossing->getCrossingEdges().size() == 1) && (crossing->getCrossingEdges().front() == edge->getNBEdge())) {
1131 myNet->deleteCrossing(crossing, undoList);
1132 } else {
1133 // remove this edge of the edge's attribute of crossing (note: This can invalidate the crossing)
1134 std::vector<std::string> edges = GNEAttributeCarrier::parse<std::vector<std::string>>(crossing->getAttribute(SUMO_ATTR_EDGES));
1135 edges.erase(std::find(edges.begin(), edges.end(), edge->getID()));
1136 crossing->setAttribute(SUMO_ATTR_EDGES, joinToString(edges, " "), undoList);
1137 }
1138 }
1139 }
1140}
1141
1142
1143bool
1147
1148
1150GNEJunction::retrieveGNECrossing(NBNode::Crossing* NBNodeCrossing, bool createIfNoExist) {
1151 // iterate over all crossing
1152 for (const auto& crossing : myGNECrossings) {
1153 // if found, return it
1154 if (crossing->getCrossingEdges() == NBNodeCrossing->edges) {
1155 return crossing;
1156 }
1157 }
1158 if (createIfNoExist) {
1159 // create new GNECrossing
1160 GNECrossing* createdGNECrossing = new GNECrossing(this, NBNodeCrossing->edges);
1161 // update geometry after creating
1162 createdGNECrossing->updateGeometry();
1163 // add it in Network
1164 myNet->addGLObjectIntoGrid(createdGNECrossing);
1165 // add it in attributeCarriers
1166 myNet->getAttributeCarriers()->insertCrossing(createdGNECrossing);
1167 return createdGNECrossing;
1168 } else {
1169 return nullptr;
1170 }
1171}
1172
1173
1175GNEJunction::retrieveGNEWalkingArea(const std::string& NBNodeWalkingAreaID, bool createIfNoExist) {
1176 // iterate over all walkingArea
1177 for (const auto& walkingArea : myGNEWalkingAreas) {
1178 // if found, return it
1179 if (walkingArea->getID() == NBNodeWalkingAreaID) {
1180 return walkingArea;
1181 }
1182 }
1183 if (createIfNoExist) {
1184 // create new GNEWalkingArea
1185 GNEWalkingArea* createdGNEWalkingArea = new GNEWalkingArea(this, NBNodeWalkingAreaID);
1186 // update geometry after creating
1187 createdGNEWalkingArea->updateGeometry();
1188 // add it in Network
1189 myNet->addGLObjectIntoGrid(createdGNEWalkingArea);
1190 // add it in attributeCarriers
1191 myNet->getAttributeCarriers()->insertWalkingArea(createdGNEWalkingArea);
1192 return createdGNEWalkingArea;
1193 } else {
1194 return nullptr;
1195 }
1196}
1197
1198
1199void
1201 // only it's needed to mark the connections of incoming edges
1202 for (const auto& i : myGNEIncomingEdges) {
1203 for (const auto& j : i->getGNEConnections()) {
1204 j->markConnectionGeometryDeprecated();
1205 }
1206 if (includingNeighbours) {
1207 i->getFromJunction()->markConnectionsDeprecated(false);
1208 }
1209 }
1210}
1211
1212
1213void
1214GNEJunction::setJunctionType(const std::string& value, GNEUndoList* undoList) {
1215 undoList->begin(this, "change " + getTagStr() + " type");
1217 if (getNBNode()->isTLControlled() &&
1218 // if switching changing from or to traffic_light_right_on_red we need to remove the old plan
1221 ) {
1222 // make a copy because we will modify the original
1223 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1224 for (const auto& TLS : copyOfTls) {
1225 undoList->add(new GNEChange_TLS(this, TLS, false), true);
1226 }
1227 }
1228 if (!getNBNode()->isTLControlled()) {
1229 // create new traffic light
1230 undoList->add(new GNEChange_TLS(this, nullptr, true), true);
1231 }
1232 } else if (getNBNode()->isTLControlled()) {
1233 // delete old traffic light
1234 // make a copy because we will modify the original
1235 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1236 for (const auto& TLS : copyOfTls) {
1237 undoList->add(new GNEChange_TLS(this, TLS, false, false), true);
1238 const std::vector<NBNode*> copyOfNodes = TLS->getNodes(); // make a copy!
1239 for (const auto& node : copyOfNodes) {
1240 GNEJunction* sharing = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1241 sharing->invalidateTLS(undoList);
1242 }
1243 }
1244 }
1245 // must be the final step, otherwise we do not know which traffic lights to remove via GNEChange_TLS
1246 GNEChange_Attribute::changeAttribute(this, SUMO_ATTR_TYPE, value, undoList, true);
1247 for (const auto& crossing : myGNECrossings) {
1248 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX, "-1", undoList, true);
1249 GNEChange_Attribute::changeAttribute(crossing, SUMO_ATTR_TLLINKINDEX2, "-1", undoList, true);
1250 }
1251 undoList->end();
1252}
1253
1254
1255void
1257 // delete non retrieved GNEWalkingAreas (we don't need to extract if from Tree two times)
1258 for (const auto& walkingArea : myGNEWalkingAreas) {
1259 walkingArea->decRef();
1260 // check if walkingArea is selected
1261 if (walkingArea->isAttributeCarrierSelected()) {
1262 walkingArea->unselectAttributeCarrier();
1263 }
1264 // remove it from inspected ACS
1266 // remove it from net
1267 myNet->removeGLObjectFromGrid(walkingArea);
1268 // remove it from attributeCarriers
1270 if (walkingArea->unreferenced()) {
1271 delete walkingArea;
1272 }
1273 }
1274 myGNEWalkingAreas.clear();
1275}
1276
1277
1278void
1280 // first clear GNEWalkingAreas
1282 // iterate over NBNode::WalkingAreas of GNEJunction
1283 for (const auto& walkingArea : myNBNode->getWalkingAreas()) {
1284 // retrieve existent GNEWalkingArea, or create it
1285 GNEWalkingArea* retrievedGNEWalkingArea = retrieveGNEWalkingArea(walkingArea.id, true);
1286 // include reference to created GNEWalkingArea
1287 retrievedGNEWalkingArea->incRef();
1288 // update geometry of retrieved walkingArea
1289 retrievedGNEWalkingArea->updateGeometry();
1290 // update boundary
1291 retrievedGNEWalkingArea->updateCenteringBoundary(false);
1292 // add in walkingAreas
1293 myGNEWalkingAreas.push_back(retrievedGNEWalkingArea);
1294 }
1295}
1296
1297
1298
1299void
1301 if (std::find(myInternalLanes.begin(), myInternalLanes.end(), internalLane) != myInternalLanes.end()) {
1302 throw ProcessError(internalLane->getTagStr() + " with ID='" + internalLane->getID() + "' already exist");
1303 } else {
1304 myInternalLanes.push_back(internalLane);
1305 }
1306}
1307
1308
1309void
1311 const auto finder = std::find(myInternalLanes.begin(), myInternalLanes.end(), internalLane);
1312 if (finder == myInternalLanes.end()) {
1313 throw ProcessError(internalLane->getTagStr() + " with ID='" + internalLane->getID() + "' wasn't previously inserted");
1314 } else {
1315 myInternalLanes.erase(finder);
1316 }
1317}
1318
1319
1320std::string
1322 switch (key) {
1323 case SUMO_ATTR_ID:
1324 return getMicrosimID();
1325 case SUMO_ATTR_POSITION:
1326 return toString(myNBNode->getPosition());
1327 case SUMO_ATTR_TYPE:
1328 return toString(myNBNode->getType());
1330 return myLogicStatus;
1331 case SUMO_ATTR_SHAPE:
1332 return toString(myNBNode->getShape());
1333 case SUMO_ATTR_RADIUS:
1334 if (myNBNode->getRadius() < 0) {
1335 return "default";
1336 } else {
1337 return toString(myNBNode->getRadius());
1338 }
1339 case SUMO_ATTR_TLTYPE:
1341 // @todo this causes problems if the node were to have multiple programs of different type (plausible)
1342 return toString((*myNBNode->getControllingTLS().begin())->getType());
1343 } else {
1344 return "No TLS";
1345 }
1346 case SUMO_ATTR_TLLAYOUT:
1348 return toString((*myNBNode->getControllingTLS().begin())->getLayout());
1349 } else {
1350 return "No TLS";
1351 }
1352 case SUMO_ATTR_TLID:
1354 return toString((*myNBNode->getControllingTLS().begin())->getID());
1355 } else {
1356 return "No TLS";
1357 }
1361 // keep clear is only used as a convenience feature in plain xml
1362 // input. When saving to .net.xml the status is saved only for the connections
1363 // to show the correct state we must check all connections
1364 for (const auto& i : myGNEIncomingEdges) {
1365 for (const auto& j : i->getGNEConnections()) {
1366 if (j->getNBEdgeConnection().keepClear) {
1367 return TRUE_STR;
1368 }
1369 }
1370 }
1371 return FALSE_STR;
1374 case SUMO_ATTR_FRINGE:
1378 case SUMO_ATTR_NAME:
1379 return myNBNode->getName();
1380 default:
1381 return getCommonAttribute(key);
1382 }
1383}
1384
1385
1386double
1390
1391
1396
1397
1400 switch (key) {
1401 case SUMO_ATTR_SHAPE:
1402 return myNBNode->getShape();
1403 default:
1405 }
1406}
1407
1408
1409void
1410GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
1411 if (value == getAttribute(key)) {
1412 return; //avoid needless changes, later logic relies on the fact that attributes have changed
1413 }
1414 switch (key) {
1415 case SUMO_ATTR_ID:
1417 case SUMO_ATTR_SHAPE:
1418 case SUMO_ATTR_RADIUS:
1420 case SUMO_ATTR_FRINGE:
1422 case SUMO_ATTR_NAME:
1423 GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);
1424 break;
1425 case SUMO_ATTR_POSITION: {
1426 const GNEJunction* junctionToMerge = nullptr;
1427 bool alreadyAsked = false;
1428 // parse position
1429 Position newPosition = GNEAttributeCarrier::parse<Position>(value);
1430 // check if caculate new position based in edges
1431 if (newPosition == Position::INVALID) {
1432 Boundary b;
1433 // set new position of adjacent edges
1434 for (const auto& edge : myGNEIncomingEdges) {
1435 b.add(edge->getNBEdge()->getGeometry().back());
1436 }
1437 for (const auto& edge : myGNEOutgoingEdges) {
1438 b.add(edge->getNBEdge()->getGeometry().front());
1439 }
1440 newPosition = b.getCenter();
1441 }
1442 // retrieve all junctions placed in this position
1443 myNet->getViewNet()->updateObjectsInPosition(newPosition);
1444 for (const auto& junction : myNet->getViewNet()->getViewObjectsSelector().getJunctions()) {
1445 // check distance position
1446 if ((junctionToMerge == nullptr) && (junction != this) &&
1447 (junction->getPositionInView().distanceTo2D(newPosition) < myNet->getViewNet()->getVisualisationSettings().neteditSizeSettings.junctionBubbleRadius) &&
1448 myNet->getViewNet()->askMergeJunctions(this, junction, alreadyAsked)) {
1449 junctionToMerge = junction;
1450 }
1451 }
1452 // also check the merging junctions located during drawGL
1453 for (const auto& junction : myNet->getViewNet()->getViewObjectsSelector().getMergingJunctions()) {
1454 // check distance position
1455 if ((junctionToMerge == nullptr) && (junction != this) && myNet->getViewNet()->askMergeJunctions(this, junction, alreadyAsked)) {
1456 junctionToMerge = junction;
1457 }
1458 }
1459 // if we merge the junction, this junction will be removed, therefore we don't have to change the position
1460 if (junctionToMerge) {
1461 myNet->mergeJunctions(this, junctionToMerge, undoList);
1462 } else {
1463 // change Keep Clear attribute in all connections
1464 undoList->begin(this, TL("change junction position"));
1465 // obtain NBNode position
1466 const Position orig = myNBNode->getPosition();
1467 // change junction position
1468 GNEChange_Attribute::changeAttribute(this, key, toString(newPosition), undoList, true);
1469 // calculate delta using new position
1470 const bool moveOnlyCenter = myNet->getViewParent()->getMoveFrame()->getNetworkMoveOptions()->getMoveOnlyJunctionCenter();
1471 const Position delta = myNBNode->getPosition() - (moveOnlyCenter ? myNBNode->getPosition() : orig);
1472 // set new position of adjacent edges
1473 for (const auto& edge : myGNEIncomingEdges) {
1474 const Position newEnd = edge->getNBEdge()->getGeometry().back() + delta;
1476 }
1477 for (const auto& edge : myGNEOutgoingEdges) {
1478 const Position newStart = edge->getNBEdge()->getGeometry().front() + delta;
1479 GNEChange_Attribute::changeAttribute(edge, GNE_ATTR_SHAPE_START, toString(newStart), undoList, true);
1480 }
1481 undoList->end();
1482 }
1483 break;
1484 }
1486 // change Keep Clear attribute in all connections
1487 undoList->begin(this, TL("change keepClear for whole junction"));
1488 for (const auto& incomingEdge : myGNEIncomingEdges) {
1489 for (const auto& junction : incomingEdge->getGNEConnections()) {
1490 GNEChange_Attribute::changeAttribute(junction, key, value, undoList, true);
1491 }
1492 }
1493 undoList->end();
1494 break;
1495 case SUMO_ATTR_TYPE: {
1496 // set junction type
1497 setJunctionType(value, undoList);
1498 break;
1499 }
1500 case SUMO_ATTR_TLTYPE: {
1501 undoList->begin(this, "change " + getTagStr() + " tl-type");
1502 // make a copy because we will modify the original
1503 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1504 for (const auto& TLS : copyOfTls) {
1505 NBLoadedSUMOTLDef* oldLoaded = dynamic_cast<NBLoadedSUMOTLDef*>(TLS);
1506 if (oldLoaded != nullptr) {
1507 NBTrafficLightDefinition* newDef = nullptr;
1508 if (value == toString(TrafficLightType::NEMA) || oldLoaded->getType() == TrafficLightType::NEMA) {
1509 // rebuild the program because the old and new ones are incompatible
1510 newDef = new NBOwnTLDef(oldLoaded->getID(), oldLoaded->getOffset(), TrafficLightType::NEMA);
1511 newDef->setProgramID(oldLoaded->getProgramID());
1512 } else {
1513 NBLoadedSUMOTLDef* newLDef = new NBLoadedSUMOTLDef(*oldLoaded, *oldLoaded->getLogic());
1514 newLDef->guessMinMaxDuration(); // minDur and maxDur are never written for a static tls
1515 newDef = newLDef;
1516 }
1517 std::vector<NBNode*> nodes = TLS->getNodes();
1518 for (const auto& node : nodes) {
1519 GNEJunction* junction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1520 undoList->add(new GNEChange_TLS(junction, TLS, false), true);
1521 undoList->add(new GNEChange_TLS(junction, newDef, true), true);
1522 }
1523 }
1524 }
1525 GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);
1526 undoList->end();
1527 break;
1528 }
1529 case SUMO_ATTR_TLLAYOUT: {
1530 undoList->begin(this, "change " + getTagStr() + " tlLayout");
1531 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1532 for (const auto& oldTLS : copyOfTls) {
1533 std::vector<NBNode*> copyOfNodes = oldTLS->getNodes();
1534 NBOwnTLDef* newTLS = new NBOwnTLDef(oldTLS->getID(), oldTLS->getOffset(), oldTLS->getType());
1536 newTLS->setProgramID(oldTLS->getProgramID());
1537 for (const auto& node : copyOfNodes) {
1538 GNEJunction* oldJunction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1539 undoList->add(new GNEChange_TLS(oldJunction, oldTLS, false), true);
1540 }
1541 for (const auto& node : copyOfNodes) {
1542 GNEJunction* oldJunction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1543 undoList->add(new GNEChange_TLS(oldJunction, newTLS, true), true);
1544 }
1545 }
1546 undoList->end();
1547 break;
1548 }
1549 case SUMO_ATTR_TLID: {
1550 undoList->begin(this, "change " + toString(SUMO_TAG_TRAFFIC_LIGHT) + " id");
1551 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
1552 assert(copyOfTls.size() > 0);
1553 NBTrafficLightDefinition* currentTLS = *copyOfTls.begin();
1554 NBTrafficLightDefinition* currentTLSCopy = nullptr;
1555 const bool currentIsSingle = currentTLS->getNodes().size() == 1;
1556 const bool currentIsLoaded = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS) != nullptr;
1557 if (currentIsLoaded) {
1558 currentTLSCopy = new NBLoadedSUMOTLDef(*currentTLS,
1559 *dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS)->getLogic());
1560 }
1561 // remove from previous tls
1562 for (const auto& TLS : copyOfTls) {
1563 undoList->add(new GNEChange_TLS(this, TLS, false), true);
1564 }
1566 // programs to which the current node shall be added
1567 const std::map<std::string, NBTrafficLightDefinition*> programs = tlCont.getPrograms(value);
1568 if (programs.size() > 0) {
1569 for (const auto& TLSProgram : programs) {
1570 NBTrafficLightDefinition* oldTLS = TLSProgram.second;
1571 if (dynamic_cast<NBOwnTLDef*>(oldTLS) != nullptr) {
1572 undoList->add(new GNEChange_TLS(this, oldTLS, true), true);
1573 } else {
1574 // delete and re-create the definition because the loaded phases are now invalid
1575 if (dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS) != nullptr &&
1576 dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->usingSignalGroups()) {
1577 // keep the old program and add all-red state for the added links
1578 NBLoadedSUMOTLDef* newTLSJoined = new NBLoadedSUMOTLDef(*oldTLS, *dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->getLogic());
1579 newTLSJoined->joinLogic(currentTLSCopy);
1580 undoList->add(new GNEChange_TLS(this, newTLSJoined, true, true), true);
1581 } else {
1582 undoList->add(new GNEChange_TLS(this, nullptr, true, false, value), true);
1583 }
1585 // switch from old to new definition
1586 std::vector<NBNode*> copyOfNodes = oldTLS->getNodes();
1587 for (const auto& node : copyOfNodes) {
1588 GNEJunction* oldJunction = myNet->getAttributeCarriers()->retrieveJunction(node->getID());
1589 undoList->add(new GNEChange_TLS(oldJunction, oldTLS, false), true);
1590 undoList->add(new GNEChange_TLS(oldJunction, newTLS, true), true);
1591 }
1592 }
1593 }
1594 } else {
1595 if (currentIsSingle && currentIsLoaded) {
1596 // rename the traffic light but keep everything else
1597 NBTrafficLightLogic* renamedLogic = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLSCopy)->getLogic();
1598 renamedLogic->setID(value);
1599 NBLoadedSUMOTLDef* renamedTLS = new NBLoadedSUMOTLDef(*currentTLSCopy, *renamedLogic);
1600 renamedTLS->setID(value);
1601 undoList->add(new GNEChange_TLS(this, renamedTLS, true, true), true);
1602 } else {
1603 // create new traffic light
1604 undoList->add(new GNEChange_TLS(this, nullptr, true, false, value), true);
1605 }
1606 }
1607 delete currentTLSCopy;
1608 undoList->end();
1609 break;
1610 }
1611 default:
1612 setCommonAttribute(key, value, undoList);
1613 break;
1614 }
1615}
1616
1617
1618bool
1619GNEJunction::isValid(SumoXMLAttr key, const std::string& value) {
1620 switch (key) {
1621 case SUMO_ATTR_ID:
1622 return SUMOXMLDefinitions::isValidNetID(value) && (myNet->getAttributeCarriers()->retrieveJunction(value, false) == nullptr);
1623 case SUMO_ATTR_TYPE:
1625 case SUMO_ATTR_POSITION:
1626 if (value.empty()) {
1627 return (myGNEIncomingEdges.size() + myGNEOutgoingEdges.size()) > 0;
1628 } else {
1629 return canParse<Position>(value);
1630 }
1631 case SUMO_ATTR_SHAPE:
1632 // empty shapes are allowed
1633 return canParse<PositionVector>(value);
1634 case SUMO_ATTR_RADIUS:
1635 if (value.empty() || (value == "default")) {
1636 return true;
1637 } else {
1638 return canParse<double>(value) && ((parse<double>(value) >= 0) || (parse<double>(value) == -1));
1639 }
1640 case SUMO_ATTR_TLTYPE:
1642 case SUMO_ATTR_TLLAYOUT:
1644 case SUMO_ATTR_TLID:
1646 return myNBNode->isTLControlled();
1647 } else {
1648 return false;
1649 }
1651 return canParse<bool>(value);
1654 case SUMO_ATTR_FRINGE:
1658 case SUMO_ATTR_NAME:
1659 return true;
1660 default:
1661 return isCommonAttributeValid(key, value);
1662 }
1663}
1664
1665
1666bool
1668 switch (key) {
1669 case SUMO_ATTR_TLTYPE:
1670 case SUMO_ATTR_TLLAYOUT:
1671 case SUMO_ATTR_TLID:
1672 return myNBNode->isTLControlled();
1673 case SUMO_ATTR_KEEP_CLEAR: {
1674 // check if at least there is an incoming connection
1675 for (const auto& incomingEdge : myGNEIncomingEdges) {
1676 if (incomingEdge->getGNEConnections().size() > 0) {
1677 return true;
1678 }
1679 }
1680 return false;
1681 }
1683 return false;
1684 default:
1685 return true;
1686 }
1687}
1688
1689
1690bool
1692 switch (key) {
1693 case SUMO_ATTR_SHAPE:
1694 return !myNBNode->hasCustomShape();
1695 default:
1696 return false;
1697 }
1698}
1699
1700
1701void
1703 myAmResponsible = newVal;
1704}
1705
1706// ===========================================================================
1707// private
1708// ===========================================================================
1709
1710bool
1711GNEJunction::drawAsBubble(const GUIVisualizationSettings& s, const double junctionShapeArea) const {
1712 const auto& editModes = myNet->getViewNet()->getEditModes();
1713 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
1714 // check conditions
1715 if (junctionShapeArea < 4) {
1716 // force draw if this junction is a candidate
1719 return true;
1720 }
1721 // force draw if we're in person/container plan mode
1722 if (editModes.isCurrentSupermodeDemand() &&
1723 ((editModes.demandEditMode == DemandEditMode::DEMAND_PERSON) ||
1724 (editModes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) ||
1725 (editModes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) ||
1726 (editModes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN))) {
1727 return true;
1728 }
1729 // force draw if we're inspecting a vehicle that start or ends in a junction
1730 if (inspectedElements.isInspectingSingleElement()) {
1731 // check if starts or ends in this junction
1732 if ((inspectedElements.getFirstAC()->hasAttribute(SUMO_ATTR_FROM_JUNCTION) &&
1733 (inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_FROM_JUNCTION) == getID())) ||
1734 (inspectedElements.getFirstAC()->hasAttribute(SUMO_ATTR_TO_JUNCTION) &&
1735 (inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_TO_JUNCTION) == getID()))) {
1736 return true;
1737 }
1738 }
1739 }
1740 if (!s.drawJunctionShape) {
1741 // don't draw bubble if it was disabled in GUIVisualizationSettings
1742 return false;
1743 }
1745 // force draw bubbles if we enabled option in checkbox of viewNet
1746 return true;
1747 }
1748 if (junctionShapeArea >= 4) {
1749 // don't draw if shape area is greater than 4
1750 return false;
1751 }
1752 if (!editModes.isCurrentSupermodeNetwork()) {
1753 // only draw bubbles in network mode
1754 return false;
1755 }
1756 return true;
1757}
1758
1759
1760void
1762 const double exaggeration) const {
1763 // calculate bubble radius
1764 const double bubbleRadius = s.neteditSizeSettings.junctionBubbleRadius * exaggeration;
1765 // set bubble color
1766 const RGBColor bubbleColor = setColor(s, true);
1767 if (bubbleColor.alpha() == 0) {
1768 // never draw when at full transparency (make sure no matrices have been pushed before return)
1769 return;
1770 }
1771 // push matrix
1773 // set color
1774 GLHelper::setColor(bubbleColor);
1775 // move matrix junction center
1776 glTranslated(myNBNode->getPosition().x(), myNBNode->getPosition().y(), 1.5);
1777 // draw filled circle
1778 GLHelper::drawFilledCircleDetailed(d, bubbleRadius);
1779 // pop matrix
1781}
1782
1783
1784void
1786 // first check drawing conditions
1787 if (s.drawJunctionShape && (myNBNode->getShape().size() > 0)) {
1788 // set shape color
1789 const RGBColor junctionShapeColor = setColor(s, false);
1790 if (junctionShapeColor.alpha() == 0) {
1791 // never draw when at full transparency (make sure no matrices have been pushed before return)
1792 return;
1793 }
1794 // set color
1795 GLHelper::setColor(junctionShapeColor);
1796 // adjust shape to exaggeration (check)
1797 if ((exaggeration > 1 || myExaggeration > 1) && exaggeration != myExaggeration) {
1798 myExaggeration = exaggeration;
1801 myTesselation.getShapeRef().scaleRelative(exaggeration);
1803 }
1804 // check if draw tesselation or or polygon
1806 // draw shape with high detail
1808 } else {
1809 // draw shape
1811 }
1812 // draw shape points only in Network supermode
1815 // set color
1816 const RGBColor darkerColor = junctionShapeColor.changedBrightness(-32);
1817 // calculate geometry
1818 GUIGeometry junctionGeometry;
1819 // obtain junction Shape
1820 PositionVector junctionOpenShape = myNBNode->getShape();
1821 // adjust shape to exaggeration
1822 if (exaggeration > 1) {
1823 junctionOpenShape.scaleRelative(exaggeration);
1824 }
1825 // update geometry
1826 junctionGeometry.updateGeometry(junctionOpenShape);
1827 // set color
1828 GLHelper::setColor(darkerColor);
1829 // draw shape
1831 // draw geometry points
1832 GUIGeometry::drawGeometryPoints(d, junctionOpenShape, darkerColor,
1835 }
1836 }
1837}
1838
1839
1840void
1843 // push matrix
1845 // set color
1846 GLHelper::setColor(setColor(s, true).changedBrightness(-20));
1847 // move matrix junction center
1848 glTranslated(myNBNode->getPosition().x(), myNBNode->getPosition().y(), 1.7);
1849 // draw filled circle
1851 // pop matrix
1853 }
1854}
1855
1856
1857void
1859 // draw TLS icon if isn't being drawn for selecting
1863 const Position pos = myNBNode->getPosition();
1864 glTranslated(pos.x(), pos.y(), 2.2);
1865 glColor3d(1, 1, 1);
1866 const double halfWidth = 32 / s.scale;
1867 const double halfHeight = 64 / s.scale;
1868 GUITexturesHelper::drawTexturedBox(GUITextureSubSys::getTexture(GUITexture::TLS), -halfWidth, -halfHeight, halfWidth, halfHeight);
1870 }
1871}
1872
1873
1874void
1876 // check if draw elevation
1879 // Translate to center of junction
1880 glTranslated(myNBNode->getPosition().x(), myNBNode->getPosition().y(), 0.1);
1881 // draw Z value
1884 }
1885}
1886
1887
1888void
1895
1896
1897void
1899 // draw crossings
1900 for (const auto& crossing : myGNECrossings) {
1901 crossing->drawGL(s);
1902 }
1903 // draw walking areas
1904 for (const auto& walkingArea : myGNEWalkingAreas) {
1905 walkingArea->drawGL(s);
1906 }
1907 // draw internalLanes
1908 for (const auto& internalLanes : myInternalLanes) {
1909 internalLanes->drawGL(s);
1910 }
1911 // draw connections
1912 for (const auto& incomingEdge : myGNEIncomingEdges) {
1913 for (const auto& connection : incomingEdge->getGNEConnections()) {
1914 connection->drawGL(s);
1915 }
1916 }
1917 // draw child demand elements
1918 for (const auto& demandElement : getChildDemandElements()) {
1919 demandElement->drawGL(s);
1920 }
1921 // draw child demand elements
1922 for (const auto& demandElement : getChildDemandElements()) {
1923 demandElement->drawGL(s);
1924 }
1925 // draw path additional elements
1929}
1930
1931
1932void
1934 const double exaggeration, const bool drawBubble) const {
1935 // if we're selecting using a boundary, first don't calculate contour bt check if edge boundary is within selection boundary
1937 // simply add object in ViewObjectsHandler with full boundary
1938 gViewObjectsHandler.selectObject(s, this, getType(), false, nullptr);
1939 } else {
1940 // always calculate for shape
1941 myNetworkElementContour.calculateContourClosedShape(s, d, this, myNBNode->getShape(), getType(), exaggeration, this);
1942 // check if calculate contour for bubble
1943 if (drawBubble) {
1945 }
1946 // check geometry points if we're editing shape
1947 if (myShapeEdited) {
1949 exaggeration, true);
1950 }
1951 }
1952}
1953
1954
1955void
1956GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value) {
1957 switch (key) {
1958 case SUMO_ATTR_KEEP_CLEAR: {
1959 throw InvalidArgument(toString(key) + " cannot be edited");
1960 }
1961 case SUMO_ATTR_ID: {
1963 break;
1964 }
1965 case SUMO_ATTR_TYPE: {
1970 }
1972 break;
1973 }
1974 case SUMO_ATTR_POSITION: {
1975 // set new position in NBNode updating edge boundaries
1976 moveJunctionGeometry(parse<Position>(value), true);
1977 // mark this connections and all of the junction's Neighbours as deprecated
1979 // update centering boundary and grid
1980 if (myGNEIncomingEdges.size() + myGNEOutgoingEdges.size() > 0) {
1982 } else {
1984 }
1985 break;
1986 }
1988 if (myLogicStatus == FEATURE_GUESSED && value != FEATURE_GUESSED) {
1989 // clear guessed connections. previous connections will be restored
1991 // Clear GNEConnections of incoming edges
1992 for (const auto& i : myGNEIncomingEdges) {
1993 i->clearGNEConnections();
1994 }
1995 }
1996 myLogicStatus = value;
1997 break;
1998 case SUMO_ATTR_SHAPE: {
1999 // set new shape (without updating grid)
2000 myNBNode->setCustomShape(parse<PositionVector>(value));
2001 // mark this connections and all of the junction's neighbors as deprecated
2003 // update centering boundary and grid
2005 break;
2006 }
2007 case SUMO_ATTR_RADIUS: {
2008 if (value.empty() || (value == "default")) {
2009 myNBNode->setRadius(-1);
2010 } else {
2011 myNBNode->setRadius(parse<double>(value));
2012 }
2013 break;
2014 }
2015 case SUMO_ATTR_TLTYPE: {
2016 // we need to make a copy of controlling TLS (because original will be updated)
2017 const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode->getControllingTLS();
2018 for (const auto& TLS : copyOfTls) {
2019 TLS->setType(SUMOXMLDefinitions::TrafficLightTypes.get(value));
2020 }
2021 break;
2022 }
2023 case SUMO_ATTR_TLLAYOUT:
2024 // should not be triggered (handled via GNEChange_TLS)
2025 break;
2028 break;
2029 case SUMO_ATTR_FRINGE:
2031 break;
2034 break;
2035 case SUMO_ATTR_NAME:
2036 myNBNode->setName(value);
2037 break;
2038 default:
2039 setCommonAttribute(key, value);
2040 break;
2041 }
2042 // invalidate demand path calculator
2044}
2045
2046
2047double
2048GNEJunction::getColorValue(const GUIVisualizationSettings& /* s */, int activeScheme) const {
2049 switch (activeScheme) {
2050 case 0:
2052 return 3;
2053 } else {
2054 return 0;
2055 }
2056 case 1:
2058 case 2:
2059 switch (myNBNode->getType()) {
2061 return 0;
2063 return 1;
2065 return 2;
2067 return 3;
2069 return 4;
2071 return 5;
2073 return 6;
2075 return 7;
2078 return 8;
2080 return 8; // may happen before first network computation
2082 assert(false);
2083 return 8;
2085 return 9;
2087 return 10;
2089 return 11;
2091 return 12;
2093 return 13;
2094 default:
2095 assert(false);
2096 return 0;
2097 }
2098 case 3:
2099 return myNBNode->getPosition().z();
2100 default:
2101 assert(false);
2102 return 0;
2103 }
2104}
2105
2106void
2108 for (auto edge : myGNEIncomingEdges) {
2109 if (edge->getGNEConnections().size() > 0) {
2111 return;
2112 }
2113 }
2114 // no connections. Use normal color for border edges and cul-de-sac
2115 if (myGNEIncomingEdges.size() == 0 || myGNEOutgoingEdges.size() == 0) {
2117 return;
2118 } else if (myGNEIncomingEdges.size() == 1 && myGNEOutgoingEdges.size() == 1) {
2119 NBEdge* in = myGNEIncomingEdges[0]->getNBEdge();
2120 NBEdge* out = myGNEOutgoingEdges[0]->getNBEdge();
2121 if (in->isTurningDirectionAt(out)) {
2123 return;
2124 }
2125 }
2127}
2128
2129
2130void
2131GNEJunction::moveJunctionGeometry(const Position& pos, const bool updateEdgeBoundaries) {
2132 // reinit NBNode
2133 myNBNode->reinit(pos, myNBNode->getType());
2134 // declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
2135 std::set<GNEJunction*> affectedJunctions;
2136 std::set<GNEEdge*> affectedEdges;
2137 // Iterate over GNEEdges
2138 for (const auto& edge : getChildEdges()) {
2139 // Add source and destination junctions
2140 affectedJunctions.insert(edge->getFromJunction());
2141 affectedJunctions.insert(edge->getToJunction());
2142 // Obtain neighbors of Junction source
2143 for (const auto& junctionSourceEdge : edge->getFromJunction()->getChildEdges()) {
2144 affectedEdges.insert(junctionSourceEdge);
2145 }
2146 // Obtain neighbors of Junction destination
2147 for (const auto& junctionDestinationEdge : edge->getToJunction()->getChildEdges()) {
2148 affectedEdges.insert(junctionDestinationEdge);
2149 }
2150 }
2151 // reset walking areas of affected edges
2152 for (const auto& affectedJunction : affectedJunctions) {
2153 affectedJunction->clearWalkingAreas();
2154 }
2155 // Iterate over affected Edges
2156 for (const auto& affectedEdge : affectedEdges) {
2157 // update edge boundaries
2158 if (updateEdgeBoundaries) {
2159 affectedEdge->updateCenteringBoundary(true);
2160 }
2161 // Update edge geometry
2162 affectedEdge->updateGeometry();
2163 }
2164}
2165
2166
2169 // get active scheme
2170 const int scheme = s.junctionColorer.getActive();
2171 // first check if we're editing shape
2172 if (myShapeEdited) {
2173 return s.junctionColorer.getScheme().getColor(4);
2174 }
2175 // set default color
2177 // set special bubble color
2178 if (bubble && (scheme == 0) && !myColorForMissingConnections) {
2179 color = s.junctionColorer.getScheme().getColor(1);
2180 }
2181 // override with special colors (unless the color scheme is based on selection)
2182 if (drawUsingSelectColor() && scheme != 1) {
2183 color = s.colorSettings.selectionColor;
2184 }
2185 // overwrite color if we're in data mode
2187 color = s.junctionColorer.getScheme().getColor(6);
2188 }
2189 // special color for source candidate junction
2190 if (mySourceCandidate) {
2192 }
2193 // special color for target candidate junction
2194 if (myTargetCandidate) {
2196 }
2197 // special color for special candidate junction
2198 if (mySpecialCandidate) {
2200 }
2201 // special color for possible candidate junction
2202 if (myPossibleCandidate) {
2204 }
2205 // special color for conflicted candidate junction
2208 }
2209 // return color
2210 return color;
2211}
2212
2213
2214void
2217 tlCont.insert(tlDef, forceInsert); // may return false for tlDef which controls multiple junctions
2218 tlDef->addNode(myNBNode);
2219}
2220
2221
2222void
2225 if (tlDef->getNodes().size() == 1) {
2226 tlCont.extract(tlDef);
2227 }
2229}
2230
2231
2232/****************************************************************************/
@ 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 drawFilledCircleDetailed(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 drawSymbols, 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, const bool allowDelete, const bool addSeparator)
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:3810
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition NBEdge.cpp:4172
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:137
EdgeVector edges
The edges being crossed.
Definition NBNode.h:144
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:302
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:347
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
Definition NBNode.cpp:361
static const double UNSPECIFIED_RADIUS
unspecified lane width
Definition NBNode.h:222
FringeType getFringeType() const
Returns fringe type.
Definition NBNode.h:307
void buildCrossingsAndWalkingAreas()
build crossings, and walkingareas. Also removes invalid loaded crossings if wished
Definition NBNode.cpp:3058
SumoXMLNodeType getType() const
Returns the type of this node.
Definition NBNode.h:287
bool isTrafficLight() const
Definition NBNode.h:841
void setRoundaboutType(RoundaboutType roundaboutType)
set roundabout type
Definition NBNode.h:593
void setRightOfWay(RightOfWay rightOfWay)
set method for computing right-of-way
Definition NBNode.h:583
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition NBNode.cpp:2798
void invalidateIncomingConnections(bool reallowSetting=false)
invalidate incoming connections
Definition NBNode.cpp:2137
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
Definition NBNode.h:270
void mirrorX()
mirror coordinates along the x-axis
Definition NBNode.cpp:418
std::vector< std::pair< Position, std::string > > getEndPoints() const
return list of unique endpoint coordinates of all edges at this node
Definition NBNode.cpp:4379
const std::vector< std::unique_ptr< Crossing > > & getCrossingsIncludingInvalid() const
Definition NBNode.h:761
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
Definition NBNode.h:275
bool hasCustomShape() const
return whether the shape was set by the user
Definition NBNode.h:603
std::vector< Crossing * > getCrossings() const
return this junctions pedestrian crossings
Definition NBNode.cpp:3107
const std::string & getName() const
Returns intersection name.
Definition NBNode.h:317
void setRadius(double radius)
set the turning radius
Definition NBNode.h:573
void setName(const std::string &name)
set intersection name
Definition NBNode.h:598
const Position & getPosition() const
Definition NBNode.h:262
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
Definition NBNode.cpp:447
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node)
Definition NBNode.h:280
const PositionVector & getShape() const
retrieve the junction shape
Definition NBNode.cpp:2792
RoundaboutType getRoundaboutType() const
Returns roundabout type.
Definition NBNode.h:312
double getRadius() const
Returns the turning radius of this node.
Definition NBNode.h:292
bool isRoundabout() const
return whether this node is part of a roundabout
Definition NBNode.cpp:4079
bool checkIsRemovableReporting(std::string &reason) const
check if node is removable and return reason if not
Definition NBNode.cpp:2679
const std::vector< WalkingArea > & getWalkingAreas() const
return this junctions pedestrian walking areas
Definition NBNode.h:766
PositionVector myPoly
the (outer) shape of the junction
Definition NBNode.h:974
void setFringeType(FringeType fringeType)
set fringe type
Definition NBNode.h:588
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition NBNode.h:338
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:96
RGBColor changedBrightness(int change, int toChange=3) const
Returns a new color with altered brightness.
Definition RGBColor.cpp:210
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:79
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