Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNEMoveElementLaneSingle.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
18// Class used for elements that can be moved over a lane with only one position
19/****************************************************************************/
20
23#include <netedit/GNENet.h>
24#include <netedit/GNEUndoList.h>
26
28
29// ===========================================================================
30// static members
31// ===========================================================================
32
33const std::string GNEMoveElementLaneSingle::PositionType::SINGLE = "single";
34const std::string GNEMoveElementLaneSingle::PositionType::STARPOS = TL("lane start");
35const std::string GNEMoveElementLaneSingle::PositionType::ENDPOS = TL("lane end");
36
37// ===========================================================================
38// Method definitions
39// ===========================================================================
40
42 SumoXMLAttr posAttr, double& position, bool& friendlyPos, const std::string& defaultBehavior) :
43 GNEMoveElement(element),
44 myPosAttr(posAttr),
45 myPosOverLane(position),
46 myFriendlyPos(friendlyPos),
47 myPositionType(defaultBehavior) {
48}
49
50
52
53
56 // check if allow change lane is enabled
58 // continue depending if we're moving the start or the end position
61 myMovedElement->getHierarchicalElement()->getParentLanes().back(), myPosOverLane, false, allowChangeLane);
62 } else {
64 myMovedElement->getHierarchicalElement()->getParentLanes().back(), INVALID_DOUBLE, true, allowChangeLane);
65 }
66}
67
68
69std::string
71 if (key == myPosAttr) {
73 return myPositionType;
74 } else {
75 return toString(myPosOverLane);
76 }
77 } else {
78 switch (key) {
79 case SUMO_ATTR_LANE:
80 return myMovedElement->getHierarchicalElement()->getParentLanes().front()->getID();
82 return toString(myFriendlyPos);
83 default:
85 }
86 }
87}
88
89
90double
92 if (key == myPosAttr) {
93 return myPosOverLane;
94 } else {
96 }
97}
98
99
104
105
110
111
112void
114 if (key == myPosAttr) {
116 } else {
117 switch (key) {
118 case SUMO_ATTR_LANE:
121 break;
122 default:
123 myMovedElement->setCommonAttribute(key, value, undoList);
124 break;
125 }
126 }
127}
128
129
130bool
132 if (key == myPosAttr) {
133 if ((myPositionType != PositionType::SINGLE) && (value.empty() || (value == myPositionType))) {
134 return true;
135 } else {
136 return GNEAttributeCarrier::canParse<double>(value);
137 }
138 } else {
139 switch (key) {
140 case SUMO_ATTR_LANE:
141 if (myMovedElement->getNet()->getAttributeCarriers()->retrieveLane(value, false) != nullptr) {
142 return true;
143 } else {
144 return false;
145 }
147 return GNEAttributeCarrier::canParse<bool>(value);
148 default:
149 return myMovedElement->isCommonAttributeValid(key, value);
150 }
151 }
152}
153
154
155void
157 if (key == myPosAttr) {
158 if (value.empty()) {
160 } else if ((value == PositionType::STARPOS) && (myPositionType == PositionType::STARPOS)) {
162 } else if ((value == PositionType::ENDPOS) && (myPositionType == PositionType::ENDPOS)) {
164 } else {
165 myPosOverLane = GNEAttributeCarrier::parse<double>(value);
166 }
167 } else {
168 switch (key) {
170 myFriendlyPos = GNEAttributeCarrier::parse<bool>(value);
171 break;
172 default:
174 break;
175 }
176 }
177}
178
179
180void
181GNEMoveElementLaneSingle::removeGeometryPoint(const Position /*clickedPosition*/, GNEUndoList* /*undoList*/) {
182 // nothing to do here
183}
184
185
186bool
188 // obtain lane final length
189 const double laneLenght = (myPositionType == PositionType::ENDPOS) ? myMovedElement->getHierarchicalElement()->getParentLanes().back()->getParentEdge()->getNBEdge()->getFinalLength() :
190 myMovedElement->getHierarchicalElement()->getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
191 // adjust position (negative means start counting from backward)
192 const double adjustedPosition = (myPosOverLane == INVALID_DOUBLE) ? 0 : (myPosOverLane < 0) ? (myPosOverLane + laneLenght) : myPosOverLane;
193 // check conditions
194 if (myFriendlyPos) {
195 return true;
196 } else if (adjustedPosition < 0) {
197 return false;
198 } else if (adjustedPosition > laneLenght) {
199 return false;
200 } else if ((myPositionType == PositionType::STARPOS) && (adjustedPosition > (laneLenght - POSITION_EPS))) {
201 return false;
202 } else {
203 return true;
204 }
205}
206
207
208std::string
210 // obtain lane final length
211 const double laneLenght = (myPositionType == PositionType::ENDPOS) ? myMovedElement->getHierarchicalElement()->getParentLanes().back()->getParentEdge()->getNBEdge()->getFinalLength() :
212 myMovedElement->getHierarchicalElement()->getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
213 // adjust position (negative means start counting from backward)
214 const double adjustedPosition = (myPosOverLane == INVALID_DOUBLE) ? 0 : (myPosOverLane < 0) ? (myPosOverLane + laneLenght) : myPosOverLane;
215 // check conditions
216 if (myFriendlyPos) {
217 return "";
218 } else if (adjustedPosition < 0) {
219 return TLF("% < 0", toString(myPosAttr));
220 } else if (adjustedPosition > laneLenght) {
221 return TLF("% > length of lane", toString(myPosAttr));
222 } else if ((myPositionType == PositionType::STARPOS) && (adjustedPosition > (laneLenght - POSITION_EPS))) {
223 return TLF("% > (length of lane - EPS)", toString(myPosAttr));
224 } else {
225 return "";
226 }
227}
228
229
230void
232 // obtain lane final length
233 const double laneLenght = myMovedElement->getHierarchicalElement()->getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
234 // adjust position (negative means start counting from backward)
235 const double adjustedPosition = (myPosOverLane == INVALID_DOUBLE) ? 0 : (myPosOverLane < 0) ? (myPosOverLane + laneLenght) : myPosOverLane;
236 // check conditions
237 if (adjustedPosition < 0) {
239 } else if (adjustedPosition > laneLenght) {
241 } else if ((myPositionType == PositionType::STARPOS) && (adjustedPosition > (laneLenght - POSITION_EPS))) {
243 }
244}
245
246
247void
249 // lane
251 // position (don't write if is an invalid double, except in no default)
254 }
255 // friendly position (only if true)
256 if (myFriendlyPos) {
258 }
259}
260
261
262double
263GNEMoveElementLaneSingle::getFixedPositionOverLane(const bool adjustGeometryFactor) const {
264 // get lane depending of type
266 const double laneLength = lane->getParentEdge()->getNBEdge()->getFinalLength();
267 // continue depending if we defined a end position
270 return adjustGeometryFactor ? (laneLength * lane->getLengthGeometryFactor()) : laneLength;
271 } else {
272 return 0;
273 }
274 } else {
275 // fix position
276 double fixedPos = myPosOverLane;
277 // adjust fixedPos
278 if (fixedPos < 0) {
279 fixedPos += laneLength;
280 }
281 // set length geometry factor
282 if (adjustGeometryFactor) {
283 // adjust geometry factor
284 fixedPos *= lane->getLengthGeometryFactor();
285 // return depending of fixedPos
286 if (fixedPos < 0) {
287 return 0;
288 } else if (fixedPos > lane->getLaneShapeLength()) {
289 return lane->getLaneShapeLength();
290 } else {
291 return fixedPos;
292 }
293 } else {
294 // return depending of fixedPos
295 if (fixedPos < 0) {
296 return 0;
297 } else if (fixedPos > laneLength) {
298 return laneLength;
299 } else {
300 return fixedPos;
301 }
302 }
303 }
304}
305
306
307void
310 // change position
311 myPosOverLane = moveResult.newLastPos;
312 // set lateral offset
314 } else {
315 // change position
316 myPosOverLane = moveResult.newFirstPos;
317 // set lateral offset
319 }
320 // update geometry
322}
323
324
325void
327 // reset lateral offset
329 // begin change attribute
330 undoList->begin(myMovedElement, TLF("position of %", myMovedElement->getTagStr()));
331 // set position
334 // check if lane has to be changed
335 if (moveResult.newLastLane && (moveResult.newLastLane != myMovedElement->getHierarchicalElement()->getParentLanes().back())) {
336 // set new lane
338 }
339 } else {
341 // check if lane has to be changed
342 if (moveResult.newFirstLane && (moveResult.newFirstLane != myMovedElement->getHierarchicalElement()->getParentLanes().front())) {
343 // set new lane
345 }
346 }
347 // end change attribute
348 undoList->end();
349}
350
351/****************************************************************************/
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_LANE
@ SUMO_ATTR_FRIENDLY_POS
const double INVALID_DOUBLE
invalid double
Definition StdDefs.h:68
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
const std::string getID() const
get ID (all Attribute Carriers have one)
double getCommonAttributeDouble(SumoXMLAttr key) const
PositionVector getCommonAttributePositionVector(SumoXMLAttr key) const
void setCommonAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
const std::string & getTagStr() const
get tag assigned to this object in string format
Position getCommonAttributePosition(SumoXMLAttr key) const
virtual GNEHierarchicalElement * getHierarchicalElement()=0
methods to retrieve the elements linked to this AttributeCarrier
GNENet * getNet() const
get pointer to net
bool isCommonAttributeValid(SumoXMLAttr key, const std::string &value) const
virtual void updateGeometry()=0
update pre-computed geometry information
virtual void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)=0
virtual std::string getAttribute(SumoXMLAttr key) const =0
std::string getCommonAttribute(SumoXMLAttr key) const
static void changeAttribute(GNEAttributeCarrier *AC, SumoXMLAttr key, const std::string &value, GNEUndoList *undoList, const bool force=false)
change attribute
const GNEHierarchicalContainerParents< GNELane * > & getParentLanes() const
get parent lanes
double myMovingLateralOffset
move element lateral offset
GNEAttributeCarrier * myMovedElement
pointer to element
double & myPosOverLane
position over lane
GNEMoveElementLaneSingle(GNEAttributeCarrier *element, SumoXMLAttr posAttr, double &position, bool &friendlyPos, const std::string &defaultBehavior)
constructor
bool & myFriendlyPos
friendly position
bool isMoveElementValid() const
check if current moving element is valid to be written into XML
void removeGeometryPoint(const Position clickedPosition, GNEUndoList *undoList) override
remove geometry point in the clicked position
double getMovingAttributeDouble(SumoXMLAttr key) const override
get moving attribute double
std::string getMovingProblem() const
return a string with the current moving problem
SumoXMLAttr myPosAttr
pos attribute
const std::string myPositionType
default behavior
std::string getMovingAttribute(SumoXMLAttr key) const override
get moving attribute
void setMovingAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList) override
set moving attribute (using undo-list)
bool isMovingAttributeValid(SumoXMLAttr key, const std::string &value) const override
check if the given moving attribute is valid
void writeMoveAttributes(OutputDevice &device) const
write move attributes
void commitMoveShape(const GNEMoveResult &moveResult, GNEUndoList *undoList) override
commit move shape
void setMoveShape(const GNEMoveResult &moveResult) override
set move shape
GNEMoveOperation * getMoveOperation()
get move operation
double getFixedPositionOverLane(const bool adjustGeometryFactor) const
get fixed offset position over lane
Position getMovingAttributePosition(SumoXMLAttr key) const override
get moving attribute position
PositionVector getMovingAttributePositionVector(SumoXMLAttr key) const override
get moving attribute positionVector
void fixMovingProblem()
fix moving problem
bool getAllowChangeLane() const
allow change lane
CommonMoveOptions * getCommonMoveOptions() const
get common mode options
const GNELane * newFirstLane
new first Lane
double newFirstPos
new first position
double lastLaneOffset
lane offset
const GNELane * newLastLane
new last Lane
double firstLaneOffset
lane offset
double newLastPos
new last position
GNELane * retrieveLane(const std::string &id, bool hardFail=true, bool checkVolatileChange=false) const
get lane by id
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:144
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2193
void end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
GNEViewParent * getViewParent() const
get the net object
GNEUndoList * getUndoList() const
get the undoList object
GNEMoveFrame * getMoveFrame() const
get frame for move elements
Static storage of an output device and its base (abstract) implementation.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
A list of positions.