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
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:260
double rotationDegreeAtOffset(double pos) const
Returns the rotation at the given length.
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
const std::string & getAdditionalID() const
returns Additional ID
std::vector< GNECalibratorRoute * > myCalibratorRoutes
calibrator route values
A calibrator placed over edge.
GNEAdditional * getAdditional(SumoXMLTag type, const std::string &id) const
Returns the named additional.
Definition: GNENet.cpp:1667
Stores the information about how to visualize structures.
double y() const
Returns the y-position.
Definition: Position.h:67
const std::vector< GNECalibratorVehicleType * > & getCalibratorVehicleTypes() const
get calibrator vehicleTypes
std::vector< GNECalibratorVehicleType * > myCalibratorVehicleTypes
calibrator vehicleType values
std::string getAttribute(SumoXMLAttr key) const
This functions has to be implemented in all GNEAttributeCarriers.
~GNECalibrator()
Destructor.
double x() const
Returns the x-position.
Definition: Position.h:62
Position getPositionInView() const
Returns position of additional in view.
Representation of a RouteProbe in netedit.
Definition: GNERouteProbe.h:42
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
void changeAdditionalID(const std::string &newID)
change ID of additional
void openAdditionalDialog()
open Calibrator Dialog
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.
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
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 getLaneParametricLength() const
returns the parameteric length of the lane
Definition: GNELane.cpp:701
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
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
bool isValid(SumoXMLAttr key, const std::string &value)
method for checking if the key and their conrrespond attribute are valids
PositionVector myShape
The shape of the additional element.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:45
friend class GNEChange_Attribute
declare friend class
A calibrator placed over lane (used in netedit)
void addCalibratorRoute(GNECalibratorRoute *route)
add calibrator route
void removeCalibratorRoute(GNECalibratorRoute *route)
add calibrator route
std::vector< double > myShapeLengths
The lengths of the shape parts.
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
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
const std::vector< GNECalibratorRoute * > & getCalibratorRoutes() const
get calibrator routes
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
const std::string & getParentName() const
Returns the name of the parent object.
Dialog for edit calibrators.
double myPositionOverLane
position over Lane
void addCalibratorFlow(GNECalibratorFlow *flow)
add calibrator flow
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
double length() const
Returns the length.
GNEEdge * changeEdge(GNEEdge *oldEdge, const std::string &newEdgeID)
change edge of additional
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
GUIGlID getGlID() const
Returns the numerical id of the object.
double getExaggeration(const GUIVisualizationSettings &s, double factor=20) const
return the drawing size including exaggeration and constantSize values
void commitGeometryMoving(const Position &oldPos, GNEUndoList *undoList)
commit geometry changes in the attributes of an element after use of moveGeometry(...)
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
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
const std::vector< GNECalibratorFlow * > & getCalibratorFlows() const
get calibrator flows
bool isValidAdditionalID(const std::string &newID) const
check if a new additional ID is valid
bool isAdditionalSelected() const
static const RGBColor selectionColor
Definition: GNENet.h:107
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
GNELane * retrieveLane(const std::string &id, bool failHard=true, bool checkVolatileChange=false)
get lane by id
Definition: GNENet.cpp:1000
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
GNELane * changeLane(GNELane *oldLane, const std::string &newLaneID)
change lane of additional
SumoXMLTag getTag() const
get XML Tag assigned to this object