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-2018 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 #include <config.h>
22 
23 #include <string>
24 #include <iostream>
25 #include <utility>
29 #include <utils/common/ToString.h>
30 #include <utils/geom/GeomHelper.h>
35 #include <utils/gui/div/GLHelper.h>
42 #include <netedit/GNEUndoList.h>
43 #include <netedit/GNENet.h>
45 #include <netedit/GNEViewNet.h>
46 
47 #include "GNEStoppingPlace.h"
48 #include "GNEAdditionalHandler.h"
49 
50 // ===========================================================================
51 // static members
52 // ===========================================================================
53 
54 const double GNEStoppingPlace::myCircleWidth = 1.1;
55 const double GNEStoppingPlace::myCircleWidthSquared = 1.21;
56 const double GNEStoppingPlace::myCircleInWidth = 0.9;
57 const double GNEStoppingPlace::myCircleInText = 1.6;
58 
59 // ===========================================================================
60 // member method definitions
61 // ===========================================================================
62 
63 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) :
64  GNEAdditional(id, viewNet, type, tag, name, blockMovement),
65  myLane(lane),
66  myStartPosition(startPos),
67  myEndPosition(endPos),
68  myFriendlyPosition(friendlyPosition) {
69 }
70 
71 
73 
74 
77  double startPos = canParse<double>(myStartPosition) ? parse<double>(myStartPosition) : 0;
78  double endPos = canParse<double>(myEndPosition) ? parse<double>(myEndPosition) : myLane->getShape().length();
79  if (myStartPosition.empty() && myEndPosition.empty()) {
81  } else if (myStartPosition.empty()) {
82  return myLane->getShape().positionAtOffset(endPos);
83  } else if (myEndPosition.empty()) {
84  return myLane->getShape().positionAtOffset(startPos);
85  } else {
86  return myLane->getShape().positionAtOffset((startPos + endPos) / 2.0);
87  }
88 }
89 
90 
91 void
92 GNEStoppingPlace::moveGeometry(const Position& oldPos, const Position& offset) {
93  // only move if at leats start or end positions is defined
94  if (!myStartPosition.empty() || !myEndPosition.empty()) {
95  // Calculate new position using old position
96  Position newStoppingPlaceCenterPosition = oldPos;
97  newStoppingPlaceCenterPosition.add(offset);
98  double newStoppingPlaceCenter = myLane->getShape().nearest_offset_to_point2D(newStoppingPlaceCenterPosition, false);
99  // move stopping palce depending if start or end position is defined
100  if (!myStartPosition.empty() && !myEndPosition.empty()) {
101  double halfStoppingPlaceLength = (parse<double>(myEndPosition) - parse<double>(myStartPosition)) / 2.0;
102  // change start and end position of stopping place
103  myStartPosition = toString(newStoppingPlaceCenter - halfStoppingPlaceLength);
104  myEndPosition = toString(newStoppingPlaceCenter + halfStoppingPlaceLength);
105  } else if (myStartPosition.empty()) {
106  myEndPosition = toString(newStoppingPlaceCenter);
107  } else {
108  myStartPosition = toString(newStoppingPlaceCenter);
109  }
110  // Update geometry
111  updateGeometry(false);
112  }
113 }
114 
115 
116 void
118  // only commit geometry moving if at leats start or end positions is defined
119  if (!myStartPosition.empty() || !myEndPosition.empty()) {
120  // calculate old stopping place center
121  double oldStoppingPlaceCenterOffset = myLane->getShape().nearest_offset_to_point2D(oldPos, false);
122  undoList->p_begin("position of " + toString(getTag()));
123  // change myStartPosition or myEndPosition depending if they are defined
124  if (!myStartPosition.empty() && !myEndPosition.empty()) {
125  double halfStoppingPlaceLength = (parse<double>(myEndPosition) - parse<double>(myStartPosition)) / 2.0;
126  undoList->p_add(new GNEChange_Attribute(this, SUMO_ATTR_STARTPOS, toString(myStartPosition), true, toString(oldStoppingPlaceCenterOffset - halfStoppingPlaceLength)));
127  undoList->p_add(new GNEChange_Attribute(this, SUMO_ATTR_ENDPOS, myEndPosition, true, toString(oldStoppingPlaceCenterOffset + halfStoppingPlaceLength)));
128  } else if (myStartPosition.empty()) {
129  undoList->p_add(new GNEChange_Attribute(this, SUMO_ATTR_ENDPOS, myEndPosition, true, toString(oldStoppingPlaceCenterOffset)));
130  } else {
131  undoList->p_add(new GNEChange_Attribute(this, SUMO_ATTR_STARTPOS, toString(myStartPosition), true, toString(oldStoppingPlaceCenterOffset)));
132  }
133  // only change end position if its set
134  if (!myEndPosition.empty()) {
135  }
136  undoList->p_end();
137  }
138 }
139 
140 
141 GNELane*
143  return myLane;
144 }
145 
146 
147 double
149  if (canParse<double>(myStartPosition)) {
150  return parse<double>(myStartPosition);
151  } else {
152  return 0;
153  }
154 }
155 
156 
157 double
159  if (canParse<double>(myEndPosition)) {
160  return parse<double>(myEndPosition);
161  } else {
162  return myLane->getLaneShapeLength();
163  }
164 }
165 
166 
167 bool
169  // with friendly position enabled position are "always fixed"
170  if (myFriendlyPosition) {
171  return true;
172  } else {
173  if (myStartPosition.empty() && myEndPosition.empty()) {
174  return true;
175  } else if (myStartPosition.empty()) {
176  return (canParse<double>(myEndPosition) && (parse<double>(myEndPosition) <= myLane->getParentEdge().getNBEdge()->getFinalLength()));
177  } else if (myEndPosition.empty()) {
178  return (canParse<double>(myStartPosition) && (parse<double>(myStartPosition) >= 0));
179  } else {
180  return canParse<double>(myStartPosition) && canParse<double>(myEndPosition) &&
181  (parse<double>(myStartPosition) >= 0) &&
182  (parse<double>(myEndPosition) <= myLane->getParentEdge().getNBEdge()->getFinalLength()) &&
183  ((parse<double>(myEndPosition) - parse<double>(myStartPosition)) >= POSITION_EPS);
184  }
185  }
186 }
187 
188 
189 std::string
191  return myLane->getMicrosimID();
192 }
193 
194 
195 void
197  // Clear all containers
198  myShapeRotations.clear();
199  myShapeLengths.clear();
200 
201  // Get value of option "lefthand"
202  double offsetSign = OptionsCont::getOptions().getBool("lefthand") ? -1 : 1;
203 
204  // Get shape of lane parent
205  myShape = myLane->getShape();
206 
207  // Move shape to side
208  myShape.move2side(movingToSide * offsetSign);
209 
210  // set start position
211  double startPosFixed;
212  if (!canParse<double>(myStartPosition)) {
213  startPosFixed = 0;
214  } else if (parse<double>(myStartPosition) < 0) {
215  startPosFixed = 0;
216  } else if (parse<double>(myStartPosition) > myLane->getParentEdge().getNBEdge()->getFinalLength()) {
217  startPosFixed = myLane->getParentEdge().getNBEdge()->getFinalLength();
218  } else {
219  startPosFixed = parse<double>(myStartPosition);
220  }
221 
222  // set end position
223  double endPosFixed;
224  if (!canParse<double>(myEndPosition)) {
225  endPosFixed = myLane->getParentEdge().getNBEdge()->getFinalLength();
226  } else if (parse<double>(myEndPosition) < 0) {
227  endPosFixed = 0;
228  } else if (parse<double>(myEndPosition) > myLane->getParentEdge().getNBEdge()->getFinalLength()) {
229  endPosFixed = myLane->getParentEdge().getNBEdge()->getFinalLength();
230  } else {
231  endPosFixed = parse<double>(myEndPosition);
232  }
233 
234  // Cut shape using as delimitators fixed start position and fixed end position
235  myShape = myShape.getSubpart(startPosFixed * myLane->getLengthGeometryFactor(), endPosFixed * myLane->getLengthGeometryFactor());
236 
237  // Get number of parts of the shape
238  int numberOfSegments = (int) myShape.size() - 1;
239 
240  // If number of segments is more than 0
241  if (numberOfSegments >= 0) {
242 
243  // Reserve memory (To improve efficiency)
244  myShapeRotations.reserve(numberOfSegments);
245  myShapeLengths.reserve(numberOfSegments);
246 
247  // For every part of the shape
248  for (int i = 0; i < numberOfSegments; ++i) {
249 
250  // Obtain first position
251  const Position& f = myShape[i];
252 
253  // Obtain next position
254  const Position& s = myShape[i + 1];
255 
256  // Save distance between position into myShapeLengths
257  myShapeLengths.push_back(f.distanceTo(s));
258 
259  // Save rotation (angle) of the vector constructed by points f and s
260  myShapeRotations.push_back((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double)M_PI);
261  }
262  }
263 }
264 
265 
266 std::string
268  return toString(getTag()) + ": " + getID();
269 }
270 
271 
272 std::string
274  return toString(getTag());
275 }
276 
277 /****************************************************************************/
SumoXMLTag
Numbers representing SUMO-XML - element names.
void commitGeometryMoving(const Position &oldPos, GNEUndoList *undoList)
commit geometry changes in the attributes of an element after use of moveGeometry(...)
bool areStoppingPlacesPositionsFixed() const
check if Position of stoppingPlace are fixed
GUIGlObjectType
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:126
std::string getHierarchyName() const
get Hierarchy Name (Used in AC Hierarchy)
std::string getPopUpID() const
get PopPup ID (Used in AC Hierarchy)
static const double myCircleWidthSquared
squared circle width resolution for all stopping places
double y() const
Returns the y-position.
Definition: Position.h:61
static const double myCircleInWidth
inner circle width resolution for all stopping places
Position getPositionInView() const
Returns position of additional in view.
double x() const
Returns the x-position.
Definition: Position.h:56
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:47
bool myFriendlyPosition
Flag for friendly position.
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:78
void moveGeometry(const Position &oldPos, const Position &offset)
change the position of the element geometry without saving in undoList
std::string myStartPosition
The relative start position this stopping place is located at (optional, if empty takes 0) ...
static const double myCircleInText
text inner circle width resolution for all stopping places
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
std::string getParentName() const
Returns the name of the parent object (if any)
std::vector< double > myShapeRotations
GNELane * getLane() const
get Lane
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
double getEndPosition() const
get end Position
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
GNEEdge & getParentEdge()
Returns underlying parent edge.
Definition: GNELane.cpp:1230
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:85
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
GNELane * myLane
The lane in which this lane is placed.
friend class GNEChange_Attribute
declare friend class
double getLengthGeometryFactor() const
get lenght geometry factor
Definition: GNELane.cpp:1287
std::vector< double > myShapeLengths
The lengths of the shape parts.
#define POSITION_EPS
Definition: config.h:172
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.
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
~GNEStoppingPlace()
Destructor.
const std::string getID() const
function to support debugging
PositionVector getSubpart(double beginOffset, double endOffset) const
get subpart of a position vector
double getLaneShapeLength() const
returns the length of the lane&#39;s shape
Definition: GNELane.cpp:726
double getFinalLength() const
get length that will be assigned to the lanes in the final network
Definition: NBEdge.cpp:3523
void move2side(double amount)
move position vector to side using certain ammount
static const double myCircleWidth
circle width resolution for all stopping places
double getStartPosition() const
get start Position
void setStoppingPlaceGeometry(double movingToSide)
set geometry common to all stopping places
const PositionVector & getShape() const
returns the shape of the lane
Definition: GNELane.cpp:613
double length() const
Returns the length.
#define M_PI
Definition: odrSpiral.cpp:40
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:53
virtual void updateGeometry(bool updateGrid)=0
update pre-computed geometry information
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:233
std::string myEndPosition
The position this stopping place is located at (optional, if empty takes the lane lenght) ...
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.cpp:586
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
SumoXMLTag getTag() const
get XML Tag assigned to this object