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#include <config.h>
21
24#include <netedit/GNENet.h>
25#include <netedit/GNEUndoList.h>
27
29
30// ===========================================================================
31// static members
32// ===========================================================================
33
34const std::string GNEMoveElementLaneSingle::PositionType::SINGLE = "single";
35const std::string GNEMoveElementLaneSingle::PositionType::STARPOS = TL("lane start");
36const std::string GNEMoveElementLaneSingle::PositionType::ENDPOS = TL("lane end");
37
38// ===========================================================================
39// Method definitions
40// ===========================================================================
41
43 SumoXMLAttr posAttr, double& position, bool& friendlyPos, const std::string& defaultBehavior) :
44 GNEMoveElement(element),
45 myPosAttr(posAttr),
46 myPosOverLane(position),
47 myFriendlyPos(friendlyPos),
48 myPositionType(defaultBehavior) {
49}
50
51
53
54
57 // check if allow change lane is enabled
59 // continue depending if we're moving the start or the end position
62 myMovedElement->getHierarchicalElement()->getParentLanes().back(), myPosOverLane, false, allowChangeLane);
63 } else {
65 myMovedElement->getHierarchicalElement()->getParentLanes().back(), INVALID_DOUBLE, true, allowChangeLane);
66 }
67}
68
69
70std::string
72 if (key == myPosAttr) {
74 return myPositionType;
75 } else {
76 return toString(myPosOverLane);
77 }
78 } else {
79 switch (key) {
80 case SUMO_ATTR_LANE:
81 return myMovedElement->getHierarchicalElement()->getParentLanes().front()->getID();
83 return toString(myFriendlyPos);
84 default:
86 }
87 }
88}
89
90
91double
93 if (key == myPosAttr) {
94 return myPosOverLane;
95 } else {
97 }
98}
99
100
105
106
111
112
113void
115 if (key == myPosAttr) {
117 } else {
118 switch (key) {
119 case SUMO_ATTR_LANE:
122 break;
123 default:
124 myMovedElement->setCommonAttribute(key, value, undoList);
125 break;
126 }
127 }
128}
129
130
131bool
133 if (key == myPosAttr) {
134 if ((myPositionType != PositionType::SINGLE) && (value.empty() || (value == myPositionType))) {
135 return true;
136 } else {
137 return GNEAttributeCarrier::canParse<double>(value);
138 }
139 } else {
140 switch (key) {
141 case SUMO_ATTR_LANE:
142 if (myMovedElement->getNet()->getAttributeCarriers()->retrieveLane(value, false) != nullptr) {
143 return true;
144 } else {
145 return false;
146 }
148 return GNEAttributeCarrier::canParse<bool>(value);
149 default:
150 return myMovedElement->isCommonAttributeValid(key, value);
151 }
152 }
153}
154
155
156void
158 if (key == myPosAttr) {
159 if (value.empty()) {
161 } else if ((value == PositionType::STARPOS) && (myPositionType == PositionType::STARPOS)) {
163 } else if ((value == PositionType::ENDPOS) && (myPositionType == PositionType::ENDPOS)) {
165 } else {
166 myPosOverLane = GNEAttributeCarrier::parse<double>(value);
167 }
168 } else {
169 switch (key) {
171 myFriendlyPos = GNEAttributeCarrier::parse<bool>(value);
172 break;
173 default:
175 break;
176 }
177 }
178}
179
180
181void
182GNEMoveElementLaneSingle::removeGeometryPoint(const Position /*clickedPosition*/, GNEUndoList* /*undoList*/) {
183 // nothing to do here
184}
185
186
187bool
189 // obtain lane final length
190 const double laneLenght = (myPositionType == PositionType::ENDPOS) ? myMovedElement->getHierarchicalElement()->getParentLanes().back()->getParentEdge()->getNBEdge()->getFinalLength() :
191 myMovedElement->getHierarchicalElement()->getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
192 // adjust position (negative means start counting from backward)
193 const double adjustedPosition = (myPosOverLane == INVALID_DOUBLE) ? 0 : (myPosOverLane < 0) ? (myPosOverLane + laneLenght) : myPosOverLane;
194 // check conditions
195 if (myFriendlyPos) {
196 return true;
197 } else if (adjustedPosition < 0) {
198 return false;
199 } else if (adjustedPosition > laneLenght) {
200 return false;
201 } else if ((myPositionType == PositionType::STARPOS) && (adjustedPosition > (laneLenght - POSITION_EPS))) {
202 return false;
203 } else {
204 return true;
205 }
206}
207
208
209std::string
211 // obtain lane final length
212 const double laneLenght = (myPositionType == PositionType::ENDPOS) ? myMovedElement->getHierarchicalElement()->getParentLanes().back()->getParentEdge()->getNBEdge()->getFinalLength() :
213 myMovedElement->getHierarchicalElement()->getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
214 // adjust position (negative means start counting from backward)
215 const double adjustedPosition = (myPosOverLane == INVALID_DOUBLE) ? 0 : (myPosOverLane < 0) ? (myPosOverLane + laneLenght) : myPosOverLane;
216 // check conditions
217 if (myFriendlyPos) {
218 return "";
219 } else if (adjustedPosition < 0) {
220 return TLF("% < 0", toString(myPosAttr));
221 } else if (adjustedPosition > laneLenght) {
222 return TLF("% > length of lane", toString(myPosAttr));
223 } else if ((myPositionType == PositionType::STARPOS) && (adjustedPosition > (laneLenght - POSITION_EPS))) {
224 return TLF("% > (length of lane - EPS)", toString(myPosAttr));
225 } else {
226 return "";
227 }
228}
229
230
231void
233 // obtain lane final length
234 const double laneLenght = myMovedElement->getHierarchicalElement()->getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
235 // adjust position (negative means start counting from backward)
236 const double adjustedPosition = (myPosOverLane == INVALID_DOUBLE) ? 0 : (myPosOverLane < 0) ? (myPosOverLane + laneLenght) : myPosOverLane;
237 // check conditions
238 if (adjustedPosition < 0) {
240 } else if (adjustedPosition > laneLenght) {
242 } else if ((myPositionType == PositionType::STARPOS) && (adjustedPosition > (laneLenght - POSITION_EPS))) {
244 }
245}
246
247
248void
250 // lane
252 // position (don't write if is an invalid double, except in no default)
255 }
256 // friendly position (only if true)
257 if (myFriendlyPos) {
259 }
260}
261
262
263double
264GNEMoveElementLaneSingle::getFixedPositionOverLane(const bool adjustGeometryFactor) const {
265 // get lane depending of type
267 const double laneLength = lane->getParentEdge()->getNBEdge()->getFinalLength();
268 // continue depending if we defined a end position
271 return adjustGeometryFactor ? (laneLength * lane->getLengthGeometryFactor()) : laneLength;
272 } else {
273 return 0;
274 }
275 } else {
276 // fix position
277 double fixedPos = myPosOverLane;
278 // adjust fixedPos
279 if (fixedPos < 0) {
280 fixedPos += laneLength;
281 }
282 // set length geometry factor
283 if (adjustGeometryFactor) {
284 // adjust geometry factor
285 fixedPos *= lane->getLengthGeometryFactor();
286 // return depending of fixedPos
287 if (fixedPos < 0) {
288 return 0;
289 } else if (fixedPos > lane->getLaneShapeLength()) {
290 return lane->getLaneShapeLength();
291 } else {
292 return fixedPos;
293 }
294 } else {
295 // return depending of fixedPos
296 if (fixedPos < 0) {
297 return 0;
298 } else if (fixedPos > laneLength) {
299 return laneLength;
300 } else {
301 return fixedPos;
302 }
303 }
304 }
305}
306
307
308void
311 // change position
312 myPosOverLane = moveResult.newLastPos;
313 // set lateral offset
315 } else {
316 // change position
317 myPosOverLane = moveResult.newFirstPos;
318 // set lateral offset
320 }
321 // update geometry
323}
324
325
326void
328 // reset lateral offset
330 // begin change attribute
331 undoList->begin(myMovedElement, TLF("position of %", myMovedElement->getTagStr()));
332 // set position
335 // check if lane has to be changed
336 if (moveResult.newLastLane && (moveResult.newLastLane != myMovedElement->getHierarchicalElement()->getParentLanes().back())) {
337 // set new lane
339 }
340 } else {
342 // check if lane has to be changed
343 if (moveResult.newFirstLane && (moveResult.newFirstLane != myMovedElement->getHierarchicalElement()->getParentLanes().front())) {
344 // set new lane
346 }
347 }
348 // end change attribute
349 undoList->end();
350}
351
352/****************************************************************************/
#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
double getCommonAttributeDouble(SumoXMLAttr key) const
const std::string getID() const override
get ID (all Attribute Carriers have one)
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
GNEMoveOperation * getMoveOperation() override
get move operation
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
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.