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 
25 #include <string>
26 #include <utility>
29 #include <utils/geom/Position.h>
34 #include <utils/gui/div/GLHelper.h>
39 #include <netbuild/NBOwnTLDef.h>
41 #include <netbuild/NBAlgorithms.h>
46 #include <netedit/GNEViewParent.h>
47 #include <netedit/GNENet.h>
48 #include <netedit/GNEUndoList.h>
49 #include <netedit/GNEViewNet.h>
50 
51 #include "GNEEdge.h"
52 #include "GNEConnection.h"
53 #include "GNEJunction.h"
54 #include "GNECrossing.h"
55 
56 
57 // ===========================================================================
58 // static members
59 // ===========================================================================
60 
61 const double GNEJunction::BUBBLE_RADIUS(4);
62 
63 // ===========================================================================
64 // method definitions
65 // ===========================================================================
66 
67 GNEJunction::GNEJunction(NBNode& nbn, GNENet* net, bool loaded) :
68  GNENetElement(net, nbn.getID(), GLO_JUNCTION, SUMO_TAG_JUNCTION),
69  myNBNode(nbn),
70  myAmCreateEdgeSource(false),
71  myLogicStatus(loaded ? FEATURE_LOADED : FEATURE_GUESSED),
72  myAmResponsible(false),
73  myHasValidLogic(loaded),
74  myAmTLSSelected(false) {
75  // give a temporal value for boundary
77 }
78 
79 
81  // delete all GNECrossing
82  for (auto it : myGNECrossings) {
83  it->decRef();
84  if (it->unreferenced()) {
85  // show extra information for tests
86  WRITE_DEBUG("Deleting unreferenced " + toString(it->getTag()) + " '" + it->getID() + "' in GNEJunction destructor");
87  delete it;
88  }
89  }
90 
91  if (myAmResponsible) {
92  // show extra information for tests
93  WRITE_DEBUG("Deleting NBNode of '" + getID() + "' in GNEJunction destructor");
94  delete &myNBNode;
95  }
96 }
97 
98 
99 void
100 GNEJunction::updateGeometry(bool updateGrid) {
101  // first check if object has to be removed from grid (SUMOTree)
102  if (updateGrid) {
104  }
105  // calculate boundary using EXTENT as size
106  const double EXTENT = 2;
107  myJunctionBoundary = Boundary(myNBNode.getPosition().x() - EXTENT, myNBNode.getPosition().y() - EXTENT,
108  myNBNode.getPosition().x() + EXTENT, myNBNode.getPosition().y() + EXTENT);
109  // if junctio own a extra shape, add it to boundary
110  if (myNBNode.getShape().size() > 0) {
112  }
114  // last step is to check if object has to be added into grid (SUMOTree) again
115  if (updateGrid) {
116  myNet->addGLObjectIntoGrid(this);
117  }
118  // rebuild GNECrossings
119  rebuildGNECrossings(true);
120 }
121 
122 
123 void
124 GNEJunction::rebuildGNECrossings(bool rebuildNBNodeCrossings) {
125  // rebuild GNECrossings only if create crossings and walkingAreas in net is enabled
127  if (rebuildNBNodeCrossings) {
128  // build new NBNode::Crossings and walking areas
130  }
131  // extract ALL crossing of Tree (Due after rebuild some IDs can referenciate another GNECrossing)
132  for (auto i : myGNECrossings) {
134  }
135 
136  // create a vector to keep retrieved and created crossings
137  std::vector<GNECrossing*> retrievedCrossings;
138  // iterate over NBNode::Crossings of GNEJunction
139  for (auto NBc : myNBNode.getCrossingsIncludingInvalid()) {
140  // retrieve existent GNECrossing, or create it
141  GNECrossing* retrievedGNECrossing = retrieveGNECrossing(NBc);
142  retrievedCrossings.push_back(retrievedGNECrossing);
143  // check if previously this GNECrossings exists, and if true, remove it from myGNECrossings and insert in tree again
144  std::vector<GNECrossing*>::iterator retrievedExists = std::find(myGNECrossings.begin(), myGNECrossings.end(), retrievedGNECrossing);
145  if (retrievedExists != myGNECrossings.end()) {
146  myGNECrossings.erase(retrievedExists);
147  // insert retrieved crossing in tree again
148  myNet->addGLObjectIntoGrid(retrievedGNECrossing);
149  // update geometry of retrieved crossing
150  retrievedGNECrossing->updateGeometry(true);
151  } else {
152  // include reference to created GNECrossing
153  retrievedGNECrossing->incRef();
154  }
155  // check if crossing is selected
156  if (retrievedGNECrossing->isAttributeCarrierSelected()) {
157  retrievedGNECrossing->selectAttributeCarrier();
158  }
159  }
160  // delete non retrieved GNECrossings (we don't need to extract if from Tree two times)
161  for (auto it : myGNECrossings) {
162  it->decRef();
163  // check if crossing is selected
164  if (it->isAttributeCarrierSelected()) {
165  it->unselectAttributeCarrier();
166  }
167  if (it->unreferenced()) {
168  // show extra information for tests
169  WRITE_DEBUG("Deleting unreferenced " + toString(it->getTag()) + " in rebuildGNECrossings()");
170  delete it;
171  }
172  }
173  // copy retrieved (existent and created) GNECrossigns to myGNECrossings
174  myGNECrossings = retrievedCrossings;
175  }
176 }
177 
178 
181  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
182  buildPopupHeader(ret, app);
185  // build selection and show parameters menu
188  buildPositionCopyEntry(ret, false);
189  //if (parent.getVisualisationSettings()->editMode != GNE_MODE_CONNECT) {
190  // // XXX if joinable
191  // new FXMenuCommand(ret, "Join adjacent edges", 0, &parent, MID_GNE_JOIN_EDGES);
192  //}
193  const int numEndpoints = (int)myNBNode.getEndPoints().size();
194  // create menu commands
195  FXMenuCommand* mcCustomShape = new FXMenuCommand(ret, "Set custom junction shape", 0, &parent, MID_GNE_JUNCTION_EDIT_SHAPE);
196  FXMenuCommand* mcReplace = new FXMenuCommand(ret, "Replace junction by geometry point", 0, &parent, MID_GNE_JUNCTION_REPLACE);
197  FXMenuCommand* mcSplit = new FXMenuCommand(ret, ("Split junction (" + toString(numEndpoints) + " end points)").c_str(), 0, &parent, MID_GNE_JUNCTION_SPLIT);
198  FXMenuCommand* mcClearConnections = new FXMenuCommand(ret, "Clear connections", 0, &parent, MID_GNE_JUNCTION_CLEAR_CONNECTIONS);
199  FXMenuCommand* mcResetConnections = new FXMenuCommand(ret, "Reset connections", 0, &parent, MID_GNE_JUNCTION_RESET_CONNECTIONS);
200  // check if menu commands has to be disabled
201  EditMode editMode = myNet->getViewNet()->getCurrentEditMode();
202  const bool wrongMode = (editMode == GNE_MODE_CONNECT || editMode == GNE_MODE_TLS || editMode == GNE_MODE_CREATE_EDGE);
203  if (wrongMode) {
204  mcCustomShape->disable();
205  mcClearConnections->disable();
206  mcResetConnections->disable();
207  }
208  // disable mcClearConnections if juction hasn't connections
209  if (getGNEConnections().empty()) {
210  mcClearConnections->disable();
211  }
212  // checkIsRemovable requiers turnarounds to be computed. This is ugly
213  if (myNBNode.getIncomingEdges().size() == 2 && myNBNode.getOutgoingEdges().size() == 2) {
215  }
216  std::string reason = "wrong edit mode";
217  if (wrongMode || !myNBNode.checkIsRemovableReporting(reason)) {
218  mcReplace->setText(mcReplace->getText() + " (" + reason.c_str() + ")");
219  mcReplace->disable();
220  }
221  if (numEndpoints == 1) {
222  mcSplit->disable();
223  }
224  return ret;
225 }
226 
227 
228 Boundary
230  // Return Boundary depending if myMovingGeometryBoundary is initialised (important for move geometry)
233  } else {
235  b.grow(20);
236  return b;
237  }
238 }
239 
240 
241 void
243  /*
244  // first call function mouseOverObject (to check if this object is under cursor)
245  // @note currently disabled. It will be implemented in an different ticket of #2905
246  mouseOverObject(s);
247  */
248  // declare variables
249  GLfloat color[4];
250  double exaggeration = isAttributeCarrierSelected() ? s.selectionScale : 1;
251  exaggeration *= s.junctionSize.getExaggeration(s);
252  // declare values for circles
253  double circleWidth = BUBBLE_RADIUS * exaggeration;
254  double circleWidthSquared = circleWidth * circleWidth;
255  int circleResolution = GNEAttributeCarrier::getCircleResolution(s);
256  // push name
257  glPushName(getGlID());
258  if (s.scale * exaggeration * myMaxSize < 1.) {
259  // draw something simple so that selection still works
261  } else {
262  // node shape has been computed and is valid for drawing
263  const bool drawShape = myNBNode.getShape().size() > 0 && s.drawJunctionShape;
264  const bool drawBubble = (((!drawShape || myNBNode.getShape().area() < 4)
265  && s.drawJunctionShape)
267 
268  if (drawShape) {
269  setColor(s, false);
270  // recognize full transparency and simply don't draw
271  glGetFloatv(GL_CURRENT_COLOR, color);
272  if (color[3] != 0) {
273  glPushMatrix();
274  glTranslated(0, 0, getType());
275  PositionVector shape = myNBNode.getShape();
276  shape.closePolygon();
277  if (exaggeration > 1) {
278  shape.scaleRelative(exaggeration);
279  }
280  if ((s.drawForSelecting) || (s.scale * exaggeration * myMaxSize < 40.)) {
281  GLHelper::drawFilledPoly(shape, true);
282  } else {
284  }
285  // check if dotted contour has to be drawn
286  if (!s.drawForSelecting && (myNet->getViewNet()->getACUnderCursor() == this) && !drawBubble) {
288  }
289  glPopMatrix();
290  }
291  }
292  if (drawBubble) {
293  setColor(s, true);
294  // recognize full transparency and simply don't draw
295  glGetFloatv(GL_CURRENT_COLOR, color);
296  if (color[3] != 0) {
297  glPushMatrix();
298  glTranslated(myNBNode.getPosition().x(), myNBNode.getPosition().y(), getType() + 0.05);
299  if (!s.drawForSelecting || (myNet->getViewNet()->getPositionInformation().distanceSquaredTo(myNBNode.getPosition()) <= (circleWidthSquared + 2))) {
300  std::vector<Position> vertices = GLHelper::drawFilledCircleReturnVertices(circleWidth, circleResolution);
301  // check if dotted contour has to be drawn
302  if (!s.drawForSelecting && myNet->getViewNet()->getACUnderCursor() == this) {
304  }
305  } else {
306  GLHelper::drawBoxLine(Position(0, 1), 0, 2, 1);
307  }
308  glPopMatrix();
309  }
310  }
311  // draw TLS icon if isn't being drawn for selecting
313  glPushMatrix();
314  Position pos = myNBNode.getPosition();
315  glTranslated(pos.x(), pos.y(), getType() + 0.1);
316  glColor3d(1, 1, 1);
317  const double halfWidth = 32 / s.scale;
318  const double halfHeight = 64 / s.scale;
319  GUITexturesHelper::drawTexturedBox(GUITextureSubSys::getTexture(GNETEXTURE_TLS), -halfWidth, -halfHeight, halfWidth, halfHeight);
320  glPopMatrix();
321  }
322  // draw crossings
323  for (auto it : myGNECrossings) {
324  it->drawGL(s);
325  }
326  // (optional) draw name @todo expose this setting if isn't drawed if isn't being drawn for selecting
327  if (!s.drawForSelecting) {
329  }
330  }
331  glPopName();
332 }
333 
334 Boundary
336  return myJunctionBoundary;
337 }
338 
339 
340 NBNode*
342  return &myNBNode;
343 }
344 
345 
346 Position
348  return myNBNode.getPosition();
349 }
350 
351 
352 std::vector<GNEJunction*>
354  // use set to avoid duplicates junctions
355  std::set<GNEJunction*> junctions;
356  for (auto i : myGNEIncomingEdges) {
357  junctions.insert(i->getGNEJunctionSource());
358  }
359  for (auto i : myGNEOutgoingEdges) {
360  junctions.insert(i->getGNEJunctionDestiny());
361  }
362  return std::vector<GNEJunction*>(junctions.begin(), junctions.end());
363 }
364 
365 
366 void
368  // Check if incoming edge was already inserted
369  std::vector<GNEEdge*>::iterator i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
370  if (i != myGNEIncomingEdges.end()) {
371  throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + toString(getTag()) + " with ID " + getID() + "'");
372  } else {
373  // Add edge into containers
374  myGNEIncomingEdges.push_back(edge);
375  myGNEEdges.push_back(edge);
376  }
377 }
378 
379 
380 
381 void
383  // Check if outgoing edge was already inserted
384  std::vector<GNEEdge*>::iterator i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
385  if (i != myGNEOutgoingEdges.end()) {
386  throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + toString(getTag()) + " with ID " + getID() + "'");
387  } else {
388  // Add edge into containers
389  myGNEOutgoingEdges.push_back(edge);
390  myGNEEdges.push_back(edge);
391  }
392 }
393 
394 
395 void
397  // Check if incoming edge was already inserted
398  std::vector<GNEEdge*>::iterator i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
399  if (i == myGNEIncomingEdges.end()) {
400  throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + toString(getTag()) + " with ID " + getID() + "'");
401  } else {
402  // remove edge from containers
403  myGNEIncomingEdges.erase(i);
404  myGNEEdges.erase(std::find(myGNEEdges.begin(), myGNEEdges.end(), edge));
405  }
406 }
407 
408 
409 void
411  // Check if outgoing edge was already inserted
412  std::vector<GNEEdge*>::iterator i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
413  if (i == myGNEOutgoingEdges.end()) {
414  throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + toString(getTag()) + " with ID " + getID() + "'");
415  } else {
416  // remove edge from containers
417  myGNEOutgoingEdges.erase(i);
418  myGNEEdges.erase(std::find(myGNEEdges.begin(), myGNEEdges.end(), edge));
419  }
420 }
421 
422 
423 const std::vector<GNEEdge*>&
425  return myGNEEdges;
426 }
427 
428 
429 const std::vector<GNEEdge*>&
431  return myGNEIncomingEdges;
432 }
433 
434 
435 const std::vector<GNEEdge*>&
437  return myGNEOutgoingEdges;
438 }
439 
440 
441 const std::vector<GNECrossing*>&
443  return myGNECrossings;
444 }
445 
446 
447 std::vector<GNEConnection*>
449  std::vector<GNEConnection*> connections;
450  for (auto i : myGNEIncomingEdges) {
451  for (auto j : i->getGNEConnections()) {
452  connections.push_back(j);
453  }
454  }
455  return connections;
456 }
457 
458 
459 void
461  myAmCreateEdgeSource = true;
462 }
463 
464 
465 void
467  myAmCreateEdgeSource = false;
468 }
469 
470 
471 void
472 GNEJunction::selectTLS(bool selected) {
473  myAmTLSSelected = selected;
474 }
475 
476 
477 void
478 GNEJunction::startGeometryMoving(bool extendToNeighbors) {
479  // save current centering boundary
481  // First declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
482  std::set<GNEJunction*> affectedJunctions;
483  std::set<GNEEdge*> affectedEdges;
484  // Iterate over GNEEdges
485  for (auto i : myGNEEdges) {
486  // Add source and destiny junctions
487  affectedJunctions.insert(i->getGNEJunctionSource());
488  affectedJunctions.insert(i->getGNEJunctionDestiny());
489  // Obtain neighbors of Junction source
490  for (auto j : i->getGNEJunctionSource()->getGNEEdges()) {
491  affectedEdges.insert(j);
492  }
493  // Obtain neighbors of Junction destiny
494  for (auto j : i->getGNEJunctionDestiny()->getGNEEdges()) {
495  affectedEdges.insert(j);
496  }
497  }
498  // Iterate over affected Junctions only if extendToNeighbors is enabled
499  if (extendToNeighbors) {
500  for (auto i : affectedJunctions) {
501  // don't include this junction (to avoid start more than one times)
502  if (i != this) {
503  // start geometry moving in edges
504  i->startGeometryMoving(false);
505  }
506  }
507  }
508  // Iterate over affected Edges
509  for (auto i : affectedEdges) {
510  // start geometry moving in edges
511  i->startGeometryMoving();
512  }
513 }
514 
515 
516 void
517 GNEJunction::endGeometryMoving(bool extendToNeighbors) {
518  // Remove object from net
520  // reset myMovingGeometryBoundary
522  // update geometry without updating grid
523  updateGeometry(false);
524  // First declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
525  std::set<GNEJunction*> affectedJunctions;
526  std::set<GNEEdge*> affectedEdges;
527  // Iterate over GNEEdges
528  for (auto i : myGNEEdges) {
529  // Add source and destiny junctions
530  affectedJunctions.insert(i->getGNEJunctionSource());
531  affectedJunctions.insert(i->getGNEJunctionDestiny());
532  // Obtain neighbors of Junction source
533  for (auto j : i->getGNEJunctionSource()->getGNEEdges()) {
534  affectedEdges.insert(j);
535  }
536  // Obtain neighbors of Junction destiny
537  for (auto j : i->getGNEJunctionDestiny()->getGNEEdges()) {
538  affectedEdges.insert(j);
539  }
540  }
541  // Iterate over affected Junctions
542  if (extendToNeighbors) {
543  for (auto i : affectedJunctions) {
544  // don't include this junction (to avoid end it more than one times)
545  if (i != this) {
546  // end geometry moving in edges
547  i->endGeometryMoving(false);
548  }
549  }
550  }
551  // Iterate over affected Edges
552  for (auto i : affectedEdges) {
553  // end geometry moving in edges
554  i->endGeometryMoving();
555  }
556  // add object into grid again (using the new centering boundary)
557  myNet->addGLObjectIntoGrid(this);
558 }
559 
560 
561 void
562 GNEJunction::moveGeometry(const Position& oldPos, const Position& offset) {
563  // Abort moving if there is another junction in the exactly target position
564  bool abort = false;
565  std::vector<GNEJunction*> junctionNeighbours = getJunctionNeighbours();
566  for (auto i : junctionNeighbours) {
567  if (i->getPositionInView() == myNBNode.getPosition()) {
568  abort = true;
569  }
570  }
571  if (!abort) {
572  Position newPosition = oldPos;
573  newPosition.add(offset);
574  moveJunctionGeometry(newPosition, false);
575  }
576 }
577 
578 
579 void
582  undoList->p_begin("position of " + toString(getTag()));
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 != 0) {
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 != 0) {
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 != 0) {
806  NBTrafficLightDefinition* replacementDef = 0;
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 " + toString(createdGNECrossing->getTag()) + " '" + createdGNECrossing->getID() + "' in retrieveGNECrossing()");
893  // insert it in Tree
894  myNet->addGLObjectIntoGrid(createdGNECrossing);
895  // update geometry after creating
896  createdGNECrossing->updateGeometry(true);
897  return createdGNECrossing;
898  } else {
899  return nullptr;
900  }
901 }
902 
903 
904 void
905 GNEJunction::markConnectionsDeprecated(bool includingNeighbours) {
906  // only it's needed to mark the connections of incoming edges
907  for (auto i : myGNEIncomingEdges) {
908  for (auto j : i->getGNEConnections()) {
909  j->markConnectionGeometryDeprecated();
910  }
911  if (includingNeighbours) {
912  i->getGNEJunctionSource()->markConnectionsDeprecated(false);
913  }
914  }
915 }
916 
917 
918 std::string
920  switch (key) {
921  case SUMO_ATTR_ID:
922  return getMicrosimID();
923  case SUMO_ATTR_POSITION:
924  return toString(myNBNode.getPosition());
925  case SUMO_ATTR_TYPE:
926  return toString(myNBNode.getType());
928  return myLogicStatus;
929  case SUMO_ATTR_SHAPE:
930  return toString(myNBNode.getShape());
931  case SUMO_ATTR_RADIUS:
932  return toString(myNBNode.getRadius());
933  case SUMO_ATTR_TLTYPE:
934  // @todo this causes problems if the node were to have multiple programs of different type (plausible)
935  return myNBNode.isTLControlled() ? toString((*myNBNode.getControllingTLS().begin())->getType()) : "";
936  case SUMO_ATTR_TLID:
937  return myNBNode.isTLControlled() ? toString((*myNBNode.getControllingTLS().begin())->getID()) : "";
939  // keep clear is only used as a convenience feature in plain xml
940  // input. When saving to .net.xml the status is saved only for the connections
941  // to show the correct state we must check all connections
942  if (!myNBNode.getKeepClear()) {
943  return toString(false);
944  } else {
945  for (auto i : myGNEIncomingEdges) {
946  for (auto j : i->getGNEConnections()) {
947  if (j->getNBEdgeConnection().keepClear) {
948  return toString(true);
949  }
950  }
951  }
952  return toString(false);
953  }
954  case GNE_ATTR_SELECTED:
956  case GNE_ATTR_GENERIC:
957  return getGenericParametersStr();
958  default:
959  throw InvalidArgument(toString(getTag()) + " 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:
976  case GNE_ATTR_SELECTED:
977  case GNE_ATTR_GENERIC:
978  undoList->add(new GNEChange_Attribute(this, key, value), true);
979  break;
981  // change Keep Clear attribute in all connections
982  undoList->p_begin("change keepClear for whole junction");
983  for (auto i : myGNEIncomingEdges) {
984  for (auto j : i->getGNEConnections()) {
985  undoList->add(new GNEChange_Attribute(j, key, value), true);
986  }
987  }
988  undoList->add(new GNEChange_Attribute(this, key, value), true);
989  undoList->p_end();
990  break;
991  case SUMO_ATTR_TYPE: {
992  undoList->p_begin("change " + toString(getTag()) + " type");
994  if (getNBNode()->isTLControlled() &&
995  // if switching changing from or to traffic_light_right_on_red we need to remove the old plan
998  ) {
999  // make a copy because we will modify the original
1000  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1001  for (auto it : copyOfTls) {
1002  undoList->add(new GNEChange_TLS(this, it, false), true);
1003  }
1004  }
1005  if (!getNBNode()->isTLControlled()) {
1006  // create new traffic light
1007  undoList->add(new GNEChange_TLS(this, 0, true), true);
1008  }
1009  } else if (getNBNode()->isTLControlled()) {
1010  // delete old traffic light
1011  // make a copy because we will modify the original
1012  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1013  for (auto it : copyOfTls) {
1014  undoList->add(new GNEChange_TLS(this, it, false, false), true);
1015  }
1016  }
1017  // must be the final step, otherwise we do not know which traffic lights to remove via GNEChange_TLS
1018  undoList->add(new GNEChange_Attribute(this, key, value), true);
1019  undoList->p_end();
1020  break;
1021  }
1022  case SUMO_ATTR_TLID: {
1023  undoList->p_begin("change " + toString(SUMO_TAG_TRAFFIC_LIGHT) + " id");
1024  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1025  assert(copyOfTls.size() > 0);
1026  NBTrafficLightDefinition* currentTLS = *copyOfTls.begin();
1027  NBTrafficLightDefinition* currentTLSCopy = 0;
1028  const bool currentIsSingle = currentTLS->getNodes().size() == 1;
1029  const bool currentIsLoaded = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS) != 0;
1030  if (currentIsLoaded) {
1031  currentTLSCopy = new NBLoadedSUMOTLDef(currentTLS,
1032  dynamic_cast<NBLoadedSUMOTLDef*>(currentTLS)->getLogic());
1033  }
1034  // remove from previous tls
1035  for (auto it : copyOfTls) {
1036  undoList->add(new GNEChange_TLS(this, it, false), true);
1037  }
1039  // programs to which the current node shall be added
1040  const std::map<std::string, NBTrafficLightDefinition*> programs = tlCont.getPrograms(value);
1041  if (programs.size() > 0) {
1042  for (auto it : programs) {
1043  NBTrafficLightDefinition* oldTLS = it.second;
1044  if (dynamic_cast<NBOwnTLDef*>(oldTLS) != 0) {
1045  undoList->add(new GNEChange_TLS(this, oldTLS, true), true);
1046  } else {
1047  // delete and re-create the definition because the loaded phases are now invalid
1048  if (dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS) != 0 &&
1049  dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->usingSignalGroups()) {
1050  // keep the old program and add all-red state for the added links
1051  NBLoadedSUMOTLDef* newTLSJoined = new NBLoadedSUMOTLDef(oldTLS, dynamic_cast<NBLoadedSUMOTLDef*>(oldTLS)->getLogic());
1052  newTLSJoined->joinLogic(currentTLSCopy);
1053  undoList->add(new GNEChange_TLS(this, newTLSJoined, true, true), true);
1054  } else {
1055  undoList->add(new GNEChange_TLS(this, 0, true, false, value), true);
1056  }
1058  // switch from old to new definition
1059  const std::vector<NBNode*> copyOfNodes = oldTLS->getNodes();
1060  for (auto it_node : copyOfNodes) {
1061  GNEJunction* oldJunction = myNet->retrieveJunction(it_node->getID());
1062  undoList->add(new GNEChange_TLS(oldJunction, oldTLS, false), true);
1063  undoList->add(new GNEChange_TLS(oldJunction, newTLS, true), true);
1064  }
1065  }
1066  }
1067  } else {
1068  if (currentIsSingle && currentIsLoaded) {
1069  // rename the traffic light but keep everything else
1070  NBTrafficLightLogic* renamedLogic = dynamic_cast<NBLoadedSUMOTLDef*>(currentTLSCopy)->getLogic();
1071  renamedLogic->setID(value);
1072  NBLoadedSUMOTLDef* renamedTLS = new NBLoadedSUMOTLDef(currentTLSCopy, renamedLogic);
1073  renamedTLS->setID(value);
1074  undoList->add(new GNEChange_TLS(this, renamedTLS, true, true), true);
1075  } else {
1076  // create new traffic light
1077  undoList->add(new GNEChange_TLS(this, 0, true, false, value), true);
1078  }
1079  }
1080  delete currentTLSCopy;
1081  undoList->p_end();
1082  break;
1083  }
1084  default:
1085  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
1086  }
1087 }
1088 
1089 
1090 bool
1091 GNEJunction::isValid(SumoXMLAttr key, const std::string& value) {
1092  switch (key) {
1093  case SUMO_ATTR_ID:
1094  return SUMOXMLDefinitions::isValidNetID(value) && (myNet->retrieveJunction(value, false) == 0);
1095  case SUMO_ATTR_TYPE:
1097  case SUMO_ATTR_POSITION: {
1098  bool ok;
1099  return GeomConvHelper::parseShapeReporting(value, "user-supplied position", 0, ok, false).size() == 1;
1100  }
1101  case SUMO_ATTR_SHAPE: {
1102  bool ok = true;
1103  PositionVector shape = GeomConvHelper::parseShapeReporting(value, "user-supplied position", 0, ok, true);
1104  return ok;
1105  }
1106  case SUMO_ATTR_RADIUS:
1107  return canParse<double>(value);
1108  case SUMO_ATTR_TLTYPE:
1110  case SUMO_ATTR_TLID:
1111  return myNBNode.isTLControlled() && (value != "");
1112  case SUMO_ATTR_KEEP_CLEAR:
1113  return canParse<bool>(value);
1114  case GNE_ATTR_SELECTED:
1115  return canParse<bool>(value);
1116  case GNE_ATTR_GENERIC:
1117  return isGenericParametersValid(value);
1118  default:
1119  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
1120  }
1121 }
1122 
1123 
1124 bool
1125 GNEJunction::addGenericParameter(const std::string& key, const std::string& value) {
1126  if (!myNBNode.knowsParameter(key)) {
1127  myNBNode.setParameter(key, value);
1128  return true;
1129  } else {
1130  return false;
1131  }
1132 }
1133 
1134 
1135 bool
1136 GNEJunction::removeGenericParameter(const std::string& key) {
1137  if (myNBNode.knowsParameter(key)) {
1138  myNBNode.unsetParameter(key);
1139  return true;
1140  } else {
1141  return false;
1142  }
1143 }
1144 
1145 
1146 bool
1147 GNEJunction::updateGenericParameter(const std::string& oldKey, const std::string& newKey) {
1148  if (myNBNode.knowsParameter(oldKey) && !myNBNode.knowsParameter(newKey)) {
1149  std::string value = myNBNode.getParameter(oldKey);
1150  myNBNode.unsetParameter(oldKey);
1151  myNBNode.setParameter(newKey, value);
1152  return true;
1153  } else {
1154  return false;
1155  }
1156 }
1157 
1158 
1159 bool
1160 GNEJunction::updateGenericParameterValue(const std::string& key, const std::string& newValue) {
1161  if (myNBNode.knowsParameter(key)) {
1162  myNBNode.setParameter(key, newValue);
1163  return true;
1164  } else {
1165  return false;
1166  }
1167 }
1168 
1169 
1170 std::string
1172  std::string result;
1173  // Generate an string using the following structure: "key1=value1|key2=value2|...
1174  for (auto i : myNBNode.getParametersMap()) {
1175  result += i.first + "=" + i.second + "|";
1176  }
1177  // remove the last "|"
1178  if (!result.empty()) {
1179  result.pop_back();
1180  }
1181  return result;
1182 }
1183 
1184 
1185 std::vector<std::pair<std::string, std::string> >
1187  std::vector<std::pair<std::string, std::string> > result;
1188  // iterate over parameters map and fill result
1189  for (auto i : myNBNode.getParametersMap()) {
1190  result.push_back(std::make_pair(i.first, i.second));
1191  }
1192  return result;
1193 }
1194 
1195 
1196 void
1197 GNEJunction::setGenericParametersStr(const std::string& value) {
1198  // clear parameters
1200  // separate value in a vector of string using | as separator
1201  std::vector<std::string> parsedValues;
1202  StringTokenizer stValues(value, "|", true);
1203  while (stValues.hasNext()) {
1204  parsedValues.push_back(stValues.next());
1205  }
1206  // check that parsed values (A=B)can be parsed in generic parameters
1207  for (auto i : parsedValues) {
1208  std::vector<std::string> parsedParameters;
1209  StringTokenizer stParam(i, "=", true);
1210  while (stParam.hasNext()) {
1211  parsedParameters.push_back(stParam.next());
1212  }
1213  // Check that parsed parameters are exactly two and contains valid chracters
1214  if (parsedParameters.size() == 2 && SUMOXMLDefinitions::isValidGenericParameterKey(parsedParameters.front()) && SUMOXMLDefinitions::isValidGenericParameterValue(parsedParameters.back())) {
1215  myNBNode.setParameter(parsedParameters.front(), parsedParameters.back());
1216  }
1217  }
1218 }
1219 
1220 
1221 void
1223  myAmResponsible = newVal;
1224 }
1225 
1226 // ===========================================================================
1227 // private
1228 // ===========================================================================
1229 
1230 void
1231 GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value) {
1232  switch (key) {
1233  case SUMO_ATTR_ID: {
1234  myNet->renameJunction(this, value);
1235  break;
1236  }
1237  case SUMO_ATTR_TYPE: {
1239  break;
1240  }
1241  case SUMO_ATTR_POSITION: {
1242  // set new position in NBNode (note: Junctions don't need to refresh it in the RTREE due the variable myJunctionBoundary
1243  bool ok;
1244  moveJunctionGeometry(GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, false)[0], true);
1245  // mark this connections and all of the junction's Neighbours as deprecated
1247  break;
1248  }
1250  if (myLogicStatus == FEATURE_GUESSED && value != FEATURE_GUESSED) {
1251  // clear guessed connections. previous connections will be restored
1253  // Clear GNEConnections of incoming edges
1254  for (auto i : myGNEIncomingEdges) {
1255  i->clearGNEConnections();
1256  }
1257  }
1258  myLogicStatus = value;
1259  break;
1260  case SUMO_ATTR_SHAPE: {
1261  bool ok;
1262  const PositionVector shape = GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, true);
1263  myNBNode.setCustomShape(shape);
1264  // mark this connections and all of the junction's Neighbours as deprecated
1266  break;
1267  }
1268  case SUMO_ATTR_RADIUS: {
1269  myNBNode.setRadius(parse<double>(value));
1270  break;
1271  }
1272  case SUMO_ATTR_TLTYPE: {
1273  const std::set<NBTrafficLightDefinition*> copyOfTls = myNBNode.getControllingTLS();
1274  for (auto it : copyOfTls) {
1275  it->setType(SUMOXMLDefinitions::TrafficLightTypes.get(value));
1276  }
1277  break;
1278  }
1279  case SUMO_ATTR_KEEP_CLEAR: {
1280  myNBNode.setKeepClear(parse<bool>(value));
1281  break;
1282  }
1283  case GNE_ATTR_SELECTED:
1284  if (parse<bool>(value)) {
1286  } else {
1288  }
1289  break;
1290  case GNE_ATTR_GENERIC:
1291  setGenericParametersStr(value);
1292  break;
1293  default:
1294  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
1295  }
1296  // After setting attribute always update Geometry
1297  updateGeometry(true);
1298 }
1299 
1300 
1301 void
1303  // only continue if there isn't already a AC under cursor
1304  if (myNet->getViewNet()->getACUnderCursor() == nullptr) {
1305  // obtain current x-y coordinates
1307  // check if junction are drawn as buuble or as polygon
1308  const bool drawShape = myNBNode.getShape().size() > 0 && s.drawJunctionShape;
1309  const bool drawBubble = (((!drawShape || myNBNode.getShape().area() < 4) && s.drawJunctionShape) || myNet->getViewNet()->showJunctionAsBubbles());
1310  // declare values for circles
1311  double exaggeration = isAttributeCarrierSelected() ? s.selectionScale : 1;
1312  exaggeration *= s.junctionSize.getExaggeration(s);
1313  double circleWidth = BUBBLE_RADIUS * exaggeration;
1314  double circleWidthSquared = circleWidth * circleWidth;
1315  if (drawBubble) {
1316  // check if cursor is whithin the circle
1317  if (myNet->getViewNet()->getPositionInformation().distanceSquaredTo(myNBNode.getPosition()) <= circleWidthSquared) {
1318  myNet->getViewNet()->setACUnderCursor(this);
1319  }
1320  } else if (drawShape) {
1321  // check if cursor is within the shape
1322  if (myNBNode.getShape().around(mousePos)) {
1323  myNet->getViewNet()->setACUnderCursor(this);
1324  }
1325  }
1326  }
1327 }
1328 
1329 
1330 double
1332  switch (s.junctionColorer.getActive()) {
1333  case 0:
1334  if (bubble) {
1335  return 1;
1336  } else {
1337  return 0;
1338  }
1339  case 1:
1340  return isAttributeCarrierSelected();
1341  case 2:
1342  switch (myNBNode.getType()) {
1344  return 0;
1346  return 1;
1347  case NODETYPE_PRIORITY:
1348  return 2;
1350  return 3;
1352  return 4;
1353  case NODETYPE_ALLWAY_STOP:
1354  return 5;
1355  case NODETYPE_DISTRICT:
1356  return 6;
1357  case NODETYPE_NOJUNCTION:
1358  return 7;
1359  case NODETYPE_DEAD_END:
1361  return 8;
1362  case NODETYPE_UNKNOWN:
1363  case NODETYPE_INTERNAL:
1364  assert(false);
1365  return 8;
1366  case NODETYPE_RAIL_SIGNAL:
1367  return 9;
1368  case NODETYPE_ZIPPER:
1369  return 10;
1371  return 11;
1373  return 12;
1374  }
1375  case 3:
1376  return myNBNode.getPosition().z();
1377  default:
1378  assert(false);
1379  return 0;
1380  }
1381 }
1382 
1383 
1384 void
1385 GNEJunction::moveJunctionGeometry(const Position& pos, bool updateGrid) {
1386  const Position orig = myNBNode.getPosition();
1387  myNBNode.reinit(pos, myNBNode.getType());
1388  // set new position of adjacent edges
1389  for (auto i : getNBNode()->getEdges()) {
1390  myNet->retrieveEdge(i->getID())->updateJunctionPosition(this, orig, updateGrid);
1391  }
1392  // Update shapes without include connections, because the aren't showed in Move mode
1393  updateShapesAndGeometries(updateGrid);
1394 }
1395 
1396 
1397 void
1398 GNEJunction::setColor(const GUIVisualizationSettings& s, bool bubble) const {
1400  // override with special colors (unless the color scheme is based on selection)
1403  }
1404  if (myAmCreateEdgeSource) {
1405  glColor3d(0, 1, 0);
1406  }
1407 }
1408 
1409 void
1412  tlCont.insert(tlDef, forceInsert); // may return false for tlDef which controls multiple junctions
1413  tlDef->addNode(&myNBNode);
1414 }
1415 
1416 
1417 void
1420  if (tlDef->getNodes().size() == 1) {
1421  tlCont.extract(tlDef);
1422  }
1424 }
1425 
1426 /****************************************************************************/
GUIVisualizationSizeSettings junctionSize
bool getKeepClear() const
Returns the keepClear flag.
Definition: NBNode.h:276
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:293
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...
bool myHasValidLogic
whether this junctions logic is valid
Definition: GNEJunction.h:296
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:283
const GNEAttributeCarrier * getACUnderCursor() const
get AttributeCarrier under cursor
Position getPositionInView() const
Return current position.
std::string myLogicStatus
modification status of the junction logic (all connections across this junction)
Definition: GNEJunction.h:290
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:907
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:66
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 add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:126
PositionVector myPoly
the (outer) shape of the junction
Definition: NBNode.h:796
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:1399
A loaded (complete) traffic light logic.
bool myAmCreateEdgeSource
whether this junction is the first junction for a newly creatededge
Definition: GNEJunction.h:287
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:277
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
Definition: NBNode.cpp:284
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:724
double y() const
Returns the y-position.
Definition: Position.h:61
bool hasCustomShape() const
return whether the shape was set by the user
Definition: NBNode.h:494
The representation of a single edge during network building.
Definition: NBEdge.h:65
TrafficLightType getType() const
get the algorithm type (static etc..)
void unsetParameter(const std::string &key)
Removes a parameter.
double x() const
Returns the x-position.
Definition: Position.h:56
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
link,node: the traffic light id responsible for this link
T MAX2(T a, T b)
Definition: StdDefs.h:68
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:80
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition: NBEdge.cpp:2961
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:78
void addExplicitTurnaround(std::string id)
add edge id to the list of explicit turnarounds
Definition: GNENet.cpp:1775
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:69
bool myAmTLSSelected
whether this junction is selected in tls-mode
Definition: GNEJunction.h:299
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:345
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition: NBNode.cpp:1917
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:720
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:254
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:1763
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:64
void setRadius(double radius)
set the turning radius
Definition: NBNode.h:484
std::string getAttribute(SumoXMLAttr key) const
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition: NBNode.h:297
void invalidateIncomingConnections()
invalidate incoming connections
Definition: NBNode.cpp:1450
void mouseOverObject(const GUIVisualizationSettings &s) const
method for check if mouse is over objects
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.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
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.
bool updateGenericParameter(const std::string &oldKey, const std::string &newKey)
update generic parameter
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:85
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:894
A list of positions.
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:1167
void buildCrossingsAndWalkingAreas()
build crossings, and walkingareas. Also removes invalid loaded crossings if wished ...
Definition: NBNode.cpp:2200
void addConnection(NBEdge *from, NBEdge *to, int fromLane, int toLane, int linkIndex, bool reconstruct=true)
Adds a connection and immediately informs the edges.
double distanceSquaredTo(const Position &p2) const
returns the square of the distance to another position
Definition: Position.h:238
friend class GNEChange_Attribute
declare friend class
T get(const std::string &str) const
void updateGeometry(bool updateGrid)
Update the boundary of the junction.
Boundary myJunctionBoundary
junction boundary
Definition: GNEJunction.h:271
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
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:259
bool showJunctionAsBubbles() const
return true if junction must be showed as bubbles
Definition: GNEViewNet.cpp:355
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:722
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:579
void addOutgoingGNEEdge(GNEEdge *edge)
add outgoing GNEEdge
std::vector< GNEEdge * > myGNEEdges
vector with the GNEEdges vinculated with this junction
Definition: GNEJunction.h:274
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:249
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:268
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:489
bool checkIsRemovableReporting(std::string &reason) const
check if node is removable and return reason if not
Definition: NBNode.cpp:1821
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:1911
int getToLane() const
returns the to-lane
NBEdge * getTo() const
returns the to-edge (end of the connection)
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
bool removeGenericParameter(const std::string &key)
remove generic parameter
void setID(const std::string &newID)
resets the id
Definition: Named.h:77
reset junction&#39;s connections
Definition: GUIAppEnum.h:718
bool updateGenericParameterValue(const std::string &key, const std::string &newValue)
update value generic parameter
const std::vector< GNELane * > & getLanes()
returns a reference to the lane vector
Definition: GNEEdge.cpp:832
double selectionScale
the current selection scaling in NETEDIT (temporary)
void setACUnderCursor(const GNEAttributeCarrier *AC)
set attributeCarrier under cursor
~GNEJunction()
Destructor.
Definition: GNEJunction.cpp:80
double getRadius() const
Returns the turning radius of this node.
Definition: NBNode.h:271
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:249
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:862
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 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:302
void setColor(const GUIVisualizationSettings &s, bool bubble) const
sets junction color depending on circumstances
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:34
std::vector< GNECrossing * > myGNECrossings
the built crossing objects
Definition: GNEJunction.h:302
std::vector< Position > getEndPoints() const
return list of unique endpoint coordinates of all edges at this node
Definition: NBNode.cpp:3115
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:266
const std::string getParameter(const std::string &key, const std::string &defaultValue="") const
Returns the value for a given key.
static int getCircleResolution(const GUIVisualizationSettings &settings)
function to calculate circle resolution for all circles drawn in drawGL(...) functions ...
std::vector< GNEEdge * > myGNEOutgoingEdges
vector with the outgoings GNEEdges vinculated with this junction
Definition: GNEJunction.h:280
void buildSelectionPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to (de)select the object.
void replaceIncomingConnections(GNEEdge *which, GNEEdge *by, GNEUndoList *undoList)
replace one edge by another in all tls connections
bool addGenericParameter(const std::string &key, const std::string &value)
add generic parameter
const Position & getPosition() const
Definition: NBNode.h:241
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.
double getExaggeration(const GUIVisualizationSettings &s, double factor=20) const
return the drawing size including exaggeration and constantSize values
A definition of a pedestrian crossing.
Definition: NBNode.h:125
GNEJunction(NBNode &nbn, GNENet *net, bool loaded=false)
Constructor.
Definition: GNEJunction.cpp:67
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:636
bool drawJunctionShape
whether the shape of the junction should be drawn
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
static const RGBColor selectionColor
Definition: GNENet.h:96
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:586
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
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:1160
void setLogicValid(bool valid, GNEUndoList *undoList, const std::string &status=FEATURE_GUESSED)
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition: GNENet.cpp:1757
static bool isTrafficLight(SumoXMLNodeType type)
return whether the given type is a traffic light
Definition: NBNode.cpp:3010
static PositionVector parseShapeReporting(const std::string &shpdef, const std::string &objecttype, const char *objectid, bool &ok, bool allowEmpty, bool report=true)
Builds a PositionVector from a string representation, reporting occurred errors.
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:230
void requireRecompute()
inform the net about the need for recomputation
Definition: GNENet.cpp:1376
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:716
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:1737
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
SumoXMLTag getTag() const
get XML Tag assigned to this object