1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2002-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    RONet.h
11 /// @author  Daniel Krajzewicz
12 /// @author  Michael Behrisch
13 /// @author  Jakob Erdmann
14 /// @author  Yun-Pang Floetteroed
15 /// @date    Sept 2002
16 /// @version $Id$
17 ///
18 // The router's network representation
19 /****************************************************************************/
20 #ifndef RONet_h
21 #define RONet_h
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #include <config.h>
28 
29 #include <vector>
30 #include <utils/common/MsgHandler.h>
31 #include <utils/common/NamedObjectCont.h>
32 #include <utils/distribution/RandomDistributor.h>
33 #include <utils/vehicle/SUMOVehicleParameter.h>
34 #include <utils/vehicle/SUMOVTypeParameter.h>
35 #include "ROLane.h"
36 #include "RORoutable.h"
37 #include "RORouteDef.h"
38 
39 #ifdef HAVE_FOX
40 #include <utils/foxtools/FXWorkerThread.h>
41 #endif
42 
43 
44 // ===========================================================================
45 // class declarations
46 // ===========================================================================
47 class ROEdge;
48 class RONode;
49 class ROPerson;
50 class ROVehicle;
51 class OptionsCont;
52 class OutputDevice;
53 
54 
55 // ===========================================================================
56 // class definitions
57 // ===========================================================================
58 /**
59  * @class RONet
60  * @brief The router's network representation.
61  *
62  * A router network is responsible for watching loaded edges, nodes,!!!
63  */
64 class RONet {
65 public:
66 
67     typedef std::map<const SUMOTime, std::vector<RORoutable*> > RoutablesMap;
68 
69     /// @brief Constructor
70     RONet();
71 
72 
73     /** @brief Returns the pointer to the unique instance of RONet (singleton).
74      * @return Pointer to the unique RONet-instance
75      */
76     static RONet* getInstance();
77 
78 
79     /// @brief Destructor
80     virtual ~RONet();
81 
82 
83     /** @brief Adds a restriction for an edge type
84      * @param[in] id The id of the type
85      * @param[in] svc The vehicle class the restriction refers to
86      * @param[in] speed The restricted speed
87      */
88     void addRestriction(const std::string& id, const SUMOVehicleClass svc, const double speed);
89 
90 
91     /** @brief Returns the restrictions for an edge type
92      * If no restrictions are present, 0 is returned.
93      * @param[in] id The id of the type
94      * @return The mapping of vehicle classes to maximum speeds
95      */
96     const std::map<SUMOVehicleClass, double>* getRestrictions(const std::string& id) const;
97 
98 
99     /// @name Insertion and retrieval of graph parts
100     //@{
101 
102     /* @brief Adds a read edge to the network
103      *
104      * If the edge is already known (another one with the same id exists),
105      *  an error is generated and given to msg-error-handler. The edge
106      *  is deleted in this case and false is returned.
107      *
108      * @param[in] edge The edge to add
109      * @return Whether the edge was added (if not, it was deleted, too)
110      */
111     virtual bool addEdge(ROEdge* edge);
112 
113 
114     /* @brief Adds a district and connecting edges to the network
115      *
116      * If the district is already known (another one with the same id exists),
117      *  an error is generated and given to msg-error-handler. The edges
118      *  are deleted in this case and false is returned.
119      *
120      * @param[in] id The district to add
121      * @return Whether the district was added
122      */
123     bool addDistrict(const std::string id, ROEdge* source, ROEdge* sink);
124 
125 
126     /* @brief Adds a district and connecting edges to the network
127      *
128      * If the district is already known (another one with the same id exists),
129      *  an error is generated and given to msg-error-handler. The edges
130      *  are deleted in this case and false is returned.
131      *
132      * @param[in] id The district to add
133      * @return Whether the district was added
134      */
135     bool addDistrictEdge(const std::string tazID, const std::string edgeID, const bool isSource);
136 
137     /** @brief Retrieves all TAZ (districts) from the network
138      *
139      * @return The map of all districts
140      */
getDistricts()141     const std::map<std::string, std::pair<std::vector<std::string>, std::vector<std::string> > >& getDistricts() const {
142         return myDistricts;
143     }
144 
145     /** @brief Retrieves an edge from the network
146      *
147      * This is not very pretty, but necessary, though, as routes run
148      *  over instances, not over ids.
149      *
150      * @param[in] name The name of the edge to retrieve
151      * @return The named edge if known, otherwise 0
152      */
getEdge(const std::string & name)153     ROEdge* getEdge(const std::string& name) const {
154         return myEdges.get(name);
155     }
156 
157 
158     /** @brief Retrieves an edge from the network when the lane id is given
159      *
160      * @param[in] laneID The name of the lane to retrieve the edge for
161      * @return The edge of the named lane if known, otherwise 0
162      */
getEdgeForLaneID(const std::string & laneID)163     ROEdge* getEdgeForLaneID(const std::string& laneID) const {
164         return getEdge(laneID.substr(0, laneID.rfind("_")));
165     }
166 
167 
168     /* @brief Adds a read node to the network
169      *
170      * If the node is already known (another one with the same id exists),
171      *  an error is generated and given to msg-error-handler. The node
172      *  is deleted in this case
173      *
174      * @param[in] node The node to add
175      */
176     void addNode(RONode* node);
177 
178 
179     /** @brief Retrieves an node from the network
180      *
181      * @param[in] name The name of the node to retrieve
182      * @return The named node if known, otherwise 0
183      * @todo Check whether a const pointer may be returned
184      */
getNode(const std::string & id)185     RONode* getNode(const std::string& id) const {
186         return myNodes.get(id);
187     }
188 
189 
190     /* @brief Adds a read stopping place (bus, train, container, parking)  to the network
191      *
192      * If the place is already known (another one with the same id and category exists),
193      *  an error is generated and given to msg-error-handler. The stop
194      *  is deleted in this case
195      *
196      * @param[in] id The name of the stop to add
197      * @param[in] category The type of stop
198      * @param[in] stop The detailed stop description
199      */
200     void addStoppingPlace(const std::string& id, const SumoXMLTag category, SUMOVehicleParameter::Stop* stop);
201 
202     /** @brief Retrieves a stopping place from the network
203      *
204      * @param[in] id The name of the stop to retrieve
205      * @param[in] category The type of stop
206      * @return The named stop if known, otherwise 0
207      */
getStoppingPlace(const std::string & id,const SumoXMLTag category)208     const SUMOVehicleParameter::Stop* getStoppingPlace(const std::string& id, const SumoXMLTag category) const {
209         if (myStoppingPlaces.count(category) > 0) {
210             return myStoppingPlaces.find(category)->second.get(id);
211         }
212         return 0;
213     }
214 
215     /// @brief return the name for the given stopping place id
216     const std::string getStoppingPlaceName(const std::string& id) const;
217     //@}
218 
219 
220 
221     /// @name Insertion and retrieval of vehicle types, vehicles, routes, and route definitions
222     //@{
223 
224     /** @brief Checks whether the vehicle type (distribution) may be added
225      *
226      * This method checks also whether the default type may still be replaced
227      * @param[in] id The id of the vehicle type (distribution) to add
228      * @return Whether the type (distribution) may be added
229      */
230     bool checkVType(const std::string& id);
231 
232 
233     /** @brief Adds a read vehicle type definition to the network
234      *
235      * If the vehicle type definition is already known (another one with
236      *  the same id exists), false is returned, and the vehicle type
237      *  is deleted.
238      *
239      * @param[in] def The vehicle type to add
240      * @return Whether the vehicle type could be added
241      */
242     virtual bool addVehicleType(SUMOVTypeParameter* type);
243 
244 
245     /** @brief Adds a vehicle type distribution
246      *
247      * If another vehicle type (or distribution) with the same id exists, false is returned.
248      *  Otherwise, the vehicle type distribution is added to the internal vehicle type distribution
249      *  container "myVTypeDistDict".
250      *
251      * This control get responsible for deletion of the added vehicle
252      *  type distribution.
253      *
254      * @param[in] id The id of the distribution to add
255      * @param[in] vehTypeDistribution The vehicle type distribution to add
256      * @return Whether the vehicle type could be added
257      */
258     bool addVTypeDistribution(const std::string& id, RandomDistributor<SUMOVTypeParameter*>* vehTypeDistribution);
259 
260 
261     /** @brief Retrieves the named vehicle type
262      *
263      * If the name is "" the default type is returned.
264      * If the named vehicle type (or typeDistribution) was not added to the net before
265      * 0 is returned
266      *
267      * @param[in] id The id of the vehicle type to return
268      * @return The named vehicle type
269      * @todo Check whether a const pointer may be returned
270      */
271     SUMOVTypeParameter* getVehicleTypeSecure(const std::string& id);
272 
273 
274     /* @brief Adds a route definition to the network
275      *
276      * If the route definition is already known (another one with
277      *  the same id exists), false is returned, but the route definition
278      *  is not deleted.
279      *
280      * @param[in] def The route definition to add
281      * @return Whether the route definition could be added
282      * @todo Rename myRoutes to myRouteDefinitions
283      */
284     bool addRouteDef(RORouteDef* def);
285 
286 
287     /** @brief Returns the named route definition
288      *
289      * @param[in] name The name of the route definition to retrieve
290      * @return The named route definition if known, otherwise 0
291      * @todo Check whether a const pointer may be returned
292      * @todo Rename myRoutes to myRouteDefinitions
293      */
getRouteDef(const std::string & name)294     RORouteDef* getRouteDef(const std::string& name) const {
295         return myRoutes.get(name);
296     }
297 
298 
299     /* @brief Adds a vehicle to the network
300      *
301      * If the vehicle is already known (another one with the same id
302      *  exists), false is returned, but the vehicle is not deleted.
303      *
304      * Otherwise, the number of loaded routes ("myReadRouteNo") is increased.
305      *
306      * @param[in] id The id of the vehicle to add
307      * @param[in] veh The vehicle to add
308      * @return Whether the vehicle could be added
309      */
310     virtual bool addVehicle(const std::string& id, ROVehicle* veh);
311 
312 
313     /* @brief Adds a flow of vehicles to the network
314      *
315      * If the flow is already known (another one with the same id
316      *  exists), false is returned, but the vehicle parameter are not deleted.
317      *
318      * Otherwise, the number of loaded routes ("myReadRouteNo") is increased.
319      *
320      * @param[in] flow The parameter of the flow to add
321      * @return Whether the flow could be added
322      */
323     bool addFlow(SUMOVehicleParameter* flow, const bool randomize);
324 
325 
326     /* @brief Adds a person to the network
327      *
328      * @param[in] person   The person to add
329      */
330     bool addPerson(ROPerson* person);
331 
332 
333     /* @brief Adds a container to the network
334      *
335      * @param[in] depart The departure time of the container
336      * @param[in] desc   The xml description of the container
337      */
338     void addContainer(const SUMOTime depart, const std::string desc);
339     // @}
340 
341 
342     /// @name Processing stored vehicle definitions
343     //@{
344 
345     /** @brief Computes routes described by their definitions and saves them
346      *
347      * As long as a vehicle with a departure time smaller than the given
348      *  exists, its route is computed and it is written and removed from
349      *  the internal container.
350      *
351      * @param[in] options The options used during this process
352      * @param[in] provider The router provider for routes computation
353      * @param[in] time The time until which route definitions shall be processed
354      * @return The last seen departure time>=time
355      */
356     SUMOTime saveAndRemoveRoutesUntil(OptionsCont& options,
357                                       const RORouterProvider& provider, SUMOTime time);
358 
359 
360     /// Returns the information whether further vehicles, persons or containers are stored
361     bool furtherStored();
362     //@}
363 
364 
365     /** @brief Opens the output for computed routes
366      *
367      * If one of the file outputs can not be build, an IOError is thrown.
368      *
369      * @param[in] options The options to be asked for "output-file", "alternatives-output" and "vtype-output"
370      */
371     void openOutput(const OptionsCont& options);
372 
373 
374     /** @brief Writes the intermodal network and weights if requested
375      *
376      * If one of the file outputs can not be build, an IOError is thrown.
377      *
378      * @param[in] options The options to be asked for "intermodal-network-output" and "intermodal-weight-output"
379      */
380     void writeIntermodal(const OptionsCont& options, ROIntermodalRouter& router) const;
381 
382 
383     /** @brief closes the file output for computed routes and deletes associated threads if necessary */
384     void cleanup();
385 
386 
387     /// Returns the total number of edges the network contains including internal edges
388     int getEdgeNumber() const;
389 
390     /// Returns the number of internal edges the network contains
391     int getInternalEdgeNumber() const;
392 
getEdgeMap()393     const NamedObjectCont<ROEdge*>& getEdgeMap() const {
394         return myEdges;
395     }
396 
397     static void adaptIntermodalRouter(ROIntermodalRouter& router);
398 
399     bool hasPermissions() const;
400 
401     void setPermissionsFound();
402 
403     OutputDevice* getRouteOutput(const bool alternative = false) {
404         if (alternative) {
405             return myRouteAlternativesOutput;
406         }
407         return myRoutesOutput;
408     }
409 
410 #ifdef HAVE_FOX
getThreadPool()411     FXWorkerThread::Pool& getThreadPool() {
412         return myThreadPool;
413     }
414 
415     class WorkerThread : public FXWorkerThread, public RORouterProvider {
416     public:
WorkerThread(FXWorkerThread::Pool & pool,const RORouterProvider & original)417         WorkerThread(FXWorkerThread::Pool& pool,
418                      const RORouterProvider& original)
419             : FXWorkerThread(pool), RORouterProvider(original) {}
~WorkerThread()420         virtual ~WorkerThread() {
421             stop();
422         }
423     };
424 
425     class BulkmodeTask : public FXWorkerThread::Task {
426     public:
BulkmodeTask(const bool value)427         BulkmodeTask(const bool value) : myValue(value) {}
run(FXWorkerThread * context)428         void run(FXWorkerThread* context) {
429             static_cast<WorkerThread*>(context)->getVehicleRouter().setBulkMode(myValue);
430         }
431     private:
432         const bool myValue;
433     private:
434         /// @brief Invalidated assignment operator.
435         BulkmodeTask& operator=(const BulkmodeTask&);
436     };
437 #endif
438 
439 
440 private:
441     void checkFlows(SUMOTime time, MsgHandler* errorHandler);
442 
443     void createBulkRouteRequests(const RORouterProvider& provider, const SUMOTime time, const bool removeLoops);
444 
445 private:
446     /// @brief Unique instance of RONet
447     static RONet* myInstance;
448 
449     /// @brief Known vehicle ids
450     std::set<std::string> myVehIDs;
451 
452     /// @brief Known person ids
453     std::set<std::string> myPersonIDs;
454 
455     /// @brief Known nodes
456     NamedObjectCont<RONode*> myNodes;
457 
458     /// @brief Known edges
459     NamedObjectCont<ROEdge*> myEdges;
460 
461     /// @brief Known bus / train / container stops and parking areas
462     std::map<SumoXMLTag, NamedObjectCont<SUMOVehicleParameter::Stop*> > myStoppingPlaces;
463 
464     /// @brief Known vehicle types
465     NamedObjectCont<SUMOVTypeParameter*> myVehicleTypes;
466 
467     /// @brief Vehicle type distribution dictionary type
468     typedef std::map< std::string, RandomDistributor<SUMOVTypeParameter*>* > VTypeDistDictType;
469     /// @brief A distribution of vehicle types (probability->vehicle type)
470     VTypeDistDictType myVTypeDistDict;
471 
472     /// @brief Whether the default vehicle type was already used or can still be replaced
473     bool myDefaultVTypeMayBeDeleted;
474 
475     /// @brief Whether the default pedestrian type was already used or can still be replaced
476     bool myDefaultPedTypeMayBeDeleted;
477 
478     /// @brief Whether the default bicycle type was already used or can still be replaced
479     bool myDefaultBikeTypeMayBeDeleted;
480 
481     /// @brief Known routes
482     NamedObjectCont<RORouteDef*> myRoutes;
483 
484     /// @brief Known routables
485     RoutablesMap myRoutables;
486 
487     /// @brief Known flows
488     NamedObjectCont<SUMOVehicleParameter*> myFlows;
489 
490     /// @brief whether any flows are still active
491     bool myHaveActiveFlows;
492 
493     /// @brief Known containers
494     typedef std::multimap<const SUMOTime, const std::string> ContainerMap;
495     ContainerMap myContainers;
496 
497     /// @brief vehicles to keep for public transport routing
498     std::vector<const RORoutable*> myPTVehicles;
499 
500     /// @brief Departure times for randomized flows
501     std::map<std::string, std::vector<SUMOTime> > myDepartures;
502 
503     /// @brief traffic assignment zones with sources and sinks
504     std::map<std::string, std::pair<std::vector<std::string>, std::vector<std::string> > > myDistricts;
505 
506     /// @brief The file to write the computed routes into
507     OutputDevice* myRoutesOutput;
508 
509     /// @brief The file to write the computed route alternatives into
510     OutputDevice* myRouteAlternativesOutput;
511 
512     /// @brief The file to write the vehicle types into
513     OutputDevice* myTypesOutput;
514 
515     /// @brief The number of read routes
516     int myReadRouteNo;
517 
518     /// @brief The number of discarded routes
519     int myDiscardedRouteNo;
520 
521     /// @brief The number of written routes
522     int myWrittenRouteNo;
523 
524     /// @brief Whether the network contains edges which not all vehicles may pass
525     bool myHavePermissions;
526 
527     /// @brief The vehicle class specific speed restrictions
528     std::map<std::string, std::map<SUMOVehicleClass, double> > myRestrictions;
529 
530     /// @brief The number of internal edges in the dictionary
531     int myNumInternalEdges;
532 
533     /// @brief handler for ignorable error messages
534     MsgHandler* myErrorHandler;
535 
536     /// @brief whether to keep the the vtype distribution in output
537     const bool myKeepVTypeDist;
538 
539 #ifdef HAVE_FOX
540 private:
541     class RoutingTask : public FXWorkerThread::Task {
542     public:
RoutingTask(RORoutable * v,const bool removeLoops,MsgHandler * errorHandler)543         RoutingTask(RORoutable* v, const bool removeLoops, MsgHandler* errorHandler)
544             : myRoutable(v), myRemoveLoops(removeLoops), myErrorHandler(errorHandler) {}
545         void run(FXWorkerThread* context);
546     private:
547         RORoutable* const myRoutable;
548         const bool myRemoveLoops;
549         MsgHandler* const myErrorHandler;
550     private:
551         /// @brief Invalidated assignment operator.
552         RoutingTask& operator=(const RoutingTask&);
553     };
554 
555 
556 private:
557     /// @brief for multi threaded routing
558     FXWorkerThread::Pool myThreadPool;
559 #endif
560 
561 private:
562     /// @brief Invalidated copy constructor
563     RONet(const RONet& src);
564 
565     /// @brief Invalidated assignment operator
566     RONet& operator=(const RONet& src);
567 
568 };
569 
570 
571 #endif
572 
573 /****************************************************************************/
574 
575