SUMO - Simulation of Urban MObility
GNEDetectorE3.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>
38 #include <utils/common/ToString.h>
39 #include <utils/geom/GeomHelper.h>
46 #include <utils/gui/div/GLHelper.h>
51 
52 #include "GNEDetectorE3.h"
53 #include "GNEDetectorEntry.h"
54 #include "GNEDetectorExit.h"
55 #include "GNELane.h"
56 #include "GNEViewNet.h"
57 #include "GNEUndoList.h"
58 #include "GNENet.h"
59 #include "GNEChange_Attribute.h"
60 
61 
62 // ===========================================================================
63 // member method definitions
64 // ===========================================================================
65 
66 GNEDetectorE3::GNEDetectorE3(const std::string& id, GNEViewNet* viewNet, Position pos, double freq, const std::string& filename, const double timeThreshold, double speedThreshold) :
67  GNEAdditional(id, viewNet, pos, SUMO_TAG_E3DETECTOR, ICON_E3),
68  myFreq(freq),
69  myFilename(filename),
70  myTimeThreshold(timeThreshold),
71  mySpeedThreshold(speedThreshold) {
72  // Update geometry;
74  // Set colors
75  myBaseColor = RGBColor(76, 170, 50, 255);
76  myBaseColorSelected = RGBColor(161, 255, 135, 255);
77 }
78 
79 
81 }
82 
83 
84 void
86  // Clear shape
87  myShape.clear();
88 
89  // Set block icon position
91 
92  // Set block icon offset
93  myBlockIconOffset = Position(-0.5, -0.5);
94 
95  // Set block icon rotation, and using their rotation for draw logo
97 
98  // Set position
99  myShape.push_back(myPosition);
100 
101  // Refresh element (neccesary to avoid grabbing problems)
103 
104  // Clear all containers
105  myShapeRotations.clear();
106  myShapeLengths.clear();
107 
108 
109  // iterate over entry childs and update their gemometries
110  for (std::vector<GNEDetectorEntry*>::iterator i = myGNEDetectorEntrys.begin(); i != myGNEDetectorEntrys.end(); i++) {
111  (*i)->updateGeometryByParent();
112  }
113 
114  // iterate over entry childs and update their gemometries
115  for (std::vector<GNEDetectorExit*>::iterator i = myGNEDetectorExits.begin(); i != myGNEDetectorExits.end(); i++) {
116  (*i)->updateGeometryByParent();
117  }
118 
119  // Update connection's geometry
121 }
122 
123 
124 Position
126  return myPosition;
127 }
128 
129 
130 void
131 GNEDetectorE3::moveAdditionalGeometry(double offsetx, double offsety) {
132  // change Position
133  myPosition.set(offsetx, offsety);
134  updateGeometry();
135 }
136 
137 
138 void
139 GNEDetectorE3::commmitAdditionalGeometryMoved(double oldPosx, double oldPosy, GNEUndoList* undoList) {
140  undoList->p_begin("position of " + toString(getTag()));
141  undoList->p_add(new GNEChange_Attribute(this, SUMO_ATTR_X, toString(myPosition.x()), true, toString(oldPosx)));
142  undoList->p_add(new GNEChange_Attribute(this, SUMO_ATTR_Y, toString(myPosition.y()), true, toString(oldPosy)));
143  undoList->p_end();
144  // Refresh element
146 }
147 
148 
149 void
151  // Only save E3 if have Entry/Exits
152  if ((myGNEDetectorEntrys.size() + myGNEDetectorExits.size()) > 0) {
153  // Write parameters
154  device.openTag(getTag());
155  device.writeAttr(SUMO_ATTR_ID, getID());
157  if (!myFilename.empty()) {
159  }
162  device.writeAttr(SUMO_ATTR_X, myPosition.x());
163  device.writeAttr(SUMO_ATTR_Y, myPosition.y());
164 
165  // Write entrys
166  for (std::vector<GNEDetectorEntry*>::const_iterator i = myGNEDetectorEntrys.begin(); i != myGNEDetectorEntrys.end(); i++) {
167  device.openTag((*i)->getTag());
168  device.writeAttr(SUMO_ATTR_LANE, (*i)->getLane()->getID());
169  device.writeAttr(SUMO_ATTR_POSITION, (*i)->getPositionOverLane());
170  device.closeTag();
171  }
172 
173  // Write exits
174  for (std::vector<GNEDetectorExit*>::const_iterator i = myGNEDetectorExits.begin(); i != myGNEDetectorExits.end(); i++) {
175  device.openTag((*i)->getTag());
176  device.writeAttr(SUMO_ATTR_LANE, (*i)->getLane()->getID());
177  device.writeAttr(SUMO_ATTR_POSITION, (*i)->getPositionOverLane());
178  device.closeTag();
179  }
180 
181  // Close E3 tag
182  device.closeTag();
183  } else {
184  WRITE_WARNING(toString(getTag()) + " with ID '" + getID() + "' cannot be writed in additional file because doesn't have childs.");
185  }
186 }
187 
188 
189 std::string
191  int counter = 0;
193  counter++;
194  }
195  return (getID() + toString(SUMO_TAG_DET_ENTRY) + toString(counter));
196 }
197 
198 
199 std::string
201  int counter = 0;
203  counter++;
204  }
205  return (getID() + toString(SUMO_TAG_DET_EXIT) + toString(counter));
206 }
207 
208 
209 const std::string&
211  return myViewNet->getNet()->getMicrosimID();
212 }
213 
214 
215 void
217  // Check that entry is valid and doesn't exist previously
218  if (entry == NULL) {
219  throw InvalidArgument("Trying to add an empty " + toString(SUMO_TAG_DET_ENTRY) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
220  } else if (std::find(myGNEDetectorEntrys.begin(), myGNEDetectorEntrys.end(), entry) != myGNEDetectorEntrys.end()) {
221  throw InvalidArgument("Trying to add a duplicated " + toString(SUMO_TAG_DET_ENTRY) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
222  } else {
223  myGNEDetectorEntrys.push_back(entry);
224  }
225 }
226 
227 
228 void
230  // Check that entry is valid and exist previously
231  if (entry == NULL) {
232  throw InvalidArgument("Trying to remove an empty " + toString(SUMO_TAG_DET_ENTRY) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
233  } else if (std::find(myGNEDetectorEntrys.begin(), myGNEDetectorEntrys.end(), entry) == myGNEDetectorEntrys.end()) {
234  throw InvalidArgument("Trying to remove a non previously inserted " + toString(SUMO_TAG_DET_ENTRY) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
235  } else {
236  myGNEDetectorEntrys.erase(std::find(myGNEDetectorEntrys.begin(), myGNEDetectorEntrys.end(), entry));
237  }
238 }
239 
240 
241 void
243  // Check that exit is valid and doesn't exist previously
244  if (exit == NULL) {
245  throw InvalidArgument("Trying to add an empty " + toString(SUMO_TAG_DET_EXIT) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
246  } else if (std::find(myGNEDetectorExits.begin(), myGNEDetectorExits.end(), exit) != myGNEDetectorExits.end()) {
247  throw InvalidArgument("Trying to add a duplicated " + toString(SUMO_TAG_DET_EXIT) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
248  } else {
249  myGNEDetectorExits.push_back(exit);
250  }
251 }
252 
253 
254 void
256  // Check that exit is valid and exist previously
257  if (exit == NULL) {
258  throw InvalidArgument("Trying to remove an empty " + toString(SUMO_TAG_DET_EXIT) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
259  } else if (std::find(myGNEDetectorExits.begin(), myGNEDetectorExits.end(), exit) == myGNEDetectorExits.end()) {
260  throw InvalidArgument("Trying to remove a non previously inserted " + toString(SUMO_TAG_DET_EXIT) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
261  } else {
262  myGNEDetectorExits.erase(std::find(myGNEDetectorExits.begin(), myGNEDetectorExits.end(), exit));
263  }
264 }
265 
266 
267 int
269  return (int)myGNEDetectorEntrys.size();
270 }
271 
272 
273 int
275  return (int)myGNEDetectorExits.size();
276 }
277 
278 
279 void
281  // Start drawing adding an gl identificator
282  glPushName(getGlID());
283 
284  // Add a draw matrix for drawing logo
285  glPushMatrix();
286  glTranslated(myShape[0].x(), myShape[0].y(), getType());
287  glColor3d(1, 1, 1);
288  glRotated(180, 0, 0, 1);
289  // Draw icon depending of detector is or isn't selected
290  if (isAdditionalSelected()) {
292  } else {
294  }
295 
296  // Pop logo matrix
297  glPopMatrix();
298 
299  // Show Lock icon depending of the Edit mode
300  drawLockIcon(0.4);
301 
302  // Draw connections
304 
305  // Pop name
306  glPopName();
307 
308  // Draw name
309  drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
310 }
311 
312 
313 std::string
315  switch (key) {
316  case SUMO_ATTR_ID:
317  return getAdditionalID();
318  case SUMO_ATTR_X:
319  return toString(myPosition.x());
320  case SUMO_ATTR_Y:
321  return toString(myPosition.y());
322  case SUMO_ATTR_FREQUENCY:
323  return toString(myFreq);
324  case SUMO_ATTR_FILE:
325  return myFilename;
327  return toString(myTimeThreshold);
329  return toString(mySpeedThreshold);
331  return toString(myBlocked);
332  default:
333  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
334  }
335 }
336 
337 
338 void
339 GNEDetectorE3::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
340  if (value == getAttribute(key)) {
341  return; //avoid needless changes, later logic relies on the fact that attributes have changed
342  }
343  switch (key) {
344  case SUMO_ATTR_ID:
345  case SUMO_ATTR_FREQUENCY:
346  case SUMO_ATTR_X:
347  case SUMO_ATTR_Y:
348  case SUMO_ATTR_FILE:
352  undoList->p_add(new GNEChange_Attribute(this, key, value));
353  updateGeometry();
354  break;
355  default:
356  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
357  }
358 }
359 
360 
361 bool
362 GNEDetectorE3::isValid(SumoXMLAttr key, const std::string& value) {
363  switch (key) {
364  case SUMO_ATTR_ID:
365  if (myViewNet->getNet()->getAdditional(getTag(), value) == NULL) {
366  return true;
367  } else {
368  return false;
369  }
370  case SUMO_ATTR_X:
371  return canParse<double>(value);
372  case SUMO_ATTR_Y:
373  return canParse<double>(value);
374  case SUMO_ATTR_FREQUENCY:
375  return (canParse<double>(value) && parse<double>(value) >= 0);
376  case SUMO_ATTR_FILE:
377  return isValidFilename(value);
379  return (canParse<double>(value) && parse<double>(value) >= 0);
381  return (canParse<double>(value) && parse<double>(value) >= 0);
383  return canParse<bool>(value);
384  default:
385  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
386  }
387 }
388 
389 
390 void
391 GNEDetectorE3::setAttribute(SumoXMLAttr key, const std::string& value) {
392  switch (key) {
393  case SUMO_ATTR_ID:
394  setAdditionalID(value);
395  // Change Ids of all Entry/Exits childs
396  for (std::vector<GNEDetectorEntry*>::iterator i = myGNEDetectorEntrys.begin(); i != myGNEDetectorEntrys.end(); i++) {
397  (*i)->setAdditionalID(generateEntryID());
398  }
399  for (std::vector<GNEDetectorExit*>::iterator i = myGNEDetectorExits.begin(); i != myGNEDetectorExits.end(); i++) {
400  (*i)->setAdditionalID(generateExitID());
401  }
402  break;
403  case SUMO_ATTR_X:
404  myPosition.setx(parse<double>(value));
405  updateGeometry();
406  getViewNet()->update();
407  break;
408  case SUMO_ATTR_Y:
409  myPosition.sety(parse<double>(value));
410  updateGeometry();
411  getViewNet()->update();
412  break;
413  case SUMO_ATTR_FREQUENCY:
414  myFreq = parse<double>(value);
415  break;
416  case SUMO_ATTR_FILE:
417  myFilename = value;
418  break;
420  myTimeThreshold = parse<double>(value);
421  break;
423  mySpeedThreshold = parse<double>(value);
424  break;
426  myBlocked = parse<bool>(value);
427  getViewNet()->update();
428  break;
429  default:
430  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
431  }
432 }
433 
434 
435 void
437  myConnectionPositions.clear();
438  // Iterate over Entrys
439  for (std::vector<GNEDetectorEntry*>::iterator i = myGNEDetectorEntrys.begin(); i != myGNEDetectorEntrys.end(); i++) {
440  std::vector<Position> posConnection;
441  double A = std::abs((*i)->getPositionInView().x() - getPositionInView().x());
442  double B = std::abs((*i)->getPositionInView().y() - getPositionInView().y());
443  // Set positions of connection's vertex. Connection is build from Entry to E3
444  posConnection.push_back((*i)->getPositionInView());
445  if (getPositionInView().x() > (*i)->getPositionInView().x()) {
446  if (getPositionInView().y() > (*i)->getPositionInView().y()) {
447  posConnection.push_back(Position((*i)->getPositionInView().x() + A, (*i)->getPositionInView().y()));
448  } else {
449  posConnection.push_back(Position((*i)->getPositionInView().x(), (*i)->getPositionInView().y() - B));
450  }
451  } else {
452  if (getPositionInView().y() > (*i)->getPositionInView().y()) {
453  posConnection.push_back(Position((*i)->getPositionInView().x(), (*i)->getPositionInView().y() + B));
454  } else {
455  posConnection.push_back(Position((*i)->getPositionInView().x() - A, (*i)->getPositionInView().y()));
456  }
457  }
458  posConnection.push_back(getPositionInView());
459  myConnectionPositions.push_back(posConnection);
460  }
461  // Iterate over exits
462  for (std::vector<GNEDetectorExit*>::iterator i = myGNEDetectorExits.begin(); i != myGNEDetectorExits.end(); i++) {
463  std::vector<Position> posConnection;
464  double A = std::abs((*i)->getPositionInView().x() - getPositionInView().x());
465  double B = std::abs((*i)->getPositionInView().y() - getPositionInView().y());
466  // Set positions of connection's vertex. Connection is build from Entry to E3
467  posConnection.push_back((*i)->getPositionInView());
468  if (getPositionInView().x() > (*i)->getPositionInView().x()) {
469  if (getPositionInView().y() > (*i)->getPositionInView().y()) {
470  posConnection.push_back(Position((*i)->getPositionInView().x() + A, (*i)->getPositionInView().y()));
471  } else {
472  posConnection.push_back(Position((*i)->getPositionInView().x(), (*i)->getPositionInView().y() - B));
473  }
474  } else {
475  if (getPositionInView().y() > (*i)->getPositionInView().y()) {
476  posConnection.push_back(Position((*i)->getPositionInView().x(), (*i)->getPositionInView().y() + B));
477  } else {
478  posConnection.push_back(Position((*i)->getPositionInView().x() - A, (*i)->getPositionInView().y()));
479  }
480  }
481  posConnection.push_back(getPositionInView());
482  myConnectionPositions.push_back(posConnection);
483  }
484 }
485 
486 /****************************************************************************/
static void drawTexturedBox(int which, double size)
Draws a named texture as a box with the given size.
double mySpeedThreshold
The speed-based threshold that describes how slow a vehicle has to be to be recognized as halting...
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
const std::string & getParentName() const
Returns the name of the parent object (if any)
void moveAdditionalGeometry(double offsetx, double offsety)
change the position of the E3 geometry
double scale
information about a lane&#39;s width (temporary, used for a single view)
void commmitAdditionalGeometryMoved(double oldPosx, double oldPosy, GNEUndoList *undoList)
updated geometry changes in the attributes of additional
GNEDetectorE3(const std::string &id, GNEViewNet *viewNet, Position pos, double freq, const std::string &filename, const double timeThreshold, double speedThreshold)
GNEDetectorE3 Constructor.
GUIVisualizationTextSettings addName
std::string getAttribute(SumoXMLAttr key) const
const std::string & getAdditionalID() const
returns the ID of additional
static GUIGlID getTexture(GUITexture which)
returns a texture previously defined in the enum GUITexture
GNEAdditional * getAdditional(SumoXMLTag type, const std::string &id) const
Returns the named additional.
Definition: GNENet.cpp:1331
Position getPositionInView() const
Returns position of detector E3 in view.
Stores the information about how to visualize structures.
double y() const
Returns the y-position.
Definition: Position.h:68
void addExitChild(GNEDetectorExit *exit)
add an Exit child
double myTimeThreshold
The time-based threshold that describes how much time has to pass until a vehicle is recognized as ha...
double x() const
Returns the x-position.
Definition: Position.h:63
std::vector< GNEDetectorEntry * > myGNEDetectorEntrys
vector with the GNEDetectorE3EntryExits of the detector
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
void p_begin(const std::string &description)
Begin undo command sub-group. This begins a new group of commands that are treated as a single comman...
Definition: GNEUndoList.cpp:82
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
void set(double x, double y)
set positions x and y
Definition: Position.h:93
static bool isValidFilename(const std::string &value)
true if value is a valid file value
std::vector< double > myShapeRotations
#define abs(a)
Definition: polyfonts.c:67
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
int getNumberOfEntryChilds() const
get number of entry childs
an e3 entry point
bool isValid(SumoXMLAttr key, const std::string &value)
method for checking if the key and their conrrespond attribute are valids
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
void drawParentAndChildrenConnections() const
draw connections between Parent and childrens
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
void updateGeometry()
update pre-computed geometry information
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.
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise, the sub-group will be added as a new command into parent group. A matching begin() must have been called previously.
Definition: GNEUndoList.cpp:89
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
void setx(double x)
set position x
Definition: Position.h:78
an e3 exit point
void setBlockIconRotation(GNELane *lane=NULL)
set Rotation of block Icon
friend class GNEChange_Attribute
declare friend class
std::vector< std::vector< Position > > myConnectionPositions
Matrix with the Vertex&#39;s positions of connections between Additional Parent an their childs...
std::vector< GNEDetectorExit * > myGNEDetectorExits
vector with the GNEDetectorE3EntryExits of the detector
void updateGeometryConnections()
update Connection&#39;s geometry
block movement of a graphic element
std::string generateEntryID()
gererate a new ID for an Entry detector child
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
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
const std::string getID() const
function to support debugging
void writeAdditional(OutputDevice &device) const
writte additionals element into a xml file
Position myBlockIconOffset
The offSet of the block icon.
double myFreq
frequency of E3 detector
GNEViewNet * getViewNet() const
Returns a pointer to GNEViewNet in which additional element is located.
bool myBlocked
boolean to check if additional element is blocked (i.e. cannot be moved with mouse) ...
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:62
void sety(double y)
set position y
Definition: Position.h:83
RGBColor myBaseColor
base color (Default green)
~GNEDetectorE3()
GNEDetectorE3 6Destructor.
GNENet * getNet() const
get the net object
GUIGlID getGlID() const
Returns the numerical id of the object.
int getNumberOfExitChilds() const
get number of exit childs
void addEntryChild(GNEDetectorEntry *entry)
add an Entry child
void removeEntryChild(GNEDetectorEntry *entry)
delete an Entry child
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
Position myPosition
The position in which this additional element is located.
bool closeTag()
Closes the most recently opened tag.
bool isAdditionalSelected() const
std::string generateExitID()
gererate a new ID for an Exit detector child
void removeExitChild(GNEDetectorExit *exit)
delete an Exit child
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
std::string myFilename
fielname of E3 detector
Position myBlockIconPosition
position of the block icon
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
method for setting the attribute and letting the object perform additional changes ...
SumoXMLTag getTag() const
get XML Tag assigned to this object