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...
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
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
const std::string & getParentName() const
Returns the name of the parent object (if any)
static GUIGlID getTexture(GUITexture which)
returns a texture previously defined in the enum GUITexture
double x() const
Returns the x-position.
Definition: Position.h:63
Stores the information about how to visualize structures.
void addExitChild(GNEDetectorExit *exit)
add an Exit child
bool isAdditionalSelected() const
double myTimeThreshold
The time-based threshold that describes how much time has to pass until a vehicle is recognized as ha...
Position getPositionInView() const
Returns position of detector E3 in view.
std::vector< GNEDetectorEntry * > myGNEDetectorEntrys
vector with the GNEDetectorE3EntryExits of the detector
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 writeAdditional(OutputDevice &device) const
writte additionals element into a xml file
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
GUIGlID getGlID() const
Returns the numerical id of the object.
#define abs(a)
Definition: polyfonts.c:67
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
an e3 entry point
bool isValid(SumoXMLAttr key, const std::string &value)
method for checking if the key and their conrrespond attribute are valids
GNEViewNet * myViewNet
The GNEViewNet this additional element belongs.
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
RGBColor myBaseColorSelected
base color selected (Default blue)
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
GNEViewNet * getViewNet() const
Returns a pointer to GNEViewNet in which additional element is located.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
const std::string & getAdditionalID() const
returns the ID of additional
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
double y() const
Returns the y-position.
Definition: Position.h:68
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 setAdditionalID(const std::string &id)
set the ID of additional
const std::string getID() const
function to support debugging
void drawLockIcon(double size=0.5) const
draw lock icon
Position myBlockIconOffset
The offSet of the block icon.
void drawParentAndChildrenConnections() const
draw connections between Parent and childrens
GNEAdditional * getAdditional(SumoXMLTag type, const std::string &id) const
Returns the named additional.
Definition: GNENet.cpp:1331
double myFreq
frequency of E3 detector
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)
std::string getAttribute(SumoXMLAttr key) const
GNENet * getNet() const
get the net object
~GNEDetectorE3()
GNEDetectorE3 6Destructor.
SumoXMLTag getTag() const
get XML Tag assigned to this object
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.
std::string generateExitID()
gererate a new ID for an Exit detector child
int getNumberOfEntryChilds() const
get number of entry childs
int getNumberOfExitChilds() const
get number of exit childs
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
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
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 ...