Eclipse SUMO - Simulation of Urban MObility
GNEStoppingPlace.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-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
15 // A abstract class to define common parameters of lane area in which vehicles can halt (GNE version)
16 /****************************************************************************/
17 
18 // ===========================================================================
19 // included modules
20 // ===========================================================================
21 
22 #include <netedit/GNENet.h>
23 #include <netedit/GNEUndoList.h>
24 #include <netedit/GNEViewNet.h>
30 
31 #include "GNEStoppingPlace.h"
32 
33 // ===========================================================================
34 // static members
35 // ===========================================================================
36 
37 const double GNEStoppingPlace::myCircleWidth = 1.1;
38 const double GNEStoppingPlace::myCircleWidthSquared = 1.21;
39 const double GNEStoppingPlace::myCircleInWidth = 0.9;
40 const double GNEStoppingPlace::myCircleInText = 1.6;
41 
42 // ===========================================================================
43 // member method definitions
44 // ===========================================================================
45 
46 GNEStoppingPlace::GNEStoppingPlace(const std::string& id, GNEViewNet* viewNet, GUIGlObjectType type, SumoXMLTag tag, GNELane* lane, const std::string& startPos, const std::string& endPos,
47  const std::string& name, bool friendlyPosition, bool blockMovement) :
48  GNEAdditional(id, viewNet, type, tag, name, blockMovement, {}, {lane}, {}, {}, {}, {}, {}, {}, {}, {}),
49  myStartPosition(startPos),
50  myEndPosition(endPos),
51 myFriendlyPosition(friendlyPosition) {
52 }
53 
54 
56 
57 
58 bool
60  // with friendly position enabled position are "always fixed"
61  if (myFriendlyPosition) {
62  return true;
63  } else {
64  // obtain lane length
65  double laneLenght = getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength() * getLaneParents().front()->getLengthGeometryFactor();
66  // calculate start and end positions
67  double startPos = canParse<double>(myStartPosition) ? parse<double>(myStartPosition) : 0;
68  double endPos = canParse<double>(myEndPosition) ? parse<double>(myEndPosition) : laneLenght;
69  // check if position has to be fixed
70  if (startPos < 0) {
71  startPos += laneLenght;
72  }
73  if (endPos < 0) {
74  endPos += laneLenght;
75  }
76  // check values
77  if (myStartPosition.empty() && myEndPosition.empty()) {
78  return true;
79  } else if (myStartPosition.empty()) {
80  return (endPos <= getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength());
81  } else if (myEndPosition.empty()) {
82  return (startPos >= 0);
83  } else {
84  return ((startPos >= 0) && (endPos <= getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength()) && ((endPos - startPos) >= POSITION_EPS));
85  }
86  }
87 }
88 
89 
90 std::string
92  // calculate start and end positions
93  double startPos = canParse<double>(myStartPosition) ? parse<double>(myStartPosition) : 0;
94  double endPos = canParse<double>(myEndPosition) ? parse<double>(myEndPosition) : getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength();
95  // obtain lane lenght
96  double laneLenght = getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength();
97  // check if position has to be fixed
98  if (startPos < 0) {
99  startPos += laneLenght;
100  }
101  if (endPos < 0) {
102  endPos += laneLenght;
103  }
104  // declare variables
105  std::string errorStart, separator, errorEnd;
106  // check positions over lane
107  if (startPos < 0) {
108  errorStart = (toString(SUMO_ATTR_STARTPOS) + " < 0");
109  } else if (startPos > getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength()) {
110  errorStart = (toString(SUMO_ATTR_STARTPOS) + " > lanes's length");
111  }
112  if (endPos < 0) {
113  errorEnd = (toString(SUMO_ATTR_ENDPOS) + " < 0");
114  } else if (endPos > getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength()) {
115  errorEnd = (toString(SUMO_ATTR_ENDPOS) + " > lanes's length");
116  }
117  // check separator
118  if ((errorStart.size() > 0) && (errorEnd.size() > 0)) {
119  separator = " and ";
120  }
121  return errorStart + separator + errorEnd;
122 }
123 
124 
125 void
127  // declare new start and end position
128  std::string newStartPos = myStartPosition;
129  std::string newEndPos = myEndPosition;
130  // fix start and end positions using fixStoppinPlacePosition
131  fixStoppinPlacePosition(newStartPos, newEndPos, getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength(), true);
132  // set new start and end positions
135 }
136 
137 
138 bool
139 GNEStoppingPlace::checkStoppinPlacePosition(const std::string& startPosStr, const std::string& endPosStr, const double laneLength, const bool friendlyPos) {
140  // obtain start and end position in double format, depending if it can be parsed to double
141  double startPos = GNEAttributeCarrier::canParse<double>(startPosStr) ? GNEAttributeCarrier::parse<double>(startPosStr) : 0;
142  double endPos = GNEAttributeCarrier::canParse<double>(endPosStr) ? GNEAttributeCarrier::parse<double>(endPosStr) : laneLength;
143  // return check stop pos (note: this is the same function of SUMORouteHandler::checkStopPos)
144  if (POSITION_EPS > laneLength) {
145  return false;
146  }
147  if (startPos < 0) {
148  startPos += laneLength;
149  }
150  if (endPos < 0) {
151  endPos += laneLength;
152  }
153  if (endPos < POSITION_EPS || endPos > laneLength) {
154  if (!friendlyPos) {
155  return false;
156  }
157  }
158  if (startPos < 0 || startPos > endPos - POSITION_EPS) {
159  if (!friendlyPos) {
160  return false;
161  }
162  }
163  return true;
164 }
165 
166 
167 bool
168 GNEStoppingPlace::fixStoppinPlacePosition(std::string& startPosStr, std::string& endPosStr, const double laneLength, const bool friendlyPos) {
169  // obtain start and end position in double format
170  double startPos = fabs(canParse<double>(startPosStr) ? parse<double>(startPosStr) : 0);
171  double endPos = fabs(parse<double>(endPosStr) ? parse<double>(endPosStr) : laneLength);
172  double minLength = POSITION_EPS + 0.01;
173  // return check stop pos (note: this is the same function of SUMORouteHandler::checkStopPos)
174  if (minLength > laneLength) {
175  return false;
176  }
177  if (startPos < 0) {
178  startPos += laneLength;
179  }
180  if (endPos < 0) {
181  endPos += laneLength;
182  }
183  if (endPos < minLength || endPos > laneLength) {
184  if (!friendlyPos) {
185  return false;
186  }
187  if (endPos < minLength) {
188  endPos = minLength;
189  }
190  if (endPos > laneLength) {
191  endPos = laneLength;
192  }
193  }
194  if (startPos < 0 || startPos > endPos - minLength) {
195  if (!friendlyPos) {
196  return false;
197  }
198  if (startPos < 0) {
199  startPos = 0;
200  }
201  if (startPos > endPos - minLength) {
202  startPos = endPos - minLength;
203  }
204  }
205  startPosStr = toString(startPos);
206  endPosStr = toString(endPos);
207  return true;
208 }
209 
210 
211 Position
213  // calculate start and end positions as absolute values
214  double startPos = fabs(canParse<double>(myStartPosition) ? parse<double>(myStartPosition) : 0);
215  double endPos = fabs(canParse<double>(myEndPosition) ? parse<double>(myEndPosition) : getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength());
216  // obtain position in view depending if both positions are defined
217  if (myStartPosition.empty() && myEndPosition.empty()) {
218  return getLaneParents().front()->getGeometry().shape.positionAtOffset(getLaneParents().front()->getGeometry().shape.length() / 2);
219  } else if (myStartPosition.empty()) {
220  return getLaneParents().front()->getGeometry().shape.positionAtOffset(endPos);
221  } else if (myEndPosition.empty()) {
222  return getLaneParents().front()->getGeometry().shape.positionAtOffset(startPos);
223  } else {
224  return getLaneParents().front()->getGeometry().shape.positionAtOffset((startPos + endPos) / 2.0);
225  }
226 }
227 
228 
229 void
231  // only move if at leats start or end positions is defined
232  if (!myStartPosition.empty() || !myEndPosition.empty()) {
233  // Calculate new position using old position
234  Position newPosition = myMove.originalViewPosition;
235  newPosition.add(offset);
236  // filtern position using snap to active grid
237  newPosition = myViewNet->snapToActiveGrid(newPosition);
238  double offsetLane = getLaneParents().front()->getGeometry().shape.nearest_offset_to_point2D(newPosition, false) - getLaneParents().front()->getGeometry().shape.nearest_offset_to_point2D(myMove.originalViewPosition, false);
239  // check if both position has to be moved
240  if (!myStartPosition.empty() && !myEndPosition.empty()) {
241  // calculate stoppingPlace lenght and lane lenght (After apply geometry factor)
242  double stoppingPlaceLenght = fabs(parse<double>(myMove.secondOriginalPosition) - parse<double>(myMove.firstOriginalLanePosition));
243  double laneLengt = getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength() * getLaneParents().front()->getLengthGeometryFactor();
244  // avoid changing stopping place's lenght
245  if ((parse<double>(myMove.firstOriginalLanePosition) + offsetLane) < 0) {
246  myStartPosition = "0";
247  myEndPosition = toString(stoppingPlaceLenght);
248  } else if ((parse<double>(myMove.secondOriginalPosition) + offsetLane) > laneLengt) {
249  myStartPosition = toString(laneLengt - stoppingPlaceLenght);
250  myEndPosition = toString(laneLengt);
251  } else {
252  myStartPosition = toString(parse<double>(myMove.firstOriginalLanePosition) + offsetLane);
253  myEndPosition = toString(parse<double>(myMove.secondOriginalPosition) + offsetLane);
254  }
255  } else {
256  // check if start position must be moved
257  if (!myStartPosition.empty()) {
258  myStartPosition = toString(parse<double>(myMove.firstOriginalLanePosition) + offsetLane);
259  }
260  // check if start position must be moved
261  if (!myEndPosition.empty()) {
262  myEndPosition = toString(parse<double>(myMove.secondOriginalPosition) + offsetLane);
263  }
264  }
265  // update demand element children
266  for (const auto& i : getDemandElementChildren()) {
267  // if child is a person plan, update geometry of their person parent
268  if (i->getTagProperty().isPersonPlan()) {
269  i->getDemandElementParents().front()->markSegmentGeometryDeprecated();
270  i->getDemandElementParents().front()->updateGeometry();
271  } else {
272  i->markSegmentGeometryDeprecated();
273  i->updateGeometry();
274  }
275  }
276  // Update geometry
277  updateGeometry();
278  }
279 }
280 
281 
282 void
284  // only commit geometry moving if at leats start or end positions is defined
285  if (!myStartPosition.empty() || !myEndPosition.empty()) {
286  undoList->p_begin("position of " + getTagStr());
287  if (!myStartPosition.empty()) {
289  }
290  if (!myEndPosition.empty()) {
292  }
293  undoList->p_end();
294  // update demand element children
295  for (const auto& i : getDemandElementChildren()) {
296  // if child is a person plan, update geometry of their person parent
297  if (i->getTagProperty().isPersonPlan()) {
298  i->getDemandElementParents().front()->markSegmentGeometryDeprecated();
299  i->getDemandElementParents().front()->updateGeometry();
300  } else {
301  i->markSegmentGeometryDeprecated();
302  i->updateGeometry();
303  }
304  }
305  }
306 }
307 
308 
309 double
311  if (canParse<double>(myStartPosition)) {
312  return parse<double>(myStartPosition);
313  } else {
314  return 0;
315  }
316 }
317 
318 
319 double
321  if (canParse<double>(myEndPosition)) {
322  return parse<double>(myEndPosition);
323  } else {
324  return getLaneParents().front()->getLaneShapeLength();
325  }
326 }
327 
328 
329 std::string
331  return getLaneParents().front()->getMicrosimID();
332 }
333 
334 
335 void
337  // Clear all containers
339 
340  // Get value of option "lefthand"
341  double offsetSign = OptionsCont::getOptions().getBool("lefthand") ? -1 : 1;
342 
343  // Get shape of lane parent
344  myGeometry.shape = getLaneParents().front()->getGeometry().shape;
345 
346  // Move shape to side
347  myGeometry.shape.move2side(movingToSide * offsetSign);
348 
349  // Cut shape using as delimitators fixed start position and fixed end position
351 
352  // Get calculate lenghts and rotations
354 }
355 
356 
357 double
359  if (myStartPosition.empty()) {
360  return 0;
361  } else {
362  double fixedPos = parse<double>(myStartPosition);
363  const double len = getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength();
364  if (fixedPos < 0) {
365  fixedPos += len;
366  }
367  return fixedPos * getLaneParents().front()->getLengthGeometryFactor();
368  }
369 }
370 
371 
372 double
374  if (myEndPosition.empty()) {
375  return getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength();
376  } else {
377  double fixedPos = parse<double>(myEndPosition);
378  const double len = getLaneParents().front()->getParentEdge().getNBEdge()->getFinalLength();
379  if (fixedPos < 0) {
380  fixedPos += len;
381  }
382  return fixedPos * getLaneParents().front()->getLengthGeometryFactor();
383  }
384 }
385 
386 
387 std::string
389  return getTagStr() + ": " + getID();
390 }
391 
392 
393 std::string
395  return getTagStr();
396 }
397 
398 /****************************************************************************/
GNEStoppingPlace::setAttribute
virtual void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)=0
method for setting the attribute and letting the object perform additional changes
GNEAdditional
An Element which don't belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:47
GNEAttributeCarrier::getID
const std::string getID() const
function to support debugging
Definition: GNEAttributeCarrier.cpp:1187
GNEAdditional::AdditionalGeometry::shape
PositionVector shape
The shape of the additional element.
Definition: GNEAdditional.h:68
GNEUndoList::p_end
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
Definition: GNEUndoList.cpp:80
OptionsCont.h
PositionVector::getSubpart
PositionVector getSubpart(double beginOffset, double endOffset) const
get subpart of a position vector
Definition: PositionVector.cpp:698
OptionsCont::getBool
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
Definition: OptionsCont.cpp:223
OptionsCont::getOptions
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
GNEViewNet
Definition: GNEViewNet.h:43
SUMO_ATTR_ENDPOS
Definition: SUMOXMLDefinitions.h:795
GNEAdditional::AdditionalMove::secondOriginalPosition
std::string secondOriginalPosition
value for saving second original position over lane before moving
Definition: GNEAdditional.h:335
SumoXMLTag
SumoXMLTag
Numbers representing SUMO-XML - element names.
Definition: SUMOXMLDefinitions.h:42
GNEStoppingPlace::myCircleInWidth
static const double myCircleInWidth
inner circle width resolution for all stopping places
Definition: GNEStoppingPlace.h:176
GUISUMOAbstractView::snapToActiveGrid
Position snapToActiveGrid(const Position &pos, bool snapXY=true) const
Returns a position that is mapped to the closest grid point if the grid is active.
Definition: GUISUMOAbstractView.cpp:194
GNEAdditional::myMove
AdditionalMove myMove
variable AdditionalMove
Definition: GNEAdditional.h:371
GNEAdditional::myViewNet
GNEViewNet * myViewNet
The GNEViewNet this additional element belongs.
Definition: GNEAdditional.h:365
GUIGlObjectType
GUIGlObjectType
Definition: GUIGlObjectTypes.h:40
GNEAttributeCarrier::GNEChange_Attribute
friend class GNEChange_Attribute
declare friend class
Definition: GNEAttributeCarrier.h:57
GNEHierarchicalElementParents::getLaneParents
const std::vector< GNELane * > & getLaneParents() const
get lanes of VSS
Definition: GNEHierarchicalElementParents.cpp:182
GNEUndoList::p_add
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
Definition: GNEUndoList.cpp:132
GNEViewNet::getNet
GNENet * getNet() const
get the net object
Definition: GNEViewNet.cpp:927
GNEStoppingPlace::myFriendlyPosition
bool myFriendlyPosition
Flag for friendly position.
Definition: GNEStoppingPlace.h:164
GNEStoppingPlace::GNEStoppingPlace
GNEStoppingPlace(const std::string &id, GNEViewNet *viewNet, GUIGlObjectType type, SumoXMLTag tag, GNELane *lane, const std::string &startPos, const std::string &endPos, const std::string &name, bool friendlyPosition, bool blockMovement)
Constructor.
Definition: GNEStoppingPlace.cpp:46
GNEStoppingPlace::getPositionInView
Position getPositionInView() const
Returns position of additional in view.
Definition: GNEStoppingPlace.cpp:212
GNEStoppingPlace::getStartPosition
double getStartPosition() const
get start Position
Definition: GNEStoppingPlace.cpp:310
SUMO_ATTR_STARTPOS
Definition: SUMOXMLDefinitions.h:794
GNEStoppingPlace::getHierarchyName
std::string getHierarchyName() const
get Hierarchy Name (Used in AC Hierarchy)
Definition: GNEStoppingPlace.cpp:394
GNEStoppingPlace::updateGeometry
virtual void updateGeometry()=0
update pre-computed geometry information
GNEStoppingPlace::myCircleWidthSquared
static const double myCircleWidthSquared
squared circle width resolution for all stopping places
Definition: GNEStoppingPlace.h:173
GNEDemandElement.h
GNEStoppingPlace::setStoppingPlaceGeometry
void setStoppingPlaceGeometry(double movingToSide)
set geometry common to all stopping places
Definition: GNEStoppingPlace.cpp:336
GNEViewNet.h
GNEAdditional::AdditionalGeometry::clearGeometry
void clearGeometry()
reset geometry
Definition: GNEAdditional.cpp:53
Position
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
GNEEdge.h
GNEViewNet::getUndoList
GNEUndoList * getUndoList() const
get the undoList object
Definition: GNEViewNet.cpp:933
GNEStoppingPlace::getEndPosition
double getEndPosition() const
get end Position
Definition: GNEStoppingPlace.cpp:320
GNEStoppingPlace::myStartPosition
std::string myStartPosition
The relative start position this stopping place is located at (optional, if empty takes 0)
Definition: GNEStoppingPlace.h:158
GNEStoppingPlace::getPopUpID
std::string getPopUpID() const
get PopPup ID (Used in AC Hierarchy)
Definition: GNEStoppingPlace.cpp:388
GNEStoppingPlace::getEndGeometryPositionOverLane
double getEndGeometryPositionOverLane() const
get end position over lane that is applicable to the shape
Definition: GNEStoppingPlace.cpp:373
GNELane.h
GNEStoppingPlace::isAdditionalValid
bool isAdditionalValid() const
check if current additional is valid to be writed into XML (by default true, can be reimplemented in ...
Definition: GNEStoppingPlace.cpp:59
GNEStoppingPlace::getStartGeometryPositionOverLane
double getStartGeometryPositionOverLane() const
get start position over lane that is applicable to the shape
Definition: GNEStoppingPlace.cpp:358
GNEStoppingPlace::fixStoppinPlacePosition
static bool fixStoppinPlacePosition(std::string &startPosStr, std::string &endPosStr, const double laneLength, const bool friendlyPos)
check if the position of an stoppingPlace over a la can be fixed
Definition: GNEStoppingPlace.cpp:168
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
GNEStoppingPlace::moveGeometry
void moveGeometry(const Position &offset)
change the position of the element geometry without saving in undoList
Definition: GNEStoppingPlace.cpp:230
GNEStoppingPlace.h
GNEStoppingPlace::fixAdditionalProblem
void fixAdditionalProblem()
fix additional problem
Definition: GNEStoppingPlace.cpp:126
GNEAdditional::myGeometry
AdditionalGeometry myGeometry
geometry to be precomputed in updateGeometry(...)
Definition: GNEAdditional.h:368
GNEStoppingPlace::commitGeometryMoving
void commitGeometryMoving(GNEUndoList *undoList)
commit geometry changes in the attributes of an element after use of moveGeometry(....
Definition: GNEStoppingPlace.cpp:283
Position::add
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:127
GNEStoppingPlace::myCircleInText
static const double myCircleInText
text inner circle width resolution for all stopping places
Definition: GNEStoppingPlace.h:179
GNEAttributeCarrier::getTagStr
const std::string & getTagStr() const
get tag assigned to this object in string format
Definition: GNEAttributeCarrier.cpp:1165
GNEUndoList
Definition: GNEUndoList.h:49
GNEStoppingPlace::getParentName
std::string getParentName() const
Returns the name of the parent object (if any)
Definition: GNEStoppingPlace.cpp:330
GNEHierarchicalElementChildren::getDemandElementChildren
const std::vector< GNEDemandElement * > & getDemandElementChildren() const
return vector of demand elements that have as Parent this edge (For example, Calibrators)
Definition: GNEHierarchicalElementChildren.cpp:297
GNEUndoList::p_begin
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:73
GNEStoppingPlace::~GNEStoppingPlace
~GNEStoppingPlace()
Destructor.
Definition: GNEStoppingPlace.cpp:55
GNEStoppingPlace::getAdditionalProblem
std::string getAdditionalProblem() const
return a string with the current additional problem
Definition: GNEStoppingPlace.cpp:91
GNEAdditional::AdditionalMove::originalViewPosition
Position originalViewPosition
value for saving first original position over lane before moving
Definition: GNEAdditional.h:329
POSITION_EPS
#define POSITION_EPS
Definition: config.h:169
GNEAdditional::AdditionalMove::firstOriginalLanePosition
std::string firstOriginalLanePosition
value for saving first original position over lane before moving
Definition: GNEAdditional.h:332
GNELane
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
GNEStoppingPlace::myCircleWidth
static const double myCircleWidth
circle width resolution for all stopping places
Definition: GNEStoppingPlace.h:170
GNEStoppingPlace::checkStoppinPlacePosition
static bool checkStoppinPlacePosition(const std::string &startPosStr, const std::string &endPosStr, const double laneLength, const bool friendlyPos)
check if the position of an stoppingPlace over a lane is valid (without modifications)
Definition: GNEStoppingPlace.cpp:139
GNEChange_Attribute.h
GNENet.h
PositionVector::move2side
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
Definition: PositionVector.cpp:1086
GNEUndoList.h
GNEAdditional::AdditionalGeometry::calculateShapeRotationsAndLengths
void calculateShapeRotationsAndLengths()
calculate shape rotations and lenghts
Definition: GNEAdditional.cpp:74
GNEStoppingPlace::myEndPosition
std::string myEndPosition
The position this stopping place is located at (optional, if empty takes the lane lenght)
Definition: GNEStoppingPlace.h:161