SUMO - Simulation of Urban MObility
GNECalibrator.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 "GNECalibrator.h"
48 #include "GNEEdge.h"
49 #include "GNELane.h"
50 #include "GNEViewNet.h"
51 #include "GNEUndoList.h"
52 #include "GNENet.h"
53 #include "GNEChange_Attribute.h"
54 #include "GNERouteProbe.h"
55 #include "GNECalibratorDialog.h"
56 #include "GNECalibratorFlow.h"
58 #include "GNECalibratorRoute.h"
59 
60 
61 // ===========================================================================
62 // member method definitions
63 // ===========================================================================
64 
65 GNECalibrator::GNECalibrator(const std::string& id, GNEViewNet* viewNet, GNEEdge* edge, double pos, double frequency, const std::string& output) :
67  myEdge(edge),
68  myLane(NULL),
69  myPositionOverLane(pos / edge->getLanes().at(0)->getLaneParametricLength()),
70  myFrequency(frequency),
71  myOutput(output),
72  myRouteProbe(NULL) {
73 }
74 
75 
76 GNECalibrator::GNECalibrator(const std::string& id, GNEViewNet* viewNet, GNELane* lane, double pos, double frequency, const std::string& output) :
78  myEdge(NULL),
79  myLane(lane),
80  myPositionOverLane(pos / lane->getLaneParametricLength()),
81  myFrequency(frequency),
82  myOutput(output),
83  myRouteProbe(NULL) {
84 }
85 
86 
88 
89 
90 void
92  // Write parameters
94  device.writeAttr(SUMO_ATTR_ID, getID());
95  if (myLane) {
98  } else if (myEdge) {
100  device.writeAttr(SUMO_ATTR_POSITION, myPositionOverLane * myEdge->getLanes().at(0)->getLaneParametricLength());
101  } else {
102  throw ProcessError("Both myEdge and myLane aren't defined");
103  }
106  // write all routes of this calibrator
107  for (auto i : myCalibratorRoutes) {
108  i->writeRoute(device);
109  }
110  // write all vehicle types of this calibrator
111  for (auto i : myCalibratorVehicleTypes) {
112  i->writeVehicleType(device);
113  }
114  // Write all flows of this calibrator
115  for (auto i : myCalibratorFlows) {
116  i->writeFlow(device);
117  }
118  // Close tag
119  device.closeTag();
120 }
121 
122 
123 void
125  // This additional cannot be moved
126 }
127 
128 
129 void
131  // This additional cannot be moved
132 }
133 
134 
135 void
137  // Clear all containers
138  myShapeRotations.clear();
139  myShapeLengths.clear();
140  // clear Shape
141  myShape.clear();
142  // get shape depending of we have a edge or a lane
143  if (myLane) {
144  // Get shape of lane parent
146  // Save rotation (angle) of the vector constructed by points f and s
148  } else if (myEdge) {
149  for (auto i : myEdge->getLanes()) {
150  // Get shape of lane parent
151  myShape.push_back(i->getShape().positionAtOffset(myPositionOverLane * i->getShape().length()));
152  // Save rotation (angle) of the vector constructed by points f and s
153  myShapeRotations.push_back(myEdge->getLanes().at(0)->getShape().rotationDegreeAtOffset(myPositionOverLane * i->getShape().length()) * -1);
154  }
155  } else {
156  throw ProcessError("Both myEdge and myLane aren't defined");
157  }
158  // Refresh element (neccesary to avoid grabbing problems)
159  myViewNet->getNet()->refreshElement(this);
160 }
161 
162 
163 Position
165  // get position depending of we have a edge or a lane
166  if (myLane) {
168  } else if (myEdge) {
169  return myEdge->getLanes().at(0)->getShape().positionAtOffset(myPositionOverLane * myEdge->getLanes().at(0)->getShape().length());
170  } else {
171  throw ProcessError("Both myEdge and myLane aren't defined");
172  }
173 }
174 
175 
176 const std::string&
178  // get parent name depending of we have a edge or a lane
179  if (myLane) {
180  return myLane->getMicrosimID();
181  } else if (myEdge) {
182  return myEdge->getLanes().at(0)->getMicrosimID();
183  } else {
184  throw ProcessError("Both myEdge and myLane aren't defined");
185  }
186 }
187 
188 
189 void
191  // get values
192  glPushName(getGlID());
193  glLineWidth(1.0);
194  const double exaggeration = s.addSize.getExaggeration(s);
195 
196  // iterate over every Calibrator symbol
197  for (int i = 0; i < (int)myShape.size(); ++i) {
198  const Position& pos = myShape[i];
199  double rot = myShapeRotations[i];
200  glPushMatrix();
201  glTranslated(pos.x(), pos.y(), getType());
202  glRotated(rot, 0, 0, 1);
203  glTranslated(0, 0, getType());
204  glScaled(exaggeration, exaggeration, 1);
205  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
206 
207  if (isAdditionalSelected()) {
209  } else {
210  GLHelper::setColor(RGBColor(255, 204, 0));
211  }
212  // base
213  glBegin(GL_TRIANGLES);
214  glVertex2d(0 - 1.4, 0);
215  glVertex2d(0 - 1.4, 6);
216  glVertex2d(0 + 1.4, 6);
217  glVertex2d(0 + 1.4, 0);
218  glVertex2d(0 - 1.4, 0);
219  glVertex2d(0 + 1.4, 6);
220  glEnd();
221 
222  // draw text
223  if (s.scale * exaggeration >= 1.) {
224  // set color depending of selection status
226  // draw "C"
227  GLHelper::drawText("C", Position(0, 1.5), 0.1, 3, textColor, 180);
228  // draw "edge" or "lane "
229  if (myLane) {
230  GLHelper::drawText("lane", Position(0, 3), .1, 1, textColor, 180);
231  } else if (myEdge) {
232  GLHelper::drawText("edge", Position(0, 3), .1, 1, textColor, 180);
233  } else {
234  throw ProcessError("Both myEdge and myLane aren't defined");
235  }
236  }
237  glPopMatrix();
238  }
239  drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
240  glPopName();
241 }
242 
243 
244 void
246  // Open calibrator dialog
247  GNECalibratorDialog calibratorDialog(this);
248 }
249 
250 
251 
252 
253 
254 void
256  myCalibratorRoutes.push_back(route);
257 }
258 
259 
260 void
262  myCalibratorRoutes.erase(std::find(myCalibratorRoutes.begin(), myCalibratorRoutes.end(), route));
263 }
264 
265 
266 const std::vector<GNECalibratorRoute*>&
268  return myCalibratorRoutes;
269 }
270 
271 
272 void
274  assert(flow);
275  myCalibratorFlows.push_back(flow);
276 }
277 
278 
279 void
281  myCalibratorFlows.erase(std::find(myCalibratorFlows.begin(), myCalibratorFlows.end(), flow));
282 }
283 
284 
285 const std::vector<GNECalibratorFlow*>&
287  return myCalibratorFlows;
288 }
289 
290 
291 void
293  myCalibratorVehicleTypes.push_back(vehicleType);
294 }
295 
296 
297 void
299  myCalibratorVehicleTypes.erase(std::find(myCalibratorVehicleTypes.begin(), myCalibratorVehicleTypes.end(), vehicleType));
300 }
301 
302 
303 const std::vector<GNECalibratorVehicleType*>&
306 }
307 
308 
309 std::string
311  switch (key) {
312  case SUMO_ATTR_ID:
313  return getAdditionalID();
314  case SUMO_ATTR_EDGE:
315  return myEdge->getID();
316  case SUMO_ATTR_LANE:
317  return myLane->getID();
318  case SUMO_ATTR_POSITION:
319  if (myEdge) {
320  return toString(myPositionOverLane * myEdge->getLanes().at(0)->getLaneParametricLength());
321  } else if (myLane) {
323  } else {
324  throw ProcessError("Both myEdge and myLane aren't defined");
325  }
326  case SUMO_ATTR_FREQUENCY:
327  return toString(myFrequency);
328  case SUMO_ATTR_OUTPUT:
329  return myOutput;
331  if (myRouteProbe) {
332  return myRouteProbe->getID();
333  } else {
334  return "";
335  }
336  default:
337  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
338  }
339 }
340 
341 
342 void
343 GNECalibrator::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
344  if (value == getAttribute(key)) {
345  return; //avoid needless changes, later logic relies on the fact that attributes have changed
346  }
347  switch (key) {
348  case SUMO_ATTR_ID:
349  case SUMO_ATTR_EDGE:
350  case SUMO_ATTR_LANE:
351  case SUMO_ATTR_POSITION:
352  case SUMO_ATTR_FREQUENCY:
353  case SUMO_ATTR_OUTPUT:
355  undoList->p_add(new GNEChange_Attribute(this, key, value));
356  break;
357  default:
358  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
359  }
360 
361 }
362 
363 
364 bool
365 GNECalibrator::isValid(SumoXMLAttr key, const std::string& value) {
366  switch (key) {
367  case SUMO_ATTR_ID:
368  return isValidAdditionalID(value);
369  case SUMO_ATTR_EDGE:
370  if (myViewNet->getNet()->retrieveEdge(value, false) != NULL) {
371  return true;
372  } else {
373  return false;
374  }
375  case SUMO_ATTR_LANE:
376  if (myViewNet->getNet()->retrieveLane(value, false) != NULL) {
377  return true;
378  } else {
379  return false;
380  }
381  case SUMO_ATTR_POSITION:
382  if (canParse<double>(value)) {
383  // obtain relative new start position
384  double newPosition;
385  if (myEdge) {
386  newPosition = parse<double>(value) / myEdge->getLanes().at(0)->getLaneParametricLength();
387  } else if (myLane) {
388  newPosition = parse<double>(value) / myLane->getLaneParametricLength();
389  } else {
390  throw ProcessError("Both myEdge and myLane aren't defined");
391  }
392  if ((newPosition < 0) || (newPosition > 1)) {
393  return false;
394  } else {
395  return true;
396  }
397  } else {
398  return false;
399  }
400  case SUMO_ATTR_FREQUENCY:
401  return (canParse<double>(value) && parse<double>(value) >= 0);
402  case SUMO_ATTR_OUTPUT:
403  return isValidFilename(value);
405  if (isValidID(value) && (myViewNet->getNet()->getAdditional(SUMO_TAG_ROUTEPROBE, value) != NULL)) {
406  return true;
407  } else {
408  return false;
409  }
410  default:
411  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
412  }
413 }
414 
415 // ===========================================================================
416 // private
417 // ===========================================================================
418 
419 void
420 GNECalibrator::setAttribute(SumoXMLAttr key, const std::string& value) {
421  switch (key) {
422  case SUMO_ATTR_ID:
423  changeAdditionalID(value);
424  break;
425  case SUMO_ATTR_EDGE:
426  myEdge = changeEdge(myEdge, value);
427  break;
428  case SUMO_ATTR_LANE:
429  myLane = changeLane(myLane, value);
430  break;
431  case SUMO_ATTR_POSITION:
432  if (myEdge) {
433  myPositionOverLane = parse<double>(value) / myEdge->getLanes().at(0)->getLaneParametricLength();
434  } else if (myLane) {
435  myPositionOverLane = parse<double>(value) / myLane->getLaneParametricLength();
436  } else {
437  throw ProcessError("Both myEdge and myLane aren't defined");
438  }
439  break;
440  case SUMO_ATTR_FREQUENCY:
441  myFrequency = parse<double>(value);
442  break;
443  case SUMO_ATTR_OUTPUT:
444  myOutput = value;
445  break;
448  break;
449  default:
450  throw InvalidArgument(toString(getTag()) + " doesn't have an attribute of type '" + toString(key) + "'");
451  }
452  // After setting attribute always update Geometry
453  updateGeometry();
454 }
455 
456 /****************************************************************************/
void removeCalibratorFlow(GNECalibratorFlow *flow)
remove calibrator flow
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:260
void writeAdditional(OutputDevice &device) const
writte additional element into a xml file
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
a routeprobe detector
GNEEdge * retrieveEdge(const std::string &id, bool failHard=true)
get edge by id
Definition: GNENet.cpp:902
double scale
information about a lane&#39;s width (temporary, used for a single view)
GUIVisualizationTextSettings addName
void refreshElement(GUIGlObject *o)
refreshes boundary information for o and update
Definition: GNENet.cpp:1082
std::vector< GNECalibratorRoute * > myCalibratorRoutes
calibrator route values
bool isValidAdditionalID(const std::string &newID) const
check if a new additional ID is valid
A calibrator placed over edge.
double x() const
Returns the x-position.
Definition: Position.h:62
Stores the information about how to visualize structures.
bool isAdditionalSelected() const
std::vector< GNECalibratorVehicleType * > myCalibratorVehicleTypes
calibrator vehicleType values
~GNECalibrator()
Destructor.
const std::vector< GNECalibratorVehicleType * > & getCalibratorVehicleTypes() const
get calibrator vehicleTypes
Representation of a RouteProbe in netedit.
Definition: GNERouteProbe.h:42
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
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
GNERouteProbe * myRouteProbe
pointer to current RouteProbe
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:53
void removeCalibratorVehicleType(GNECalibratorVehicleType *vehicleType)
remove calibrator vehicleType
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
std::vector< GNECalibratorFlow * > myCalibratorFlows
calibrator flow values
static const RGBColor BLACK
Definition: RGBColor.h:186
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
method for setting the attribute and letting the object perform additional changes ...
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.
void changeAdditionalID(const std::string &newID)
change ID of additional
void openAdditionalDialog()
open Calibrator Dialog
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
GUIVisualizationSizeSettings addSize
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
GNECalibrator(const std::string &id, GNEViewNet *viewNet, GNEEdge *edge, double pos, double frequency, const std::string &output)
Constructor using edge.
static const RGBColor selectedAdditionalColor
color of selected additionals
Definition: GNENet.h:116
double getExaggeration(const GUIVisualizationSettings &s, double factor=20) const
return the drawing size including exaggeration and constantSize values
std::string myOutput
output of calibrator
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
const std::string & getAdditionalID() const
returns Additional ID
bool isValid(SumoXMLAttr key, const std::string &value)
method for checking if the key and their conrrespond attribute are valids
std::string getAttribute(SumoXMLAttr key) const
This functions has to be implemented in all GNEAttributeCarriers.
PositionVector myShape
The shape of the additional element.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:45
double rotationDegreeAtOffset(double pos) const
Returns the rotation at the given length.
friend class GNEChange_Attribute
declare friend class
double y() const
Returns the y-position.
Definition: Position.h:67
A calibrator placed over lane (used in netedit)
void addCalibratorRoute(GNECalibratorRoute *route)
add calibrator route
void removeCalibratorRoute(GNECalibratorRoute *route)
add calibrator route
double length() const
Returns the length.
std::vector< double > myShapeLengths
The lengths of the shape parts.
const std::string getID() const
function to support debugging
GNELane * myLane
The lane in which CalibratorLane are placed.
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:56
void addCalibratorVehicleType(GNECalibratorVehicleType *vehicleType)
add calibrator vehicleType
Dialog for edit calibrators.
double myPositionOverLane
position over Lane
void addCalibratorFlow(GNECalibratorFlow *flow)
add calibrator flow
GNEAdditional * getAdditional(SumoXMLTag type, const std::string &id) const
Returns the named additional.
Definition: GNENet.cpp:1667
const PositionVector & getShape() const
returns the shape of the lane
Definition: GNELane.cpp:599
const std::vector< GNELane * > & getLanes()
returns a reference to the lane vector
Definition: GNEEdge.cpp:653
GNEEdge * changeEdge(GNEEdge *oldEdge, const std::string &newEdgeID)
change edge of additional
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:59
void moveGeometry(const Position &oldPos, const Position &offset)
change the position of the element geometry without saving in undoList
GNEEdge * myEdge
The edge in which Calibrators are placed.
GNENet * getNet() const
get the net object
void commitGeometryMoving(const Position &oldPos, GNEUndoList *undoList)
commit geometry changes in the attributes of an element after use of moveGeometry(...)
SumoXMLTag getTag() const
get XML Tag assigned to this object
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:70
bool closeTag()
Closes the most recently opened tag.
double myFrequency
Frequency of calibrator.
void updateGeometry()
update pre-computed geometry information
static const RGBColor selectionColor
Definition: GNENet.h:107
const std::vector< GNECalibratorFlow * > & getCalibratorFlows() const
get calibrator flows
const std::string & getParentName() const
Returns the name of the parent object.
double getLaneParametricLength() const
returns the parameteric length of the lane
Definition: GNELane.cpp:701
GNELane * retrieveLane(const std::string &id, bool failHard=true, bool checkVolatileChange=false)
get lane by id
Definition: GNENet.cpp:1000
const std::vector< GNECalibratorRoute * > & getCalibratorRoutes() const
get calibrator routes
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
GNELane * changeLane(GNELane *oldLane, const std::string &newLaneID)
change lane of additional
Position getPositionInView() const
Returns position of additional in view.