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-2016 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>
43 #include "GNEEdge.h"
44 #include "GNENet.h"
45 #include "GNEUndoList.h"
46 #include "GNEChange_Attribute.h"
47 #include "GNEChange_Lane.h"
48 #include "GNEJunction.h"
49 #include "GNELane.h"
50 
51 #ifdef CHECK_MEMORY_LEAKS
52 #include <foreign/nvwa/debug_new.h>
53 #endif // CHECK_MEMORY_LEAKS
54 
55 
56 
57 // ===========================================================================
58 // static
59 // ===========================================================================
61 
62 // ===========================================================================
63 // members methods
64 // ===========================================================================
65 GNEEdge::GNEEdge(NBEdge& nbe, GNENet* net, bool wasSplit, bool loaded):
66  GUIGlObject(GLO_EDGE, nbe.getID()),
68  myNBEdge(nbe) ,
69  myOrigShape(nbe.getInnerGeometry()),
70  myLanes(0),
71  myNet(net),
72  myAmResponsible(false),
73  myWasSplit(wasSplit),
74  myConnectionStatus(loaded ? LOADED : GUESSED) {
75  int numLanes = myNBEdge.getNumLanes();
76  myLanes.reserve(numLanes);
77  for (int i = 0; i < numLanes; i++) {
78  myLanes.push_back(new GNELane(*this, i));
79  myLanes.back()->incRef("GNEEdge::GNEEdge");
80  }
81 }
82 
83 
85  for (LaneVector::iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
86  (*i)->decRef("GNEEdge::~GNEEdge");
87  if ((*i)->unreferenced()) {
88  delete *i;
89  }
90  }
91  if (myAmResponsible) {
92  delete &myNBEdge;
93  }
94 }
95 
96 
99  Boundary ret;
100  for (LaneVector::const_iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
101  ret.add((*i)->getBoundary());
102  }
103  ret.grow(10); // !!! magic value
104  return ret;
105 }
106 
107 
110  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
111  buildPopupHeader(ret, app);
115  buildPositionCopyEntry(ret, false);
116  return ret;
117 }
118 
119 
120 Boundary
122  Boundary b = getBoundary();
123  b.grow(20);
124  return b;
125 }
126 
127 
131 }
132 
133 
137 }
138 
139 
140 void
142  /* do something different for connectors?
143  if (myNBEdge.isMacroscopicConnector()) {
144  }
145  */
146 
147  // draw the lanes
148  for (LaneVector::const_iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
149  (*i)->drawGL(s);
150  }
151 
152  // draw geometry hints
153  if (s.scale * SNAP_RADIUS > 1.) { // check whether it is not too small
154  GLHelper::setColor(s.junctionColorer.getSchemes()[0].getColor(2));
155  glPushName(getGlID());
157  for (int i = 1; i < (int)geom.size() - 1; i++) {
158  Position pos = geom[i];
159  glPushMatrix();
160  glTranslated(pos.x(), pos.y(), GLO_JUNCTION - 0.01);
162  glPopMatrix();
163  }
164  glPopName();
165  }
166 
167  // (optionally) draw the name and/or the street name
168  const bool drawStreetName = s.streetName.show && myNBEdge.getStreetName() != "";
169  if (s.edgeName.show || drawStreetName) {
170  glPushName(getGlID());
171  GNELane* lane1 = myLanes[0];
172  GNELane* lane2 = myLanes[myLanes.size() - 1];
173  Position p = lane1->getShape().positionAtOffset(lane1->getShape().length() / (SUMOReal) 2.);
174  p.add(lane2->getShape().positionAtOffset(lane2->getShape().length() / (SUMOReal) 2.));
175  p.mul(.5);
176  SUMOReal angle = lane1->getShape().rotationDegreeAtOffset(lane1->getShape().length() / (SUMOReal) 2.);
177  angle += 90;
178  if (angle > 90 && angle < 270) {
179  angle -= 180;
180  }
181  if (s.edgeName.show) {
182  drawName(p, s.scale, s.edgeName, angle);
183  }
184  if (drawStreetName) {
186  s.streetName.size / s.scale, s.streetName.color, angle);
187  }
188  glPopName();
189  }
190 }
191 
192 
196  GUIParameterTableWindow* ret = 0;
197  UNUSED_PARAMETER(&app);
198  return ret;
199 }
200 
201 
202 void
204  Position delta = junction->getNBNode()->getPosition() - origPos;
206  // geometry endpoint need not equal junction position hence we modify it with delta
207  if (junction == getSource()) {
208  geom[0].add(delta);
209  } else {
210  geom[-1].add(delta);
211  }
212  setGeometry(geom, false);
213 }
214 
215 
216 Position
217 GNEEdge::getSplitPos(const Position& clickPos) {
218  const PositionVector& geom = myNBEdge.getGeometry();
219  int index = geom.indexOfClosest(clickPos);
220  if (geom[index].distanceTo(clickPos) < SNAP_RADIUS) {
221  // split at existing geometry point
222  return geom[index];
223  } else {
224  // split straight between the next two points
225  return geom.positionAtOffset(geom.nearest_offset_to_point2D(clickPos));
226  }
227 }
228 
229 
230 Position
231 GNEEdge::moveGeometry(const Position& oldPos, const Position& newPos, bool relative) {
233  bool changed = changeGeometry(geom, getMicrosimID(), oldPos, newPos, relative);
234  if (changed) {
235  setGeometry(geom, false);
236  return newPos;
237  } else {
238  return oldPos;
239  }
240 }
241 
242 
243 bool
244 GNEEdge::changeGeometry(PositionVector& geom, const std::string& id, const Position& oldPos, const Position& newPos, bool relative, bool moveEndPoints) {
245  if (geom.size() < 2) {
246  throw ProcessError("Invalid geometry size in edge " + id);
247  } else {
248  int index = geom.indexOfClosest(oldPos);
249  const SUMOReal nearestOffset = geom.nearest_offset_to_point2D(oldPos, true);
250  if (nearestOffset != GeomHelper::INVALID_OFFSET
251  && (moveEndPoints || (nearestOffset >= SNAP_RADIUS
252  && nearestOffset <= geom.length2D() - SNAP_RADIUS))) {
253  const Position nearest = geom.positionAtOffset2D(nearestOffset);
254  const SUMOReal distance = geom[index].distanceTo2D(nearest);
255  if (distance < SNAP_RADIUS) { //move existing
256  if (moveEndPoints || (index != 0 && index != (int)geom.size() - 1)) {
257  const bool closed = geom.isClosed();
258  if (relative) {
259  geom[index] = geom[index] + newPos;
260  } else {
261  geom[index] = newPos;
262  }
263  if (closed && moveEndPoints && (index == 0 || index == (int)geom.size() - 1)) {
264  const int otherIndex = (int)geom.size() - 1 - index;
265  geom[otherIndex] = geom[index];
266  }
267  return true;
268  }
269  } else {
270  if (relative) {
271  int index = geom.insertAtClosest(nearest);
272  geom[index] = geom[index] + newPos;
273  return true;
274  } else {
275  geom.insertAtClosest(newPos); // insert new
276  return true;
277  }
278  }
279  }
280  return false;
281  }
282 }
283 
284 
285 void
288  if (geom.size() == 0) {
289  return;
290  }
291  geom.add(delta.x(), delta.y(), delta.z());
292  setGeometry(geom, true);
293 }
294 
295 
296 bool
299  if (geom.size() == 0) {
300  return false;
301  }
302  int index = geom.indexOfClosest(pos);
303  if (geom[index].distanceTo(pos) < SNAP_RADIUS) {
304  geom.erase(geom.begin() + index);
305  setAttribute(SUMO_ATTR_SHAPE, toString(geom), undoList);
306  return true;
307  } else {
308  return false;
309  }
310 }
311 
312 
313 void
315  undoList->p_begin("set endpoint");
317  int index = geom.indexOfClosest(pos);
318  if (geom[index].distanceTo(pos) < SNAP_RADIUS) { // snap to existing geometry
319  pos = geom[index];
320  }
321  Position destPos = getDest()->getNBNode()->getPosition();
322  Position sourcePos = getSource()->getNBNode()->getPosition();
323  if (pos.distanceTo2D(destPos) < pos.distanceTo2D(sourcePos)) {
324  setAttribute(GNE_ATTR_SHAPE_END, toString(pos), undoList);
326  } else {
327  setAttribute(GNE_ATTR_SHAPE_START, toString(pos), undoList);
329  }
330  // possibly existing inner point is no longer needed
331  deleteGeometry(pos, undoList);
332  undoList->p_end();
333 }
334 
335 
336 void
338  Position destPos = getDest()->getNBNode()->getPosition();
339  Position sourcePos = getSource()->getNBNode()->getPosition();
340  if (pos.distanceTo2D(destPos) < pos.distanceTo2D(sourcePos)) {
341  setAttribute(GNE_ATTR_SHAPE_END, toString(destPos), undoList);
343  } else {
344  setAttribute(GNE_ATTR_SHAPE_START, toString(sourcePos), undoList);
346  }
347 }
348 
349 
350 void
352  myNBEdge.setGeometry(geom, inner);
356  myNet->refreshElement(this);
357 }
358 
359 
360 void
362  for (LaneVector::iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
363  (*i)->updateGeometry();
364  }
365 }
366 
367 
368 void
370  undoList->p_begin("copy template");
378  // copy lane attributes as well
379  for (unsigned int i = 0; i < myLanes.size(); i++) {
380  myLanes[i]->setAttribute(SUMO_ATTR_ALLOW, tpl->myLanes[i]->getAttribute(SUMO_ATTR_ALLOW), undoList);
381  myLanes[i]->setAttribute(SUMO_ATTR_DISALLOW, tpl->myLanes[i]->getAttribute(SUMO_ATTR_DISALLOW), undoList);
382  myLanes[i]->setAttribute(SUMO_ATTR_SPEED, tpl->myLanes[i]->getAttribute(SUMO_ATTR_SPEED), undoList);
383  myLanes[i]->setAttribute(SUMO_ATTR_WIDTH, tpl->myLanes[i]->getAttribute(SUMO_ATTR_WIDTH), undoList);
384  myLanes[i]->setAttribute(SUMO_ATTR_ENDOFFSET, tpl->myLanes[i]->getAttribute(SUMO_ATTR_ENDOFFSET), undoList);
385  }
386  undoList->p_end();
387 }
388 
389 
390 std::set<GUIGlID>
392  std::set<GUIGlID> result;
393  for (size_t i = 0; i < myLanes.size(); i++) {
394  result.insert(myLanes[i]->getGlID());
395  }
396  return result;
397 }
398 
399 
400 std::string
402  switch (key) {
403  case SUMO_ATTR_ID:
404  return getMicrosimID();
405  case SUMO_ATTR_FROM:
406  return getSource()->getMicrosimID();
407  case SUMO_ATTR_TO:
408  return getDest()->getMicrosimID();
409  case SUMO_ATTR_NUMLANES:
410  return toString(myNBEdge.getNumLanes());
411  case SUMO_ATTR_PRIORITY:
412  return toString(myNBEdge.getPriority());
413  case SUMO_ATTR_LENGTH:
414  return toString(myNBEdge.getFinalLength());
415  case SUMO_ATTR_TYPE:
416  return myNBEdge.getTypeID();
417  case SUMO_ATTR_SHAPE:
421  case SUMO_ATTR_NAME:
422  return myNBEdge.getStreetName();
423  case SUMO_ATTR_ALLOW:
424  // return all allowed classes (may differ from the written attributes)
426  (myNBEdge.hasLaneSpecificPermissions() ? " (combined!)" : ""));
427  case SUMO_ATTR_DISALLOW: {
428  // return classes disallowed on at least one lane (may differ from the written attributes)
429  SVCPermissions combinedDissallowed = 0;
430  for (int i = 0; i < (int)myNBEdge.getNumLanes(); ++i) {
431  combinedDissallowed |= ~myNBEdge.getPermissions(i);
432  }
433  return (getVehicleClassNames(combinedDissallowed) +
434  (myNBEdge.hasLaneSpecificPermissions() ? " (combined!)" : ""));
435  }
436  case SUMO_ATTR_SPEED:
438  return "lane specific";
439  } else {
440  return toString(myNBEdge.getSpeed());
441  }
442  case SUMO_ATTR_WIDTH:
444  return "lane specific";
445  } else {
446  return toString(myNBEdge.getLaneWidth());
447  }
448  case SUMO_ATTR_ENDOFFSET:
450  return "lane specific";
451  } else {
452  return toString(myNBEdge.getEndOffset());
453  }
455  return myConnectionStatus;
457  return toString(myNBEdge.getGeometry()[0]);
458  case GNE_ATTR_SHAPE_END:
459  return toString(myNBEdge.getGeometry()[-1]);
460  default:
461  throw InvalidArgument("edge attribute '" + toString(key) + "' not allowed");
462  }
463 }
464 
465 
466 void
467 GNEEdge::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
468  switch (key) {
469  case SUMO_ATTR_WIDTH:
470  case SUMO_ATTR_ENDOFFSET:
471  case SUMO_ATTR_SPEED:
472  case SUMO_ATTR_ALLOW:
473  case SUMO_ATTR_DISALLOW: {
474  undoList->p_begin("change edge attribute");
475  const std::string origValue = getAttribute(key); // will have intermediate value of "lane specific"
476  // lane specific attributes need to be changed via lanes to allow undo
477  for (LaneVector::iterator it = myLanes.begin(); it != myLanes.end(); it++) {
478  (*it)->setAttribute(key, value, undoList);
479  }
480  // ensure that the edge value is also changed. Actually this sets the lane attributes again but it does not matter
481  undoList->p_add(new GNEChange_Attribute(this, key, value, true, origValue));
482  undoList->p_end();
483  break;
484  }
485  case SUMO_ATTR_FROM: {
486  undoList->p_begin("change edge attribute");
487  undoList->p_add(new GNEChange_Attribute(this, key, value));
488  getSource()->setLogicValid(false, undoList);
489  myNet->retrieveJunction(value)->setLogicValid(false, undoList);
490  setAttribute(GNE_ATTR_SHAPE_START, toString(getSource()->getNBNode()->getPosition()), undoList);
492  undoList->p_end();
493  break;
494  }
495  case SUMO_ATTR_TO: {
496  undoList->p_begin("change edge attribute");
497  undoList->p_add(new GNEChange_Attribute(this, key, value));
498  getDest()->setLogicValid(false, undoList);
499  myNet->retrieveJunction(value)->setLogicValid(false, undoList);
500  setAttribute(GNE_ATTR_SHAPE_END, toString(getDest()->getNBNode()->getPosition()), undoList);
502  undoList->p_end();
503  break;
504  }
505  case SUMO_ATTR_ID:
506  case SUMO_ATTR_PRIORITY:
507  case SUMO_ATTR_LENGTH:
508  case SUMO_ATTR_TYPE:
512  case GNE_ATTR_SHAPE_END:
513  undoList->p_add(new GNEChange_Attribute(this, key, value));
514  break;
515  case SUMO_ATTR_NAME:
516  // user cares about street names. Make sure they appear in the output
518  OptionsCont::getOptions().set("output.street-names", "true");
519  undoList->p_add(new GNEChange_Attribute(this, key, value));
520  break;
521  case SUMO_ATTR_NUMLANES:
522  if (value != getAttribute(key)) {
523  setNumLanes((unsigned int)parse<int>(value), undoList);
524  }
525  break;
526  case SUMO_ATTR_SHAPE:
527  // @note: assumes value of inner geometry!
528  // actually the geometry is already updated (incrementally
529  // during mouse movement). We set the restore point to the end
530  // of the last change-set
532  undoList->p_add(new GNEChange_Attribute(this, key, value));
533  break;
534  default:
535  throw InvalidArgument("edge attribute '" + toString(key) + "' not allowed");
536  }
537 }
538 
539 
540 bool
541 GNEEdge::isValid(SumoXMLAttr key, const std::string& value) {
542  switch (key) {
543  case SUMO_ATTR_ID:
544  return isValidID(value) && myNet->retrieveEdge(value, false) == 0;
545  break;
546  case SUMO_ATTR_FROM:
547  return isValidID(value) && myNet->retrieveJunction(value, false) != 0 && value != getDest()->getMicrosimID();
548  break;
549  case SUMO_ATTR_TO:
550  return isValidID(value) && myNet->retrieveJunction(value, false) != 0 && value != getSource()->getMicrosimID();
551  break;
552  case SUMO_ATTR_SPEED:
553  return isPositive<SUMOReal>(value);
554  break;
555  case SUMO_ATTR_NUMLANES:
556  return isPositive<int>(value);
557  break;
558  case SUMO_ATTR_PRIORITY:
559  return canParse<int>(value);
560  break;
561  case SUMO_ATTR_LENGTH:
562  return isPositive<SUMOReal>(value) || parse<SUMOReal>(value) == NBEdge::UNSPECIFIED_LOADED_LENGTH;
563  break;
564  case SUMO_ATTR_ALLOW:
565  case SUMO_ATTR_DISALLOW:
566  return canParseVehicleClasses(value);
567  break;
568  case SUMO_ATTR_TYPE:
569  return true;
570  break;
571  case SUMO_ATTR_SHAPE: {
572  bool ok = true;
574  value, "user-supplied position", 0, ok, true);
575  return ok;
576  break;
577  }
580  break;
581  case SUMO_ATTR_NAME:
582  return true;
583  break;
584  case SUMO_ATTR_WIDTH:
585  return isPositive<SUMOReal>(value) || parse<SUMOReal>(value) == NBEdge::UNSPECIFIED_WIDTH;
586  break;
587  case SUMO_ATTR_ENDOFFSET:
588  return canParse<SUMOReal>(value);
589  break;
590  default:
591  throw InvalidArgument("edge attribute '" + toString(key) + "' not allowed");
592  }
593 }
594 
595 
596 // ===========================================================================
597 // private
598 // ===========================================================================
599 void
600 GNEEdge::setAttribute(SumoXMLAttr key, const std::string& value) {
601  switch (key) {
602  case SUMO_ATTR_ID:
603  myNet->renameEdge(this, value);
604  break;
605  case SUMO_ATTR_FROM:
606  myNet->changeEdgeEndpoints(this, value, getDest()->getMicrosimID());
607  break;
608  case SUMO_ATTR_TO:
609  myNet->changeEdgeEndpoints(this, getSource()->getMicrosimID(), value);
610  break;
611  case SUMO_ATTR_NUMLANES:
612  throw InvalidArgument("GNEEdge::setAttribute (private) called for attr SUMO_ATTR_NUMLANES. This should never happen");
613  break;
614  case SUMO_ATTR_PRIORITY:
615  myNBEdge.myPriority = parse<int>(value);
616  break;
617  case SUMO_ATTR_LENGTH:
618  myNBEdge.setLoadedLength(parse<SUMOReal>(value));
619  break;
620  case SUMO_ATTR_TYPE:
621  myNBEdge.myType = value;
622  break;
623  case SUMO_ATTR_SHAPE:
624  bool ok;
625  myOrigShape = GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, true);
626  setGeometry(myOrigShape, true);
627  break;
630  break;
631  case SUMO_ATTR_NAME:
632  myNBEdge.setStreetName(value);
633  break;
634  case SUMO_ATTR_SPEED:
635  myNBEdge.setSpeed(-1, parse<SUMOReal>(value));
636  break;
637  case SUMO_ATTR_WIDTH:
638  myNBEdge.setLaneWidth(-1, parse<SUMOReal>(value));
639  break;
640  case SUMO_ATTR_ENDOFFSET:
641  myNBEdge.setEndOffset(-1, parse<SUMOReal>(value));
642  break;
643  case SUMO_ATTR_ALLOW:
644  break; // no edge value
645  case SUMO_ATTR_DISALLOW:
646  break; // no edge value
648  myConnectionStatus = value;
649  if (value == GUESSED) {
651  } else if (value == MODIFIED) {
653  }
654  break;
655  case GNE_ATTR_SHAPE_START: {
657  geom[0] = GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, false)[0];
658  setGeometry(geom, false);
659  break;
660  }
661  case GNE_ATTR_SHAPE_END: {
663  geom[-1] = GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, false)[0];
664  setGeometry(geom, false);
665  break;
666  }
667  default:
668  throw InvalidArgument("edge attribute '" + toString(key) + "' not allowed");
669  }
670 }
671 
672 
673 void
674 GNEEdge::setNumLanes(unsigned int numLanes, GNEUndoList* undoList) {
675  undoList->p_begin("change number of lanes");
676  getSource()->setLogicValid(false, undoList);
677  getDest()->setLogicValid(false, undoList);
678 
679  const unsigned int oldNumLanes = (unsigned int)myLanes.size();
680  for (unsigned int i = oldNumLanes; i < numLanes; i++) {
681  // since the GNELane does not exist yet, it cannot have yet been referenced so we only pass a zero-pointer
682  undoList->add(new GNEChange_Lane(this, 0,
683  myNBEdge.getLaneStruct(oldNumLanes - 1), true), true);
684  }
685  for (unsigned int i = oldNumLanes - 1; i > numLanes - 1; i--) {
686  // delete leftmost lane
687  undoList->add(new GNEChange_Lane(this, myLanes[i], myNBEdge.getLaneStruct(i), false), true);
688  }
689  undoList->p_end();
690 }
691 
692 
693 void
694 GNEEdge::addLane(GNELane* lane, const NBEdge::Lane& laneAttrs) {
695  const int index = lane ? lane->getIndex() : myNBEdge.getNumLanes();
696  // the laneStruct must be created first to ensure we have some geometry
697  myNBEdge.addLane(index);
698  if (lane) {
699  // restore a previously deleted lane
700  myLanes.insert(myLanes.begin() + index, lane);
701 
702  } else {
703  // create a new lane by copying leftmost lane
704  lane = new GNELane(*this, index);
705  myLanes.push_back(lane);
706  }
707  lane->incRef("GNEEdge::addLane");
708  // we copy all attributes except shape since this is recomputed from edge shape
709  myNBEdge.setSpeed(lane->getIndex(), laneAttrs.speed);
710  myNBEdge.setPermissions(laneAttrs.permissions, lane->getIndex());
712  myNBEdge.setEndOffset(lane->getIndex(), laneAttrs.endOffset);
713  myNBEdge.setLaneWidth(lane->getIndex(), laneAttrs.width);
714  // udate indices
715  for (int i = 0; i < (int)myLanes.size(); ++i) {
716  myLanes[i]->setIndex(i);
717  }
718  /* while technically correct, this looks ugly
719  getSource()->invalidateShape();
720  getDest()->invalidateShape();
721  */
722  myNet->refreshElement(this);
723 }
724 
725 
726 void
728  if (lane == 0) {
729  lane = myLanes.back();
730  }
731  myNBEdge.deleteLane(lane->getIndex());
732  lane->decRef("GNEEdge::removeLane");
733  myLanes.erase(myLanes.begin() + lane->getIndex());
734  if (myLanes.back()->unreferenced()) {
735  delete lane;
736  }
737  // udate indices
738  for (int i = 0; i < (int)myLanes.size(); ++i) {
739  myLanes[i]->setIndex(i);
740  }
741  /* while technically correct, this looks ugly
742  getSource()->invalidateShape();
743  getDest()->invalidateShape();
744  */
745 
746  myNet->refreshElement(this);
747 }
748 
749 
750 void
751 GNEEdge::addConnection(unsigned int fromLane, const std::string& toEdgeID, unsigned int toLane, bool mayPass) {
752  NBEdge* destEdge = myNet->retrieveEdge(toEdgeID)->getNBEdge();
753  myNBEdge.setConnection(fromLane, destEdge, toLane, NBEdge::L2L_USER, true, mayPass);
754  myNet->refreshElement(this); // actually we only do this to force a redraw
755 }
756 
757 
758 void
759 GNEEdge::removeConnection(unsigned int fromLane, const std::string& toEdgeID, unsigned int toLane) {
760  NBEdge* destEdge = myNet->retrieveEdge(toEdgeID)->getNBEdge();
761  if (destEdge == myNBEdge.getTurnDestination()) {
763  }
764  myNBEdge.removeFromConnections(destEdge, fromLane, toLane);
765  myNet->refreshElement(this); // actually we only do this to force a redraw
766 }
767 
768 
769 void
770 GNEEdge::setMicrosimID(const std::string& newID) {
772  for (LaneVector::iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
773  (*i)->setMicrosimID(getNBEdge()->getLaneID((*i)->getIndex()));
774  }
775 }
776 
777 
778 /****************************************************************************/
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:694
void copyTemplate(GNEEdge *tpl, GNEUndoList *undolist)
copy edge attributes from tpl
Definition: GNEEdge.cpp:369
void invalidateConnections(bool reallowSetting=false)
Definition: NBEdge.cpp:949
The information about how to spread the lanes from the given position.
const std::string & getTypeID() const
Definition: NBEdge.h:907
SUMOReal endOffset
This lane&#39;s offset to the intersection begin.
Definition: NBEdge.h:136
GNEEdge * retrieveEdge(const std::string &id, bool failHard=true)
get edge by id
Definition: GNENet.cpp:541
static const SUMOReal UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:201
GUIVisualizationTextSettings streetName
void resetWritable()
Resets all options to be writeable.
bool myAmResponsible
whether we are responsible for deleting myNBNode
Definition: GNEEdge.h:252
SUMOReal nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
void invalidateShape()
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
std::string myConnectionStatus
modification status of the connections
Definition: GNEEdge.h:258
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:119
void refreshElement(GUIGlObject *o)
refreshes boundary information for o and update
Definition: GNENet.cpp:592
bool hasString(const std::string &str) const
PositionVector myOrigShape
restore point for undo
Definition: GNEEdge.h:243
void setMicrosimID(const std::string &newID)
override to also set lane ids
Definition: GNEEdge.cpp:770
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
bool hasLaneSpecificEndOffset() const
whether lanes differ in offset
Definition: NBEdge.cpp:1465
void setLaneWidth(int lane, SUMOReal width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2294
std::set< GUIGlID > getLaneGlIDs()
Definition: GNEEdge.cpp:391
void setSpeed(int lane, SUMOReal speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2349
void setLogicValid(bool valid, GNEUndoList *undoList=0, const std::string &status=GUESSED)
Stores the information about how to visualize structures.
int SVCPermissions
The representation of a single edge during network building.
Definition: NBEdge.h:70
void declareConnectionsAsLoaded()
Definition: NBEdge.h:1078
Position moveGeometry(const Position &oldPos, const Position &newPos, bool relative=false)
change the edge geometry without registering undo/redo It is up to the Edge to decide whether an new ...
Definition: GNEEdge.cpp:231
const std::vector< T > & getSchemes() const
void setStreetName(const std::string &name)
sets the street name of this edge
Definition: NBEdge.h:471
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
Definition: GUIGlObject.h:167
std::string getAttribute(SumoXMLAttr key) const
Definition: GNEEdge.cpp:401
SUMOReal getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:449
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:77
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:2365
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:56
void p_begin(const std::string &description)
Definition: GNEUndoList.cpp:75
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
static void drawText(const std::string &text, const Position &pos, const SUMOReal layer, const SUMOReal size, const RGBColor &col=RGBColor::BLACK, const SUMOReal angle=0)
draw Text with given parameters
Definition: GLHelper.cpp:460
bool setConnection(unsigned int lane, NBEdge *destEdge, unsigned int destLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true, SUMOReal contPos=UNSPECIFIED_CONTPOS)
Adds a connection to a certain lane of a certain edge.
Definition: NBEdge.cpp:724
unsigned int getIndex() const
Definition: GNELane.h:139
bool isClosed() const
~GNEEdge()
Destructor.
Definition: GNEEdge.cpp:84
SUMOReal x() const
Returns the x-position.
Definition: Position.h:63
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.
Position positionAtOffset2D(SUMOReal pos, SUMOReal lateralOffset=0) const
Returns the position at the given length.
void addConnection(unsigned int fromLane, const std::string &toEdgeID, unsigned int toLane, bool mayPass)
adds a connection
Definition: GNEEdge.cpp:751
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge&#39;s geometry
Definition: NBEdge.cpp:436
GUIGlID getGlID() const
Returns the numerical id of the object.
Definition: GUIGlObject.h:123
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
SUMOReal scale
information about a lane&#39;s width (temporary, used for a single view)
virtual GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
Definition: GNEEdge.cpp:194
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNEEdge.cpp:141
SUMOReal speed
The speed allowed on this lane.
Definition: NBEdge.h:130
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
GUIVisualizationTextSettings edgeName
static void drawFilledCircle(SUMOReal width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:344
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:65
SUMOReal length2D() const
Returns the length.
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:132
GNENet * myNet
Definition: GNEEdge.h:249
static const std::string MODIFIED
feature has been manually modified (implies approval)
const PositionVector getInnerGeometry() const
Returns the geometry of the edge without the endpoints.
Definition: NBEdge.cpp:417
const Position & getPosition() const
Returns the position of this node.
Definition: NBNode.h:228
bool hasLaneSpecificSpeed() const
whether lanes differ in speed
Definition: NBEdge.cpp:1454
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:353
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:443
SVCPermissions preferred
List of vehicle types that are preferred on this lane.
Definition: NBEdge.h:134
void p_end()
Definition: GNEUndoList.cpp:82
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:529
A list of positions.
void add(SUMOReal xoff, SUMOReal yoff, SUMOReal zoff)
int indexOfClosest(const Position &p) const
bool hasLaneSpecificPermissions() const
whether lanes differ in allowed vehicle classes
Definition: NBEdge.cpp:1429
friend class GNEChange_Attribute
Boundary getBoundary() const
Returns the street&#39;s geometry.
Definition: GNEEdge.cpp:98
unsigned int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:345
SUMOReal z() const
Returns the z-position.
Definition: Position.h:73
Position positionAtOffset(SUMOReal pos, SUMOReal lateralOffset=0) const
Returns the position at the given length.
int myPriority
The priority of the edge.
Definition: NBEdge.h:1277
NBNode * getNBNode()
returns the internal NBNode
Definition: GNEJunction.h:153
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNEEdge.cpp:121
GUIColorer junctionColorer
The junction colorer.
int insertAtClosest(const Position &p)
void drawName(const Position &pos, const SUMOReal scale, const GUIVisualizationTextSettings &settings, const SUMOReal angle=0) const
void setLoadedLength(SUMOReal val)
Definition: NBEdge.cpp:2408
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:54
void incRef(const std::string &debugMsg="")
The connection was given by the user.
Definition: NBEdge.h:113
void removeFromConnections(NBEdge *toEdge, int fromLane=-1, int toLane=-1, bool tryLater=false)
Removes the specified connection(s)
Definition: NBEdge.cpp:922
std::string getVehicleClassNames(SVCPermissions permissions)
Returns the ids of the given classes, divided using a &#39; &#39;.
void removeLane(GNELane *lane)
Definition: GNEEdge.cpp:727
SUMOReal getEndOffset() const
Returns the offset to the destination node.
Definition: NBEdge.h:478
virtual GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition: GNEEdge.cpp:109
void decRef(const std::string &debugMsg="")
void setGeometry(PositionVector geom, bool inner)
update edge geometry and inform the lanes
Definition: GNEEdge.cpp:351
GNEEdge(NBEdge &nbe, GNENet *net, bool wasSplit=false, bool loaded=false)
Constructor.
Definition: GNEEdge.cpp:65
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.h:132
bool canParseVehicleClasses(const std::string &classes)
Checks whether the given string contains only known vehicle classes.
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:61
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:2393
SUMOReal length() const
Returns the length.
SUMOReal rotationDegreeAtOffset(SUMOReal pos) const
Returns the rotation at the given length.
void add(SUMOReal x, SUMOReal y)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:76
Boundary & grow(SUMOReal by)
extends the boundary by the given amount
Definition: Boundary.cpp:201
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:369
const PositionVector & getShape() const
Definition: GNELane.cpp:427
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:297
virtual void setMicrosimID(const std::string &newID)
Changes the microsimID of the object (happens in NETEDIT)
static const SUMOReal UNSPECIFIED_LOADED_LENGTH
no length override given
Definition: NBEdge.h:210
void deleteLane(unsigned int index, bool recompute=true)
Definition: NBEdge.cpp:2221
void setPreferredVehicleClass(SVCPermissions permissions, int lane=-1)
Definition: NBEdge.cpp:2379
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:523
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
void updateJunctionPosition(GNEJunction *junction, const Position &origPos)
update edge geometry after junction move
Definition: GNEEdge.cpp:203
The popup menu of a globject.
an edge
static const SUMOReal SNAP_RADIUS
Definition: GNEEdge.h:236
void mul(SUMOReal val)
Multiplies both positions with the given value.
Definition: Position.h:99
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:1263
GNEJunction * getDest() const
returns the destination-junction
Definition: GNEEdge.cpp:135
void renameEdge(GNEEdge *edge, const std::string &newID)
updates the map and reserves new id
Definition: GNENet.cpp:816
bool isValid(SumoXMLAttr key, const std::string &value)
Definition: GNEEdge.cpp:541
void updateLaneGeometries()
update edge geometry and inform the lanes let the lanes recompute their precomputed geometry informat...
Definition: GNEEdge.cpp:361
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge&#39;s lanes&#39; lateral offset is computed.
Definition: NBEdge.h:603
void removeExplicitTurnaround(std::string id)
remove edge id from the list of explicit turnarounds
Definition: GNENet.cpp:850
LaneVector myLanes
List of this edges lanes.
Definition: GNEEdge.h:246
Lane & getLaneStruct(unsigned int lane)
Definition: NBEdge.h:1067
SUMOReal distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:232
bool hasLaneSpecificWidth() const
whether lanes differ in width
Definition: NBEdge.cpp:1443
void setEndOffset(int lane, SUMOReal offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2333
#define SUMOReal
Definition: config.h:213
static const std::string GUESSED
feature has been reguessed (may still be unchanged be we can&#39;t tell (yet)
void setEndpoint(Position pos, GNEUndoList *undoList)
makes pos the new geometry endpoint at the appropriate end
Definition: GNEEdge.cpp:314
empty max
NBEdge & myNBEdge
the underlying NBEdge
Definition: GNEEdge.h:240
SUMOReal getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:431
SUMOReal getFinalLength() const
length that will be assigned to the lanes in the final network
Definition: NBEdge.cpp:2560
const SUMOReal SUMO_const_halfLaneWidth
Definition: StdDefs.h:50
void setLaneSpreadFunction(LaneSpreadFunction spread)
(Re)sets how the lanes lateral offset shall be computed
Definition: NBEdge.cpp:547
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition: GNEEdge.cpp:467
const std::string & getStreetName() const
Returns the street name of this edge.
Definition: NBEdge.h:465
void addLane(unsigned int index, bool recompute=true)
Definition: NBEdge.cpp:2186
void resetEndpoint(const Position &pos, GNEUndoList *undoList)
restores the endpoint to the junction position at the appropriate end
Definition: GNEEdge.cpp:337
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:825
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition: NBEdge.cpp:2157
GNEJunction * getSource() const
returns the source-junction
Definition: GNEEdge.cpp:129
Position getSplitPos(const Position &clickPos)
Definition: GNEEdge.cpp:217
friend class GNEChange_Lane
Definition: GNEEdge.h:63
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:244
SUMOReal width
This lane&#39;s width.
Definition: NBEdge.h:138
static const SUMOReal INVALID_OFFSET
a value to signify offsets outside the range of [0, Line.length()]
Definition: GeomHelper.h:59
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
void setNumLanes(unsigned int numLanes, GNEUndoList *undoList)
changes the number of lanes. When reducing the number of lanes, higher-numbered lanes are removed fir...
Definition: GNEEdge.cpp:674
a junction
void removeConnection(unsigned int fromLane, const std::string &toEdgeID, unsigned int toLane)
removes a connection
Definition: GNEEdge.cpp:759
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:361