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 /****************************************************************************/
14 // A abstract class to define common parameters of lane area in which vehicles can halt (GNE version)
15 /****************************************************************************/
16 
17 // ===========================================================================
18 // included modules
19 // ===========================================================================
20 
21 #include <netedit/GNENet.h>
22 #include <netedit/GNEUndoList.h>
23 #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, double startPos, double endPos,
47  int parametersSet, const std::string& name, bool friendlyPosition, bool blockMovement) :
48  GNEAdditional(id, viewNet, type, tag, name, blockMovement, {}, {lane}, {}, {}, {}, {}, {}, {}, {}, {}),
49  myStartPosition(startPos),
50  myEndPosition(endPos),
51  myParametersSet(parametersSet),
52 myFriendlyPosition(friendlyPosition) {
53 }
54 
55 
57 
58 
59 bool
61  // with friendly position enabled position are "always fixed"
62  if (myFriendlyPosition) {
63  return true;
64  } else {
65  // obtain lane length
66  double laneLength = getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength() * getParentLanes().front()->getLengthGeometryFactor();
67  // calculate start and end positions
69  double endPos = (myParametersSet & STOPPINGPLACE_ENDPOS_SET) ? myEndPosition : laneLength;
70  // check if position has to be fixed
71  if (startPos < 0) {
72  startPos += laneLength;
73  }
74  if (endPos < 0) {
75  endPos += laneLength;
76  }
77  // check values
78  if (myParametersSet == 0) {
79  return true;
80  } else if ((myParametersSet & STOPPINGPLACE_STARTPOS_SET) == 0) {
81  return (endPos <= getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength());
82  } else if ((myParametersSet & STOPPINGPLACE_ENDPOS_SET) == 0) {
83  return (startPos >= 0);
84  } else {
85  return ((startPos >= 0) && (endPos <= getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength()) && ((endPos - startPos) >= POSITION_EPS));
86  }
87  }
88 }
89 
90 
91 std::string
93  // calculate start and end positions
95  double endPos = (myParametersSet & STOPPINGPLACE_ENDPOS_SET) ? myEndPosition : getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
96  // obtain lane length
97  double laneLength = getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
98  // check if position has to be fixed
99  if (startPos < 0) {
100  startPos += laneLength;
101  }
102  if (endPos < 0) {
103  endPos += laneLength;
104  }
105  // declare variables
106  std::string errorStart, separator, errorEnd;
107  // check positions over lane
108  if (startPos < 0) {
109  errorStart = (toString(SUMO_ATTR_STARTPOS) + " < 0");
110  } else if (startPos > getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength()) {
111  errorStart = (toString(SUMO_ATTR_STARTPOS) + " > lanes's length");
112  }
113  if (endPos < 0) {
114  errorEnd = (toString(SUMO_ATTR_ENDPOS) + " < 0");
115  } else if (endPos > getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength()) {
116  errorEnd = (toString(SUMO_ATTR_ENDPOS) + " > lanes's length");
117  }
118  // check separator
119  if ((errorStart.size() > 0) && (errorEnd.size() > 0)) {
120  separator = " and ";
121  }
122  return errorStart + separator + errorEnd;
123 }
124 
125 
126 void
128  // declare new start and end position
129  double newStartPos = myStartPosition;
130  double newEndPos = myEndPosition;
131  // fix start and end positions using fixStoppingPlacePosition
132  SUMORouteHandler::checkStopPos(newStartPos, newEndPos, getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength(), POSITION_EPS, true);
133  // set new start and end positions
136 }
137 
138 
139 Position
141  // calculate start and end positions as absolute values
142  double startPos = fabs((myParametersSet & STOPPINGPLACE_STARTPOS_SET) ? myStartPosition : 0);
143  double endPos = fabs((myParametersSet & STOPPINGPLACE_ENDPOS_SET) ? myEndPosition : getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength());
144  // obtain position in view depending if both positions are defined
145  if (myParametersSet == 0) {
146  return getParentLanes().front()->getLaneShape().positionAtOffset(getParentLanes().front()->getLaneShape().length() / 2);
147  } else if ((myParametersSet & STOPPINGPLACE_STARTPOS_SET) == 0) {
148  return getParentLanes().front()->getLaneShape().positionAtOffset(endPos);
149  } else if ((myParametersSet & STOPPINGPLACE_ENDPOS_SET) == 0) {
150  return getParentLanes().front()->getLaneShape().positionAtOffset(startPos);
151  } else {
152  return getParentLanes().front()->getLaneShape().positionAtOffset((startPos + endPos) / 2.0);
153  }
154 }
155 
156 
157 void
158 GNEStoppingPlace::splitEdgeGeometry(const double splitPosition, const GNENetElement* originalElement, const GNENetElement* newElement, GNEUndoList* undoList) {
159  // first check tat both net elements are lanes and originalElement correspond to stoppingPlace lane
160  if ((originalElement->getTagProperty().getTag() == SUMO_TAG_LANE) &&
161  (originalElement->getTagProperty().getTag() == SUMO_TAG_LANE) &&
162  (getParentLanes().front() == originalElement)) {
163  // check if we have to change additional lane depending of split position
165  // calculate middle position
166  const double middlePosition = ((myEndPosition - myStartPosition) / 2.0) + myStartPosition;
167  // four cases:
168  if (splitPosition < myStartPosition) {
169  // change lane
170  setAttribute(SUMO_ATTR_LANE, newElement->getID(), undoList);
171  // now adjust start and end position
172  setAttribute(SUMO_ATTR_STARTPOS, toString(myStartPosition - splitPosition), undoList);
173  setAttribute(SUMO_ATTR_ENDPOS, toString(myEndPosition - splitPosition), undoList);
174  } else if ((splitPosition > myStartPosition) && (splitPosition < middlePosition)) {
175  // change lane
176  setAttribute(SUMO_ATTR_LANE, newElement->getID(), undoList);
177  // now adjust start and end position
178  setAttribute(SUMO_ATTR_STARTPOS, "0", undoList);
179  setAttribute(SUMO_ATTR_ENDPOS, toString(myEndPosition - splitPosition), undoList);
180  } else if ((splitPosition > middlePosition) && (splitPosition < myEndPosition)) {
181  // only adjust end position
182  setAttribute(SUMO_ATTR_ENDPOS, toString(splitPosition), undoList);
183  } else if ((splitPosition > myEndPosition)) {
184  // nothing to do
185  }
186  } else if ((myParametersSet & STOPPINGPLACE_STARTPOS_SET) && (splitPosition < myStartPosition)) {
187  // change lane
188  setAttribute(SUMO_ATTR_LANE, newElement->getID(), undoList);
189  // now adjust start position
190  setAttribute(SUMO_ATTR_STARTPOS, toString(myStartPosition - splitPosition), undoList);
191  } else if ((myParametersSet & STOPPINGPLACE_ENDPOS_SET) && (splitPosition < myEndPosition)) {
192  // change lane
193  setAttribute(SUMO_ATTR_LANE, newElement->getID(), undoList);
194  // now adjust end position
195  setAttribute(SUMO_ATTR_ENDPOS, toString(myEndPosition - splitPosition), undoList);
196  }
197  }
198 }
199 
200 
201 void
203  // only move if at leats start or end positions is defined
204  if (myParametersSet > 0) {
205  // Calculate new position using old position
206  Position newPosition = myMove.originalViewPosition;
207  newPosition.add(offset);
208  // filtern position using snap to active grid
209  newPosition = myViewNet->snapToActiveGrid(newPosition);
210  double offsetLane = getParentLanes().front()->getLaneShape().nearest_offset_to_point2D(newPosition, false) - getParentLanes().front()->getLaneShape().nearest_offset_to_point2D(myMove.originalViewPosition, false);
211  // check if both position has to be moved
213  // calculate stoppingPlace length and lane length (After apply geometry factor)
214  double stoppingPlaceLength = fabs(parse<double>(myMove.secondOriginalPosition) - parse<double>(myMove.firstOriginalLanePosition));
215  double laneLengt = getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength() * getParentLanes().front()->getLengthGeometryFactor();
216  // avoid changing stopping place's length
217  if ((parse<double>(myMove.firstOriginalLanePosition) + offsetLane) < 0) {
218  myStartPosition = 0;
219  myEndPosition = stoppingPlaceLength;
220  } else if ((parse<double>(myMove.secondOriginalPosition) + offsetLane) > laneLengt) {
221  myStartPosition = laneLengt - stoppingPlaceLength;
222  myEndPosition = laneLengt;
223  } else {
224  myStartPosition = parse<double>(myMove.firstOriginalLanePosition) + offsetLane;
225  myEndPosition = parse<double>(myMove.secondOriginalPosition) + offsetLane;
226  }
227  } else {
228  // check if start position must be moved
230  myStartPosition = parse<double>(myMove.firstOriginalLanePosition) + offsetLane;
231  }
232  // check if start position must be moved
234  myEndPosition = parse<double>(myMove.secondOriginalPosition) + offsetLane;
235  }
236  }
237  // Update geometry
238  updateGeometry();
239  }
240 }
241 
242 
243 void
245  // only commit geometry moving if at leats start or end positions is defined
246  if (myParametersSet > 0) {
247  undoList->p_begin("position of " + getTagStr());
250  }
253  }
254  undoList->p_end();
255  }
256 }
257 
258 
259 double
262  return myStartPosition;
263  } else {
264  return 0;
265  }
266 }
267 
268 
269 double
272  return myEndPosition;
273  } else {
274  return getParentLanes().front()->getLaneShapeLength();
275  }
276 }
277 
278 
279 std::string
281  return getParentLanes().front()->getMicrosimID();
282 }
283 
284 
285 void
287  // Get value of option "lefthand"
288  double offsetSign = OptionsCont::getOptions().getBool("lefthand") ? -1 : 1;
289 
290  // obtain laneShape
291  PositionVector laneShape = getParentLanes().front()->getLaneShape();
292 
293  // Move shape to side
294  laneShape.move2side(movingToSide * offsetSign);
295 
296  // Cut shape using as delimitators fixed start position and fixed end position
298 }
299 
300 
301 double
304  double fixedPos = myStartPosition;
305  const double len = getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
306  if (fixedPos < 0) {
307  fixedPos += len;
308  }
309  return fixedPos * getParentLanes().front()->getLengthGeometryFactor();
310  } else {
311  return 0;
312  }
313 }
314 
315 
316 double
319  double fixedPos = myEndPosition;
320  const double len = getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
321  if (fixedPos < 0) {
322  fixedPos += len;
323  }
324  return fixedPos * getParentLanes().front()->getLengthGeometryFactor();
325  } else {
326  return getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
327  }
328 }
329 
330 
331 double
333  switch (key) {
334  case SUMO_ATTR_STARTPOS:
336  return myStartPosition;
337  } else {
338  return -1;
339  }
340  case SUMO_ATTR_ENDPOS:
342  return myEndPosition;
343  } else {
344  return -1;
345  }
346  default:
347  throw InvalidArgument(getTagStr() + " doesn't have a double attribute of type '" + toString(key) + "'");
348  }
349 }
350 
351 
352 bool
354  // all stopping place attributes are always enabled
355  return true;
356 }
357 
358 
359 std::string
361  return getTagStr() + ": " + getID();
362 }
363 
364 
365 std::string
367  return getTagStr();
368 }
369 
370 /****************************************************************************/
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
GNEStoppingPlace::myStartPosition
double myStartPosition
The relative start position this stopping place is located at (optional, if empty takes 0)
Definition: GNEStoppingPlace.h:159
GNEAdditional
An Element which don't belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:48
GNEAttributeCarrier::getID
const std::string getID() const
function to support debugging
Definition: GNEAttributeCarrier.cpp:1289
GNEGeometry::Geometry::updateGeometryShape
void updateGeometryShape(const PositionVector &shape, double startPos=-1, double endPos=-1, const Position &extraFirstPosition=Position::INVALID, const Position &extraLastPosition=Position::INVALID)
update geometry shape
Definition: GNEGeometry.cpp:48
GNEStoppingPlace::GNEStoppingPlace
GNEStoppingPlace(const std::string &id, GNEViewNet *viewNet, GUIGlObjectType type, SumoXMLTag tag, GNELane *lane, double startPos, double endPos, int parametersSet, const std::string &name, bool friendlyPosition, bool blockMovement)
Constructor.
Definition: GNEStoppingPlace.cpp:46
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:79
GNEStoppingPlace::splitEdgeGeometry
void splitEdgeGeometry(const double splitPosition, const GNENetElement *originalElement, const GNENetElement *newElement, GNEUndoList *undoList)
split geometry
Definition: GNEStoppingPlace.cpp:158
OptionsCont.h
SUMO_TAG_LANE
begin/end of the description of a single lane
Definition: SUMOXMLDefinitions.h:49
OptionsCont::getBool
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
Definition: OptionsCont.cpp:222
GNEHierarchicalParentElements::getParentLanes
const std::vector< GNELane * > & getParentLanes() const
get parent lanes
Definition: GNEHierarchicalParentElements.cpp:235
STOPPINGPLACE_STARTPOS_SET
const int STOPPINGPLACE_STARTPOS_SET
Definition: GNEStoppingPlace.h:29
OptionsCont::getOptions
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:57
GNEViewNet
Definition: GNEViewNet.h:42
SUMO_ATTR_LANE
Definition: SUMOXMLDefinitions.h:637
SUMO_ATTR_ENDPOS
Definition: SUMOXMLDefinitions.h:798
STOPPINGPLACE_ENDPOS_SET
const int STOPPINGPLACE_ENDPOS_SET
Definition: GNEStoppingPlace.h:30
PositionVector
A list of positions.
Definition: PositionVector.h:45
GNEAdditional::AdditionalMove::secondOriginalPosition
std::string secondOriginalPosition
value for saving second original position over lane before moving
Definition: GNEAdditional.h:297
SumoXMLTag
SumoXMLTag
Numbers representing SUMO-XML - element names.
Definition: SUMOXMLDefinitions.h:41
GNEStoppingPlace::myCircleInWidth
static const double myCircleInWidth
inner circle width resolution for all stopping places
Definition: GNEStoppingPlace.h:180
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:196
GNEAttributeCarrier::TagProperties::getTag
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
Definition: GNEAttributeCarrier.cpp:523
SUMORouteHandler::checkStopPos
static StopPos checkStopPos(double &startPos, double &endPos, const double laneLength, const double minLength, const bool friendlyPos)
check start and end position of a stop
Definition: SUMORouteHandler.cpp:283
GNEAdditional::myMove
AdditionalMove myMove
variable AdditionalMove
Definition: GNEAdditional.h:344
GNEAdditional::myViewNet
GNEViewNet * myViewNet
The GNEViewNet this additional element belongs.
Definition: GNEAdditional.h:335
GNEStoppingPlace::myParametersSet
int myParametersSet
Variable used for set/unset start/endPositions.
Definition: GNEStoppingPlace.h:165
GUIGlObjectType
GUIGlObjectType
Definition: GUIGlObjectTypes.h:39
GNEAttributeCarrier::GNEChange_Attribute
friend class GNEChange_Attribute
declare friend class
Definition: GNEAttributeCarrier.h:57
GNEUndoList::p_add
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
Definition: GNEUndoList.cpp:131
GNEViewNet::getNet
GNENet * getNet() const
get the net object
Definition: GNEViewNet.cpp:1014
GNEStoppingPlace::myFriendlyPosition
bool myFriendlyPosition
Flag for friendly position.
Definition: GNEStoppingPlace.h:168
GNEStoppingPlace::isAttributeEnabled
bool isAttributeEnabled(SumoXMLAttr key) const
Definition: GNEStoppingPlace.cpp:353
GNEStoppingPlace::getPositionInView
Position getPositionInView() const
Returns position of additional in view.
Definition: GNEStoppingPlace.cpp:140
GNEAttributeCarrier::getTagProperty
const TagProperties & getTagProperty() const
get Tag Property assigned to this object
Definition: GNEAttributeCarrier.cpp:1273
GNEStoppingPlace::getStartPosition
double getStartPosition() const
get start Position
Definition: GNEStoppingPlace.cpp:260
SUMO_ATTR_STARTPOS
Definition: SUMOXMLDefinitions.h:797
GNEStoppingPlace::getHierarchyName
std::string getHierarchyName() const
get Hierarchy Name (Used in AC Hierarchy)
Definition: GNEStoppingPlace.cpp:366
GNEStoppingPlace::getAttributeDouble
double getAttributeDouble(SumoXMLAttr key) const
Definition: GNEStoppingPlace.cpp:332
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:177
GNEDemandElement.h
GNEStoppingPlace::setStoppingPlaceGeometry
void setStoppingPlaceGeometry(double movingToSide)
set geometry common to all stopping places
Definition: GNEStoppingPlace.cpp:286
GNEViewNet.h
Position
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:38
GNEEdge.h
GNEViewNet::getUndoList
GNEUndoList * getUndoList() const
get the undoList object
Definition: GNEViewNet.cpp:1020
GNEAdditional::myAdditionalGeometry
GNEGeometry::Geometry myAdditionalGeometry
geometry to be precomputed in updateGeometry(...)
Definition: GNEAdditional.h:338
GNEStoppingPlace::getEndPosition
double getEndPosition() const
get end Position
Definition: GNEStoppingPlace.cpp:270
GNENetElement
Definition: GNENetElement.h:43
GNEStoppingPlace::getPopUpID
std::string getPopUpID() const
get PopPup ID (Used in AC Hierarchy)
Definition: GNEStoppingPlace.cpp:360
GNEStoppingPlace::getEndGeometryPositionOverLane
double getEndGeometryPositionOverLane() const
get end position over lane that is applicable to the shape
Definition: GNEStoppingPlace.cpp:317
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:60
GNEStoppingPlace::getStartGeometryPositionOverLane
double getStartGeometryPositionOverLane() const
get start position over lane that is applicable to the shape
Definition: GNEStoppingPlace.cpp:302
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:47
InvalidArgument
Definition: UtilExceptions.h:56
SUMORouteHandler.h
GNEStoppingPlace::moveGeometry
void moveGeometry(const Position &offset)
change the position of the element geometry without saving in undoList
Definition: GNEStoppingPlace.cpp:202
GNEStoppingPlace.h
GNEStoppingPlace::fixAdditionalProblem
void fixAdditionalProblem()
fix additional problem
Definition: GNEStoppingPlace.cpp:127
GNEStoppingPlace::commitGeometryMoving
void commitGeometryMoving(GNEUndoList *undoList)
commit geometry changes in the attributes of an element after use of moveGeometry(....
Definition: GNEStoppingPlace.cpp:244
Position::add
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:126
GNEStoppingPlace::myEndPosition
double myEndPosition
The position this stopping place is located at (optional, if empty takes the lane length)
Definition: GNEStoppingPlace.h:162
GNEStoppingPlace::myCircleInText
static const double myCircleInText
text inner circle width resolution for all stopping places
Definition: GNEStoppingPlace.h:183
GNEAttributeCarrier::getTagStr
const std::string & getTagStr() const
get tag assigned to this object in string format
Definition: GNEAttributeCarrier.cpp:1267
GNEUndoList
Definition: GNEUndoList.h:48
GNEStoppingPlace::getParentName
std::string getParentName() const
Returns the name of the parent object (if any)
Definition: GNEStoppingPlace.cpp:280
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:72
GNEStoppingPlace::~GNEStoppingPlace
~GNEStoppingPlace()
Destructor.
Definition: GNEStoppingPlace.cpp:56
SumoXMLAttr
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
Definition: SUMOXMLDefinitions.h:372
GNEStoppingPlace::getAdditionalProblem
std::string getAdditionalProblem() const
return a string with the current additional problem
Definition: GNEStoppingPlace.cpp:92
GNEAdditional::AdditionalMove::originalViewPosition
Position originalViewPosition
value for saving first original position over lane before moving
Definition: GNEAdditional.h:291
POSITION_EPS
#define POSITION_EPS
Definition: config.h:172
GNEAdditional::AdditionalMove::firstOriginalLanePosition
std::string firstOriginalLanePosition
value for saving first original position over lane before moving
Definition: GNEAdditional.h:294
GNELane
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:45
GNEStoppingPlace::myCircleWidth
static const double myCircleWidth
circle width resolution for all stopping places
Definition: GNEStoppingPlace.h:174
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:1103
GNEUndoList.h