SUMO - Simulation of Urban MObility
GNEDetectorE2.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 //
18 /****************************************************************************/
19 
20 // ===========================================================================
21 // included modules
22 // ===========================================================================
23 #ifdef _MSC_VER
24 #include <windows_config.h>
25 #else
26 #include <config.h>
27 #endif
28 
29 #include <string>
30 #include <iostream>
31 #include <utility>
35 #include <utils/common/ToString.h>
36 #include <utils/geom/GeomHelper.h>
42 #include <utils/gui/div/GLHelper.h>
46 
47 #include "GNEDetectorE2.h"
48 #include "GNELane.h"
49 #include "GNEViewNet.h"
50 #include "GNEUndoList.h"
51 #include "GNENet.h"
52 #include "GNEChange_Attribute.h"
53 #include "GNEEdge.h"
54 
55 
56 // ===========================================================================
57 // member method definitions
58 // ===========================================================================
59 
60 GNEDetectorE2::GNEDetectorE2(const std::string& id, GNELane* lane, GNEViewNet* viewNet, double pos, double length, double freq, const std::string& filename,
61  bool cont, const double timeThreshold, double speedThreshold, double jamThreshold, bool friendlyPos) :
62  GNEDetector(id, viewNet, SUMO_TAG_E2DETECTOR, ICON_E2, lane, pos, freq, filename, friendlyPos, NULL),
63  myRelativeLength(length / lane->getLaneParametricLength()),
64  myCont(cont),
65  myTimeThreshold(timeThreshold),
66  mySpeedThreshold(speedThreshold),
67  myJamThreshold(jamThreshold) {
68 }
69 
70 
72 }
73 
74 
75 void
77  // Clear all containers
78  myShapeRotations.clear();
79  myShapeLengths.clear();
80 
81  // Get shape of lane parent
82  myShape = myLane->getShape();
83 
84  // Cut shape using as delimitators fixed start position and fixed end position
85  double startPosFixed = (myPositionOverLane < 0) ? 0 : myPositionOverLane;
86  double endPosFixed = ((myPositionOverLane + myRelativeLength) > 1) ? 1 : (myPositionOverLane + myRelativeLength);
87  myShape = myShape.getSubpart(startPosFixed * myShape.length(), endPosFixed * myShape.length());
88 
89  // Get number of parts of the shape
90  int numberOfSegments = (int)myShape.size() - 1;
91 
92  // If number of segments is more than 0
93  if (numberOfSegments >= 0) {
94 
95  // Reserve memory (To improve efficiency)
96  myShapeRotations.reserve(numberOfSegments);
97  myShapeLengths.reserve(numberOfSegments);
98 
99  // For every part of the shape
100  for (int i = 0; i < numberOfSegments; ++i) {
101 
102  // Obtain first position
103  const Position& f = myShape[i];
104 
105  // Obtain next position
106  const Position& s = myShape[i + 1];
107 
108  // Save distance between position into myShapeLengths
109  myShapeLengths.push_back(f.distanceTo(s));
110 
111  // Save rotation (angle) of the vector constructed by points f and s
112  myShapeRotations.push_back((double)atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double)M_PI);
113  }
114  }
115 
116  // Set block icon position
118 
119  // Set offset of the block icon
120  myBlockIconOffset = Position(-0.75, 0);
121 
122  // Set block icon rotation, and using their rotation for draw logo
124 
125  // Refresh element (neccesary to avoid grabbing problems)
126  myViewNet->getNet()->refreshElement(this);
127 }
128 
129 
130 void
132  // Write parameters
133  device.openTag(getTag());
134  device.writeAttr(SUMO_ATTR_ID, getID());
135  device.writeAttr(SUMO_ATTR_LANE, myLane->getID());
139  if (!myFilename.empty()) {
141  }
147  // Close tag
148  device.closeTag();
149 }
150 
151 
153  // with friendly position enabled position are "always fixed"
154  if (myFriendlyPosition) {
155  return true;
156  } else {
157  // floors are needed to avoid precision problems
158  return ((floor(myPositionOverLane * 1000) / 1000) >= 0) && ((floor((myPositionOverLane + myRelativeLength) * 1000) / 1000) <= 1);
159  }
160 }
161 
162 
165 }
166 
167 
168 void
170  // Start drawing adding an gl identificator
171  glPushName(getGlID());
172 
173  // Add a draw matrix
174  glPushMatrix();
175 
176  // Start with the drawing of the area traslating matrix to origing
177  glTranslated(0, 0, getType());
178 
179  // Set color of the base
180  if (isAdditionalSelected()) {
182  } else {
183  GLHelper::setColor(RGBColor(0, 204, 204));
184  }
185 
186  // Obtain exaggeration of the draw
187  const double exaggeration = s.addSize.getExaggeration(s);
188 
189  // Draw the area using shape, shapeRotations, shapeLengths and value of exaggeration
191 
192  // Pop last matrix
193  glPopMatrix();
194 
195  // Check if the distance is enougth to draw details
196  if (s.scale * exaggeration >= 10) {
197  // Push matrix
198  glPushMatrix();
199  // Traslate to center of detector
200  glTranslated(myShape.getLineCenter().x(), myShape.getLineCenter().y(), getType() + 0.1);
201  // Rotate depending of myBlockIconRotation
202  glRotated(myBlockIconRotation, 0, 0, -1);
203  //move to logo position
204  glTranslated(-0.75, 0, 0);
205  // draw E2 logo
206  if (isAdditionalSelected()) {
208  } else {
209  GLHelper::drawText("E2", Position(), .1, 1.5, RGBColor::BLACK);
210  }
211  // pop matrix
212  glPopMatrix();
213 
214  // Show Lock icon depending of the Edit mode
215  drawLockIcon();
216  }
217 
218  // Draw name
219  drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
220 
221  // Pop name
222  glPopName();
223 }
224 
225 
226 std::string
228  switch (key) {
229  case SUMO_ATTR_ID:
230  return getAdditionalID();
231  case SUMO_ATTR_LANE:
232  return myLane->getID();
233  case SUMO_ATTR_POSITION:
235  case SUMO_ATTR_FREQUENCY:
236  return toString(myFreq);
237  case SUMO_ATTR_LENGTH:
239  case SUMO_ATTR_FILE:
240  return myFilename;
241  case SUMO_ATTR_CONT:
242  return toString(myCont);
244  return toString(myTimeThreshold);
246  return toString(mySpeedThreshold);
248  return toString(myJamThreshold);
252  return toString(myBlocked);
253  default:
254  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
255  }
256 }
257 
258 
259 void
260 GNEDetectorE2::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
261  if (value == getAttribute(key)) {
262  return; //avoid needless changes, later logic relies on the fact that attributes have changed
263  }
264  switch (key) {
265  case SUMO_ATTR_ID:
266  case SUMO_ATTR_LANE:
267  case SUMO_ATTR_POSITION:
268  case SUMO_ATTR_FREQUENCY:
269  case SUMO_ATTR_LENGTH:
270  case SUMO_ATTR_FILE:
271  case SUMO_ATTR_CONT:
277  undoList->p_add(new GNEChange_Attribute(this, key, value));
278  break;
279  default:
280  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
281  }
282 }
283 
284 
285 bool
286 GNEDetectorE2::isValid(SumoXMLAttr key, const std::string& value) {
287  switch (key) {
288  case SUMO_ATTR_ID:
289  return isValidAdditionalID(value);
290  case SUMO_ATTR_LANE:
291  if (myViewNet->getNet()->retrieveLane(value, false) != NULL) {
292  return true;
293  } else {
294  return false;
295  }
296  case SUMO_ATTR_POSITION:
297  return canParse<double>(value);
298  case SUMO_ATTR_FREQUENCY:
299  return (canParse<double>(value) && (parse<double>(value) >= 0));
300  case SUMO_ATTR_LENGTH:
301  if (canParse<double>(value)) {
302  // obtain relative new start position
303  double newLength = parse<double>(value);
304  // lengths withs size 0 aren't valid
305  if (newLength <= 0) {
306  return false;
307  } else {
308  newLength = newLength / myLane->getLaneParametricLength();
309  if ((myPositionOverLane + newLength) > 1) {
310  return false;
311  } else {
312  return true;
313  }
314  }
315  }
316  case SUMO_ATTR_FILE:
317  return isValidFilename(value);
318  case SUMO_ATTR_CONT:
319  return canParse<bool>(value);
321  return (canParse<double>(value) && (parse<double>(value) >= 0));
323  return (canParse<double>(value) && (parse<double>(value) >= 0));
325  return (canParse<double>(value) && (parse<double>(value) >= 0));
327  return canParse<bool>(value);
329  return canParse<bool>(value);
330  default:
331  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
332  }
333 }
334 
335 // ===========================================================================
336 // private
337 // ===========================================================================
338 
339 void
340 GNEDetectorE2::setAttribute(SumoXMLAttr key, const std::string& value) {
341  switch (key) {
342  case SUMO_ATTR_ID:
343  changeAdditionalID(value);
344  break;
345  case SUMO_ATTR_LANE:
346  myLane = changeLane(myLane, value);
347  break;
348  case SUMO_ATTR_POSITION:
349  myPositionOverLane = parse<double>(value) / myLane->getLaneParametricLength();
350  break;
351  case SUMO_ATTR_FREQUENCY:
352  myFreq = parse<double>(value);
353  break;
354  case SUMO_ATTR_LENGTH:
355  myRelativeLength = parse<double>(value) / myLane->getLaneParametricLength();
356  break;
357  case SUMO_ATTR_FILE:
358  myFilename = value;
359  break;
360  case SUMO_ATTR_CONT:
361  myCont = parse<bool>(value);
362  break;
364  myTimeThreshold = parse<double>(value);
365  break;
367  mySpeedThreshold = parse<double>(value);
368  break;
370  myJamThreshold = parse<double>(value);
371  break;
373  myFriendlyPosition = parse<bool>(value);;
374  break;
376  myBlocked = parse<bool>(value);
377  break;
378  default:
379  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
380  }
381  // After setting attribute always update Geometry
382  updateGeometry();
383 }
384 
385 /****************************************************************************/
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:260
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:183
GUIVisualizationTextSettings addName
void refreshElement(GUIGlObject *o)
refreshes boundary information for o and update
Definition: GNENet.cpp:1082
bool isDetectorPositionFixed() const
check if Position of detector is fixed
const std::string & getAdditionalID() const
returns Additional ID
void writeAdditional(OutputDevice &device) const
writte additional element into a xml file
Stores the information about how to visualize structures.
double y() const
Returns the y-position.
Definition: Position.h:67
double myRelativeLength
relative length [0,1]
double x() const
Returns the x-position.
Definition: Position.h:62
double myFreq
The aggregation period the values the detector collects shall be summed up.
Definition: GNEDetector.h:141
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, int align=0, double width=-1)
Definition: GLHelper.cpp:487
bool myCont
attribute to enable or disable splitByType
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:53
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
method for setting the attribute and letting the object perform additional changes ...
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
double getAbsoluteLenght() const
get absolute lenght
void updateGeometry()
update pre-computed geometry information
static const RGBColor BLACK
Definition: RGBColor.h:186
static bool isValidFilename(const std::string &value)
true if value is a valid file value
std::vector< double > myShapeRotations
void changeAdditionalID(const std::string &newID)
change ID of additional
Position getLineCenter() const
get line center
~GNEDetectorE2()
Destructor.
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.
double mySpeedThreshold
The speed-based threshold that describes how slow a vehicle has to be to be recognized as halting...
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
GUIVisualizationSizeSettings addSize
static const RGBColor selectedAdditionalColor
color of selected additionals
Definition: GNENet.h:116
double getLaneParametricLength() const
returns the parameteric length of the lane
Definition: GNELane.cpp:701
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:55
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:449
PositionVector myShape
The shape of the additional element.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:45
friend class GNEChange_Attribute
declare friend class
block movement of a graphic element
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
const std::string getID() const
function to support debugging
PositionVector getSubpart(double beginOffset, double endOffset) const
get subpart of a position vector
bool myFriendlyPosition
Flag for friendly position.
Definition: GNEDetector.h:147
Position myBlockIconOffset
The offSet of the block icon.
std::string myFilename
The path to the output file.
Definition: GNEDetector.h:144
std::string getAttribute(SumoXMLAttr key) const
This functions has to be implemented in all GNEAttributeCarriers.
const PositionVector & getShape() const
returns the shape of the lane
Definition: GNELane.cpp:599
bool myBlocked
boolean to check if additional element is blocked (i.e. cannot be moved with mouse) ...
double length() const
Returns the length.
#define M_PI
Definition: odrSpiral.cpp:40
bool isValid(SumoXMLAttr key, const std::string &value)
method for checking if the key and their conrrespond attribute are valids
void setBlockIconRotation(GNELane *additionalLane=NULL)
GNELane * myLane
The lane in which this detector is placed.
Definition: GNEDetector.h:135
GNENet * getNet() const
get the net object
GUIGlID getGlID() const
Returns the numerical id of the object.
double getExaggeration(const GUIVisualizationSettings &s, double factor=20) const
return the drawing size including exaggeration and constantSize values
double myTimeThreshold
The time-based threshold that describes how much time has to pass until a vehicle is recognized as ha...
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:70
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:239
bool closeTag()
Closes the most recently opened tag.
GNEDetectorE2(const std::string &id, GNELane *lane, GNEViewNet *viewNet, double pos, double length, double freq, const std::string &filename, bool cont, const double timeThreshold, double speedThreshold, double jamThreshold, bool friendlyPos)
Constructor.
bool isValidAdditionalID(const std::string &newID) const
check if a new additional ID is valid
double myJamThreshold
The minimum distance to the next standing vehicle in order to make this vehicle count as a participan...
bool isAdditionalSelected() const
static const RGBColor selectionColor
Definition: GNENet.h:107
GNELane * retrieveLane(const std::string &id, bool failHard=true, bool checkVolatileChange=false)
get lane by id
Definition: GNENet.cpp:1000
double getAbsolutePositionOverLane() const
get absolute position over Lane
Definition: GNEDetector.cpp:80
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
double myBlockIconRotation
The rotation of the block icon.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
GNELane * changeLane(GNELane *oldLane, const std::string &newLaneID)
change lane of additional
double myPositionOverLane
position of detector over Lane
Definition: GNEDetector.h:138
Position myBlockIconPosition
position of the block icon
SumoXMLTag getTag() const
get XML Tag assigned to this object