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