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