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 // ===========================================================================
59  GNENetElement(parentJunction->getNet(), crossing->id, GLO_CROSSING, SUMO_TAG_CROSSING, ICON_CROSSING),
60  myParentJunction(parentJunction),
61  myCrossing(crossing) {
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)M_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 && 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->valid) {
119  glColor3d(1.0, 0.1, 0.1);
120  } else if (myCrossing->priority) {
121  glColor3d(0.9, 0.9, 0.9);
122  } else {
123  glColor3d(0.1, 0.1, 0.1);
124  }
125  // traslate to front
126  glTranslated(0, 0, .2);
127  // set default values
128  double length = 0.5;
129  double spacing = 1.0;
130  double halfWidth = myCrossing->width * 0.5;
131  // push second draw matrix
132  glPushMatrix();
133  // draw on top of of the white area between the rails
134  glTranslated(0, 0, 0.1);
135  for (int i = 0; i < (int)myCrossing->shape.size() - 1; ++i) {
136  // push three draw matrix
137  glPushMatrix();
138  // traslete and rotate
139  glTranslated(myCrossing->shape[i].x(), myCrossing->shape[i].y(), 0.0);
140  glRotated(myShapeRotations[i], 0, 0, 1);
141  // draw crossing
142  for (double t = 0; t < myShapeLengths[i]; t += spacing) {
143  glBegin(GL_QUADS);
144  glVertex2d(-halfWidth, -t);
145  glVertex2d(-halfWidth, -t - length);
146  glVertex2d(halfWidth, -t - length);
147  glVertex2d(halfWidth, -t);
148  glEnd();
149  }
150  // pop three draw matrix
151  glPopMatrix();
152  }
153  // XXX draw junction index / tls index
154  // pop second draw matrix
155  glPopMatrix();
156  // traslate to back
157  glTranslated(0, 0, -.2);
158  // pop name
159  glPopName();
160  // pop draw matrix
161  glPopMatrix();
162  }
163 }
164 
165 
168  myPopup = new GUIGLObjectPopupMenu(app, parent, *this);
170  return myPopup;
171 }
172 
173 
177  new GUIParameterTableWindow(app, *this, 2);
178  // add items
179  // close building
180  ret->closeBuilding();
181  return ret;
182 }
183 
184 
185 Boundary
188  b.grow(10);
189  return b;
190 }
191 
192 
193 std::string
195  switch (key) {
196  case SUMO_ATTR_ID:
197  return getMicrosimID();
198  break;
199  case SUMO_ATTR_WIDTH:
200  return toString(myCrossing->width);
201  break;
202  case SUMO_ATTR_PRIORITY:
203  return myCrossing->priority ? "true" : "false";
204  break;
205  case SUMO_ATTR_EDGES:
206  return toString(myCrossing->edges);
207  break;
208  default:
209  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
210  }
211 }
212 
213 
214 void
215 GNECrossing::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
216  if (value == getAttribute(key)) {
217  return; //avoid needless changes, later logic relies on the fact that attributes have changed
218  }
219  switch (key) {
220  case SUMO_ATTR_ID:
221  throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + toString(getTag()) + " isn't allowed");
222  case SUMO_ATTR_EDGES:
223  case SUMO_ATTR_WIDTH:
224  case SUMO_ATTR_PRIORITY:
225  undoList->add(new GNEChange_Attribute(this, key, value), true);
226  break;
227  default:
228  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
229  }
230 }
231 
232 
233 bool
234 GNECrossing::isValid(SumoXMLAttr key, const std::string& value) {
235  switch (key) {
236  case SUMO_ATTR_ID:
237  return false;
238  case SUMO_ATTR_EDGES: {
239  std::vector<std::string> NBEdgeIDs = GNEAttributeCarrier::parse<std::vector<std::string> > (value);
240  // Obtain NBEdges of GNENet and check if exists
241  for (std::vector<std::string>::iterator i = NBEdgeIDs.begin(); i != NBEdgeIDs.end(); i++) {
242  if (myNet->retrieveEdge((*i), false) == NULL) {
243  return false;
244  }
245  }
246  return true;
247  }
248  case SUMO_ATTR_WIDTH:
249  return canParse<double>(value) && isPositive<double>(value);
250  case SUMO_ATTR_PRIORITY:
251  return canParse<bool>(value);
252  default:
253  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
254  }
255 }
256 
257 
258 bool
260  if (std::find(myCrossing->edges.begin(), myCrossing->edges.end(), edge->getNBEdge()) != myCrossing->edges.end()) {
261  return true;
262  } else {
263  return false;
264  }
265 }
266 
267 
268 bool
269 GNECrossing::checkEdgeBelong(const std::vector<GNEEdge*>& edges) const {
270  for (std::vector<GNEEdge*>::const_iterator i = edges.begin(); i != edges.end(); i++) {
271  if (checkEdgeBelong(*i)) {
272  return true;
273  }
274  }
275  return false;
276 }
277 
278 // ===========================================================================
279 // private
280 // ===========================================================================
281 
282 void
283 GNECrossing::setAttribute(SumoXMLAttr key, const std::string& value) {
284  switch (key) {
285  case SUMO_ATTR_ID:
286  throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + toString(getTag()) + " isn't allowed");
287  case SUMO_ATTR_EDGES: {
288  // remove edges of crossing
289  myCrossing->edges.clear();
290  std::vector<std::string> NBEdgeIDs = GNEAttributeCarrier::parse<std::vector<std::string> > (value);
291  // Obtain NBEdges of GNENet and insert it in the crossing
292  for (std::vector<std::string>::iterator i = NBEdgeIDs.begin(); i != NBEdgeIDs.end(); i++) {
293  myCrossing->edges.push_back(myNet->retrieveEdge(*i)->getNBEdge());
294  }
295  // update geometry of parent junction
297  break;
298  }
299  case SUMO_ATTR_WIDTH:
300  // Change width an refresh element
301  myCrossing->width = parse<double>(value);
302  myNet->refreshElement(this);
303  break;
304  case SUMO_ATTR_PRIORITY:
305  myCrossing->priority = parse<bool>(value);
306  break;
307  default:
308  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
309  }
310 }
311 
312 /****************************************************************************/
bool checkEdgeBelong(GNEEdge *edges) const
return true if a edge belongs to crossing&#39;s edges
a tl-logic
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
GNEEdge * retrieveEdge(const std::string &id, bool failHard=true)
get edge by id
Definition: GNENet.cpp:899
void closeBuilding(const Parameterised *p=0)
Closes the building of the table.
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:250
GNENet * myNet
the net to inform about updates
void refreshElement(GUIGlObject *o)
refreshes boundary information for o and update
Definition: GNENet.cpp:990
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
double x() const
Returns the x-position.
Definition: Position.h:63
Stores the information about how to visualize structures.
NBNode * getNBNode() const
Return net build node.
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:150
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
std::string getAttribute(SumoXMLAttr key) const
This functions has to be implemented in allGNEAttributeCarrier.
GNECrossing(GNEJunction *parentJunction, NBNode::Crossing *crossing)
Constructor.
Definition: GNECrossing.cpp:58
GUIGlID getGlID() const
Returns the numerical id of the object.
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
bool priority
whether the pedestrians have priority
Definition: NBNode.h:160
void updateGeometry()
update pre-computed geometry information
Definition: GNECrossing.cpp:71
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
NBNode::Crossing * myCrossing
the data for this crossing
Definition: GNECrossing.h:141
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:149
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
double y() const
Returns the y-position.
Definition: Position.h:68
GNEJunction * getParentJunction() const
get parent Junction
Definition: GNECrossing.cpp:94
GNEJunction * myParentJunction
the parent junction of this crossing
Definition: GNECrossing.h:138
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:302
GUIGLObjectPopupMenu * myPopup
the created popup
Definition: GNECrossing.h:156
const PositionVector & getShape() const
retrieve the junction shape
Definition: NBNode.cpp:1726
NBNode::Crossing * getNBCrossing() const
get referente to NBode::Crossing
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:58
double width
This lane&#39;s width.
Definition: NBNode.h:152
void updateGeometry()
Update the boundary of the junction.
#define M_PI
Definition: odrSpiral.cpp:40
The popup menu of a globject.
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
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:148
A definition of a pedestrian crossing.
Definition: NBNode.h:135
SumoXMLTag getTag() const
get XML Tag assigned to this object
bool isValid(SumoXMLAttr key, const std::string &value)
std::vector< double > myShapeLengths
The lengths of the shape parts.
Definition: GNECrossing.h:152
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.cpp:306
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
GUISelectedStorage gSelected
A global holder of selected objects.
A window containing a gl-object&#39;s parameter.
bool valid
whether this crossing is valid (and can be written to the net.xml). This is needed for netedit becaus...
Definition: NBNode.h:166
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
a junction