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-2018 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 
28 #include <utils/gui/div/GLHelper.h>
30 #include <netbuild/NBOwnTLDef.h>
32 #include <netbuild/NBAlgorithms.h>
36 #include <netedit/GNENet.h>
37 #include <netedit/GNEUndoList.h>
38 #include <netedit/GNEViewNet.h>
39 #include <netbuild/NBNetBuilder.h>
41 
42 #include "GNEEdge.h"
43 #include "GNEConnection.h"
44 #include "GNEJunction.h"
45 #include "GNECrossing.h"
46 
47 
48 // ===========================================================================
49 // static members
50 // ===========================================================================
51 
52 const double GNEJunction::BUBBLE_RADIUS(4);
53 
54 // ===========================================================================
55 // method definitions
56 // ===========================================================================
57 
58 GNEJunction::GNEJunction(NBNode& nbn, GNENet* net, bool loaded) :
59  GNENetElement(net, nbn.getID(), GLO_JUNCTION, SUMO_TAG_JUNCTION),
60  myNBNode(nbn),
61  myAmCreateEdgeSource(false),
62  myLogicStatus(loaded ? FEATURE_LOADED : FEATURE_GUESSED),
63  myAmResponsible(false),
64  myHasValidLogic(loaded),
65  myAmTLSSelected(false) {
66  // give a temporal value for boundary
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 void
91 GNEJunction::updateGeometry(bool updateGrid) {
92  // first check if object has to be removed from grid (SUMOTree)
93  if (updateGrid) {
95  }
96  // calculate boundary using EXTENT as size
97  const double EXTENT = 2;
99  myNBNode.getPosition().x() + EXTENT, myNBNode.getPosition().y() + EXTENT);
100  // if junctio own a extra shape, add it to boundary
101  if (myNBNode.getShape().size() > 0) {
103  }
105  // last step is to check if object has to be added into grid (SUMOTree) again
106  if (updateGrid) {
107  myNet->addGLObjectIntoGrid(this);
108  }
109  // rebuild GNECrossings
110  rebuildGNECrossings(true);
111 }
112 
113 
114 void
115 GNEJunction::rebuildGNECrossings(bool rebuildNBNodeCrossings) {
116  // rebuild GNECrossings only if create crossings and walkingAreas in net is enabled
118  if (rebuildNBNodeCrossings) {
119  // build new NBNode::Crossings and walking areas
121  }
122  // create a vector to keep retrieved and created crossings
123  std::vector<GNECrossing*> retrievedCrossings;
124  // iterate over NBNode::Crossings of GNEJunction
125  for (auto NBc : myNBNode.getCrossingsIncludingInvalid()) {
126  // retrieve existent GNECrossing, or create it
127  GNECrossing* retrievedGNECrossing = retrieveGNECrossing(NBc);
128  retrievedCrossings.push_back(retrievedGNECrossing);
129  // check if previously this GNECrossings exists, and if true, remove it from myGNECrossings and insert in tree again
130  std::vector<GNECrossing*>::iterator retrievedExists = std::find(myGNECrossings.begin(), myGNECrossings.end(), retrievedGNECrossing);
131  if (retrievedExists != myGNECrossings.end()) {
132  myGNECrossings.erase(retrievedExists);
133  // update geometry of retrieved crossing
134  retrievedGNECrossing->updateGeometry(true);
135  } else {
136  // include reference to created GNECrossing
137  retrievedGNECrossing->incRef();
138  }
139  }
140  // delete non retrieved GNECrossings (we don't need to extract if from Tree two times)
141  for (auto it : myGNECrossings) {
142  it->decRef();
143  // check if crossing is selected
144  if (it->isAttributeCarrierSelected()) {
145  it->unselectAttributeCarrier();
146  }
147  if (it->unreferenced()) {
148  // show extra information for tests
149  WRITE_DEBUG("Deleting unreferenced " + it->getTagStr() + " in rebuildGNECrossings()");
150  delete it;
151  }
152  }
153  // copy retrieved (existent and created) GNECrossigns to myGNECrossings
154  myGNECrossings = retrievedCrossings;
155  }
156 }
157 
158 
161  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
162  buildPopupHeader(ret, app);
165  // build selection and show parameters menu
168  buildPositionCopyEntry(ret, false);
169  //if (parent.getVisualisationSettings()->editMode != GNE_MODE_CONNECT) {
170  // // XXX if joinable
171  // new FXMenuCommand(ret, "Join adjacent edges", 0, &parent, MID_GNE_JOIN_EDGES);
172  //}
173  const int numEndpoints = (int)myNBNode.getEndPoints().size();
174  // create menu commands
175  FXMenuCommand* mcCustomShape = new FXMenuCommand(ret, "Set custom junction shape", nullptr, &parent, MID_GNE_JUNCTION_EDIT_SHAPE);
176  FXMenuCommand* mcResetCustomShape = new FXMenuCommand(ret, "Reset junction shape", nullptr, &parent, MID_GNE_JUNCTION_RESET_SHAPE);
177  FXMenuCommand* mcReplace = new FXMenuCommand(ret, "Replace junction by geometry point", nullptr, &parent, MID_GNE_JUNCTION_REPLACE);
178  FXMenuCommand* mcSplit = new FXMenuCommand(ret, ("Split junction (" + toString(numEndpoints) + " end points)").c_str(), nullptr, &parent, MID_GNE_JUNCTION_SPLIT);
179  FXMenuCommand* mcClearConnections = new FXMenuCommand(ret, "Clear connections", nullptr, &parent, MID_GNE_JUNCTION_CLEAR_CONNECTIONS);
180  FXMenuCommand* mcResetConnections = new FXMenuCommand(ret, "Reset connections", nullptr, &parent, MID_GNE_JUNCTION_RESET_CONNECTIONS);
181  // check if menu commands has to be disabled
182  EditMode editMode = myNet->getViewNet()->getCurrentEditMode();
183  const bool wrongMode = (editMode == GNE_MODE_CONNECT || editMode == GNE_MODE_TLS || editMode == GNE_MODE_CREATE_EDGE);
184  if (wrongMode) {
185  mcCustomShape->disable();
186  mcClearConnections->disable();
187  mcResetConnections->disable();
188  }
189  // disable mcClearConnections if juction hasn't connections
190  if (getGNEConnections().empty()) {
191  mcClearConnections->disable();
192  }
193  // disable mcResetCustomShape if junction doesn't have a custom shape
194  if (!myNBNode.hasCustomShape()) {
195  mcResetCustomShape->disable();
196  }
197  // checkIsRemovable requiers turnarounds to be computed. This is ugly
198  if (myNBNode.getIncomingEdges().size() == 2 && myNBNode.getOutgoingEdges().size() == 2) {
200  }
201  std::string reason = "wrong edit mode";
202  if (wrongMode || !myNBNode.checkIsRemovableReporting(reason)) {
203  mcReplace->setText(mcReplace->getText() + " (" + reason.c_str() + ")");
204  mcReplace->disable();
205  }
206  if (numEndpoints == 1) {
207  mcSplit->disable();
208  }
209  return ret;
210 }
211 
212 
213 Boundary
215  // Return Boundary depending if myMovingGeometryBoundary is initialised (important for move geometry)
218  } else {
220  b.grow(20);
221  return b;
222  }
223 }
224 
225 
226 void
228  /*
229  // first call function mouseOverObject (to check if this object is under cursor)
230  // @note currently disabled. It will be implemented in an different ticket of #2905
231  mouseOverObject(s);
232  */
233  // declare variables
234  GLfloat color[4];
235  double exaggeration = isAttributeCarrierSelected() ? s.selectionScale : 1;
236  exaggeration *= s.junctionSize.getExaggeration(s, this);
237  // declare values for circles
238  double circleWidth = BUBBLE_RADIUS * exaggeration;
239  double circleWidthSquared = circleWidth * circleWidth;
240  int circleResolution = GNEAttributeCarrier::getCircleResolution(s);
241  // push name
242  if (s.scale * exaggeration * myMaxSize < 1.) {
243  // draw something simple so that selection still works
244  glPushName(getGlID());
246  glPopName();
247  } else {
248  // node shape has been computed and is valid for drawing
249  glPushName(getGlID());
250  const bool drawShape = myNBNode.getShape().size() > 0 && s.drawJunctionShape;
251  const bool drawBubble = (((!drawShape || myNBNode.getShape().area() < 4)
252  && s.drawJunctionShape)
254 
255  if (drawShape) {
256  setColor(s, false);
257  // recognize full transparency and simply don't draw
258  glGetFloatv(GL_CURRENT_COLOR, color);
259  if (color[3] != 0) {
260  glPushMatrix();
261  glTranslated(0, 0, getType());
262  PositionVector shape = myNBNode.getShape();
263  shape.closePolygon();
264  if (exaggeration > 1) {
265  shape.scaleRelative(exaggeration);
266  }
267  if ((s.drawForSelecting) || (s.scale * exaggeration * myMaxSize < 40.)) {
268  GLHelper::drawFilledPoly(shape, true);
269  } else {
271  }
272  // check if dotted contour has to be drawn
273  if (!s.drawForSelecting && (myNet->getViewNet()->getDottedAC() == this) && !drawBubble) {
275  }
276  glPopMatrix();
277  }
278  }
279  if (drawBubble) {
280  setColor(s, true);
281  // recognize full transparency and simply don't draw
282  glGetFloatv(GL_CURRENT_COLOR, color);
283  if (color[3] != 0) {
284  glPushMatrix();
285  glTranslated(myNBNode.getPosition().x(), myNBNode.getPosition().y(), getType() + 0.05);
286  if (!s.drawForSelecting || (myNet->getViewNet()->getPositionInformation().distanceSquaredTo2D(myNBNode.getPosition()) <= (circleWidthSquared + 2))) {
287  std::vector<Position> vertices = GLHelper::drawFilledCircleReturnVertices(circleWidth, circleResolution);
288  // check if dotted contour has to be drawn
289  if (!s.drawForSelecting && myNet->getViewNet()->getDottedAC() == this) {
291  }
292  } else {
293  GLHelper::drawBoxLine(Position(0, 1), 0, 2, 1);
294  }
295  glPopMatrix();
296  }
297  }
298  // draw TLS icon if isn't being drawn for selecting
300  glPushMatrix();
301  Position pos = myNBNode.getPosition();
302  glTranslated(pos.x(), pos.y(), getType() + 0.1);
303  glColor3d(1, 1, 1);
304  const double halfWidth = 32 / s.scale;
305  const double halfHeight = 64 / s.scale;
306  GUITexturesHelper::drawTexturedBox(GUITextureSubSys::getTexture(GNETEXTURE_TLS), -halfWidth, -halfHeight, halfWidth, halfHeight);
307  glPopMatrix();
308  }
309  // (optional) draw name @todo expose this setting if isn't drawed if isn't being drawn for selecting
310  if (!s.drawForSelecting) {
312  }
313  // draw elevation
315  glPushMatrix();
316  // Translate to center of junction
317  glTranslated(myNBNode.getPosition().x(), myNBNode.getPosition().y(), getType() + 1);
318  // draw Z value
320  glPopMatrix();
321  }
322  // name must be removed from selection stack before drawing crossings
323  glPopName();
324  // draw crossings
325  for (auto it : myGNECrossings) {
326  it->drawGL(s);
327  }
328  }
329 }
330 
331 Boundary
333  return myJunctionBoundary;
334 }
335 
336 
337 NBNode*
339  return &myNBNode;
340 }
341 
342 
343 Position
345  return myNBNode.getPosition();
346 }
347 
348 
349 std::vector<GNEJunction*>
351  // use set to avoid duplicates junctions
352  std::set<GNEJunction*> junctions;
353  for (auto i : myGNEIncomingEdges) {
354  junctions.insert(i->getGNEJunctionSource());
355  }
356  for (auto i : myGNEOutgoingEdges) {
357  junctions.insert(i->getGNEJunctionDestiny());
358  }
359  return std::vector<GNEJunction*>(junctions.begin(), junctions.end());
360 }
361 
362 
363 void
365  // Check if incoming edge was already inserted
366  std::vector<GNEEdge*>::iterator i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
367  if (i != myGNEIncomingEdges.end()) {
368  throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + getTagStr() + " with ID " + getID() + "'");
369  } else {
370  // Add edge into containers
371  myGNEIncomingEdges.push_back(edge);
372  myGNEEdges.push_back(edge);
373  }
374 }
375 
376 
377 
378 void
380  // Check if outgoing edge was already inserted
381  std::vector<GNEEdge*>::iterator i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
382  if (i != myGNEOutgoingEdges.end()) {
383  throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + getTagStr() + " with ID " + getID() + "'");
384  } else {
385  // Add edge into containers
386  myGNEOutgoingEdges.push_back(edge);
387  myGNEEdges.push_back(edge);
388  }
389 }
390 
391 
392 void
394  // Check if incoming edge was already inserted
395  std::vector<GNEEdge*>::iterator i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
396  if (i == myGNEIncomingEdges.end()) {
397  throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + getTagStr() + " with ID " + getID() + "'");
398  } else {
399  // remove edge from containers
400  myGNEIncomingEdges.erase(i);
401  myGNEEdges.erase(std::find(myGNEEdges.begin(), myGNEEdges.end(), edge));
402  }
403 }
404 
405 
406 void
408  // Check if outgoing edge was already inserted
409  std::vector<GNEEdge*>::iterator i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
410  if (i == myGNEOutgoingEdges.end()) {
411  throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + getTagStr() + " with ID " + getID() + "'");
412  } else {
413  // remove edge from containers
414  myGNEOutgoingEdges.erase(i);
415  myGNEEdges.erase(std::find(myGNEEdges.begin(), myGNEEdges.end(), edge));
416  }
417 }
418 
419 
420 const std::vector<GNEEdge*>&
422  return myGNEEdges;
423 }
424 
425 
426 const std::vector<GNEEdge*>&
428  return myGNEIncomingEdges;
429 }
430 
431 
432 const std::vector<GNEEdge*>&
434  return myGNEOutgoingEdges;
435 }
436 
437 
438 const std::vector<GNECrossing*>&
440  return myGNECrossings;
441 }
442 
443 
444 std::vector<GNEConnection*>
446  std::vector<GNEConnection*> connections;
447  for (auto i : myGNEIncomingEdges) {
448  for (auto j : i->getGNEConnections()) {
449  connections.push_back(j);
450  }
451  }
452  return connections;
453 }
454 
455 
456 void
458  myAmCreateEdgeSource = true;
459 }
460 
461 
462 void
464  myAmCreateEdgeSource = false;
465 }
466 
467 
468 void
469 GNEJunction::selectTLS(bool selected) {
470  myAmTLSSelected = selected;
471 }
472 
473 
474 void
475 GNEJunction::startGeometryMoving(bool extendToNeighbors) {
476  // save current centering boundary
478  // First declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
479  std::set<GNEJunction*> affectedJunctions;
480  std::set<GNEEdge*> affectedEdges;
481  // Iterate over GNEEdges
482  for (auto i : myGNEEdges) {
483  // Add source and destiny junctions
484  affectedJunctions.insert(i->getGNEJunctionSource());
485  affectedJunctions.insert(i->getGNEJunctionDestiny());
486  // Obtain neighbors of Junction source
487  for (auto j : i->getGNEJunctionSource()->getGNEEdges()) {
488  affectedEdges.insert(j);
489  }
490  // Obtain neighbors of Junction destiny
491  for (auto j : i->getGNEJunctionDestiny()->getGNEEdges()) {
492  affectedEdges.insert(j);
493  }
494  }
495  // Iterate over affected Junctions only if extendToNeighbors is enabled
496  if (extendToNeighbors) {
497  for (auto i : affectedJunctions) {
498  // don't include this junction (to avoid start more than one times)
499  if (i != this) {
500  // start geometry moving in edges
501  i->startGeometryMoving(false);
502  }
503  }
504  }
505  // Iterate over affected Edges
506  for (auto i : affectedEdges) {
507  // start geometry moving in edges
508  i->startGeometryMoving();
509  }
510 }
511 
512 
513 void
514 GNEJunction::endGeometryMoving(bool extendToNeighbors) {
515  // Remove object from net
517  // reset myMovingGeometryBoundary
519  // update geometry without updating grid
520  updateGeometry(false);
521  // First declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
522  std::set<GNEJunction*> affectedJunctions;
523  std::set<GNEEdge*> affectedEdges;
524  // Iterate over GNEEdges
525  for (auto i : myGNEEdges) {
526  // Add source and destiny junctions
527  affectedJunctions.insert(i->getGNEJunctionSource());
528  affectedJunctions.insert(i->getGNEJunctionDestiny());
529  // Obtain neighbors of Junction source
530  for (auto j : i->getGNEJunctionSource()->getGNEEdges()) {
531  affectedEdges.insert(j);
532  }
533  // Obtain neighbors of Junction destiny
534  for (auto j : i->getGNEJunctionDestiny()->getGNEEdges()) {
535  affectedEdges.insert(j);
536  }
537  }
538  // Iterate over affected Junctions
539  if (extendToNeighbors) {
540  for (auto i : affectedJunctions) {
541  // don't include this junction (to avoid end it more than one times)
542  if (i != this) {
543  // end geometry moving in edges
544  i->endGeometryMoving(false);
545  }
546  }
547  }
548  // Iterate over affected Edges
549  for (auto i : affectedEdges) {
550  // end geometry moving in edges
551  i->endGeometryMoving();
552  }
553  // add object into grid again (using the new centering boundary)
554  myNet->addGLObjectIntoGrid(this);
555 }
556 
557 
558 void
559 GNEJunction::moveGeometry(const Position& oldPos, const Position& offset) {
560  // Abort moving if there is another junction in the exactly target position
561  bool abort = false;
562  std::vector<GNEJunction*> junctionNeighbours = getJunctionNeighbours();
563  for (auto i : junctionNeighbours) {
564  if (i->getPositionInView() == myNBNode.getPosition()) {
565  abort = true;
566  }
567  }
568  if (!abort) {
569  Position newPosition = oldPos;
570  newPosition.add(offset);
571  // filtern position using snap to active grid
572  // filtern position using snap to active grid
573  newPosition = myNet->getViewNet()->snapToActiveGrid(newPosition);
574  moveJunctionGeometry(newPosition, false);
575  }
576 }
577 
578 
579 void
582  undoList->p_begin("position of " + getTagStr());
583  undoList->p_add(new GNEChange_Attribute(this, SUMO_ATTR_POSITION, toString(myNBNode.getPosition()), true, toString(oldPos)));
584  undoList->p_end();
585  } else {
586  // tried to set an invalid position, revert back to the previous one
587  moveJunctionGeometry(oldPos, true);
588  }
589 }
590 
591 
592 void
594  // First declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
595  std::set<GNEJunction*> affectedJunctions;
596  std::set<GNEEdge*> affectedEdges;
597  // Iterate over GNEEdges
598  for (auto i : myGNEEdges) {
599  // Add source and destiny junctions
600  affectedJunctions.insert(i->getGNEJunctionSource());
601  affectedJunctions.insert(i->getGNEJunctionDestiny());
602  // Obtain neighbors of Junction source
603  for (auto j : i->getGNEJunctionSource()->getGNEEdges()) {
604  affectedEdges.insert(j);
605  }
606  // Obtain neighbors of Junction destiny
607  for (auto j : i->getGNEJunctionDestiny()->getGNEEdges()) {
608  affectedEdges.insert(j);
609  }
610  }
611  // Iterate over affected Junctions only if updateGrid is enabled
612  if (updateGrid) {
613  for (auto i : affectedJunctions) {
614  // Update geometry of Junction
615  i->updateGeometry(updateGrid);
616  }
617  }
618  // Iterate over affected Edges
619  for (auto i : affectedEdges) {
620  // Update edge geometry
621  i->updateGeometry(updateGrid);
622  }
623  // Finally update geometry of this junction
624  updateGeometry(updateGrid);
625  // Update view to show the new shapes
626  if (myNet->getViewNet()) {
627  myNet->getViewNet()->update();
628  }
629 }
630 
631 
632 void
634  if (!myNBNode.hasCustomShape()) {
635  myNBNode.myPoly.clear();
637  }
638 }
639 
640 
641 void
642 GNEJunction::setLogicValid(bool valid, GNEUndoList* undoList, const std::string& status) {
643  myHasValidLogic = valid;
644  if (!valid) {
645  assert(undoList != 0);
646  assert(undoList->hasCommandGroup());
648  EdgeVector incoming = myNBNode.getIncomingEdges();
649  for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
650  GNEEdge* srcEdge = myNet->retrieveEdge((*it)->getID());
651  removeConnectionsFrom(srcEdge, undoList, false); // false, because the whole tls will be invalidated at the end
652  undoList->add(new GNEChange_Attribute(srcEdge, GNE_ATTR_MODIFICATION_STATUS, status), true);
653  }
654  undoList->add(new GNEChange_Attribute(this, GNE_ATTR_MODIFICATION_STATUS, status), true);
655  invalidateTLS(undoList);
656  } else {
657  // logic valed, then rebuild GNECrossings to adapt it to the new logic
658  // (but don't rebuild the crossings in NBNode because they are already finished)
659  rebuildGNECrossings(false);
660  }
661 }
662 
663 
664 void
665 GNEJunction::removeConnectionsFrom(GNEEdge* edge, GNEUndoList* undoList, bool updateTLS, int lane) {
666  NBEdge* srcNBE = edge->getNBEdge();
667  NBEdge* turnEdge = srcNBE->getTurnDestination();
668  // Make a copy of connections
669  std::vector<NBEdge::Connection> connections = srcNBE->getConnections();
670  // delete in reverse so that undoing will add connections in the original order
671  for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) {
672  if (lane >= 0 && (*con_it).fromLane != lane) {
673  continue;
674  }
675  bool hasTurn = con_it->toEdge == turnEdge;
676  undoList->add(new GNEChange_Connection(edge, *con_it, false, false), true);
677  // needs to come after GNEChange_Connection
678  // XXX bug: this code path will not be used on a redo!
679  if (hasTurn) {
680  myNet->addExplicitTurnaround(srcNBE->getID());
681  }
682  }
683  if (updateTLS) {
684  std::vector<NBConnection> removeConnections;
685  for (NBEdge::Connection con : connections) {
686  removeConnections.push_back(NBConnection(srcNBE, con.fromLane, con.toEdge, con.toLane));
687  }
688  removeTLSConnections(removeConnections, undoList);
689  }
690 }
691 
692 
693 void
694 GNEJunction::removeConnectionsTo(GNEEdge* edge, GNEUndoList* undoList, bool updateTLS, int lane) {
695  NBEdge* destNBE = edge->getNBEdge();
696  std::vector<NBConnection> removeConnections;
697  for (NBEdge* srcNBE : myNBNode.getIncomingEdges()) {
698  GNEEdge* srcEdge = myNet->retrieveEdge(srcNBE->getID());
699  std::vector<NBEdge::Connection> connections = srcNBE->getConnections();
700  for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) {
701  if ((*con_it).toEdge == destNBE) {
702  if (lane >= 0 && (*con_it).toLane != lane) {
703  continue;
704  }
705  bool hasTurn = srcNBE->getTurnDestination() == destNBE;
706  undoList->add(new GNEChange_Connection(srcEdge, *con_it, false, false), true);
707  // needs to come after GNEChange_Connection
708  // XXX bug: this code path will not be used on a redo!
709  if (hasTurn) {
710  myNet->addExplicitTurnaround(srcNBE->getID());
711  }
712  removeConnections.push_back(NBConnection(srcNBE, (*con_it).fromLane, destNBE, (*con_it).toLane));
713  }
714  }
715  }
716  if (updateTLS) {
717  removeTLSConnections(removeConnections, undoList);
718  }
719 }
720 
721 
722 void
723 GNEJunction::removeTLSConnections(std::vector<NBConnection>& connections, GNEUndoList* undoList) {
724  if (connections.size() == 0) {
725  return;
726  }
727  const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode.getControllingTLS(); // make a copy!
728  for (auto it : coypOfTls) {
729  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it);
730  // guessed TLS (NBOwnTLDef) do not need to be updated
731  if (tlDef != nullptr) {
732  std::string newID = tlDef->getID();
733  // create replacement before deleting the original because deletion will mess up saving original nodes
734  NBLoadedSUMOTLDef* replacementDef = new NBLoadedSUMOTLDef(tlDef, tlDef->getLogic());
735  for (NBConnection& con : connections) {
736  replacementDef->removeConnection(con);
737  }
738  undoList->add(new GNEChange_TLS(this, tlDef, false), true);
739  undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
740  // the removed traffic light may have controlled more than one junction. These too have become invalid now
741  const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
742  for (auto it_node : copyOfNodes) {
743  GNEJunction* sharing = myNet->retrieveJunction(it_node->getID());
744  undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
745  undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
746  }
747  }
748  }
749 }
750 
751 
752 void
754  // remap connections of the edge
755  assert(which->getLanes().size() == by->getLanes().size());
756  std::vector<NBEdge::Connection> connections = which->getNBEdge()->getConnections();
757  for (NBEdge::Connection& c : connections) {
758  undoList->add(new GNEChange_Connection(which, c, false, false), true);
759  undoList->add(new GNEChange_Connection(by, c, false, true), true);
760  }
761  // also remap tls connections
762  const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode.getControllingTLS(); // make a copy!
763  for (auto it : coypOfTls) {
764  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it);
765  // guessed TLS (NBOwnTLDef) do not need to be updated
766  if (tlDef != nullptr) {
767  std::string newID = tlDef->getID();
768  // create replacement before deleting the original because deletion will mess up saving original nodes
769  NBLoadedSUMOTLDef* replacementDef = new NBLoadedSUMOTLDef(tlDef, tlDef->getLogic());
770  for (int i = 0; i < (int)which->getLanes().size(); ++i) {
771  replacementDef->replaceRemoved(which->getNBEdge(), i, by->getNBEdge(), i);
772  }
773  undoList->add(new GNEChange_TLS(this, tlDef, false), true);
774  undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
775  // the removed traffic light may have controlled more than one junction. These too have become invalid now
776  const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
777  for (auto it_node : copyOfNodes) {
778  GNEJunction* sharing = myNet->retrieveJunction(it_node->getID());
779  undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
780  undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
781  }
782  }
783  }
784 }
785 
786 
787 void
789  EdgeVector incoming = myNBNode.getIncomingEdges();
790  for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
791  NBEdge* srcNBE = *it;
792  GNEEdge* srcEdge = myNet->retrieveEdge(srcNBE->getID());
793  undoList->add(new GNEChange_Attribute(srcEdge, GNE_ATTR_MODIFICATION_STATUS, FEATURE_MODIFIED), true);
794  }
795 }
796 
797 
798 void
799 GNEJunction::invalidateTLS(GNEUndoList* undoList, const NBConnection& deletedConnection, const NBConnection& addedConnection) {
800  assert(undoList->hasCommandGroup());
801  // NBLoadedSUMOTLDef becomes invalid, replace with NBOwnTLDef which will be dynamically recomputed
802  const std::set<NBTrafficLightDefinition*> coypOfTls = myNBNode.getControllingTLS(); // make a copy!
803  for (auto it : coypOfTls) {
804  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it);
805  if (tlDef != nullptr) {
806  NBTrafficLightDefinition* replacementDef = nullptr;
807  std::string newID = tlDef->getID(); // + "_reguessed"; // changes due to reguessing will be visible in diff
808  if (deletedConnection != NBConnection::InvalidConnection) {
809  // create replacement before deleting the original because deletion will mess up saving original nodes
810  NBLoadedSUMOTLDef* repl = new NBLoadedSUMOTLDef(tlDef, tlDef->getLogic());
811  repl->removeConnection(deletedConnection);
812  replacementDef = repl;
813  } else if (addedConnection != NBConnection::InvalidConnection) {
814  if (addedConnection.getTLIndex() == NBConnection::InvalidTlIndex) {
815  // custom tl indices of crossings might become invalid upon recomputation so we must save them
816  // however, the could remain valud so we register a change but keep them at their old value
817  for (GNECrossing* c : myGNECrossings) {
818  const std::string oldValue = c->getAttribute(SUMO_ATTR_TLLINKINDEX);
820  undoList->add(new GNEChange_Attribute(c, SUMO_ATTR_TLLINKINDEX, oldValue), true);
821  const std::string oldValue2 = c->getAttribute(SUMO_ATTR_TLLINKINDEX);
823  undoList->add(new GNEChange_Attribute(c, SUMO_ATTR_TLLINKINDEX2, oldValue2), true);
824  }
825  }
826  NBLoadedSUMOTLDef* repl = new NBLoadedSUMOTLDef(tlDef, tlDef->getLogic());
827  repl->addConnection(addedConnection.getFrom(), addedConnection.getTo(),
828  addedConnection.getFromLane(), addedConnection.getToLane(), addedConnection.getTLIndex());
829  replacementDef = repl;
830  } else {
831  replacementDef = new NBOwnTLDef(newID, tlDef->getOffset(), tlDef->getType());
832  replacementDef->setProgramID(tlDef->getProgramID());
833  }
834  undoList->add(new GNEChange_TLS(this, tlDef, false), true);
835  undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
836  // the removed traffic light may have controlled more than one junction. These too have become invalid now
837  const std::vector<NBNode*> copyOfNodes = tlDef->getNodes(); // make a copy!
838  for (auto it_node : copyOfNodes) {
839  GNEJunction* sharing = myNet->retrieveJunction(it_node->getID());
840  undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
841  undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
842  }
843  }
844  }
845 }
846 
847 void
849  // obtain a copy of GNECrossing of junctions
850  auto copyOfGNECrossings = myGNECrossings;
851  // iterate over copy of GNECrossings
852  for (int i = 0; i < (int)myGNECrossings.size(); i++) {
853  auto c = myGNECrossings.at(i);
854  // obtain the set of edges vinculated with the crossing (due it works as ID)
855  EdgeSet edgeSet(c->getCrossingEdges().begin(), c->getCrossingEdges().end());
856  // If this edge is part of the set of edges of crossing
857  if (edgeSet.count(edge->getNBEdge()) == 1) {
858  // delete crossing if this is their last edge
859  if ((c->getCrossingEdges().size() == 1) && (c->getCrossingEdges().front() == edge->getNBEdge())) {
860  myNet->deleteCrossing(c, undoList);
861  i = 0;
862  } else {
863  // remove this edge of the edge's attribute of crossing (note: This can invalidate the crossing)
864  std::vector<std::string> edges = GNEAttributeCarrier::parse<std::vector<std::string>>(c->getAttribute(SUMO_ATTR_EDGES));
865  edges.erase(std::find(edges.begin(), edges.end(), edge->getID()));
866  c->setAttribute(SUMO_ATTR_EDGES, joinToString(edges, " "), undoList);
867  }
868  }
869  }
870 }
871 
872 
873 bool
875  return myHasValidLogic;
876 }
877 
878 
880 GNEJunction::retrieveGNECrossing(NBNode::Crossing* crossing, bool createIfNoExist) {
881  // iterate over all crossing
882  for (auto i : myGNECrossings) {
883  // if found, return it
884  if (i->getCrossingEdges() == crossing->edges) {
885  return i;
886  }
887  }
888  if (createIfNoExist) {
889  // create new GNECrossing
890  GNECrossing* createdGNECrossing = new GNECrossing(this, crossing->edges);
891  // show extra information for tests
892  WRITE_DEBUG("Created " + createdGNECrossing->getTagStr() + " '" + createdGNECrossing->getID() + "' in retrieveGNECrossing()");
893  // update geometry after creating
894  createdGNECrossing->updateGeometry(true);
895  return createdGNECrossing;
896  } else {
897  return nullptr;
898  }
899 }
900 
901 
902 void
903 GNEJunction::markConnectionsDeprecated(bool includingNeighbours) {
904  // only it's needed to mark the connections of incoming edges
905  for (auto i : myGNEIncomingEdges) {
906  for (auto j : i->getGNEConnections()) {
907  j->markConnectionGeometryDeprecated();
908  }
909  if (includingNeighbours) {
910  i->getGNEJunctionSource()->markConnectionsDeprecated(false);
911  }
912  }
913 }
914 
915 
916 std::string
918  switch (key) {
919  case SUMO_ATTR_ID:
920  return getMicrosimID();
921  case SUMO_ATTR_POSITION:
922  return toString(myNBNode.getPosition());
923  case SUMO_ATTR_TYPE:
924  return toString(myNBNode.getType());
926  return myLogicStatus;
927  case SUMO_ATTR_SHAPE:
928  return toString(myNBNode.getShape());
929  case SUMO_ATTR_RADIUS:
930  return toString(myNBNode.getRadius());
931  case SUMO_ATTR_TLTYPE:
932  // @todo this causes problems if the node were to have multiple programs of different type (plausible)
933  return myNBNode.isTLControlled() ? toString((*myNBNode.getControllingTLS().begin())->getType()) : "";
934  case SUMO_ATTR_TLID:
935  return myNBNode.isTLControlled() ? toString((*myNBNode.getControllingTLS().begin())->getID()) : "";
937  // keep clear is only used as a convenience feature in plain xml
938  // input. When saving to .net.xml the status is saved only for the connections
939  // to show the correct state we must check all connections
940  if (!myNBNode.getKeepClear()) {
941  return toString(false);
942  } else {
943  for (auto i : myGNEIncomingEdges) {
944  for (auto j : i->getGNEConnections()) {
945  if (j->getNBEdgeConnection().keepClear) {
946  return toString(true);
947  }
948  }
949  }
950  return toString(false);
951  }
954  case GNE_ATTR_SELECTED:
956  case GNE_ATTR_GENERIC:
957  return getGenericParametersStr();
958  default:
959  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
960  }
961 }
962 
963 
964 void
965 GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
966  if (value == getAttribute(key)) {
967  return; //avoid needless changes, later logic relies on the fact that attributes have changed
968  }
969  switch (key) {
970  case SUMO_ATTR_ID:
971  case SUMO_ATTR_POSITION:
973  case SUMO_ATTR_SHAPE:
974  case SUMO_ATTR_RADIUS:
975  case SUMO_ATTR_TLTYPE:
977  case GNE_ATTR_SELECTED:
978  case GNE_ATTR_GENERIC:
979  undoList->add(new GNEChange_Attribute(this, key, value), true);
980  break;
982  // change Keep Clear attribute in all connections
983  undoList->p_begin("change keepClear for whole junction");
984  for (auto i : myGNEIncomingEdges) {
985  for (auto j : i->getGNEConnections()) {
986  undoList->add(new GNEChange_Attribute(j, key, value), true);
987  }
988  }
989  undoList->add(new GNEChange_Attribute(this, key, value), true);
990  undoList->p_end();
991  break;
992  case SUMO_ATTR_TYPE: {
993  undoList->p_begin("change " + getTagStr() + " type");
995  if (getNBNode()->isTLControlled() &&
996  // if switching changing from or to traffic_light_right_on_red we need to remove the old plan
999  ) {
1000  // make a copy because we will modify the original
1001  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1002  for (auto it : copyOfTls) {
1003  undoList->add(new GNEChange_TLS(this, it, false), true);
1004  }
1005  }
1006  if (!getNBNode()->isTLControlled()) {
1007  // create new traffic light
1008  undoList->add(new GNEChange_TLS(this, nullptr, true), true);
1009  }
1010  } else if (getNBNode()->isTLControlled()) {
1011  // delete old traffic light
1012  // make a copy because we will modify the original
1013  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1014  for (auto it : copyOfTls) {
1015  undoList->add(new GNEChange_TLS(this, it, false, false), true);
1016  }
1017  }
1018  // must be the final step, otherwise we do not know which traffic lights to remove via GNEChange_TLS
1019  undoList->add(new GNEChange_Attribute(this, key, value), true);
1020  undoList->p_end();
1021  break;
1022  }
1023  case SUMO_ATTR_TLID: {
1024  undoList->p_begin("change " + toString(SUMO_TAG_TRAFFIC_LIGHT) + " id");
1025  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1026  assert(copyOfTls.size() > 0);
1027  NBTrafficLightDefinition* currentTLS = *copyOfTls.begin();
1028  NBTrafficLightDefinition* currentTLSCopy = nullptr;
1029  const bool currentIsSingle = currentTLS->getNodes().size() == 1;
1030  const bool currentIsLoaded = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS) != nullptr;
1031  if (currentIsLoaded) {
1032  currentTLSCopy = new NBLoadedSUMOTLDef(currentTLS,
1033  dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS)->getLogic());
1034  }
1035  // remove from previous tls
1036  for (auto it : copyOfTls) {
1037  undoList->add(new GNEChange_TLS(this, it, false), true);
1038  }
1040  // programs to which the current node shall be added
1041  const std::map<std::string, NBTrafficLightDefinition*> programs = tlCont.getPrograms(value);
1042  if (programs.size() > 0) {
1043  for (auto it : programs) {
1044  NBTrafficLightDefinition* oldTLS = it.second;
1045  if (dynamic_cast<NBOwnTLDef*>(oldTLS) != nullptr) {
1046  undoList->add(new GNEChange_TLS(this, oldTLS, true), true);
1047  } else {
1048  // delete and re-create the definition because the loaded phases are now invalid
1049  if (dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS) != nullptr &&
1050  dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->usingSignalGroups()) {
1051  // keep the old program and add all-red state for the added links
1052  NBLoadedSUMOTLDef* newTLSJoined = new NBLoadedSUMOTLDef(oldTLS, dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->getLogic());
1053  newTLSJoined->joinLogic(currentTLSCopy);
1054  undoList->add(new GNEChange_TLS(this, newTLSJoined, true, true), true);
1055  } else {
1056  undoList->add(new GNEChange_TLS(this, nullptr, true, false, value), true);
1057  }
1059  // switch from old to new definition
1060  const std::vector<NBNode*> copyOfNodes = oldTLS->getNodes();
1061  for (auto it_node : copyOfNodes) {
1062  GNEJunction* oldJunction = myNet->retrieveJunction(it_node->getID());
1063  undoList->add(new GNEChange_TLS(oldJunction, oldTLS, false), true);
1064  undoList->add(new GNEChange_TLS(oldJunction, newTLS, true), true);
1065  }
1066  }
1067  }
1068  } else {
1069  if (currentIsSingle && currentIsLoaded) {
1070  // rename the traffic light but keep everything else
1071  NBTrafficLightLogic* renamedLogic = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLSCopy)->getLogic();
1072  renamedLogic->setID(value);
1073  NBLoadedSUMOTLDef* renamedTLS = new NBLoadedSUMOTLDef(currentTLSCopy, renamedLogic);
1074  renamedTLS->setID(value);
1075  undoList->add(new GNEChange_TLS(this, renamedTLS, true, true), true);
1076  } else {
1077  // create new traffic light
1078  undoList->add(new GNEChange_TLS(this, nullptr, true, false, value), true);
1079  }
1080  }
1081  delete currentTLSCopy;
1082  undoList->p_end();
1083  break;
1084  }
1085  default:
1086  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1087  }
1088 }
1089 
1090 
1091 bool
1092 GNEJunction::isValid(SumoXMLAttr key, const std::string& value) {
1093  switch (key) {
1094  case SUMO_ATTR_ID:
1095  return SUMOXMLDefinitions::isValidNetID(value) && (myNet->retrieveJunction(value, false) == nullptr);
1096  case SUMO_ATTR_TYPE:
1098  case SUMO_ATTR_POSITION:
1099  return canParse<Position>(value);
1100  case SUMO_ATTR_SHAPE:
1101  // empty shapes are allowed
1102  return canParse<PositionVector>(value);
1103  case SUMO_ATTR_RADIUS:
1104  return canParse<double>(value);
1105  case SUMO_ATTR_TLTYPE:
1107  case SUMO_ATTR_TLID:
1108  return myNBNode.isTLControlled() && (value != "");
1109  case SUMO_ATTR_KEEP_CLEAR:
1110  return canParse<bool>(value);
1113  case GNE_ATTR_SELECTED:
1114  return canParse<bool>(value);
1115  case GNE_ATTR_GENERIC:
1116  return isGenericParametersValid(value);
1117  default:
1118  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1119  }
1120 }
1121 
1122 
1123 std::string
1125  std::string result;
1126  // Generate an string using the following structure: "key1=value1|key2=value2|...
1127  for (auto i : myNBNode.getParametersMap()) {
1128  result += i.first + "=" + i.second + "|";
1129  }
1130  // remove the last "|"
1131  if (!result.empty()) {
1132  result.pop_back();
1133  }
1134  return result;
1135 }
1136 
1137 
1138 std::vector<std::pair<std::string, std::string> >
1140  std::vector<std::pair<std::string, std::string> > result;
1141  // iterate over parameters map and fill result
1142  for (auto i : myNBNode.getParametersMap()) {
1143  result.push_back(std::make_pair(i.first, i.second));
1144  }
1145  return result;
1146 }
1147 
1148 
1149 void
1150 GNEJunction::setGenericParametersStr(const std::string& value) {
1151  // clear parameters
1153  // separate value in a vector of string using | as separator
1154  std::vector<std::string> parsedValues;
1155  StringTokenizer stValues(value, "|", true);
1156  while (stValues.hasNext()) {
1157  parsedValues.push_back(stValues.next());
1158  }
1159  // check that parsed values (A=B)can be parsed in generic parameters
1160  for (auto i : parsedValues) {
1161  std::vector<std::string> parsedParameters;
1162  StringTokenizer stParam(i, "=", true);
1163  while (stParam.hasNext()) {
1164  parsedParameters.push_back(stParam.next());
1165  }
1166  // Check that parsed parameters are exactly two and contains valid chracters
1167  if (parsedParameters.size() == 2 && SUMOXMLDefinitions::isValidGenericParameterKey(parsedParameters.front()) && SUMOXMLDefinitions::isValidGenericParameterValue(parsedParameters.back())) {
1168  myNBNode.setParameter(parsedParameters.front(), parsedParameters.back());
1169  }
1170  }
1171 }
1172 
1173 
1174 void
1176  myAmResponsible = newVal;
1177 }
1178 
1179 // ===========================================================================
1180 // private
1181 // ===========================================================================
1182 
1183 void
1184 GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value) {
1185  switch (key) {
1186  case SUMO_ATTR_ID: {
1187  myNet->renameJunction(this, value);
1188  break;
1189  }
1190  case SUMO_ATTR_TYPE: {
1192  break;
1193  }
1194  case SUMO_ATTR_POSITION: {
1195  // set new position in NBNode (note: Junctions don't need to refresh it in the RTREE due the variable myJunctionBoundary
1196  moveJunctionGeometry(parse<Position>(value), true);
1197  // mark this connections and all of the junction's Neighbours as deprecated
1199  break;
1200  }
1202  if (myLogicStatus == FEATURE_GUESSED && value != FEATURE_GUESSED) {
1203  // clear guessed connections. previous connections will be restored
1205  // Clear GNEConnections of incoming edges
1206  for (auto i : myGNEIncomingEdges) {
1207  i->clearGNEConnections();
1208  }
1209  }
1210  myLogicStatus = value;
1211  break;
1212  case SUMO_ATTR_SHAPE: {
1213  const PositionVector shape = parse<PositionVector>(value);
1214  myNBNode.setCustomShape(shape);
1215  // mark this connections and all of the junction's Neighbours as deprecated
1217  break;
1218  }
1219  case SUMO_ATTR_RADIUS: {
1220  myNBNode.setRadius(parse<double>(value));
1221  break;
1222  }
1223  case SUMO_ATTR_TLTYPE: {
1224  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1225  for (auto it : copyOfTls) {
1226  it->setType(SUMOXMLDefinitions::TrafficLightTypes.get(value));
1227  }
1228  break;
1229  }
1230  case SUMO_ATTR_KEEP_CLEAR: {
1231  myNBNode.setKeepClear(parse<bool>(value));
1232  break;
1233  }
1236  break;
1237  case GNE_ATTR_SELECTED:
1238  if (parse<bool>(value)) {
1240  } else {
1242  }
1243  break;
1244  case GNE_ATTR_GENERIC:
1245  setGenericParametersStr(value);
1246  break;
1247  default:
1248  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1249  }
1250  // Update Geometry after setting a new attribute (but avoided for certain attributes)
1251  if((key != SUMO_ATTR_ID) && (key != GNE_ATTR_GENERIC) && (key != GNE_ATTR_SELECTED)) {
1252  updateGeometry(true);
1253  }
1254 }
1255 
1256 
1257 void
1259  // only continue if there isn't already a AC under cursor
1260  if (myNet->getViewNet()->getDottedAC() == nullptr) {
1261  // obtain current x-y coordinates
1263  // check if junction are drawn as buuble or as polygon
1264  const bool drawShape = myNBNode.getShape().size() > 0 && s.drawJunctionShape;
1265  const bool drawBubble = (((!drawShape || myNBNode.getShape().area() < 4) && s.drawJunctionShape) || myNet->getViewNet()->showJunctionAsBubbles());
1266  // declare values for circles
1267  double exaggeration = isAttributeCarrierSelected() ? s.selectionScale : 1;
1268  exaggeration *= s.junctionSize.getExaggeration(s, this);
1269  double circleWidth = BUBBLE_RADIUS * exaggeration;
1270  double circleWidthSquared = circleWidth * circleWidth;
1271  if (drawBubble) {
1272  // check if cursor is whithin the circle
1273  if (myNet->getViewNet()->getPositionInformation().distanceSquaredTo2D(myNBNode.getPosition()) <= circleWidthSquared) {
1274  myNet->getViewNet()->setDottedAC(this);
1275  }
1276  } else if (drawShape) {
1277  // check if cursor is within the shape
1278  if (myNBNode.getShape().around(mousePos)) {
1279  myNet->getViewNet()->setDottedAC(this);
1280  }
1281  }
1282  }
1283 }
1284 
1285 
1286 double
1288  switch (s.junctionColorer.getActive()) {
1289  case 0:
1290  if (bubble) {
1291  return 1;
1292  } else {
1293  return 0;
1294  }
1295  case 1:
1296  return isAttributeCarrierSelected();
1297  case 2:
1298  switch (myNBNode.getType()) {
1300  return 0;
1302  return 1;
1303  case NODETYPE_PRIORITY:
1304  return 2;
1306  return 3;
1308  return 4;
1309  case NODETYPE_ALLWAY_STOP:
1310  return 5;
1311  case NODETYPE_DISTRICT:
1312  return 6;
1313  case NODETYPE_NOJUNCTION:
1314  return 7;
1315  case NODETYPE_DEAD_END:
1317  return 8;
1318  case NODETYPE_UNKNOWN:
1319  case NODETYPE_INTERNAL:
1320  assert(false);
1321  return 8;
1322  case NODETYPE_RAIL_SIGNAL:
1323  return 9;
1324  case NODETYPE_ZIPPER:
1325  return 10;
1327  return 11;
1329  return 12;
1330  }
1331  case 3:
1332  return myNBNode.getPosition().z();
1333  default:
1334  assert(false);
1335  return 0;
1336  }
1337 }
1338 
1339 
1340 void
1341 GNEJunction::moveJunctionGeometry(const Position& pos, bool updateGrid) {
1342  const Position orig = myNBNode.getPosition();
1343  myNBNode.reinit(pos, myNBNode.getType());
1344  // set new position of adjacent edges
1345  for (auto i : getNBNode()->getEdges()) {
1346  myNet->retrieveEdge(i->getID())->updateJunctionPosition(this, orig, updateGrid);
1347  }
1348  // Update shapes without include connections, because the aren't showed in Move mode
1349  updateShapesAndGeometries(updateGrid);
1350 }
1351 
1352 
1353 void
1354 GNEJunction::setColor(const GUIVisualizationSettings& s, bool bubble) const {
1356  // override with special colors (unless the color scheme is based on selection)
1359  }
1360  if (myAmCreateEdgeSource) {
1361  glColor3d(0, 1, 0);
1362  }
1363 }
1364 
1365 void
1368  tlCont.insert(tlDef, forceInsert); // may return false for tlDef which controls multiple junctions
1369  tlDef->addNode(&myNBNode);
1370 }
1371 
1372 
1373 void
1376  if (tlDef->getNodes().size() == 1) {
1377  tlCont.extract(tlDef);
1378  }
1380 }
1381 
1382 /****************************************************************************/
GUIVisualizationSizeSettings junctionSize
bool getKeepClear() const
Returns the keepClear flag.
Definition: NBNode.h:277
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:281
bool around(const Position &p, double offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point...
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...
static StringBijection< RightOfWay > RightOfWayValues
lane spread functions
bool myHasValidLogic
whether this junctions logic is valid
Definition: GNEJunction.h:284
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:271
Position getPositionInView() const
Return current position.
std::string myLogicStatus
modification status of the junction logic (all connections across this junction)
Definition: GNEJunction.h:278
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:160
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:900
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()
void invalidateShape()
void moveJunctionGeometry(const Position &pos, bool updateGrid)
reposition the node at pos and informs the edges
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
void setRightOfWay(RightOfWay rightOfWay)
set method for computing right-of-way
Definition: NBNode.h:506
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:817
void markAsCreateEdgeSource()
marks as first junction in createEdge-mode
void removeEdgeFromCrossings(GNEEdge *edge, GNEUndoList *undoList)
removes the given edge from all pedestrian crossings
NBNetBuilder * getNetBuilder() const
get net builder
Definition: GNENet.cpp:1392
A loaded (complete) traffic light logic.
bool myAmCreateEdgeSource
whether this junction is the first junction for a newly creatededge
Definition: GNEJunction.h:275
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:265
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
Definition: NBNode.cpp:286
bool isValid(SumoXMLAttr key, const std::string &value)
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:734
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:511
Position snapToActiveGrid(const Position &pos) const
Returns a position that is mapped to the closest grid point if the grid is active.
The representation of a single edge during network building.
Definition: NBEdge.h:65
TrafficLightType getType() const
get the algorithm type (static etc..)
double x() const
Returns the x-position.
Definition: Position.h:57
mode for editing tls
Definition: GNEViewNet.h:58
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:611
link,node: the traffic light id responsible for this link
T MAX2(T a, T b)
Definition: StdDefs.h:76
double getWidth() const
Returns the width of the boudary (x-axis)
Definition: Boundary.cpp:155
std::string getGenericParametersStr() const
return generic parameters in string format
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:77
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition: NBEdge.cpp:3013
static void drawFilledPoly(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:78
int editMode
the current NETEDIT mode (temporary)
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:1773
NBEdge * getFrom() const
returns the from-edge (start of the connection)
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
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:78
bool myAmTLSSelected
whether this junction is selected in tls-mode
Definition: GNEJunction.h:287
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
Definition: NBNode.cpp:347
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition: NBNode.cpp:1985
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.
Boundary getBoundary() const
Returns the boundary of the junction.
turn junction into geometry node
Definition: GUIAppEnum.h:730
generic attribute
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:42
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.
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:255
double area() const
Returns the area (0 for non-closed)
SUMOTime getOffset()
Returns the offset.
void renameJunction(GNEJunction *junction, const std::string &newID)
updates the map and reserves new id
Definition: GNENet.cpp:1761
static void drawFilledPolyTesselated(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:97
void removeOutgoingGNEEdge(GNEEdge *edge)
remove outgoing GNEEdge
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
const std::vector< GNECrossing * > & getGNECrossings() const
Returns GNECrossings.
void updateGeometry(bool updateGrid)
update pre-computed geometry information
Definition: GNECrossing.cpp:53
void setRadius(double radius)
set the turning radius
Definition: NBNode.h:496
std::string getAttribute(SumoXMLAttr key) const
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition: NBNode.h:303
void invalidateIncomingConnections()
invalidate incoming connections
Definition: NBNode.cpp:1518
void mouseOverObject(const GUIVisualizationSettings &s) const
method for check if mouse is over objects
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:46
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:49
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:573
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
GNEJunction * retrieveJunction(const std::string &id, bool failHard=true)
get junction by id
Definition: GNENet.cpp:887
A list of positions.
double scaledSize(double scale, double constFactor=0.1) const
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:1160
void buildCrossingsAndWalkingAreas()
build crossings, and walkingareas. Also removes invalid loaded crossings if wished ...
Definition: NBNode.cpp:2268
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
reset junction shape
Definition: GUIAppEnum.h:736
void updateGeometry(bool updateGrid)
Update the boundary of the junction.
Definition: GNEJunction.cpp:91
Boundary myJunctionBoundary
junction boundary
Definition: GNEJunction.h:259
static std::vector< Position > drawFilledCircleReturnVertices(double width, int steps=8)
Draws a filled circle around (0,0) returning circle vertex.
Definition: GLHelper.cpp:350
void commitGeometryMoving(const Position &oldPos, GNEUndoList *undoList)
registers completed movement with the undoList
RGBColor selectionColor
NETEDIT special colors.
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:260
bool showJunctionAsBubbles() const
return true if junction must be showed as bubbles
Definition: GNEViewNet.cpp:781
void setDottedAC(const GNEAttributeCarrier *AC)
set attributeCarrier under cursor
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:732
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:555
void addOutgoingGNEEdge(GNEEdge *edge)
add outgoing GNEEdge
std::vector< GNEEdge * > myGNEEdges
vector with the GNEEdges vinculated with this junction
Definition: GNEJunction.h:262
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:248
const std::string & getProgramID() const
Returns the ProgramID.
void incRef(const std::string &debugMsg="")
Increarse reference.
double getColorValue(const GUIVisualizationSettings &s, bool bubble) const
determines color value
void setGenericParametersStr(const std::string &value)
set generic parameters in string format
NBNode & myNBNode
A reference to the represented junction.
Definition: GNEJunction.h:256
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
EditMode
Definition: GNEViewNet.h:42
void selectAttributeCarrier(bool changeFlag=true)
select attribute carrier using GUIGlobalSelection
void setKeepClear(bool keepClear)
set the keepClear flag
Definition: NBNode.h:501
bool checkIsRemovableReporting(std::string &reason) const
check if node is removable and return reason if not
Definition: NBNode.cpp:1889
static void computeTurnDirectionsForNode(NBNode *node, bool warn)
Computes turnaround destinations for all incoming edges of the given nodes (if any) ...
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
EditMode getCurrentEditMode() const
get the current edit mode
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:1979
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:282
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:50
static const double BUBBLE_RADIUS
constant values for drawing buubles
Definition: GNEJunction.h:56
void reset()
Resets the boundary.
Definition: Boundary.cpp:67
void setID(const std::string &newID)
resets the id
Definition: Named.h:86
reset junction&#39;s connections
Definition: GUIAppEnum.h:728
const std::vector< GNELane * > & getLanes()
returns a reference to the lane vector
Definition: GNEEdge.cpp:873
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:617
~GNEJunction()
Destructor.
Definition: GNEJunction.cpp:71
double getRadius() const
Returns the turning radius of this node.
Definition: NBNode.h:272
bool haveNetworkCrossings()
notify about style of loaded network (Without Crossings)
Definition: NBNetBuilder.h:191
const EdgeVector & getIncomingEdges() const
Returns this node&#39;s incoming edges (The edges which yield in this node)
Definition: NBNode.h:250
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:867
double getHeight() const
Returns the height of the boundary (y-axis)
Definition: Boundary.cpp:161
static void drawShapeDottedContour(const int type, const PositionVector &shape, const double width)
draw a dotted contour around the given Non closed shape with certain width
Definition: GLHelper.cpp:471
const GNEAttributeCarrier * getDottedAC() const
get AttributeCarrier under cursor
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:308
void setColor(const GUIVisualizationSettings &s, bool bubble) const
sets junction color depending on circumstances
bool editingElevation() const
return true if elevation is being edited
Definition: GNEViewNet.cpp:739
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:34
std::vector< GNECrossing * > myGNECrossings
the built crossing objects
Definition: GNEJunction.h:290
std::vector< Position > getEndPoints() const
return list of unique endpoint coordinates of all edges at this node
Definition: NBNode.cpp:3207
const std::string & getTagStr() const
get tag assigned to this object in string format
void scaleRelative(double factor)
enlarges/shrinks the polygon by a factor based at the centroid
void updateShapesAndGeometries(bool updateGrid)
update shapes of all elements associated to the junction
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
The popup menu of a globject.
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:267
static int getCircleResolution(const GUIVisualizationSettings &settings)
function to calculate circle resolution for all circles drawn in drawGL(...) functions ...
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:268
void replaceIncomingConnections(GNEEdge *which, GNEEdge *by, GNEUndoList *undoList)
replace one edge by another in all tls connections
const Position & getPosition() const
Definition: NBNode.h:242
EdgeVector edges
The edges being crossed.
Definition: NBNode.h:131
int getFromLane() const
returns the from-lane
Represents a single node (junction) during network building.
Definition: NBNode.h:68
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
GUIGlID getGlID() const
Returns the numerical id of the object.
A definition of a pedestrian crossing.
Definition: NBNode.h:125
GNEJunction(NBNode &nbn, GNENet *net, bool loaded=false)
Constructor.
Definition: GNEJunction.cpp:58
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
Position getPositionInformation() const
Returns the cursor&#39;s x/y position within the network.
link: the index of the link within the traffic light
const std::vector< Crossing * > & getCrossingsIncludingInvalid() const
Definition: NBNode.h:653
bool drawJunctionShape
whether the shape of the junction should be drawn
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
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.
mode for connecting lanes
Definition: GNEViewNet.h:56
mode for creating new edges
Definition: GNEViewNet.h:46
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:132
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
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.cpp:613
std::vector< GNEJunction * > getJunctionNeighbours() const
return GNEJunction neighbours
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:79
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
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:1153
void setLogicValid(bool valid, GNEUndoList *undoList, const std::string &status=FEATURE_GUESSED)
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition: GNENet.cpp:1750
static bool isTrafficLight(SumoXMLNodeType type)
return whether the given type is a traffic light
Definition: NBNode.cpp:3102
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:237
void requireRecompute()
inform the net about the need for recomputation
Definition: GNENet.cpp:1369
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
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:726
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:1730
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