/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file GNEMoveElement.h14/// @author Pablo Alvarez Lopez15/// @date Mar 202016///17// Class used for elements that own a movable shape18/****************************************************************************/19#pragma once20#include <config.h>2122#include <utils/gui/div/GUIGeometry.h>2324// ===========================================================================25// class declaration26// ===========================================================================2728class GNELane;29class GNEMoveElement;30class GNEUndoList;31class GNEViewNet;32class GUIGlObject;3334// ===========================================================================35// class definitions36// ===========================================================================3738/// @brief move operation39class GNEMoveOperation {4041public:42enum class OperationType {43POSITION,44ENTIRE_SHAPE,45GEOMETRY_POINTS,46WIDTH,47HEIGHT,48LENGTH,49SINGLE_LANE,50SINGLE_LANE_MOVE_FIRST,51SINGLE_LANE_MOVE_LAST,52SINGLE_LANE_MOVE_BOTH,53MULTIPLE_LANES_MOVE_FIRST,54MULTIPLE_LANES_MOVE_LAST,55MULTIPLE_LANES_MOVE_BOTH_FIRST,56MULTIPLE_LANES_MOVE_BOTH_LAST57};5859/// @brief constructor for values with a single position (junctions, E3, ParkingSpaces...)60GNEMoveOperation(GNEMoveElement* moveElement,61const Position originalPosition);6263/// @brief constructor for entire geometries (Polygon with blocked shapes)64GNEMoveOperation(GNEMoveElement* moveElement,65const PositionVector originalShape);6667/// @brief constructor for entire geometries (Polygon with blocked shapes)68GNEMoveOperation(GNEMoveElement* moveElement,69const PositionVector originalShape,70const bool firstGeometryPoint,71const OperationType operationType);7273/// @brief constructor for elements with editable shapes (edges, polygons...)74GNEMoveOperation(GNEMoveElement* moveElement,75const PositionVector originalShape,76const std::vector<int> originalgeometryPoints,77const PositionVector shapeToMove,78const std::vector<int> geometryPointsToMove);7980/// @brief constructor for elements placed over lanes with one position (detectors, vehicles...)81GNEMoveOperation(GNEMoveElement* moveElement,82const GNELane* lane,83const double firstPosition,84const bool allowChangeLane);8586/// @brief constructor for elements placed over same lanes with two positions (StoppingPlaces)87GNEMoveOperation(GNEMoveElement* moveElement,88const GNELane* lane,89const double firstPosition,90const double lastPosition,91const bool allowChangeLane,92const OperationType operationType);9394/// @brief constructor for elements placed over two lanes with two positions (E2 Multilane, vehicles..)95GNEMoveOperation(GNEMoveElement* moveElement,96const GNELane* firstLane,97const double firstStartPos,98const GNELane* lastLane,99const double lastStartPos,100const bool allowChangeLane,101const OperationType operationType);102103/// @brief destructor104~GNEMoveOperation();105106/// @brief move element107GNEMoveElement* moveElement;108109/// @brief original shape110const PositionVector originalShape;111112/// @brief original shape points to move (of original shape)113const std::vector<int> originalGeometryPoints;114115/// @brief original first lane116const GNELane* firstLane = nullptr;117118/// @brief original first Position119const double firstPosition = INVALID_DOUBLE;120121/// @brief original last lane122const GNELane* lastLane = nullptr;123124/// @brief original last Position125const double lastPosition = INVALID_DOUBLE;126127/**@brief shape to move128* @note: it can be different of originalShape, for example due a new geometry point129*/130const PositionVector shapeToMove;131132/// @brief shape points to move (of shapeToMove)133const std::vector<int> geometryPointsToMove;134135/// @brief allow change lane136const bool allowChangeLane;137138/// @brief first position (used for edit with/height139const bool firstGeometryPoint;140141/// @brief operation type142const OperationType operationType;143144private:145/// @brief Invalidated copy constructor.146GNEMoveOperation(const GNEMoveOperation&) = delete;147148/// @brief Invalidated assignment operator.149GNEMoveOperation& operator=(const GNEMoveOperation&) = delete;150};151152/// @brief move offset153class GNEMoveOffset {154155public:156/// @brief constructor157GNEMoveOffset();158159/// @brief constructor for X-Y move160GNEMoveOffset(const double x, const double y);161162/// @brief constructor for Z move163GNEMoveOffset(const double z);164165/// @brief destructor166~GNEMoveOffset();167168/// @brief X169const double x;170171/// @brief Y172const double y;173174/// @brief Z175const double z;176};177178/// @brief move result179class GNEMoveResult {180181public:182/// @brief constructor183GNEMoveResult(const GNEMoveOperation* moveOperation);184185/// @brief destructor186~GNEMoveResult();187188/// @brief clear lanes189void clearLanes();190191/// @brief shape to update (edited in moveElement)192PositionVector shapeToUpdate;193194/// @brief shape points to move (of shapeToMove)195std::vector<int> geometryPointsToMove;196197/// @brief move operation198const GNEMoveOperation::OperationType operationType;199200/// @brief lane offset201double firstLaneOffset;202203/// @brief new first Lane204const GNELane* newFirstLane;205206/// @brief new first position207double newFirstPos;208209/// @brief lane offset210double lastLaneOffset;211212/// @brief new last Lane213const GNELane* newLastLane;214215/// @brief new last position216double newLastPos;217218private:219/// @brief Invalidated copy constructor.220GNEMoveResult(const GNEMoveResult&) = delete;221};222223224/// @brief move element225class GNEMoveElement {226227public:228/// @brief constructor229GNEMoveElement();230231//// @brief empty destructor232virtual ~GNEMoveElement() {}233234/**@brief get move operation235* @note returned GNEMoveOperation can be nullptr236*/237virtual GNEMoveOperation* getMoveOperation() = 0;238239/// @brief remove geometry point in the clicked position240virtual void removeGeometryPoint(const Position clickedPosition, GNEUndoList* undoList) = 0;241242/// @brief move element the for given offset (note: offset can be X-Y-0, 0-0-Z or X-Y-Z)243static void moveElement(const GNEViewNet* viewNet, GNEMoveOperation* moveOperation, const GNEMoveOffset& offset);244245/// @brief commit move element for the given offset246static void commitMove(const GNEViewNet* viewNet, GNEMoveOperation* moveOperation, const GNEMoveOffset& offset, GNEUndoList* undoList);247248protected:249/// @brief move element lateral offset (used by elements placed over lanes250double myMoveElementLateralOffset;251252/// @brief calculate move shape operation253GNEMoveOperation* calculateMoveShapeOperation(const GUIGlObject* obj, const PositionVector originalShape, const bool maintainShapeClosed);254255private:256/// @brief set move shape257virtual void setMoveShape(const GNEMoveResult& moveResult) = 0;258259/// @brief commit move shape260virtual void commitMoveShape(const GNEMoveResult& moveResult, GNEUndoList* undoList) = 0;261262/// @brief calculate lane offset263static double calculateLaneOffset(const GNEViewNet* viewNet, const GNELane* lane, const double firstPosition, const double lastPosition,264const GNEMoveOffset& offset, const double extremFrom, const double extremTo);265266/// @brief calculate single movement over one lane267static void calculateMoveResult(GNEMoveResult& moveResult, const GNEViewNet* viewNet, const GNELane* lane, const double pos,268const GNEMoveOffset& offset, const double extremFrom, const double extremTo);269270/// @brief calculate double movement over one lane271static void calculateMoveResult(GNEMoveResult& moveResult, const GNEViewNet* viewNet, const GNELane* lane, const double firstPos,272const double lastPos, const GNEMoveOffset& offset);273274/// @brief calculate double movement over two lanes275static void calculateMoveResult(GNEMoveResult& moveResult, const GNEViewNet* viewNet, const GNELane* firstLane, const double firstPos,276const GNELane* lastLane, const double lastPos, const GNEMoveOffset& offset);277278/// @brief calculate new lane change279static void calculateNewLaneChange(const GNEViewNet* viewNet, const GNELane* originalLane, const GNELane*& newLane, double& laneOffset);280281/// @brief calculate width/height shape282static PositionVector calculateExtrapolatedVector(const GNEMoveOperation* moveOperation, const GNEMoveResult& moveResult);283284/// @brief Invalidated copy constructor.285GNEMoveElement(const GNEMoveElement&) = delete;286287/// @brief Invalidated assignment operator.288GNEMoveElement& operator=(const GNEMoveElement&) = delete;289};290291292