SUMO - Simulation of Urban MObility
GNECrossing.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 Inner Lanes (used when editing traffic lights)
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>
33 #include <time.h>
38 #include <utils/common/ToString.h>
42 #include <utils/gui/div/GLHelper.h>
45 
46 #include "GNECrossing.h"
47 #include "GNEJunction.h"
48 #include "GNEUndoList.h"
49 #include "GNENet.h"
50 #include "GNEEdge.h"
51 #include "GNEViewNet.h"
52 #include "GNEChange_Attribute.h"
53 
54 // ===========================================================================
55 // method definitions
56 // ===========================================================================
58  GNENetElement(parentJunction->getNet(), crossing->id, GLO_CROSSING, SUMO_TAG_CROSSING, ICON_CROSSING),
59  myParentJunction(parentJunction),
60  myCrossing(crossing),
61  myForceDrawCustomShape(crossing->customShape.size() > 0) {
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
79  int segments = (int)shape.size() - 1;
80  if (segments >= 0) {
81  myShapeRotations.reserve(segments);
82  myShapeLengths.reserve(segments);
83  for (int i = 0; i < segments; ++i) {
84  const Position& f = shape[i];
85  const Position& s = shape[i + 1];
86  myShapeLengths.push_back(f.distanceTo2D(s));
87  myShapeRotations.push_back((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double)M_PI);
88  }
89  }
90  }
91 }
92 
93 
96  return myParentJunction;
97 }
98 
99 
102  return myCrossing;
103 }
104 
105 
106 void
108  // only draw if option drawCrossingsAndWalkingareas is enabled and size of shape is greather than 0
109  if (s.drawCrossingsAndWalkingareas && myShapeRotations.size() > 0 && myShapeLengths.size() > 0) {
110  // first declare what shape will be drawed
112  // push first draw matrix
113  glPushMatrix();
114  // push name
115  glPushName(getGlID());
116  // must draw on top of junction
117  glTranslated(0, 0, GLO_JUNCTION + 0.1);
118  // set color depending of selection and priority
119  if (gSelected.isSelected(getType(), getGlID())) {
120  glColor3d(0.118, 0.565, 1.000);
121  } else if (!myCrossing->valid) {
122  glColor3d(1.0, 0.1, 0.1);
123  } else if (myCrossing->priority) {
124  glColor3d(0.9, 0.9, 0.9);
125  } else {
126  glColor3d(0.1, 0.1, 0.1);
127  }
128  // traslate to front
129  glTranslated(0, 0, .2);
130  // set default values
131  double length = 0.5;
132  double spacing = 1.0;
133  double halfWidth = myCrossing->width * 0.5;
134  // push second draw matrix
135  glPushMatrix();
136  // draw on top of of the white area between the rails
137  glTranslated(0, 0, 0.1);
138  for (int i = 0; i < (int)shape.size() - 1; ++i) {
139  // push three draw matrix
140  glPushMatrix();
141  // traslete and rotate
142  glTranslated(shape[i].x(), shape[i].y(), 0.0);
143  glRotated(myShapeRotations[i], 0, 0, 1);
144  // draw crossing
145  for (double t = 0; t < myShapeLengths[i]; t += spacing) {
146  glBegin(GL_QUADS);
147  glVertex2d(-halfWidth, -t);
148  glVertex2d(-halfWidth, -t - length);
149  glVertex2d(halfWidth, -t - length);
150  glVertex2d(halfWidth, -t);
151  glEnd();
152  }
153  // pop three draw matrix
154  glPopMatrix();
155  }
156  // XXX draw junction index / tls index
157  // pop second draw matrix
158  glPopMatrix();
159  // traslate to back
160  glTranslated(0, 0, -.2);
161  // pop name
162  glPopName();
163  // pop draw matrix
164  glPopMatrix();
165  }
166 }
167 
168 
171  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
172  buildPopupHeader(ret, app);
175  // build selection and show parameters menu
178  // build position copy entry
179  buildPositionCopyEntry(ret, false);
180  // create menu commands
181  FXMenuCommand* mcCustomShape = new FXMenuCommand(ret, "Set custom crossing shape", 0, &parent, MID_GNE_CROSSING_EDIT_SHAPE);
182  // check if menu commands has to be disabled
183  EditMode editMode = myNet->getViewNet()->getCurrentEditMode();
184  const bool wrongMode = (editMode == GNE_MODE_CONNECT || editMode == GNE_MODE_TLS || editMode == GNE_MODE_CREATE_EDGE);
185  if (wrongMode) {
186  mcCustomShape->disable();
187  }
188  return ret;
189 }
190 
191 
192 Boundary
195  b.grow(10);
196  return b;
197 }
198 
199 
200 std::string
202  switch (key) {
203  case SUMO_ATTR_ID:
204  return getMicrosimID();
205  case SUMO_ATTR_WIDTH:
207  case SUMO_ATTR_PRIORITY:
208  return myCrossing->priority ? "true" : "false";
209  case SUMO_ATTR_EDGES:
210  return toString(myCrossing->edges);
215  default:
216  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
217  }
218 }
219 
220 
221 void
222 GNECrossing::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
223  if (value == getAttribute(key)) {
224  return; //avoid needless changes, later logic relies on the fact that attributes have changed
225  }
226  switch (key) {
227  case SUMO_ATTR_ID:
228  throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + toString(getTag()) + " isn't allowed");
229  case SUMO_ATTR_EDGES:
230  case SUMO_ATTR_WIDTH:
231  case SUMO_ATTR_PRIORITY:
234  undoList->add(new GNEChange_Attribute(this, key, value), true);
235  break;
236  default:
237  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
238  }
239 }
240 
241 
242 bool
243 GNECrossing::isValid(SumoXMLAttr key, const std::string& value) {
244  switch (key) {
245  case SUMO_ATTR_ID:
246  return false;
247  case SUMO_ATTR_EDGES:
248  return checkGNEEdgesValid(myNet, value, false);
249  case SUMO_ATTR_WIDTH:
250  return canParse<double>(value) && isPositive<double>(value);
251  case SUMO_ATTR_PRIORITY:
252  return canParse<bool>(value);
254  return (myCrossing->tlID != "" && canParse<int>(value) && isPositive<int>(value)
255  && myParentJunction->getNBNode()->getControllingTLS().size() > 0
256  && (*myParentJunction->getNBNode()->getControllingTLS().begin())->compute(OptionsCont::getOptions())->getNumLinks() > parse<int>(value));
257  case SUMO_ATTR_CUSTOMSHAPE: {
258  bool ok = true;
259  PositionVector shape = GeomConvHelper::parseShapeReporting(value, "user-supplied shape", 0, ok, true);
260  return ok;
261  }
262  default:
263  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
264  }
265 }
266 
267 
268 bool
270  if (std::find(myCrossing->edges.begin(), myCrossing->edges.end(), edge->getNBEdge()) != myCrossing->edges.end()) {
271  return true;
272  } else {
273  return false;
274  }
275 }
276 
277 
278 bool
279 GNECrossing::checkEdgeBelong(const std::vector<GNEEdge*>& edges) const {
280  for (std::vector<GNEEdge*>::const_iterator i = edges.begin(); i != edges.end(); i++) {
281  if (checkEdgeBelong(*i)) {
282  return true;
283  }
284  }
285  return false;
286 }
287 
288 // ===========================================================================
289 // private
290 // ===========================================================================
291 
292 void
293 GNECrossing::setAttribute(SumoXMLAttr key, const std::string& value) {
294  switch (key) {
295  case SUMO_ATTR_ID:
296  throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + toString(getTag()) + " isn't allowed");
297  case SUMO_ATTR_EDGES: {
298  // obtain GNEEdges
299  std::vector<GNEEdge*> edges = parseGNEEdges(myNet, value);
300  // remove NBEdges of crossing
301  myCrossing->edges.clear();
302  // set NBEdge of every GNEEdge into Crossing Edges
303  for (auto i : edges) {
304  myCrossing->edges.push_back(i->getNBEdge());
305  }
306  // update geometry of parent junction
308  break;
309  }
310  case SUMO_ATTR_WIDTH:
311  // Change width an refresh element
312  myCrossing->customWidth = parse<double>(value);
313  myNet->refreshElement(this);
314  break;
315  case SUMO_ATTR_PRIORITY:
316  myCrossing->priority = parse<bool>(value);
317  break;
319  myCrossing->customTLIndex = parse<int>(value);
320  break;
321  case SUMO_ATTR_CUSTOMSHAPE: {
322  bool ok;
323  myCrossing->customShape = GeomConvHelper::parseShapeReporting(value, "user-supplied shape", 0, ok, true);
324  // Check if custom shaped has to be drawn
326  updateGeometry();
327  myNet->refreshElement(this);
328  break;
329  }
330  default:
331  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
332  }
333 }
334 
335 /****************************************************************************/
a tl-logic
bool myForceDrawCustomShape
flag used for force draw custom shape
Definition: GNECrossing.h:144
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
bool checkEdgeBelong(GNEEdge *edges) const
return true if a edge belongs to crossing&#39;s edges
whether a given shape is user-defined
GNENet * myNet
the net to inform about updates
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
void refreshElement(GUIGlObject *o)
refreshes boundary information for o and update
Definition: GNENet.cpp:1082
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:249
Stores the information about how to visualize structures.
double y() const
Returns the y-position.
Definition: Position.h:67
double x() const
Returns the x-position.
Definition: Position.h:62
mode for editing tls
Definition: GNEViewNet.h:62
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
PositionVector shape
The crossing&#39;s shape.
Definition: NBNode.h:139
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
GNECrossing(GNEJunction *parentJunction, NBNode::Crossing *crossing)
Constructor.
Definition: GNECrossing.cpp:57
static std::vector< GNEEdge * > parseGNEEdges(GNENet *net, const std::string &value)
parse string into vector of GNEEdges
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.
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:47
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:64
bool priority
whether the pedestrians have priority
Definition: NBNode.h:151
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
void updateGeometry()
update pre-computed geometry information
Definition: GNECrossing.cpp:71
NBNode::Crossing * myCrossing
the data for this crossing
Definition: GNECrossing.h:131
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:55
edit junction shape
Definition: GUIAppEnum.h:737
std::vector< double > myShapeRotations
Definition: GNECrossing.h:136
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:45
A list of positions.
friend class GNEChange_Attribute
declare friend class
GNEJunction * myParentJunction
the parent junction of this crossing
Definition: GNECrossing.h:128
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:301
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
EditMode
Definition: GNEViewNet.h:46
EditMode getCurrentEditMode() const
get the current edit mode
const PositionVector & getShape() const
retrieve the junction shape
Definition: NBNode.cpp:1726
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:56
double width
This crossing&#39;s width.
Definition: NBNode.h:143
int customTLIndex
the custom traffic light index of this crossing (if controlled)
Definition: NBNode.h:157
void updateGeometry()
Update the boundary of the junction.
PositionVector customShape
optional customShape for this crossing
Definition: NBNode.h:153
#define M_PI
Definition: odrSpiral.cpp:40
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node (The set of tls that control this node) ...
Definition: NBNode.h:302
double customWidth
This crossing&#39;s width.
Definition: NBNode.h:141
The popup menu of a globject.
crossing between edges for pedestrians
void buildSelectionPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to (de)select the object.
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:137
GUIGlID getGlID() const
Returns the numerical id of the object.
A definition of a pedestrian crossing.
Definition: NBNode.h:131
link: the index of the link within the traffic light
std::string tlID
The id of the traffic light that controls this connection.
Definition: NBNode.h:159
bool isValid(SumoXMLAttr key, const std::string &value)
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
NBNode::Crossing * getNBCrossing() const
get referente to NBode::Crossing
std::vector< double > myShapeLengths
The lengths of the shape parts.
Definition: GNECrossing.h:139
mode for connecting lanes
Definition: GNEViewNet.h:60
mode for creating new edges
Definition: GNEViewNet.h:50
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.cpp:412
static bool checkGNEEdgesValid(GNENet *net, const std::string &value, bool report)
check if a list of edge IDs is valid
NBNode * getNBNode() const
Return net build node.
GUISelectedStorage gSelected
A global holder of selected objects.
bool valid
whether this crossing is valid (and can be written to the net.xml). This is needed for netedit becaus...
Definition: NBNode.h:161
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.
std::string getAttribute(SumoXMLAttr key) const
This functions has to be implemented in all GNEAttributeCarriers.
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:1607
a junction
GNEJunction * getParentJunction() const
get parent Junction
Definition: GNECrossing.cpp:95
SumoXMLTag getTag() const
get XML Tag assigned to this object