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 #include "GNEAdditional.h"
51 #include "GNEAdditionalSet.h"
52 
53 #ifdef CHECK_MEMORY_LEAKS
54 #include <foreign/nvwa/debug_new.h>
55 #endif // CHECK_MEMORY_LEAKS
56 
57 
58 
59 // ===========================================================================
60 // static
61 // ===========================================================================
63 
64 // ===========================================================================
65 // members methods
66 // ===========================================================================
67 GNEEdge::GNEEdge(NBEdge& nbe, GNENet* net, bool wasSplit, bool loaded):
68  GNENetElement(net, nbe.getID(), GLO_EDGE, SUMO_TAG_EDGE),
69  myNBEdge(nbe) ,
70  myOrigShape(nbe.getInnerGeometry()),
71  myLanes(0),
72  myAmResponsible(false),
73  myWasSplit(wasSplit),
74  myConnectionStatus(loaded ? LOADED : GUESSED) {
75  // Create lanes
76  int numLanes = myNBEdge.getNumLanes();
77  myLanes.reserve(numLanes);
78  for (int i = 0; i < numLanes; i++) {
79  myLanes.push_back(new GNELane(*this, i));
80  myLanes.back()->incRef("GNEEdge::GNEEdge");
81  }
82 }
83 
84 
86  for (LaneVector::iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
87  (*i)->decRef("GNEEdge::~GNEEdge");
88  if ((*i)->unreferenced()) {
89  delete *i;
90  }
91  }
92  if (myAmResponsible) {
93  delete &myNBEdge;
94  }
95  // Remove all references to this edge in their additionals
96  for (AdditionalVector::iterator i = myAdditionals.begin(); i != myAdditionals.end(); i++) {
97  (*i)->removeEdgeReference();
98  }
99 }
100 
101 
102 void
104 
105 
106 Boundary
108  Boundary ret;
109  for (LaneVector::const_iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
110  ret.add((*i)->getBoundary());
111  }
112  ret.grow(10); // !!! magic value
113  return ret;
114 }
115 
116 
119  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
120  buildPopupHeader(ret, app);
124  buildPositionCopyEntry(ret, false);
125  return ret;
126 }
127 
128 
129 Boundary
131  Boundary b = getBoundary();
132  b.grow(20);
133  return b;
134 }
135 
136 
140 }
141 
142 
146 }
147 
148 
149 void
151  /* do something different for connectors?
152  if (myNBEdge.isMacroscopicConnector()) {
153  }
154  */
155 
156  // draw the lanes
157  for (LaneVector::const_iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
158  (*i)->drawGL(s);
159  }
160 
161  // draw geometry hints
162  if (s.scale * SNAP_RADIUS > 1.) { // check whether it is not too small
163  GLHelper::setColor(s.junctionColorer.getSchemes()[0].getColor(2));
164  glPushName(getGlID());
166  for (int i = 1; i < (int)geom.size() - 1; i++) {
167  Position pos = geom[i];
168  glPushMatrix();
169  glTranslated(pos.x(), pos.y(), GLO_JUNCTION - 0.01);
171  glPopMatrix();
172  }
173  glPopName();
174  }
175 
176  // (optionally) draw the name and/or the street name
177  const bool drawStreetName = s.streetName.show && myNBEdge.getStreetName() != "";
178  if (s.edgeName.show || drawStreetName) {
179  glPushName(getGlID());
180  GNELane* lane1 = myLanes[0];
181  GNELane* lane2 = myLanes[myLanes.size() - 1];
182  Position p = lane1->getShape().positionAtOffset(lane1->getShape().length() / (SUMOReal) 2.);
183  p.add(lane2->getShape().positionAtOffset(lane2->getShape().length() / (SUMOReal) 2.));
184  p.mul(.5);
185  SUMOReal angle = lane1->getShape().rotationDegreeAtOffset(lane1->getShape().length() / (SUMOReal) 2.);
186  angle += 90;
187  if (angle > 90 && angle < 270) {
188  angle -= 180;
189  }
190  if (s.edgeName.show) {
191  drawName(p, s.scale, s.edgeName, angle);
192  }
193  if (drawStreetName) {
195  s.streetName.size / s.scale, s.streetName.color, angle);
196  }
197  glPopName();
198  }
199 }
200 
201 
205  GUIParameterTableWindow* ret = 0;
206  UNUSED_PARAMETER(&app);
207  return ret;
208 }
209 
210 
211 void
213  Position delta = junction->getNBNode()->getPosition() - origPos;
215  // geometry endpoint need not equal junction position hence we modify it with delta
216  if (junction == getSource()) {
217  geom[0].add(delta);
218  } else {
219  geom[-1].add(delta);
220  }
221  setGeometry(geom, false);
222 }
223 
224 NBEdge*
226  return &myNBEdge;
227 }
228 
229 
230 Position
231 GNEEdge::getSplitPos(const Position& clickPos) {
232  const PositionVector& geom = myNBEdge.getGeometry();
233  int index = geom.indexOfClosest(clickPos);
234  if (geom[index].distanceTo(clickPos) < SNAP_RADIUS) {
235  // split at existing geometry point
236  return geom[index];
237  } else {
238  // split straight between the next two points
239  return geom.positionAtOffset(geom.nearest_offset_to_point2D(clickPos));
240  }
241 }
242 
243 
244 Position
245 GNEEdge::moveGeometry(const Position& oldPos, const Position& newPos, bool relative) {
247  bool changed = changeGeometry(geom, getMicrosimID(), oldPos, newPos, relative);
248  if (changed) {
249  setGeometry(geom, false);
250  return newPos;
251  } else {
252  return oldPos;
253  }
254 }
255 
256 
257 bool
258 GNEEdge::changeGeometry(PositionVector& geom, const std::string& id, const Position& oldPos, const Position& newPos, bool relative, bool moveEndPoints) {
259  if (geom.size() < 2) {
260  throw ProcessError("Invalid geometry size in edge " + id);
261  } else {
262  int index = geom.indexOfClosest(oldPos);
263  const SUMOReal nearestOffset = geom.nearest_offset_to_point2D(oldPos, true);
264  if (nearestOffset != GeomHelper::INVALID_OFFSET
265  && (moveEndPoints || (nearestOffset >= SNAP_RADIUS
266  && nearestOffset <= geom.length2D() - SNAP_RADIUS))) {
267  const Position nearest = geom.positionAtOffset2D(nearestOffset);
268  const SUMOReal distance = geom[index].distanceTo2D(nearest);
269  if (distance < SNAP_RADIUS) { //move existing
270  if (moveEndPoints || (index != 0 && index != (int)geom.size() - 1)) {
271  const bool closed = geom.isClosed();
272  if (relative) {
273  geom[index] = geom[index] + newPos;
274  } else {
275  geom[index] = newPos;
276  }
277  if (closed && moveEndPoints && (index == 0 || index == (int)geom.size() - 1)) {
278  const int otherIndex = (int)geom.size() - 1 - index;
279  geom[otherIndex] = geom[index];
280  }
281  return true;
282  }
283  } else {
284  if (relative) {
285  int index = geom.insertAtClosest(nearest);
286  geom[index] = geom[index] + newPos;
287  return true;
288  } else {
289  geom.insertAtClosest(newPos); // insert new
290  return true;
291  }
292  }
293  }
294  return false;
295  }
296 }
297 
298 
299 void
302  if (geom.size() == 0) {
303  return;
304  }
305  geom.add(delta.x(), delta.y(), delta.z());
306  setGeometry(geom, true);
307 }
308 
309 
310 bool
313  if (geom.size() == 0) {
314  return false;
315  }
316  int index = geom.indexOfClosest(pos);
317  if (geom[index].distanceTo(pos) < SNAP_RADIUS) {
318  geom.erase(geom.begin() + index);
319  setAttribute(SUMO_ATTR_SHAPE, toString(geom), undoList);
320  return true;
321  } else {
322  return false;
323  }
324 }
325 
326 
327 void
329  undoList->p_begin("set endpoint");
331  int index = geom.indexOfClosest(pos);
332  if (geom[index].distanceTo(pos) < SNAP_RADIUS) { // snap to existing geometry
333  pos = geom[index];
334  }
335  Position destPos = getDest()->getNBNode()->getPosition();
336  Position sourcePos = getSource()->getNBNode()->getPosition();
337  if (pos.distanceTo2D(destPos) < pos.distanceTo2D(sourcePos)) {
338  setAttribute(GNE_ATTR_SHAPE_END, toString(pos), undoList);
340  } else {
341  setAttribute(GNE_ATTR_SHAPE_START, toString(pos), undoList);
343  }
344  // possibly existing inner point is no longer needed
345  deleteGeometry(pos, undoList);
346  undoList->p_end();
347 }
348 
349 
350 void
352  Position destPos = getDest()->getNBNode()->getPosition();
353  Position sourcePos = getSource()->getNBNode()->getPosition();
354  if (pos.distanceTo2D(destPos) < pos.distanceTo2D(sourcePos)) {
355  setAttribute(GNE_ATTR_SHAPE_END, toString(destPos), undoList);
357  } else {
358  setAttribute(GNE_ATTR_SHAPE_START, toString(sourcePos), undoList);
360  }
361 }
362 
363 
364 void
366  myNBEdge.setGeometry(geom, inner);
370  myNet->refreshElement(this);
371 }
372 
373 
374 void
376  // Update geometry of lanes
377  for (LaneVector::iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
378  (*i)->updateGeometry();
379  }
380  // Update geometry of additionals vinculated to this edge
381  for (AdditionalVector::iterator i = myAdditionals.begin(); i != myAdditionals.end(); ++i) {
382  (*i)->updateGeometry();
383  }
384  // Update geometry of additionalSets vinculated to this edge
385  for (AdditionalSetVector::iterator i = myAdditionalSets.begin(); i != myAdditionalSets.end(); ++i) {
386  (*i)->updateGeometry();
387  }
388 }
389 
390 
391 void
393  undoList->p_begin("copy template");
401  // copy lane attributes as well
402  for (unsigned int i = 0; i < myLanes.size(); i++) {
403  myLanes[i]->setAttribute(SUMO_ATTR_ALLOW, tpl->myLanes[i]->getAttribute(SUMO_ATTR_ALLOW), undoList);
404  myLanes[i]->setAttribute(SUMO_ATTR_DISALLOW, tpl->myLanes[i]->getAttribute(SUMO_ATTR_DISALLOW), undoList);
405  myLanes[i]->setAttribute(SUMO_ATTR_SPEED, tpl->myLanes[i]->getAttribute(SUMO_ATTR_SPEED), undoList);
406  myLanes[i]->setAttribute(SUMO_ATTR_WIDTH, tpl->myLanes[i]->getAttribute(SUMO_ATTR_WIDTH), undoList);
407  myLanes[i]->setAttribute(SUMO_ATTR_ENDOFFSET, tpl->myLanes[i]->getAttribute(SUMO_ATTR_ENDOFFSET), undoList);
408  }
409  undoList->p_end();
410 }
411 
412 
413 std::set<GUIGlID>
415  std::set<GUIGlID> result;
416  for (size_t i = 0; i < myLanes.size(); i++) {
417  result.insert(myLanes[i]->getGlID());
418  }
419  return result;
420 }
421 
422 
423 const std::vector<GNELane*>&
425  return myLanes;
426 }
427 
428 
429 bool
431  return myWasSplit;
432 }
433 
434 
435 std::string
437  switch (key) {
438  case SUMO_ATTR_ID:
439  return getMicrosimID();
440  case SUMO_ATTR_FROM:
441  return getSource()->getMicrosimID();
442  case SUMO_ATTR_TO:
443  return getDest()->getMicrosimID();
444  case SUMO_ATTR_NUMLANES:
445  return toString(myNBEdge.getNumLanes());
446  case SUMO_ATTR_PRIORITY:
447  return toString(myNBEdge.getPriority());
448  case SUMO_ATTR_LENGTH:
449  return toString(myNBEdge.getFinalLength());
450  case SUMO_ATTR_TYPE:
451  return myNBEdge.getTypeID();
452  case SUMO_ATTR_SHAPE:
456  case SUMO_ATTR_NAME:
457  return myNBEdge.getStreetName();
458  case SUMO_ATTR_ALLOW:
459  // return all allowed classes (may differ from the written attributes)
461  (myNBEdge.hasLaneSpecificPermissions() ? " (combined!)" : ""));
462  case SUMO_ATTR_DISALLOW: {
463  // return classes disallowed on at least one lane (may differ from the written attributes)
464  SVCPermissions combinedDissallowed = 0;
465  for (int i = 0; i < (int)myNBEdge.getNumLanes(); ++i) {
466  combinedDissallowed |= ~myNBEdge.getPermissions(i);
467  }
468  return (getVehicleClassNames(combinedDissallowed) +
469  (myNBEdge.hasLaneSpecificPermissions() ? " (combined!)" : ""));
470  }
471  case SUMO_ATTR_SPEED:
473  return "lane specific";
474  } else {
475  return toString(myNBEdge.getSpeed());
476  }
477  case SUMO_ATTR_WIDTH:
479  return "lane specific";
480  } else {
481  return toString(myNBEdge.getLaneWidth());
482  }
483  case SUMO_ATTR_ENDOFFSET:
485  return "lane specific";
486  } else {
487  return toString(myNBEdge.getEndOffset());
488  }
490  return myConnectionStatus;
492  return toString(myNBEdge.getGeometry()[0]);
493  case GNE_ATTR_SHAPE_END:
494  return toString(myNBEdge.getGeometry()[-1]);
495  default:
496  throw InvalidArgument("edge attribute '" + toString(key) + "' not allowed");
497  }
498 }
499 
500 
501 void
502 GNEEdge::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
503  switch (key) {
504  case SUMO_ATTR_WIDTH:
505  case SUMO_ATTR_ENDOFFSET:
506  case SUMO_ATTR_SPEED:
507  case SUMO_ATTR_ALLOW:
508  case SUMO_ATTR_DISALLOW: {
509  undoList->p_begin("change edge attribute");
510  const std::string origValue = getAttribute(key); // will have intermediate value of "lane specific"
511  // lane specific attributes need to be changed via lanes to allow undo
512  for (LaneVector::iterator it = myLanes.begin(); it != myLanes.end(); it++) {
513  (*it)->setAttribute(key, value, undoList);
514  }
515  // ensure that the edge value is also changed. Actually this sets the lane attributes again but it does not matter
516  undoList->p_add(new GNEChange_Attribute(this, key, value, true, origValue));
517  undoList->p_end();
518  break;
519  }
520  case SUMO_ATTR_FROM: {
521  undoList->p_begin("change edge attribute");
522  undoList->p_add(new GNEChange_Attribute(this, key, value));
523  getSource()->setLogicValid(false, undoList);
524  myNet->retrieveJunction(value)->setLogicValid(false, undoList);
525  setAttribute(GNE_ATTR_SHAPE_START, toString(getSource()->getNBNode()->getPosition()), undoList);
527  undoList->p_end();
528  break;
529  }
530  case SUMO_ATTR_TO: {
531  undoList->p_begin("change edge attribute");
532  undoList->p_add(new GNEChange_Attribute(this, key, value));
533  getDest()->setLogicValid(false, undoList);
534  myNet->retrieveJunction(value)->setLogicValid(false, undoList);
535  setAttribute(GNE_ATTR_SHAPE_END, toString(getDest()->getNBNode()->getPosition()), undoList);
537  undoList->p_end();
538  break;
539  }
540  case SUMO_ATTR_ID:
541  case SUMO_ATTR_PRIORITY:
542  case SUMO_ATTR_LENGTH:
543  case SUMO_ATTR_TYPE:
547  case GNE_ATTR_SHAPE_END:
548  undoList->p_add(new GNEChange_Attribute(this, key, value));
549  break;
550  case SUMO_ATTR_NAME:
551  // user cares about street names. Make sure they appear in the output
553  OptionsCont::getOptions().set("output.street-names", "true");
554  undoList->p_add(new GNEChange_Attribute(this, key, value));
555  break;
556  case SUMO_ATTR_NUMLANES:
557  if (value != getAttribute(key)) {
558  setNumLanes((unsigned int)parse<int>(value), undoList);
559  }
560  break;
561  case SUMO_ATTR_SHAPE:
562  // @note: assumes value of inner geometry!
563  // actually the geometry is already updated (incrementally
564  // during mouse movement). We set the restore point to the end
565  // of the last change-set
567  undoList->p_add(new GNEChange_Attribute(this, key, value));
568  break;
569  default:
570  throw InvalidArgument("edge attribute '" + toString(key) + "' not allowed");
571  }
572 }
573 
574 
575 bool
576 GNEEdge::isValid(SumoXMLAttr key, const std::string& value) {
577  switch (key) {
578  case SUMO_ATTR_ID:
579  return isValidID(value) && myNet->retrieveEdge(value, false) == 0;
580  break;
581  case SUMO_ATTR_FROM:
582  return isValidID(value) && myNet->retrieveJunction(value, false) != 0 && value != getDest()->getMicrosimID();
583  break;
584  case SUMO_ATTR_TO:
585  return isValidID(value) && myNet->retrieveJunction(value, false) != 0 && value != getSource()->getMicrosimID();
586  break;
587  case SUMO_ATTR_SPEED:
588  return isPositive<SUMOReal>(value);
589  break;
590  case SUMO_ATTR_NUMLANES:
591  return isPositive<int>(value);
592  break;
593  case SUMO_ATTR_PRIORITY:
594  return canParse<int>(value);
595  break;
596  case SUMO_ATTR_LENGTH:
597  return canParse<SUMOReal>(value) && (isPositive<SUMOReal>(value) || parse<SUMOReal>(value) == NBEdge::UNSPECIFIED_LOADED_LENGTH);
598  break;
599  case SUMO_ATTR_ALLOW:
600  case SUMO_ATTR_DISALLOW:
601  return canParseVehicleClasses(value);
602  break;
603  case SUMO_ATTR_TYPE:
604  return true;
605  break;
606  case SUMO_ATTR_SHAPE: {
607  bool ok = true;
609  value, "user-supplied position", 0, ok, true);
610  return ok;
611  break;
612  }
615  break;
616  case SUMO_ATTR_NAME:
617  return true;
618  break;
619  case SUMO_ATTR_WIDTH:
620  return canParse<SUMOReal>(value) && (isPositive<SUMOReal>(value) || parse<SUMOReal>(value) == NBEdge::UNSPECIFIED_WIDTH);
621  break;
622  case SUMO_ATTR_ENDOFFSET:
623  return canParse<SUMOReal>(value);
624  break;
625  default:
626  throw InvalidArgument("edge attribute '" + toString(key) + "' not allowed");
627  }
628 }
629 
630 
631 void
633  myAmResponsible = newVal;
634 }
635 
636 // ===========================================================================
637 // private
638 // ===========================================================================
639 void
640 GNEEdge::setAttribute(SumoXMLAttr key, const std::string& value) {
641  switch (key) {
642  case SUMO_ATTR_ID:
643  myNet->renameEdge(this, value);
644  break;
645  case SUMO_ATTR_FROM:
646  myNet->changeEdgeEndpoints(this, value, getDest()->getMicrosimID());
647  break;
648  case SUMO_ATTR_TO:
649  myNet->changeEdgeEndpoints(this, getSource()->getMicrosimID(), value);
650  break;
651  case SUMO_ATTR_NUMLANES:
652  throw InvalidArgument("GNEEdge::setAttribute (private) called for attr SUMO_ATTR_NUMLANES. This should never happen");
653  break;
654  case SUMO_ATTR_PRIORITY:
655  myNBEdge.myPriority = parse<int>(value);
656  break;
657  case SUMO_ATTR_LENGTH:
658  myNBEdge.setLoadedLength(parse<SUMOReal>(value));
659  break;
660  case SUMO_ATTR_TYPE:
661  myNBEdge.myType = value;
662  break;
663  case SUMO_ATTR_SHAPE:
664  bool ok;
665  myOrigShape = GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, true);
666  setGeometry(myOrigShape, true);
667  break;
670  break;
671  case SUMO_ATTR_NAME:
672  myNBEdge.setStreetName(value);
673  break;
674  case SUMO_ATTR_SPEED:
675  myNBEdge.setSpeed(-1, parse<SUMOReal>(value));
676  break;
677  case SUMO_ATTR_WIDTH:
678  myNBEdge.setLaneWidth(-1, parse<SUMOReal>(value));
679  break;
680  case SUMO_ATTR_ENDOFFSET:
681  myNBEdge.setEndOffset(-1, parse<SUMOReal>(value));
682  break;
683  case SUMO_ATTR_ALLOW:
684  break; // no edge value
685  case SUMO_ATTR_DISALLOW:
686  break; // no edge value
688  myConnectionStatus = value;
689  if (value == GUESSED) {
691  } else if (value == MODIFIED) {
693  }
694  break;
695  case GNE_ATTR_SHAPE_START: {
697  geom[0] = GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, false)[0];
698  setGeometry(geom, false);
699  break;
700  }
701  case GNE_ATTR_SHAPE_END: {
703  geom[-1] = GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, false)[0];
704  setGeometry(geom, false);
705  break;
706  }
707  default:
708  throw InvalidArgument("edge attribute '" + toString(key) + "' not allowed");
709  }
710 }
711 
712 
713 void
714 GNEEdge::setNumLanes(unsigned int numLanes, GNEUndoList* undoList) {
715  undoList->p_begin("change number of lanes");
716  getSource()->setLogicValid(false, undoList);
717  getDest()->setLogicValid(false, undoList);
718 
719  const unsigned int oldNumLanes = (unsigned int)myLanes.size();
720  for (unsigned int i = oldNumLanes; i < numLanes; i++) {
721  // since the GNELane does not exist yet, it cannot have yet been referenced so we only pass a zero-pointer
722  undoList->add(new GNEChange_Lane(this, 0,
723  myNBEdge.getLaneStruct(oldNumLanes - 1), true), true);
724  }
725  for (unsigned int i = oldNumLanes - 1; i > numLanes - 1; i--) {
726  // delete leftmost lane
727  undoList->add(new GNEChange_Lane(this, myLanes[i], myNBEdge.getLaneStruct(i), false), true);
728  }
729  undoList->p_end();
730 }
731 
732 
733 void
734 GNEEdge::addLane(GNELane* lane, const NBEdge::Lane& laneAttrs) {
735  const int index = lane ? lane->getIndex() : myNBEdge.getNumLanes();
736  // the laneStruct must be created first to ensure we have some geometry
737  myNBEdge.addLane(index);
738  if (lane) {
739  // restore a previously deleted lane
740  myLanes.insert(myLanes.begin() + index, lane);
741 
742  } else {
743  // create a new lane by copying leftmost lane
744  lane = new GNELane(*this, index);
745  myLanes.push_back(lane);
746  }
747  lane->incRef("GNEEdge::addLane");
748  // we copy all attributes except shape since this is recomputed from edge shape
749  myNBEdge.setSpeed(lane->getIndex(), laneAttrs.speed);
750  myNBEdge.setPermissions(laneAttrs.permissions, lane->getIndex());
752  myNBEdge.setEndOffset(lane->getIndex(), laneAttrs.endOffset);
753  myNBEdge.setLaneWidth(lane->getIndex(), laneAttrs.width);
754  // udate indices
755  for (int i = 0; i < (int)myLanes.size(); ++i) {
756  myLanes[i]->setIndex(i);
757  }
758  /* while technically correct, this looks ugly
759  getSource()->invalidateShape();
760  getDest()->invalidateShape();
761  */
762  myNet->refreshElement(this);
763 }
764 
765 
766 void
768  if (myLanes.size() == 0) {
769  throw ProcessError("Should not remove the last lane from an edge\n");
770  }
771  if (lane == 0) {
772  lane = myLanes.back();
773  }
774  myNBEdge.deleteLane(lane->getIndex());
775  lane->decRef("GNEEdge::removeLane");
776  myLanes.erase(myLanes.begin() + lane->getIndex());
777  if (lane->unreferenced()) {
778  delete lane;
779  }
780  // udate indices
781  for (int i = 0; i < (int)myLanes.size(); ++i) {
782  myLanes[i]->setIndex(i);
783  }
784  /* while technically correct, this looks ugly
785  getSource()->invalidateShape();
786  getDest()->invalidateShape();
787  */
788 
789  myNet->refreshElement(this);
790 }
791 
792 
793 void
794 GNEEdge::addConnection(unsigned int fromLane, const std::string& toEdgeID, unsigned int toLane, bool mayPass) {
795  NBEdge* destEdge = myNet->retrieveEdge(toEdgeID)->getNBEdge();
796  myNBEdge.setConnection(fromLane, destEdge, toLane, NBEdge::L2L_USER, true, mayPass);
797  myNet->refreshElement(this); // actually we only do this to force a redraw
798 }
799 
800 
801 void
802 GNEEdge::removeConnection(unsigned int fromLane, const std::string& toEdgeID, unsigned int toLane) {
803  NBEdge* destEdge = myNet->retrieveEdge(toEdgeID)->getNBEdge();
804  if (destEdge == myNBEdge.getTurnDestination()) {
806  }
807  myNBEdge.removeFromConnections(destEdge, fromLane, toLane);
808  myNet->refreshElement(this); // actually we only do this to force a redraw
809 }
810 
811 
812 void
813 GNEEdge::setMicrosimID(const std::string& newID) {
815  for (LaneVector::iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
816  (*i)->setMicrosimID(getNBEdge()->getLaneID((*i)->getIndex()));
817  }
818 }
819 
820 
821 bool
823  // Check if additional already exists before insertion
824  for (AdditionalVector::iterator i = myAdditionals.begin(); i != myAdditionals.end(); i++) {
825  if ((*i) == additional) {
826  return false;
827  }
828  }
829  // Insert it and retur true
830  myAdditionals.push_back(additional);
831  return true;
832 }
833 
834 
835 bool
837  // search additional and remove it
838  for (AdditionalVector::iterator i = myAdditionals.begin(); i != myAdditionals.end(); i++) {
839  if ((*i) == additional) {
840  myAdditionals.erase(i);
841  return true;
842  }
843  }
844  // If additional wasn't found, return false
845  return false;
846 }
847 
848 
849 const std::vector<GNEAdditional*>&
851  return myAdditionals;
852 }
853 
854 
855 bool
857  // Check if additionalSet already exists before insertion
858  for (AdditionalSetVector::iterator i = myAdditionalSets.begin(); i != myAdditionalSets.end(); i++) {
859  if ((*i) == additionalSet) {
860  return false;
861  }
862  }
863  // Insert it and retur true
864  myAdditionalSets.push_back(additionalSet);
865  return true;
866 }
867 
868 
869 bool
871  // search additionalSet and remove it
872  for (AdditionalSetVector::iterator i = myAdditionalSets.begin(); i != myAdditionalSets.end(); i++) {
873  if ((*i) == additionalSet) {
874  myAdditionalSets.erase(i);
875  return true;
876  }
877  }
878  // If additionalSet wasn't found, return false
879  return false;
880 }
881 
882 
883 const std::vector<GNEAdditionalSet*>&
885  return myAdditionalSets;
886 }
887 
888 /****************************************************************************/
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:734
void copyTemplate(GNEEdge *tpl, GNEUndoList *undolist)
copy edge attributes from tpl
Definition: GNEEdge.cpp:392
void invalidateConnections(bool reallowSetting=false)
Definition: NBEdge.cpp:961
The information about how to spread the lanes from the given position.
const std::string & getTypeID() const
Definition: NBEdge.h:930
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:616
static const SUMOReal UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:203
GUIVisualizationTextSettings streetName
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:250
SUMOReal nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
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:256
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:690
bool hasString(const std::string &str) const
PositionVector myOrigShape
restore point for undo
Definition: GNEEdge.h:244
void setMicrosimID(const std::string &newID)
override to also set lane ids
Definition: GNEEdge.cpp:813
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
bool hasLaneSpecificEndOffset() const
whether lanes differ in offset
Definition: NBEdge.cpp:1493
void setLaneWidth(int lane, SUMOReal width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2478
std::set< GUIGlID > getLaneGlIDs()
returns GLIDs of all lanes
Definition: GNEEdge.cpp:414
void setSpeed(int lane, SUMOReal speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2533
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:1101
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:245
const std::vector< T > & getSchemes() const
NBNode * getNBNode() const
Return net build node.
void setStreetName(const std::string &name)
sets the street name of this edge
Definition: NBEdge.h:491
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
std::string getAttribute(SumoXMLAttr key) const
Definition: GNEEdge.cpp:436
SUMOReal getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:469
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:86
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:2549
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:54
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:86
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 addAdditional(GNEAdditional *additional)
add additional to this edge
Definition: GNEEdge.cpp:822
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:736
const std::vector< GNEAdditional * > & getAdditionals() const
return list of additionals associated with this edge
Definition: GNEEdge.cpp:850
unsigned int getIndex() const
returns the index of the lane
Definition: GNELane.cpp:485
An Element wich group additionalSet elements.
bool isClosed() const
check if PositionVector is closed
bool myWasSplit
whether this edge was created from a split
Definition: GNEEdge.h:253
~GNEEdge()
Destructor.
Definition: GNEEdge.cpp:85
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:794
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge&#39;s geometry
Definition: NBEdge.cpp:448
GUIGlID getGlID() const
Returns the numerical id of the object.
#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)
bool removeAdditional(GNEAdditional *additional)
remove additional from this edge
Definition: GNEEdge.cpp:836
const std::vector< GNEAdditionalSet * > & getAdditionalSets()
return list of additionalSets associated with this edge
Definition: GNEEdge.cpp:884
virtual GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
Definition: GNEEdge.cpp:203
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNEEdge.cpp:150
SUMOReal speed
The speed allowed on this lane.
Definition: NBEdge.h:130
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
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:66
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
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:429
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:1471
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:355
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()
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:93
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:603
A list of positions.
void add(SUMOReal xoff, SUMOReal yoff, SUMOReal zoff)
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:1457
friend class GNEChange_Attribute
declare friend class
void updateLaneGeometriesAndAdditionals()
update edge geometry and inform the lanes let the lanes recompute their precomputed geometry informat...
Definition: GNEEdge.cpp:375
AdditionalVector myAdditionals
list with the additonals vinculated with this edge
Definition: GNEEdge.h:259
Boundary getBoundary() const
Returns the street&#39;s geometry.
Definition: GNEEdge.cpp:107
SUMOReal z() const
Returns the z-position.
Definition: Position.h:73
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:347
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:1303
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNEEdge.cpp:130
GUIColorer junctionColorer
The junction colorer.
int insertAtClosest(const Position &p)
inserts p between the two closest positions and returns the insertion index
void drawName(const Position &pos, const SUMOReal scale, const GUIVisualizationTextSettings &settings, const SUMOReal angle=0) const
draw name of item
void setLoadedLength(SUMOReal val)
Definition: NBEdge.cpp:2592
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
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:934
std::string getVehicleClassNames(SVCPermissions permissions)
Returns the ids of the given classes, divided using a &#39; &#39;.
void removeLane(GNELane *lane)
the number of lanes by one. argument is only used to increase robustness (assertions) ...
Definition: GNEEdge.cpp:767
SUMOReal getEndOffset() const
Returns the offset to the destination node.
Definition: NBEdge.h:498
virtual GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition: GNEEdge.cpp:118
void decRef(const std::string &debugMsg="")
void setGeometry(PositionVector geom, bool inner)
update edge geometry and inform the lanes
Definition: GNEEdge.cpp:365
GNEEdge(NBEdge &nbe, GNENet *net, bool wasSplit=false, bool loaded=false)
Constructor.
Definition: GNEEdge.cpp:67
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:54
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:2577
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
void setResponsible(bool newVal)
set responsibility for deleting internal strctures
Definition: GNEEdge.cpp:632
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:371
const PositionVector & getShape() const
returns the shape of the lane
Definition: GNELane.cpp:434
const std::vector< GNELane * > & getLanes()
returns a reference to the lane vector
Definition: GNEEdge.cpp:424
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:311
virtual void setMicrosimID(const std::string &newID)
Changes the microsimID of the object.
static const SUMOReal UNSPECIFIED_LOADED_LENGTH
no length override given
Definition: NBEdge.h:212
void deleteLane(unsigned int index, bool recompute=true)
Definition: NBEdge.cpp:2405
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:63
void setPreferredVehicleClass(SVCPermissions permissions, int lane=-1)
Definition: NBEdge.cpp:2563
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:546
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:212
void updateGeometry()
update pre-computed geometry information
Definition: GNEEdge.cpp:103
The popup menu of a globject.
an edge
static const SUMOReal SNAP_RADIUS
Definition: GNEEdge.h:237
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:1289
GNEJunction * getDest() const
returns the destination-junction
Definition: GNEEdge.cpp:144
void renameEdge(GNEEdge *edge, const std::string &newID)
updates the map and reserves new id
Definition: GNENet.cpp:940
bool isValid(SumoXMLAttr key, const std::string &value)
Definition: GNEEdge.cpp:576
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge&#39;s lanes&#39; lateral offset is computed.
Definition: NBEdge.h:626
void removeExplicitTurnaround(std::string id)
remove edge id from the list of explicit turnarounds
Definition: GNENet.cpp:980
LaneVector myLanes
List of this edges lanes.
Definition: GNEEdge.h:247
Lane & getLaneStruct(unsigned int lane)
Definition: NBEdge.h:1090
SUMOReal distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:232
bool removeAdditionalSet(GNEAdditionalSet *additionalSet)
remove GNEAdditionalSet from this edge
Definition: GNEEdge.cpp:870
bool hasLaneSpecificWidth() const
whether lanes differ in width
Definition: NBEdge.cpp:1482
void setEndOffset(int lane, SUMOReal offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2517
#define SUMOReal
Definition: config.h:214
static const std::string GUESSED
feature has been reguessed (may still be unchanged be we can&#39;t tell (yet)
bool addAdditionalSet(GNEAdditionalSet *additionalSet)
add GNEAdditionalSet to this edge
Definition: GNEEdge.cpp:856
void setEndpoint(Position pos, GNEUndoList *undoList)
makes pos the new geometry endpoint at the appropriate end
Definition: GNEEdge.cpp:328
empty max
AdditionalSetVector myAdditionalSets
list with the additonalSets vinculated with this edge
Definition: GNEEdge.h:262
NBEdge & myNBEdge
the underlying NBEdge
Definition: GNEEdge.h:241
SUMOReal getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:451
SUMOReal getFinalLength() const
length that will be assigned to the lanes in the final network
Definition: NBEdge.cpp:2757
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.cpp:225
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:559
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition: GNEEdge.cpp:502
const std::string & getStreetName() const
Returns the street name of this edge.
Definition: NBEdge.h:485
void addLane(unsigned int index, bool recompute=true)
Definition: NBEdge.cpp:2370
void resetEndpoint(const Position &pos, GNEUndoList *undoList)
restores the endpoint to the junction position at the appropriate end
Definition: GNEEdge.cpp:351
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:949
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition: NBEdge.cpp:2341
bool wasSplit()
whether this edge was created from a split
Definition: GNEEdge.cpp:430
GNEJunction * getSource() const
returns the source-junction
Definition: GNEEdge.cpp:138
Position getSplitPos(const Position &clickPos)
Definition: GNEEdge.cpp:231
friend class GNEChange_Lane
Friend class.
Definition: GNEEdge.h:57
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:258
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:714
a junction
void removeConnection(unsigned int fromLane, const std::string &toEdgeID, unsigned int toLane)
removes a connection
Definition: GNEEdge.cpp:802
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:363