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 /****************************************************************************/
static void drawTexturedBox(int which, double size)
Draws a named texture as a box with the given size.
int getConnectionIndex(const NBEdge *from, const NBEdge::Connection &con) const
return the index of the given connection
Definition: NBNode.cpp:2698
The link is a partial left direction.
std::string getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a &#39; &#39;.
double getLength() const
Returns the computed length of the edge.
Definition: NBEdge.h:480
bool setMultiColor(const GUIColorer &c) const
sets multiple colors according to the current scheme index and some lane function ...
Definition: GNELane.cpp:941
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
std::vector< GNEAdditional * > myAdditionalParents
list of Additional parents of this NetElement
void drawLane2LaneConnections() const
draw lane to lane connections
Definition: GNELane.cpp:220
set non-default geometry endpoint
Definition: GUIAppEnum.h:689
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
bool isRestricted(SUMOVehicleClass vclass) const
check if this lane is restricted
Definition: GNELane.cpp:749
double scale
information about a lane&#39;s width (temporary, used for a single view)
double laneWidthExaggeration
The lane exaggeration (upscale thickness)
Copy edge name (for lanes only)
Definition: GUIAppEnum.h:232
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
double z() const
Returns the z-position.
Definition: Position.h:72
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
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
double getLaneSpeed(int lane) const
get lane speed
Definition: NBEdge.cpp:1647
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
static GUIGlID getTexture(GUITexture which)
returns a texture previously defined in the enum GUITexture
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:249
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2966
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
Boundary getBoundary() const
returns the boundry (including lanes)
Definition: GNELane.cpp:617
add bikelane
Definition: GUIAppEnum.h:778
GUIColorer laneColorer
The lane colorer.
Stores the information about how to visualize structures.
This is an uncontrolled, minor link, has to stop.
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:419
vehicle is a bicycle
double y() const
Returns the y-position.
Definition: Position.h:67
GUIVisualizationSettings * getVisualisationSettings() const
get visualitation settings
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:70
bool showRails
Information whether rails shall be drawn.
The link is a 180 degree turn.
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
double x() const
Returns the x-position.
Definition: Position.h:62
mode for editing tls
Definition: GNEViewNet.h:62
const std::vector< double > & getShapeRotations() const
returns the vector with the shape rotations
Definition: GNELane.cpp:605
std::string getAttributeForSelection(SumoXMLAttr key) const
method for getting the attribute in the context of object selection
Definition: GNELane.cpp:786
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
T MAX2(T a, T b)
Definition: StdDefs.h:73
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
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:53
int editMode
the current NETEDIT mode (temporary)
bool showLaneDirection
Whether to show direction indicators for lanes.
double getSpeed() const
returns the current speed of lane
Definition: GNELane.cpp:695
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.
bool drawAsRailway(const GUIVisualizationSettings &s) const
whether to draw this lane as a railway
Definition: GNELane.cpp:1045
interpolate z values linear between junctions
Definition: GUIAppEnum.h:697
const double SUMO_const_laneOffset
Definition: StdDefs.h:52
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
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
duplicate a lane
Definition: GUIAppEnum.h:768
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
double getColorValue(int activeScheme) const
return value for lane coloring according to the given scheme
Definition: GNELane.cpp:963
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.
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
bool setFunctionalColor(int activeScheme) const
sets the color according to the current scheme index and some lane function
Definition: GNELane.cpp:927
This is an uncontrolled, zipper-merge link.
The link is a (hard) left direction.
std::vector< std::string > getStrings() const
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
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNELane.cpp:269
add reverse edge
Definition: GUIAppEnum.h:707
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
The link is a straight direction.
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
std::vector< Connection > getConnectionsFromLane(int lane) const
Returns connections from a given lane.
Definition: NBEdge.cpp:1037
bool drawAsWaterway(const GUIVisualizationSettings &s) const
whether to draw this lane as a waterways
Definition: GNELane.cpp:1051
static double naviDegree(const double angle)
Definition: GeomHelper.cpp:186
int getIndex() const
returns the index of the lane
Definition: GNELane.cpp:683
double getLaneParametricLength() const
returns the parameteric length of the lane
Definition: GNELane.cpp:701
remove inner geometry
Definition: GUIAppEnum.h:693
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
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
const std::vector< GNEEdge * > & getGNEIncomingEdges() const
Returns incoming GNEEdges.
This is an uncontrolled, minor link, has to brake.
std::string getLaneID(int lane) const
get Lane ID (Secure)
Definition: NBEdge.cpp:2783
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:412
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:45
A list of positions.
bool controlsEdge(GNEEdge &edge) const
whether the given edge is controlled by the currently edited tlDef
transform lane to busLane
Definition: GUIAppEnum.h:774
bool isLogicValid()
whether this junction has a valid logic
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
T get(const std::string &str) const
add busLane
Definition: GUIAppEnum.h:780
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
GNEJunction * getGNEJunctionDestiny() const
returns the destination-junction
Definition: GNEEdge.cpp:323
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
transform lane to bikelane
Definition: GUIAppEnum.h:772
virtual void updateGeometry()=0
update pre-computed geometry information
void drawArrows() const
draw arrows
Definition: GNELane.cpp:150
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
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...
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
const std::string getID() const
function to support debugging
const T getColor(const double value) const
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition: GLHelper.cpp:276
std::vector< GNEConnection * > getGNEOutcomingConnections()
returns a vector with the outgoing GNEConnections of this lane
Definition: GNELane.cpp:1148
std::vector< Connection > myConnections
List of connections to following edges.
Definition: NBEdge.h:1397
GNEJunction * getGNEJunctionSource() const
returns the source-junction
Definition: GNEEdge.cpp:317
double laneMinSize
The minimum visual lane width for drawing.
The link is a partial right direction.
double getLaneShapeLength() const
returns the length of the lane&#39;s shape
Definition: GNELane.cpp:712
double width
This lane&#39;s width.
Definition: NBEdge.h:141
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:3025
vehicle is a passenger car (a "normal" car)
void updateGeometry()
update pre-computed geometry information
Definition: GNELane.cpp:623
is an arbitrary ship
std::string getAttribute(SumoXMLAttr key) const
This functions has to be implemented in all GNEAttributeCarriers.
Definition: GNELane.cpp:755
begin/end of the description of an edge
restore geometry endpoint to node position
Definition: GUIAppEnum.h:691
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
EditMode getCurrentEditMode() const
get the current edit mode
bool canParseVehicleClasses(const std::string &classes)
Checks whether the given string contains only known vehicle classes.
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:56
reverse an edge
Definition: GUIAppEnum.h:705
void drawDirectionIndicators() const
direction indicators for lanes
Definition: GNELane.cpp:1081
GNEEdge & myParentEdge
The Edge that to which this lane belongs.
Definition: GNELane.h:200
smooth elevation with regard to adjoining edges
Definition: GUIAppEnum.h:699
vehicle is a bus
double getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:522
transform lane to sidewalk
Definition: GUIAppEnum.h:770
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)
double length() const
Returns the length.
void updateConnectionIDs()
Definition: GNELane.cpp:1163
void drawMarkings(const bool &selectedEdge, double scale) const
draw lane markings
Definition: GNELane.cpp:399
long onDefault(FXObject *, FXSelector, void *)
multiplexes message to two targets
Definition: GNELane.cpp:1112
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
Definition: NBEdge.cpp:778
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
void drawTLSLinkNo(const GUIVisualizationSettings &s) const
draw TLS Link Number
Definition: GNELane.cpp:122
The link is controlled by a tls which is off and blinks, has to brake.
void drawCrossties(double length, double spacing, double halfWidth) const
draw crossties for railroads
Definition: GNELane.cpp:1057
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
remove busLane
Definition: GUIAppEnum.h:786
This is an uncontrolled, major link, may pass.
void drawLinkNo(const GUIVisualizationSettings &s) const
draw link Number
Definition: GNELane.cpp:98
void buildSelectionPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to (de)select the object.
void drawLinkRules() const
draw link rules
Definition: GNELane.cpp:145
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
GUIGlID getGlID() const
Returns the numerical id of the object.
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
smooth geometry
Definition: GUIAppEnum.h:695
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
Position getPositionInformation() const
Returns the cursor&#39;s x/y position within the network.
void removeShapeChild(GNEShape *shape)
remove shape child of this lane
Definition: GNELane.cpp:731
split an edge
Definition: GUIAppEnum.h:701
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
const std::string & getParentName() const
Returns the name of the parent object.
Definition: GNELane.cpp:1106
static const RGBColor selectionColor
Definition: GNENet.h:107
void setLaneColor(const GUIVisualizationSettings &s) const
set color according to edit mode and visualisation settings
Definition: GNELane.cpp:905
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
split an edge
Definition: GUIAppEnum.h:703
const std::vector< double > & getShapeLengths() const
returns the vector with the shape lengths
Definition: GNELane.cpp:611
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
remove bikelane
Definition: GUIAppEnum.h:784
GUISelectedStorage gSelected
A global holder of selected objects.
PositionVector customShape
A custom shape for this lane set by the user.
Definition: NBEdge.h:154
const std::vector< GNEShape * > & getShapeChilds() const
get shape childs of lane
Definition: GNELane.cpp:743
static FXIcon * getIcon(GUIIcon which)
returns a icon previously defined in the enum GUIIcon
GUIVisualizationTextSettings drawLinkJunctionIndex
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:433
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.
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNELane.cpp:591
~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.
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:1607
The link has no direction (is a dead end link)
a junction
static RGBColor getColor()
gets the gl-color
Definition: GLHelper.cpp:455
SumoXMLTag getTag() const
get XML Tag assigned to this object