SUMO - Simulation of Urban MObility
GNEContainerStop.cpp
Go to the documentation of this file.
1 /****************************************************************************/
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 // 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>
50 
51 #include "GNEContainerStop.h"
52 #include "GNELane.h"
53 #include "GNEEdge.h"
54 #include "GNEJunction.h"
55 #include "GNEUndoList.h"
56 #include "GNENet.h"
57 #include "GNEChange_Attribute.h"
58 #include "GNEViewNet.h"
59 
60 // ===========================================================================
61 // method definitions
62 // ===========================================================================
63 
64 GNEContainerStop::GNEContainerStop(const std::string& id, GNELane* lane, GNEViewNet* viewNet, double startPos, double endPos, const std::vector<std::string>& lines) :
65  GNEStoppingPlace(id, viewNet, SUMO_TAG_CONTAINER_STOP, ICON_CONTAINERSTOP, lane, startPos, endPos),
66  myLines(lines) {
67  // When a new additional element is created, updateGeometry() must be called
69  // Set colors
70  myBaseColor = RGBColor(83, 89, 172, 255);
71  myBaseColorSelected = RGBColor(103, 109, 192, 255);
72  mySignColor = RGBColor(177, 184, 186, 171);
73  mySignColorSelected = RGBColor(197, 204, 206, 171);
74  myTextColor = RGBColor(83, 89, 172, 255);
75  myTextColorSelected = RGBColor(103, 109, 192, 255);
76 }
77 
78 
80 
81 
82 void
84  // Clear all containers
85  myShapeRotations.clear();
86  myShapeLengths.clear();
87 
88  // Get value of option "lefthand"
89  double offsetSign = OptionsCont::getOptions().getBool("lefthand") ? -1 : 1;
90 
91  // Get shape of lane parent
92  myShape = myLane->getShape();
93 
94  // Move shape to side
95  myShape.move2side(1.65 * offsetSign);
96 
97  // Cut shape using as delimitators from start position and end position
99 
100  // Get number of parts of the shape
101  int numberOfSegments = (int) myShape.size() - 1;
102 
103  // If number of segments is more than 0
104  if (numberOfSegments >= 0) {
105 
106  // Reserve memory (To improve efficiency)
107  myShapeRotations.reserve(numberOfSegments);
108  myShapeLengths.reserve(numberOfSegments);
109 
110  // For every part of the shape
111  for (int i = 0; i < numberOfSegments; ++i) {
112 
113  // Obtain first position
114  const Position& f = myShape[i];
115 
116  // Obtain next position
117  const Position& s = myShape[i + 1];
118 
119  // Save distance between position into myShapeLengths
120  myShapeLengths.push_back(f.distanceTo(s));
121 
122  // Save rotation (angle) of the vector constructed by points f and s
123  myShapeRotations.push_back((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double) PI);
124  }
125  }
126 
127  // Obtain a copy of the shape
128  PositionVector tmpShape = myShape;
129 
130  // Move shape to side
131  tmpShape.move2side(1.5 * offsetSign);
132 
133  // Get position of the sign
134  mySignPos = tmpShape.getLineCenter();
135 
136  // Set block icon position
138 
139  // Set block icon rotation, and using their rotation for sign
141 
142  // Refresh element (neccesary to avoid grabbing problems)
144 }
145 
146 
147 void
149  // Write parameters
150  device.openTag(getTag());
151  device.writeAttr(SUMO_ATTR_ID, getID());
152  device.writeAttr(SUMO_ATTR_LANE, myLane->getID());
155  if (myLines.size() > 0) {
157  }
158  if (myBlocked) {
160  }
161  // Close tag
162  device.closeTag();
163 }
164 
165 
166 std::vector<std::string>
168  return myLines;
169 }
170 
171 
172 void
174  // Start drawing adding an gl identificator
175  glPushName(getGlID());
176 
177  // Add a draw matrix
178  glPushMatrix();
179 
180  // Start with the drawing of the area traslating matrix to origin
181  glTranslated(0, 0, getType());
182 
183  // Set color of the base
184  if (isAdditionalSelected()) {
186  } else {
188  }
189 
190  // Obtain exaggeration of the draw
191  const double exaggeration = s.addSize.getExaggeration(s);
192 
193  // Draw the area using shape, shapeRotations, shapeLengths and value of exaggeration
195 
196  // Check if the distance is enought to draw details
197  if (s.scale * exaggeration >= 10) {
198 
199  // Add a draw matrix
200  glPushMatrix();
201 
202  // Obtain rotation of the sing depeding of the option "lefthand"
203  double rotSign = OptionsCont::getOptions().getBool("lefthand");
204 
205  // Set color of the lines
206  if (isAdditionalSelected()) {
208  } else {
210  }
211 
212  // Iterate over every line
213  for (int i = 0; i < (int)myLines.size(); ++i) {
214  // Add a new push matrix
215  glPushMatrix();
216 
217  // Traslate End positionof signal
218  glTranslated(mySignPos.x(), mySignPos.y(), 0);
219 
220  // Rotate 180 (Eje X -> Mirror)
221  glRotated(180, 1, 0, 0);
222 
223  // Rotate again depending of the option rotSign
224  glRotated(rotSign * myBlockIconRotation, 0, 0, 1);
225 
226  // Set poligon mode
227  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
228 
229  // set polyfront position ot 0
230  pfSetPosition(0, 0);
231 
232  // Set polyfront scale to 1
233  pfSetScale(1.f);
234 
235  // traslate matrix for every line
236  glTranslated(1.2, -(double)i, 0);
237 
238  // draw line
239  pfDrawString(myLines[i].c_str());
240 
241  // pop matrix
242  glPopMatrix();
243  }
244 
245  // Start drawing sign traslating matrix to signal position
246  glTranslated(mySignPos.x(), mySignPos.y(), 0);
247 
248  // Define number of points (for efficiency)
249  int noPoints = 9;
250 
251  // If the scale * exaggeration is more than 25, recalculate number of points
252  if (s.scale * exaggeration > 25) {
253  noPoints = MIN2((int)(9.0 + (s.scale * exaggeration) / 10.0), 36);
254  }
255 
256  // scale matrix depending of the exaggeration
257  glScaled(exaggeration, exaggeration, 1);
258 
259  // Draw green circle
260  GLHelper::drawFilledCircle((double) 1.1, noPoints);
261 
262  // Traslate to front
263  glTranslated(0, 0, .1);
264 
265  // Set color of the lines
266  if (isAdditionalSelected()) {
268  } else {
270  }
271 
272  // draw another circle in the same position, but a little bit more small
273  GLHelper::drawFilledCircle((double) 0.9, noPoints);
274 
275  // If the scale * exageration is equal or more than 4.5, draw H
276  if (s.scale * exaggeration >= 4.5) {
277  if (isAdditionalSelected()) {
279  } else {
281  }
282  }
283 
284  // pop draw matrix
285  glPopMatrix();
286 
287  // Show Lock icon depending of the Edit mode
288  drawLockIcon();
289  }
290 
291  // pop draw matrix
292  glPopMatrix();
293 
294  // Draw name
295  drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
296 
297  // Pop name
298  glPopName();
299 }
300 
301 
302 std::string
304  switch (key) {
305  case SUMO_ATTR_ID:
306  return getAdditionalID();
307  case SUMO_ATTR_LANE:
309  case SUMO_ATTR_STARTPOS:
310  return toString(myStartPos);
311  case SUMO_ATTR_ENDPOS:
312  return toString(myEndPos);
313  case SUMO_ATTR_LINES:
314  return joinToString(myLines, " ");
316  return toString(myBlocked);
317  default:
318  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
319  }
320 }
321 
322 
323 void
324 GNEContainerStop::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
325  if (value == getAttribute(key)) {
326  return; //avoid needless changes, later logic relies on the fact that attributes have changed
327  }
328  switch (key) {
329  case SUMO_ATTR_ID:
330  case SUMO_ATTR_LANE:
331  case SUMO_ATTR_STARTPOS:
332  case SUMO_ATTR_ENDPOS:
333  case SUMO_ATTR_LINES:
335  undoList->p_add(new GNEChange_Attribute(this, key, value));
336  updateGeometry();
337  break;
338  default:
339  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
340  }
341 }
342 
343 
344 bool
345 GNEContainerStop::isValid(SumoXMLAttr key, const std::string& value) {
346  switch (key) {
347  case SUMO_ATTR_ID:
348  if (myViewNet->getNet()->getAdditional(getTag(), value) == NULL) {
349  return true;
350  } else {
351  return false;
352  }
353  case SUMO_ATTR_LANE:
354  if (myViewNet->getNet()->retrieveLane(value, false) != NULL) {
355  return true;
356  } else {
357  return false;
358  }
359  case SUMO_ATTR_STARTPOS:
360  return (canParse<double>(value) && parse<double>(value) >= 0 && parse<double>(value) < (myEndPos - 1));
361  case SUMO_ATTR_ENDPOS: {
362  if (canParse<double>(value) && parse<double>(value) >= 1 && parse<double>(value) > myStartPos) {
363  // If extension is larger than Lane
364  if (parse<double>(value) > myLane->getLaneParametricLength()) {
365  // write warning if netedit is running in testing mode
366  if (myViewNet->isTestingModeEnabled() == true) {
367  WRITE_WARNING("Opening FXMessageBox of type 'question'");
368  }
369  // Ask user if want to assign the length of lane as endPosition
370  FXuint answer = FXMessageBox::question(getViewNet()->getApp(), MBOX_YES_NO,
371  (toString(SUMO_ATTR_ENDPOS) + " exceeds the size of the " + toString(SUMO_TAG_LANE)).c_str(), "%s",
372  (toString(SUMO_ATTR_ENDPOS) + " exceeds the size of the " + toString(SUMO_TAG_LANE) +
373  ". Do you want to assign the length of the " + toString(SUMO_TAG_LANE) + " as " + toString(SUMO_ATTR_ENDPOS) + "?").c_str());
374  if (answer == 1) { //1:yes, 2:no, 4:esc
375  // write warning if netedit is running in testing mode
376  if (myViewNet->isTestingModeEnabled() == true) {
377  WRITE_WARNING("Closed FXMessageBox of type 'question' with 'Yes'");
378  }
379  return true;
380  } else {
381  // write warning if netedit is running in testing mode
382  if ((answer == 2) && (myViewNet->isTestingModeEnabled() == true)) {
383  WRITE_WARNING("Closed FXMessageBox of type 'question' with 'No'");
384  } else if ((answer == 4) && (myViewNet->isTestingModeEnabled() == true)) {
385  WRITE_WARNING("Closed FXMessageBox of type 'question' with 'ESC'");
386  }
387  return false;
388  }
389  } else {
390  return true;
391  }
392  } else {
393  return false;
394  }
395  }
396  case SUMO_ATTR_LINES:
397  return canParse<std::vector<std::string> >(value);
399  return canParse<bool>(value);
400  default:
401  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
402  }
403 }
404 
405 // ===========================================================================
406 // private
407 // ===========================================================================
408 
409 void
410 GNEContainerStop::setAttribute(SumoXMLAttr key, const std::string& value) {
411  switch (key) {
412  case SUMO_ATTR_ID:
413  setAdditionalID(value);
414  break;
415  case SUMO_ATTR_LANE:
416  changeLane(value);
417  break;
418  case SUMO_ATTR_STARTPOS:
419  myStartPos = parse<double>(value);
420  updateGeometry();
421  getViewNet()->update();
422  break;
423  case SUMO_ATTR_ENDPOS:
424  if (parse<double>(value) > myLane->getLaneParametricLength()) {
426  } else {
427  myEndPos = parse<double>(value);
428  }
429  updateGeometry();
430  getViewNet()->update();
431  break;
432  case SUMO_ATTR_LINES:
433  myLines = GNEAttributeCarrier::parse<std::vector<std::string> >(value);
434  getViewNet()->update();
435  break;
437  myBlocked = parse<bool>(value);
438  getViewNet()->update();
439  break;
440  default:
441  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
442  }
443 }
444 
445 /****************************************************************************/
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
int pfDrawString(const char *c)
Definition: polyfonts.c:1074
~GNEContainerStop()
Destructor.
double scale
information about a lane&#39;s width (temporary, used for a single view)
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:172
GUIVisualizationTextSettings addName
bool isValid(SumoXMLAttr key, const std::string &value)
method for checking if the key and their conrrespond attribute are valids
begin/end of the description of a single lane
void pfSetScale(double s)
Definition: polyfonts.c:465
const std::string & getAdditionalID() const
returns the ID of additional
GNEAdditional * getAdditional(SumoXMLTag type, const std::string &id) const
Returns the named additional.
Definition: GNENet.cpp:1331
GNELane * myLane
The lane this additional belongs.
Stores the information about how to visualize structures.
double y() const
Returns the y-position.
Definition: Position.h:68
RGBColor myTextColorSelected
Text color selected (Default blue)
double getPositionRelativeToParametricLength(double position) const
Definition: GNELane.cpp:727
double x() const
Returns the x-position.
Definition: Position.h:63
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:54
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
void pfSetPosition(double x, double y)
Definition: polyfonts.c:480
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
std::vector< std::string > getLines() const
get string vector with the lines of the busStop
std::vector< double > myShapeRotations
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:340
std::string getAttribute(SumoXMLAttr key) const
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
Position getLineCenter() const
get line center
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:65
bool isTestingModeEnabled() const
check if netedit is running in testing mode
Definition: GNEViewNet.cpp:405
double myEndPos
The end position this stopping place is located at.
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
GNEViewNet * myViewNet
The GNEViewNet this additional element belongs.
RGBColor myBaseColorSelected
base color selected (Default blue)
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
GUIVisualizationSizeSettings addSize
double getLaneParametricLength() const
returns the parameteric length of the lane
Definition: GNELane.cpp:715
#define PI
Definition: polyfonts.c:61
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
void drawLockIcon(double size=0.5) const
draw lock icon
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:439
GNEContainerStop(const std::string &id, GNELane *lane, GNEViewNet *viewNet, double startPos, double endPos, const std::vector< std::string > &lines)
Constructor.
void refreshAdditional(GNEAdditional *additional)
refreshes boundary information of an additional after a geometry update
Definition: GNENet.cpp:825
PositionVector myShape
The shape of the additional element.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
void updateGeometry()
update pre-computed geometry information
RGBColor mySignColor
sign color (Default yellow)
A list of positions.
GNELane * retrieveLane(const std::string &id, bool failHard=true)
get lane by id
Definition: GNENet.cpp:785
void setBlockIconRotation(GNELane *lane=NULL)
set Rotation of block Icon
std::vector< std::string > myLines
The list of lines that are assigned to this stop.
friend class GNEChange_Attribute
declare friend class
RGBColor myTextColor
Text color (Default cyan)
block movement of a graphic element
T MIN2(T a, T b)
Definition: StdDefs.h:64
std::vector< double > myShapeLengths
The lengths of the shape parts.
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
void setAdditionalID(const std::string &id)
set the ID of additional
const std::string getID() const
function to support debugging
PositionVector getSubpart(double beginOffset, double endOffset) const
get subpart of a position vector
void changeLane(const std::string &laneID)
change lane of additional
void move2side(double amount)
move position vector to side using certain ammount
std::string getAttribute(SumoXMLAttr key) const
Definition: GNELane.cpp:780
GNEViewNet * getViewNet() const
Returns a pointer to GNEViewNet in which additional element is located.
const PositionVector & getShape() const
returns the shape of the lane
Definition: GNELane.cpp:621
bool myBlocked
boolean to check if additional element is blocked (i.e. cannot be moved with mouse) ...
RGBColor myBaseColor
base color (Default green)
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
method for setting the attribute and letting the object perform additional changes ...
GNENet * getNet() const
get the net object
GUIGlID getGlID() const
Returns the numerical id of the object.
double myStartPos
The start position this stopping place is located at.
double getExaggeration(const GUIVisualizationSettings &s, double factor=20) const
return the drawing size including exaggeration and constantSize values
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:240
bool closeTag()
Closes the most recently opened tag.
bool isAdditionalSelected() const
void writeAdditional(OutputDevice &device) const
writte additional element into a xml file
Position mySignPos
The position of the sign.
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0)
draw Text with given parameters
Definition: GLHelper.cpp:456
double myBlockIconRotation
The rotation of the block icon.
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:228
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
RGBColor mySignColorSelected
sign selected color (Default blue)
Position myBlockIconPosition
position of the block icon
SumoXMLTag getTag() const
get XML Tag assigned to this object