SUMO - Simulation of Urban MObility
GNELane.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
17 // A class for visualizing Lane geometry (adapted from GNELaneWrapper)
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #ifdef _MSC_VER
25 #include <windows_config.h>
26 #else
27 #include <config.h>
28 #endif
29 
30 #include <string>
31 #include <iostream>
32 #include <utility>
37 #include <utils/common/ToString.h>
38 #include <utils/geom/GeomHelper.h>
45 #include <utils/gui/div/GLHelper.h>
49 
50 #include "GNELane.h"
51 #include "GNEEdge.h"
52 #include "GNEJunction.h"
53 #include "GNETLSEditorFrame.h"
54 #include "GNEInternalLane.h"
55 #include "GNEUndoList.h"
56 #include "GNENet.h"
57 #include "GNEChange_Attribute.h"
58 #include "GNEViewNet.h"
59 #include "GNEViewParent.h"
60 #include "GNEConnection.h"
61 #include "GNEShape.h"
62 #include "GNEAdditional.h"
63 #include "GNEChange_Additional.h"
64 
65 // ===========================================================================
66 // FOX callback mapping
67 // ===========================================================================
68 
69 // Object implementation
70 FXIMPLEMENT(GNELane, FXDelegator, 0, 0)
71 
72 // ===========================================================================
73 // method definitions
74 // ===========================================================================
75 
76 GNELane::GNELane(GNEEdge& edge, const int index) :
77  GNENetElement(edge.getNet(), edge.getNBEdge()->getLaneID(index), GLO_LANE, SUMO_TAG_LANE, ICON_LANE),
78  myParentEdge(edge),
79  myIndex(index),
80  mySpecialColor(0),
81  myTLSEditor(0) {
82 }
83 
85  GNENetElement(NULL, "dummyConstructorGNELane", GLO_LANE, SUMO_TAG_LANE, ICON_LOCATEEDGE),
86  myParentEdge(*static_cast<GNEEdge*>(0)),
87  myIndex(-1),
88  mySpecialColor(0),
89  myTLSEditor(0) {
90 }
91 
92 
94 }
95 
96 
97 void
99  const std::vector<NBEdge::Connection>& cons = myParentEdge.getNBEdge()->getConnectionsFromLane(myIndex);
100  int noLinks = (int)cons.size();
101  if (noLinks == 0) {
102  return;
103  }
104  // draw all links
105  glPushMatrix();
106  glTranslated(0, 0, GLO_LANE + 0.1);
107  double w = myParentEdge.getNBEdge()->getLaneWidth(myIndex) / (double) noLinks;
108  double x1 = myParentEdge.getNBEdge()->getLaneWidth(myIndex) / 2;
109  const bool lefthand = OptionsCont::getOptions().getBool("lefthand");
110  for (int i = noLinks; --i >= 0;) {
111  double x2 = x1 - (double)(w / 2.);
113  cons[lefthand ? noLinks - 1 - i : i]);
115  x1 -= w;
116  }
117  glPopMatrix();
118 }
119 
120 
121 void
123  const std::vector<NBEdge::Connection>& cons = myParentEdge.getNBEdge()->getConnectionsFromLane(myIndex);
124  int noLinks = (int)cons.size();
125  if (noLinks == 0) {
126  return;
127  }
128  // draw all links
129  glPushMatrix();
130  glTranslated(0, 0, GLO_LANE + 0.1);
131  double w = myParentEdge.getNBEdge()->getLaneWidth(myIndex) / (double) noLinks;
132  double x1 = myParentEdge.getNBEdge()->getLaneWidth(myIndex) / 2;
133  const bool lefthand = OptionsCont::getOptions().getBool("lefthand");
134  for (int i = noLinks; --i >= 0;) {
135  double x2 = x1 - (double)(w / 2.);
136  int linkNo = cons[lefthand ? noLinks - 1 - i : i].tlLinkNo;
138  x1 -= w;
139  }
140  glPopMatrix();
141 }
142 
143 
144 void
146 }
147 
148 
149 void
151  const Position& end = getShape().back();
152  const Position& f = getShape()[-2];
153  double rot = (double) atan2((end.x() - f.x()), (f.y() - end.y())) * (double) 180.0 / (double)M_PI;
154  glPushMatrix();
155  glPushName(0);
156  glTranslated(0, 0, GLO_JUNCTION + .1); // must draw on top of junction shape
157  glColor3d(1, 1, 1);
158  glTranslated(end.x(), end.y(), 0);
159  glRotated(rot, 0, 0, 1);
160 
161  // draw all links
162  const std::vector<NBEdge::Connection>& edgeCons = myParentEdge.getNBEdge()->myConnections;
163  NBNode* dest = myParentEdge.getNBEdge()->myTo;
164  for (auto i : edgeCons) {
165  if (i.fromLane == myIndex) {
166  LinkDirection dir = dest->getDirection(myParentEdge.getNBEdge(), i.toEdge, OptionsCont::getOptions().getBool("lefthand"));
167  switch (dir) {
168  case LINKDIR_STRAIGHT:
169  GLHelper::drawBoxLine(Position(0, 4), 0, 2, .05);
170  GLHelper::drawTriangleAtEnd(Position(0, 4), Position(0, 1), (double) 1, (double) .25);
171  break;
172  case LINKDIR_LEFT:
173  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
174  GLHelper::drawBoxLine(Position(0, 2.5), 90, 1, .05);
175  GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.5, 2.5), (double) 1, (double) .25);
176  break;
177  case LINKDIR_RIGHT:
178  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
179  GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
180  GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.5, 2.5), (double) 1, (double) .25);
181  break;
182  case LINKDIR_TURN:
183  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
184  GLHelper::drawBoxLine(Position(0, 2.5), 90, .5, .05);
185  GLHelper::drawBoxLine(Position(0.5, 2.5), 180, 1, .05);
186  GLHelper::drawTriangleAtEnd(Position(0.5, 2.5), Position(0.5, 4), (double) 1, (double) .25);
187  break;
189  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
190  GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
191  GLHelper::drawBoxLine(Position(-0.5, 2.5), -180, 1, .05);
192  GLHelper::drawTriangleAtEnd(Position(-0.5, 2.5), Position(-0.5, 4), (double) 1, (double) .25);
193  break;
194  case LINKDIR_PARTLEFT:
195  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
196  GLHelper::drawBoxLine(Position(0, 2.5), 45, .7, .05);
197  GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.2, 1.3), (double) 1, (double) .25);
198  break;
199  case LINKDIR_PARTRIGHT:
200  GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
201  GLHelper::drawBoxLine(Position(0, 2.5), -45, .7, .05);
202  GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.2, 1.3), (double) 1, (double) .25);
203  break;
204  case LINKDIR_NODIR:
205  GLHelper::drawBoxLine(Position(1, 5.8), 245, 2, .05);
206  GLHelper::drawBoxLine(Position(-1, 5.8), 115, 2, .05);
207  glTranslated(0, 5, 0);
208  GLHelper::drawOutlineCircle(0.9, 0.8, 32);
209  glTranslated(0, -5, 0);
210  break;
211  }
212  }
213  }
214  glPopName();
215  glPopMatrix();
216 }
217 
218 
219 void
221  glPushMatrix();
222  glPushName(0);
223  glTranslated(0, 0, GLO_JUNCTION + .1); // must draw on top of junction shape
224  std::vector<NBEdge::Connection> connections = myParentEdge.getNBEdge()->getConnectionsFromLane(myIndex);
225  NBNode* node = myParentEdge.getNBEdge()->getToNode();
226  const Position& startPos = getShape()[-1];
227  for (auto it : connections) {
228  const LinkState state = node->getLinkState(myParentEdge.getNBEdge(), it.toEdge, it.fromLane, it.toLane, it.mayDefinitelyPass, it.tlID);
229  switch (state) {
231  glColor3d(1, 1, 0);
232  break;
234  glColor3d(0, 1, 1);
235  break;
236  case LINKSTATE_MAJOR:
237  glColor3d(1, 1, 1);
238  break;
239  case LINKSTATE_MINOR:
240  glColor3d(.4, .4, .4);
241  break;
242  case LINKSTATE_STOP:
243  glColor3d(.7, .4, .4);
244  break;
245  case LINKSTATE_EQUAL:
246  glColor3d(.7, .7, .7);
247  break;
249  glColor3d(.7, .7, 1);
250  case LINKSTATE_ZIPPER:
251  glColor3d(.75, .5, 0.25);
252  break;
253  default:
254  throw ProcessError("Unexpected LinkState '" + toString(state) + "'");
255  }
256  const Position& endPos = it.toEdge->getLaneShape(it.toLane)[0];
257  glBegin(GL_LINES);
258  glVertex2d(startPos.x(), startPos.y());
259  glVertex2d(endPos.x(), endPos.y());
260  glEnd();
261  GLHelper::drawTriangleAtEnd(startPos, endPos, (double) 1.5, (double) .2);
262  }
263  glPopName();
264  glPopMatrix();
265 }
266 
267 
268 void
270  // Push draw matrix 1
271  glPushMatrix();
272  // Push name
273  glPushName(getGlID());
274  // Traslate to fromt
275  glTranslated(0, 0, getType());
276  // Check if edge parent or this lane is selected
277  const bool selectedEdge = gSelected.isSelected(myParentEdge.getType(), myParentEdge.getGlID());
278  const bool selected = gSelected.isSelected(getType(), getGlID());
279  setLaneColor(s);
280  // start drawing lane checking whether it is not too small
281  const double selectionScale = selected || selectedEdge ? s.selectionScale : 1;
282  double exaggeration = selectionScale * s.laneWidthExaggeration; // * s.laneScaler.getScheme().getColor(getScaleValue(s.laneScaler.getActive()));
283  // XXX apply usefull scale values
284  //exaggeration *= s.laneScaler.getScheme().getColor(getScaleValue(s.laneScaler.getActive()));
285 
286  // recognize full transparency and simply don't draw
287  GLfloat color[4];
288  glGetFloatv(GL_CURRENT_COLOR, color);
289  if (color[3] == 0 || s.scale * exaggeration < s.laneMinSize) {
290  // Pop draw matrix 1
291  glPopMatrix();
292  } else if (s.scale * exaggeration < 1.) {
293  // draw as lines, depending of myShapeColors
294  if (myShapeColors.size() > 0) {
296  } else {
298  }
299  // Pop draw matrix 1
300  glPopMatrix();
301  } else {
302  if (drawAsRailway(s)) {
303  // draw as railway
304  const double halfRailWidth = 0.725 * exaggeration;
305  // Draw box depending of myShapeColors
306  if (myShapeColors.size() > 0) {
308  } else {
310  }
311  // Save current color
312  RGBColor current = GLHelper::getColor();
313  // Set white color
314  glColor3d(1, 1, 1);
315  // Traslate matrix 1
316  glTranslated(0, 0, .1);
317  // Draw Box
319  // Set current color back
320  GLHelper::setColor(current);
321  // Draw crossties
322  drawCrossties(0.3 * exaggeration, 1 * exaggeration, 1 * exaggeration);
323  } else {
324  // Draw as a normal lane, and reduce width to make sure that a selected edge can still be seen
325  const double halfWidth = exaggeration * (myParentEdge.getNBEdge()->getLaneWidth(myIndex) / 2 - (selectedEdge ? .3 : 0));
326  if (myShapeColors.size() > 0) {
328  } else {
330  }
331  }
332  // Pop draw matrix 1
333  glPopMatrix();
334  // only draw details depending of the scale
335  if (s.scale >= 10) {
336  // if exaggeration is 1, draw drawMarkings
337  if (s.laneShowBorders && exaggeration == 1) {
338  drawMarkings(selectedEdge, exaggeration);
339  }
340  // draw ROWs only if target junction has a valid logic)
342  drawArrows();
343  }
344  // Draw direction indicators if the correspondient option is enabled
345  if (s.showLaneDirection) {
346  if (drawAsRailway(s)) {
347  // improve visibility of superposed rail edges
348  setLaneColor(s);
349  } else {
350  glColor3d(0.3, 0.3, 0.3);
351  }
353  }
354  if (s.drawLinkJunctionIndex.show) {
355  drawLinkNo(s);
356  }
357  if (s.drawLinkTLIndex.show) {
358  drawTLSLinkNo(s);
359  }
360  }
361  // If there are texture of restricted lanes to draw, and draw lane icons is enabled in options
362  if ((OptionsCont::getOptions().getBool("disable-laneIcons") == false) && (myLaneRestrictedTexturePositions.size() > 0) && (s.scale >= 10)) {
363  // Declare default width of icon (3)
364  double iconWidth = 1;
365  // Obtain width of icon, if width of lane is different
367  iconWidth = myParentEdge.getNBEdge()->getLaneStruct(myIndex).width / 3;
368  }
369  // Draw list of icons
370  for (int i = 0; i < (int)myLaneRestrictedTexturePositions.size(); i++) {
371  // Push draw matrix 2
372  glPushMatrix();
373  // Set white color
374  glColor3d(1, 1, 1);
375  // Traslate matrix 2
376  glTranslated(myLaneRestrictedTexturePositions.at(i).x(), myLaneRestrictedTexturePositions.at(i).y(), getType() + 0.1);
377  // Rotate matrix 2
378  glRotated(myLaneRestrictedTextureRotations.at(i), 0, 0, -1);
379  glRotated(-90, 0, 0, 1);
380  // draw texture box depending of type of restriction
383  } else if (isRestricted(SVC_BICYCLE)) {
385  } else if (isRestricted(SVC_BUS)) {
387  }
388  // Pop draw matrix 2
389  glPopMatrix();
390  }
391  }
392  }
393  // Pop Name
394  glPopName();
395 }
396 
397 
398 void
399 GNELane::drawMarkings(const bool& selectedEdge, double scale) const {
400  glPushMatrix();
401  glTranslated(0, 0, GLO_EDGE);
402 
403  const double halfWidth = myParentEdge.getNBEdge()->getLaneWidth(myIndex) * 0.5;
404  // optionally draw inverse markings
406  double mw = (halfWidth + SUMO_const_laneOffset + .01) * scale;
407  int e = (int) getShape().size() - 1;
408  for (int i = 0; i < e; ++i) {
409  glPushMatrix();
410  glTranslated(getShape()[i].x(), getShape()[i].y(), 0.1);
411  glRotated(myShapeRotations[i], 0, 0, 1);
412  for (double t = 0; t < myShapeLengths[i]; t += 6) {
413  const double length = MIN2((double)3, myShapeLengths[i] - t);
414  glBegin(GL_QUADS);
415  glVertex2d(-mw, -t);
416  glVertex2d(-mw, -t - length);
417  glVertex2d(halfWidth * 0.5 * scale, -t - length);
418  glVertex2d(halfWidth * 0.5 * scale, -t);
419  glEnd();
420  }
421  glPopMatrix();
422  }
423  }
424 
425  // draw white boundings (and white markings) depending on selection
426  if (selectedEdge) {
427  glTranslated(0, 0, 0.2); // draw selection on top of regular markings
429  } else {
430  glColor3d(1, 1, 1);
431  }
432 
434  getShape(),
436  getShapeLengths(),
437  (halfWidth + SUMO_const_laneOffset) * scale);
438  glPopMatrix();
439 
440 }
441 
442 
445  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
446  buildPopupHeader(ret, app);
448  new FXMenuCommand(ret, ("Copy " + toString(SUMO_TAG_EDGE) + " name to clipboard").c_str(), 0, ret, MID_COPY_EDGE_NAME);
450  // build selection and show parameters menu
453  // build position copy entry
454  buildPositionCopyEntry(ret, false);
455  const int editMode = parent.getVisualisationSettings()->editMode;
456  myTLSEditor = 0;
457  if (editMode != GNE_MODE_CONNECT && editMode != GNE_MODE_TLS && editMode != GNE_MODE_CREATE_EDGE) {
458  // Get icons
459  FXIcon* pedestrianIcon = GUIIconSubSys::getIcon(ICON_LANEPEDESTRIAN);
460  FXIcon* bikeIcon = GUIIconSubSys::getIcon(ICON_LANEBIKE);
461  FXIcon* busIcon = GUIIconSubSys::getIcon(ICON_LANEBUS);
462  // Create basic commands
463  const std::string edgeDesc = toString(SUMO_TAG_EDGE);
464  std::string edgeDescPossibleMulti = edgeDesc;
465  const int edgeSelSize = (int)myNet->retrieveEdges(true).size();
466  if (edgeSelSize && edgeSelSize > 1) {
467  edgeDescPossibleMulti = toString(edgeSelSize) + " " + edgeDesc + "s";
468  }
469  new FXMenuCommand(ret, ("Split " + toString(SUMO_TAG_EDGE) + " here").c_str(), 0, &parent, MID_GNE_EDGE_SPLIT);
470  new FXMenuCommand(ret, ("Split " + toString(SUMO_TAG_EDGE) + "s in both direction here").c_str(), 0, &parent, MID_GNE_EDGE_SPLIT_BIDI);
471  new FXMenuCommand(ret, ("Reverse " + toString(SUMO_TAG_EDGE)).c_str(), 0, &parent, MID_GNE_EDGE_REVERSE);
472  new FXMenuCommand(ret, "Add reverse direction", 0, &parent, MID_GNE_EDGE_ADD_REVERSE);
473  new FXMenuCommand(ret, "Set geometry endpoint here", 0, &parent, MID_GNE_EDGE_SET_ENDPOINT);
474  new FXMenuCommand(ret, "Restore geometry endpoint", 0, &parent, MID_GNE_EDGE_RESET_ENDPOINT);
475  new FXMenuCommand(ret, ("Straighten " + edgeDescPossibleMulti).c_str(), 0, &parent, MID_GNE_EDGE_STRAIGHTEN);
476  new FXMenuCommand(ret, ("Smooth " + edgeDescPossibleMulti).c_str(), 0, &parent, MID_GNE_EDGE_SMOOTH);
477  new FXMenuCommand(ret, ("Straighten elevation of " + edgeDescPossibleMulti).c_str(), 0, &parent, MID_GNE_EDGE_STRAIGHTEN_ELEVATION);
478  new FXMenuCommand(ret, ("Smooth elevation of " + edgeDescPossibleMulti).c_str(), 0, &parent, MID_GNE_EDGE_SMOOTH_ELEVATION);
480  std::string pluralLanes = myNet->retrieveLanes(true).size() > 1 ? "s" : "";
481  new FXMenuCommand(ret, ("Duplicate selected " + toString(SUMO_TAG_LANE) + pluralLanes).c_str(), 0, &parent, MID_GNE_LANE_DUPLICATE);
482  // Create panel for lane operations
483  FXMenuPane* addSpecialLanes = new FXMenuPane(ret);
484  ret->insertMenuPaneChild(addSpecialLanes);
485  FXMenuPane* removeSpecialLanes = new FXMenuPane(ret);
486  ret->insertMenuPaneChild(removeSpecialLanes);
487  FXMenuPane* transformSlanes = new FXMenuPane(ret);
488  ret->insertMenuPaneChild(transformSlanes);
489  // Create menu comands for all add special lanes
490  new FXMenuCommand(addSpecialLanes, "Sidewalks", pedestrianIcon, &parent, MID_GNE_LANE_ADD_SIDEWALK);
491  new FXMenuCommand(addSpecialLanes, "Bikelanes", bikeIcon, &parent, MID_GNE_LANE_ADD_BIKE);
492  new FXMenuCommand(addSpecialLanes, "Buslanes", busIcon, &parent, MID_GNE_LANE_ADD_BUS);
493  // Create menu comands for all remove special lanes and disable it
494  new FXMenuCommand(removeSpecialLanes, "Sidewalks", pedestrianIcon, &parent, MID_GNE_LANE_REMOVE_SIDEWALK);
495  new FXMenuCommand(removeSpecialLanes, "Bikelanes", bikeIcon, &parent, MID_GNE_LANE_REMOVE_BIKE);
496  new FXMenuCommand(removeSpecialLanes, "Buslanes", busIcon, &parent, MID_GNE_LANE_REMOVE_BUS);
497  // Create menu comands for all trasform special lanes and disable it
498  new FXMenuCommand(transformSlanes, "Sidewalks", pedestrianIcon, &parent, MID_GNE_LANE_TRANSFORM_SIDEWALK);
499  new FXMenuCommand(transformSlanes, "Bikelanes", bikeIcon, &parent, MID_GNE_LANE_TRANSFORM_BIKE);
500  new FXMenuCommand(transformSlanes, "Buslanes", busIcon, &parent, MID_GNE_LANE_TRANSFORM_BUS);
501  // add menuCascade for lane operations
502  new FXMenuCascade(ret, ("add restricted " + toString(SUMO_TAG_LANE) + "s").c_str(), 0, addSpecialLanes);
503  new FXMenuCascade(ret, ("remove restricted " + toString(SUMO_TAG_LANE) + "s").c_str(), 0, removeSpecialLanes);
504  new FXMenuCascade(ret, ("transform to restricted " + toString(SUMO_TAG_LANE) + "s").c_str(), 0, transformSlanes);
505  } else {
506  new FXMenuCommand(ret, ("Duplicate " + toString(SUMO_TAG_LANE)).c_str(), 0, &parent, MID_GNE_LANE_DUPLICATE);
507  // Declare flags
508  bool edgeHasSidewalk = myParentEdge.hasRestrictedLane(SVC_PEDESTRIAN);
509  bool edgeHasBikelane = myParentEdge.hasRestrictedLane(SVC_BICYCLE);
510  bool edgeHasBuslane = myParentEdge.hasRestrictedLane(SVC_BUS);
511  // Create panel for lane operations and insert it in ret
512  FXMenuPane* addSpecialLanes = new FXMenuPane(ret);
513  ret->insertMenuPaneChild(addSpecialLanes);
514  FXMenuPane* removeSpecialLanes = new FXMenuPane(ret);
515  ret->insertMenuPaneChild(removeSpecialLanes);
516  FXMenuPane* transformSlanes = new FXMenuPane(ret);
517  ret->insertMenuPaneChild(transformSlanes);
518  // Create menu comands for all add special lanes
519  FXMenuCommand* addSidewalk = new FXMenuCommand(addSpecialLanes, "Sidewalk", pedestrianIcon, &parent, MID_GNE_LANE_ADD_SIDEWALK);
520  FXMenuCommand* addBikelane = new FXMenuCommand(addSpecialLanes, "Bikelane", bikeIcon, &parent, MID_GNE_LANE_ADD_BIKE);
521  FXMenuCommand* addBuslane = new FXMenuCommand(addSpecialLanes, "Buslane", busIcon, &parent, MID_GNE_LANE_ADD_BUS);
522  // Create menu comands for all remove special lanes and disable it
523  FXMenuCommand* removeSidewalk = new FXMenuCommand(removeSpecialLanes, "Sidewalk", pedestrianIcon, &parent, MID_GNE_LANE_REMOVE_SIDEWALK);
524  removeSidewalk->disable();
525  FXMenuCommand* removeBikelane = new FXMenuCommand(removeSpecialLanes, "Bikelane", bikeIcon, &parent, MID_GNE_LANE_REMOVE_BIKE);
526  removeBikelane->disable();
527  FXMenuCommand* removeBuslane = new FXMenuCommand(removeSpecialLanes, "Buslane", busIcon, &parent, MID_GNE_LANE_REMOVE_BUS);
528  removeBuslane->disable();
529  // Create menu comands for all trasform special lanes and disable it
530  FXMenuCommand* transformLaneToSidewalk = new FXMenuCommand(transformSlanes, "Sidewalk", pedestrianIcon, &parent, MID_GNE_LANE_TRANSFORM_SIDEWALK);
531  FXMenuCommand* transformLaneToBikelane = new FXMenuCommand(transformSlanes, "Bikelane", bikeIcon, &parent, MID_GNE_LANE_TRANSFORM_BIKE);
532  FXMenuCommand* transformLaneToBuslane = new FXMenuCommand(transformSlanes, "Buslane", busIcon, &parent, MID_GNE_LANE_TRANSFORM_BUS);
533  // add menuCascade for lane operations
534  FXMenuCascade* cascadeAddSpecialLane = new FXMenuCascade(ret, ("add restricted " + toString(SUMO_TAG_LANE)).c_str(), 0, addSpecialLanes);
535  FXMenuCascade* cascadeRemoveSpecialLane = new FXMenuCascade(ret, ("remove restricted " + toString(SUMO_TAG_LANE)).c_str(), 0, removeSpecialLanes);
536  new FXMenuCascade(ret, ("transform to restricted " + toString(SUMO_TAG_LANE)).c_str(), 0, transformSlanes);
537  // Enable and disable options depending of current transform of the lane
538  if (edgeHasSidewalk) {
539  transformLaneToSidewalk->disable();
540  addSidewalk->disable();
541  removeSidewalk->enable();
542  }
543  if (edgeHasBikelane) {
544  transformLaneToBikelane->disable();
545  addBikelane->disable();
546  removeBikelane->enable();
547  }
548  if (edgeHasBuslane) {
549  transformLaneToBuslane->disable();
550  addBuslane->disable();
551  removeBuslane->enable();
552  }
553  // Check if cascade menus must be disabled
554  if (edgeHasSidewalk && edgeHasBikelane && edgeHasBuslane) {
555  cascadeAddSpecialLane->disable();
556  }
557  if (!edgeHasSidewalk && !edgeHasBikelane && !edgeHasBuslane) {
558  cascadeRemoveSpecialLane->disable();
559  }
560  }
561  } else if (editMode == GNE_MODE_TLS) {
562  myTLSEditor = static_cast<GNEViewNet&>(parent).getViewParent()->getTLSEditorFrame();
564  new FXMenuCommand(ret, "Select state for all links from this edge:", 0, 0, 0);
565  const std::vector<std::string> names = GNEInternalLane::LinkStateNames.getStrings();
566  for (auto it : names) {
567  FXuint state = GNEInternalLane::LinkStateNames.get(it);
568  FXMenuRadio* mc = new FXMenuRadio(ret, it.c_str(), this, FXDataTarget::ID_OPTION + state);
569  mc->setSelBackColor(MFXUtils::getFXColor(GNEInternalLane::colorForLinksState(state)));
571  }
572  }
573  } else {
574  FXMenuCommand* mc = new FXMenuCommand(ret, "Additional options available in 'Inspect Mode'", 0, 0, 0);
575  mc->handle(&parent, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), 0);
576  }
577  // buildShowParamsPopupEntry(ret, false);
578  new FXMenuSeparator(ret);
579  const double pos = getShape().nearest_offset_to_point2D(parent.getPositionInformation());
580  const double height = getShape().positionAtOffset2D(getShape().nearest_offset_to_point2D(parent.getPositionInformation())).z();
581  new FXMenuCommand(ret, ("Shape pos: " + toString(pos)).c_str(), 0, 0, 0);
582  new FXMenuCommand(ret, ("Length pos: " + toString(pos * getLaneParametricLength() / getLaneShapeLength())).c_str(), 0, 0, 0);
583  new FXMenuCommand(ret, ("Height: " + toString(height)).c_str(), 0, 0, 0);
584  // new FXMenuSeparator(ret);
585  // buildPositionCopyEntry(ret, false);
586  return ret;
587 }
588 
589 
590 Boundary
593  b.grow(10);
594  return b;
595 }
596 
597 
598 const PositionVector&
601 }
602 
603 
604 const std::vector<double>&
606  return myShapeRotations;
607 }
608 
609 
610 const std::vector<double>&
612  return myShapeLengths;
613 }
614 
615 
616 Boundary
619 }
620 
621 
622 void
624  // Clear containers
625  myShapeRotations.clear();
626  myShapeLengths.clear();
629  //double length = myParentEdge.getLength(); // @todo see ticket #448
630  // may be different from length
631 
632  // Obtain lane and shape rotations
633  int segments = (int) getShape().size() - 1;
634  if (segments >= 0) {
635  myShapeRotations.reserve(segments);
636  myShapeLengths.reserve(segments);
637  for (int i = 0; i < segments; ++i) {
638  const Position& f = getShape()[i];
639  const Position& s = getShape()[i + 1];
640  myShapeLengths.push_back(f.distanceTo2D(s));
641  myShapeRotations.push_back((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double)M_PI);
642  }
643  }
644  // Update geometry of additionals chiolds vinculated with this lane
645  for (auto i : myAdditionalChilds) {
646  i->updateGeometry();
647  }
648  // Update geometry of additionals àremtvinculated with this lane
649  for (auto i : myAdditionalParents) {
650  i->updateGeometry();
651  }
652  // Update geometry of Shapes vinculated with this lane
653  for (auto i : myShapes) {
654  i->updateGeometry();
655  }
656  // In Move mode, connections aren't updated
658  // Update incoming connections of this lane
659  auto incomingConnections = getGNEIncomingConnections();
660  for (auto i : incomingConnections) {
661  i->updateGeometry();
662  }
663  // Update outgoings connections of this lane
664  auto outGoingConnections = getGNEOutcomingConnections();
665  for (auto i : outGoingConnections) {
666  i->updateGeometry();
667  }
668  }
669  // If lane has enought length for show textures of restricted lanes
670  if ((getLaneShapeLength() > 4)) {
671  // if lane is restricted
673  // get values for position and rotation of icons
674  for (int i = 2; i < getLaneShapeLength() - 1; i += 15) {
675  myLaneRestrictedTexturePositions.push_back(getShape().positionAtOffset(i));
676  myLaneRestrictedTextureRotations.push_back(getShape().rotationDegreeAtOffset(i));
677  }
678  }
679  }
680 }
681 
682 int
684  return myIndex;
685 }
686 
687 void
688 GNELane::setIndex(int index) {
689  myIndex = index;
691 }
692 
693 
694 double
697 }
698 
699 
700 double
702  double laneParametricLenght = myParentEdge.getNBEdge()->getLoadedLength();
703  if (laneParametricLenght > 0) {
704  return laneParametricLenght;
705  } else {
706  throw ProcessError("Lane Parametric Lenght cannot be never 0");
707  }
708 }
709 
710 
711 double
713  return getShape().length();
714 }
715 
716 
717 void
719  // Check if Shape exist before remove
720  if (std::find(myShapes.begin(), myShapes.end(), shape) == myShapes.end()) {
721  myShapes.push_back(shape);
722  // update Geometry of shape after add
723  shape->updateGeometry();
724  } else {
725  throw ProcessError(toString(shape->getTag()) + " with ID='" + shape->getID() + "' was already inserted in lane with ID='" + getID() + "'");
726  }
727 }
728 
729 
730 void
732  auto it = std::find(myShapes.begin(), myShapes.end(), shape);
733  // Check if Shape exist before remove
734  if (it != myShapes.end()) {
735  myShapes.erase(it);
736  } else {
737  throw ProcessError(toString(shape->getTag()) + " with ID='" + shape->getID() + "' doesn't exist in lane with ID='" + getID() + "'");
738  }
739 }
740 
741 
742 const std::vector<GNEShape*>&
744  return myShapes;
745 }
746 
747 
748 bool
750  return myParentEdge.getNBEdge()->getPermissions(myIndex) == vclass;
751 }
752 
753 
754 std::string
756  const NBEdge* edge = myParentEdge.getNBEdge();
757  switch (key) {
758  case SUMO_ATTR_ID:
759  return getMicrosimID();
760  case SUMO_ATTR_SPEED:
761  return toString(edge->getLaneSpeed(myIndex));
762  case SUMO_ATTR_ALLOW:
764  case SUMO_ATTR_DISALLOW:
766  case SUMO_ATTR_WIDTH:
768  return "default";
769  } else {
770  return toString(edge->getLaneStruct(myIndex).width);
771  }
772  case SUMO_ATTR_ENDOFFSET:
773  return toString(edge->getLaneStruct(myIndex).endOffset);
775  return toString(edge->getLaneStruct(myIndex).accelRamp);
777  return toString(edge->getLaneStruct(myIndex).customShape);
778  case SUMO_ATTR_INDEX:
779  return toString(myIndex);
780  default:
781  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
782  }
783 }
784 
785 std::string
787  std::string result = getAttribute(key);
788  if ((key == SUMO_ATTR_ALLOW || key == SUMO_ATTR_DISALLOW) && result.find("all") != std::string::npos) {
789  result += " " + getVehicleClassNames(SVCAll, true);
790  }
791  return result;
792 }
793 
794 
795 void
796 GNELane::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
797  switch (key) {
798  case SUMO_ATTR_ID:
799  throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + toString(getTag()) + " isn't allowed");
800  case SUMO_ATTR_SPEED:
801  case SUMO_ATTR_ALLOW:
802  case SUMO_ATTR_DISALLOW:
803  case SUMO_ATTR_WIDTH:
804  case SUMO_ATTR_ENDOFFSET:
807  case SUMO_ATTR_INDEX:
808  // no special handling
809  undoList->p_add(new GNEChange_Attribute(this, key, value));
810  break;
811  default:
812  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
813  }
814 }
815 
816 
817 bool
818 GNELane::isValid(SumoXMLAttr key, const std::string& value) {
819  switch (key) {
820  case SUMO_ATTR_ID:
821  return false;
822  case SUMO_ATTR_SPEED:
823  return canParse<double>(value);
824  case SUMO_ATTR_ALLOW:
825  case SUMO_ATTR_DISALLOW:
826  return canParseVehicleClasses(value);
827  case SUMO_ATTR_WIDTH:
828  if (value == "default") {
829  return true;
830  } else {
831  return canParse<double>(value) && (isPositive<double>(value) || parse<double>(value) == NBEdge::UNSPECIFIED_WIDTH);
832  }
833  case SUMO_ATTR_ENDOFFSET:
834  return canParse<double>(value);
836  return canParse<bool>(value);
837  case SUMO_ATTR_CUSTOMSHAPE: {
838  bool ok = true;
839  PositionVector shape = GeomConvHelper::parseShapeReporting(value, "user-supplied position", 0, ok, true);
840  return ok;
841  }
842  case SUMO_ATTR_INDEX:
843  return canParse<int>(value) && (parse<int>(value) == myIndex);
844  default:
845  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
846  }
847 }
848 
849 
850 void
852  mySpecialColor = color;
853 }
854 
855 // ===========================================================================
856 // private
857 // ===========================================================================
858 
859 void
860 GNELane::setAttribute(SumoXMLAttr key, const std::string& value) {
861  NBEdge* edge = myParentEdge.getNBEdge();
862  switch (key) {
863  case SUMO_ATTR_ID:
864  throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + toString(getTag()) + " isn't allowed");
865  case SUMO_ATTR_SPEED:
866  edge->setSpeed(myIndex, parse<double>(value));
867  break;
868  case SUMO_ATTR_ALLOW:
870  updateGeometry();
871  myNet->getViewNet()->update();
872  break;
873  case SUMO_ATTR_DISALLOW:
875  updateGeometry();
876  myNet->getViewNet()->update();
877  break;
878  case SUMO_ATTR_WIDTH:
879  if (value == "default") {
881  } else {
882  edge->setLaneWidth(myIndex, parse<double>(value));
883  }
884  updateGeometry();
885  myNet->getViewNet()->update();
886  break;
887  case SUMO_ATTR_ENDOFFSET:
888  edge->setEndOffset(myIndex, parse<double>(value));
889  break;
891  edge->setAcceleration(myIndex, parse<bool>(value));
892  break;
893  case SUMO_ATTR_CUSTOMSHAPE: {
894  bool ok;
895  edge->setLaneShape(myIndex, GeomConvHelper::parseShapeReporting(value, "user-supplied position", 0, ok, true));
896  break;
897  }
898  default:
899  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
900  }
901 }
902 
903 
904 void
906  const bool selectedEdge = gSelected.isSelected(myParentEdge.getType(), myParentEdge.getGlID());
907  const bool selected = gSelected.isSelected(getType(), getGlID());
908  if (mySpecialColor != 0) {
909  // If special color is enabled, set it
911  } else if (selected && s.laneColorer.getActive() != 1) {
912  // override with special colors (unless the color scheme is based on selection)
914  } else if (selectedEdge && s.laneColorer.getActive() != 1) {
915  // override with special colors (unless the color scheme is based on selection)
917  } else {
918  // Get normal lane color
919  const GUIColorer& c = s.laneColorer;
920  if (!setFunctionalColor(c.getActive()) && !setMultiColor(c)) {
922  }
923  }
924 }
925 
926 bool
927 GNELane::setFunctionalColor(int activeScheme) const {
928  switch (activeScheme) {
929  case 6: {
930  double hue = GeomHelper::naviDegree(getShape().beginEndAngle()); // [0-360]
932  return true;
933  }
934  default:
935  return false;
936  }
937 }
938 
939 
940 bool
942  const int activeScheme = c.getActive();
943  myShapeColors.clear();
944  switch (activeScheme) {
945  case 9: // color by height at segment start
946  for (PositionVector::const_iterator ii = getShape().begin(); ii != getShape().end() - 1; ++ii) {
947  myShapeColors.push_back(c.getScheme().getColor(ii->z()));
948  }
949  return true;
950  case 11: // color by inclination at segment start
951  for (int ii = 1; ii < (int)getShape().size(); ++ii) {
952  const double inc = (getShape()[ii].z() - getShape()[ii - 1].z()) / MAX2(POSITION_EPS, getShape()[ii].distanceTo2D(getShape()[ii - 1]));
953  myShapeColors.push_back(c.getScheme().getColor(inc));
954  }
955  return true;
956  default:
957  return false;
958  }
959 }
960 
961 
962 double
963 GNELane::getColorValue(int activeScheme) const {
964  const SVCPermissions myPermissions = myParentEdge.getNBEdge()->getPermissions(myIndex);
965  switch (activeScheme) {
966  case 0:
967  switch (myPermissions) {
968  case SVC_PEDESTRIAN:
969  return 1;
970  case SVC_BICYCLE:
971  return 2;
972  case 0:
973  return 3;
974  case SVC_SHIP:
975  return 4;
976  default:
977  break;
978  }
979  if ((myPermissions & SVC_PASSENGER) != 0 || isRailway(myPermissions)) {
980  return 0;
981  } else {
982  return 5;
983  }
984  case 1:
985  return gSelected.isSelected(getType(), getGlID()) ||
986  gSelected.isSelected(GLO_EDGE, dynamic_cast<GNEEdge*>(&myParentEdge)->getGlID());
987  case 2:
988  return (double)myPermissions;
989  case 3:
991  case 4:
992  return myParentEdge.getNBEdge()->getNumLanes();
993  case 5: {
995  }
996  // case 6: by angle (functional)
997  case 7: {
998  return myParentEdge.getNBEdge()->getPriority();
999  }
1000  case 8: {
1001  // color by z of first shape point
1002  return getShape()[0].z();
1003  }
1004  // case 9: by segment height
1005  case 10: {
1006  // color by incline
1007  return (getShape()[-1].z() - getShape()[0].z()) / myParentEdge.getNBEdge()->getLength();
1008  }
1009  }
1010  return 0;
1011 }
1012 
1013 
1014 void
1016  // iterate over all additional parents of lane
1017  for (auto i : myAdditionalParents) {
1018  // Obtain attribute LANES of additional
1019  std::vector<std::string> laneIDs = parse<std::vector<std::string> >(i->getAttribute(SUMO_ATTR_LANES));
1020  // check that at least there is an lane
1021  if (laneIDs.empty()) {
1022  throw ProcessError("Additional lane childs is empty");
1023  } else if ((laneIDs.size() == 1) && (allowEmpty == false)) {
1024  // remove entire Additional if SUMO_ATTR_LANES cannot be empty
1025  if (laneIDs.front() == getID()) {
1026  undoList->add(new GNEChange_Additional(i, false), true);
1027  } else {
1028  throw ProcessError("lane ID wasnt' found in Additional");
1029  }
1030  } else {
1031  auto it = std::find(laneIDs.begin(), laneIDs.end(), getID());
1032  if (it != laneIDs.end()) {
1033  // set new attribute in Additional
1034  laneIDs.erase(it);
1035  i->setAttribute(SUMO_ATTR_LANES, toString(laneIDs), undoList);
1036  } else {
1037  throw ProcessError("lane ID wasnt' found in Additional");
1038  }
1039  }
1040  }
1041 }
1042 
1043 
1044 bool
1047 }
1048 
1049 
1050 bool
1052  return isWaterway(myParentEdge.getNBEdge()->getPermissions(myIndex)) && s.showRails; // reusing the showRails setting
1053 }
1054 
1055 
1056 void
1057 GNELane::drawCrossties(double length, double spacing, double halfWidth) const {
1058  glPushMatrix();
1059  // draw on top of of the white area between the rails
1060  glTranslated(0, 0, 0.1);
1061  int e = (int) getShape().size() - 1;
1062  for (int i = 0; i < e; ++i) {
1063  glPushMatrix();
1064  glTranslated(getShape()[i].x(), getShape()[i].y(), 0.0);
1065  glRotated(myShapeRotations[i], 0, 0, 1);
1066  for (double t = 0; t < myShapeLengths[i]; t += spacing) {
1067  glBegin(GL_QUADS);
1068  glVertex2d(-halfWidth, -t);
1069  glVertex2d(-halfWidth, -t - length);
1070  glVertex2d(halfWidth, -t - length);
1071  glVertex2d(halfWidth, -t);
1072  glEnd();
1073  }
1074  glPopMatrix();
1075  }
1076  glPopMatrix();
1077 }
1078 
1079 
1080 void
1082  const double width = myParentEdge.getNBEdge()->getLaneWidth(myIndex);
1083  glPushMatrix();
1084  glTranslated(0, 0, GLO_JUNCTION + 0.1);
1085  int e = (int) getShape().size() - 1;
1086  for (int i = 0; i < e; ++i) {
1087  glPushMatrix();
1088  glTranslated(getShape()[i].x(), getShape()[i].y(), 0.1);
1089  glRotated(myShapeRotations[i], 0, 0, 1);
1090  for (double t = 0; t < myShapeLengths[i]; t += width) {
1091  const double length = MIN2(width * 0.5, myShapeLengths[i] - t);
1092  glBegin(GL_TRIANGLES);
1093  glVertex2d(0, -t - length);
1094  glVertex2d(-width * 0.25, -t);
1095  glVertex2d(+width * 0.25, -t);
1096  glEnd();
1097  }
1098  glPopMatrix();
1099  }
1100  glPopMatrix();
1101 }
1102 
1103 
1104 
1105 const std::string&
1107  return myParentEdge.getMicrosimID();
1108 }
1109 
1110 
1111 long
1112 GNELane::onDefault(FXObject* obj, FXSelector sel, void* data) {
1113  if (myTLSEditor != 0) {
1114  myTLSEditor->handleMultiChange(this, obj, sel, data);
1115  }
1116  return 1;
1117 }
1118 
1119 
1120 GNEEdge&
1122  return myParentEdge;
1123 }
1124 
1125 
1126 std::vector<GNEConnection*>
1128  // Declare a vector to save incoming connections
1129  std::vector<GNEConnection*> incomingConnections;
1130  // Obtain incoming edges if junction source was already created
1131  GNEJunction* junctionSource = myParentEdge.getGNEJunctionSource();
1132  if (junctionSource) {
1133  // Iterate over incoming GNEEdges of junction
1134  for (auto i : junctionSource->getGNEIncomingEdges()) {
1135  // Iterate over connection of incoming edges
1136  for (auto j : i->getGNEConnections()) {
1137  if (j->getNBEdgeConnection().fromLane == getIndex()) {
1138  incomingConnections.push_back(j);
1139  }
1140  }
1141  }
1142  }
1143  return incomingConnections;
1144 }
1145 
1146 
1147 std::vector<GNEConnection*>
1149  // Obtain GNEConnection of edge parent
1150  const std::vector<GNEConnection*>& edgeConnections = myParentEdge.getGNEConnections();
1151  std::vector<GNEConnection*> outcomingConnections;
1152  // Obtain outgoing connections
1153  for (auto i : edgeConnections) {
1154  if (i->getNBEdgeConnection().fromLane == getIndex()) {
1155  outcomingConnections.push_back(i);
1156  }
1157  }
1158  return outcomingConnections;
1159 }
1160 
1161 
1162 void
1164  // update incoming connections of lane
1165  std::vector<GNEConnection*> incomingConnections = getGNEIncomingConnections();
1166  for (auto i : incomingConnections) {
1167  i->updateID();
1168  }
1169  // update outocming connections of lane
1170  std::vector<GNEConnection*> outcomingConnections = getGNEOutcomingConnections();
1171  for (auto i : outcomingConnections) {
1172  i->updateID();
1173  }
1174 }
1175 
1176 /****************************************************************************/
bool drawAsWaterway(const GUIVisualizationSettings &s) const
whether to draw this lane as a waterways
Definition: GNELane.cpp:1051
static void drawTexturedBox(int which, double size)
Draws a named texture as a box with the given size.
double getLaneShapeLength() const
returns the length of the lane&#39;s shape
Definition: GNELane.cpp:712
EditMode getCurrentEditMode() const
get the current edit mode
The link is a partial left direction.
void setLaneColor(const GUIVisualizationSettings &s) const
set color according to edit mode and visualisation settings
Definition: GNELane.cpp:905
std::string getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a &#39; &#39;.
double z() const
Returns the z-position.
Definition: Position.h:72
std::vector< double > myShapeLengths
The lengths of the shape parts.
Definition: GNELane.h:211
std::vector< GNELane * > retrieveLanes(bool onlySelected=false)
return all lanes
Definition: GNENet.cpp:986
bool controlsEdge(GNEEdge &edge) const
whether the given edge is controlled by the currently edited tlDef
std::vector< GNEAdditional * > myAdditionalParents
list of Additional parents of this NetElement
const std::string & getParentName() const
Returns the name of the parent object.
Definition: GNELane.cpp:1106
double scale
information about a lane&#39;s width (temporary, used for a single view)
double laneWidthExaggeration
The lane exaggeration (upscale thickness)
GNEJunction * getGNEJunctionSource() const
returns the source-junction
Definition: GNEEdge.cpp:317
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:249
PositionVector shape
The lane&#39;s shape.
Definition: NBEdge.h:126
whether a given shape is user-defined
GNENet * myNet
the net to inform about updates
is a pedestrian
mode for moving things
Definition: GNEViewNet.h:52
GNETLSEditorFrame * myTLSEditor
the tls-editor for setting multiple links in TLS-mode
Definition: GNELane.h:230
static void drawBoxLines(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double width, int cornerDetail=0, double offset=0)
Draws thick lines.
Definition: GLHelper.cpp:183
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
begin/end of the description of a single lane
restore geometry endpoint to node position
Definition: GUIAppEnum.h:691
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition: GNELane.cpp:444
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
NBNode * myTo
Definition: NBEdge.h:1376
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2950
const std::vector< GNEShape * > & getShapeChilds() const
get shape childs of lane
Definition: GNELane.cpp:743
const RGBColor * mySpecialColor
optional special color
Definition: GNELane.h:224
static const RGBColor selectedLaneColor
color of selected lane
Definition: GNENet.h:110
static void drawTextAtEnd(const std::string &text, const PositionVector &shape, double x, double size, RGBColor color)
draw text and the end of shape
Definition: GLHelper.cpp:543
static RGBColor fromHSV(double h, double s, double v)
Converts the given hsv-triplet to rgb.
Definition: RGBColor.cpp:301
std::vector< Connection > getConnectionsFromLane(int lane) const
Returns connections from a given lane.
Definition: NBEdge.cpp:1037
static GUIGlID getTexture(GUITexture which)
returns a texture previously defined in the enum GUITexture
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn&#39;t set.
Definition: NBEdge.h:489
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
transform lane to busLane
Definition: GUIAppEnum.h:774
int getConnectionIndex(const NBEdge *from, const NBEdge::Connection &con) const
return the index of the given connection
Definition: NBNode.cpp:2698
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2966
GUIColorer laneColorer
The lane colorer.
double x() const
Returns the x-position.
Definition: Position.h:62
Stores the information about how to visualize structures.
This is an uncontrolled, minor link, has to stop.
vehicle is a bicycle
add bikelane
Definition: GUIAppEnum.h:778
bool isRestricted(SUMOVehicleClass vclass) const
check if this lane is restricted
Definition: GNELane.cpp:749
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
std::string getAttributeForSelection(SumoXMLAttr key) const
method for getting the attribute in the context of object selection
Definition: GNELane.cpp:786
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
The representation of a single edge during network building.
Definition: NBEdge.h:70
bool showRails
Information whether rails shall be drawn.
The link is a 180 degree turn.
Copy edge name (for lanes only)
Definition: GUIAppEnum.h:232
static RGBColor colorForLinksState(FXuint state)
return the color for each linkstate
bool hasRestrictedLane(SUMOVehicleClass vclass) const
check if edge has a restricted lane
Definition: GNEEdge.cpp:1236
mode for editing tls
Definition: GNEViewNet.h:62
smooth elevation with regard to adjoining edges
Definition: GUIAppEnum.h:699
set non-default geometry endpoint
Definition: GUIAppEnum.h:689
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
bool setFunctionalColor(int activeScheme) const
sets the color according to the current scheme index and some lane function
Definition: GNELane.cpp:927
T MAX2(T a, T b)
Definition: StdDefs.h:73
double getColorValue(int activeScheme) const
return value for lane coloring according to the given scheme
Definition: GNELane.cpp:963
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
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:2997
add busLane
Definition: GUIAppEnum.h:780
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:53
transform lane to bikelane
Definition: GUIAppEnum.h:772
int editMode
the current NETEDIT mode (temporary)
bool showLaneDirection
Whether to show direction indicators for lanes.
bool setMultiColor(const GUIColorer &c) const
sets multiple colors according to the current scheme index and some lane function ...
Definition: GNELane.cpp:941
double endOffset
This lane&#39;s offset to the intersection begin.
Definition: NBEdge.h:138
bool laneShowBorders
Information whether lane borders shall be drawn.
GNELane()
FOX needs this.
Definition: GNELane.cpp:84
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
std::vector< RGBColor > myShapeColors
The color of the shape parts (cached)
Definition: GNELane.h:227
This is an uncontrolled, right-before-left link.
const double SUMO_const_laneOffset
Definition: StdDefs.h:52
const std::vector< GNEConnection * > & getGNEConnections()
returns a reference to the GNEConnection vector
Definition: GNEEdge.cpp:659
void handleMultiChange(GNELane *lane, FXObject *obj, FXSelector sel, void *data)
update phase definition for the current traffic light and phase
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
const SVCPermissions SVCAll
all VClasses are allowed
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1177
The link is controlled by a tls which is off, not blinking, may pass.
This is an uncontrolled, all-way stop link.
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to copy the cursor position if geo projection is used, also builds an entry for copying the geo-position.
Boundary getBoundary() const
returns the boundry (including lanes)
Definition: GNELane.cpp:617
int getIndex() const
returns the index of the lane
Definition: GNELane.cpp:683
GUIGlID getGlID() const
Returns the numerical id of the object.
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:254
void setIndex(int index)
Definition: GNELane.cpp:688
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:47
int myIndex
The index of this lane.
Definition: GNELane.h:203
This is an uncontrolled, zipper-merge link.
The link is a (hard) left direction.
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:64
void setLaneShape(int lane, const PositionVector &shape)
sets a custom lane shape
Definition: NBEdge.cpp:2989
bool accelRamp
Whether this lane is an acceleration lane.
Definition: NBEdge.h:147
void setAcceleration(int lane, bool accelRamp)
marks one lane as acceleration lane
Definition: NBEdge.cpp:2981
std::vector< double > myLaneRestrictedTextureRotations
Rotations of textures of restricted lanes.
Definition: GNELane.h:217
SVCPermissions invertPermissions(SVCPermissions permissions)
negate the given permissions and ensure that only relevant bits are set
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
std::vector< std::string > getStrings() const
The link is a straight direction.
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
double getSpeed() const
returns the current speed of lane
Definition: GNELane.cpp:695
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
bool drawAsRailway(const GUIVisualizationSettings &s) const
whether to draw this lane as a railway
Definition: GNELane.cpp:1045
void drawDirectionIndicators() const
direction indicators for lanes
Definition: GNELane.cpp:1081
remove busLane
Definition: GUIAppEnum.h:786
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
static double naviDegree(const double angle)
Definition: GeomHelper.cpp:186
void drawLane2LaneConnections() const
draw lane to lane connections
Definition: GNELane.cpp:220
double getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:522
void drawArrows() const
draw arrows
Definition: GNELane.cpp:150
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:419
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:449
GNEEdge & getParentEdge()
Returns underlying parent edge.
Definition: GNELane.cpp:1121
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition: GNELane.cpp:796
void drawTLSLinkNo(const GUIVisualizationSettings &s) const
draw TLS Link Number
Definition: GNELane.cpp:122
This is an uncontrolled, minor link, has to brake.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:45
const std::vector< double > & getShapeRotations() const
returns the vector with the shape rotations
Definition: GNELane.cpp:605
A list of positions.
bool isLogicValid()
whether this junction has a valid logic
add reverse edge
Definition: GUIAppEnum.h:707
bool isWaterway(SVCPermissions permissions)
Returns whether an edge with the given permission is a waterway edge.
void removeLaneOfAdditionalParents(GNEUndoList *undoList, bool allowEmpty)
remove lane of Additional Parent
Definition: GNELane.cpp:1015
std::vector< double > myShapeRotations
Definition: GNELane.h:208
friend class GNEChange_Attribute
declare friend class
double y() const
Returns the y-position.
Definition: Position.h:67
std::vector< GNEConnection * > getGNEIncomingConnections()
returns a vector with the incoming GNEConnections of this lane
Definition: GNELane.cpp:1127
void addShapeChild(GNEShape *shape)
add shape child to this lane
Definition: GNELane.cpp:718
smooth geometry
Definition: GUIAppEnum.h:695
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:412
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
const T getColor(const double value) const
double length() const
Returns the length.
virtual void updateGeometry()=0
update pre-computed geometry information
GUIVisualizationTextSettings drawLinkTLIndex
T MIN2(T a, T b)
Definition: StdDefs.h:67
static void drawOutlineCircle(double width, double iwidth, int steps=8)
Draws an unfilled circle around (0,0)
Definition: GLHelper.cpp:381
The link is a (hard) right direction.
#define POSITION_EPS
Definition: config.h:175
split an edge
Definition: GUIAppEnum.h:703
LinkState getLinkState(const NBEdge *incoming, NBEdge *outgoing, int fromLane, int toLane, bool mayDefinitelyPass, const std::string &tlID) const
get link state
Definition: NBNode.cpp:1606
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:301
std::vector< GNEShape * > myShapes
list with the shapes vinculated with this lane
Definition: GNELane.h:221
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
remove bikelane
Definition: GUIAppEnum.h:784
duplicate a lane
Definition: GUIAppEnum.h:768
void drawMarkings(const bool &selectedEdge, double scale) const
draw lane markings
Definition: GNELane.cpp:399
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition: GLHelper.cpp:276
const std::string getID() const
function to support debugging
std::vector< GNEConnection * > getGNEOutcomingConnections()
returns a vector with the outgoing GNEConnections of this lane
Definition: GNELane.cpp:1148
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream&#39;s direction.
Definition: NBNode.cpp:1539
reverse an edge
Definition: GUIAppEnum.h:705
std::vector< Connection > myConnections
List of connections to following edges.
Definition: NBEdge.h:1397
double laneMinSize
The minimum visual lane width for drawing.
The link is a partial right direction.
double width
This lane&#39;s width.
Definition: NBEdge.h:141
vehicle is a passenger car (a "normal" car)
void updateGeometry()
update pre-computed geometry information
Definition: GNELane.cpp:623
is an arbitrary ship
begin/end of the description of an edge
bool canParseVehicleClasses(const std::string &classes)
Checks whether the given string contains only known vehicle classes.
std::string getAttribute(SumoXMLAttr key) const
This functions has to be implemented in all GNEAttributeCarriers.
Definition: GNELane.cpp:755
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:56
const std::vector< double > & getShapeLengths() const
returns the vector with the shape lengths
Definition: GNELane.cpp:611
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:3025
void drawLinkRules() const
draw link rules
Definition: GNELane.cpp:145
GNEEdge & myParentEdge
The Edge that to which this lane belongs.
Definition: GNELane.h:200
vehicle is a bus
double getLaneSpeed(int lane) const
get lane speed
Definition: NBEdge.cpp:1647
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:433
double getLength() const
Returns the computed length of the edge.
Definition: NBEdge.h:480
const PositionVector & getShape() const
returns the shape of the lane
Definition: GNELane.cpp:599
bool showLinkDecals
Information whether link textures (arrows) shall be drawn.
double selectionScale
the current selection scaling in NETEDIT (temporary)
void updateConnectionIDs()
Definition: GNELane.cpp:1163
long onDefault(FXObject *, FXSelector, void *)
multiplexes message to two targets
Definition: GNELane.cpp:1112
std::vector< GNEEdge * > retrieveEdges(bool onlySelected=false)
return all edges
Definition: GNENet.cpp:974
virtual void setMicrosimID(const std::string &newID)
Changes the microsimID of the object.
#define M_PI
Definition: odrSpiral.cpp:40
The link is controlled by a tls which is off and blinks, has to brake.
std::vector< Position > myLaneRestrictedTexturePositions
Position of textures of restricted lanes.
Definition: GNELane.h:214
void setSpecialColor(const RGBColor *Color2)
Definition: GNELane.cpp:851
The popup menu of a globject.
an edge
This is an uncontrolled, major link, may pass.
void buildSelectionPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to (de)select the object.
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNELane.cpp:591
transform lane to sidewalk
Definition: GUIAppEnum.h:770
static const StringBijection< FXuint > LinkStateNames
long names for link states
static FXColor getFXColor(const RGBColor &col)
converts FXColor to RGBColor
Definition: MFXUtils.cpp:120
Represents a single node (junction) during network building.
Definition: NBNode.h:74
T get(const std::string &str) const
void insertMenuPaneChild(FXMenuPane *child)
Insert a sub-menu pane in this GUIGLObjectPopupMenu.
The link is a 180 degree turn (left-hand network)
std::vector< GNEAdditional * > myAdditionalChilds
list of Additional Childs of this NetElement
SumoXMLTag getTag() const
get XML Tag assigned to this object
GUIVisualizationSettings * getVisualisationSettings() const
get visualitation settings
static void drawTriangleAtEnd(const Position &p1, const Position &p2, double tLength, double tWidth)
Draws a triangle at the end of the given line.
Definition: GLHelper.cpp:428
void removeShapeChild(GNEShape *shape)
remove shape child of this lane
Definition: GNELane.cpp:731
void drawCrossties(double length, double spacing, double halfWidth) const
draw crossties for railroads
Definition: GNELane.cpp:1057
std::string getLaneID(int lane) const
get Lane ID (Secure)
Definition: NBEdge.cpp:2783
const std::vector< GNEEdge * > & getGNEIncomingEdges() const
Returns incoming GNEEdges.
static const RGBColor selectionColor
Definition: GNENet.h:107
mode for connecting lanes
Definition: GNEViewNet.h:60
mode for creating new edges
Definition: GNEViewNet.h:50
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:137
bool isValid(SumoXMLAttr key, const std::string &value)
Definition: GNELane.cpp:818
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.cpp:412
Position getPositionInformation() const
Returns the cursor&#39;s x/y position within the network.
remove inner geometry
Definition: GUIAppEnum.h:693
double getLaneParametricLength() const
returns the parameteric length of the lane
Definition: GNELane.cpp:701
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
GUISelectedStorage gSelected
A global holder of selected objects.
PositionVector customShape
A custom shape for this lane set by the user.
Definition: NBEdge.h:154
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:1607
static FXIcon * getIcon(GUIIcon which)
returns a icon previously defined in the enum GUIIcon
GUIVisualizationTextSettings drawLinkJunctionIndex
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
Definition: NBEdge.cpp:778
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNELane.cpp:269
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.
~GNELane()
Destructor.
Definition: GNELane.cpp:93
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2911
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
void drawLinkNo(const GUIVisualizationSettings &s) const
draw link Number
Definition: GNELane.cpp:98
interpolate z values linear between junctions
Definition: GUIAppEnum.h:697
The link has no direction (is a dead end link)
split an edge
Definition: GUIAppEnum.h:701
a junction
GNEJunction * getGNEJunctionDestiny() const
returns the destination-junction
Definition: GNEEdge.cpp:323
static RGBColor getColor()
gets the gl-color
Definition: GLHelper.cpp:455