SUMO - Simulation of Urban MObility
GNEDetectorE3.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 //
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 #include "GNEEdge.h"
61 
62 
63 // ===========================================================================
64 // member method definitions
65 // ===========================================================================
66 
67 GNEDetectorE3::GNEDetectorE3(const std::string& id, GNEViewNet* viewNet, Position pos, double freq, const std::string& filename, const double timeThreshold, double speedThreshold) :
69  myPosition(pos),
70  myFreq(freq),
71  myFilename(filename),
72  myTimeThreshold(timeThreshold),
73  mySpeedThreshold(speedThreshold) {
74  // Update geometry;
76 }
77 
78 
80 
81 
82 void
84  // Clear shape
85  myShape.clear();
86 
87  // Set block icon position
89 
90  // Set block icon offset
91  myBlockIconOffset = Position(-0.5, -0.5);
92 
93  // Set block icon rotation, and using their rotation for draw logo
95 
96  // Set position
97  myShape.push_back(myPosition);
98 
99  // Refresh element (neccesary to avoid grabbing problems)
101 
102  // Clear all containers
103  myShapeRotations.clear();
104  myShapeLengths.clear();
105 
106 
107  // iterate over entry childs and update their gemometries
108  for (std::vector<GNEDetectorEntry*>::iterator i = myGNEDetectorEntrys.begin(); i != myGNEDetectorEntrys.end(); i++) {
109  (*i)->updateGeometryByParent();
110  }
111 
112  // iterate over entry childs and update their gemometries
113  for (std::vector<GNEDetectorExit*>::iterator i = myGNEDetectorExits.begin(); i != myGNEDetectorExits.end(); i++) {
114  (*i)->updateGeometryByParent();
115  }
116 
117  // Update connection's geometry
119 }
120 
121 
122 Position
124  return myPosition;
125 }
126 
127 
128 void
130  // change Position
131  myPosition = newPosition;
132  updateGeometry();
133 }
134 
135 
136 void
138  undoList->p_begin("position of " + toString(getTag()));
139  undoList->p_add(new GNEChange_Attribute(this, SUMO_ATTR_X, toString(myPosition.x()), true, toString(oldPos.x())));
140  undoList->p_add(new GNEChange_Attribute(this, SUMO_ATTR_Y, toString(myPosition.y()), true, toString(oldPos.y())));
141  undoList->p_end();
142  // Refresh element
144 }
145 
146 
147 void
148 GNEDetectorE3::writeAdditional(OutputDevice& device, bool volatileOptionsEnabled) const {
149  // Only save E3 if have Entry/Exits
150  if ((myGNEDetectorEntrys.size() + myGNEDetectorExits.size()) > 0) {
151  // Write parameters
152  device.openTag(getTag());
153  device.writeAttr(SUMO_ATTR_ID, getID());
155  if (!myFilename.empty()) {
157  }
160  device.writeAttr(SUMO_ATTR_X, myPosition.x());
161  device.writeAttr(SUMO_ATTR_Y, myPosition.y());
162 
163  // Write entrys
164  for (std::vector<GNEDetectorEntry*>::const_iterator i = myGNEDetectorEntrys.begin(); i != myGNEDetectorEntrys.end(); i++) {
165  device.openTag((*i)->getTag());
166  // Check if another lane ID must be changed if sidewalks.guess option is enabled
167  if (volatileOptionsEnabled && OptionsCont::getOptions().getBool("sidewalks.guess") && ((*i)->getLane()->getParentEdge().getLanes().front()->isRestricted(SVC_PEDESTRIAN) == false)) {
168  // add a new extra lane to edge
169  myViewNet->getNet()->duplicateLane((*i)->getLane()->getParentEdge().getLanes().front(), myViewNet->getUndoList());
170  // write ID (now is different because there are a new lane)
171  device.writeAttr(SUMO_ATTR_LANE, (*i)->getLane()->getID());
172  // undo set extra lane
173  myViewNet->getUndoList()->undo();
174  } else {
175  device.writeAttr(SUMO_ATTR_LANE, (*i)->getLane()->getID());
176  }
177  device.writeAttr(SUMO_ATTR_POSITION, (*i)->getAttribute(SUMO_ATTR_POSITION));
178  device.writeAttr(SUMO_ATTR_FRIENDLY_POS, (*i)->getAttribute(SUMO_ATTR_FRIENDLY_POS));
179  device.closeTag();
180  }
181 
182  // Write exits
183  for (std::vector<GNEDetectorExit*>::const_iterator i = myGNEDetectorExits.begin(); i != myGNEDetectorExits.end(); i++) {
184  device.openTag((*i)->getTag());
185  // Check if another lane ID must be changed if sidewalks.guess option is enabled
186  if (volatileOptionsEnabled && OptionsCont::getOptions().getBool("sidewalks.guess") && ((*i)->getLane()->getParentEdge().getLanes().front()->isRestricted(SVC_PEDESTRIAN) == false)) {
187  // add a new extra lane to edge
188  myViewNet->getNet()->duplicateLane((*i)->getLane()->getParentEdge().getLanes().front(), myViewNet->getUndoList());
189  // write ID (now is different because there are a new lane)
190  device.writeAttr(SUMO_ATTR_LANE, (*i)->getLane()->getID());
191  // undo set extra lane
192  myViewNet->getUndoList()->undo();
193  } else {
194  device.writeAttr(SUMO_ATTR_LANE, (*i)->getLane()->getID());
195  }
196  device.writeAttr(SUMO_ATTR_POSITION, (*i)->getAttribute(SUMO_ATTR_POSITION));
197  device.writeAttr(SUMO_ATTR_FRIENDLY_POS, (*i)->getAttribute(SUMO_ATTR_FRIENDLY_POS));
198  device.closeTag();
199  }
200 
201  // Close E3 tag
202  device.closeTag();
203  } else {
204  WRITE_WARNING(toString(getTag()) + " with ID '" + getID() + "' cannot be writed in additional file because doesn't have childs.");
205  }
206 }
207 
208 
209 std::string
211  int counter = 0;
213  counter++;
214  }
215  return (getID() + toString(SUMO_TAG_DET_ENTRY) + toString(counter));
216 }
217 
218 
219 std::string
221  int counter = 0;
223  counter++;
224  }
225  return (getID() + toString(SUMO_TAG_DET_EXIT) + toString(counter));
226 }
227 
228 
229 const std::string&
231  return myViewNet->getNet()->getMicrosimID();
232 }
233 
234 
235 void
237  // Check that entry is valid and doesn't exist previously
238  if (entry == NULL) {
239  throw InvalidArgument("Trying to add an empty " + toString(SUMO_TAG_DET_ENTRY) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
240  } else if (std::find(myGNEDetectorEntrys.begin(), myGNEDetectorEntrys.end(), entry) != myGNEDetectorEntrys.end()) {
241  throw InvalidArgument("Trying to add a duplicated " + toString(SUMO_TAG_DET_ENTRY) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
242  } else {
243  myGNEDetectorEntrys.push_back(entry);
244  }
245 }
246 
247 
248 void
250  // Check that entry is valid and exist previously
251  if (entry == NULL) {
252  throw InvalidArgument("Trying to remove an empty " + toString(SUMO_TAG_DET_ENTRY) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
253  } else if (std::find(myGNEDetectorEntrys.begin(), myGNEDetectorEntrys.end(), entry) == myGNEDetectorEntrys.end()) {
254  throw InvalidArgument("Trying to remove a non previously inserted " + toString(SUMO_TAG_DET_ENTRY) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
255  } else {
256  myGNEDetectorEntrys.erase(std::find(myGNEDetectorEntrys.begin(), myGNEDetectorEntrys.end(), entry));
257  }
258 }
259 
260 
261 void
263  // Check that exit is valid and doesn't exist previously
264  if (exit == NULL) {
265  throw InvalidArgument("Trying to add an empty " + toString(SUMO_TAG_DET_EXIT) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
266  } else if (std::find(myGNEDetectorExits.begin(), myGNEDetectorExits.end(), exit) != myGNEDetectorExits.end()) {
267  throw InvalidArgument("Trying to add a duplicated " + toString(SUMO_TAG_DET_EXIT) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
268  } else {
269  myGNEDetectorExits.push_back(exit);
270  }
271 }
272 
273 
274 void
276  // Check that exit is valid and exist previously
277  if (exit == NULL) {
278  throw InvalidArgument("Trying to remove an empty " + toString(SUMO_TAG_DET_EXIT) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
279  } else if (std::find(myGNEDetectorExits.begin(), myGNEDetectorExits.end(), exit) == myGNEDetectorExits.end()) {
280  throw InvalidArgument("Trying to remove a non previously inserted " + toString(SUMO_TAG_DET_EXIT) + " child in " + toString(SUMO_TAG_E3DETECTOR) + " with ID='" + getID() + "'");
281  } else {
282  myGNEDetectorExits.erase(std::find(myGNEDetectorExits.begin(), myGNEDetectorExits.end(), exit));
283  }
284 }
285 
286 
287 int
289  return (int)myGNEDetectorEntrys.size();
290 }
291 
292 
293 int
295  return (int)myGNEDetectorExits.size();
296 }
297 
298 
299 void
301  // Start drawing adding an gl identificator
302  glPushName(getGlID());
303 
304  // Add a draw matrix for drawing logo
305  glPushMatrix();
306  glTranslated(myShape[0].x(), myShape[0].y(), getType());
307  glColor3d(1, 1, 1);
308  glRotated(180, 0, 0, 1);
309  // Draw icon depending of detector is or isn't selected
310  if (isAdditionalSelected()) {
312  } else {
314  }
315 
316  // Pop logo matrix
317  glPopMatrix();
318 
319  // Show Lock icon depending of the Edit mode
320  drawLockIcon(0.4);
321 
322  // Draw connections
324 
325  // Pop name
326  glPopName();
327 
328  // Draw name
329  drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
330 }
331 
332 
333 std::string
335  switch (key) {
336  case SUMO_ATTR_ID:
337  return getAdditionalID();
338  case SUMO_ATTR_X:
339  return toString(myPosition.x());
340  case SUMO_ATTR_Y:
341  return toString(myPosition.y());
342  case SUMO_ATTR_FREQUENCY:
343  return toString(myFreq);
344  case SUMO_ATTR_FILE:
345  return myFilename;
347  return toString(myTimeThreshold);
349  return toString(mySpeedThreshold);
351  return toString(myBlocked);
352  default:
353  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
354  }
355 }
356 
357 
358 void
359 GNEDetectorE3::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
360  if (value == getAttribute(key)) {
361  return; //avoid needless changes, later logic relies on the fact that attributes have changed
362  }
363  switch (key) {
364  case SUMO_ATTR_ID:
365  case SUMO_ATTR_FREQUENCY:
366  case SUMO_ATTR_X:
367  case SUMO_ATTR_Y:
368  case SUMO_ATTR_FILE:
372  undoList->p_add(new GNEChange_Attribute(this, key, value));
373  updateGeometry();
374  break;
375  default:
376  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
377  }
378 }
379 
380 
381 bool
382 GNEDetectorE3::isValid(SumoXMLAttr key, const std::string& value) {
383  switch (key) {
384  case SUMO_ATTR_ID:
385  if (isValidID(value) && (myViewNet->getNet()->getAdditional(getTag(), value) == NULL)) {
386  return true;
387  } else {
388  return false;
389  }
390  case SUMO_ATTR_X:
391  return canParse<double>(value);
392  case SUMO_ATTR_Y:
393  return canParse<double>(value);
394  case SUMO_ATTR_FREQUENCY:
395  return canParse<double>(value) && (parse<double>(value) >= 0);
396  case SUMO_ATTR_FILE:
397  return isValidFilename(value);
399  return canParse<double>(value) && (parse<double>(value) >= 0);
401  return canParse<double>(value) && (parse<double>(value) >= 0);
403  return canParse<bool>(value);
404  default:
405  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
406  }
407 }
408 
409 
410 void
411 GNEDetectorE3::setAttribute(SumoXMLAttr key, const std::string& value) {
412  switch (key) {
413  case SUMO_ATTR_ID:
414  setAdditionalID(value);
415  // Change Ids of all Entry/Exits childs
416  for (std::vector<GNEDetectorEntry*>::iterator i = myGNEDetectorEntrys.begin(); i != myGNEDetectorEntrys.end(); i++) {
417  (*i)->setAdditionalID(generateEntryID());
418  }
419  for (std::vector<GNEDetectorExit*>::iterator i = myGNEDetectorExits.begin(); i != myGNEDetectorExits.end(); i++) {
420  (*i)->setAdditionalID(generateExitID());
421  }
422  break;
423  case SUMO_ATTR_X:
424  myPosition.setx(parse<double>(value));
425  updateGeometry();
426  getViewNet()->update();
427  break;
428  case SUMO_ATTR_Y:
429  myPosition.sety(parse<double>(value));
430  updateGeometry();
431  getViewNet()->update();
432  break;
433  case SUMO_ATTR_FREQUENCY:
434  myFreq = parse<double>(value);
435  break;
436  case SUMO_ATTR_FILE:
437  myFilename = value;
438  break;
440  myTimeThreshold = parse<double>(value);
441  break;
443  mySpeedThreshold = parse<double>(value);
444  break;
446  myBlocked = parse<bool>(value);
447  getViewNet()->update();
448  break;
449  default:
450  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
451  }
452 }
453 
454 
455 void
457  myConnectionPositions.clear();
458  // Iterate over Entrys
459  for (std::vector<GNEDetectorEntry*>::iterator i = myGNEDetectorEntrys.begin(); i != myGNEDetectorEntrys.end(); i++) {
460  std::vector<Position> posConnection;
461  double A = std::abs((*i)->getPositionInView().x() - getPositionInView().x());
462  double B = std::abs((*i)->getPositionInView().y() - getPositionInView().y());
463  // Set positions of connection's vertex. Connection is build from Entry to E3
464  posConnection.push_back((*i)->getPositionInView());
465  if (getPositionInView().x() > (*i)->getPositionInView().x()) {
466  if (getPositionInView().y() > (*i)->getPositionInView().y()) {
467  posConnection.push_back(Position((*i)->getPositionInView().x() + A, (*i)->getPositionInView().y()));
468  } else {
469  posConnection.push_back(Position((*i)->getPositionInView().x(), (*i)->getPositionInView().y() - B));
470  }
471  } else {
472  if (getPositionInView().y() > (*i)->getPositionInView().y()) {
473  posConnection.push_back(Position((*i)->getPositionInView().x(), (*i)->getPositionInView().y() + B));
474  } else {
475  posConnection.push_back(Position((*i)->getPositionInView().x() - A, (*i)->getPositionInView().y()));
476  }
477  }
478  posConnection.push_back(getPositionInView());
479  myConnectionPositions.push_back(posConnection);
480  }
481  // Iterate over exits
482  for (std::vector<GNEDetectorExit*>::iterator i = myGNEDetectorExits.begin(); i != myGNEDetectorExits.end(); i++) {
483  std::vector<Position> posConnection;
484  double A = std::abs((*i)->getPositionInView().x() - getPositionInView().x());
485  double B = std::abs((*i)->getPositionInView().y() - getPositionInView().y());
486  // Set positions of connection's vertex. Connection is build from Entry to E3
487  posConnection.push_back((*i)->getPositionInView());
488  if (getPositionInView().x() > (*i)->getPositionInView().x()) {
489  if (getPositionInView().y() > (*i)->getPositionInView().y()) {
490  posConnection.push_back(Position((*i)->getPositionInView().x() + A, (*i)->getPositionInView().y()));
491  } else {
492  posConnection.push_back(Position((*i)->getPositionInView().x(), (*i)->getPositionInView().y() - B));
493  }
494  } else {
495  if (getPositionInView().y() > (*i)->getPositionInView().y()) {
496  posConnection.push_back(Position((*i)->getPositionInView().x(), (*i)->getPositionInView().y() + B));
497  } else {
498  posConnection.push_back(Position((*i)->getPositionInView().x() - A, (*i)->getPositionInView().y()));
499  }
500  }
501  posConnection.push_back(getPositionInView());
502  myConnectionPositions.push_back(posConnection);
503  }
504 }
505 
506 /****************************************************************************/
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:261
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
void setBlockIconRotation()
double scale
information about a lane&#39;s width (temporary, used for a single view)
GNEDetectorE3(const std::string &id, GNEViewNet *viewNet, Position pos, double freq, const std::string &filename, const double timeThreshold, double speedThreshold)
GNEDetectorE3 Constructor.
is a pedestrian
GUIVisualizationTextSettings addName
Position myPosition
position of E3 in view
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 getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
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 additional in view.
void writeAdditional(OutputDevice &device, bool volatileOptionsEnabled) const
writte additional element into a xml file
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:85
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
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
void undo()
undo the last command group
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:65
an e3 entry point
GNEUndoList * getUndoList() const
get the undoList object
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.
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
static bool isValidID(const std::string &value)
true if value is a valid sumo ID
void moveGeometry(const Position &newPosition)
change the position of the element geometry without saving in undoList
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:998
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:92
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
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:1680
double myFreq
frequency of E3 detector
bool myBlocked
boolean to check if additional element is blocked (i.e. cannot be moved with mouse) ...
void commitGeometryMoving(const Position &oldPos, GNEUndoList *undoList)
commit geometry changes in the attributes of an element after use of moveGeometry(...)
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
std::string getAttribute(SumoXMLAttr key) const
This functions has to be implemented in allGNEAttributeCarrier.
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
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 duplicateLane(GNELane *lane, GNEUndoList *undoList)
duplicates lane
Definition: GNENet.cpp:544
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 ...