SUMO - Simulation of Urban MObility
GNECrossing.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // A class for visualizing Inner Lanes (used when editing traffic lights)
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
10 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 
31 #include <string>
32 #include <iostream>
33 #include <utility>
34 #include <time.h>
39 #include <utils/common/ToString.h>
44 #include <utils/gui/div/GLHelper.h>
46 
47 #include "GNECrossing.h"
48 #include "GNEJunction.h"
49 #include "GNEUndoList.h"
50 #include "GNENet.h"
51 #include "GNEEdge.h"
52 #include "GNEViewNet.h"
53 #include "GNEChange_Attribute.h"
54 
55 // ===========================================================================
56 // method definitions
57 // ===========================================================================
58 GNECrossing::GNECrossing(GNEJunction* parentJunction, const std::string& id) :
59  GNENetElement(parentJunction->getNet(), id, GLO_CROSSING, SUMO_TAG_CROSSING, ICON_CROSSING),
60  myParentJunction(parentJunction),
61  myCrossing(parentJunction->getNBNode()->getCrossingRef(id)) {
62  // Update geometry
64 }
65 
66 
68 
69 
70 void
72  // Clear Shape rotations and segments
73  myShapeRotations.clear();
74  myShapeLengths.clear();
75  // only rebuild shape if junction's shape isn't in Buuble mode
76  if (myParentJunction->getNBNode()->getShape().size() > 0) {
77  // Obtain segments of size and calculate it
78  int segments = (int) myCrossing.shape.size() - 1;
79  if (segments >= 0) {
80  myShapeRotations.reserve(segments);
81  myShapeLengths.reserve(segments);
82  for (int i = 0; i < segments; ++i) {
83  const Position& f = myCrossing.shape[i];
84  const Position& s = myCrossing.shape[i + 1];
85  myShapeLengths.push_back(f.distanceTo2D(s));
86  myShapeRotations.push_back((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double) PI);
87  }
88  }
89  }
90 }
91 
92 
95  return myParentJunction;
96 }
97 
98 
101  return myCrossing;
102 }
103 
104 
105 void
107  // only draw if option drawCrossingsAndWalkingareas is enabled and size of shape is greather than 0
108  if (s.drawCrossingsAndWalkingareas == true && myShapeRotations.size() > 0 && myShapeLengths.size() > 0) {
109  // push first draw matrix
110  glPushMatrix();
111  // push name
112  glPushName(getGlID());
113  // must draw on top of junction
114  glTranslated(0, 0, GLO_JUNCTION + 0.1);
115  // set color depending of selection and priority
116  if (gSelected.isSelected(getType(), getGlID())) {
117  glColor3d(0.118, 0.565, 1.000);
118  } else if (myCrossing.priority) {
119  glColor3d(0.9, 0.9, 0.9);
120  } else {
121  glColor3d(0.1, 0.1, 0.1);
122  }
123  // traslate to front
124  glTranslated(0, 0, .2);
125  // set default values
126  double length = 0.5;
127  double spacing = 1.0;
128  double halfWidth = myCrossing.width * 0.5;
129  // push second draw matrix
130  glPushMatrix();
131  // draw on top of of the white area between the rails
132  glTranslated(0, 0, 0.1);
133  for (int i = 0; i < (int)myCrossing.shape.size() - 1; ++i) {
134  // push three draw matrix
135  glPushMatrix();
136  // traslete and rotate
137  glTranslated(myCrossing.shape[i].x(), myCrossing.shape[i].y(), 0.0);
138  glRotated(myShapeRotations[i], 0, 0, 1);
139  // draw crossing
140  for (double t = 0; t < myShapeLengths[i]; t += spacing) {
141  glBegin(GL_QUADS);
142  glVertex2d(-halfWidth, -t);
143  glVertex2d(-halfWidth, -t - length);
144  glVertex2d(halfWidth, -t - length);
145  glVertex2d(halfWidth, -t);
146  glEnd();
147  }
148  // pop three draw matrix
149  glPopMatrix();
150  }
151  // XXX draw junction index / tls index
152  // pop second draw matrix
153  glPopMatrix();
154  // traslate to back
155  glTranslated(0, 0, -.2);
156  // pop name
157  glPopName();
158  // pop draw matrix
159  glPopMatrix();
160  }
161 }
162 
163 
166  myPopup = new GUIGLObjectPopupMenu(app, parent, *this);
168  return myPopup;
169 }
170 
171 
175  new GUIParameterTableWindow(app, *this, 2);
176  // add items
177  // close building
178  ret->closeBuilding();
179  return ret;
180 }
181 
182 
183 Boundary
186  b.grow(10);
187  return b;
188 }
189 
190 
191 std::string
193  switch (key) {
194  case SUMO_ATTR_ID:
195  return getMicrosimID();
196  break;
197  case SUMO_ATTR_WIDTH:
198  return toString(myCrossing.width);
199  break;
200  case SUMO_ATTR_PRIORITY:
201  return myCrossing.priority ? "true" : "false";
202  break;
203  case SUMO_ATTR_EDGES:
204  return toString(myCrossing.edges);
205  break;
206  default:
207  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
208  }
209 }
210 
211 
212 void
213 GNECrossing::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
214  if (value == getAttribute(key)) {
215  return; //avoid needless changes, later logic relies on the fact that attributes have changed
216  }
217  switch (key) {
218  case SUMO_ATTR_ID:
219  throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + toString(getTag()) + " isn't allowed");
220  case SUMO_ATTR_EDGES:
221  case SUMO_ATTR_WIDTH:
222  case SUMO_ATTR_PRIORITY:
223  undoList->add(new GNEChange_Attribute(this, key, value), true);
224  break;
225  default:
226  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
227  }
228 }
229 
230 
231 bool
232 GNECrossing::isValid(SumoXMLAttr key, const std::string& value) {
233  switch (key) {
234  case SUMO_ATTR_ID:
235  return false;
236  case SUMO_ATTR_EDGES: {
237  std::vector<std::string> NBEdgeIDs = GNEAttributeCarrier::parse<std::vector<std::string> > (value);
238  // Obtain NBEdges of GNENet and check if exists
239  for (std::vector<std::string>::iterator i = NBEdgeIDs.begin(); i != NBEdgeIDs.end(); i++) {
240  if (myNet->retrieveEdge((*i), false) == NULL) {
241  return false;
242  }
243  }
244  return true;
245  }
246  case SUMO_ATTR_WIDTH:
247  return isPositive<double>(value);
248  case SUMO_ATTR_PRIORITY:
249  return ((value == "true") || (value == "false"));
250  default:
251  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
252  }
253 }
254 
255 // ===========================================================================
256 // private
257 // ===========================================================================
258 
259 void
260 GNECrossing::setAttribute(SumoXMLAttr key, const std::string& value) {
261  switch (key) {
262  case SUMO_ATTR_ID:
263  throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + toString(getTag()) + " isn't allowed");
264  case SUMO_ATTR_EDGES: {
265  // remove edges of crossing
266  myCrossing.edges.clear();
267  std::vector<std::string> NBEdgeIDs = GNEAttributeCarrier::parse<std::vector<std::string> > (value);
268  // Obtain NBEdges of GNENet and insert it in the crossing
269  for (std::vector<std::string>::iterator i = NBEdgeIDs.begin(); i != NBEdgeIDs.end(); i++) {
270  myCrossing.edges.push_back(myNet->retrieveEdge(*i)->getNBEdge());
271  }
272  break;
273  }
274  case SUMO_ATTR_WIDTH:
275  // Change width an refresh element
276  myCrossing.width = parse<double>(value);
277  myNet->refreshElement(this);
278  break;
279  case SUMO_ATTR_PRIORITY:
280  myCrossing.priority = parse<bool>(value);
281  break;
282  default:
283  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
284  }
285 }
286 
287 /****************************************************************************/
a tl-logic
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
NBNode::Crossing & myCrossing
the data for this crossing
Definition: GNECrossing.h:134
GNEEdge * retrieveEdge(const std::string &id, bool failHard=true)
get edge by id
Definition: GNENet.cpp:743
GNENet * myNet
the net to inform about updates
void refreshElement(GUIGlObject *o)
refreshes boundary information for o and update
Definition: GNENet.cpp:817
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:250
Stores the information about how to visualize structures.
double y() const
Returns the y-position.
Definition: Position.h:68
double x() const
Returns the x-position.
Definition: Position.h:63
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
PositionVector shape
The lane&#39;s shape.
Definition: NBNode.h:149
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
bool priority
whether the pedestrians have priority
Definition: NBNode.h:159
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
GNECrossing(GNEJunction *parentJunction, const std::string &id)
Constructor.
Definition: GNECrossing.cpp:58
void updateGeometry()
update pre-computed geometry information
Definition: GNECrossing.cpp:71
#define PI
Definition: polyfonts.c:61
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
the edges of a route
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
std::vector< double > myShapeRotations
Definition: GNECrossing.h:142
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
friend class GNEChange_Attribute
declare friend class
GNEJunction * myParentJunction
the parent junction of this crossing
Definition: GNECrossing.h:131
NBNode::Crossing & getNBCrossing() const
get referente to NBode::Crossing
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:234
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
GUIGLObjectPopupMenu * myPopup
the created popup
Definition: GNECrossing.h:149
const PositionVector & getShape() const
retrieve the junction shape
Definition: NBNode.cpp:1716
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
double width
This lane&#39;s width.
Definition: NBNode.h:151
The popup menu of a globject.
crossing between edges for pedestrians
virtual ~GNECrossing()
Destructor.
Definition: GNECrossing.cpp:67
bool drawCrossingsAndWalkingareas
whether crosings and walkingareas shall be drawn
EdgeVector edges
The edges being crossed.
Definition: NBNode.h:147
GUIGlID getGlID() const
Returns the numerical id of the object.
A definition of a pedestrian crossing.
Definition: NBNode.h:135
bool isValid(SumoXMLAttr key, const std::string &value)
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
std::vector< double > myShapeLengths
The lengths of the shape parts.
Definition: GNECrossing.h:145
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.cpp:261
NBNode * getNBNode() const
Return net build node.
GUISelectedStorage gSelected
A global holder of selected objects.
void closeBuilding()
Closes the building of the table.
A window containing a gl-object&#39;s parameter.
std::string getAttribute(SumoXMLAttr key) const
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
a junction
GNEJunction * getParentJunction() const
get parent Junction
Definition: GNECrossing.cpp:94
SumoXMLTag getTag() const
get XML Tag assigned to this object