SUMO - Simulation of Urban MObility
GNEEdge.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // A road/street connecting two junctions (netedit-version, adapted from GUIEdge)
8 // Basically a container for an NBEdge with drawing and editing capabilities
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 <vector>
33 #include <cmath>
34 #include <string>
35 #include <algorithm>
39 #include <utils/geom/GeomHelper.h>
42 #include <utils/gui/div/GLHelper.h>
45 
46 #include "GNEEdge.h"
47 #include "GNENet.h"
48 #include "GNEViewNet.h"
49 #include "GNEUndoList.h"
50 #include "GNEChange_Attribute.h"
51 #include "GNEChange_Lane.h"
52 #include "GNEJunction.h"
53 #include "GNELane.h"
54 #include "GNEAdditional.h"
55 #include "GNEConnection.h"
56 #include "GNERouteProbe.h"
57 #include "GNEVaporizer.h"
58 #include "GNERerouter.h"
59 #include "GNECrossing.h"
60 
61 
62 // ===========================================================================
63 // static
64 // ===========================================================================
66 
67 // ===========================================================================
68 // members methods
69 // ===========================================================================
70 GNEEdge::GNEEdge(NBEdge& nbe, GNENet* net, bool wasSplit, bool loaded):
71  GNENetElement(net, nbe.getID(), GLO_EDGE, SUMO_TAG_EDGE, ICON_EDGE),
72  myNBEdge(nbe) ,
73  myGNEJunctionSource(myNet->retrieveJunction(myNBEdge.getFromNode()->getID())),
74  myGNEJunctionDestiny(myNet->retrieveJunction(myNBEdge.getToNode()->getID())),
75  myOrigShape(nbe.getInnerGeometry()),
76  myLanes(0),
77  myAmResponsible(false),
78  myWasSplit(wasSplit),
79  myConnectionStatus(loaded ? LOADED : GUESSED) {
80  // Create lanes
81  int numLanes = myNBEdge.getNumLanes();
82  myLanes.reserve(numLanes);
83  for (int i = 0; i < numLanes; i++) {
84  myLanes.push_back(new GNELane(*this, i));
85  myLanes.back()->incRef("GNEEdge::GNEEdge");
86  }
87  // update Lane geometries
88  for (LaneVector::iterator i = myLanes.begin(); i != myLanes.end(); i++) {
89  (*i)->updateGeometry();
90  }
91 }
92 
93 
95  // Delete references to this eddge in lanes
96  for (LaneVector::iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
97  (*i)->decRef("GNEEdge::~GNEEdge");
98  if ((*i)->unreferenced()) {
99  // show extra information for tests
100  if (OptionsCont::getOptions().getBool("gui-testing-debug")) {
101  WRITE_WARNING("Deleting unreferenced " + toString((*i)->getTag()) + " '" + (*i)->getID() + "' in GNEEdge destructor");
102  }
103  delete *i;
104  }
105  }
106  // delete references to this eddge in connections
107  for (ConnectionVector::const_iterator i = myGNEConnections.begin(); i != myGNEConnections.end(); ++i) {
108  (*i)->decRef("GNEEdge::~GNEEdge");
109  if ((*i)->unreferenced()) {
110  // show extra information for tests
111  if (OptionsCont::getOptions().getBool("gui-testing-debug")) {
112  WRITE_WARNING("Deleting unreferenced " + toString((*i)->getTag()) + " '" + (*i)->getID() + "' in GNEEdge destructor");
113  }
114  delete(*i);
115  }
116  }
117  if (myAmResponsible) {
118  delete &myNBEdge;
119  }
120 }
121 
122 
123 void
125  // Update geometry of lanes
126  for (LaneVector::iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
127  (*i)->updateGeometry();
128  }
129  // Update geometry of additionals vinculated to this edge
130  for (AdditionalVector::iterator i = myAdditionals.begin(); i != myAdditionals.end(); ++i) {
131  (*i)->updateGeometry();
132  }
133 }
134 
135 
136 void GNEEdge::commitGeometryMoving(const PositionVector& oldShape, double minDistToEnd, GNEUndoList* undoList) {
137  // shape has to be cleaned
138  PositionVector cleanedShape = myNBEdge.getInnerGeometry();
139  auto it = cleanedShape.begin();
140  // iterate over shape and remove nearest point to Junctions
141  while (it != cleanedShape.end()) {
142  if (it->distanceTo2D(myGNEJunctionSource->getPositionInView()) < minDistToEnd) {
143  it = cleanedShape.erase(it);
144  } else if (it->distanceTo2D(myGNEJunctionDestiny->getPositionInView()) < minDistToEnd) {
145  it = cleanedShape.erase(it);
146  } else {
147  it++;
148  }
149  }
150  if (oldShape != cleanedShape) {
151  undoList->p_begin("moving " + toString(SUMO_ATTR_SHAPE) + " of " + toString(getTag()));
153  undoList->p_add(new GNEChange_Attribute(this, SUMO_ATTR_SHAPE, toString(cleanedShape)));
154  undoList->p_end();
155  } else {
156  setGeometry(oldShape, true);
157  }
158 
159 }
160 
161 
162 Boundary
164  Boundary ret;
165  for (LaneVector::const_iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
166  ret.add((*i)->getBoundary());
167  }
168  ret.grow(10); // !!! magic value
169  return ret;
170 }
171 
172 
173 Boundary
175  Boundary b = getBoundary();
176  b.grow(20);
177  return b;
178 }
179 
180 
183  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
184  buildPopupHeader(ret, app);
188  buildPositionCopyEntry(ret, false);
189  return ret;
190 }
191 
192 
195  return myGNEJunctionSource;
196 }
197 
198 
201  return myGNEJunctionDestiny;
202 }
203 
204 void
206  /* do something different for connectors?
207  if (myNBEdge.isMacroscopicConnector()) {
208  }
209  */
210 
211  // draw the lanes
212  for (LaneVector::const_iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
213  (*i)->drawGL(s);
214  }
215 
216  // draw the connections
217  if (s.scale >= 2) {
218  for (ConnectionVector::const_iterator i = myGNEConnections.begin(); i != myGNEConnections.end(); ++i) {
219  (*i)->drawGL(s);
220  }
221  }
222 
223  // draw geometry hints
224  if (s.scale * SNAP_RADIUS > 1.) { // check whether it is not too small
225  GLHelper::setColor(s.junctionColorer.getSchemes()[0].getColor(2));
226  if (gSelected.isSelected(getType(), getGlID()) && s.laneColorer.getActive() != 1) {
227  // override with special colors (unless the color scheme is based on selection)
228  GLHelper::setColor(GNENet::selectionColor.changedBrightness(-20));
229  }
230  // recognize full transparency and simply don't draw
231  GLfloat color[4];
232  glGetFloatv(GL_CURRENT_COLOR, color);
233  if (color[3] > 0) {
234  glPushName(getGlID());
236  // draw geometry points
237  for (int i = 1; i < (int)geom.size() - 1; i++) {
238  Position pos = geom[i];
239  glPushMatrix();
240  glTranslated(pos.x(), pos.y(), GLO_JUNCTION - 0.01);
241  // resolution of drawn circle depending of the zoom (To improve smothness)
242  if (s.scale >= 10) {
244  } else if (s.scale >= 2) {
246  } else if (s.scale >= 1) {
248  } else {
250  }
251  glPopMatrix();
252  }
253  glPopName();
254  }
255  }
256 
257  // (optionally) draw the name and/or the street name
258  const bool drawStreetName = s.streetName.show && myNBEdge.getStreetName() != "";
259  if (s.edgeName.show || drawStreetName) {
260  glPushName(getGlID());
261  GNELane* lane1 = myLanes[0];
262  GNELane* lane2 = myLanes[myLanes.size() - 1];
263  Position p = lane1->getShape().positionAtOffset(lane1->getShape().length() / (double) 2.);
264  p.add(lane2->getShape().positionAtOffset(lane2->getShape().length() / (double) 2.));
265  p.mul(.5);
266  double angle = lane1->getShape().rotationDegreeAtOffset(lane1->getShape().length() / (double) 2.);
267  angle += 90;
268  if (angle > 90 && angle < 270) {
269  angle -= 180;
270  }
271  if (s.edgeName.show) {
272  drawName(p, s.scale, s.edgeName, angle);
273  }
274  if (drawStreetName) {
276  s.streetName.size / s.scale, s.streetName.color, angle);
277  }
278  glPopName();
279  }
280 }
281 
282 
286  GUIParameterTableWindow* ret = 0;
287  UNUSED_PARAMETER(&app);
288  return ret;
289 }
290 
291 
292 void
294  Position delta = junction->getNBNode()->getPosition() - origPos;
296  // geometry endpoint need not equal junction position hence we modify it with delta
297  if (junction == myGNEJunctionSource) {
298  geom[0].add(delta);
299  } else {
300  geom[-1].add(delta);
301  }
302  setGeometry(geom, false);
303 }
304 
305 NBEdge*
307  return &myNBEdge;
308 }
309 
310 
311 Position
312 GNEEdge::getSplitPos(const Position& clickPos) {
313  const PositionVector& geom = myNBEdge.getGeometry();
314  int index = geom.indexOfClosest(clickPos);
315  if (geom[index].distanceTo(clickPos) < SNAP_RADIUS) {
316  // split at existing geometry point
317  return geom[index];
318  } else {
319  // split straight between the next two points
320  return geom.positionAtOffset(geom.nearest_offset_to_point2D(clickPos));
321  }
322 }
323 
324 
325 Position
326 GNEEdge::moveGeometry(const Position& oldPos, const Position& newPos, bool relative) {
328  bool changed = changeGeometry(geom, getMicrosimID(), oldPos, newPos, relative);
329  if (changed) {
330  setGeometry(geom, false);
331  return newPos;
332  } else {
333  return oldPos;
334  }
335 }
336 
337 
338 bool
339 GNEEdge::changeGeometry(PositionVector& geom, const std::string& id, const Position& oldPos, const Position& newPos, bool relative, bool moveEndPoints) {
340  if (geom.size() < 2) {
341  throw ProcessError("Invalid geometry size in " + toString(SUMO_TAG_EDGE) + " with ID='" + id + "'");
342  } else {
343  // obtain index of closest point to old position
344  int index = geom.indexOfClosest(oldPos);
345  const double nearestOffset = geom.nearest_offset_to_point2D(oldPos, true);
346  if (nearestOffset != GeomHelper::INVALID_OFFSET
347  && (moveEndPoints || (nearestOffset >= SNAP_RADIUS
348  && nearestOffset <= geom.length2D() - SNAP_RADIUS))) {
349  const Position nearest = geom.positionAtOffset2D(nearestOffset);
350  const double distance = geom[index].distanceTo2D(nearest);
351  if (distance < SNAP_RADIUS) { //move existing
352  if (moveEndPoints || (index != 0 && index != (int)geom.size() - 1)) {
353  const bool closed = geom.isClosed();
354  if (relative) {
355  geom[index] = geom[index] + newPos;
356  } else {
357  geom[index] = newPos;
358  }
359  if (closed && moveEndPoints && (index == 0 || index == (int)geom.size() - 1)) {
360  const int otherIndex = (int)geom.size() - 1 - index;
361  geom[otherIndex] = geom[index];
362  }
363  return true;
364  }
365  } else {
366  if (relative) {
367  index = geom.insertAtClosest(nearest);
368  geom[index] = geom[index] + newPos;
369  return true;
370  } else {
371  // insert newPos between the two closest positions
372  geom.insertAtClosest(newPos);
373  return true;
374  }
375  }
376  }
377  return false;
378  }
379 }
380 
381 
382 void
385  if (geom.size() == 0) {
386  return;
387  }
388  geom.add(delta.x(), delta.y(), delta.z());
389  setGeometry(geom, true);
390 }
391 
392 
393 bool
396  if (geom.size() == 0) {
397  return false;
398  }
399  int index = geom.indexOfClosest(pos);
400  if (geom[index].distanceTo(pos) < SNAP_RADIUS) {
401  geom.erase(geom.begin() + index);
402  setAttribute(SUMO_ATTR_SHAPE, toString(geom), undoList);
403  return true;
404  } else {
405  return false;
406  }
407 }
408 
409 
410 void
412  undoList->p_begin("set endpoint");
414  int index = geom.indexOfClosest(pos);
415  if (geom[index].distanceTo(pos) < SNAP_RADIUS) { // snap to existing geometry
416  pos = geom[index];
417  }
420  if (pos.distanceTo2D(destPos) < pos.distanceTo2D(sourcePos)) {
421  setAttribute(GNE_ATTR_SHAPE_END, toString(pos), undoList);
423  } else {
424  setAttribute(GNE_ATTR_SHAPE_START, toString(pos), undoList);
426  }
427  // possibly existing inner point is no longer needed
428  deleteGeometry(pos, undoList);
429  undoList->p_end();
430 }
431 
432 
433 void
437  if (pos.distanceTo2D(destPos) < pos.distanceTo2D(sourcePos)) {
438  setAttribute(GNE_ATTR_SHAPE_END, toString(destPos), undoList);
440  } else {
441  setAttribute(GNE_ATTR_SHAPE_START, toString(sourcePos), undoList);
443  }
444 }
445 
446 
447 void
449  myNBEdge.setGeometry(geom, inner);
450  updateGeometry();
453  myNet->refreshElement(this);
454 }
455 
456 
457 void
459  // create new and removed unused GNEConnectinos
460  const std::vector<NBEdge::Connection>& connections = myNBEdge.getConnections();
461  // create a vector to keep retrieved and created connections
462  std::vector<GNEConnection*> retrievedConnections;
463  // iterate over NBEdge::Connections of GNEEdge
464  for (std::vector<NBEdge::Connection>::const_iterator it = connections.begin(); it != connections.end(); it++) {
465  // retrieve existent GNEConnection, or create it
466  GNEConnection* retrievedGNEConnection = retrieveGNEConnection(it->fromLane, it->toEdge, it->toLane);
467  retrievedConnections.push_back(retrievedGNEConnection);
468  // check if previously this GNEConnections exists, and if true, remove it from myGNEConnections
469  std::vector<GNEConnection*>::iterator retrievedExists = std::find(myGNEConnections.begin(), myGNEConnections.end(), retrievedGNEConnection);
470  if (retrievedExists != myGNEConnections.end()) {
471  myGNEConnections.erase(retrievedExists);
472  } else {
473  // include reference to created GNEConnection
474  retrievedGNEConnection->incRef("GNEEdge::remakeGNEConnections");
475  retrievedGNEConnection->updateLinkState();
476  }
477  }
478  // delete non retrieved GNEConnections
479  for (std::vector<GNEConnection*>::const_iterator it = myGNEConnections.begin(); it != myGNEConnections.end(); it++) {
480  (*it)->decRef();
481  if ((*it)->unreferenced()) {
482  // show extra information for tests
483  if (OptionsCont::getOptions().getBool("gui-testing-debug")) {
484  WRITE_WARNING("Deleting unreferenced " + toString((*it)->getTag()) + " '" + (*it)->getID() + "' in rebuildGNEConnections()");
485  }
486  delete *it;
487  }
488  }
489  // copy retrieved (existent and created) GNECrossigns to myGNEConnections
490  myGNEConnections = retrievedConnections;
491 }
492 
493 
494 void
496  // Drop all existents connections that aren't referenced anymore
497  for (ConnectionVector::iterator i = myGNEConnections.begin(); i != myGNEConnections.end(); i++) {
498  // Dec reference of connection
499  (*i)->decRef("GNEEdge::clearGNEConnections");
500  // Delete GNEConnectionToErase if is unreferenced
501  if ((*i)->unreferenced()) {
502  // show extra information for tests
503  if (OptionsCont::getOptions().getBool("gui-testing-debug")) {
504  WRITE_WARNING("Deleting unreferenced " + toString((*i)->getTag()) + " '" + (*i)->getID() + "' in clearGNEConnections()");
505  }
506  delete(*i);
507  }
508  }
509  myGNEConnections.clear();
510 }
511 
512 
513 int
515  AdditionalVector routeProbes;
516  for (AdditionalVector::const_iterator i = myAdditionals.begin(); i != myAdditionals.end(); i++) {
517  if ((*i)->getTag() == routeProbe->getTag()) {
518  routeProbes.push_back(*i);
519  }
520  }
521  // return index of routeProbe in routeProbes vector
522  AdditionalVector::const_iterator it = std::find(routeProbes.begin(), routeProbes.end(), routeProbe);
523  if (it == routeProbes.end()) {
524  return -1;
525  } else {
526  return (int)(it - routeProbes.begin());
527  }
528 }
529 
530 
531 int
533  AdditionalVector vaporizers;
534  for (AdditionalVector::const_iterator i = myAdditionals.begin(); i != myAdditionals.end(); i++) {
535  if ((*i)->getTag() == vaporizer->getTag()) {
536  vaporizers.push_back(*i);
537  }
538  }
539  // return index of routeProbe in routeProbes vector
540  AdditionalVector::const_iterator it = std::find(vaporizers.begin(), vaporizers.end(), vaporizer);
541  if (it == vaporizers.end()) {
542  return -1;
543  } else {
544  return (int)(it - vaporizers.begin());
545  }
546 }
547 
548 
549 std::vector<GNECrossing*>
551  std::vector<GNECrossing*> crossings;
552  for (auto i : myGNEJunctionSource->getGNECrossings()) {
553  if (i->checkEdgeBelong(this)) {
554  crossings.push_back(i);
555  }
556  }
557  for (auto i : myGNEJunctionDestiny->getGNECrossings()) {
558  if (i->checkEdgeBelong(this)) {
559  crossings.push_back(i);
560  }
561  }
562  return crossings;
563 }
564 
565 
566 void
568  undoList->p_begin("copy template");
576  // copy lane attributes as well
577  for (int i = 0; i < (int)myLanes.size(); i++) {
578  myLanes[i]->setAttribute(SUMO_ATTR_ALLOW, tpl->myLanes[i]->getAttribute(SUMO_ATTR_ALLOW), undoList);
579  myLanes[i]->setAttribute(SUMO_ATTR_DISALLOW, tpl->myLanes[i]->getAttribute(SUMO_ATTR_DISALLOW), undoList);
580  myLanes[i]->setAttribute(SUMO_ATTR_SPEED, tpl->myLanes[i]->getAttribute(SUMO_ATTR_SPEED), undoList);
581  myLanes[i]->setAttribute(SUMO_ATTR_WIDTH, tpl->myLanes[i]->getAttribute(SUMO_ATTR_WIDTH), undoList);
582  myLanes[i]->setAttribute(SUMO_ATTR_ENDOFFSET, tpl->myLanes[i]->getAttribute(SUMO_ATTR_ENDOFFSET), undoList);
583  }
584  undoList->p_end();
585 }
586 
587 
588 std::set<GUIGlID>
590  std::set<GUIGlID> result;
591  for (size_t i = 0; i < myLanes.size(); i++) {
592  result.insert(myLanes[i]->getGlID());
593  }
594  return result;
595 }
596 
597 
598 const std::vector<GNELane*>&
600  return myLanes;
601 }
602 
603 
604 const std::vector<GNEConnection*>&
606  return myGNEConnections;
607 }
608 
609 
610 bool
612  return myWasSplit;
613 }
614 
615 
616 std::string
618  switch (key) {
619  case SUMO_ATTR_ID:
620  return getMicrosimID();
621  case SUMO_ATTR_FROM:
623  case SUMO_ATTR_TO:
625  case SUMO_ATTR_NUMLANES:
626  return toString(myNBEdge.getNumLanes());
627  case SUMO_ATTR_PRIORITY:
628  return toString(myNBEdge.getPriority());
629  case SUMO_ATTR_LENGTH:
630  return toString(myNBEdge.getFinalLength());
631  case SUMO_ATTR_TYPE:
632  return myNBEdge.getTypeID();
633  case SUMO_ATTR_SHAPE:
637  case SUMO_ATTR_NAME:
638  return myNBEdge.getStreetName();
639  case SUMO_ATTR_ALLOW:
640  return (getVehicleClassNames(myNBEdge.getPermissions()) + (myNBEdge.hasLaneSpecificPermissions() ? " (combined!)" : ""));
641  case SUMO_ATTR_DISALLOW: {
643  }
644  case SUMO_ATTR_SPEED:
646  return "lane specific";
647  } else {
648  return toString(myNBEdge.getSpeed());
649  }
650  case SUMO_ATTR_WIDTH:
652  return "lane specific";
654  return "default";
655  } else {
656  return toString(myNBEdge.getLaneWidth());
657  }
658  case SUMO_ATTR_ENDOFFSET:
660  return "lane specific";
661  } else {
662  return toString(myNBEdge.getEndOffset());
663  }
665  return myConnectionStatus;
668  return "";
669  } else {
670  return toString(myNBEdge.getGeometry()[0]);
671  }
672  case GNE_ATTR_SHAPE_END:
674  return "";
675  } else {
676  return toString(myNBEdge.getGeometry()[-1]);
677  }
678  default:
679  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
680  }
681 }
682 
683 std::string
685  std::string result = getAttribute(key);
686  if ((key == SUMO_ATTR_ALLOW || key == SUMO_ATTR_DISALLOW) && result.find("all") != std::string::npos) {
687  result += " " + getVehicleClassNames(SVCAll, true);
688  }
689  return result;
690 }
691 
692 void
693 GNEEdge::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
694  switch (key) {
695  case SUMO_ATTR_WIDTH:
696  case SUMO_ATTR_ENDOFFSET:
697  case SUMO_ATTR_SPEED:
698  case SUMO_ATTR_ALLOW:
699  case SUMO_ATTR_DISALLOW: {
700  undoList->p_begin("change " + toString(getTag()) + " attribute");
701  const std::string origValue = myLanes.at(0)->getAttribute(key); // will have intermediate value of "lane specific"
702  // lane specific attributes need to be changed via lanes to allow undo
703  for (LaneVector::iterator it = myLanes.begin(); it != myLanes.end(); it++) {
704  (*it)->setAttribute(key, value, undoList);
705  }
706  // ensure that the edge value is also changed. Actually this sets the lane attributes again but it does not matter
707  undoList->p_add(new GNEChange_Attribute(this, key, value, true, origValue));
708  undoList->p_end();
709  break;
710  }
711  case SUMO_ATTR_FROM: {
712  undoList->p_begin("change " + toString(getTag()) + " attribute");
713  // Remove edge from crossings of junction source
715  // continue changing from junction
716  GNEJunction* oldGNEJunctionSource = myGNEJunctionSource;
717  myGNEJunctionSource->setLogicValid(false, undoList);
718  undoList->p_add(new GNEChange_Attribute(this, key, value));
719  myGNEJunctionSource->setLogicValid(false, undoList);
720  myNet->retrieveJunction(value)->setLogicValid(false, undoList);
723  undoList->p_end();
724  // update geometries of all implicated junctions
725  oldGNEJunctionSource->updateGeometry();
728  break;
729  }
730  case SUMO_ATTR_TO: {
731  undoList->p_begin("change " + toString(getTag()) + " attribute");
732  // Remove edge from crossings of junction destiny
734  // continue changing destiny junction
735  GNEJunction* oldGNEJunctionDestiny = myGNEJunctionDestiny;
736  myGNEJunctionDestiny->setLogicValid(false, undoList);
737  undoList->p_add(new GNEChange_Attribute(this, key, value));
738  myGNEJunctionDestiny->setLogicValid(false, undoList);
739  myNet->retrieveJunction(value)->setLogicValid(false, undoList);
742  undoList->p_end();
743  // update geometries of all implicated junctions
744  oldGNEJunctionDestiny->updateGeometry();
747  break;
748  }
749  case SUMO_ATTR_ID:
750  case SUMO_ATTR_PRIORITY:
751  case SUMO_ATTR_LENGTH:
752  case SUMO_ATTR_TYPE:
756  case GNE_ATTR_SHAPE_END:
757  undoList->p_add(new GNEChange_Attribute(this, key, value));
758  break;
759  case SUMO_ATTR_NAME:
760  // user cares about street names. Make sure they appear in the output
762  OptionsCont::getOptions().set("output.street-names", "true");
763  undoList->p_add(new GNEChange_Attribute(this, key, value));
764  break;
765  case SUMO_ATTR_NUMLANES:
766  if (value != getAttribute(key)) {
767  // Remove edge from crossings of junction source
769  // Remove edge from crossings of junction destiny
771  // set num lanes
772  setNumLanes(parse<int>(value), undoList);
773  }
774  break;
775  case SUMO_ATTR_SHAPE:
776  // @note: assumes value of inner geometry!
777  // actually the geometry is already updated (incrementally
778  // during mouse movement). We set the restore point to the end
779  // of the last change-set
781  undoList->p_add(new GNEChange_Attribute(this, key, value));
782  break;
783  default:
784  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
785  }
786 }
787 
788 
789 bool
790 GNEEdge::isValid(SumoXMLAttr key, const std::string& value) {
791  switch (key) {
792  case SUMO_ATTR_ID:
793  return isValidID(value) && (myNet->retrieveEdge(value, false) == 0);
794  case SUMO_ATTR_FROM: {
795  // check that is a valid ID and is different of ID of junction destiny
796  if (isValidID(value) && (value != myGNEJunctionDestiny->getMicrosimID())) {
797  GNEJunction* junctionFrom = myNet->retrieveJunction(value, false);
798  // check that there isn't already another edge with the same From and To Edge
799  if ((junctionFrom != NULL) && (myNet->retrieveEdge(junctionFrom, myGNEJunctionDestiny, false) == NULL)) {
800  return true;
801  } else {
802  return false;
803  }
804  } else {
805  return false;
806  }
807  }
808  case SUMO_ATTR_TO: {
809  // check that is a valid ID and is different of ID of junction Source
810  if (isValidID(value) && (value != myGNEJunctionSource->getMicrosimID())) {
811  GNEJunction* junctionTo = myNet->retrieveJunction(value, false);
812  // check that there isn't already another edge with the same From and To Edge
813  if ((junctionTo != NULL) && (myNet->retrieveEdge(myGNEJunctionSource, junctionTo, false) == NULL)) {
814  return true;
815  } else {
816  return false;
817  }
818  } else {
819  return false;
820  }
821  }
822  case SUMO_ATTR_SPEED:
823  return canParse<double>(value) && isPositive<double>(value);
824  case SUMO_ATTR_NUMLANES:
825  return canParse<int>(value) && isPositive<int>(value);
826  case SUMO_ATTR_PRIORITY:
827  return canParse<int>(value);
828  case SUMO_ATTR_LENGTH:
829  return canParse<double>(value) && (isPositive<double>(value) || (parse<double>(value) == NBEdge::UNSPECIFIED_LOADED_LENGTH));
830  case SUMO_ATTR_ALLOW:
831  case SUMO_ATTR_DISALLOW:
832  return canParseVehicleClasses(value);
833  case SUMO_ATTR_TYPE:
834  return true;
835  case SUMO_ATTR_SHAPE: {
836  bool ok = true;
837  PositionVector shape = GeomConvHelper::parseShapeReporting(value, "user-supplied position", 0, ok, true);
838  return ok;
839  }
842  case SUMO_ATTR_NAME:
843  return true;
844  case SUMO_ATTR_WIDTH:
845  if (value == "default") {
846  return true;
847  } else {
848  return canParse<double>(value) && (isPositive<double>(value) || (parse<double>(value) == NBEdge::UNSPECIFIED_WIDTH));
849  }
850  case SUMO_ATTR_ENDOFFSET:
851  return canParse<double>(value);
852  case GNE_ATTR_SHAPE_START: {
853  bool ok;
854  if (value != "") {
855  PositionVector shapeStart = GeomConvHelper::parseShapeReporting(value, "user-supplied position", 0, ok, false);
856  if ((shapeStart.size() == 1) && (shapeStart[0] != myNBEdge.getGeometry()[-1])) {
857  return true;
858  } else {
859  return false;
860  }
861  } else {
862  return true;
863  }
864  }
865  case GNE_ATTR_SHAPE_END: {
866  bool ok;
867  if (value != "") {
868  PositionVector shapeStart = GeomConvHelper::parseShapeReporting(value, "user-supplied position", 0, ok, false);
869  if ((shapeStart.size() == 1) && (shapeStart[0] != myNBEdge.getGeometry()[0])) {
870  return true;
871  } else {
872  return false;
873  }
874  } else {
875  return true;
876  }
877  }
878  default:
879  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
880  }
881 }
882 
883 
884 void
886  myAmResponsible = newVal;
887 }
888 
889 // ===========================================================================
890 // private
891 // ===========================================================================
892 
893 void
894 GNEEdge::setAttribute(SumoXMLAttr key, const std::string& value) {
895  switch (key) {
896  case SUMO_ATTR_ID:
897  myNet->renameEdge(this, value);
898  break;
899  case SUMO_ATTR_FROM:
901  // update this edge of list of outgoings edges of the old GNEJunctionSource
903  // update GNEJunctionSource
905  // update this edge of list of outgoings edges of the new GNEJunctionSource
907  break;
908  case SUMO_ATTR_TO:
910  // update this edge of list of incomings edges of the old GNEJunctionDestiny
912  // update GNEJunctionDestiny
914  // update this edge of list of incomings edges of the new GNEJunctionDestiny
916  break;
917  case SUMO_ATTR_NUMLANES:
918  throw InvalidArgument("GNEEdge::setAttribute (private) called for attr SUMO_ATTR_NUMLANES. This should never happen");
919  break;
920  case SUMO_ATTR_PRIORITY:
921  myNBEdge.myPriority = parse<int>(value);
922  break;
923  case SUMO_ATTR_LENGTH:
924  myNBEdge.setLoadedLength(parse<double>(value));
925  break;
926  case SUMO_ATTR_TYPE:
927  myNBEdge.myType = value;
928  break;
929  case SUMO_ATTR_SHAPE:
930  bool ok;
931  myOrigShape = GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, true);
932  setGeometry(myOrigShape, true);
933  break;
936  break;
937  case SUMO_ATTR_NAME:
938  myNBEdge.setStreetName(value);
939  break;
940  case SUMO_ATTR_SPEED:
941  myNBEdge.setSpeed(-1, parse<double>(value));
942  break;
943  case SUMO_ATTR_WIDTH:
944  if (value == "default") {
946  } else {
947  myNBEdge.setLaneWidth(-1, parse<double>(value));
948  }
949  break;
950  case SUMO_ATTR_ENDOFFSET:
951  myNBEdge.setEndOffset(-1, parse<double>(value));
952  break;
953  case SUMO_ATTR_ALLOW:
954  break; // no edge value
955  case SUMO_ATTR_DISALLOW:
956  break; // no edge value
958  myConnectionStatus = value;
959  if (value == GUESSED) {
962  } else if (value != GUESSED) {
964  }
965  break;
966  case GNE_ATTR_SHAPE_START: {
967  // get geometry of NBEdge, remove FIRST element with the new value (or with the Junction Source position) and set it back to edge
969  geom.erase(geom.begin());
970  if (value == "") {
972  } else {
973  geom.push_front_noDoublePos(GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, false)[0]);
974  }
975  setGeometry(geom, false);
976  break;
977  }
978  case GNE_ATTR_SHAPE_END: {
979  // get geometry of NBEdge, remove LAST element with the new value (or with the Junction Destiny position) and set it back to edge
981  geom.pop_back();
982  if (value == "") {
984  } else {
985  geom.push_back_noDoublePos(GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, false)[0]);
986  }
987  setGeometry(geom, false);
988  break;
989  }
990  default:
991  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
992  }
993 }
994 
995 
996 void
997 GNEEdge::setNumLanes(int numLanes, GNEUndoList* undoList) {
998  undoList->p_begin("change number of " + toString(SUMO_TAG_LANE) + "s");
999  myGNEJunctionSource->setLogicValid(false, undoList);
1000  myGNEJunctionDestiny->setLogicValid(false, undoList);
1001 
1002  const int oldNumLanes = (int)myLanes.size();
1003  for (int i = oldNumLanes; i < numLanes; i++) {
1004  // since the GNELane does not exist yet, it cannot have yet been referenced so we only pass a zero-pointer
1005  undoList->add(new GNEChange_Lane(this, 0,
1006  myNBEdge.getLaneStruct(oldNumLanes - 1), true), true);
1007  }
1008  for (int i = oldNumLanes - 1; i > numLanes - 1; i--) {
1009  // delete leftmost lane
1010  undoList->add(new GNEChange_Lane(this, myLanes[i], myNBEdge.getLaneStruct(i), false), true);
1011  }
1012  undoList->p_end();
1013 }
1014 
1015 
1016 void
1017 GNEEdge::addLane(GNELane* lane, const NBEdge::Lane& laneAttrs) {
1018  const int index = lane ? lane->getIndex() : myNBEdge.getNumLanes();
1019  // the laneStruct must be created first to ensure we have some geometry
1020  myNBEdge.addLane(index);
1021  if (lane) {
1022  // restore a previously deleted lane
1023  myLanes.insert(myLanes.begin() + index, lane);
1024 
1025  } else {
1026  // create a new lane by copying leftmost lane
1027  lane = new GNELane(*this, index);
1028  myLanes.push_back(lane);
1029  }
1030  lane->incRef("GNEEdge::addLane");
1031  // we copy all attributes except shape since this is recomputed from edge shape
1032  myNBEdge.setSpeed(lane->getIndex(), laneAttrs.speed);
1033  myNBEdge.setPermissions(laneAttrs.permissions, lane->getIndex());
1035  myNBEdge.setEndOffset(lane->getIndex(), laneAttrs.endOffset);
1036  myNBEdge.setLaneWidth(lane->getIndex(), laneAttrs.width);
1037  // udate indices
1038  for (int i = 0; i < (int)myLanes.size(); ++i) {
1039  myLanes[i]->setIndex(i);
1040  }
1041  /* while technically correct, this looks ugly
1042  myGNEJunctionSource->invalidateShape();
1043  myGNEJunctionDestiny->invalidateShape();
1044  */
1045  // Remake connections for this edge and all edges that target this lane
1047  // remake connections of all edges of junction source and destiny
1048  for (std::vector<GNEEdge*>::const_iterator i = myGNEJunctionSource->getGNEEdges().begin(); i != myGNEJunctionSource->getGNEEdges().end(); i++) {
1049  (*i)->remakeGNEConnections();
1050  }
1051  // remake connections of all edges of junction source and destiny
1052  for (std::vector<GNEEdge*>::const_iterator i = myGNEJunctionDestiny->getGNEEdges().begin(); i != myGNEJunctionDestiny->getGNEEdges().end(); i++) {
1053  (*i)->remakeGNEConnections();
1054  }
1055  // Update element
1056  myNet->refreshElement(this);
1057  updateGeometry();
1058 }
1059 
1060 
1061 void
1063  if (myLanes.size() == 0) {
1064  throw ProcessError("Should not remove the last " + toString(SUMO_TAG_LANE) + " from an " + toString(getTag()));
1065  }
1066  if (lane == 0) {
1067  lane = myLanes.back();
1068  }
1069  // Delete lane of edge's container
1070  myNBEdge.deleteLane(lane->getIndex());
1071  lane->decRef("GNEEdge::removeLane");
1072  myLanes.erase(myLanes.begin() + lane->getIndex());
1073  // Delete lane if is unreferenced
1074  if (lane->unreferenced()) {
1075  // show extra information for tests
1076  if (OptionsCont::getOptions().getBool("gui-testing-debug")) {
1077  WRITE_WARNING("Deleting unreferenced " + toString(lane->getTag()) + " '" + lane->getID() + "' in removeLane()");
1078  }
1079  delete lane;
1080  }
1081  // udate indices
1082  for (int i = 0; i < (int)myLanes.size(); ++i) {
1083  myLanes[i]->setIndex(i);
1084  }
1085  /* while technically correct, this looks ugly
1086  myGNEJunctionSource->invalidateShape();
1087  myGNEJunctionDestiny->invalidateShape();
1088  */
1089  // Remake connections of this edge
1091  // remake connections of all edges of junction source and destiny
1092  for (std::vector<GNEEdge*>::const_iterator i = myGNEJunctionSource->getGNEEdges().begin(); i != myGNEJunctionSource->getGNEEdges().end(); i++) {
1093  (*i)->remakeGNEConnections();
1094  }
1095  // remake connections of all edges of junction source and destiny
1096  for (std::vector<GNEEdge*>::const_iterator i = myGNEJunctionDestiny->getGNEEdges().begin(); i != myGNEJunctionDestiny->getGNEEdges().end(); i++) {
1097  (*i)->remakeGNEConnections();
1098  }
1099  // Update element
1100  myNet->refreshElement(this);
1101  updateGeometry();
1102 }
1103 
1104 
1105 void
1106 GNEEdge::addConnection(NBEdge::Connection nbCon, bool selectAfterCreation) {
1107  // If a new connection was sucesfully created
1108  if (myNBEdge.setConnection(nbCon.fromLane, nbCon.toEdge, nbCon.toLane, NBEdge::L2L_USER, true, nbCon.mayDefinitelyPass, nbCon.keepClear, nbCon.contPos, nbCon.visibility)) {
1109  // Create or retrieve existent GNEConection
1110  GNEConnection* con = retrieveGNEConnection(nbCon.fromLane, nbCon.toEdge, nbCon.toLane);
1111  // add it to GNEConnection container
1112  myGNEConnections.push_back(con);
1113  // Add reference
1114  myGNEConnections.back()->incRef("GNEEdge::addConnection");
1115  // select GNEConnection if needed
1116  if (selectAfterCreation) {
1117  gSelected.deselect(con->getGlID());
1118  }
1119  // update geometry
1120  con->updateGeometry();
1121  }
1122  myNet->refreshElement(this); // actually we only do this to force a redraw
1123 }
1124 
1125 
1126 void
1128  // check if is a explicit turnaround
1129  if (nbCon.toEdge == myNBEdge.getTurnDestination()) {
1131  }
1132  // remove NBEdge::connection from NBEdge
1134  // remove their associated GNEConnection
1135  GNEConnection* con = retrieveGNEConnection(nbCon.fromLane, nbCon.toEdge, nbCon.toLane, false);
1136  if (con != NULL) {
1137  con->decRef("GNEEdge::removeConnection");
1138  myGNEConnections.erase(std::find(myGNEConnections.begin(), myGNEConnections.end(), con));
1139  if (con->unreferenced()) {
1140  // show extra information for tests
1141  if (OptionsCont::getOptions().getBool("gui-testing-debug")) {
1142  WRITE_WARNING("Deleting unreferenced " + toString(con->getTag()) + " '" + con->getID() + "' in removeConnection()");
1143  }
1144  delete con;
1145  myNet->refreshElement(this); // actually we only do this to force a redraw
1146  }
1147  }
1148 }
1149 
1150 
1152 GNEEdge::retrieveGNEConnection(int fromLane, NBEdge* to, int toLane, bool createIfNoExist) {
1153  for (ConnectionVector::iterator i = myGNEConnections.begin(); i != myGNEConnections.end(); ++i) {
1154  if ((*i)->getFromLaneIndex() == fromLane
1155  && (*i)->getEdgeTo()->getNBEdge() == to
1156  && (*i)->getToLaneIndex() == toLane) {
1157  return *i;
1158  }
1159  }
1160  if (createIfNoExist) {
1161  // create new connection
1162  GNEConnection* createdConnection = new GNEConnection(myLanes[fromLane], myNet->retrieveEdge(to->getID())->getLanes()[toLane]);
1163  // show extra information for tests
1164  if (OptionsCont::getOptions().getBool("gui-testing-debug")) {
1165  WRITE_WARNING("Created " + toString(createdConnection->getTag()) + " '" + createdConnection->getID() + "' in retrieveGNEConnection()");
1166  }
1167  return createdConnection;
1168  } else {
1169  return NULL;
1170  }
1171 }
1172 
1173 
1174 
1175 void
1176 GNEEdge::setMicrosimID(const std::string& newID) {
1178  for (LaneVector::iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
1179  (*i)->setMicrosimID(getNBEdge()->getLaneID((*i)->getIndex()));
1180  }
1181 }
1182 
1183 
1184 void
1186  // First check that additional wasn't already inserted
1187  if (std::find(myAdditionals.begin(), myAdditionals.end(), additional) != myAdditionals.end()) {
1188  throw ProcessError(toString(additional->getTag()) + " with ID='" + additional->getID() + "' was already inserted in " + toString(getTag()) + " with ID='" + getID() + "'");
1189  } else {
1190  myAdditionals.push_back(additional);
1191  // update geometry is needed for stacked additionals (routeProbes and Vaporicers)
1192  updateGeometry();
1193  }
1194 }
1195 
1196 
1197 void
1199  // First check that additional was already inserted
1200  AdditionalVector::iterator it = std::find(myAdditionals.begin(), myAdditionals.end(), additional);
1201  if (it == myAdditionals.end()) {
1202  throw ProcessError(toString(additional->getTag()) + " with ID='" + additional->getID() + "' doesn't exist in " + toString(getTag()) + " with ID='" + getID() + "'");
1203  } else {
1204  myAdditionals.erase(it);
1205  // update geometry is needed for stacked additionals (routeProbes and Vaporicers)
1206  updateGeometry();
1207  }
1208 }
1209 
1210 
1211 const std::vector<GNEAdditional*>&
1213  return myAdditionals;
1214 }
1215 
1216 
1217 void
1219  if (std::find(myReroutes.begin(), myReroutes.end(), rerouter) == myReroutes.end()) {
1220  myReroutes.push_back(rerouter);
1221  } else {
1222  throw ProcessError(toString(rerouter->getTag()) + " '" + rerouter->getID() + "' was previously inserted");
1223  }
1224 }
1225 
1226 
1227 void
1229  std::vector<GNERerouter*>::iterator it = std::find(myReroutes.begin(), myReroutes.end(), rerouter);
1230  if (it != myReroutes.end()) {
1231  myReroutes.erase(it);
1232  } else {
1233  throw ProcessError(toString(rerouter->getTag()) + " '" + rerouter->getID() + "' wasn't previously inserted");
1234  }
1235 }
1236 
1237 
1238 const std::vector<GNERerouter*>&
1240  return myReroutes;
1241 }
1242 
1243 
1244 int
1246  return (int)myReroutes.size();
1247 }
1248 
1249 
1250 bool
1252  for (std::vector<GNELane*>::const_iterator i = myLanes.begin(); i != myLanes.end(); i++) {
1253  if ((*i)->isRestricted(vclass)) {
1254  return true;
1255  }
1256  }
1257  return false;
1258 }
1259 
1260 
1261 void
1263  // obtain a copy of Crossings
1264  auto crossings = junction->getGNECrossings();
1265  // Remove all crossings that contain this edge in parameter "edges"
1266  for (auto i : crossings) {
1267  if (i->checkEdgeBelong(this)) {
1268  myNet->deleteCrossing(i, undoList);
1269  }
1270  }
1271 }
1272 
1273 /****************************************************************************/
void addLane(GNELane *lane, const NBEdge::Lane &laneAttrs)
increase number of lanes by one use the given attributes and restore the GNELane
Definition: GNEEdge.cpp:1017
void copyTemplate(GNEEdge *tpl, GNEUndoList *undolist)
copy edge attributes from tpl
Definition: GNEEdge.cpp:567
void invalidateConnections(bool reallowSetting=false)
invalidate current connections of edge
Definition: NBEdge.cpp:1254
GNEJunction * myGNEJunctionSource
pointer to GNEJunction source
Definition: GNEEdge.h:274
The information about how to spread the lanes from the given position.
void updateGeometry()
update pre-computed geometry information
std::string getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a &#39; &#39;.
void remakeGNEConnections()
remake connections
Definition: GNEEdge.cpp:458
double z() const
Returns the z-position.
Definition: Position.h:73
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
const std::string & getTypeID() const
get ID of type
Definition: NBEdge.h:972
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:165
void addIncomingGNEEdge(GNEEdge *edge)
add incoming GNEEdge
void setNumLanes(int numLanes, GNEUndoList *undoList)
changes the number of lanes. When reducing the number of lanes, higher-numbered lanes are removed fir...
Definition: GNEEdge.cpp:997
int toLane
The lane the connections yields in.
Definition: NBEdge.h:191
GNEEdge * retrieveEdge(const std::string &id, bool failHard=true)
get edge by id
Definition: GNENet.cpp:899
double scale
information about a lane&#39;s width (temporary, used for a single view)
GUIVisualizationTextSettings streetName
double laneWidthExaggeration
The lane exaggeration (upscale thickness)
GNEJunction * getGNEJunctionSource() const
returns the source-junction
Definition: GNEEdge.cpp:194
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:250
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
Definition: NBEdge.h:271
void resetWritable()
Resets all options to be writeable.
GNENet * myNet
the net to inform about updates
bool myAmResponsible
whether we are responsible for deleting myNBNode
Definition: GNEEdge.h:289
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.
NBEdge * toEdge
The edge the connections yields in.
Definition: NBEdge.h:188
begin/end of the description of a single lane
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
std::string myConnectionStatus
modification status of the connections
Definition: GNEEdge.h:295
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:133
void refreshElement(GUIGlObject *o)
refreshes boundary information for o and update
Definition: GNENet.cpp:990
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2913
GNEJunction * myGNEJunctionDestiny
pointer to GNEJunction destiny
Definition: GNEEdge.h:277
bool hasString(const std::string &str) const
PositionVector myOrigShape
restore point for undo
Definition: GNEEdge.h:280
void setMicrosimID(const std::string &newID)
override to also set lane ids
Definition: GNEEdge.cpp:1176
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
lane spread functions
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
bool hasLaneSpecificEndOffset() const
whether lanes differ in offset
Definition: NBEdge.cpp:1801
std::set< GUIGlID > getLaneGlIDs()
returns GLIDs of all lanes
Definition: GNEEdge.cpp:589
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2929
GUIColorer laneColorer
The lane colorer.
void setLogicValid(bool valid, GNEUndoList *undoList=0, const std::string &status=GUESSED)
double x() const
Returns the x-position.
Definition: Position.h:63
Stores the information about how to visualize structures.
static const double SNAP_RADIUS
Definition: GNEEdge.h:255
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
The representation of a single edge during network building.
Definition: NBEdge.h:71
Position moveGeometry(const Position &oldPos, const Position &newPos, bool relative=false)
change the edge geometry It is up to the Edge to decide whether an new geometry node should be genera...
Definition: GNEEdge.cpp:326
const std::vector< T > & getSchemes() const
bool hasRestrictedLane(SUMOVehicleClass vclass) const
check if edge has a restricted lane
Definition: GNEEdge.cpp:1251
NBNode * getNBNode() const
Return net build node.
void setStreetName(const std::string &name)
sets the street name of this edge
Definition: NBEdge.h:542
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
void removeFromConnections(NBEdge *toEdge, int fromLane=-1, int toLane=-1, bool tryLater=false, const bool adaptToLaneRemoval=false)
Removes the specified connection(s)
Definition: NBEdge.cpp:1187
std::string getAttribute(SumoXMLAttr key) const
This functions has to be implemented in allGNEAttributeCarrier.
Definition: GNEEdge.cpp:617
Position getPositionInView() const
Return current position.
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:92
void setPermissions(SVCPermissions permissions, int lane=-1)
set allowed/disallowed classes for the given lane or for all lanes if -1 is given ...
Definition: NBEdge.cpp:2960
double getEndOffset() const
Returns the offset to the destination node.
Definition: NBEdge.h:549
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:54
double getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:508
void setLoadedLength(double val)
set loaded lenght
Definition: NBEdge.cpp:3003
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:85
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
Definition: NBEdge.h:200
double endOffset
This lane&#39;s offset to the intersection begin.
Definition: NBEdge.h:139
void clearGNEConnections()
clear current connections
Definition: GNEEdge.cpp:495
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
double visibility
custom foe visiblity for connection
Definition: NBEdge.h:209
void removeEdgeFromCrossings(GNEJunction *junction, GNEUndoList *undoList)
remove crossing of junction
Definition: GNEEdge.cpp:1262
const std::vector< GNEConnection * > & getGNEConnections()
returns a reference to the GNEConnection vector
Definition: GNEEdge.cpp:605
const std::vector< GNEAdditional * > & getAdditionalChilds() const
return list of additionals associated with this edge
Definition: GNEEdge.cpp:1212
const std::vector< GNEEdge * > & getGNEEdges() const
Returns all GNEEdges vinculated with this Junction.
const SVCPermissions SVCAll
all VClasses are allowed
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1161
bool isClosed() const
check if PositionVector is closed
int getRouteProbeRelativePosition(GNERouteProbe *routeProbe) const
obtain relative positions of RouteProbes
Definition: GNEEdge.cpp:514
bool myWasSplit
whether this edge was created from a split
Definition: GNEEdge.h:292
~GNEEdge()
Destructor.
Definition: GNEEdge.cpp:94
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:339
first coordinate of edge shape
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.
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge&#39;s geometry
Definition: NBEdge.cpp:524
int getIndex() const
returns the index of the lane
Definition: GNELane.cpp:701
GUIGlID getGlID() const
Returns the numerical id of the object.
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:40
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:256
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:65
bool setConnection(int lane, NBEdge *destEdge, int destLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE)
Adds a connection to a certain lane of a certain edge.
Definition: NBEdge.cpp:954
whether a feature has been loaded,guessed,modified or approved
SVCPermissions invertPermissions(SVCPermissions permissions)
negate the given permissions and ensure that only relevant bits are set
virtual GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
Definition: GNEEdge.cpp:284
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNEEdge.cpp:205
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
void removeOutgoingGNEEdge(GNEEdge *edge)
remove outgoing GNEEdge
bool keepClear
whether the junction must be kept clear when using this connection
Definition: NBEdge.h:203
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
GUIVisualizationTextSettings edgeName
An (internal) definition of a single lane of an edge.
Definition: NBEdge.h:122
const std::string & getID() const
Returns the id.
Definition: Named.h:66
static bool isValidID(const std::string &value)
true if value is a valid sumo ID
SVCPermissions permissions
List of vehicle types that are allowed on this lane.
Definition: NBEdge.h:133
void addLane(int index, bool recompute=true)
add lane
Definition: NBEdge.cpp:2766
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
const std::vector< GNERerouter * > & getGNERerouters() const
get rerouters vinculated with this edge
Definition: GNEEdge.cpp:1239
const PositionVector getInnerGeometry() const
Returns the geometry of the edge without the endpoints.
Definition: NBEdge.cpp:494
void push_front_noDoublePos(const Position &p)
insert in front a non double position
void addAdditionalChild(GNEAdditional *additional)
add additional child to this edge
Definition: GNEEdge.cpp:1185
const Position & getPosition() const
Definition: NBNode.h:235
double getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:524
bool hasLaneSpecificSpeed() const
whether lanes differ in speed
Definition: NBEdge.cpp:1779
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:421
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
void addGNERerouter(GNERerouter *rerouter)
add a reference to a rerouter that has this edge as parameter
Definition: GNEEdge.cpp:1218
int getNumberOfGNERerouters() const
get number of rerouters that has this edge as parameters
Definition: GNEEdge.cpp:1245
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:438
const double SUMO_const_halfLaneWidth
Definition: StdDefs.h:51
SVCPermissions preferred
List of vehicle types that are preferred on this lane.
Definition: NBEdge.h:136
const std::vector< GNECrossing * > & getGNECrossings() const
Returns GNECrossings.
int fromLane
The lane the connections starts at.
Definition: NBEdge.h:185
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
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:92
void deleteLane(int index, bool recompute=true)
delete lane
Definition: NBEdge.cpp:2801
GNEJunction * retrieveJunction(const std::string &id, bool failHard=true)
get junction by id
Definition: GNENet.cpp:886
A list of positions.
double rotationDegreeAtOffset(double pos) const
Returns the rotation at the given length.
int indexOfClosest(const Position &p) const
index of the closest position to p
bool hasLaneSpecificPermissions() const
whether lanes differ in allowed vehicle classes
Definition: NBEdge.cpp:1765
std::vector< GNERerouter * > myReroutes
list of reroutes that has this edge as parameter
Definition: GNEEdge.h:301
void removeGNERerouter(GNERerouter *rerouter)
remove a reference to a rerouter that has this edge as parameter
Definition: GNEEdge.cpp:1228
friend class GNEChange_Attribute
declare friend class
AdditionalVector myAdditionals
list with the additionals vinculated with this edge
Definition: GNEEdge.h:298
Boundary getBoundary() const
Returns the street&#39;s geometry.
Definition: GNEEdge.cpp:163
double y() const
Returns the y-position.
Definition: Position.h:68
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:414
int getVaporizerRelativePosition(GNEVaporizer *vaporizer) const
obtain relative positions of Vaporizer
Definition: GNEEdge.cpp:532
GNEConnection * retrieveGNEConnection(int fromLane, NBEdge *to, int toLane, bool createIfNoExist=true)
get GNEConnection if exist, and if not create it if create is enabled
Definition: GNEEdge.cpp:1152
double length() const
Returns the length.
int myPriority
The priority of the edge.
Definition: NBEdge.h:1373
T MIN2(T a, T b)
Definition: StdDefs.h:68
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNEEdge.cpp:174
edge: the shape in xml-definition
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:302
GUIColorer junctionColorer
The junction colorer.
void deleteCrossing(GNECrossing *crossing, GNEUndoList *undoList)
remove crossing
Definition: GNENet.cpp:498
void addOutgoingGNEEdge(GNEEdge *edge)
add outgoing GNEEdge
int insertAtClosest(const Position &p)
inserts p between the two closest positions and returns the insertion index
const std::string getID() const
function to support debugging
static const double INVALID_OFFSET
a value to signify offsets outside the range of [0, Line.length()]
Definition: GeomHelper.h:59
void incRef(const std::string &debugMsg="")
Increarse reference.
The connection was given by the user.
Definition: NBEdge.h:113
double speed
The speed allowed on this lane.
Definition: NBEdge.h:130
double width
This lane&#39;s width.
Definition: NBEdge.h:142
void removeLane(GNELane *lane)
the number of lanes by one. argument is only used to increase robustness (assertions) ...
Definition: GNEEdge.cpp:1062
virtual GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition: GNEEdge.cpp:182
void decRef(const std::string &debugMsg="")
Decrease reference.
std::vector< GNECrossing * > getGNECrossings()
get GNECrossings vinculated with this Edge
Definition: GNEEdge.cpp:550
begin/end of the description of an edge
void setGeometry(PositionVector geom, bool inner)
update edge geometry and inform the lanes
Definition: GNEEdge.cpp:448
GNEEdge(NBEdge &nbe, GNENet *net, bool wasSplit=false, bool loaded=false)
Constructor.
Definition: GNEEdge.cpp:70
bool canParseVehicleClasses(const std::string &classes)
Checks whether the given string contains only known vehicle classes.
void commitGeometryMoving(const PositionVector &oldShape, double minDistToEnd, GNEUndoList *undoList)
registers completed movement with the undoList
Definition: GNEEdge.cpp:136
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:58
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:2988
ConnectionVector myGNEConnections
vector with the connections of this edge
Definition: GNEEdge.h:286
void setResponsible(bool newVal)
set responsibility for deleting internal strctures
Definition: GNEEdge.cpp:885
void addConnection(NBEdge::Connection nbCon, bool selectAfterCreation=false)
adds a connection
Definition: GNEEdge.cpp:1106
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:435
const PositionVector & getShape() const
returns the shape of the lane
Definition: GNELane.cpp:625
void deselect(GUIGlID id)
Deselects the object with the given id.
const std::vector< GNELane * > & getLanes()
returns a reference to the lane vector
Definition: GNEEdge.cpp:599
double length2D() const
Returns the length.
bool set(const std::string &name, const std::string &value)
Sets the given value for the named option.
bool deleteGeometry(const Position &pos, GNEUndoList *undoList)
deletes the closest geometry node within SNAP_RADIUS.
Definition: GNEEdge.cpp:394
void updateGeometry()
Update the boundary of the junction.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
virtual void setMicrosimID(const std::string &newID)
Changes the microsimID of the object.
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:62
void setPreferredVehicleClass(SVCPermissions permissions, int lane=-1)
set preferred Vehicle Class
Definition: NBEdge.cpp:2974
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:596
double getFinalLength() const
get length that will be assigned to the lanes in the final network
Definition: NBEdge.cpp:3203
double contPos
custom position for internal junction on this connection
Definition: NBEdge.h:206
void updateJunctionPosition(GNEJunction *junction, const Position &origPos)
update edge geometry after junction move
Definition: GNEEdge.cpp:293
void updateGeometry()
update pre-computed geometry information
Definition: GNEEdge.cpp:124
The popup menu of a globject.
an edge
std::vector< GNEAdditional * > AdditionalVector
Definition of the additionals vector.
Definition: GNEEdge.h:72
void buildSelectionPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to (de)select the object.
std::string myType
The type of the edge.
Definition: NBEdge.h:1357
void renameEdge(GNEEdge *edge, const std::string &newID)
updates the map and reserves new id
Definition: GNENet.cpp:1496
bool isValid(SumoXMLAttr key, const std::string &value)
Definition: GNEEdge.cpp:790
void declareConnectionsAsLoaded(EdgeBuildingStep step=LANES2LANES_USER)
declares connections as fully loaded. This is needed to avoid recomputing connections if an edge has ...
Definition: NBEdge.h:1175
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge&#39;s lanes&#39; lateral offset is computed.
Definition: NBEdge.h:678
void removeExplicitTurnaround(std::string id)
remove edge id from the list of explicit turnarounds
Definition: GNENet.cpp:1546
LaneVector myLanes
vectgor with the lanes of this edge
Definition: GNEEdge.h:283
SumoXMLTag getTag() const
get XML Tag assigned to this object
void removeConnection(NBEdge::Connection nbCon)
removes a connection
Definition: GNEEdge.cpp:1127
bool hasLaneSpecificWidth() const
whether lanes differ in width
Definition: NBEdge.cpp:1790
void updateLinkState()
recompute cached myLinkState
static const std::string GUESSED
feature has been reguessed (may still be unchanged be we can&#39;t tell (yet)
last coordinate of edge shape
void setEndpoint(Position pos, GNEUndoList *undoList)
makes pos the new geometry endpoint at the appropriate end
Definition: GNEEdge.cpp:411
void push_back_noDoublePos(const Position &p)
insert in back a non double position
static const RGBColor selectionColor
Definition: GNENet.h:103
empty max
void removeAdditionalChild(GNEAdditional *additional)
remove additional child from this edge
Definition: GNEEdge.cpp:1198
NBEdge & myNBEdge
the underlying NBEdge
Definition: GNEEdge.h:271
void mul(double val)
Multiplies both positions with the given value.
Definition: Position.h:113
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.cpp:306
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0)
draw Text with given parameters
Definition: GLHelper.cpp:455
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:86
std::string getAttributeForSelection(SumoXMLAttr key) const
method for getting the attribute in the context of object selection
Definition: GNEEdge.cpp:684
void add(double xoff, double yoff, double zoff)
void setLaneSpreadFunction(LaneSpreadFunction spread)
(Re)sets how the lanes lateral offset shall be computed
Definition: NBEdge.cpp:776
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition: GNEEdge.cpp:693
const std::string & getStreetName() const
Returns the street name of this edge.
Definition: NBEdge.h:537
GUISelectedStorage gSelected
A global holder of selected objects.
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:835
void resetEndpoint(const Position &pos, GNEUndoList *undoList)
restores the endpoint to the junction position at the appropriate end
Definition: GNEEdge.cpp:434
A window containing a gl-object&#39;s parameter.
void changeEdgeEndpoints(GNEEdge *edge, const std::string &newSourceID, const std::string &newDestID)
modifies endpoins of the given edge
Definition: GNENet.cpp:1509
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition: NBEdge.cpp:2737
bool wasSplit()
whether this edge was created from a split
Definition: GNEEdge.cpp:611
Position getSplitPos(const Position &clickPos)
Definition: GNEEdge.cpp:312
bool unreferenced()
check if object ins&#39;t referenced
friend class GNEChange_Lane
Friend class.
Definition: GNEEdge.h:61
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.
static bool changeGeometry(PositionVector &geom, const std::string &id, const Position &oldPos, const Position &newPos, bool relative=false, bool moveEndPoints=false)
Definition: GNEEdge.cpp:339
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2874
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
a junction
GNEJunction * getGNEJunctionDestiny() const
returns the destination-junction
Definition: GNEEdge.cpp:200
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:428