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>
44 #include "GNEEdge.h"
45 #include "GNENet.h"
46 #include "GNEViewNet.h"
47 #include "GNEUndoList.h"
48 #include "GNEChange_Attribute.h"
49 #include "GNEChange_Lane.h"
50 #include "GNEJunction.h"
51 #include "GNELane.h"
52 #include "GNEAdditional.h"
53 #include "GNEConnection.h"
54 #include "GNERouteProbe.h"
55 #include "GNEVaporizer.h"
56 #include "GNERerouter.h"
57 
58 
59 
60 
61 // ===========================================================================
62 // static
63 // ===========================================================================
65 
66 // ===========================================================================
67 // members methods
68 // ===========================================================================
69 GNEEdge::GNEEdge(NBEdge& nbe, GNENet* net, bool wasSplit, bool loaded):
70  GNENetElement(net, nbe.getID(), GLO_EDGE, SUMO_TAG_EDGE, ICON_EDGE),
71  myNBEdge(nbe) ,
72  myGNEJunctionSource(myNet->retrieveJunction(myNBEdge.getFromNode()->getID())),
73  myGNEJunctionDestiny(myNet->retrieveJunction(myNBEdge.getToNode()->getID())),
74  myOrigShape(nbe.getInnerGeometry()),
75  myLanes(0),
76  myAmResponsible(false),
77  myWasSplit(wasSplit),
78  myConnectionStatus(loaded ? LOADED : GUESSED) {
79  // Create lanes
80  int numLanes = myNBEdge.getNumLanes();
81  myLanes.reserve(numLanes);
82  for (int i = 0; i < numLanes; i++) {
83  myLanes.push_back(new GNELane(*this, i));
84  myLanes.back()->incRef("GNEEdge::GNEEdge");
85  }
86  // update Lane geometries
87  for (LaneVector::iterator i = myLanes.begin(); i != myLanes.end(); i++) {
88  (*i)->updateGeometry();
89  }
90 }
91 
92 
94  // Delete references to this eddge in lanes
95  for (LaneVector::iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
96  (*i)->decRef("GNEEdge::~GNEEdge");
97  if ((*i)->unreferenced()) {
98  delete *i;
99  }
100  }
101  // delete references to this eddge in connections
102  for (ConnectionVector::const_iterator i = myGNEConnections.begin(); i != myGNEConnections.end(); ++i) {
103  (*i)->decRef("GNEEdge::~GNEEdge");
104  if ((*i)->unreferenced()) {
105  delete(*i);
106  }
107  }
108  if (myAmResponsible) {
109  delete &myNBEdge;
110  }
111 }
112 
113 
114 void
116  // Update geometry of lanes
117  for (LaneVector::iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
118  (*i)->updateGeometry();
119  }
120  // Update geometry of additionals vinculated to this edge
121  for (AdditionalVector::iterator i = myAdditionals.begin(); i != myAdditionals.end(); ++i) {
122  (*i)->updateGeometry();
123  }
124 }
125 
126 
127 Boundary
129  Boundary ret;
130  for (LaneVector::const_iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
131  ret.add((*i)->getBoundary());
132  }
133  ret.grow(10); // !!! magic value
134  return ret;
135 }
136 
137 
138 Boundary
140  Boundary b = getBoundary();
141  b.grow(20);
142  return b;
143 }
144 
145 
148  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
149  buildPopupHeader(ret, app);
153  buildPositionCopyEntry(ret, false);
154  return ret;
155 }
156 
157 
160  return myGNEJunctionSource;
161 }
162 
163 
166  return myGNEJunctionDestiny;
167 }
168 
169 void
171  /* do something different for connectors?
172  if (myNBEdge.isMacroscopicConnector()) {
173  }
174  */
175 
176  // draw the lanes
177  for (LaneVector::const_iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
178  (*i)->drawGL(s);
179  }
180 
181  // draw the connections
182  if (s.scale >= 2) {
183  for (ConnectionVector::const_iterator i = myGNEConnections.begin(); i != myGNEConnections.end(); ++i) {
184  (*i)->drawGL(s);
185  }
186  }
187 
188  // draw geometry hints
189  if (s.scale * SNAP_RADIUS > 1.) { // check whether it is not too small
190  GLHelper::setColor(s.junctionColorer.getSchemes()[0].getColor(2));
191  if (gSelected.isSelected(getType(), getGlID()) && s.laneColorer.getActive() != 1) {
192  // override with special colors (unless the color scheme is based on selection)
193  GLHelper::setColor(GNENet::selectionColor.changedBrightness(-20));
194  }
195  // recognize full transparency and simply don't draw
196  GLfloat color[4];
197  glGetFloatv(GL_CURRENT_COLOR, color);
198  if (color[3] > 0) {
199  glPushName(getGlID());
201  for (int i = 1; i < (int)geom.size() - 1; i++) {
202  Position pos = geom[i];
203  glPushMatrix();
204  glTranslated(pos.x(), pos.y(), GLO_JUNCTION - 0.01);
206  glPopMatrix();
207  }
208  glPopName();
209  }
210  }
211 
212  // (optionally) draw the name and/or the street name
213  const bool drawStreetName = s.streetName.show && myNBEdge.getStreetName() != "";
214  if (s.edgeName.show || drawStreetName) {
215  glPushName(getGlID());
216  GNELane* lane1 = myLanes[0];
217  GNELane* lane2 = myLanes[myLanes.size() - 1];
218  Position p = lane1->getShape().positionAtOffset(lane1->getShape().length() / (double) 2.);
219  p.add(lane2->getShape().positionAtOffset(lane2->getShape().length() / (double) 2.));
220  p.mul(.5);
221  double angle = lane1->getShape().rotationDegreeAtOffset(lane1->getShape().length() / (double) 2.);
222  angle += 90;
223  if (angle > 90 && angle < 270) {
224  angle -= 180;
225  }
226  if (s.edgeName.show) {
227  drawName(p, s.scale, s.edgeName, angle);
228  }
229  if (drawStreetName) {
231  s.streetName.size / s.scale, s.streetName.color, angle);
232  }
233  glPopName();
234  }
235 }
236 
237 
241  GUIParameterTableWindow* ret = 0;
242  UNUSED_PARAMETER(&app);
243  return ret;
244 }
245 
246 
247 void
249  Position delta = junction->getNBNode()->getPosition() - origPos;
251  // geometry endpoint need not equal junction position hence we modify it with delta
252  if (junction == myGNEJunctionSource) {
253  geom[0].add(delta);
254  } else {
255  geom[-1].add(delta);
256  }
257  setGeometry(geom, false);
258 }
259 
260 NBEdge*
262  return &myNBEdge;
263 }
264 
265 
266 Position
267 GNEEdge::getSplitPos(const Position& clickPos) {
268  const PositionVector& geom = myNBEdge.getGeometry();
269  int index = geom.indexOfClosest(clickPos);
270  if (geom[index].distanceTo(clickPos) < SNAP_RADIUS) {
271  // split at existing geometry point
272  return geom[index];
273  } else {
274  // split straight between the next two points
275  return geom.positionAtOffset(geom.nearest_offset_to_point2D(clickPos));
276  }
277 }
278 
279 
280 Position
281 GNEEdge::moveGeometry(const Position& oldPos, const Position& newPos, bool relative) {
283  bool changed = changeGeometry(geom, getMicrosimID(), oldPos, newPos, relative);
284  if (changed) {
285  setGeometry(geom, false);
286  return newPos;
287  } else {
288  return oldPos;
289  }
290 }
291 
292 
293 bool
294 GNEEdge::changeGeometry(PositionVector& geom, const std::string& id, const Position& oldPos, const Position& newPos, bool relative, bool moveEndPoints) {
295  if (geom.size() < 2) {
296  throw ProcessError("Invalid geometry size in " + toString(SUMO_TAG_EDGE) + " with ID='" + id + "'");
297  } else {
298  int index = geom.indexOfClosest(oldPos);
299  const double nearestOffset = geom.nearest_offset_to_point2D(oldPos, true);
300  if (nearestOffset != GeomHelper::INVALID_OFFSET
301  && (moveEndPoints || (nearestOffset >= SNAP_RADIUS
302  && nearestOffset <= geom.length2D() - SNAP_RADIUS))) {
303  const Position nearest = geom.positionAtOffset2D(nearestOffset);
304  const double distance = geom[index].distanceTo2D(nearest);
305  if (distance < SNAP_RADIUS) { //move existing
306  if (moveEndPoints || (index != 0 && index != (int)geom.size() - 1)) {
307  const bool closed = geom.isClosed();
308  if (relative) {
309  geom[index] = geom[index] + newPos;
310  } else {
311  geom[index] = newPos;
312  }
313  if (closed && moveEndPoints && (index == 0 || index == (int)geom.size() - 1)) {
314  const int otherIndex = (int)geom.size() - 1 - index;
315  geom[otherIndex] = geom[index];
316  }
317  return true;
318  }
319  } else {
320  if (relative) {
321  int index = geom.insertAtClosest(nearest);
322  geom[index] = geom[index] + newPos;
323  return true;
324  } else {
325  geom.insertAtClosest(newPos); // insert new
326  return true;
327  }
328  }
329  }
330  return false;
331  }
332 }
333 
334 
335 void
338  if (geom.size() == 0) {
339  return;
340  }
341  geom.add(delta.x(), delta.y(), delta.z());
342  setGeometry(geom, true);
343 }
344 
345 
346 bool
349  if (geom.size() == 0) {
350  return false;
351  }
352  int index = geom.indexOfClosest(pos);
353  if (geom[index].distanceTo(pos) < SNAP_RADIUS) {
354  geom.erase(geom.begin() + index);
355  setAttribute(SUMO_ATTR_SHAPE, toString(geom), undoList);
356  return true;
357  } else {
358  return false;
359  }
360 }
361 
362 
363 void
365  undoList->p_begin("set endpoint");
367  int index = geom.indexOfClosest(pos);
368  if (geom[index].distanceTo(pos) < SNAP_RADIUS) { // snap to existing geometry
369  pos = geom[index];
370  }
373  if (pos.distanceTo2D(destPos) < pos.distanceTo2D(sourcePos)) {
374  setAttribute(GNE_ATTR_SHAPE_END, toString(pos), undoList);
376  } else {
377  setAttribute(GNE_ATTR_SHAPE_START, toString(pos), undoList);
379  }
380  // possibly existing inner point is no longer needed
381  deleteGeometry(pos, undoList);
382  undoList->p_end();
383 }
384 
385 
386 void
390  if (pos.distanceTo2D(destPos) < pos.distanceTo2D(sourcePos)) {
391  setAttribute(GNE_ATTR_SHAPE_END, toString(destPos), undoList);
393  } else {
394  setAttribute(GNE_ATTR_SHAPE_START, toString(sourcePos), undoList);
396  }
397 }
398 
399 
400 void
402  myNBEdge.setGeometry(geom, inner);
403  updateGeometry();
406  myNet->refreshElement(this);
407 }
408 
409 void
411  for (std::vector<GNEEdge*>::const_iterator i = myGNEJunctionSource->getGNEIncomingEdges().begin(); i != myGNEJunctionSource->getGNEIncomingEdges().end(); i++) {
412  (*i)->remakeGNEConnections();
413  }
414 }
415 
416 void
418  // @note: this method may only be called once the whole network is initialized
419 
420  // first check that there are the same number of NBLanes as GNELanes
421  while (myLanes.size() < myNBEdge.getLanes().size()) {
422  GNELane* lane = new GNELane(*this, (int)myLanes.size());
423  const NBEdge::Lane& laneAttrs = myNBEdge.getLanes().at(myLanes.size());
424  myLanes.push_back(lane);
425  lane->incRef("GNEEdge::addLane");
426  // we copy all attributes except shape since this is recomputed from edge shape
428  myNBEdge.setPermissions(laneAttrs.permissions, lane->getIndex());
429  myNBEdge.setPreferredVehicleClass(laneAttrs.preferred, lane->getIndex());
430  myNBEdge.setEndOffset(lane->getIndex(), laneAttrs.endOffset);
431  myNBEdge.setLaneWidth(lane->getIndex(), laneAttrs.width);
432  // update indices
433  for (int i = 0; i < (int)myLanes.size(); ++i) {
434  myLanes[i]->setIndex(i);
435  }
436  lane->updateGeometry();
437  // Remake connections for this edge and all edges that target this lane
440  // Update element
441  myNet->refreshElement(this);
442  updateGeometry();
443  }
444 
445  // Create connections (but reuse existing objects)
446  std::vector<NBEdge::Connection>& myConnections = myNBEdge.getConnections();
447  ConnectionVector newCons;
448  for (std::vector<NBEdge::Connection>::iterator i = myConnections.begin(); i != myConnections.end(); i++) {
449  const NBEdge::Connection& con = *i;
450  newCons.push_back(retrieveConnection(con.fromLane, con.toEdge, con.toLane));
451  newCons.back()->incRef("GNEEdge::GNEEdge");
452  newCons.back()->updateLinkState();
453  }
455  myGNEConnections = newCons;
456 }
457 
458 
459 void
461  // Drop all existents connections that aren't referenced anymore
462  for (ConnectionVector::iterator i = myGNEConnections.begin(); i != myGNEConnections.end(); i++) {
463  // Dec reference of connection
464  (*i)->decRef("GNEEdge::clearGNEConnections");
465  // Delete GNEConnectionToErase if is unreferenced
466  if ((*i)->unreferenced()) {
467  delete(*i);
468  }
469  }
470  myGNEConnections.clear();
471 }
472 
473 
474 int
476  AdditionalVector routeProbes;
477  for (AdditionalVector::const_iterator i = myAdditionals.begin(); i != myAdditionals.end(); i++) {
478  if ((*i)->getTag() == routeProbe->getTag()) {
479  routeProbes.push_back(*i);
480  }
481  }
482  // return index of routeProbe in routeProbes vector
483  AdditionalVector::const_iterator it = std::find(routeProbes.begin(), routeProbes.end(), routeProbe);
484  if (it == routeProbes.end()) {
485  return -1;
486  } else {
487  return (int)(it - routeProbes.begin());
488  }
489 }
490 
491 
492 int
494  AdditionalVector vaporizers;
495  for (AdditionalVector::const_iterator i = myAdditionals.begin(); i != myAdditionals.end(); i++) {
496  if ((*i)->getTag() == vaporizer->getTag()) {
497  vaporizers.push_back(*i);
498  }
499  }
500  // return index of routeProbe in routeProbes vector
501  AdditionalVector::const_iterator it = std::find(vaporizers.begin(), vaporizers.end(), vaporizer);
502  if (it == vaporizers.end()) {
503  return -1;
504  } else {
505  return (int)(it - vaporizers.begin());
506  }
507 }
508 
509 
510 void
512  undoList->p_begin("copy template");
520  // copy lane attributes as well
521  for (int i = 0; i < (int)myLanes.size(); i++) {
522  myLanes[i]->setAttribute(SUMO_ATTR_ALLOW, tpl->myLanes[i]->getAttribute(SUMO_ATTR_ALLOW), undoList);
523  myLanes[i]->setAttribute(SUMO_ATTR_DISALLOW, tpl->myLanes[i]->getAttribute(SUMO_ATTR_DISALLOW), undoList);
524  myLanes[i]->setAttribute(SUMO_ATTR_SPEED, tpl->myLanes[i]->getAttribute(SUMO_ATTR_SPEED), undoList);
525  myLanes[i]->setAttribute(SUMO_ATTR_WIDTH, tpl->myLanes[i]->getAttribute(SUMO_ATTR_WIDTH), undoList);
526  myLanes[i]->setAttribute(SUMO_ATTR_ENDOFFSET, tpl->myLanes[i]->getAttribute(SUMO_ATTR_ENDOFFSET), undoList);
527  }
528  undoList->p_end();
529 }
530 
531 
532 std::set<GUIGlID>
534  std::set<GUIGlID> result;
535  for (size_t i = 0; i < myLanes.size(); i++) {
536  result.insert(myLanes[i]->getGlID());
537  }
538  return result;
539 }
540 
541 
542 const std::vector<GNELane*>&
544  return myLanes;
545 }
546 
547 
548 const std::vector<GNEConnection*>&
550  return myGNEConnections;
551 }
552 
553 
554 bool
556  return myWasSplit;
557 }
558 
559 
560 std::string
562  switch (key) {
563  case SUMO_ATTR_ID:
564  return getMicrosimID();
565  case SUMO_ATTR_FROM:
567  case SUMO_ATTR_TO:
569  case SUMO_ATTR_NUMLANES:
570  return toString(myNBEdge.getNumLanes());
571  case SUMO_ATTR_PRIORITY:
572  return toString(myNBEdge.getPriority());
573  case SUMO_ATTR_LENGTH:
574  return toString(myNBEdge.getFinalLength());
575  case SUMO_ATTR_TYPE:
576  return myNBEdge.getTypeID();
577  case SUMO_ATTR_SHAPE:
581  case SUMO_ATTR_NAME:
582  return myNBEdge.getStreetName();
583  case SUMO_ATTR_ALLOW:
584  // return all allowed classes (may differ from the written attributes)
585  return (getVehicleClassNames(myNBEdge.getPermissions()) + (myNBEdge.hasLaneSpecificPermissions() ? " (combined!)" : ""));
586  case SUMO_ATTR_DISALLOW: {
587  // return classes disallowed on at least one lane (may differ from the written attributes)
588  SVCPermissions combinedDissallowed = 0;
589  for (int i = 0; i < (int)myNBEdge.getNumLanes(); ++i) {
590  combinedDissallowed |= ~myNBEdge.getPermissions(i);
591  }
592  return (getVehicleClassNames(combinedDissallowed) + (myNBEdge.hasLaneSpecificPermissions() ? " (combined!)" : ""));
593  }
594  case SUMO_ATTR_SPEED:
596  return "lane specific";
597  } else {
598  return toString(myNBEdge.getSpeed());
599  }
600  case SUMO_ATTR_WIDTH:
602  return "lane specific";
604  return "default";
605  } else {
606  return toString(myNBEdge.getLaneWidth());
607  }
608  case SUMO_ATTR_ENDOFFSET:
610  return "lane specific";
611  } else {
612  return toString(myNBEdge.getEndOffset());
613  }
615  return myConnectionStatus;
618  return "";
619  } else {
620  return toString(myNBEdge.getGeometry()[0]);
621  }
622  case GNE_ATTR_SHAPE_END:
624  return "";
625  } else {
626  return toString(myNBEdge.getGeometry()[-1]);
627  }
628  default:
629  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
630  }
631 }
632 
633 
634 void
635 GNEEdge::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
636  switch (key) {
637  case SUMO_ATTR_WIDTH:
638  case SUMO_ATTR_ENDOFFSET:
639  case SUMO_ATTR_SPEED:
640  case SUMO_ATTR_ALLOW:
641  case SUMO_ATTR_DISALLOW: {
642  undoList->p_begin("change " + toString(getTag()) + " attribute");
643  const std::string origValue = myLanes.at(0)->getAttribute(key); // will have intermediate value of "lane specific"
644  // lane specific attributes need to be changed via lanes to allow undo
645  for (LaneVector::iterator it = myLanes.begin(); it != myLanes.end(); it++) {
646  (*it)->setAttribute(key, value, undoList);
647  }
648  // ensure that the edge value is also changed. Actually this sets the lane attributes again but it does not matter
649  undoList->p_add(new GNEChange_Attribute(this, key, value, true, origValue));
650  undoList->p_end();
651  break;
652  }
653  case SUMO_ATTR_FROM: {
654  undoList->p_begin("change " + toString(getTag()) + " attribute");
655  undoList->p_add(new GNEChange_Attribute(this, key, value));
656  myGNEJunctionSource->setLogicValid(false, undoList);
657  myNet->retrieveJunction(value)->setLogicValid(false, undoList);
660  undoList->p_end();
661  break;
662  }
663  case SUMO_ATTR_TO: {
664  undoList->p_begin("change " + toString(getTag()) + " attribute");
665  undoList->p_add(new GNEChange_Attribute(this, key, value));
666  myGNEJunctionDestiny->setLogicValid(false, undoList);
667  myNet->retrieveJunction(value)->setLogicValid(false, undoList);
670  undoList->p_end();
671  break;
672  }
673  case SUMO_ATTR_ID:
674  case SUMO_ATTR_PRIORITY:
675  case SUMO_ATTR_LENGTH:
676  case SUMO_ATTR_TYPE:
680  case GNE_ATTR_SHAPE_END:
681  undoList->p_add(new GNEChange_Attribute(this, key, value));
682  break;
683  case SUMO_ATTR_NAME:
684  // user cares about street names. Make sure they appear in the output
686  OptionsCont::getOptions().set("output.street-names", "true");
687  undoList->p_add(new GNEChange_Attribute(this, key, value));
688  break;
689  case SUMO_ATTR_NUMLANES:
690  if (value != getAttribute(key)) {
691  setNumLanes(parse<int>(value), undoList);
692  }
693  break;
694  case SUMO_ATTR_SHAPE:
695  // @note: assumes value of inner geometry!
696  // actually the geometry is already updated (incrementally
697  // during mouse movement). We set the restore point to the end
698  // of the last change-set
700  undoList->p_add(new GNEChange_Attribute(this, key, value));
701  break;
702  default:
703  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
704  }
705 }
706 
707 
708 bool
709 GNEEdge::isValid(SumoXMLAttr key, const std::string& value) {
710  switch (key) {
711  case SUMO_ATTR_ID:
712  return isValidID(value) && myNet->retrieveEdge(value, false) == 0;
713  break;
714  case SUMO_ATTR_FROM:
715  return isValidID(value) && myNet->retrieveJunction(value, false) != 0 && value != myGNEJunctionDestiny->getMicrosimID();
716  break;
717  case SUMO_ATTR_TO:
718  return isValidID(value) && myNet->retrieveJunction(value, false) != 0 && value != myGNEJunctionSource->getMicrosimID();
719  break;
720  case SUMO_ATTR_SPEED:
721  return isPositive<double>(value);
722  break;
723  case SUMO_ATTR_NUMLANES:
724  return isPositive<int>(value);
725  break;
726  case SUMO_ATTR_PRIORITY:
727  return canParse<int>(value);
728  break;
729  case SUMO_ATTR_LENGTH:
730  return canParse<double>(value) && (isPositive<double>(value) || parse<double>(value) == NBEdge::UNSPECIFIED_LOADED_LENGTH);
731  break;
732  case SUMO_ATTR_ALLOW:
733  case SUMO_ATTR_DISALLOW:
734  return canParseVehicleClasses(value);
735  break;
736  case SUMO_ATTR_TYPE:
737  return true;
738  break;
739  case SUMO_ATTR_SHAPE: {
740  bool ok = true;
741  PositionVector shape = GeomConvHelper::parseShapeReporting(value, "user-supplied position", 0, ok, true);
742  return ok;
743  break;
744  }
747  break;
748  case SUMO_ATTR_NAME:
749  return true;
750  break;
751  case SUMO_ATTR_WIDTH:
752  if (value == "default") {
753  return true;
754  } else {
755  return canParse<double>(value) && (isPositive<double>(value) || parse<double>(value) == NBEdge::UNSPECIFIED_WIDTH);
756  }
757  break;
758  case SUMO_ATTR_ENDOFFSET:
759  return canParse<double>(value);
760  break;
761  case GNE_ATTR_SHAPE_START: {
762  bool ok;
763  return value == "" || GeomConvHelper::parseShapeReporting(value, "user-supplied position", 0, ok, false).size() == 1;
764  break;
765  }
766  case GNE_ATTR_SHAPE_END: {
767  bool ok;
768  return value == "" || GeomConvHelper::parseShapeReporting(value, "user-supplied position", 0, ok, false).size() == 1;
769  break;
770  }
771  default:
772  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
773  }
774 }
775 
776 
777 void
779  myAmResponsible = newVal;
780 }
781 
782 // ===========================================================================
783 // private
784 // ===========================================================================
785 
786 void
787 GNEEdge::setAttribute(SumoXMLAttr key, const std::string& value) {
788  switch (key) {
789  case SUMO_ATTR_ID:
790  myNet->renameEdge(this, value);
791  break;
792  case SUMO_ATTR_FROM:
794  // update this edge of list of outgoings edges of the old GNEJunctionSource
796  // update GNEJunctionSource
798  // update this edge of list of outgoings edges of the new GNEJunctionSource
800  break;
801  case SUMO_ATTR_TO:
803  // update this edge of list of incomings edges of the old GNEJunctionDestiny
805  // update GNEJunctionDestiny
807  // update this edge of list of incomings edges of the new GNEJunctionDestiny
809  break;
810  case SUMO_ATTR_NUMLANES:
811  throw InvalidArgument("GNEEdge::setAttribute (private) called for attr SUMO_ATTR_NUMLANES. This should never happen");
812  break;
813  case SUMO_ATTR_PRIORITY:
814  myNBEdge.myPriority = parse<int>(value);
815  break;
816  case SUMO_ATTR_LENGTH:
817  myNBEdge.setLoadedLength(parse<double>(value));
818  break;
819  case SUMO_ATTR_TYPE:
820  myNBEdge.myType = value;
821  break;
822  case SUMO_ATTR_SHAPE:
823  bool ok;
824  myOrigShape = GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, true);
825  setGeometry(myOrigShape, true);
826  break;
829  break;
830  case SUMO_ATTR_NAME:
831  myNBEdge.setStreetName(value);
832  break;
833  case SUMO_ATTR_SPEED:
834  myNBEdge.setSpeed(-1, parse<double>(value));
835  break;
836  case SUMO_ATTR_WIDTH:
837  if (value == "default") {
839  } else {
840  myNBEdge.setLaneWidth(-1, parse<double>(value));
841  }
842  break;
843  case SUMO_ATTR_ENDOFFSET:
844  myNBEdge.setEndOffset(-1, parse<double>(value));
845  break;
846  case SUMO_ATTR_ALLOW:
847  break; // no edge value
848  case SUMO_ATTR_DISALLOW:
849  break; // no edge value
851  myConnectionStatus = value;
852  if (value == GUESSED) {
855  } else if (value != GUESSED) {
857  }
858  break;
859  case GNE_ATTR_SHAPE_START: {
860  // get geometry of NBEdge, remove FIRST element with the new value (or with the Junction Source position) and set it back to edge
862  geom.erase(geom.begin());
863  if (value == "") {
865  } else {
866  geom.push_front_noDoublePos(GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, false)[0]);
867  }
868  setGeometry(geom, false);
869  break;
870  }
871  case GNE_ATTR_SHAPE_END: {
872  // get geometry of NBEdge, remove LAST element with the new value (or with the Junction Destiny position) and set it back to edge
874  geom.pop_back();
875  if (value == "") {
877  } else {
878  geom.push_back_noDoublePos(GeomConvHelper::parseShapeReporting(value, "netedit-given", 0, ok, false)[0]);
879  }
880  setGeometry(geom, false);
881  break;
882  }
883  default:
884  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
885  }
886 }
887 
888 
889 void
890 GNEEdge::setNumLanes(int numLanes, GNEUndoList* undoList) {
891  undoList->p_begin("change number of " + toString(SUMO_TAG_LANE) + "s");
892  myGNEJunctionSource->setLogicValid(false, undoList);
893  myGNEJunctionDestiny->setLogicValid(false, undoList);
894 
895  const int oldNumLanes = (int)myLanes.size();
896  for (int i = oldNumLanes; i < numLanes; i++) {
897  // since the GNELane does not exist yet, it cannot have yet been referenced so we only pass a zero-pointer
898  undoList->add(new GNEChange_Lane(this, 0,
899  myNBEdge.getLaneStruct(oldNumLanes - 1), true), true);
900  }
901  for (int i = oldNumLanes - 1; i > numLanes - 1; i--) {
902  // delete leftmost lane
903  undoList->add(new GNEChange_Lane(this, myLanes[i], myNBEdge.getLaneStruct(i), false), true);
904  }
905  undoList->p_end();
906 }
907 
908 
909 void
910 GNEEdge::addLane(GNELane* lane, const NBEdge::Lane& laneAttrs) {
911  const int index = lane ? lane->getIndex() : myNBEdge.getNumLanes();
912  // the laneStruct must be created first to ensure we have some geometry
913  myNBEdge.addLane(index);
914  if (lane) {
915  // restore a previously deleted lane
916  myLanes.insert(myLanes.begin() + index, lane);
917 
918  } else {
919  // create a new lane by copying leftmost lane
920  lane = new GNELane(*this, index);
921  myLanes.push_back(lane);
922  }
923  lane->incRef("GNEEdge::addLane");
924  // we copy all attributes except shape since this is recomputed from edge shape
925  myNBEdge.setSpeed(lane->getIndex(), laneAttrs.speed);
926  myNBEdge.setPermissions(laneAttrs.permissions, lane->getIndex());
928  myNBEdge.setEndOffset(lane->getIndex(), laneAttrs.endOffset);
929  myNBEdge.setLaneWidth(lane->getIndex(), laneAttrs.width);
930  // udate indices
931  for (int i = 0; i < (int)myLanes.size(); ++i) {
932  myLanes[i]->setIndex(i);
933  }
934  /* while technically correct, this looks ugly
935  myGNEJunctionSource->invalidateShape();
936  myGNEJunctionDestiny->invalidateShape();
937  */
938  // Remake connections for this edge and all edges that target this lane
941  // Update element
942  myNet->refreshElement(this);
943  updateGeometry();
944 }
945 
946 
947 void
949  if (myLanes.size() == 0) {
950  throw ProcessError("Should not remove the last " + toString(SUMO_TAG_LANE) + " from an " + toString(getTag()));
951  }
952  if (lane == 0) {
953  lane = myLanes.back();
954  }
955  // Delete lane of edge's container
956  myNBEdge.deleteLane(lane->getIndex());
957  lane->decRef("GNEEdge::removeLane");
958  myLanes.erase(myLanes.begin() + lane->getIndex());
959  // Delete lane if is unreferenced
960  if (lane->unreferenced()) {
961  delete lane;
962  }
963  // udate indices
964  for (int i = 0; i < (int)myLanes.size(); ++i) {
965  myLanes[i]->setIndex(i);
966  }
967  /* while technically correct, this looks ugly
968  myGNEJunctionSource->invalidateShape();
969  myGNEJunctionDestiny->invalidateShape();
970  */
971  // Remake connections for this edge and all edges that target this lane
974 
975  // Update element
976  myNet->refreshElement(this);
977  updateGeometry();
978 }
979 
980 void
982  // If a new connection was sucesfully created
983  if (myNBEdge.setConnection(nbCon.fromLane, nbCon.toEdge, nbCon.toLane, NBEdge::L2L_USER, true, nbCon.mayDefinitelyPass, nbCon.keepClear, nbCon.contPos, nbCon.visibility)) {
984  // Create GNEConection
985  con->updateGeometry();
986  myGNEConnections.push_back(con);
987  // Add reference
988  myGNEConnections.back()->incRef("GNEEdge::addConnection");
989  }
990  myNet->refreshElement(this); // actually we only do this to force a redraw
991 }
992 
993 
994 void
996 
997  if (nbCon.toEdge == myNBEdge.getTurnDestination()) {
999  }
1000  // Get connection to remove
1001  GNEConnection* con = retrieveConnection(nbCon.fromLane, nbCon.toEdge, nbCon.toLane);
1003  if (!con->unreferenced()) {
1004  con->decRef("GNEEdge::removeConnection");
1005  myGNEConnections.erase(std::find(myGNEConnections.begin(), myGNEConnections.end(), con));
1006  myNet->refreshElement(this); // actually we only do this to force a redraw
1007  }
1008 }
1009 
1010 
1012 GNEEdge::retrieveConnection(int fromLane, NBEdge* to, int toLane) {
1013  for (ConnectionVector::iterator i = myGNEConnections.begin(); i != myGNEConnections.end(); ++i) {
1014  if ((*i)->getFromLaneIndex() == fromLane
1015  && (*i)->getEdgeTo()->getNBEdge() == to
1016  && (*i)->getToLaneIndex() == toLane) {
1017  return *i;
1018  }
1019  }
1020  return new GNEConnection(myLanes[fromLane], myNet->retrieveEdge(to->getID())->getLanes()[toLane]);
1021 }
1022 
1023 
1024 
1025 void
1026 GNEEdge::setMicrosimID(const std::string& newID) {
1028  for (LaneVector::iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
1029  (*i)->setMicrosimID(getNBEdge()->getLaneID((*i)->getIndex()));
1030  }
1031 }
1032 
1033 
1034 void
1036  // First check that additional wasn't already inserted
1037  if (std::find(myAdditionals.begin(), myAdditionals.end(), additional) != myAdditionals.end()) {
1038  throw ProcessError(toString(additional->getTag()) + " with ID='" + additional->getID() + "' was already inserted in " + toString(getTag()) + " with ID='" + getID() + "'");
1039  } else {
1040  myAdditionals.push_back(additional);
1041  // update geometry is needed for stacked additionals (routeProbes and Vaporicers)
1042  updateGeometry();
1043  }
1044 }
1045 
1046 
1047 void
1049  // First check that additional was already inserted
1050  AdditionalVector::iterator it = std::find(myAdditionals.begin(), myAdditionals.end(), additional);
1051  if (it == myAdditionals.end()) {
1052  throw ProcessError(toString(additional->getTag()) + " with ID='" + additional->getID() + "' doesn't exist in " + toString(getTag()) + " with ID='" + getID() + "'");
1053  } else {
1054  myAdditionals.erase(it);
1055  // update geometry is needed for stacked additionals (routeProbes and Vaporicers)
1056  updateGeometry();
1057  }
1058 }
1059 
1060 
1061 const std::vector<GNEAdditional*>&
1063  return myAdditionals;
1064 }
1065 
1066 
1067 void
1069  if (std::find(myReroutes.begin(), myReroutes.end(), rerouter) == myReroutes.end()) {
1070  myReroutes.push_back(rerouter);
1071  } else {
1072  throw ProcessError(toString(rerouter->getTag()) + " '" + rerouter->getID() + "' was previously inserted");
1073  }
1074 }
1075 
1076 
1077 void
1079  std::vector<GNERerouter*>::iterator it = std::find(myReroutes.begin(), myReroutes.end(), rerouter);
1080  if (it != myReroutes.end()) {
1081  myReroutes.erase(it);
1082  } else {
1083  throw ProcessError(toString(rerouter->getTag()) + " '" + rerouter->getID() + "' wasn't previously inserted");
1084  }
1085 }
1086 
1087 
1088 const std::vector<GNERerouter*>&
1090  return myReroutes;
1091 }
1092 
1093 
1094 int
1096  return (int)myReroutes.size();
1097 }
1098 
1099 
1100 bool
1102  for (std::vector<GNELane*>::const_iterator i = myLanes.begin(); i != myLanes.end(); i++) {
1103  if ((*i)->isRestricted(vclass)) {
1104  return true;
1105  }
1106  }
1107  return false;
1108 }
1109 
1110 /****************************************************************************/
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge&#39;s lanes&#39; lateral offset is computed.
Definition: NBEdge.h:677
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:910
void copyTemplate(GNEEdge *tpl, GNEUndoList *undolist)
copy edge attributes from tpl
Definition: GNEEdge.cpp:511
void invalidateConnections(bool reallowSetting=false)
invalidate current connections of edge
Definition: NBEdge.cpp:1238
GNEJunction * myGNEJunctionSource
pointer to GNEJunction source
Definition: GNEEdge.h:269
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;.
const std::vector< GNEAdditional * > & getAdditionalChilds() const
return list of additionals associated with this edge
Definition: GNEEdge.cpp:1062
void remakeGNEConnections()
remake connections
Definition: GNEEdge.cpp:417
double rotationDegreeAtOffset(double pos) const
Returns the rotation at the given length.
void addConnection(NBEdge::Connection nbCon, GNEConnection *con)
adds a connection
Definition: GNEEdge.cpp:981
double length2D() const
Returns the length.
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:164
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:890
int toLane
The lane the connections yields in.
Definition: NBEdge.h:190
const std::vector< T > & getSchemes() const
GNEEdge * retrieveEdge(const std::string &id, bool failHard=true)
get edge by id
Definition: GNENet.cpp:743
double scale
information about a lane&#39;s width (temporary, used for a single view)
GUIVisualizationTextSettings streetName
double laneWidthExaggeration
The lane exaggeration (upscale thickness)
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
Definition: NBEdge.h:270
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:284
void invalidateShape()
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNEEdge.cpp:170
void removeIncomingGNEEdge(GNEEdge *edge)
remove incoming GNEEdge
double z() const
Returns the z-position.
Definition: Position.h:73
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:187
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNEEdge.cpp:139
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:290
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:817
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2846
GNEJunction * myGNEJunctionDestiny
pointer to GNEJunction destiny
Definition: GNEEdge.h:272
PositionVector myOrigShape
restore point for undo
Definition: GNEEdge.h:275
int indexOfClosest(const Position &p) const
index of the closest position to p
void setMicrosimID(const std::string &newID)
override to also set lane ids
Definition: GNEEdge.cpp:1026
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
lane spread functions
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:250
std::set< GUIGlID > getLaneGlIDs()
returns GLIDs of all lanes
Definition: GNEEdge.cpp:533
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2862
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
GUIColorer laneColorer
The lane colorer.
void setLogicValid(bool valid, GNEUndoList *undoList=0, const std::string &status=GUESSED)
Position getPosition() const
Return current position.
Stores the information about how to visualize structures.
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:420
const std::string & getTypeID() const
get ID of type
Definition: NBEdge.h:971
static const double SNAP_RADIUS
Definition: GNEEdge.h:253
double y() const
Returns the y-position.
Definition: Position.h:68
int getNumberOfGNERerouters() const
get number of rerouters that has this edge as parameters
Definition: GNEEdge.cpp:1095
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
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:281
bool hasLaneSpecificSpeed() const
whether lanes differ in speed
Definition: NBEdge.cpp:1756
bool hasRestrictedLane(SUMOVehicleClass vclass) const
check if edge has a restricted lane
Definition: GNEEdge.cpp:1101
double x() const
Returns the x-position.
Definition: Position.h:63
void setStreetName(const std::string &name)
sets the street name of this edge
Definition: NBEdge.h:541
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:1174
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:88
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition: NBEdge.cpp:2670
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:2885
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:54
void setLoadedLength(double val)
set loaded lenght
Definition: NBEdge.cpp:2928
void p_begin(const std::string &description)
Begin undo command sub-group. This begins a new group of commands that are treated as a single comman...
Definition: GNEUndoList.cpp:82
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:570
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
Definition: NBEdge.h:199
double endOffset
This lane&#39;s offset to the intersection begin.
Definition: NBEdge.h:141
void clearGNEConnections()
clear current connections
Definition: GNEEdge.cpp:460
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
double visibility
custom foe visiblity for connection
Definition: NBEdge.h:208
const std::vector< GNEConnection * > & getGNEConnections()
returns a reference to the GNEConnection vector
Definition: GNEEdge.cpp:549
const std::string & getID() const
Returns the id.
Definition: Named.h:66
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1154
bool myWasSplit
whether this edge was created from a split
Definition: GNEEdge.h:287
~GNEEdge()
Destructor.
Definition: GNEEdge.cpp:93
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:340
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:512
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:38
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:255
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
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:941
whether a feature has been loaded,guessed,modified or approved
virtual GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
Definition: GNEEdge.cpp:239
void removeOutgoingGNEEdge(GNEEdge *edge)
remove outgoing GNEEdge
bool keepClear
whether the junction must be kept clear when using this connection
Definition: NBEdge.h:202
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:124
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:135
void addLane(int index, bool recompute=true)
add lane
Definition: NBEdge.cpp:2699
std::string getAttribute(SumoXMLAttr key) const
Definition: GNEEdge.cpp:561
int getIndex() const
returns the index of the lane
Definition: GNELane.cpp:697
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:1035
bool hasLaneSpecificWidth() const
whether lanes differ in width
Definition: NBEdge.cpp:1767
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
bool hasLaneSpecificEndOffset() const
whether lanes differ in offset
Definition: NBEdge.cpp:1778
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:1068
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:439
const double SUMO_const_halfLaneWidth
Definition: StdDefs.h:49
SVCPermissions preferred
List of vehicle types that are preferred on this lane.
Definition: NBEdge.h:138
const std::vector< GNEEdge * > & getGNEIncomingEdges() const
Returns incoming GNEEdges.
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:413
int fromLane
The lane the connections starts at.
Definition: NBEdge.h:184
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise, the sub-group will be added as a new command into parent group. A matching begin() must have been called previously.
Definition: GNEUndoList.cpp:89
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
void deleteLane(int index, bool recompute=true)
delete lane
Definition: NBEdge.cpp:2734
GNEJunction * retrieveJunction(const std::string &id, bool failHard=true)
get junction by id
Definition: GNENet.cpp:730
A list of positions.
const PositionVector getInnerGeometry() const
Returns the geometry of the edge without the endpoints.
Definition: NBEdge.cpp:482
std::vector< GNERerouter * > myReroutes
list of reroutes that has this edge as parameter
Definition: GNEEdge.h:296
void removeGNERerouter(GNERerouter *rerouter)
remove a reference to a rerouter that has this edge as parameter
Definition: GNEEdge.cpp:1078
friend class GNEChange_Attribute
declare friend class
AdditionalVector myAdditionals
list with the additionals vinculated with this edge
Definition: GNEEdge.h:293
GNEJunction * getGNEJunctionDestiny() const
returns the destination-junction
Definition: GNEEdge.cpp:165
int myPriority
The priority of the edge.
Definition: NBEdge.h:1366
T MIN2(T a, T b)
Definition: StdDefs.h:64
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
const std::string & getStreetName() const
Returns the street name of this edge.
Definition: NBEdge.h:536
const std::vector< GNERerouter * > & getGNERerouters() const
get rerouters vinculated with this edge
Definition: GNEEdge.cpp:1089
edge: the shape in xml-definition
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:234
GUIColorer junctionColorer
The junction colorer.
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
void addOutgoingGNEEdge(GNEEdge *edge)
add outgoing GNEEdge
const std::string getID() const
function to support debugging
int insertAtClosest(const Position &p)
inserts p between the two closest positions and returns the insertion index
double getEndOffset() const
Returns the offset to the destination node.
Definition: NBEdge.h:548
int getVaporizerRelativePosition(GNEVaporizer *vaporizer) const
obtain relative positions of Vaporizer
Definition: GNEEdge.cpp:493
static const double INVALID_OFFSET
a value to signify offsets outside the range of [0, Line.length()]
Definition: GeomHelper.h:59
GNEJunction * getGNEJunctionSource() const
returns the source-junction
Definition: GNEEdge.cpp:159
void incRef(const std::string &debugMsg="")
The connection was given by the user.
Definition: NBEdge.h:115
double speed
The speed allowed on this lane.
Definition: NBEdge.h:132
double width
This lane&#39;s width.
Definition: NBEdge.h:144
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:2913
void removeLane(GNELane *lane)
the number of lanes by one. argument is only used to increase robustness (assertions) ...
Definition: GNEEdge.cpp:948
double getFinalLength() const
get length that will be assigned to the lanes in the final network
Definition: NBEdge.cpp:3128
void updateGeometry()
update pre-computed geometry information
Definition: GNELane.cpp:645
bool hasLaneSpecificPermissions() const
whether lanes differ in allowed vehicle classes
Definition: NBEdge.cpp:1742
virtual GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition: GNEEdge.cpp:147
void decRef(const std::string &debugMsg="")
begin/end of the description of an edge
void setGeometry(PositionVector geom, bool inner)
update edge geometry and inform the lanes
Definition: GNEEdge.cpp:401
GNEEdge(NBEdge &nbe, GNENet *net, bool wasSplit=false, bool loaded=false)
Constructor.
Definition: GNEEdge.cpp:69
double getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:507
bool canParseVehicleClasses(const std::string &classes)
Checks whether the given string contains only known vehicle classes.
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:595
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:57
int getRouteProbeRelativePosition(GNERouteProbe *routeProbe) const
obtain relative positions of RouteProbes
Definition: GNEEdge.cpp:475
ConnectionVector myGNEConnections
vector with the connections of this edge
Definition: GNEEdge.h:281
double getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:523
void setResponsible(bool newVal)
set responsibility for deleting internal strctures
Definition: GNEEdge.cpp:778
const PositionVector & getShape() const
returns the shape of the lane
Definition: GNELane.cpp:621
const std::vector< GNELane * > & getLanes()
returns a reference to the lane vector
Definition: GNEEdge.cpp:543
double length() 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:347
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:834
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
bool isClosed() const
check if PositionVector is closed
void setPreferredVehicleClass(SVCPermissions permissions, int lane=-1)
set preferred Vehicle Class
Definition: NBEdge.cpp:2899
double contPos
custom position for internal junction on this connection
Definition: NBEdge.h:205
void updateJunctionPosition(GNEJunction *junction, const Position &origPos)
update edge geometry after junction move
Definition: GNEEdge.cpp:248
void updateGeometry()
update pre-computed geometry information
Definition: GNEEdge.cpp:115
The popup menu of a globject.
an edge
std::vector< GNEAdditional * > AdditionalVector
Definition of the additionals vector.
Definition: GNEEdge.h:71
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:1350
void renameEdge(GNEEdge *edge, const std::string &newID)
updates the map and reserves new id
Definition: GNENet.cpp:1142
bool isValid(SumoXMLAttr key, const std::string &value)
Definition: GNEEdge.cpp:709
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:1168
const Position & getPosition() const
Definition: NBNode.h:232
void removeExplicitTurnaround(std::string id)
remove edge id from the list of explicit turnarounds
Definition: GNENet.cpp:1192
GUIGlID getGlID() const
Returns the numerical id of the object.
LaneVector myLanes
vectgor with the lanes of this edge
Definition: GNEEdge.h:278
void removeConnection(NBEdge::Connection nbCon)
removes a connection
Definition: GNEEdge.cpp:995
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:364
void push_back_noDoublePos(const Position &p)
insert in back a non double position
static const RGBColor selectionColor
color of selection
Definition: GNENet.h:97
empty max
void removeAdditionalChild(GNEAdditional *additional)
remove additional child from this edge
Definition: GNEEdge.cpp:1048
GNEConnection * retrieveConnection(int fromLane, NBEdge *to, int toLane)
get connection
Definition: GNEEdge.cpp:1012
NBEdge & myNBEdge
the underlying NBEdge
Definition: GNEEdge.h:266
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:427
void mul(double val)
Multiplies both positions with the given value.
Definition: Position.h:113
bool hasString(const std::string &str) const
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.cpp:261
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:456
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:86
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:763
std::vector< GNEConnection * > ConnectionVector
Definition of the connection&#39;s vector.
Definition: GNEEdge.h:68
Boundary getBoundary() const
Returns the street&#39;s geometry.
Definition: GNEEdge.cpp:128
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
NBNode * getNBNode() const
Return net build node.
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition: GNEEdge.cpp:635
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
GUISelectedStorage gSelected
A global holder of selected objects.
void resetEndpoint(const Position &pos, GNEUndoList *undoList)
restores the endpoint to the junction position at the appropriate end
Definition: GNEEdge.cpp:387
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:1155
bool wasSplit()
whether this edge was created from a split
Definition: GNEEdge.cpp:555
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:434
Position getSplitPos(const Position &clickPos)
Definition: GNEEdge.cpp:267
friend class GNEChange_Lane
Friend class.
Definition: GNEEdge.h:60
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:294
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2807
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
void remakeIncomingGNEConnections()
remake connections of all incoming edges
Definition: GNEEdge.cpp:410
a junction
SumoXMLTag getTag() const
get XML Tag assigned to this object