SUMO - Simulation of Urban MObility
GNEJunction.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // A class for visualizing and editing junctions in netedit (adapted from
8 // GUIJunctionWrapper)
9 /****************************************************************************/
10 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
11 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
12 /****************************************************************************/
13 //
14 // This file is part of SUMO.
15 // SUMO is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 #include <string>
33 #include <utility>
36 #include <utils/geom/Position.h>
43 #include <utils/gui/div/GLHelper.h>
48 #include <netbuild/NBOwnTLDef.h>
50 #include <netbuild/NBAlgorithms.h>
51 #include "GNENet.h"
52 #include "GNEEdge.h"
53 #include "GNECrossing.h"
54 #include "GNEUndoList.h"
55 #include "GNEViewNet.h"
56 #include "GNEChange_Attribute.h"
57 #include "GNEChange_Connection.h"
58 #include "GNEChange_TLS.h"
59 #include "GNEConnection.h"
60 #include "GNEJunction.h"
61 
62 // ===========================================================================
63 // method definitions
64 // ===========================================================================
65 GNEJunction::GNEJunction(NBNode& nbn, GNENet* net, bool loaded) :
67  myNBNode(nbn),
68  myOrigPos(nbn.getPosition()),
69  myAmCreateEdgeSource(false),
70  myLogicStatus(loaded ? LOADED : GUESSED),
71  myAmResponsible(false),
72  myHasValidLogic(loaded),
73  myAmTLSSelected(false) {
75 }
76 
77 
79  if (myAmResponsible) {
80  delete &myNBNode;
81  }
83 }
84 
85 
86 void
88  //myNet->getNetBuilder()->computeSingleNode(&myNBNode, OptionsCont::getOptions());
89 
90  const double EXTENT = 2;
92  myOrigPos.x() - EXTENT, myOrigPos.y() - EXTENT,
93  myOrigPos.x() + EXTENT, myOrigPos.y() + EXTENT);
94  if (myNBNode.getShape().size() > 0) {
96  }
99 }
100 
101 
102 void
104  // drop existent GNECrossings
106  // rebuild GNECrossings only if create crossings and walkingAreas in net is enabled
107  if (myNet->getNetBuilder()->haveNetworkCrossings() == true) {
108  // build new NBNode::Crossings and walking areas and create GNECrossings
110  const std::vector<NBNode::Crossing>& crossings = myNBNode.getCrossings();
111  for (std::vector<NBNode::Crossing>::const_iterator it = crossings.begin(); it != crossings.end(); it++) {
112  myGNECrossings.push_back(new GNECrossing(this, (*it).id));
113  myGNECrossings.back()->incRef();
114  }
115  }
116 }
117 
118 
121  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
122  buildPopupHeader(ret, app);
126  buildPositionCopyEntry(ret, false);
127  //if (parent.getVisualisationSettings()->editMode != GNE_MODE_CONNECT) {
128  // // XXX if joinable
129  // new FXMenuCommand(ret, "Join adjacent edges", 0, &parent, MID_GNE_JOIN_EDGES);
130  //}
131  FXMenuCommand* mcCustomShape = new FXMenuCommand(ret, "Set custom shape", 0, &parent, MID_GNE_NODE_SHAPE);
132  FXMenuCommand* mcReplace = new FXMenuCommand(ret, "Replace by geometry node", 0, &parent, MID_GNE_NODE_REPLACE);
133  const int editMode = parent.getVisualisationSettings()->editMode;
134  const bool wrongMode = (editMode == GNE_MODE_CONNECT || editMode == GNE_MODE_TLS || editMode == GNE_MODE_CREATE_EDGE);
135  if (wrongMode) {
136  mcCustomShape->handle(&parent, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), 0);
137  }
138  // checkIsRemovable requiers turnarounds to be computed. This is ugly
139  if (myNBNode.getIncomingEdges().size() == 2 && myNBNode.getOutgoingEdges().size() == 2) {
141  }
142  if (wrongMode || !myNBNode.checkIsRemovable()) {
143  mcReplace->handle(&parent, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), 0);
144  }
145  // let the GNEViewNet store the popup position
146  (dynamic_cast<GNEViewNet&>(parent)).markPopupPosition();
147  return ret;
148 }
149 
150 
153  return 0;
154 }
155 
156 
157 Boundary
159  Boundary b = myBoundary;
160  b.grow(20);
161  return b;
162 }
163 
164 
165 void
167  glPushName(getGlID());
168  double exaggeration = gSelected.isSelected(getType(), getGlID()) ? s.selectionScale : 1;
169  exaggeration *= s.junctionSize.getExaggeration(s);
170  if (s.scale * exaggeration * myMaxSize < 1.) {
171  // draw something simple so that selection still works
173  } else {
174  // node shape has been computed and is valid for drawing
175  const bool drawShape = myNBNode.getShape().size() > 0 && s.drawJunctionShape;
176  const bool drawBubble = (!drawShape || myNBNode.getShape().area() < 4) && s.drawJunctionShape; // magic threshold
177 
178  if (drawShape) {
179  setColor(s, false);
180  // recognize full transparency and simply don't draw
181  GLfloat color[4];
182  glGetFloatv(GL_CURRENT_COLOR, color);
183  if (color[3] != 0) {
184  glPushMatrix();
185  glTranslated(0, 0, getType());
186  PositionVector shape = myNBNode.getShape();
187  shape.closePolygon();
188  if (exaggeration > 1) {
189  shape.scaleRelative(exaggeration);
190  }
191  if (s.scale * exaggeration * myMaxSize < 40.) {
192  GLHelper::drawFilledPoly(shape, true);
193  } else {
195  }
196  glPopMatrix();
197  }
198  // Check if a buuble must be drawed over junction
200  setColor(s, true);
201  // recognize full transparency and simply don't draw
202  GLfloat color[4];
203  glGetFloatv(GL_CURRENT_COLOR, color);
204  if (color[3] != 0) {
205  glPushMatrix();
206  Position pos = myNBNode.getPosition();
207  glTranslated(pos.x(), pos.y(), getType() + 0.05);
208  GLHelper::drawFilledCircle(4 * exaggeration, 32);
209  glPopMatrix();
210  }
211  }
212  }
213  if (drawBubble) {
214  setColor(s, true);
215  // recognize full transparency and simply don't draw
216  GLfloat color[4];
217  glGetFloatv(GL_CURRENT_COLOR, color);
218  if (color[3] != 0) {
219  glPushMatrix();
220  Position pos = myNBNode.getPosition();
221  glTranslated(pos.x(), pos.y(), getType() - 0.05);
222  GLHelper::drawFilledCircle(4 * exaggeration, 32);
223  glPopMatrix();
224  }
225  }
226 
228  glPushMatrix();
229  Position pos = myNBNode.getPosition();
230  glTranslated(pos.x(), pos.y(), getType() + 0.1);
231  glColor3d(1, 1, 1);
232  const double halfWidth = 32 / s.scale;
233  const double halfHeight = 64 / s.scale;
234  GUITexturesHelper::drawTexturedBox(GUITextureSubSys::getTexture(GNETEXTURE_TLS), -halfWidth, -halfHeight, halfWidth, halfHeight);
235  glPopMatrix();
236  }
237  // draw crossings
238  if (s.editMode != GNE_MODE_TLS) {
239  for (std::vector<GNECrossing*>::const_iterator it = myGNECrossings.begin(); it != myGNECrossings.end(); it++) {
240  (*it)->drawGL(s);
241  }
242  }
243  // (optional) draw name @todo expose this setting
245  }
246  glPopName();
247 }
248 
249 Boundary
251  return myBoundary;
252 }
253 
254 
255 NBNode*
257  return &myNBNode;
258 }
259 
260 
261 Position
263  return myNBNode.getPosition();
264 }
265 
266 
267 std::vector<GNEJunction*>
269  // use set to avoid duplicates junctions
270  std::set<GNEJunction*> junctions;
271  for (std::vector<GNEEdge*>::const_iterator i = myGNEIncomingEdges.begin(); i != myGNEIncomingEdges.end(); i++) {
272  junctions.insert((*i)->getGNEJunctionSource());
273  }
274  for (std::vector<GNEEdge*>::const_iterator i = myGNEOutgoingEdges.begin(); i != myGNEOutgoingEdges.end(); i++) {
275  junctions.insert((*i)->getGNEJunctionDestiny());
276  }
277  return std::vector<GNEJunction*>(junctions.begin(), junctions.end());
278 }
279 
280 
281 void
283  // Check if incoming edge was already inserted
284  std::vector<GNEEdge*>::iterator i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
285  if (i != myGNEIncomingEdges.end()) {
286  throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + toString(getTag()) + " with ID " + getID() + "'");
287  } else {
288  // Add edge into containers
289  myGNEIncomingEdges.push_back(edge);
290  myGNEEdges.push_back(edge);
291  }
292 }
293 
294 
295 void
297  // Check if outgoing edge was already inserted
298  std::vector<GNEEdge*>::iterator i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
299  if (i != myGNEOutgoingEdges.end()) {
300  throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' was already inserted into " + toString(getTag()) + " with ID " + getID() + "'");
301  } else {
302  // Add edge into containers
303  myGNEOutgoingEdges.push_back(edge);
304  myGNEEdges.push_back(edge);
305  }
306 }
307 
308 
309 void
311  // Check if incoming edge was already inserted
312  std::vector<GNEEdge*>::iterator i = std::find(myGNEIncomingEdges.begin(), myGNEIncomingEdges.end(), edge);
313  if (i == myGNEIncomingEdges.end()) {
314  throw InvalidArgument("Incoming " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + toString(getTag()) + " with ID " + getID() + "'");
315  } else {
316  // remove edge from containers
317  myGNEIncomingEdges.erase(i);
318  myGNEEdges.erase(std::find(myGNEEdges.begin(), myGNEEdges.end(), edge));
319  }
320 }
321 
322 
323 void
325  // Check if outgoing edge was already inserted
326  std::vector<GNEEdge*>::iterator i = std::find(myGNEOutgoingEdges.begin(), myGNEOutgoingEdges.end(), edge);
327  if (i == myGNEOutgoingEdges.end()) {
328  throw InvalidArgument("Outgoing " + toString(SUMO_TAG_EDGE) + " with ID '" + edge->getID() + "' doesn't found into " + toString(getTag()) + " with ID " + getID() + "'");
329  } else {
330  // remove edge from containers
331  myGNEOutgoingEdges.erase(i);
332  myGNEEdges.erase(std::find(myGNEEdges.begin(), myGNEEdges.end(), edge));
333  }
334 }
335 
336 
337 const std::vector<GNEEdge*>&
339  return myGNEEdges;
340 }
341 
342 
343 const std::vector<GNEEdge*>&
345  return myGNEIncomingEdges;
346 }
347 
348 
349 const std::vector<GNEEdge*>&
351  return myGNEOutgoingEdges;
352 }
353 
354 const std::vector<GNECrossing*>&
356  return myGNECrossings;
357 }
358 
359 void
361  myAmCreateEdgeSource = true;
362 }
363 
364 
365 void
367  myAmCreateEdgeSource = false;
368 }
369 
370 
371 void
372 GNEJunction::selectTLS(bool selected) {
373  myAmTLSSelected = selected;
374 }
375 
376 
377 void
379  std::set<GNEJunction*> neighborsJunctions;
380  // obtain all neighbors junctions
381  for (std::vector<GNEEdge*>::const_iterator i = myGNEIncomingEdges.begin(); i != myGNEIncomingEdges.end(); i++) {
382  neighborsJunctions.insert((*i)->getGNEJunctionSource());
383  }
384  for (std::vector<GNEEdge*>::const_iterator i = myGNEOutgoingEdges.begin(); i != myGNEOutgoingEdges.end(); i++) {
385  neighborsJunctions.insert((*i)->getGNEJunctionDestiny());
386  }
387  // recompute all neighbors junctions
388  //for(std::set<GNEJunction*>::iterator i = neighborsJunctions.begin(); i != neighborsJunctions.end(); i++) {
389  // myNet->getNetBuilder()->computeSingleNode((*i)->getNBNode(), OptionsCont::getOptions());
390  //}
391 }
392 
393 
394 void
396  const Position orig = myNBNode.getPosition();
397  setPosition(pos);
398  const EdgeVector& incident = getNBNode()->getEdges();
399  for (EdgeVector::const_iterator it = incident.begin(); it != incident.end(); it++) {
400  GNEEdge* edge = myNet->retrieveEdge((*it)->getID());
401  edge->updateJunctionPosition(this, orig);
402  }
403  // recompute neighbors junctions
405  // recompute junction
406  //myNet->getNetBuilder()->computeSingleNode(&myNBNode, OptionsCont::getOptions());
407  // Update shapes without include connections, because the aren't showed in Move mode
409 }
410 
411 
412 void
414  Position newPos = myNBNode.getPosition();
415  std::string newPosValue = getAttribute(SUMO_ATTR_POSITION);
416  if (isValid(SUMO_ATTR_POSITION, newPosValue)) {
417  // actually the geometry is already up to date
418  // set the restore point to the end of the last change-set
420  // do not execute the command to avoid changing the edge geometry twice
421  undoList->add(new GNEChange_Attribute(this, SUMO_ATTR_POSITION, newPosValue), false);
422  setPosition(newPos);
423  // Refresh element to avoid grabbing problems
424  myNet->refreshElement(this);
425  } else {
426  // tried to set an invalid position, revert back to the previous one
427  move(myOrigPos);
428  }
429 }
430 
431 
432 void
434  // First declare three sets with all affected GNEJunctions, GNEEdges and GNEConnections
435  std::set<GNEJunction*> affectedJunctions;
436  std::set<GNEEdge*> affectedEdges;
437  // Iterate over GNEEdges
438  for (std::vector<GNEEdge*>::const_iterator i = myGNEEdges.begin(); i != myGNEEdges.end(); i++) {
439  // Add source and destiny junctions
440  affectedJunctions.insert((*i)->getGNEJunctionSource());
441  affectedJunctions.insert((*i)->getGNEJunctionDestiny());
442  // Obtain neighbors of Junction source
443  for (std::vector<GNEEdge*>::const_iterator j = (*i)->getGNEJunctionSource()->getGNEEdges().begin(); j != (*i)->getGNEJunctionSource()->getGNEEdges().end(); j++) {
444  affectedEdges.insert(*j);
445  }
446  // Obtain neighbors of Junction destiny
447  for (std::vector<GNEEdge*>::const_iterator j = (*i)->getGNEJunctionDestiny()->getGNEEdges().begin(); j != (*i)->getGNEJunctionDestiny()->getGNEEdges().end(); j++) {
448  affectedEdges.insert(*j);
449  }
450  }
451  // Iterate over affected Junctions
452  for (std::set<GNEJunction*>::iterator i = affectedJunctions.begin(); i != affectedJunctions.end(); i++) {
453  // Update geometry of Junction
454  (*i)->updateGeometry();
455  }
456  // Iterate over affected Edges
457  for (std::set<GNEEdge*>::iterator i = affectedEdges.begin(); i != affectedEdges.end(); i++) {
458  // Update edge geometry
459  (*i)->updateGeometry();
460  }
461  // Finally update geometry of this edge
462  updateGeometry();
463  // Update view to show the new shapes
464  if (myNet->getViewNet()) {
465  myNet->getViewNet()->update();
466  }
467 }
468 
469 
470 void
472  if (!myNBNode.hasCustomShape()) {
473  myNBNode.myPoly.clear();
475  }
476 }
477 
478 
479 void
480 GNEJunction::setLogicValid(bool valid, GNEUndoList* undoList, const std::string& status) {
481  myHasValidLogic = valid;
482  if (!valid) {
483  assert(undoList != 0);
484  assert(undoList->hasCommandGroup());
486  EdgeVector incoming = myNBNode.getIncomingEdges();
487  for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
488  NBEdge* srcNBE = *it;
489  NBEdge* turnEdge = srcNBE->getTurnDestination();
490  GNEEdge* srcEdge = myNet->retrieveEdge(srcNBE->getID());
491  // Make a copy of connections
492  std::vector<NBEdge::Connection> connections = srcNBE->getConnections();
493  // delete in reverse so that undoing will add connections in the original order
494  for (std::vector<NBEdge::Connection>::reverse_iterator con_it = connections.rbegin(); con_it != connections.rend(); con_it++) {
495  bool hasTurn = con_it->toEdge == turnEdge;
496  undoList->add(new GNEChange_Connection(srcEdge, *con_it, false), true);
497  // needs to come after GNEChange_Connection
498  // XXX bug: this code path will not be used on a redo!
499  if (hasTurn) {
500  myNet->addExplicitTurnaround(srcNBE->getID());
501  }
502  }
503  undoList->add(new GNEChange_Attribute(srcEdge, GNE_ATTR_MODIFICATION_STATUS, status), true);
504  }
505  undoList->add(new GNEChange_Attribute(this, GNE_ATTR_MODIFICATION_STATUS, status), true);
506  invalidateTLS(undoList);
507  } else {
509  }
510 }
511 
512 
513 void
515  EdgeVector incoming = myNBNode.getIncomingEdges();
516  for (EdgeVector::iterator it = incoming.begin(); it != incoming.end(); it++) {
517  NBEdge* srcNBE = *it;
518  GNEEdge* srcEdge = myNet->retrieveEdge(srcNBE->getID());
519  undoList->add(new GNEChange_Attribute(srcEdge, GNE_ATTR_MODIFICATION_STATUS, MODIFIED), true);
520  }
521 }
522 
523 
524 void
525 GNEJunction::invalidateTLS(GNEUndoList* undoList, const NBConnection& deletedConnection) {
526  assert(undoList->hasCommandGroup());
527  // NBLoadedSUMOTLDef becomes invalid, replace with NBOwnTLDef which will be dynamically recomputed
528  const std::set<NBTrafficLightDefinition*> tls = myNBNode.getControllingTLS(); // make a copy!
529  for (std::set<NBTrafficLightDefinition*>::iterator it = tls.begin(); it != tls.end(); it++) {
530  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(*it);
531  if (tlDef != 0) {
532  NBTrafficLightDefinition* replacementDef = 0;
533  std::string newID = tlDef->getID(); // + "_reguessed"; // changes due to reguessing will be visible in diff
534  if (deletedConnection != NBConnection::InvalidConnection) {
535  // create replacement before deleting the original because deletion will mess up saving original nodes
536  NBLoadedSUMOTLDef* repl = new NBLoadedSUMOTLDef(tlDef, tlDef->getLogic());
537  repl->removeConnection(deletedConnection);
538  replacementDef = repl;
539  } else {
540  replacementDef = new NBOwnTLDef(newID, tlDef->getOffset(), tlDef->getType());
541  replacementDef->setProgramID(tlDef->getProgramID());
542  }
543  undoList->add(new GNEChange_TLS(this, tlDef, false), true);
544  undoList->add(new GNEChange_TLS(this, replacementDef, true, false, newID), true);
545  // the removed traffic light may have controlled more than one junction. These too have become invalid now
546  const std::vector<NBNode*> coNodes = tlDef->getNodes(); // make a copy!
547  for (std::vector<NBNode*>::const_iterator it_node = coNodes.begin(); it_node != coNodes.end(); it_node++) {
548  GNEJunction* sharing = myNet->retrieveJunction((*it_node)->getID());
549  undoList->add(new GNEChange_TLS(sharing, tlDef, false), true);
550  undoList->add(new GNEChange_TLS(sharing, replacementDef, true, false, newID), true);
551  }
552  }
553  }
554 }
555 
556 void
558  // @todo implement GNEChange_Crossing
559  UNUSED_PARAMETER(undoList);
560  // make a copy because the original will be modified
561  const std::vector<NBNode::Crossing> crossings = myNBNode.getCrossings();
562  for (std::vector<NBNode::Crossing>::const_iterator it = crossings.begin(); it != crossings.end(); it++) {
563  EdgeSet edgeSet((*it).edges.begin(), (*it).edges.end());
564  if (edgeSet.count(edge->getNBEdge()) == 1) {
565  myNBNode.removeCrossing((*it).edges);
566  }
567  }
568 }
569 
570 
571 bool
573  return myHasValidLogic;
574 }
575 
576 
577 void
579  // delete all GNECrossing
580  for (std::vector<GNECrossing*>::const_iterator it = myGNECrossings.begin(); it != myGNECrossings.end(); it++) {
581  (*it)->decRef();
582  if ((*it)->unreferenced()) {
583  delete *it;
584  }
585  }
586  myGNECrossings.clear();
587 }
588 
589 
590 std::string
592  switch (key) {
593  case SUMO_ATTR_ID:
594  return getMicrosimID();
595  break;
596  case SUMO_ATTR_POSITION:
597  return toString(myNBNode.getPosition());
598  break;
599  case SUMO_ATTR_TYPE:
600  return toString(myNBNode.getType());
601  break;
603  return myLogicStatus;
604  break;
605  case SUMO_ATTR_SHAPE:
606  return toString(myNBNode.getShape());
607  case SUMO_ATTR_RADIUS:
608  return toString(myNBNode.getRadius());
609  case SUMO_ATTR_TLTYPE:
610  // @todo this causes problems if the node were to have multiple programs of different type (plausible)
611  return myNBNode.isTLControlled() ? toString((*myNBNode.getControllingTLS().begin())->getType()) : "";
612  case SUMO_ATTR_TLID:
613  return myNBNode.isTLControlled() ? toString((*myNBNode.getControllingTLS().begin())->getID()) : "";
615  return myNBNode.getKeepClear() ? "true" : "false";
616  default:
617  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
618  }
619 }
620 
621 
622 void
623 GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
624  if (value == getAttribute(key)) {
625  return; //avoid needless changes, later logic relies on the fact that attributes have changed
626  }
627  switch (key) {
628  case SUMO_ATTR_ID:
629  case SUMO_ATTR_POSITION:
631  case SUMO_ATTR_SHAPE:
632  case SUMO_ATTR_RADIUS:
633  case SUMO_ATTR_TLTYPE:
635  undoList->add(new GNEChange_Attribute(this, key, value), true);
636  break;
637  case SUMO_ATTR_TYPE: {
638  undoList->p_begin("change " + toString(getTag()) + " type");
640  if (getNBNode()->isTLControlled() &&
641  // if switching changing from or to traffic_light_right_on_red we need to remove the old plan
644  ) {
645  const std::set<NBTrafficLightDefinition*> tls = myNBNode.getControllingTLS();
646  for (std::set<NBTrafficLightDefinition*>::iterator it = tls.begin(); it != tls.end(); it++) {
647  undoList->add(new GNEChange_TLS(this, *it, false), true);
648  }
649  }
650  if (!getNBNode()->isTLControlled()) {
651  // create new traffic light
652  undoList->add(new GNEChange_TLS(this, 0, true), true);
653  }
654  } else if (getNBNode()->isTLControlled()) {
655  // delete old traffic light
656  // make a copy because we will modify the original
657  const std::set<NBTrafficLightDefinition*> tls = myNBNode.getControllingTLS();
658  for (std::set<NBTrafficLightDefinition*>::iterator it = tls.begin(); it != tls.end(); it++) {
659  undoList->add(new GNEChange_TLS(this, *it, false), true);
660  }
661  }
662  // must be the final step, otherwise we do not know which traffic lights to remove via GNEChange_TLS
663  undoList->add(new GNEChange_Attribute(this, key, value), true);
664  undoList->p_end();
665  break;
666  }
667  case SUMO_ATTR_TLID: {
668  undoList->p_begin("change " + toString(SUMO_TAG_TRAFFIC_LIGHT) + " id");
669  // junction is already controlled, remove from previous tls
670  const std::set<NBTrafficLightDefinition*> tls = myNBNode.getControllingTLS();
671  for (std::set<NBTrafficLightDefinition*>::iterator it = tls.begin(); it != tls.end(); it++) {
672  undoList->add(new GNEChange_TLS(this, *it, false), true);
673  }
675  const std::map<std::string, NBTrafficLightDefinition*>& programs = tlCont.getPrograms(value);
676  if (programs.size() > 0) {
677  // add to existing tls definitions
678  for (std::map<std::string, NBTrafficLightDefinition*>::const_iterator it = programs.begin(); it != programs.end(); it++) {
679  NBTrafficLightDefinition* oldTLS = it->second;
680  if (dynamic_cast<NBOwnTLDef*>(oldTLS) != 0) {
681  undoList->add(new GNEChange_TLS(this, oldTLS, true), true);
682  } else {
683  // delete and re-create the definition because the loaded phases are now invalid
684  const std::vector<NBNode*> nodes = oldTLS->getNodes();
685  for (std::vector<NBNode*>::const_iterator it_node = nodes.begin(); it_node != nodes.end(); ++it_node) {
686  GNEJunction* oldJunction = myNet->retrieveJunction((*it_node)->getID());
687  undoList->add(new GNEChange_TLS(oldJunction, oldTLS, false), true);
688  }
689  undoList->add(new GNEChange_TLS(this, 0, true, false, value), true);
691  // re-add existing nodes
692  for (std::vector<NBNode*>::const_iterator it_node = nodes.begin(); it_node != nodes.end(); ++it_node) {
693  GNEJunction* oldJunction = myNet->retrieveJunction((*it_node)->getID());
694  undoList->add(new GNEChange_TLS(oldJunction, newTLS, true), true);
695  }
696  }
697  }
698  } else {
699  // create new traffic light
700  undoList->add(new GNEChange_TLS(this, 0, true, false, value), true);
701  }
702  undoList->p_end();
703  break;
704  }
705  default:
706  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
707  }
708 }
709 
710 
711 bool
712 GNEJunction::isValid(SumoXMLAttr key, const std::string& value) {
713  switch (key) {
714  case SUMO_ATTR_ID:
715  return isValidID(value) && myNet->retrieveJunction(value, false) == 0;
716  break;
717  case SUMO_ATTR_TYPE:
719  break;
720  case SUMO_ATTR_POSITION:
721  bool ok;
722  return GeomConvHelper::parseShapeReporting(value, "user-supplied position", 0, ok, false).size() == 1;
723  break;
724  case SUMO_ATTR_SHAPE: {
725  bool ok = true;
726  PositionVector shape = GeomConvHelper::parseShapeReporting(value, "user-supplied position", 0, ok, true);
727  return ok;
728  break;
729  }
730  case SUMO_ATTR_RADIUS:
731  return canParse<double>(value);
732  break;
733  case SUMO_ATTR_TLTYPE:
735  case SUMO_ATTR_TLID:
736  return myNBNode.isTLControlled() && value != "";
738  return value == "true" || value == "false";
739  break;
740  default:
741  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
742  }
743 }
744 
745 
746 void
748  myAmResponsible = newVal;
749 }
750 
751 // ===========================================================================
752 // private
753 // ===========================================================================
754 
755 void
756 GNEJunction::setAttribute(SumoXMLAttr key, const std::string& value) {
757  switch (key) {
758  case SUMO_ATTR_ID:
759  myNet->renameJunction(this, value);
760  break;
761  case SUMO_ATTR_TYPE: {
763  break;
764  }
765  case SUMO_ATTR_POSITION:
766  bool ok;
767  myOrigPos = GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, false)[0];
768  move(myOrigPos);
769  // recompute neighbors junctions
771  // recompute junction
772  //myNet->getNetBuilder()->computeSingleNode(&myNBNode, OptionsCont::getOptions());
773  // Refresh element to avoid grabbing problems
774  myNet->refreshElement(this);
775  break;
777  if (myLogicStatus == GUESSED && value != GUESSED) {
778  // clear guessed connections. previous connections will be restored
780  // Clear GNEConnections of incoming edges
781  for (std::vector<GNEEdge*>::iterator i = myGNEIncomingEdges.begin(); i != myGNEIncomingEdges.end(); i++) {
782  (*i)->clearGNEConnections();
783  }
784  }
785  myLogicStatus = value;
786  break;
787  case SUMO_ATTR_SHAPE: {
788  bool ok;
789  const PositionVector shape = GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, true);
790  myNBNode.setCustomShape(shape);
791  break;
792  }
793  case SUMO_ATTR_RADIUS:
794  myNBNode.setRadius(parse<double>(value));
795  break;
796  case SUMO_ATTR_TLTYPE: {
797  const std::set<NBTrafficLightDefinition*> tls = myNBNode.getControllingTLS();
798  for (std::set<NBTrafficLightDefinition*>::iterator it = tls.begin(); it != tls.end(); it++) {
799  (*it)->setType(SUMOXMLDefinitions::TrafficLightTypes.get(value));
800  }
801  break;
802  }
804  myNBNode.setKeepClear(value == "true");
805  break;
806  default:
807  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
808  }
809 }
810 
811 
812 void
814  const Position& orig = myNBNode.getPosition();
815  myBoundary.moveby(pos.x() - orig.x(), pos.y() - orig.y());
817  /* //reshift also shifts the junction shape. this is not needed because shape is not yet computed
818  * const Position& orig = myNBNode.getPosition();
819  * myNBNode.reshiftPosition(pos.x() - orig.x(), pos.y() - orig.y());
820  */
821 }
822 
823 
824 double
826  switch (s.junctionColorer.getActive()) {
827  case 0:
828  if (bubble) {
829  return 1;
830  } else {
831  return 0;
832  }
833  case 1:
834  return gSelected.isSelected(getType(), getGlID()) ? 1 : 0;
835  case 2:
836  switch (myNBNode.getType()) {
838  return 0;
840  return 1;
841  case NODETYPE_PRIORITY:
842  return 2;
844  return 3;
846  return 4;
848  return 5;
849  case NODETYPE_DISTRICT:
850  return 6;
851  case NODETYPE_NOJUNCTION:
852  return 7;
853  case NODETYPE_DEAD_END:
855  return 8;
856  case NODETYPE_UNKNOWN:
857  case NODETYPE_INTERNAL:
858  assert(false);
859  return 8;
861  return 9;
862  case NODETYPE_ZIPPER:
863  return 10;
865  return 11;
867  return 12;
868  }
869  default:
870  assert(false);
871  return 0;
872  }
873 }
874 
875 
876 void
877 GNEJunction::setColor(const GUIVisualizationSettings& s, bool bubble) const {
879  // override with special colors (unless the color scheme is based on selection)
882  }
883  if (myAmCreateEdgeSource) {
884  glColor3d(0, 1, 0);
885  }
886 }
887 
888 void
891  tlCont.insert(tlDef, forceInsert); // may return false for tlDef which controls multiple junctions
892  tlDef->addNode(&myNBNode);
893 }
894 
895 
896 void
899  if (tlDef->getNodes().size() == 1) {
900  tlCont.extract(tlDef);
901  }
903 }
904 
905 /****************************************************************************/
GUIVisualizationSizeSettings junctionSize
bool getKeepClear() const
Returns the keepClear flag.
Definition: NBNode.h:267
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:258
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:261
void setResponsible(bool newVal)
set responsibility for deleting internal strctures
double myMaxSize
The maximum size (in either x-, or y-dimension) for determining whether to draw or not...
Definition: GNEJunction.h:245
std::string myLogicStatus
modification status of the junction logic (all connections across this junction)
Definition: GNEJunction.h:255
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
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:743
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.
void invalidateShape()
void removeIncomingGNEEdge(GNEEdge *edge)
remove incoming GNEEdge
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
PositionVector myPoly
the (outer) shape of the junction
Definition: NBNode.h:750
void refreshElement(GUIGlObject *o)
refreshes boundary information for o and update
Definition: GNENet.cpp:817
void markAsCreateEdgeSource()
marks as first junction in createEdge-mode
NBNetBuilder * getNetBuilder() const
get net builder
Definition: GNENet.cpp:1047
A loaded (complete) traffic light logic.
bool myAmCreateEdgeSource
whether this junction is the first junction for a newly creatededge
Definition: GNEJunction.h:252
static GUIGlID getTexture(GUITexture which)
returns a texture previously defined in the enum GUITexture
static const NBConnection InvalidConnection
Definition: NBConnection.h:127
A container for traffic light definitions and built programs.
std::vector< GNEEdge * > myGNEIncomingEdges
vector with the incomings GNEEdges vinculated with this junction
Definition: GNEJunction.h:236
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
Definition: NBNode.cpp:262
bool isValid(SumoXMLAttr key, const std::string &value)
void setLogicValid(bool valid, GNEUndoList *undoList=0, const std::string &status=GUESSED)
Position getPosition() const
Return current position.
friend class GNEChange_TLS
Declare friend class.
Definition: GNEJunction.h:57
Stores the information about how to visualize structures.
double y() const
Returns the y-position.
Definition: Position.h:68
GUIVisualizationSettings * getVisualisationSettings() const
get visualitation settings
bool hasCustomShape() const
return whether the shape was set by the user
Definition: NBNode.h:493
The representation of a single edge during network building.
Definition: NBEdge.h:71
TrafficLightType getType() const
get the algorithm type (static etc..)
void moveby(double x, double y, double z=0)
Moves the boundary by the given amount.
Definition: Boundary.cpp:283
const std::vector< Crossing > & getCrossings() const
return this junctions pedestrian crossings
Definition: NBNode.h:620
double x() const
Returns the x-position.
Definition: Position.h:63
mode for editing tls
Definition: GNEViewNet.h:63
turn junction into geometry node
Definition: GUIAppEnum.h:626
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.
link,node: the traffic light id responsible for this link
T MAX2(T a, T b)
Definition: StdDefs.h:70
double getWidth() const
Returns the width of the boudary (x-axis)
Definition: Boundary.cpp:162
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:88
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition: NBEdge.cpp:2670
static void drawFilledPoly(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:72
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:82
void addExplicitTurnaround(std::string id)
add edge id to the list of explicit turnarounds
Definition: GNENet.cpp:1186
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:66
bool myAmTLSSelected
whether this junction is selected in tls-mode
Definition: GNEJunction.h:264
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
Definition: NBNode.cpp:320
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition: NBNode.cpp:1722
void extract(NBTrafficLightDefinition *definition)
Extracts a traffic light definition from myDefinitions but keeps it in myExtracted for eventual * del...
void registerMove(GNEUndoList *undoList)
registers completed movement with the undoList
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:340
void updateShapesAndGeometries()
update shapes of all elements associated to the junction
const std::vector< GNEEdge * > & getGNEEdges() const
Returns all GNEEdges vinculated with this Junction.
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
removes a traffic light
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.
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:38
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
Position myOrigPos
restore point for undo
Definition: GNEJunction.h:242
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:245
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:1177
static void drawFilledPolyTesselated(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
Definition: GLHelper.cpp:91
void removeOutgoingGNEEdge(GNEEdge *edge)
remove outgoing GNEEdge
const std::vector< GNECrossing * > & getGNECrossings() const
Returns GNECrossings.
static bool isValidID(const std::string &value)
true if value is a valid sumo ID
static const std::string MODIFIED
feature has been manually modified (implies approval)
void setRadius(double radius)
set the turning radius
Definition: NBNode.h:483
std::string getAttribute(SumoXMLAttr key) const
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition: NBNode.h:288
void invalidateIncomingConnections()
invalidate incoming connections
Definition: NBNode.cpp:1349
void removeCrossing(const EdgeVector &edges)
remove a pedestrian crossing from this node (identified by its edges)
Definition: NBNode.cpp:2553
The turning radius at an intersection in m.
std::set< NBEdge * > EdgeSet
container for unique edges
Definition: NBCont.h:51
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.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:439
This object is responsible for drawing a shape and for supplying a a popup menu. Messages are routete...
Definition: GNECrossing.h:51
void buildCrossingsAndWalkingAreas(bool discardInvalid=true)
build crossings, and walkingareas. Also removes invalid loaded crossings if wished ...
Definition: NBNode.cpp:2008
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:89
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
GNEJunction * retrieveJunction(const std::string &id, bool failHard=true)
get junction by id
Definition: GNENet.cpp:730
A list of positions.
bool isLogicValid()
whether this junction has a valid logic
friend class GNEChange_Attribute
declare friend class
T get(const std::string &str) const
void removeFromCrossings(GNEEdge *edge, GNEUndoList *undoList)
removes the given edge from all pedestrian crossings
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node) ...
Definition: NBNode.h:250
bool showJunctionAsBubbles() const
return true if junction must be showed as bubbles
Definition: GNEViewNet.cpp:399
void dropGNECrossings()
drop crossings
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
NBTrafficLightLogic * getLogic()
Returns the internal logic.
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:234
GUIColorer junctionColorer
The junction colorer.
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
void addOutgoingGNEEdge(GNEEdge *edge)
add outgoing GNEEdge
std::vector< GNEEdge * > myGNEEdges
vector with the GNEEdges vinculated with this junction
Definition: GNEJunction.h:233
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
const std::string & getProgramID() const
Returns the ProgramID.
double getColorValue(const GUIVisualizationSettings &s, bool bubble) const
determines color value
NBNode & myNBNode
A reference to the represented junction.
Definition: GNEJunction.h:230
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
void setKeepClear(bool keepClear)
set the keepClear flag
Definition: NBNode.h:488
void invalidateTLS(GNEUndoList *undoList, const NBConnection &deletedConnection=NBConnection::InvalidConnection)
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
const PositionVector & getShape() const
retrieve the junction shape
Definition: NBNode.cpp:1716
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:57
edit junction shape
Definition: GUIAppEnum.h:624
double selectionScale
the current selection scaling in NETEDIT (temporary)
virtual ~GNEJunction()
Destructor.
Definition: GNEJunction.cpp:78
double getRadius() const
Returns the turning radius of this node.
Definition: NBNode.h:262
bool haveNetworkCrossings()
notify about style of loaded network (Without Crossings)
Definition: NBNetBuilder.h:192
void updateGeometry()
Update the boundary of the junction.
Definition: GNEJunction.cpp:87
const EdgeVector & getIncomingEdges() const
Returns this node&#39;s incoming edges (The edges which yield in this node)
Definition: NBNode.h:240
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:834
double getHeight() const
Returns the height of the boundary (y-axis)
Definition: Boundary.cpp:168
Boundary myBoundary
The represented junction&#39;s boundary.
Definition: GNEJunction.h:248
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:298
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:41
std::vector< GNECrossing * > myGNECrossings
the built crossing objects
Definition: GNEJunction.h:267
void recomputeNeighborsJunctions()
recompute neighbors junctions
void scaleRelative(double factor)
enlarges/shrinks the polygon by a factor based at the centroid
void rebuildGNECrossings()
rebuilds crossing objects for this junction
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
void move(Position pos)
reposition the node at pos and informs the edges
void updateJunctionPosition(GNEJunction *junction, const Position &origPos)
update edge geometry after junction move
Definition: GNEEdge.cpp:248
The popup menu of a globject.
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:257
std::vector< GNEEdge * > myGNEOutgoingEdges
vector with the outgoings GNEEdges vinculated with this junction
Definition: GNEJunction.h:239
void buildSelectionPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to (de)select the object.
const Position & getPosition() const
Definition: NBNode.h:232
Represents a single node (junction) during network building.
Definition: NBNode.h:75
GUIGlID getGlID() const
Returns the numerical id of the object.
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
double getExaggeration(const GUIVisualizationSettings &s, double factor=20) const
return the drawing size including exaggeration and constantSize values
GNEJunction(NBNode &nbn, GNENet *net, bool loaded=false)
Constructor.
Definition: GNEJunction.cpp:65
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
static const std::string GUESSED
feature has been reguessed (may still be unchanged be we can&#39;t tell (yet)
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
color of selection
Definition: GNENet.h:97
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:61
mode for creating new edges
Definition: GNEViewNet.h:51
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:126
bool hasString(const std::string &str) const
void setPosition(Position pos)
reposition the NBNnode and nothing else
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.cpp:261
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:86
A traffic light logics which must be computed (only nodes/edges are given)
Definition: NBOwnTLDef.h:54
void closePolygon()
ensures that the last position equals the first
bool checkIsRemovable() const
check if node is removable
Definition: NBNode.cpp:1642
NBNode * getNBNode() const
Return net build node.
GUISelectedStorage gSelected
A global holder of selected objects.
A window containing a gl-object&#39;s parameter.
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition: GNENet.cpp:1171
static bool isTrafficLight(SumoXMLNodeType type)
return whether the given type is a traffic light
Definition: NBNode.cpp:2698
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 occured errors.
void requireRecompute()
inform the net about the need for recomputation
Definition: GNENet.cpp:1024
void addTrafficLight(NBTrafficLightDefinition *tlDef, bool forceInsert)
adds a traffic light
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:1165
a junction
SumoXMLTag getTag() const
get XML Tag assigned to this object