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 /****************************************************************************/
10 /// @file    GNEAdditional.h
11 /// @author  Pablo Alvarez Lopez
12 /// @date    Jan 2016
13 /// @version $Id$
14 ///
15 // A abstract class for representation of additional elements
16 /****************************************************************************/
17 #ifndef GNEAdditional_h
18 #define GNEAdditional_h
19 
20 // ===========================================================================
21 // included modules
22 // ===========================================================================
23 
24 #include <config.h>
25 
26 #include <netedit/GNEHierarchicalElementParents.h>
27 #include <netedit/GNEHierarchicalElementChilds.h>
28 #include <utils/common/Parameterised.h>
29 #include <utils/geom/PositionVector.h>
30 #include <utils/gui/globjects/GUIGlObject.h>
31 
32 // ===========================================================================
33 // class declarations
34 // ===========================================================================
35 
36 class GNEViewNet;
37 class GUIGLObjectPopupMenu;
38 
39 // ===========================================================================
40 // class definitions
41 // ===========================================================================
42 
43 /**
44  * @class GNEAdditional
45  * @brief An Element which don't belongs to GNENet but has influency in the simulation
46  */
47 class GNEAdditional : public GUIGlObject, public GNEAttributeCarrier, public Parameterised, public GNEHierarchicalElementParents, public GNEHierarchicalElementChilds  {
48 
49 public:
50 
51     /// @brief struct for pack all variables related with geometry of elemement
52     struct AdditionalGeometry {
53         /// @brief constructor
54         AdditionalGeometry();
55 
56         /// @brief reset geometry
57         void clearGeometry();
58 
59         /// @brief calculate multi shape unified
60         void calculateMultiShapeUnified();
61 
62         /// @brief calculate shape rotations and lenghts
63         void calculateShapeRotationsAndLengths();
64 
65         /// @brief calculate multi shape rotations and lenghts
66         void calculateMultiShapeRotationsAndLengths();
67 
68         /// @brief The shape of the additional element
69         PositionVector shape;
70 
71         /// @brief The multi-shape of the additional element (used by certain additionals)
72         std::vector<PositionVector> multiShape;
73 
74         /// @brief The rotations of the single shape parts
75         std::vector<double> shapeRotations;
76 
77         /// @brief The lengths of the single shape parts
78         std::vector<double> shapeLengths;
79 
80         /// @brief The rotations of the multi-shape parts
81         std::vector<std::vector<double> > multiShapeRotations;
82 
83         /// @brief The lengths of the multi-shape shape parts
84         std::vector<std::vector<double> > multiShapeLengths;
85 
86         /// @brief multi shape unified
87         PositionVector multiShapeUnified;
88     };
89 
90     /**@brief Constructor
91      * @param[in] id Gl-id of the additional element (Must be unique)
92      * @param[in] viewNet pointer to GNEViewNet of this additional element belongs
93      * @param[in] type GUIGlObjectType of additional
94      * @param[in] tag Type of xml tag that define the additional element (SUMO_TAG_BUS_STOP, SUMO_TAG_REROUTER, etc...)
95      * @param[in] name Additional name
96      * @param[in] block movement enable or disable additional movement
97      * @param[in] edgeParents vector of edge parents
98      * @param[in] laneParents vector of lane parents
99      * @param[in] shapeParents vector of shape parents
100      * @param[in] additionalParents vector of additional parents
101      * @param[in] demandElementChilds vector of demandElement parents
102      * @param[in] edgeChilds vector of edge childs
103      * @param[in] laneChilds vector of lane childs
104      * @param[in] shapeChilds vector of shape childs
105      * @param[in] additionalChilds vector of additional childs
106      * @param[in] demandElementChilds vector of demandElement childs
107      */
108     GNEAdditional(const std::string& id, GNEViewNet* viewNet, GUIGlObjectType type, SumoXMLTag tag, std::string additionalName, bool blockMovement,
109                   const std::vector<GNEEdge*>& edgeParents,
110                   const std::vector<GNELane*>& laneParents,
111                   const std::vector<GNEShape*>& shapeParents,
112                   const std::vector<GNEAdditional*>& additionalParents,
113                   const std::vector<GNEDemandElement*>& demandElementParents,
114                   const std::vector<GNEEdge*>& edgeChilds,
115                   const std::vector<GNELane*>& laneChilds,
116                   const std::vector<GNEShape*>& shapeChilds,
117                   const std::vector<GNEAdditional*>& additionalChilds,
118                   const std::vector<GNEDemandElement*>& demandElementChilds);
119 
120     /**@brief Constructor used by Additionals that have two additionals as parent
121      * @param[in] additionalParent pointer to additional parent pointer (used to generate an ID)
122      * @param[in] viewNet pointer to GNEViewNet of this additional element belongs
123      * @param[in] type GUIGlObjectType of additional
124      * @param[in] tag Type of xml tag that define the additional element (SUMO_TAG_BUS_STOP, SUMO_TAG_REROUTER, etc...)
125      * @param[in] name Additional name
126      * @param[in] block movement enable or disable additional movement
127      * @param[in] edgeParents vector of edge parents
128      * @param[in] laneParents vector of lane parents
129      * @param[in] shapeParents vector of shape parents
130      * @param[in] additionalParents vector of additional parents
131      * @param[in] demandElementChilds vector of demandElement parents
132      * @param[in] edgeChilds vector of edge childs
133      * @param[in] laneChilds vector of lane childs
134      * @param[in] shapeChilds vector of shape childs
135      * @param[in] additionalChilds vector of additional childs
136      * @param[in] demandElementChilds vector of demandElement childs
137     */
138     GNEAdditional(GNEAdditional* additionalParent, GNEViewNet* viewNet, GUIGlObjectType type, SumoXMLTag tag, std::string additionalName, bool blockMovement,
139                   const std::vector<GNEEdge*>& edgeParents,
140                   const std::vector<GNELane*>& laneParents,
141                   const std::vector<GNEShape*>& shapeParents,
142                   const std::vector<GNEAdditional*>& additionalParents,
143                   const std::vector<GNEDemandElement*>& demandElementParents,
144                   const std::vector<GNEEdge*>& edgeChilds,
145                   const std::vector<GNELane*>& laneChilds,
146                   const std::vector<GNEShape*>& shapeChilds,
147                   const std::vector<GNEAdditional*>& additionalChilds,
148                   const std::vector<GNEDemandElement*>& demandElementChilds);
149 
150     /// @brief Destructor
151     ~GNEAdditional();
152 
153     /// @brief gererate a new ID for an element child
154     std::string generateChildID(SumoXMLTag childTag);
155 
156     /// @brief obtain AdditionalGeometry
157     const AdditionalGeometry& getAdditionalGeometry() const;
158 
159     /// @name members and functions relative to write additionals into XML
160     /// @{
161     /**@brief writte additional element into a xml file
162      * @param[in] device device in which write parameters of additional element
163      */
164     void writeAdditional(OutputDevice& device) const;
165 
166     /// @brief check if current additional is valid to be writed into XML (by default true, can be reimplemented in childs)
167     virtual bool isAdditionalValid() const;
168 
169     /// @brief return a string with the current additional problem (by default empty, can be reimplemented in childs)
170     virtual std::string getAdditionalProblem() const;
171 
172     /// @brief fix additional problem (by default throw an exception, has to be reimplemented in childs)
173     virtual void fixAdditionalProblem();
174     /// @}
175 
176     /**@brief open Additional Dialog
177      * @note: if additional needs an additional dialog, this function has to be implemented in childrens (see GNERerouter and GNEVariableSpeedSign)
178      * @throw invalid argument if additional doesn't have an additional Dialog
179      */
180     virtual void openAdditionalDialog();
181 
182     /// @name Functions related with geometry of element
183     /// @{
184     /// @brief begin movement (used when user click over additional to start a movement, to avoid problems with problems with GL Tree)
185     void startGeometryMoving();
186 
187     /// @brief begin movement (used when user click over additional to start a movement, to avoid problems with problems with GL Tree)
188     void endGeometryMoving();
189 
190     /**@brief change the position of the element geometry without saving in undoList
191      * @param[in] offset Position used for calculate new position of geometry without updating RTree
192      */
193     virtual void moveGeometry(const Position& offset) = 0;
194 
195     /**@brief commit geometry changes in the attributes of an element after use of moveGeometry(...)
196     * @param[in] undoList The undoList on which to register changes
197     */
198     virtual void commitGeometryMoving(GNEUndoList* undoList) = 0;
199 
200     /// @brief update pre-computed geometry information
201     virtual void updateGeometry(bool updateGrid) = 0;
202 
203     /// @brief Returns position of additional in view
204     virtual Position getPositionInView() const = 0;
205     /// @}
206 
207     /// @brief Returns a pointer to GNEViewNet in which additional element is located
208     GNEViewNet* getViewNet() const;
209 
210     /// @brief Returns additional element's shape
211     PositionVector getShape() const;
212 
213     /// @brief Check if additional item is currently blocked (i.e. cannot be moved with mouse)
214     bool isAdditionalBlocked() const;
215 
216     /// @name inherited from GUIGlObject
217     /// @{
218 
219     /**@brief Returns an own popup-menu
220      *
221      * @param[in] app The application needed to build the popup-menu
222      * @param[in] parent The parent window needed to build the popup-menu
223      * @return The built popup-menu
224      * @see GUIGlObject::getPopUpMenu
225      */
226     GUIGLObjectPopupMenu* getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent);
227 
228     /**@brief Returns an own parameter window
229      *
230      * @param[in] app The application needed to build the parameter window
231      * @param[in] parent The parent window needed to build the parameter window
232      * @return The built parameter window
233      * @see GUIGlObject::getParameterWindow
234      */
235     GUIParameterTableWindow* getParameterWindow(GUIMainWindow& app, GUISUMOAbstractView& parent);
236 
237     /**@brief Returns the boundary to which the view shall be centered in order to show the object
238      * @return The boundary the object is within
239      */
240     Boundary getCenteringBoundary() const;
241 
242     /// @brief Returns the additional name
getOptionalName()243     const std::string getOptionalName() const {
244         return myAdditionalName;
245     }
246 
247     /**@brief Draws the object
248      * @param[in] s The settings for the current view (may influence drawing)
249      * @see GUIGlObject::drawGL
250      */
251     virtual void drawGL(const GUIVisualizationSettings& s) const = 0;
252     /// @}
253 
254     /// @name inherited from GNEAttributeCarrier
255     /// @{
256     /// @brief select attribute carrier using GUIGlobalSelection
257     void selectAttributeCarrier(bool changeFlag = true);
258 
259     /// @brief unselect attribute carrier using GUIGlobalSelection
260     void unselectAttributeCarrier(bool changeFlag = true);
261 
262     /// @brief check if attribute carrier is selected
263     bool isAttributeCarrierSelected() const;
264 
265     /// @brief check if attribute carrier must be drawn using selecting color.
266     bool drawUsingSelectColor() const;
267 
268     /* @brief method for getting the Attribute of an XML key
269      * @param[in] key The attribute key
270      * @return string with the value associated to key
271      */
272     virtual std::string getAttribute(SumoXMLAttr key) const = 0;
273 
274     /**@brief method for setting the attribute and letting the object perform additional changes
275      * @param[in] key The attribute key
276      * @param[in] value The new value
277      * @param[in] undoList The undoList on which to register changes
278      */
279     virtual void setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) = 0;
280 
281     /**@brief method for checking if the key and their conrrespond attribute are valids
282      * @param[in] key The attribute key
283      * @param[in] value The value asociated to key key
284      * @return true if the value is valid, false in other case
285      */
286     virtual bool isValid(SumoXMLAttr key, const std::string& value) = 0;
287 
288     /// @brief get PopPup ID (Used in AC Hierarchy)
289     virtual std::string getPopUpID() const = 0;
290 
291     /// @brief get Hierarchy Name (Used in AC Hierarchy)
292     virtual std::string getHierarchyName() const = 0;
293     /// @}
294 
295     /// @name Functions related with Generic Paramters
296     /// @{
297 
298     /// @brief return generic parameters in string format
299     std::string getGenericParametersStr() const;
300 
301     /// @brief return generic parameters as vector of pairs format
302     std::vector<std::pair<std::string, std::string> > getGenericParameters() const;
303 
304     /// @brief set generic parameters in string format
305     void setGenericParametersStr(const std::string& value);
306 
307     /// @}
308 
309 protected:
310 
311     /// @brief struct for pack all variables related with additional move
312     struct AdditionalMove {
313         /// @brief boundary used during moving of elements (to avoid insertion in RTREE
314         Boundary movingGeometryBoundary;
315 
316         /// @brief value for saving first original position over lane before moving
317         Position originalViewPosition;
318 
319         /// @brief value for saving first original position over lane before moving
320         std::string firstOriginalLanePosition;
321 
322         /// @brief value for saving second original position over lane before moving
323         std::string secondOriginalPosition;
324     };
325 
326     /// @brief struct for pack all variables and functions related with Block Icon
327     struct BlockIcon {
328         /// @brief constructor
329         BlockIcon(GNEAdditional* additional);
330 
331         /// @brief set Rotation of block Icon (must be called in updateGeometry(bool updateGrid) function)
332         void setRotation(GNELane* additionalLane = nullptr);
333 
334         /// @brief draw lock icon
335         void draw(double size = 0.5) const;
336 
337     private:
338         /// @brief pointer to additional parent
339         GNEAdditional* myAdditional;
340 
341     public:
342         /// @brief position of the block icon
343         Position position;
344 
345         /// @brief The offSet of the block icon
346         Position offset;
347 
348         /// @brief The rotation of the block icon
349         double rotation;
350     };
351 
352     /// @brief The GNEViewNet this additional element belongs
353     GNEViewNet* myViewNet;
354 
355     /// @brief geometry to be precomputed in updateGeometry(...)
356     AdditionalGeometry myGeometry;
357 
358     /// @brief variable AdditionalMove
359     AdditionalMove myMove;
360 
361     /// @brief name of additional
362     std::string myAdditionalName;
363 
364     /// @brief boolean to check if additional element is blocked (i.e. cannot be moved with mouse)
365     bool myBlockMovement;
366 
367     /// @brief variable BlockIcon
368     BlockIcon myBlockIcon;
369 
370     /// @brief change all attributes of additional with their default values (note: this cannot be undo)
371     void setDefaultValues();
372 
373     /// @name Functions relative to change values in setAttribute(...)
374     /// @{
375 
376     /// @brief returns Additional ID
377     const std::string& getAdditionalID() const;
378 
379     /// @brief check if a new additional ID is valid
380     bool isValidAdditionalID(const std::string& newID) const;
381 
382     /// @brief check if a new detector ID is valid
383     bool isValidDetectorID(const std::string& newID) const;
384 
385     /**@brief change ID of additional
386     * @throw exception if exist already an additional whith the same ID
387     * @throw exception if ID isn't valid
388     */
389     void changeAdditionalID(const std::string& newID);
390 
391     /// @}
392 
393 private:
394     /**@brief check restriction with the number of childs
395      * @throw ProcessError if itis called without be reimplemented in child class
396      */
397     virtual bool checkAdditionalChildRestriction() const;
398 
399     /// @brief method for setting the attribute and nothing else (used in GNEChange_Attribute)
400     virtual void setAttribute(SumoXMLAttr key, const std::string& value) = 0;
401 
402     /// @brief Invalidated copy constructor.
403     GNEAdditional(const GNEAdditional&) = delete;
404 
405     /// @brief Invalidated assignment operator.
406     GNEAdditional& operator=(const GNEAdditional&) = delete;
407 };
408 
409 #endif
410