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 #ifdef CHECK_MEMORY_LEAKS
62 #include <foreign/nvwa/debug_new.h>
63 #endif
64 
65 // ===========================================================================
66 // member method definitions
67 // ===========================================================================
68 
69 GNEDetectorE3::GNEDetectorE3(const std::string& id, GNEViewNet* viewNet, Position pos, SUMOReal freq, const std::string& filename, const SUMOReal timeThreshold, SUMOReal speedThreshold) :
70  GNEAdditional(id, viewNet, pos, SUMO_TAG_E3DETECTOR, ICON_E3),
71  myFreq(freq),
72  myFilename(filename),
73  myTimeThreshold(timeThreshold),
74  mySpeedThreshold(speedThreshold) {
75  // Update geometry;
77  // Set colors
78  myBaseColor = RGBColor(76, 170, 50, 255);
79  myBaseColorSelected = RGBColor(161, 255, 135, 255);
80 }
81 
82 
84 }
85 
86 
87 void
89  // Clear shape
90  myShape.clear();
91 
92  // Set block icon position
94 
95  // Set block icon offset
96  myBlockIconOffset = Position(-0.5, -0.5);
97 
98  // Set block icon rotation, and using their rotation for draw logo
100 
101  // Set position
102  myShape.push_back(myPosition);
103 
104  // Refresh element (neccesary to avoid grabbing problems)
106 
107  // Clear all containers
108  myShapeRotations.clear();
109  myShapeLengths.clear();
110 
111 
112  // iterate over entry childs and update their gemometries
113  for (std::vector<GNEDetectorEntry*>::iterator i = myGNEDetectorEntrys.begin(); i != myGNEDetectorEntrys.end(); i++) {
114  (*i)->updateGeometryByParent();
115  }
116 
117  // iterate over entry childs and update their gemometries
118  for (std::vector<GNEDetectorExit*>::iterator i = myGNEDetectorExits.begin(); i != myGNEDetectorExits.end(); i++) {
119  (*i)->updateGeometryByParent();
120  }
121 
122  // Update connection's geometry
124 }
125 
126 
127 Position
129  return myPosition;
130 }
131 
132 
133 void
135  // change Position
136  myPosition.set(offsetx, offsety);
137  updateGeometry();
138 }
139 
140 
141 void
143  undoList->p_begin("position of " + toString(getTag()));
144  undoList->p_add(new GNEChange_Attribute(this, SUMO_ATTR_X, toString(myPosition.x()), true, toString(oldPosx)));
145  undoList->p_add(new GNEChange_Attribute(this, SUMO_ATTR_Y, toString(myPosition.y()), true, toString(oldPosy)));
146  undoList->p_end();
147  // Refresh element
149 }
150 
151 
152 void
154  // Only save E3 if have Entry/Exits
155  if ((myGNEDetectorEntrys.size() + myGNEDetectorExits.size()) > 0) {
156  // Write parameters
157  device.openTag(getTag());
158  device.writeAttr(SUMO_ATTR_ID, getID());
160  if (!myFilename.empty()) {
162  }
165  device.writeAttr(SUMO_ATTR_X, myPosition.x());
166  device.writeAttr(SUMO_ATTR_Y, myPosition.y());
167 
168  // Write entrys
169  for (std::vector<GNEDetectorEntry*>::const_iterator i = myGNEDetectorEntrys.begin(); i != myGNEDetectorEntrys.end(); i++) {
170  device.openTag((*i)->getTag());
171  device.writeAttr(SUMO_ATTR_LANE, (*i)->getLane()->getID());
172  device.writeAttr(SUMO_ATTR_POSITION, (*i)->getPositionOverLane());
173  device.closeTag();
174  }
175 
176  // Write exits
177  for (std::vector<GNEDetectorExit*>::const_iterator i = myGNEDetectorExits.begin(); i != myGNEDetectorExits.end(); i++) {
178  device.openTag((*i)->getTag());
179  device.writeAttr(SUMO_ATTR_LANE, (*i)->getLane()->getID());
180  device.writeAttr(SUMO_ATTR_POSITION, (*i)->getPositionOverLane());
181  device.closeTag();
182  }
183 
184  // Close E3 tag
185  device.closeTag();
186  } else {
187  WRITE_WARNING(toString(getTag()) + " with ID '" + getID() + "' cannot be writed in additional file because doesn't have childs.");
188  }
189 }
190 
191 
192 std::string
194  int counter = 0;
195  while (myViewNet->getNet()->getAdditional(SUMO_TAG_DET_ENTRY, getID() + "_Entry" + toString(counter)) != NULL) {
196  counter++;
197  }
198  return (getID() + "_Det_Entry" + toString(counter));
199 }
200 
201 
202 std::string
204  int counter = 0;
205  while (myViewNet->getNet()->getAdditional(SUMO_TAG_DET_EXIT, getID() + "_Exit" + toString(counter)) != NULL) {
206  counter++;
207  }
208  return (getID() + "_Det_Exit" + toString(counter));
209 }
210 
211 
212 const std::string&
214  return myViewNet->getNet()->getMicrosimID();
215 }
216 
217 
218 void
220  // Check that entry is valid and doesn't exist previously
221  if (entry == NULL) {
222  throw InvalidArgument("Trying to add an empty " + toString(SUMO_TAG_DET_ENTRY) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
223  } else if (std::find(myGNEDetectorEntrys.begin(), myGNEDetectorEntrys.end(), entry) != myGNEDetectorEntrys.end()) {
224  throw InvalidArgument("Trying to add a duplicated " + toString(SUMO_TAG_DET_ENTRY) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
225  } else {
226  myGNEDetectorEntrys.push_back(entry);
227  }
228 }
229 
230 
231 void
233  // Check that entry is valid and exist previously
234  if (entry == NULL) {
235  throw InvalidArgument("Trying to remove an empty " + toString(SUMO_TAG_DET_ENTRY) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
236  } else if (std::find(myGNEDetectorEntrys.begin(), myGNEDetectorEntrys.end(), entry) == myGNEDetectorEntrys.end()) {
237  throw InvalidArgument("Trying to remove a non previously inserted " + toString(SUMO_TAG_DET_ENTRY) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
238  } else {
239  myGNEDetectorEntrys.erase(std::find(myGNEDetectorEntrys.begin(), myGNEDetectorEntrys.end(), entry));
240  }
241 }
242 
243 
244 void
246  // Check that exit is valid and doesn't exist previously
247  if (exit == NULL) {
248  throw InvalidArgument("Trying to add an empty " + toString(SUMO_TAG_DET_EXIT) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
249  } else if (std::find(myGNEDetectorExits.begin(), myGNEDetectorExits.end(), exit) != myGNEDetectorExits.end()) {
250  throw InvalidArgument("Trying to add a duplicated " + toString(SUMO_TAG_DET_EXIT) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
251  } else {
252  myGNEDetectorExits.push_back(exit);
253  }
254 }
255 
256 
257 void
259  // Check that exit is valid and exist previously
260  if (exit == NULL) {
261  throw InvalidArgument("Trying to remove an empty " + toString(SUMO_TAG_DET_EXIT) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
262  } else if (std::find(myGNEDetectorExits.begin(), myGNEDetectorExits.end(), exit) == myGNEDetectorExits.end()) {
263  throw InvalidArgument("Trying to remove a non previously inserted " + toString(SUMO_TAG_DET_EXIT) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
264  } else {
265  myGNEDetectorExits.erase(std::find(myGNEDetectorExits.begin(), myGNEDetectorExits.end(), exit));
266  }
267 }
268 
269 
270 int
272  return (int)myGNEDetectorEntrys.size();
273 }
274 
275 
276 int
278  return (int)myGNEDetectorExits.size();
279 }
280 
281 
282 void
284  // Start drawing adding an gl identificator
285  glPushName(getGlID());
286 
287  // Add a draw matrix for drawing logo
288  glPushMatrix();
289  glTranslated(myShape[0].x(), myShape[0].y(), getType());
290  glColor3d(1, 1, 1);
291  glRotated(180, 0, 0, 1);
292  // Draw icon depending of detector is or isn't selected
293  if (isAdditionalSelected()) {
295  } else {
297  }
298 
299  // Pop logo matrix
300  glPopMatrix();
301 
302  // Show Lock icon depending of the Edit mode
303  drawLockIcon(0.4);
304 
305  // Draw connections
307 
308  // Pop name
309  glPopName();
310 
311  // Draw name
312  drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
313 }
314 
315 
316 std::string
318  switch (key) {
319  case SUMO_ATTR_ID:
320  return getAdditionalID();
321  case SUMO_ATTR_X:
322  return toString(myPosition.x());
323  case SUMO_ATTR_Y:
324  return toString(myPosition.y());
325  case SUMO_ATTR_FREQUENCY:
326  return toString(myFreq);
327  case SUMO_ATTR_FILE:
328  return myFilename;
330  return toString(myTimeThreshold);
332  return toString(mySpeedThreshold);
334  return toString(myBlocked);
335  default:
336  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
337  }
338 }
339 
340 
341 void
342 GNEDetectorE3::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
343  if (value == getAttribute(key)) {
344  return; //avoid needless changes, later logic relies on the fact that attributes have changed
345  }
346  switch (key) {
347  case SUMO_ATTR_ID:
348  case SUMO_ATTR_FREQUENCY:
349  case SUMO_ATTR_X:
350  case SUMO_ATTR_Y:
351  case SUMO_ATTR_FILE:
355  undoList->p_add(new GNEChange_Attribute(this, key, value));
356  updateGeometry();
357  break;
358  default:
359  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
360  }
361 }
362 
363 
364 bool
365 GNEDetectorE3::isValid(SumoXMLAttr key, const std::string& value) {
366  switch (key) {
367  case SUMO_ATTR_ID:
368  if (myViewNet->getNet()->getAdditional(getTag(), value) == NULL) {
369  return true;
370  } else {
371  return false;
372  }
373  case SUMO_ATTR_X:
374  return canParse<SUMOReal>(value);
375  case SUMO_ATTR_Y:
376  return canParse<SUMOReal>(value);
377  case SUMO_ATTR_FREQUENCY:
378  return (canParse<SUMOReal>(value) && parse<SUMOReal>(value) > 0);
379  case SUMO_ATTR_FILE:
380  return isValidFileValue(value);
382  return canParse<SUMOReal>(value);
384  return canParse<SUMOReal>(value);
386  return canParse<bool>(value);
387  default:
388  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
389  }
390 }
391 
392 
393 void
394 GNEDetectorE3::setAttribute(SumoXMLAttr key, const std::string& value) {
395  switch (key) {
396  case SUMO_ATTR_ID:
397  setAdditionalID(value);
398  // Change Ids of all Entry/Exits childs
399  for (std::vector<GNEDetectorEntry*>::iterator i = myGNEDetectorEntrys.begin(); i != myGNEDetectorEntrys.end(); i++) {
400  (*i)->setAdditionalID(generateEntryID());
401  }
402  for (std::vector<GNEDetectorExit*>::iterator i = myGNEDetectorExits.begin(); i != myGNEDetectorExits.end(); i++) {
403  (*i)->setAdditionalID(generateExitID());
404  }
405  break;
406  case SUMO_ATTR_X:
407  myPosition.setx(parse<SUMOReal>(value));
408  updateGeometry();
409  getViewNet()->update();
410  break;
411  case SUMO_ATTR_Y:
412  myPosition.sety(parse<SUMOReal>(value));
413  updateGeometry();
414  getViewNet()->update();
415  break;
416  case SUMO_ATTR_FREQUENCY:
417  myFreq = parse<SUMOReal>(value);
418  break;
419  case SUMO_ATTR_FILE:
420  myFilename = value;
421  break;
423  myTimeThreshold = parse<SUMOReal>(value);
424  break;
426  mySpeedThreshold = parse<SUMOReal>(value);
427  break;
429  myBlocked = parse<bool>(value);
430  getViewNet()->update();
431  break;
432  default:
433  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
434  }
435 }
436 
437 
438 void
440  myConnectionPositions.clear();
441  // Iterate over Entrys
442  for (std::vector<GNEDetectorEntry*>::iterator i = myGNEDetectorEntrys.begin(); i != myGNEDetectorEntrys.end(); i++) {
443  std::vector<Position> posConnection;
444  SUMOReal A = std::abs((*i)->getPositionInView().x() - getPositionInView().x());
445  SUMOReal B = std::abs((*i)->getPositionInView().y() - getPositionInView().y());
446  // Set positions of connection's vertex. Connection is build from Entry to E3
447  posConnection.push_back((*i)->getPositionInView());
448  if (getPositionInView().x() > (*i)->getPositionInView().x()) {
449  if (getPositionInView().y() > (*i)->getPositionInView().y()) {
450  posConnection.push_back(Position((*i)->getPositionInView().x() + A, (*i)->getPositionInView().y()));
451  } else {
452  posConnection.push_back(Position((*i)->getPositionInView().x(), (*i)->getPositionInView().y() - B));
453  }
454  } else {
455  if (getPositionInView().y() > (*i)->getPositionInView().y()) {
456  posConnection.push_back(Position((*i)->getPositionInView().x(), (*i)->getPositionInView().y() + B));
457  } else {
458  posConnection.push_back(Position((*i)->getPositionInView().x() - A, (*i)->getPositionInView().y()));
459  }
460  }
461  posConnection.push_back(getPositionInView());
462  myConnectionPositions.push_back(posConnection);
463  }
464  // Iterate over exits
465  for (std::vector<GNEDetectorExit*>::iterator i = myGNEDetectorExits.begin(); i != myGNEDetectorExits.end(); i++) {
466  std::vector<Position> posConnection;
467  SUMOReal A = std::abs((*i)->getPositionInView().x() - getPositionInView().x());
468  SUMOReal B = std::abs((*i)->getPositionInView().y() - getPositionInView().y());
469  // Set positions of connection's vertex. Connection is build from Entry to E3
470  posConnection.push_back((*i)->getPositionInView());
471  if (getPositionInView().x() > (*i)->getPositionInView().x()) {
472  if (getPositionInView().y() > (*i)->getPositionInView().y()) {
473  posConnection.push_back(Position((*i)->getPositionInView().x() + A, (*i)->getPositionInView().y()));
474  } else {
475  posConnection.push_back(Position((*i)->getPositionInView().x(), (*i)->getPositionInView().y() - B));
476  }
477  } else {
478  if (getPositionInView().y() > (*i)->getPositionInView().y()) {
479  posConnection.push_back(Position((*i)->getPositionInView().x(), (*i)->getPositionInView().y() + B));
480  } else {
481  posConnection.push_back(Position((*i)->getPositionInView().x() - A, (*i)->getPositionInView().y()));
482  }
483  }
484  posConnection.push_back(getPositionInView());
485  myConnectionPositions.push_back(posConnection);
486  }
487 }
488 
489 /****************************************************************************/
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
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
Stores the information about how to visualize structures.
void addExitChild(GNEDetectorExit *exit)
add an Exit child
void sety(SUMOReal y)
set position y
Definition: Position.h:83
bool isAdditionalSelected() const
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:86
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
void writeAdditional(OutputDevice &device) const
writte additionals element into a xml file
SUMOReal myFreq
frequency of E3 detector
SUMOReal x() const
Returns the x-position.
Definition: Position.h:63
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
SUMOReal scale
information about a lane&#39;s width (temporary, used for a single view)
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.
static bool isValidFileValue(const std::string &value)
true if value is a valid file value
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:55
std::vector< SUMOReal > myShapeLengths
The lengths of the shape parts.
SUMOReal myTimeThreshold
The time-based threshold that describes how much time has to pass until a vehicle is recognized as ha...
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:814
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:93
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
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
void drawLockIcon(SUMOReal size=0.5) const
draw lock icon
std::string generateEntryID()
gererate a new ID for an Entry detector child
void setAdditionalID(const std::string &id)
set the ID of additional
const std::string getID() const
function to support debugging
void drawName(const Position &pos, const SUMOReal scale, const GUIVisualizationTextSettings &settings, const SUMOReal angle=0) const
draw name of item
void commmitAdditionalGeometryMoved(SUMOReal oldPosx, SUMOReal oldPosy, GNEUndoList *undoList)
updated geometry changes in the attributes of additional
Position myBlockIconOffset
The offSet of the block icon.
void moveAdditionalGeometry(SUMOReal offsetx, SUMOReal offsety)
change the position of the E3 geometry
void drawParentAndChildrenConnections() const
draw connections between Parent and childrens
void setx(SUMOReal x)
set position x
Definition: Position.h:78
GNEAdditional * getAdditional(SumoXMLTag type, const std::string &id) const
Returns the named additional.
Definition: GNENet.cpp:1265
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
SUMOReal mySpeedThreshold
The speed-based threshold that describes how slow a vehicle has to be to be recognized as halting...
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
RGBColor myBaseColor
base color (Default green)
void set(SUMOReal x, SUMOReal y)
set positions x and y
Definition: Position.h:93
std::vector< SUMOReal > myShapeRotations
std::string getAttribute(SumoXMLAttr key) const
GNENet * getNet() const
get the net object
Definition: GNEViewNet.cpp:989
~GNEDetectorE3()
GNEDetectorE3 6Destructor.
GNEDetectorE3(const std::string &id, GNEViewNet *viewNet, Position pos, SUMOReal freq, const std::string &filename, const SUMOReal timeThreshold, SUMOReal speedThreshold)
GNEDetectorE3 Constructor.
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.
#define SUMOReal
Definition: config.h:208
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
static void drawTexturedBox(int which, SUMOReal size)
Draws a named texture as a box with the given size.
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 ...