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.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
15 // A class for visualizing and editing junctions in netedit (adapted from
16 // GUIJunctionWrapper)
17 /****************************************************************************/
18 
19 
20 // ===========================================================================
21 // included modules
22 // ===========================================================================
23 #include <config.h>
24 
25 #include <netbuild/NBAlgorithms.h>
27 #include <netbuild/NBNetBuilder.h>
28 #include <netbuild/NBOwnTLDef.h>
29 #include <netedit/GNENet.h>
30 #include <netedit/GNEUndoList.h>
31 #include <netedit/GNEViewNet.h>
37 #include <utils/gui/div/GLHelper.h>
43 
44 #include "GNEEdge.h"
45 #include "GNEConnection.h"
46 #include "GNEJunction.h"
47 #include "GNECrossing.h"
48 
49 
50 // ===========================================================================
51 // static members
52 // ===========================================================================
53 
54 const double GNEJunction::BUBBLE_RADIUS(4);
55 
56 // ===========================================================================
57 // method definitions
58 // ===========================================================================
59 
60 GNEJunction::GNEJunction(NBNode& nbn, GNENet* net, bool loaded) :
61  GNENetElement(net, nbn.getID(), GLO_JUNCTION, SUMO_TAG_JUNCTION),
62  myNBNode(nbn),
63  myAmCreateEdgeSource(false),
64  myLogicStatus(loaded ? FEATURE_LOADED : FEATURE_GUESSED),
65  myAmResponsible(false),
66  myHasValidLogic(loaded),
67  myAmTLSSelected(false) {
68 }
69 
70 
72  // delete all GNECrossing
73  for (auto it : myGNECrossings) {
74  it->decRef();
75  if (it->unreferenced()) {
76  // show extra information for tests
77  WRITE_DEBUG("Deleting unreferenced " + it->getTagStr() + " '" + it->getID() + "' in GNEJunction destructor");
78  delete it;
79  }
80  }
81 
82  if (myAmResponsible) {
83  // show extra information for tests
84  WRITE_DEBUG("Deleting NBNode of '" + getID() + "' in GNEJunction destructor");
85  delete &myNBNode;
86  }
87 }
88 
89 
90 std::string
92  int counter = 0;
93  while (myNet->retrieveJunction(getID() + toString(childTag) + toString(counter), false) != nullptr) {
94  counter++;
95  }
96  return (getID() + toString(childTag) + toString(counter));
97 }
98 
99 
100 void
103 }
104 
105 void
106 GNEJunction::updateGeometryAfterNetbuild(bool rebuildNBNodeCrossings) {
107  myMaxSize = MAX2(getCenteringBoundary().getWidth(), getCenteringBoundary().getHeight());
108  rebuildGNECrossings(rebuildNBNodeCrossings);
109 }
110 
111 
112 Position
114  return myNBNode.getPosition();
115 }
116 
117 
118 void
119 GNEJunction::rebuildGNECrossings(bool rebuildNBNodeCrossings) {
120  // rebuild GNECrossings only if create crossings and walkingAreas in net is enabled
122  if (rebuildNBNodeCrossings) {
123  // build new NBNode::Crossings and walking areas
124  mirrorXLeftHand();
126  mirrorXLeftHand();
127  }
128  // create a vector to keep retrieved and created crossings
129  std::vector<GNECrossing*> retrievedCrossings;
130  // iterate over NBNode::Crossings of GNEJunction
131  for (auto NBc : myNBNode.getCrossingsIncludingInvalid()) {
132  // retrieve existent GNECrossing, or create it
133  GNECrossing* retrievedGNECrossing = retrieveGNECrossing(NBc);
134  retrievedCrossings.push_back(retrievedGNECrossing);
135  // check if previously this GNECrossings exists, and if true, remove it from myGNECrossings and insert in tree again
136  std::vector<GNECrossing*>::iterator retrievedExists = std::find(myGNECrossings.begin(), myGNECrossings.end(), retrievedGNECrossing);
137  if (retrievedExists != myGNECrossings.end()) {
138  myGNECrossings.erase(retrievedExists);
139  // update geometry of retrieved crossing
140  retrievedGNECrossing->updateGeometry();
141  } else {
142  // include reference to created GNECrossing
143  retrievedGNECrossing->incRef();
144  }
145  }
146  // delete non retrieved GNECrossings (we don't need to extract if from Tree two times)
147  for (auto it : myGNECrossings) {
148  it->decRef();
149  // check if crossing is selected
150  if (it->isAttributeCarrierSelected()) {
151  it->unselectAttributeCarrier();
152  }
153  if (it->unreferenced()) {
154  // show extra information for tests
155  WRITE_DEBUG("Deleting unreferenced " + it->getTagStr() + " in rebuildGNECrossings()");
156  delete it;
157  }
158  }
159  // copy retrieved (existent and created) GNECrossigns to myGNECrossings
160  myGNECrossings = retrievedCrossings;
161  }
162 }
163 
164 void
166  if (OptionsCont::getOptions().getBool("lefthand")) {
167  myNBNode.mirrorX();
168  for (NBEdge* e : myNBNode.getEdges()) {
169  e->mirrorX();
170 
171  }
172  }
173 }
174 
175 
178  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
179  buildPopupHeader(ret, app);
182  // build selection and show parameters menu
185  buildPositionCopyEntry(ret, false);
186  //if (parent.getVisualisationSettings()->editMode != GNE_MODE_CONNECT) {
187  // // XXX if joinable
188  // new FXMenuCommand(ret, "Join adjacent edges", 0, &parent, MID_GNE_JOIN_EDGES);
189  //}
190  const int numEndpoints = (int)myNBNode.getEndPoints().size();
191  // check if we're handling a selection
192  bool handlingSelection = isAttributeCarrierSelected() && (myNet->retrieveJunctions(true).size() > 1);
193  // check if menu commands has to be disabled
194  const bool wrongMode = (myNet->getViewNet()->getEditModes().networkEditMode == GNE_NMODE_CONNECT) ||
197  // create menu commands
198  FXMenuCommand* mcCustomShape = new FXMenuCommand(ret, "Set custom junction shape", nullptr, &parent, MID_GNE_JUNCTION_EDIT_SHAPE);
199  FXMenuCommand* mcResetCustomShape = new FXMenuCommand(ret, "Reset junction shape", nullptr, &parent, MID_GNE_JUNCTION_RESET_SHAPE);
200  FXMenuCommand* mcReplace = new FXMenuCommand(ret, "Replace junction by geometry point", nullptr, &parent, MID_GNE_JUNCTION_REPLACE);
201  FXMenuCommand* mcSplit = new FXMenuCommand(ret, ("Split junction (" + toString(numEndpoints) + " end points)").c_str(), nullptr, &parent, MID_GNE_JUNCTION_SPLIT);
202  FXMenuCommand* mcSplitReconnect = new FXMenuCommand(ret, "Split junction and reconnect", nullptr, &parent, MID_GNE_JUNCTION_SPLIT_RECONNECT);
203  FXMenuCommand* mcClearConnections = new FXMenuCommand(ret, "Clear connections", nullptr, &parent, MID_GNE_JUNCTION_CLEAR_CONNECTIONS);
204  FXMenuCommand* mcResetConnections = new FXMenuCommand(ret, "Reset connections", nullptr, &parent, MID_GNE_JUNCTION_RESET_CONNECTIONS);
205  // check if current mode is correct
206  if (wrongMode) {
207  mcCustomShape->disable();
208  mcClearConnections->disable();
209  mcResetConnections->disable();
210  }
211  // check if we're handling a selection
212  if (handlingSelection) {
213  mcResetCustomShape->setText("Reset junction shapes");
214  }
215  // disable mcClearConnections if juction hasn't connections
216  if (getGNEConnections().empty()) {
217  mcClearConnections->disable();
218  }
219  // disable mcResetCustomShape if junction doesn't have a custom shape
220  if (myNBNode.getShape().size() == 0) {
221  mcResetCustomShape->disable();
222  }
223  // checkIsRemovable requiers turnarounds to be computed. This is ugly
224  if ((myNBNode.getIncomingEdges().size() == 2) && (myNBNode.getOutgoingEdges().size() == 2)) {
226  }
227  std::string reason = "wrong edit mode";
228  if (wrongMode || !myNBNode.checkIsRemovableReporting(reason)) {
229  mcReplace->setText(mcReplace->getText() + " (" + reason.c_str() + ")");
230  mcReplace->disable();
231  }
232  if (numEndpoints == 1) {
233  mcSplit->disable();
234  mcSplitReconnect->disable();
235  }
236  return ret;
237 }
238 
239 
240 Boundary
242  // Return Boundary depending if myMovingGeometryBoundary is initialised (important for move geometry)
245  } else if (myNBNode.getShape().size() > 0) {
247  b.grow(10);
248  return b;
249  } else {
250  // calculate boundary using EXTENT as size
251  const double EXTENT = 2;
252  Boundary b(myNBNode.getPosition().x() - EXTENT, myNBNode.getPosition().y() - EXTENT,
253  myNBNode.getPosition().x() + EXTENT, myNBNode.getPosition().y() + EXTENT);
254  b.grow(10);
255  return b;
256  }
257 }
258 
259 
260 void
262  // check if boundary has to be drawn
263  if (s.drawBoundaries) {
265  }
266  // declare variables
267  double exaggeration = isAttributeCarrierSelected() ? s.selectionScale : 1;
268  exaggeration *= s.junctionSize.getExaggeration(s, this, 4);
269  // declare values for circles
270  double circleWidth = BUBBLE_RADIUS * exaggeration;
271  double circleWidthSquared = circleWidth * circleWidth;
272  // push name
273  if (s.scale * exaggeration * myMaxSize < 1.) {
274  // draw something simple so that selection still works
275  glPushName(getGlID());
277  glPopName();
278  } else {
279  // node shape has been computed and is valid for drawing
280  glPushName(getGlID());
281  // declare flag for drawing junction shape
282  const bool drawShape = (myNBNode.getShape().size() > 0) && s.drawJunctionShape;
283  // declare flag for drawing junction as bubbles
284  bool drawBubble = (!drawShape || (myNBNode.getShape().area() < 4)) && s.drawJunctionShape;
285  // check if show junctions as bubbles checkbox is enabled
287  drawBubble = true;
288  }
289  // in supermode demand Bubble musn't be drawn
291  drawBubble = false;
292  }
293  // check if shape has to be drawn
294  if (drawShape) {
295  RGBColor color = setColor(s, false);
296  // recognize full transparency and simply don't draw
297  if (color.alpha() != 0) {
298  glPushMatrix();
299  glTranslated(0, 0, getType());
300  PositionVector shape = myNBNode.getShape();
301  shape.closePolygon();
302  if (exaggeration > 1) {
303  shape.scaleRelative(exaggeration);
304  }
305  if ((s.drawForSelecting) || (s.scale * exaggeration * myMaxSize < 40.)) {
306  GLHelper::drawFilledPoly(shape, true);
307  } else {
309  }
310  // check if dotted contour has to be drawn
311  if ((myNet->getViewNet()->getDottedAC() == this) && !drawBubble) {
313  }
314  glPopMatrix();
315  }
316  }
317  // check if bubble has to be drawn
318  if (drawBubble) {
319  RGBColor color = setColor(s, true);
320  // recognize full transparency and simply don't draw
321  if (color.alpha() != 0) {
322  glPushMatrix();
323  glTranslated(myNBNode.getPosition().x(), myNBNode.getPosition().y(), getType() + 0.05);
324  if (!s.drawForSelecting || (myNet->getViewNet()->getPositionInformation().distanceSquaredTo2D(myNBNode.getPosition()) <= (circleWidthSquared + 2))) {
325  std::vector<Position> vertices = GLHelper::drawFilledCircleReturnVertices(circleWidth, s.getCircleResolution());
326  // check if dotted contour has to be drawn
327  if (myNet->getViewNet()->getDottedAC() == this) {
329  }
330  } else {
331  GLHelper::drawBoxLine(Position(0, 1), 0, 2, 1);
332  }
333  glPopMatrix();
334  }
335  }
336  // draw TLS icon if isn't being drawn for selecting
339  glPushMatrix();
340  Position pos = myNBNode.getPosition();
341  glTranslated(pos.x(), pos.y(), getType() + 0.1);
342  glColor3d(1, 1, 1);
343  const double halfWidth = 32 / s.scale;
344  const double halfHeight = 64 / s.scale;
345  GUITexturesHelper::drawTexturedBox(GUITextureSubSys::getTexture(GNETEXTURE_TLS), -halfWidth, -halfHeight, halfWidth, halfHeight);
346  glPopMatrix();
347  }
348  // (optional) draw name @todo expose this setting if isn't drawed if isn't being drawn for selecting
349  if (!s.drawForSelecting) {
351  }
352  // draw elevation
354  glPushMatrix();
355  // Translate to center of junction
356  glTranslated(myNBNode.getPosition().x(), myNBNode.getPosition().y(), getType() + 1);
357  // draw Z value
359  glPopMatrix();
360  }
361  // name must be removed from selection stack before drawing crossings
362  glPopName();
363  // draw crossings only if junction isn't being moved
365  for (const auto& i : myGNECrossings) {
366  i->drawGL(s);
367  }
368  }
369  // draw connections and route elements connections (Only for incoming edges)
370  for (const auto& i : myGNEIncomingEdges) {
371  // first draw connections
372  for (const auto& j : i->getGNEConnections()) {
373  j->drawGL(s);
374  }
375  // first check if Demand elements can be shown
377  // certain demand elements children can contain loops (for example, routes) and it causes overlapping problems. It's needed to filter it before drawing
378  for (const auto& j : i->getSortedDemandElementChildrenByType(SUMO_TAG_ROUTE)) {
379  // first check if route can be drawn
381  // draw partial route
382  i->drawPartialRoute(s, j, this);
383  }
384  }
385  for (const auto& j : i->getSortedDemandElementChildrenByType(SUMO_TAG_EMBEDDEDROUTE)) {
386  // first check if embedded route can be drawn
388  // draw partial route
389  i->drawPartialRoute(s, j, this);
390  }
391  }
392  for (const auto& j : i->getSortedDemandElementChildrenByType(SUMO_TAG_TRIP)) {
393  // Start drawing adding an gl identificator
394  glPushName(j->getGlID());
395  // draw partial trip only if is being inspected or selected
396  if ((myNet->getViewNet()->getDottedAC() == j) || j->isAttributeCarrierSelected()) {
397  i->drawPartialTripFromTo(s, j, this);
398  }
399  // only draw trip in the first edge
400  if (j->getAttribute(SUMO_ATTR_FROM) == getID()) {
401  j->drawGL(s);
402  }
403  // Pop name
404  glPopName();
405  }
406  for (const auto& j : i->getSortedDemandElementChildrenByType(SUMO_TAG_FLOW)) {
407  // Start drawing adding an gl identificator
408  glPushName(j->getGlID());
409  // draw partial trip only if is being inspected or selected
410  if ((myNet->getViewNet()->getDottedAC() == j) || j->isAttributeCarrierSelected()) {
411  i->drawPartialTripFromTo(s, j, this);
412  }
413  // only draw flow in the first edge
414  if (j->getAttribute(SUMO_ATTR_FROM) == getID()) {
415  j->drawGL(s);
416  }
417  // Pop name
418  glPopName();
419  }
420  // draw partial person plan elements
421  for (const auto& j : i->getSortedDemandElementChildrenByType(SUMO_TAG_PERSONTRIP_FROMTO)) {
422  i->drawPartialPersonPlan(s, j, this);
423  }
424  for (const auto& j : i->getSortedDemandElementChildrenByType(SUMO_TAG_PERSONTRIP_BUSSTOP)) {
425  i->drawPartialPersonPlan(s, j, this);
426  }
427  for (const auto& j : i->getSortedDemandElementChildrenByType(SUMO_TAG_WALK_EDGES)) {
428  i->drawPartialPersonPlan(s, j, this);
429  }
430  for (const auto& j : i->getSortedDemandElementChildrenByType(SUMO_TAG_WALK_FROMTO)) {
431  i->drawPartialPersonPlan(s, j, this);
432  }
433  for (const auto& j : i->getSortedDemandElementChildrenByType(SUMO_TAG_WALK_BUSSTOP)) {
434  i->drawPartialPersonPlan(s, j, this);
435  }
436  for (const auto& j : i->getSortedDemandElementChildrenByType(SUMO_TAG_WALK_ROUTE)) {
437  i->drawPartialPersonPlan(s, j, this);
438  }
439  for (const auto& j : i->getSortedDemandElementChildrenByType(SUMO_TAG_RIDE_FROMTO)) {
440  i->drawPartialPersonPlan(s, j, this);
441  }
442  for (const auto& j : i->getSortedDemandElementChildrenByType(SUMO_TAG_RIDE_BUSSTOP)) {
443  i->drawPartialPersonPlan(s, j, this);
444  }
445  }
446  }
447  }
448 }
449 
450 
451 NBNode*
453  return &myNBNode;
454 }
455 
456 
457 std::vector<GNEJunction*>
459  // use set to avoid duplicates junctions
460  std::set<GNEJunction*> junctions;
461  for (auto i : myGNEIncomingEdges) {
462  junctions.insert(i->getGNEJunctionSource());
463  }
464  for (auto i : myGNEOutgoingEdges) {
465  junctions.insert(i->getGNEJunctionDestiny());
466  }
467  return std::vector<GNEJunction*>(junctions.begin(), junctions.end());
468 }
469 
470 
471 void
473  // Check if incoming edge was already inserted
474  std::vector<GNEEdge*>::iterator i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
475  if (i != myGNEIncomingEdges.end()) {
476  throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + getTagStr() + " with ID " + getID() + "'");
477  } else {
478  // Add edge into containers
479  myGNEIncomingEdges.push_back(edge);
480  myGNEEdges.push_back(edge);
481  }
482 }
483 
484 
485 
486 void
488  // Check if outgoing edge was already inserted
489  std::vector<GNEEdge*>::iterator i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
490  if (i != myGNEOutgoingEdges.end()) {
491  throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + getTagStr() + " with ID " + getID() + "'");
492  } else {
493  // Add edge into containers
494  myGNEOutgoingEdges.push_back(edge);
495  myGNEEdges.push_back(edge);
496  }
497 }
498 
499 
500 void
502  // Check if incoming edge was already inserted
503  std::vector<GNEEdge*>::iterator i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
504  if (i == myGNEIncomingEdges.end()) {
505  throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + getTagStr() + " with ID " + getID() + "'");
506  } else {
507  // remove edge from containers
508  myGNEIncomingEdges.erase(i);
509  myGNEEdges.erase(std::find(myGNEEdges.begin(), myGNEEdges.end(), edge));
510  }
511 }
512 
513 
514 void
516  // Check if outgoing edge was already inserted
517  std::vector<GNEEdge*>::iterator i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
518  if (i == myGNEOutgoingEdges.end()) {
519  throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + getTagStr() + " with ID " + getID() + "'");
520  } else {
521  // remove edge from containers
522  myGNEOutgoingEdges.erase(i);
523  myGNEEdges.erase(std::find(myGNEEdges.begin(), myGNEEdges.end(), edge));
524  }
525 }
526 
527 
528 const std::vector<GNEEdge*>&
530  return myGNEEdges;
531 }
532 
533 
534 const std::vector<GNEEdge*>&
536  return myGNEIncomingEdges;
537 }
538 
539 
540 const std::vector<GNEEdge*>&
542  return myGNEOutgoingEdges;
543 }
544 
545 
546 const std::vector<GNECrossing*>&
548  return myGNECrossings;
549 }
550 
551 
552 std::vector<GNEConnection*>
554  std::vector<GNEConnection*> connections;
555  for (auto i : myGNEIncomingEdges) {
556  for (auto j : i->getGNEConnections()) {
557  connections.push_back(j);
558  }
559  }
560  return connections;
561 }
562 
563 
564 void
566  myAmCreateEdgeSource = true;
567 }
568 
569 
570 void
572  myAmCreateEdgeSource = false;
573 }
574 
575 
576 void
577 GNEJunction::selectTLS(bool selected) {
578  myAmTLSSelected = selected;
579 }
580 
581 
582 void
583 GNEJunction::startGeometryMoving(bool extendToNeighbors) {
584  // save current centering boundary
586  // First declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
587  std::set<GNEJunction*> affectedJunctions;
588  std::set<GNEEdge*> affectedEdges;
589  // Iterate over GNEEdges
590  for (auto i : myGNEEdges) {
591  // Add source and destiny junctions
592  affectedJunctions.insert(i->getGNEJunctionSource());
593  affectedJunctions.insert(i->getGNEJunctionDestiny());
594  // Obtain neighbors of Junction source
595  for (auto j : i->getGNEJunctionSource()->getGNEEdges()) {
596  affectedEdges.insert(j);
597  }
598  // Obtain neighbors of Junction destiny
599  for (auto j : i->getGNEJunctionDestiny()->getGNEEdges()) {
600  affectedEdges.insert(j);
601  }
602  }
603  // Iterate over affected Junctions only if extendToNeighbors is enabled
604  if (extendToNeighbors) {
605  for (auto i : affectedJunctions) {
606  // don't include this junction (to avoid start more than one times)
607  if (i != this) {
608  // start geometry moving in edges
609  i->startGeometryMoving(false);
610  }
611  }
612  }
613  // Iterate over affected Edges
614  for (auto i : affectedEdges) {
615  // start geometry moving in edges
616  i->startGeometryMoving();
617  }
618 }
619 
620 
621 void
622 GNEJunction::endGeometryMoving(bool extendToNeighbors) {
623  // check that endGeometryMoving was called only once
625  // Remove object from net
627  // reset myMovingGeometryBoundary
629  // First declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
630  std::set<GNEJunction*> affectedJunctions;
631  std::set<GNEEdge*> affectedEdges;
632  // Iterate over GNEEdges
633  for (auto i : myGNEEdges) {
634  // Add source and destiny junctions
635  affectedJunctions.insert(i->getGNEJunctionSource());
636  affectedJunctions.insert(i->getGNEJunctionDestiny());
637  // Obtain neighbors of Junction source
638  for (auto j : i->getGNEJunctionSource()->getGNEEdges()) {
639  affectedEdges.insert(j);
640  }
641  // Obtain neighbors of Junction destiny
642  for (auto j : i->getGNEJunctionDestiny()->getGNEEdges()) {
643  affectedEdges.insert(j);
644  }
645  }
646  // Iterate over affected Junctions
647  if (extendToNeighbors) {
648  for (auto i : affectedJunctions) {
649  // don't include this junction (to avoid end it more than one times)
650  if (i != this) {
651  // end geometry moving in edges
652  i->endGeometryMoving(false);
653  }
654  }
655  }
656  // Iterate over affected Edges
657  for (auto i : affectedEdges) {
658  // end geometry moving in edges
659  i->endGeometryMoving();
660  }
661  // add object into grid again (using the new centering boundary)
662  myNet->addGLObjectIntoGrid(this);
663  }
664 }
665 
666 
667 void
668 GNEJunction::moveGeometry(const Position& oldPos, const Position& offset) {
669  // Abort moving if there is another junction in the exactly target position
670  bool abort = false;
671  std::vector<GNEJunction*> junctionNeighbours = getJunctionNeighbours();
672  for (auto i : junctionNeighbours) {
673  if (i->getPositionInView() == myNBNode.getPosition()) {
674  abort = true;
675  }
676  }
677  if (!abort) {
678  // calculate new position
679  Position newPosition = oldPos;
680  newPosition.add(offset);
681  // filtern position using snap to active grid
682  newPosition = myNet->getViewNet()->snapToActiveGrid(newPosition, offset.z() == 0);
683  // move junction geometry without updating grid
684  moveJunctionGeometry(newPosition);
685  }
686 }
687 
688 
689 void
691  // first end geometry point
694  undoList->p_begin("position of " + getTagStr());
695  undoList->p_add(new GNEChange_Attribute(this, myNet, SUMO_ATTR_POSITION, toString(myNBNode.getPosition()), true, toString(oldPos)));
696  undoList->p_end();
697  } else {
698  // tried to set an invalid position, revert back to the previous one
699  moveJunctionGeometry(oldPos);
700  }
701 }
702 
703 
704 void
706  if (!myNBNode.hasCustomShape()) {
707  if (myNBNode.myPoly.size() > 0) {
708  // write GL Debug
709  WRITE_GLDEBUG("<-- Invalidating shape of junction '" + getID() + "' -->");
710  // remove Juntion from grid
712  // clear poly
713  myNBNode.myPoly.clear();
714  // add Juntion into grid
715  myNet->addGLObjectIntoGrid(this);
716  }
718  }
719 }
720 
721 
722 void
723 GNEJunction::setLogicValid(bool valid, GNEUndoList* undoList, const std::string& status) {
724  myHasValidLogic = valid;
725  if (!valid) {
726  assert(undoList != 0);
727  assert(undoList->hasCommandGroup());
729  EdgeVector incoming = myNBNode.getIncomingEdges();
730  for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
731  GNEEdge* srcEdge = myNet->retrieveEdge((*it)->getID());
732  removeConnectionsFrom(srcEdge, undoList, false); // false, because the whole tls will be invalidated at the end
733  undoList->add(new GNEChange_Attribute(srcEdge, myNet, GNE_ATTR_MODIFICATION_STATUS, status), true);
734  }
735  undoList->add(new GNEChange_Attribute(this, myNet, GNE_ATTR_MODIFICATION_STATUS, status), true);
736  invalidateTLS(undoList);
737  } else {
738  // logic valed, then rebuild GNECrossings to adapt it to the new logic
739  // (but don't rebuild the crossings in NBNode because they are already finished)
740  rebuildGNECrossings(false);
741  }
742 }
743 
744 
745 void
746 GNEJunction::removeConnectionsFrom(GNEEdge* edge, GNEUndoList* undoList, bool updateTLS, int lane) {
747  NBEdge* srcNBE = edge->getNBEdge();
748  NBEdge* turnEdge = srcNBE->getTurnDestination();
749  // Make a copy of connections
750  std::vector<NBEdge::Connection> connections = srcNBE->getConnections();
751  // delete in reverse so that undoing will add connections in the original order
752  for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) {
753  if (lane >= 0 && (*con_it).fromLane != lane) {
754  continue;
755  }
756  bool hasTurn = con_it->toEdge == turnEdge;
757  undoList->add(new GNEChange_Connection(edge, *con_it, false, false), true);
758  // needs to come after GNEChange_Connection
759  // XXX bug: this code path will not be used on a redo!
760  if (hasTurn) {
761  myNet->addExplicitTurnaround(srcNBE->getID());
762  }
763  }
764  if (updateTLS) {
765  std::vector<NBConnection> removeConnections;
766  for (NBEdge::Connection con : connections) {
767  removeConnections.push_back(NBConnection(srcNBE, con.fromLane, con.toEdge, con.toLane));
768  }
769  removeTLSConnections(removeConnections, undoList);
770  }
771 }
772 
773 
774 void
775 GNEJunction::removeConnectionsTo(GNEEdge* edge, GNEUndoList* undoList, bool updateTLS, int lane) {
776  NBEdge* destNBE = edge->getNBEdge();
777  std::vector<NBConnection> removeConnections;
778  for (NBEdge* srcNBE : myNBNode.getIncomingEdges()) {
779  GNEEdge* srcEdge = myNet->retrieveEdge(srcNBE->getID());
780  std::vector<NBEdge::Connection> connections = srcNBE->getConnections();
781  for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) {
782  if ((*con_it).toEdge == destNBE) {
783  if (lane >= 0 && (*con_it).toLane != lane) {
784  continue;
785  }
786  bool hasTurn = srcNBE->getTurnDestination() == destNBE;
787  undoList->add(new GNEChange_Connection(srcEdge, *con_it, false, false), true);
788  // needs to come after GNEChange_Connection
789  // XXX bug: this code path will not be used on a redo!
790  if (hasTurn) {
791  myNet->addExplicitTurnaround(srcNBE->getID());
792  }
793  removeConnections.push_back(NBConnection(srcNBE, (*con_it).fromLane, destNBE, (*con_it).toLane));
794  }
795  }
796  }
797  if (updateTLS) {
798  removeTLSConnections(removeConnections, undoList);
799  }
800 }
801 
802 
803 void
804 GNEJunction::removeTLSConnections(std::vector<NBConnection>& connections, GNEUndoList* undoList) {
805  if (connections.size() == 0) {
806  return;
807  }
808  const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode.getControllingTLS(); // make a copy!
809  for (auto it : coypOfTls) {
810  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it);
811  // guessed TLS (NBOwnTLDef) do not need to be updated
812  if (tlDef != nullptr) {
813  std::string newID = tlDef->getID();
814  // create replacement before deleting the original because deletion will mess up saving original nodes
815  NBLoadedSUMOTLDef* replacementDef = new NBLoadedSUMOTLDef(tlDef, tlDef->getLogic());
816  for (NBConnection& con : connections) {
817  replacementDef->removeConnection(con);
818  }
819  undoList->add(new GNEChange_TLS(this, tlDef, false), true);
820  undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
821  // the removed traffic light may have controlled more than one junction. These too have become invalid now
822  const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
823  for (auto it_node : copyOfNodes) {
824  GNEJunction* sharing = myNet->retrieveJunction(it_node->getID());
825  undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
826  undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
827  }
828  }
829  }
830 }
831 
832 
833 void
835  // remap connections of the edge
836  assert(which->getLanes().size() == by->getLanes().size());
837  std::vector<NBEdge::Connection> connections = which->getNBEdge()->getConnections();
838  for (NBEdge::Connection& c : connections) {
839  undoList->add(new GNEChange_Connection(which, c, false, false), true);
840  undoList->add(new GNEChange_Connection(by, c, false, true), true);
841  }
842  // also remap tls connections
843  const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode.getControllingTLS(); // make a copy!
844  for (auto it : coypOfTls) {
845  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it);
846  // guessed TLS (NBOwnTLDef) do not need to be updated
847  if (tlDef != nullptr) {
848  std::string newID = tlDef->getID();
849  // create replacement before deleting the original because deletion will mess up saving original nodes
850  NBLoadedSUMOTLDef* replacementDef = new NBLoadedSUMOTLDef(tlDef, tlDef->getLogic());
851  for (int i = 0; i < (int)which->getLanes().size(); ++i) {
852  replacementDef->replaceRemoved(which->getNBEdge(), i, by->getNBEdge(), i);
853  }
854  undoList->add(new GNEChange_TLS(this, tlDef, false), true);
855  undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
856  // the removed traffic light may have controlled more than one junction. These too have become invalid now
857  const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
858  for (auto it_node : copyOfNodes) {
859  GNEJunction* sharing = myNet->retrieveJunction(it_node->getID());
860  undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
861  undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
862  }
863  }
864  }
865 }
866 
867 
868 void
870  EdgeVector incoming = myNBNode.getIncomingEdges();
871  for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
872  NBEdge* srcNBE = *it;
873  GNEEdge* srcEdge = myNet->retrieveEdge(srcNBE->getID());
874  undoList->add(new GNEChange_Attribute(srcEdge, myNet, GNE_ATTR_MODIFICATION_STATUS, FEATURE_MODIFIED), true);
875  }
876 }
877 
878 
879 void
880 GNEJunction::invalidateTLS(GNEUndoList* undoList, const NBConnection& deletedConnection, const NBConnection& addedConnection) {
881  assert(undoList->hasCommandGroup());
882  // NBLoadedSUMOTLDef becomes invalid, replace with NBOwnTLDef which will be dynamically recomputed
883  const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode.getControllingTLS(); // make a copy!
884  for (auto it : coypOfTls) {
885  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it);
886  if (tlDef != nullptr) {
887  NBTrafficLightDefinition* replacementDef = nullptr;
888  std::string newID = tlDef->getID(); // + "_reguessed"; // changes due to reguessing will be visible in diff
889  if (deletedConnection != NBConnection::InvalidConnection) {
890  // create replacement before deleting the original because deletion will mess up saving original nodes
891  NBLoadedSUMOTLDef* repl = new NBLoadedSUMOTLDef(tlDef, tlDef->getLogic());
892  repl->removeConnection(deletedConnection);
893  replacementDef = repl;
894  } else if (addedConnection != NBConnection::InvalidConnection) {
895  if (addedConnection.getTLIndex() == NBConnection::InvalidTlIndex) {
896  // custom tl indices of crossings might become invalid upon recomputation so we must save them
897  // however, the could remain valud so we register a change but keep them at their old value
898  for (GNECrossing* c : myGNECrossings) {
899  const std::string oldValue = c->getAttribute(SUMO_ATTR_TLLINKINDEX);
901  undoList->add(new GNEChange_Attribute(c, myNet, SUMO_ATTR_TLLINKINDEX, oldValue), true);
902  const std::string oldValue2 = c->getAttribute(SUMO_ATTR_TLLINKINDEX);
904  undoList->add(new GNEChange_Attribute(c, myNet, SUMO_ATTR_TLLINKINDEX2, oldValue2), true);
905  }
906  }
907  NBLoadedSUMOTLDef* repl = new NBLoadedSUMOTLDef(tlDef, tlDef->getLogic());
908  repl->addConnection(addedConnection.getFrom(), addedConnection.getTo(),
909  addedConnection.getFromLane(), addedConnection.getToLane(), addedConnection.getTLIndex());
910  replacementDef = repl;
911  } else {
912  replacementDef = new NBOwnTLDef(newID, tlDef->getOffset(), tlDef->getType());
913  replacementDef->setProgramID(tlDef->getProgramID());
914  }
915  undoList->add(new GNEChange_TLS(this, tlDef, false), true);
916  undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
917  // the removed traffic light may have controlled more than one junction. These too have become invalid now
918  const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
919  for (auto it_node : copyOfNodes) {
920  GNEJunction* sharing = myNet->retrieveJunction(it_node->getID());
921  undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
922  undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
923  }
924  }
925  }
926 }
927 
928 void
930  // obtain a copy of GNECrossing of junctions
931  auto copyOfGNECrossings = myGNECrossings;
932  // iterate over copy of GNECrossings
933  for (int i = 0; i < (int)myGNECrossings.size(); i++) {
934  auto c = myGNECrossings.at(i);
935  // obtain the set of edges vinculated with the crossing (due it works as ID)
936  EdgeSet edgeSet(c->getCrossingEdges().begin(), c->getCrossingEdges().end());
937  // If this edge is part of the set of edges of crossing
938  if (edgeSet.count(edge->getNBEdge()) == 1) {
939  // delete crossing if this is their last edge
940  if ((c->getCrossingEdges().size() == 1) && (c->getCrossingEdges().front() == edge->getNBEdge())) {
941  myNet->deleteCrossing(c, undoList);
942  i = 0;
943  } else {
944  // remove this edge of the edge's attribute of crossing (note: This can invalidate the crossing)
945  std::vector<std::string> edges = GNEAttributeCarrier::parse<std::vector<std::string>>(c->getAttribute(SUMO_ATTR_EDGES));
946  edges.erase(std::find(edges.begin(), edges.end(), edge->getID()));
947  c->setAttribute(SUMO_ATTR_EDGES, joinToString(edges, " "), undoList);
948  }
949  }
950  }
951 }
952 
953 
954 bool
956  return myHasValidLogic;
957 }
958 
959 
961 GNEJunction::retrieveGNECrossing(NBNode::Crossing* crossing, bool createIfNoExist) {
962  // iterate over all crossing
963  for (auto i : myGNECrossings) {
964  // if found, return it
965  if (i->getCrossingEdges() == crossing->edges) {
966  return i;
967  }
968  }
969  if (createIfNoExist) {
970  // create new GNECrossing
971  GNECrossing* createdGNECrossing = new GNECrossing(this, crossing->edges);
972  // show extra information for tests
973  WRITE_DEBUG("Created " + createdGNECrossing->getTagStr() + " '" + createdGNECrossing->getID() + "' in retrieveGNECrossing()");
974  // update geometry after creating
975  createdGNECrossing->updateGeometry();
976  return createdGNECrossing;
977  } else {
978  return nullptr;
979  }
980 }
981 
982 
983 void
984 GNEJunction::markConnectionsDeprecated(bool includingNeighbours) {
985  // only it's needed to mark the connections of incoming edges
986  for (auto i : myGNEIncomingEdges) {
987  for (auto j : i->getGNEConnections()) {
988  j->markConnectionGeometryDeprecated();
989  }
990  if (includingNeighbours) {
991  i->getGNEJunctionSource()->markConnectionsDeprecated(false);
992  }
993  }
994 }
995 
996 
997 std::string
999  switch (key) {
1000  case SUMO_ATTR_ID:
1001  return getMicrosimID();
1002  case SUMO_ATTR_POSITION:
1003  return toString(myNBNode.getPosition());
1004  case SUMO_ATTR_TYPE:
1005  return toString(myNBNode.getType());
1007  return myLogicStatus;
1008  case SUMO_ATTR_SHAPE:
1009  return toString(myNBNode.getShape());
1010  case SUMO_ATTR_RADIUS:
1011  return toString(myNBNode.getRadius());
1012  case SUMO_ATTR_TLTYPE:
1013  // @todo this causes problems if the node were to have multiple programs of different type (plausible)
1014  return myNBNode.isTLControlled() ? toString((*myNBNode.getControllingTLS().begin())->getType()) : "";
1015  case SUMO_ATTR_TLID:
1016  return myNBNode.isTLControlled() ? toString((*myNBNode.getControllingTLS().begin())->getID()) : "";
1017  case SUMO_ATTR_KEEP_CLEAR:
1018  // keep clear is only used as a convenience feature in plain xml
1019  // input. When saving to .net.xml the status is saved only for the connections
1020  // to show the correct state we must check all connections
1021  if (!myNBNode.getKeepClear()) {
1022  return toString(false);
1023  } else {
1024  for (auto i : myGNEIncomingEdges) {
1025  for (auto j : i->getGNEConnections()) {
1026  if (j->getNBEdgeConnection().keepClear) {
1027  return toString(true);
1028  }
1029  }
1030  }
1031  return toString(false);
1032  }
1035  case SUMO_ATTR_FRINGE:
1037  case GNE_ATTR_SELECTED:
1039  case GNE_ATTR_GENERIC:
1040  return getGenericParametersStr();
1041  default:
1042  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1043  }
1044 }
1045 
1046 
1047 void
1048 GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
1049  if (value == getAttribute(key)) {
1050  return; //avoid needless changes, later logic relies on the fact that attributes have changed
1051  }
1052  switch (key) {
1053  case SUMO_ATTR_ID:
1054  case SUMO_ATTR_POSITION:
1056  case SUMO_ATTR_SHAPE:
1057  case SUMO_ATTR_RADIUS:
1059  case SUMO_ATTR_FRINGE:
1060  case GNE_ATTR_SELECTED:
1061  case GNE_ATTR_GENERIC:
1062  undoList->add(new GNEChange_Attribute(this, myNet, key, value), true);
1063  break;
1064  case SUMO_ATTR_KEEP_CLEAR:
1065  // change Keep Clear attribute in all connections
1066  undoList->p_begin("change keepClear for whole junction");
1067  for (auto i : myGNEIncomingEdges) {
1068  for (auto j : i->getGNEConnections()) {
1069  undoList->add(new GNEChange_Attribute(j, myNet, key, value), true);
1070  }
1071  }
1072  undoList->add(new GNEChange_Attribute(this, myNet, key, value), true);
1073  undoList->p_end();
1074  break;
1075  case SUMO_ATTR_TYPE: {
1076  undoList->p_begin("change " + getTagStr() + " type");
1078  if (getNBNode()->isTLControlled() &&
1079  // if switching changing from or to traffic_light_right_on_red we need to remove the old plan
1082  ) {
1083  // make a copy because we will modify the original
1084  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1085  for (auto it : copyOfTls) {
1086  undoList->add(new GNEChange_TLS(this, it, false), true);
1087  }
1088  }
1089  if (!getNBNode()->isTLControlled()) {
1090  // create new traffic light
1091  undoList->add(new GNEChange_TLS(this, nullptr, true), true);
1092  }
1093  } else if (getNBNode()->isTLControlled()) {
1094  // delete old traffic light
1095  // make a copy because we will modify the original
1096  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1097  for (auto it : copyOfTls) {
1098  undoList->add(new GNEChange_TLS(this, it, false, false), true);
1099  }
1100  }
1101  // must be the final step, otherwise we do not know which traffic lights to remove via GNEChange_TLS
1102  undoList->add(new GNEChange_Attribute(this, myNet, key, value), true);
1103  for (auto it : myGNECrossings) {
1104  undoList->add(new GNEChange_Attribute(it, myNet, SUMO_ATTR_TLLINKINDEX, "-1"), true);
1105  undoList->add(new GNEChange_Attribute(it, myNet, SUMO_ATTR_TLLINKINDEX2, "-1"), true);
1106  }
1107  undoList->p_end();
1108  break;
1109  }
1110  case SUMO_ATTR_TLTYPE: {
1111  undoList->p_begin("change " + getTagStr() + " tl-type");
1112  // make a copy because we will modify the original
1113  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1114  for (auto oldDef : copyOfTls) {
1115  NBLoadedSUMOTLDef* oldLoaded = dynamic_cast<NBLoadedSUMOTLDef*>(oldDef);
1116  if (oldLoaded != nullptr) {
1117  NBLoadedSUMOTLDef* newDef = new NBLoadedSUMOTLDef(oldLoaded, oldLoaded->getLogic());
1118  newDef->guessMinMaxDuration();
1119  std::vector<NBNode*> nodes = oldDef->getNodes();
1120  for (auto it : nodes) {
1121  GNEJunction* junction = myNet->retrieveJunction(it->getID());
1122  undoList->add(new GNEChange_TLS(junction, oldDef, false), true);
1123  undoList->add(new GNEChange_TLS(junction, newDef, true), true);
1124  }
1125  }
1126  }
1127  undoList->add(new GNEChange_Attribute(this, myNet, key, value), true);
1128  undoList->p_end();
1129  break;
1130  }
1131  case SUMO_ATTR_TLID: {
1132  undoList->p_begin("change " + toString(SUMO_TAG_TRAFFIC_LIGHT) + " id");
1133  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1134  assert(copyOfTls.size() > 0);
1135  NBTrafficLightDefinition* currentTLS = *copyOfTls.begin();
1136  NBTrafficLightDefinition* currentTLSCopy = nullptr;
1137  const bool currentIsSingle = currentTLS->getNodes().size() == 1;
1138  const bool currentIsLoaded = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS) != nullptr;
1139  if (currentIsLoaded) {
1140  currentTLSCopy = new NBLoadedSUMOTLDef(currentTLS,
1141  dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS)->getLogic());
1142  }
1143  // remove from previous tls
1144  for (auto it : copyOfTls) {
1145  undoList->add(new GNEChange_TLS(this, it, false), true);
1146  }
1148  // programs to which the current node shall be added
1149  const std::map<std::string, NBTrafficLightDefinition*> programs = tlCont.getPrograms(value);
1150  if (programs.size() > 0) {
1151  for (auto it : programs) {
1152  NBTrafficLightDefinition* oldTLS = it.second;
1153  if (dynamic_cast<NBOwnTLDef*>(oldTLS) != nullptr) {
1154  undoList->add(new GNEChange_TLS(this, oldTLS, true), true);
1155  } else {
1156  // delete and re-create the definition because the loaded phases are now invalid
1157  if (dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS) != nullptr &&
1158  dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->usingSignalGroups()) {
1159  // keep the old program and add all-red state for the added links
1160  NBLoadedSUMOTLDef* newTLSJoined = new NBLoadedSUMOTLDef(oldTLS, dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->getLogic());
1161  newTLSJoined->joinLogic(currentTLSCopy);
1162  undoList->add(new GNEChange_TLS(this, newTLSJoined, true, true), true);
1163  } else {
1164  undoList->add(new GNEChange_TLS(this, nullptr, true, false, value), true);
1165  }
1167  // switch from old to new definition
1168  const std::vector<NBNode*> copyOfNodes = oldTLS->getNodes();
1169  for (auto it_node : copyOfNodes) {
1170  GNEJunction* oldJunction = myNet->retrieveJunction(it_node->getID());
1171  undoList->add(new GNEChange_TLS(oldJunction, oldTLS, false), true);
1172  undoList->add(new GNEChange_TLS(oldJunction, newTLS, true), true);
1173  }
1174  }
1175  }
1176  } else {
1177  if (currentIsSingle && currentIsLoaded) {
1178  // rename the traffic light but keep everything else
1179  NBTrafficLightLogic* renamedLogic = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLSCopy)->getLogic();
1180  renamedLogic->setID(value);
1181  NBLoadedSUMOTLDef* renamedTLS = new NBLoadedSUMOTLDef(currentTLSCopy, renamedLogic);
1182  renamedTLS->setID(value);
1183  undoList->add(new GNEChange_TLS(this, renamedTLS, true, true), true);
1184  } else {
1185  // create new traffic light
1186  undoList->add(new GNEChange_TLS(this, nullptr, true, false, value), true);
1187  }
1188  }
1189  delete currentTLSCopy;
1190  undoList->p_end();
1191  break;
1192  }
1193  default:
1194  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1195  }
1196 }
1197 
1198 
1199 bool
1200 GNEJunction::isValid(SumoXMLAttr key, const std::string& value) {
1201  switch (key) {
1202  case SUMO_ATTR_ID:
1203  return SUMOXMLDefinitions::isValidNetID(value) && (myNet->retrieveJunction(value, false) == nullptr);
1204  case SUMO_ATTR_TYPE:
1206  case SUMO_ATTR_POSITION:
1207  return canParse<Position>(value);
1208  case SUMO_ATTR_SHAPE:
1209  // empty shapes are allowed
1210  return canParse<PositionVector>(value);
1211  case SUMO_ATTR_RADIUS:
1212  return canParse<double>(value) && (parse<double>(value) >= -1);
1213  case SUMO_ATTR_TLTYPE:
1215  case SUMO_ATTR_TLID:
1216  return myNBNode.isTLControlled() && (value != "");
1217  case SUMO_ATTR_KEEP_CLEAR:
1218  return canParse<bool>(value);
1221  case SUMO_ATTR_FRINGE:
1223  case GNE_ATTR_SELECTED:
1224  return canParse<bool>(value);
1225  case GNE_ATTR_GENERIC:
1226  return isGenericParametersValid(value);
1227  default:
1228  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1229  }
1230 }
1231 
1232 
1233 std::string
1235  std::string result;
1236  // Generate an string using the following structure: "key1=value1|key2=value2|...
1237  for (auto i : myNBNode.getParametersMap()) {
1238  result += i.first + "=" + i.second + "|";
1239  }
1240  // remove the last "|"
1241  if (!result.empty()) {
1242  result.pop_back();
1243  }
1244  return result;
1245 }
1246 
1247 
1248 std::vector<std::pair<std::string, std::string> >
1250  std::vector<std::pair<std::string, std::string> > result;
1251  // iterate over parameters map and fill result
1252  for (auto i : myNBNode.getParametersMap()) {
1253  result.push_back(std::make_pair(i.first, i.second));
1254  }
1255  return result;
1256 }
1257 
1258 
1259 void
1260 GNEJunction::setGenericParametersStr(const std::string& value) {
1261  // clear parameters
1263  // separate value in a vector of string using | as separator
1264  std::vector<std::string> parsedValues;
1265  StringTokenizer stValues(value, "|", true);
1266  while (stValues.hasNext()) {
1267  parsedValues.push_back(stValues.next());
1268  }
1269  // check that parsed values (A=B)can be parsed in generic parameters
1270  for (auto i : parsedValues) {
1271  std::vector<std::string> parsedParameters;
1272  StringTokenizer stParam(i, "=", true);
1273  while (stParam.hasNext()) {
1274  parsedParameters.push_back(stParam.next());
1275  }
1276  // Check that parsed parameters are exactly two and contains valid chracters
1277  if (parsedParameters.size() == 2 && SUMOXMLDefinitions::isValidGenericParameterKey(parsedParameters.front()) && SUMOXMLDefinitions::isValidGenericParameterValue(parsedParameters.back())) {
1278  myNBNode.setParameter(parsedParameters.front(), parsedParameters.back());
1279  }
1280  }
1281 }
1282 
1283 
1284 void
1286  myAmResponsible = newVal;
1287 }
1288 
1289 // ===========================================================================
1290 // private
1291 // ===========================================================================
1292 
1293 void
1294 GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value) {
1295  switch (key) {
1296  case SUMO_ATTR_ID: {
1297  myNet->renameJunction(this, value);
1298  break;
1299  }
1300  case SUMO_ATTR_TYPE: {
1304  }
1306  break;
1307  }
1308  case SUMO_ATTR_POSITION: {
1309  // start geometry moving (because new position affect all junction children)
1311  // set new position in NBNode without updating grid
1312  moveJunctionGeometry(parse<Position>(value));
1313  // end geometry moving
1315  // mark this connections and all of the junction's Neighbours as deprecated
1317  break;
1318  }
1320  if (myLogicStatus == FEATURE_GUESSED && value != FEATURE_GUESSED) {
1321  // clear guessed connections. previous connections will be restored
1323  // Clear GNEConnections of incoming edges
1324  for (auto i : myGNEIncomingEdges) {
1325  i->clearGNEConnections();
1326  }
1327  }
1328  myLogicStatus = value;
1329  break;
1330  case SUMO_ATTR_SHAPE: {
1331  // start geometry moving (because new position affect all junction children)
1333  // set new shape (without updating grid)
1334  const PositionVector shape = parse<PositionVector>(value);
1335  myNBNode.setCustomShape(shape);
1336  // end geometry moving
1338  // mark this connections and all of the junction's Neighbours as deprecated
1340  break;
1341  }
1342  case SUMO_ATTR_RADIUS: {
1343  myNBNode.setRadius(parse<double>(value));
1344  break;
1345  }
1346  case SUMO_ATTR_TLTYPE: {
1347  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1348  for (auto it : copyOfTls) {
1349  it->setType(SUMOXMLDefinitions::TrafficLightTypes.get(value));
1350  }
1351  break;
1352  }
1353  case SUMO_ATTR_KEEP_CLEAR: {
1354  myNBNode.setKeepClear(parse<bool>(value));
1355  break;
1356  }
1359  break;
1360  case SUMO_ATTR_FRINGE:
1362  break;
1363  case GNE_ATTR_SELECTED:
1364  if (parse<bool>(value)) {
1366  } else {
1368  }
1369  break;
1370  case GNE_ATTR_GENERIC:
1371  setGenericParametersStr(value);
1372  break;
1373  default:
1374  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1375  }
1376 }
1377 
1378 
1379 double
1380 GNEJunction::getColorValue(const GUIVisualizationSettings& /* s */, int activeScheme) const {
1381  switch (activeScheme) {
1382  case 0:
1383  // ensure visibility of red connections
1385  return 1;
1386  } else {
1387  return 0;
1388  }
1389  case 1:
1390  return isAttributeCarrierSelected();
1391  case 2:
1392  switch (myNBNode.getType()) {
1394  return 0;
1396  return 1;
1397  case NODETYPE_PRIORITY:
1398  return 2;
1400  return 3;
1402  return 4;
1403  case NODETYPE_ALLWAY_STOP:
1404  return 5;
1405  case NODETYPE_DISTRICT:
1406  return 6;
1407  case NODETYPE_NOJUNCTION:
1408  return 7;
1409  case NODETYPE_DEAD_END:
1411  return 8;
1412  case NODETYPE_UNKNOWN:
1413  return 8; // may happen before first network computation
1414  case NODETYPE_INTERNAL:
1415  assert(false);
1416  return 8;
1417  case NODETYPE_RAIL_SIGNAL:
1418  return 9;
1419  case NODETYPE_ZIPPER:
1420  return 10;
1422  return 11;
1424  return 12;
1425  }
1426  case 3:
1427  return myNBNode.getPosition().z();
1428  default:
1429  assert(false);
1430  return 0;
1431  }
1432 }
1433 
1434 
1435 void
1437  // obtain NBNode position
1438  const Position orig = myNBNode.getPosition();
1439  // reinit NBNode
1440  myNBNode.reinit(pos, myNBNode.getType());
1441  // set new position of adjacent edges
1442  for (auto i : getNBNode()->getEdges()) {
1443  myNet->retrieveEdge(i->getID())->updateJunctionPosition(this, orig);
1444  }
1445  // declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
1446  std::set<GNEJunction*> affectedJunctions;
1447  std::set<GNEEdge*> affectedEdges;
1448  // Iterate over GNEEdges
1449  for (auto i : myGNEEdges) {
1450  // Add source and destiny junctions
1451  affectedJunctions.insert(i->getGNEJunctionSource());
1452  affectedJunctions.insert(i->getGNEJunctionDestiny());
1453  // Obtain neighbors of Junction source
1454  for (auto j : i->getGNEJunctionSource()->getGNEEdges()) {
1455  affectedEdges.insert(j);
1456  }
1457  // Obtain neighbors of Junction destiny
1458  for (auto j : i->getGNEJunctionDestiny()->getGNEEdges()) {
1459  affectedEdges.insert(j);
1460  }
1461  }
1462  // Iterate over affected Edges
1463  for (auto i : affectedEdges) {
1464  // Update edge geometry
1465  i->updateGeometry();
1466  }
1467 }
1468 
1469 
1470 RGBColor
1471 GNEJunction::setColor(const GUIVisualizationSettings& s, bool bubble) const {
1472  const int scheme = s.junctionColorer.getActive();
1473  RGBColor color = s.junctionColorer.getScheme().getColor(getColorValue(s, scheme));
1474  if (!bubble && scheme == 0) {
1475  color = s.junctionColorer.getScheme().getColor(0.);
1476  }
1477  // override with special colors (unless the color scheme is based on selection)
1478  if (drawUsingSelectColor() && scheme != 1) {
1479  color = s.colorSettings.selectionColor;
1480  }
1481  if (myAmCreateEdgeSource) {
1482  color = RGBColor(0, 255, 0);
1483  }
1484  GLHelper::setColor(color);
1485  return color;
1486 }
1487 
1488 
1489 void
1492  tlCont.insert(tlDef, forceInsert); // may return false for tlDef which controls multiple junctions
1493  tlDef->addNode(&myNBNode);
1494 }
1495 
1496 
1497 void
1500  if (tlDef->getNodes().size() == 1) {
1501  tlCont.extract(tlDef);
1502  }
1504 }
1505 
1506 /****************************************************************************/
GUIVisualizationSizeSettings junctionSize
bool getKeepClear() const
Returns the keepClear flag.
Definition: NBNode.h:286
static void drawTexturedBox(int which, double size)
Draws a named texture as a box with the given size.
bool myAmResponsible
whether we are responsible for deleting myNBNode
Definition: GNEJunction.h:283
GUIVisualizationTextSettings junctionName
const std::map< std::string, NBTrafficLightDefinition * > & getPrograms(const std::string &id) const
Returns all programs for the given tl-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...
std::vector< GNEJunction * > retrieveJunctions(bool onlySelected=false)
return all junctions
Definition: GNENet.cpp:1212
static StringBijection< RightOfWay > RightOfWayValues
righ of way algorithms
bool myHasValidLogic
whether this junctions logic is valid
Definition: GNEJunction.h:286
void setResponsible(bool newVal)
set responsibility for deleting internal strctures
std::vector< GNEConnection * > getGNEConnections() const
Returns all GNEConnections vinculated with this junction.
static const std::string FEATURE_MODIFIED
feature has been manually modified (implies approval)
double myMaxSize
The maximum size (in either x-, or y-dimension) for determining whether to draw or not...
Definition: GNEJunction.h:273
Position getPositionInView() const
Returns position of hierarchical element in view.
SumoXMLTag
Numbers representing SUMO-XML - element names.
std::string myLogicStatus
modification status of the junction logic (all connections across this junction)
Definition: GNEJunction.h:280
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:184
Position snapToActiveGrid(const Position &pos, bool snapXY=true) const
Returns a position that is mapped to the closest grid point if the grid is active.
void addIncomingGNEEdge(GNEEdge *edge)
add incoming GNEEdge
static StringBijection< SumoXMLNodeType > NodeTypes
node types
GNEEdge * retrieveEdge(const std::string &id, bool failHard=true)
get edge by id
Definition: GNENet.cpp:1020
double scale
information about a lane&#39;s width (temporary, used for a single view)
Whether vehicles must keep the junction clear.
const std::vector< GNEEdge * > & getGNEOutgoingEdges() const
Returns incoming GNEEdges.
GNENet * myNet
the net to inform about updates
virtual void addNode(NBNode *node)
Adds a node to the traffic light logic.
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined
void guessMinMaxDuration()
heuristically add minDur and maxDur when switching from tlType fixed to actuated
void invalidateShape()
void removeIncomingGNEEdge(GNEEdge *edge)
remove incoming GNEEdge
double z() const
Returns the z-position.
Definition: Position.h:67
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
begin/end of the description of a junction
std::string generateChildID(SumoXMLTag childTag)
gererate a new ID for an element child
Definition: GNEJunction.cpp:91
void setRightOfWay(RightOfWay rightOfWay)
set method for computing right-of-way
Definition: NBNode.h:520
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:127
PositionVector myPoly
the (outer) shape of the junction
Definition: NBNode.h:844
void markAsCreateEdgeSource()
marks as first junction in createEdge-mode
a flow definitio nusing a from-to edges instead of a route (used by router)
void removeEdgeFromCrossings(GNEEdge *edge, GNEUndoList *undoList)
removes the given edge from all pedestrian crossings
bool drawUsingSelectColor() const
check if attribute carrier must be drawn using selecting color.
NBNetBuilder * getNetBuilder() const
get net builder
Definition: GNENet.cpp:1543
A loaded (complete) traffic light logic.
bool myAmCreateEdgeSource
whether this junction is the first junction for a newly creatededge
Definition: GNEJunction.h:277
static GUIGlID getTexture(GUITexture which)
returns a texture previously defined in the enum GUITexture
static const NBConnection InvalidConnection
Definition: NBConnection.h:121
A container for traffic light definitions and built programs.
A SUMO-compliant built logic for a traffic light.
std::vector< GNEEdge * > myGNEIncomingEdges
vector with the incomings GNEEdges vinculated with this junction
Definition: GNEJunction.h:264
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
Definition: NBNode.cpp:304
bool isValid(SumoXMLAttr key, const std::string &value)
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition: RGBColor.h:83
friend class GNEChange_TLS
Declare friend class.
Definition: GNEJunction.h:51
Stores the information about how to visualize structures.
edit junction shape
Definition: GUIAppEnum.h:847
const std::string & getString(const T key) const
double y() const
Returns the y-position.
Definition: Position.h:62
bool hasCustomShape() const
return whether the shape was set by the user
Definition: NBNode.h:530
The representation of a single edge during network building.
Definition: NBEdge.h:86
TrafficLightType getType() const
get the algorithm type (static etc..)
std::vector< std::pair< Position, std::string > > getEndPoints() const
return list of unique endpoint coordinates of all edges at this node
Definition: NBNode.cpp:3375
void removeRoundabout(const NBNode *node)
remove roundabout that contains the given node
double x() const
Returns the x-position.
Definition: Position.h:57
The base class for traffic light logic definitions.
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
void removeTLSConnections(std::vector< NBConnection > &connections, GNEUndoList *undoList)
remove the given connections from all traffic light definitions of this junction
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, int align=0, double width=-1)
Definition: GLHelper.cpp:668
link,node: the traffic light id responsible for this link
#define WRITE_GLDEBUG(msg)
Definition: MsgHandler.h:247
T MAX2(T a, T b)
Definition: StdDefs.h:80
std::string getGenericParametersStr() const
return generic parameters in string format
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:78
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition: NBEdge.cpp:3116
static void drawFilledPoly(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:82
turn junction into multiple junctions and reconnect them heuristically
Definition: GUIAppEnum.h:845
void p_begin(const std::string &description)
Begin undo command sub-group. This begins a new group of commands that are treated as a single comman...
Definition: GNEUndoList.cpp:73
void addExplicitTurnaround(std::string id)
add edge id to the list of explicit turnarounds
Definition: GNENet.cpp:2121
NBEdge * getFrom() const
returns the from-edge (start of the connection)
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
bool editingElevation() const
check if we&#39;re editing elevation
void selectTLS(bool selected)
notify the junction of being selected in tls-mode. (used to control drawing)
const std::string & getID() const
Returns the id.
Definition: Named.h:77
bool myAmTLSSelected
whether this junction is selected in tls-mode
Definition: GNEJunction.h:289
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
void mirrorX()
mirror coordinates along the x-axis
Definition: NBNode.cpp:340
bool hasNext()
returns the information whether further substrings exist
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
Definition: NBNode.cpp:369
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition: NBNode.cpp:2149
void startGeometryMoving(bool extendToNeighbors=true)
begin movement (used when user click over edge to start a movement, to avoid problems with problems w...
void extract(NBTrafficLightDefinition *definition)
Extracts a traffic light definition from myDefinitions but keeps it in myExtracted for eventual * del...
const std::vector< GNEEdge * > & getGNEEdges() const
Returns all GNEEdges vinculated with this Junction.
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
removes a traffic light
static bool isValidGenericParameterKey(const std::string &value)
whether the given string is a valid key for a generic parameter
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to copy the cursor position if geo projection is used, also builds an entry for copying the geo-position.
turn junction into geometry node
Definition: GUIAppEnum.h:841
generic attribute
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:42
begin/end of the description of a route
mode for editing tls
void markConnectionsDeprecated(bool includingNeighbours)
mark connections as deprecated
Boundary myMovingGeometryBoundary
boundary used during moving of elements
void replaceRemoved(NBEdge *removed, int removedLane, NBEdge *by, int byLane)
Replaces a removed edge/lane.
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
link: the index of the opposite direction link of a pedestrian crossing
whether a feature has been loaded,guessed,modified or approved
const EdgeVector & getOutgoingEdges() const
Returns this node&#39;s outgoing edges (The edges which start at this node)
Definition: NBNode.h:264
double area() const
Returns the area (0 for non-closed)
SUMOTime getOffset()
Returns the offset.
void updateGeometry()
update pre-computed geometry information
Definition: GNECrossing.cpp:60
void renameJunction(GNEJunction *junction, const std::string &newID)
updates the map and reserves new id
Definition: GNENet.cpp:2109
static void drawFilledPolyTesselated(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:101
void removeOutgoingGNEEdge(GNEEdge *edge)
remove outgoing GNEEdge
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
static void drawBoundary(const Boundary &b)
Draw a boundary (used for debugging)
Definition: GLHelper.cpp:812
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition: GNEEdge.cpp:625
int getCircleResolution() const
function to calculate circle resolution for all circles drawn in drawGL(...) functions ...
const std::vector< GNECrossing * > & getGNECrossings() const
Returns GNECrossings.
void setRadius(double radius)
set the turning radius
Definition: NBNode.h:510
std::string getAttribute(SumoXMLAttr key) const
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition: NBNode.h:317
void invalidateIncomingConnections()
invalidate incoming connections
Definition: NBNode.cpp:1665
How to compute right of way.
static const int InvalidTlIndex
Definition: NBConnection.h:120
The turning radius at an intersection in m.
static bool isValidGenericParameterValue(const std::string &value)
whether the given string is a valid value for a generic parameter
std::set< NBEdge * > EdgeSet
container for unique edges
Definition: NBCont.h:50
void removeConnectionsFrom(GNEEdge *edge, GNEUndoList *undoList, bool updateTLS, int lane=-1)
remove all connections from the given edge
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
bool hasCommandGroup() const
Check if undoList has command group.
the edges of a route
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:616
This object is responsible for drawing a shape and for supplying a a popup menu. Messages are routete...
Definition: GNECrossing.h:45
std::vector< std::pair< std::string, std::string > > getGenericParameters() const
return generic parameters as vector of pairs format
const std::vector< GNEEdge * > & getGNEIncomingEdges() const
Returns incoming GNEEdges.
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise, the sub-group will be added as a new command into parent group. A matching begin() must have been called previously.
Definition: GNEUndoList.cpp:80
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
RGBColor selectionColor
basic selection color
GNEJunction * retrieveJunction(const std::string &id, bool failHard=true)
get junction by id
Definition: GNENet.cpp:1001
NBEdgeCont & getEdgeCont()
Definition: NBNetBuilder.h:151
A list of positions.
Supermode currentSupermode
the current supermode
double scaledSize(double scale, double constFactor=0.1) const
get scale size
static bool isGenericParametersValid(const std::string &value)
check if given string can be parsed to a map/list of generic parameters
bool isLogicValid()
whether this junction has a valid logic
void removeGLObjectFromGrid(GUIGlObject *o)
add GL Object into net
Definition: GNENet.cpp:1279
void buildCrossingsAndWalkingAreas()
build crossings, and walkingareas. Also removes invalid loaded crossings if wished ...
Definition: NBNode.cpp:2432
void addConnection(NBEdge *from, NBEdge *to, int fromLane, int toLane, int linkIndex, bool reconstruct=true)
Adds a connection and immediately informs the edges.
friend class GNEChange_Attribute
declare friend class
T get(const std::string &str) const
mode for creating new edges
reset junction shape
Definition: GUIAppEnum.h:849
static std::vector< Position > drawFilledCircleReturnVertices(double width, int steps=8)
Draws a filled circle around (0,0) returning circle vertex.
Definition: GLHelper.cpp:354
void commitGeometryMoving(const Position &oldPos, GNEUndoList *undoList)
registers completed movement with the undoList
static const std::string FEATURE_GUESSED
feature has been reguessed (may still be unchanged be we can&#39;t tell (yet)
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node) ...
Definition: NBNode.h:269
bool showJunctionAsBubbles() const
return true if junction must be showed as bubbles
Definition: GNEViewNet.cpp:506
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition: GNEEdge.cpp:840
const std::string & getID() const
Definition: NBEdge.h:1364
void setFringeType(FringeType fringeType)
set method for computing right-of-way
Definition: NBNode.h:525
static void drawShapeDottedContourAroundClosedShape(const GUIVisualizationSettings &s, const int type, const PositionVector &shape)
draw a dotted contour around the given closed shape with certain width
Definition: GLHelper.cpp:496
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
turn junction into multiple junctions
Definition: GUIAppEnum.h:843
NBTrafficLightLogic * getLogic()
Returns the internal logic.
void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
node: the type of traffic light
edge: the shape in xml-definition
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:301
GUIColorer junctionColorer
The junction colorer.
void removeConnectionsTo(GNEEdge *edge, GNEUndoList *undoList, bool updateTLS, int lane=-1)
remove all connections to the given edge
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
void deleteCrossing(GNECrossing *crossing, GNEUndoList *undoList)
remove crossing
Definition: GNENet.cpp:599
void addOutgoingGNEEdge(GNEEdge *edge)
add outgoing GNEEdge
std::vector< GNEEdge * > myGNEEdges
vector with the GNEEdges vinculated with this junction
Definition: GNEJunction.h:261
const std::string getID() const
function to support debugging
void unMarkAsCreateEdgeSource()
removes mark as first junction in createEdge-mode
void setProgramID(const std::string &programID)
Sets the programID.
const T getColor(const double value) const
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:246
const std::string & getProgramID() const
Returns the ProgramID.
void incRef(const std::string &debugMsg="")
Increarse reference.
void setGenericParametersStr(const std::string &value)
set generic parameters in string format
NBNode & myNBNode
A reference to the represented junction.
Definition: GNEJunction.h:258
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
void selectAttributeCarrier(bool changeFlag=true)
select attribute carrier using GUIGlobalSelection
void setKeepClear(bool keepClear)
set the keepClear flag
Definition: NBNode.h:515
bool checkIsRemovableReporting(std::string &reason) const
check if node is removable and return reason if not
Definition: NBNode.cpp:2053
static void computeTurnDirectionsForNode(NBNode *node, bool warn)
Computes turnaround destinations for all incoming edges of the given nodes (if any) ...
const GNEViewNetHelper::NetworkViewOptions & getNetworkViewOptions() const
get network view options
Definition: GNEViewNet.cpp:411
begin/end of the description of an edge
void joinLogic(NBTrafficLightDefinition *def)
join nodes and states from the given logic (append red state)
void unselectAttributeCarrier(bool changeFlag=true)
unselect attribute carrier using GUIGlobalSelection
static bool isValidNetID(const std::string &value)
whether the given string is a valid id for a network element
const PositionVector & getShape() const
retrieve the junction shape
Definition: NBNode.cpp:2143
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const
determines color value
int getToLane() const
returns the to-lane
NBEdge * getTo() const
returns the to-edge (end of the connection)
RightOfWay getRightOfWay() const
Returns hint on how to compute right of way.
Definition: NBNode.h:291
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:50
bool showNonInspectedDemandElements(const GNEDemandElement *demandElement) const
check if non inspected element has to be hidden
static const double BUBBLE_RADIUS
constant values for drawing buubles
Definition: GNEJunction.h:56
void reset()
Resets the boundary.
Definition: Boundary.cpp:67
bool showDemandElements() const
check if show demand elements checkbox is enabled
void setID(const std::string &newID)
resets the id
Definition: Named.h:85
reset junction&#39;s connections
Definition: GUIAppEnum.h:839
double selectionScale
the current selection scaling in NETEDIT (temporary)
void buildSelectionACPopupEntry(GUIGLObjectPopupMenu *ret, GNEAttributeCarrier *AC)
Builds an entry which allows to (de)select the object.
Definition: GNEViewNet.cpp:331
~GNEJunction()
Destructor.
Definition: GNEJunction.cpp:71
FringeType getFringeType() const
Returns fringe type.
Definition: NBNode.h:296
double getRadius() const
Returns the turning radius of this node.
Definition: NBNode.h:281
bool haveNetworkCrossings()
notify about style of loaded network (Without Crossings)
Definition: NBNetBuilder.h:196
void updateGeometry()
update pre-computed geometry information
const EdgeVector & getIncomingEdges() const
Returns this node&#39;s incoming edges (The edges which yield in this node)
Definition: NBNode.h:259
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:924
static StringBijection< FringeType > FringeTypeValues
fringe types
void updateGeometryAfterNetbuild(bool rebuildNBNodeCrossings=false)
update pre-computed geometry information without modifying netbuild structures
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
const GNEViewNetHelper::DemandViewOptions & getDemandViewOptions() const
get demand view options
Definition: GNEViewNet.cpp:417
const GNEAttributeCarrier * getDottedAC() const
get AttributeCarrier under cursor
Definition: GNEViewNet.cpp:939
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:322
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:35
std::vector< GNECrossing * > myGNECrossings
the built crossing objects
Definition: GNEJunction.h:270
RGBColor setColor(const GUIVisualizationSettings &s, bool bubble) const
sets junction color depending on circumstances
const std::string & getTagStr() const
get tag assigned to this object in string format
Demanding mode (Routes, Vehicles etc..)
void scaleRelative(double factor)
enlarges/shrinks the polygon by a factor based at the centroid
void moveGeometry(const Position &oldPos, const Position &offset)
change the position of the element geometry without saving in undoList
element is selected
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
bool isInitialised() const
check if Boundary is Initialised
Definition: Boundary.cpp:217
void updateGeometry()
update pre-computed geometry information
Definition: GNEEdge.cpp:122
The popup menu of a globject.
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:276
double distanceSquaredTo2D(const Position &p2) const
returns the square of the distance to another position (Only using x and y positions) ...
Definition: Position.h:249
std::vector< GNEEdge * > myGNEOutgoingEdges
vector with the outgoings GNEEdges vinculated with this junction
Definition: GNEJunction.h:267
void replaceIncomingConnections(GNEEdge *which, GNEEdge *by, GNEUndoList *undoList)
replace one edge by another in all tls connections
const Position & getPosition() const
Definition: NBNode.h:251
EdgeVector edges
The edges being crossed.
Definition: NBNode.h:138
int getFromLane() const
returns the from-lane
Represents a single node (junction) during network building.
Definition: NBNode.h:68
mode for connecting lanes
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
begin/end of the description of a embedded route (used in NETEDIT)
GUIGlID getGlID() const
Returns the numerical id of the object.
A definition of a pedestrian crossing.
Definition: NBNode.h:132
GNEJunction(NBNode &nbn, GNENet *net, bool loaded=false)
Constructor.
Definition: GNEJunction.cpp:60
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
void rebuildGNECrossings(bool rebuildNBNodeCrossings=true)
rebuilds crossing objects for this junction
NetworkEditMode networkEditMode
the current Network edit mode
Position getPositionInformation() const
Returns the cursor&#39;s x/y position within the network.
link: the index of the link within the traffic light
GUIVisualizationColorSettings colorSettings
color settings
const std::vector< Crossing * > & getCrossingsIncludingInvalid() const
Definition: NBNode.h:673
bool drawJunctionShape
whether the shape of the junction should be drawn
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
a single trip definition (used by router)
empty max
int getTLIndex() const
returns the index within the controlling tls or InvalidTLIndex if this link is unontrolled ...
Definition: NBConnection.h:94
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
void mirrorXLeftHand()
temporarily mirror coordinates in lefthand network to compute correct crossing geometries ...
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:136
bool hasString(const std::string &str) const
GNECrossing * retrieveGNECrossing(NBNode::Crossing *crossing, bool createIfNoExist=true)
get GNECrossing if exist, and if not create it if create is enabled
std::vector< GNEJunction * > getJunctionNeighbours() const
return GNEJunction neighbours
A traffic light logics which must be computed (only nodes/edges are given)
Definition: NBOwnTLDef.h:47
bool drawForSelecting
whether drawing is performed for the purpose of selecting objects
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
Definition: GNEViewNet.cpp:399
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values
void closePolygon()
ensures that the last position equals the first
NBNode * getNBNode() const
Return net build node.
void addGLObjectIntoGrid(GUIGlObject *o)
add GL Object into net
Definition: GNENet.cpp:1273
Fringe type of node.
void setLogicValid(bool valid, GNEUndoList *undoList, const std::string &status=FEATURE_GUESSED)
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition: GNENet.cpp:2097
bool drawBoundaries
enable or disable draw boundaries
static bool isTrafficLight(SumoXMLNodeType type)
return whether the given type is a traffic light
Definition: NBNode.cpp:3270
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:247
void requireRecompute()
inform the net about the need for recomputation
Definition: GNENet.cpp:1520
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
void moveJunctionGeometry(const Position &pos)
reposition the node at pos without updating GRID and informs the edges
void invalidateTLS(GNEUndoList *undoList, const NBConnection &deletedConnection=NBConnection::InvalidConnection, const NBConnection &addedConnection=NBConnection::InvalidConnection)
void addTrafficLight(NBTrafficLightDefinition *tlDef, bool forceInsert)
adds a traffic light
clear junction&#39;s connections
Definition: GUIAppEnum.h:837
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
void markAsModified(GNEUndoList *undoList)
prevent re-guessing connections at this junction
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:2067
void endGeometryMoving(bool extendToNeighbors=true)
begin movement (used when user click over edge to start a movement, to avoid problems with problems w...
void clearParameter()
Clears the parameter map.
a junction