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