Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 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 NBEdgeCont.h
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Tue, 20 Nov 2001
19 : ///
20 : // Storage for edges, including some functionality operating on multiple edges
21 : /****************************************************************************/
22 : #pragma once
23 : #include <config.h>
24 :
25 : #include <map>
26 : #include <iostream>
27 : #include <string>
28 : #include <vector>
29 : #include <set>
30 : #include "NBCont.h"
31 : #include <utils/common/SUMOVehicleClass.h>
32 : #include <utils/common/UtilExceptions.h>
33 : #include <utils/geom/PositionVector.h>
34 : #include <utils/common/NamedRTree.h>
35 :
36 :
37 : // ===========================================================================
38 : // class declarations
39 : // ===========================================================================
40 : class OptionsCont;
41 : class OutputDevice;
42 : class NBNodeCont;
43 : class NBTypeCont;
44 : class NBEdge;
45 : class NBNode;
46 : class NBDistrictCont;
47 : class NBTrafficLightLogicCont;
48 : class NBPTStopCont;
49 : class NBPTLineCont;
50 :
51 :
52 : // ===========================================================================
53 : // class definitions
54 : // ===========================================================================
55 : /**
56 : * @class NBEdgeCont
57 : * @brief Storage for edges, including some functionality operating on multiple edges
58 : */
59 : class NBEdgeCont {
60 :
61 : public:
62 : /** @brief Constructor
63 : * @param[in] tc The net builded; used to obtain types
64 : */
65 : NBEdgeCont(NBTypeCont& tc);
66 :
67 : /// @brief Destructor
68 : ~NBEdgeCont();
69 :
70 : /** @brief Initialises the storage by applying given options
71 : *
72 : * Options, mainly steering the acceptance of edges, are parsed
73 : * and the according internal variables are set.
74 : *
75 : * @param[in] oc The options container to read options from
76 : * @todo Recheck exceptions
77 : */
78 : void applyOptions(OptionsCont& oc);
79 :
80 : /** @brief Deletes all edges */
81 : void clear();
82 :
83 : /// @name edge access methods
84 : /// @{
85 :
86 : /** @brief Adds an edge to the dictionary
87 : *
88 : * First, it is determined whether the edge shall not be discarded due to any
89 : * reasons (being outside a boundary, or not in the optional list of edges to
90 : * import, etc.). If so, the edge is deleted and "true" is returned.
91 : * "true" is also returned if the edge is accepted - no edge with the same
92 : * name exists within this container. If another edge with the same name
93 : * exists, false is returned.
94 : *
95 : * @param[in] edge The edge to add
96 : * @param[in] ignorePrunning Whether this edge must not be prunned
97 : * @return Whether the edge was valid (no edge with the same id is already known)
98 : */
99 : bool insert(NBEdge* edge, bool ignorePrunning = false);
100 :
101 : /** @brief Returns the edge that has the given id
102 : *
103 : * If no edge that has the given id is known, 0 is returned.
104 : *
105 : * @param[in] id The id of the edge to retrieve
106 : * @param[in] bool Whether extracted edges shall be retrieved as well
107 : * @return The edge with the given id, 0 if no such edge exists
108 : */
109 : NBEdge* retrieve(const std::string& id, bool retrieveExtracted = false) const;
110 :
111 : /** @brief Tries to retrieve an edge, even if it is splitted
112 : *
113 : * The edge given with the id should exist and is followed downstream or upstream,
114 : * depending on the parameter to the last edge still starting with the id.
115 : *
116 : * @param[in] id The id of the edge to retrieve
117 : * @param[in] downstream search direction
118 : * @return The searched edge
119 : * @todo Recheck usage
120 : */
121 : NBEdge* retrievePossiblySplit(const std::string& id, bool downstream) const;
122 :
123 : /** @brief Tries to retrieve an edge, even if it is splitted
124 : *
125 : * To describe which part of the edge shall be returned, the
126 : * id of a second edge, participating at the node and the information
127 : * whether to return the outgoing or the incoming is needed.
128 : *
129 : * @param[in] id The id of the edge to retrieve
130 : * @param[in] hint An additional information which helps to retrieve the correct edge
131 : * @param[in] incoming Whether the edge to find is an incoming edge at the node "hint" participates
132 : * @return The searched edge
133 : * @todo Recheck usage
134 : */
135 : NBEdge* retrievePossiblySplit(const std::string& id, const std::string& hint, bool incoming) const;
136 :
137 : /** @brief Tries to retrieve an edge, even if it is splitted
138 : *
139 : * To describe which part of the edge shall be returned, a
140 : * position hint is supplied.
141 : *
142 : * @param[in] id The id of the edge to retrieve
143 : * @param[in] pos An additional about the position of the basic edge's subpart
144 : * @return The searched edge
145 : * @todo Recheck usage
146 : */
147 : NBEdge* retrievePossiblySplit(const std::string& id, double pos) const;
148 :
149 : /** @brief Removes the given edge from the container (deleting it)
150 : *
151 : * @param[in] dc The district container, in order to remove the edge from sources/sinks
152 : * @param[in] edge The edge to remove
153 : * @todo Recheck whether the district cont is needed - if districts are processed using an external tool
154 : */
155 : void erase(NBDistrictCont& dc, NBEdge* edge);
156 :
157 : /** @brief Removes the given edge from the container like erase but does not
158 : * delete it
159 : *
160 : * @param[in] dc The district container, in order to remove the edge from sources/sinks
161 : * @param[in] edge The edge to remove
162 : * @param[in] remember Whether to keep this edge for future reference
163 : * @todo Recheck whether the district cont is needed - if districts are processed using an external tool
164 : * @todo Recheck whether this is used at all and why
165 : */
166 : void extract(NBDistrictCont& dc, NBEdge* edge, bool remember = false);
167 :
168 : /** @brief Returns the pointer to the begin of the stored edges
169 : * @return The iterator to the beginning of stored edges
170 : */
171 : std::map<std::string, NBEdge*>::const_iterator begin() const {
172 : return myEdges.begin();
173 : }
174 :
175 : /** @brief Returns the pointer to the end of the stored edges
176 : * @return The iterator to the end of stored edges
177 : */
178 : std::map<std::string, NBEdge*>::const_iterator end() const {
179 : return myEdges.end();
180 : }
181 : /// @}
182 :
183 : /// @name explicit edge manipulation methods
184 : /// @{
185 :
186 : /** @struct Split
187 : * @brief A structure which describes changes of lane number or speed along the road
188 : */
189 490 : struct Split {
190 : /// @brief The lanes after this change
191 : std::vector<int> lanes;
192 : /// @brief The position of this change
193 : double pos = INVALID_DOUBLE;
194 : /// @brief The speed after this change
195 : double speed = INVALID_DOUBLE;
196 : /// @brief The friction after this change
197 : double friction = INVALID_DOUBLE;
198 : /// @brief The new node that is created for this split
199 : NBNode* node = nullptr;
200 : /// @brief The id for the edge before the split
201 : std::string idBefore;
202 : /// @brief The id for the edge after the split
203 : std::string idAfter;
204 : /// @brief the default node id
205 : std::string nameID;
206 : /// @brief lateral offset to edge geometry
207 : double offset = 0.;
208 : /// @brief direction in which to apply the offset (used by netgenerate for lefthand networks)
209 : int offsetFactor = 1;
210 : };
211 :
212 : /// @brief process splits
213 : void processSplits(NBEdge* e, std::vector<Split> splits,
214 : NBNodeCont& nc, NBDistrictCont& dc, NBTrafficLightLogicCont& tlc);
215 :
216 : /** @brief Splits the edge at the position nearest to the given node
217 : *
218 : * Uses "splitAt(NBDistrictCont &, NBEdge *, NBNode *, const std::string &, const std::string &, int , int)"
219 : * to perform the split; the edge names are built by appending "[0]" and "[1]",
220 : * respectively. Both edges will have the same number of lanes.
221 : *
222 : * @param[in] dc The district container, in order to remove/add the edge from/to sources/sinks
223 : * @param[in] edge The edge to split
224 : * @param[in] node The node to split the edge at
225 : * @return Whether the edge could be split
226 : * @exception ProcessError If connections between the edges can not be built
227 : * @see NBEdge::splitAt(NBDistrictCont &, NBEdge *, NBNode *, const std::string &, const std::string &, int , int)
228 : */
229 : bool splitAt(NBDistrictCont& dc, NBEdge* edge, NBNode* node);
230 :
231 : /** @brief Splits the edge at the position nearest to the given node using the given modifications
232 : *
233 : * Determines the position of the split by finding the nearest position on the
234 : * edge to the given node. If this position is too near to the edges begin/end,
235 : * false is returned.
236 : *
237 : * Otherwise, "splitAt(NBDistrictCont &, NBEdge *, double, NBNode *, const std::string &, const std::string &, int , int)"
238 : * is used to perform the split.
239 : *
240 : * @param[in] nb The net builder containing all nodes, edges etc.
241 : * @param[in] edge The edge to split
242 : * @param[in] node The node to split the edge at
243 : * @param[in] firstEdgeName The id the first part of the split edge shall have
244 : * @param[in] secondEdgeName The id the second part of the split edge shall have
245 : * @param[in] noLanesFirstEdge The number of lanes the second part of the split edge shall have
246 : * @param[in] noLanesSecondEdge The number of lanes the second part of the split edge shall have
247 : * @param[in] speed The speed for the edge after the split
248 : * @param[in] friction The friction for the edge after the split
249 : * @param[in] changedLeft The number of lanes that is added or removed on the left side of the edge
250 : * (By default all added/removed lanes are assumed to be on the right when computing connections)
251 : * @return Whether the edge could be split
252 : * @exception ProcessError If connections between the edges can not be built
253 : * @see NBEdge::splitAt(NBDistrictCont &, NBEdge *, double, NBNode *, const std::string &, const std::string &, int , int)
254 : */
255 : bool splitAt(NBDistrictCont& dc, NBEdge* edge, NBNode* node,
256 : const std::string& firstEdgeName, const std::string& secondEdgeName,
257 : int noLanesFirstEdge, int noLanesSecondEdge,
258 : const double speed = -1., const double friction = 1., const int changedLeft = 0);
259 :
260 : /** @brief Splits the edge at the position nearest to the given node using the given modifications
261 : *
262 : * @param[in] dc The district container, in order to remove/add the edge from/to sources/sinks
263 : * @param[in] edge The edge to split
264 : * @param[in] node The node to split the edge at
265 : * @param[in] firstEdgeName The id the first part of the split edge shall have
266 : * @param[in] secondEdgeName The id the second part of the split edge shall have
267 : * @param[in] noLanesFirstEdge The number of lanes the second part of the split edge shall have
268 : * @param[in] noLanesSecondEdge The number of lanes the second part of the split edge shall have
269 : * @param[in] speed The speed for the edge after the split
270 : * @param[in] changedLeft The number of lanes that is added or removed on the left side of the edge
271 : * (By default all added/removed lanes are assumed to be on the right when computing connections)
272 : * @return Whether the edge could be split
273 : * @exception ProcessError If connections between the edges can not be built
274 : */
275 : bool splitAt(NBDistrictCont& dc, NBEdge* edge, double edgepos, NBNode* node,
276 : const std::string& firstEdgeName, const std::string& secondEdgeName,
277 : int noLanesFirstEdge, int noLanesSecondEdge,
278 : const double speed = -1., const double friction = 1., const int changedLeft = 0);
279 : /// @}
280 :
281 : /// @name container access methods
282 : /// @{
283 :
284 : /** @brief Returns the number of edges
285 : * @return The number of edges stored in this container
286 : */
287 : int size() const {
288 3626 : return (int) myEdges.size();
289 : }
290 :
291 : /** @brief Returns all ids of known edges
292 : * @return All ids of known edges
293 : * @todo Recheck usage, probably, filling a given vector would be better...
294 : */
295 : std::vector<std::string> getAllNames() const;
296 :
297 : /** @brief Returns the edge split if the edge has been split, nullptr otherwise
298 : * @return the pair of edges after the split
299 : */
300 : const std::pair<NBEdge*, NBEdge*>* getSplit(const NBEdge* const origEdge) const {
301 : const auto& split = myEdgesSplit.find(origEdge);
302 18856 : if (split == myEdgesSplit.end()) {
303 : return nullptr;
304 : }
305 0 : return &split->second;
306 : }
307 :
308 : /** @brief Returns the number of edge splits
309 : * @return How often an edge was split
310 : */
311 : int getNumEdgeSplits() const {
312 3515 : return (int)myEdgesSplit.size();
313 : }
314 : /// @}
315 :
316 : /// @name Adapting the input
317 : /// @{
318 :
319 : /** @brief Removes unwished edges (not in keep-edges)
320 : * @param[in, opt. changed] dc The district container needed to remove edges
321 : * @todo Recheck usage; check whether keep-edges.postload is really useful
322 : * @return The number of removed edges
323 : */
324 : int removeUnwishedEdges(NBDistrictCont& dc);
325 :
326 : /** @brief Splits edges into multiple if they have a complex geometry
327 : *
328 : * Calls "NBEdge::splitGeometry" for all edges within the container which
329 : * have more than three positions in their geometry.
330 : *
331 : * @param[in] nc The node container needed to build (geometry) nodes
332 : * @see NBEdge::splitGeometry
333 : */
334 : void splitGeometry(NBDistrictCont& dc, NBNodeCont& nc);
335 :
336 : /** @brief
337 : * @param[in] nc The node container needed to build (geometry) nodes
338 : * @see NBEdge::reduceGeometry
339 : */
340 : void reduceGeometries(const double minDist);
341 :
342 : /** @brief
343 : * @param[in] maxAngle The maximum geometry angle allowed
344 : * @param[in] minRadius The minimum turning radius allowed at the start and end
345 : * @param[in] fix Whether to prune geometry points to avoid sharp turns at start and end
346 : * @see NBEdge::checkGeometry
347 : */
348 : void checkGeometries(const double maxAngle, bool fixAngle, const double minRadius, bool fix, bool fixRailways, bool silent = false);
349 : /// @}
350 :
351 : /// @name processing methods
352 : /// @{
353 :
354 : /** @brief Sorts all lanes of all edges within the container by their direction
355 : *
356 : * Calls "NBEdge::sortOutgoingLanesConnections" for all edges within the container.
357 : *
358 : * @todo Recheck whether a visitor-pattern should be used herefor
359 : * @see NBEdge::sortOutgoingLanesConnections
360 : */
361 : void sortOutgoingLanesConnections();
362 :
363 : /** @brief Computes for each edge the approached edges
364 : *
365 : * Calls "NBEdge::computeEdge2Edges" for all edges within the container.
366 : *
367 : * @param[in] noLeftMovers Whether left-moving connections shall be omitted
368 : * @todo Recheck whether a visitor-pattern should be used herefor
369 : * @see NBEdge::computeEdge2Edges
370 : */
371 : void computeEdge2Edges(bool noLeftMovers);
372 :
373 : /** @brief Computes for each edge which lanes approach the next edges
374 : *
375 : * Calls "NBEdge::computeLanes2Edges" for all edges within the container.
376 : *
377 : * @todo Recheck whether a visitor-pattern should be used herefor
378 : * @see NBEdge::computeLanes2Edges
379 : */
380 : void computeLanes2Edges();
381 :
382 : /** @brief Rechecks whether all lanes have a successor for each of the stored edges
383 : *
384 : * Calls "NBEdge::recheckLanes" for all edges within the container.
385 : *
386 : * @todo Recheck whether a visitor-pattern should be used herefor
387 : * @see NBEdge::recheckLanes
388 : */
389 : void recheckLanes();
390 :
391 : /** @brief Appends turnarounds to all edges stored in the container
392 : *
393 : * Calls "NBEdge::appendTurnaround" for all edges within the container.
394 : *
395 : * @param[in] noTLSControlled Whether the turnaround shall not be connected if the edge is controlled by a tls
396 : * @param[in] noFringe Whether the turnaround shall not be connected if the junction is at the (outer) fringe
397 : * @param[in] onlyDeadends Whether the turnaround shall only be built at deadends
398 : * @param[in] onlyTurnlane Whether the turnaround shall only be built when there is an exclusive (left) turn lane
399 : * @param[in] noGeometryLike Whether the turnaround shall be built at geometry-like nodes
400 : * @see NBEdge::appendTurnaround
401 : */
402 : void appendTurnarounds(bool noTLSControlled, bool noFringe, bool onlyDeadends, bool onlyTurnlane, bool noGeometryLike);
403 :
404 : /** @brief Appends turnarounds to all edges stored in the container
405 : * Calls "NBEdge::appendTurnaround" for edges with the given ids
406 : * @param[in] ids The list of ids for which to append a turnaround
407 : * @param[in] noTLSControlled Whether the turnaround shall not be connected if the edge is controlled by a tls
408 : * @see NBEdge::appendTurnaround
409 : */
410 : void appendTurnarounds(const std::set<std::string>& ids, bool noTLSControlled);
411 :
412 : /// @brief Appends turnarounds to all bidiRail edges with stops
413 : void appendRailwayTurnarounds(const NBPTStopCont& sc);
414 :
415 : /** @brief Computes the shapes of all edges stored in the container
416 : *
417 : * Calls "NBEdge::computeEdgeShape" for all edges within the container.
418 : *
419 : * @todo Recheck whether a visitor-pattern should be used herefor
420 : * @todo Recheck usage
421 : * @see NBEdge::computeEdgeShape
422 : */
423 : void computeEdgeShapes(double smoothElevationThreshold = -1);
424 :
425 : /** @brief Computes the shapes of all lanes of all edges stored in the container
426 : *
427 : * Calls "NBEdge::computeLaneShapes" for all edges within the container.
428 : *
429 : * @todo Recheck whether a visitor-pattern should be used herefor
430 : * @todo Recheck usage
431 : * @see NBEdge::computeLaneShapes
432 : */
433 : void computeLaneShapes();
434 :
435 : /// @brief Clears information about controlling traffic lights for all connenections of all edges
436 : void clearControllingTLInformation() const;
437 :
438 : /** @brief Joins the given edges because they connect the same nodes
439 : *
440 : * @param[in] dc The district container needed to remove edges
441 : * @param[in] tlc The tls container needed to remove edges
442 : * @param[in] edges The edges to join
443 : * @todo Recheck and describe usage
444 : */
445 : void joinSameNodeConnectingEdges(NBDistrictCont& dc,
446 : NBTrafficLightLogicCont& tlc, EdgeVector edges);
447 :
448 : /// @brief Sets opposite lane information for geometrically close edges
449 : void guessOpposites();
450 :
451 : /** @brief Rechecks whether the lane spread is proper
452 : *
453 : * @todo Recheck usage; check whether this is really needed and whether it works at all
454 : */
455 : void recheckLaneSpread();
456 :
457 : /// @}
458 :
459 : /// @brief Returns the edge with negated id if it exists
460 : NBEdge* getOppositeByID(const std::string& edgeID) const;
461 :
462 : /// @brief Returns the edge with id if it exists
463 : NBEdge* getByID(const std::string& edgeID) const;
464 :
465 : /** @brief Determines which edges belong to roundabouts and increases their priority
466 : * @return The number of guessed roundabouts
467 : */
468 : int guessRoundabouts();
469 :
470 : /** @brief Determines which edges have been marked as roundabouts and stores them internally
471 : * @return The number of found roundabouts
472 : */
473 : int extractRoundabouts();
474 :
475 : // brief ensure myRoundabouts only holds valid edges
476 : void cleanupRoundabouts();
477 :
478 : /** @brief Returns whether the edge with the id was ignored during parsing
479 : * @return Whether the edge with the id was ignored during parsing
480 : */
481 : bool wasIgnored(std::string id) const {
482 : return myIgnoredEdges.count(id) != 0;
483 : }
484 :
485 : /// @brief mark the given edge id as ignored
486 : void ignore(std::string id) {
487 : myIgnoredEdges.insert(id);
488 10 : }
489 :
490 : /// @brief Returns whether the edge with the id was deleted explicitly
491 : bool wasRemoved(std::string id) const {
492 : return myExtractedEdges.count(id) != 0;
493 : }
494 :
495 : /// @brief Renames the edge. Throws exception if newID already exists
496 : void rename(NBEdge* edge, const std::string& newID);
497 :
498 : /// @name Connections handling
499 : /// @{
500 :
501 : /** @brief Adds a connection which could not be set during loading
502 : * @param[in] from The id of the edge the connection starts at
503 : * @param[in] fromLane The number of the lane the connection starts at
504 : * @param[in] to The id of the edge the connection ends at
505 : * @param[in] toLane The number of the lane the connection ends at
506 : * @param[in] mayDefinitelyPass Whether the connection may be passed without braking
507 : * @param[in] keepClear Whether the connection must check to keep the junction clear
508 : * @param[in] contPos Custom position for internal junction
509 : * @param[in] visibility Custom foe visiblity connection
510 : * @param[in] speed Custom speed
511 : * @param[in] friction Custom friction
512 : * @param[in] customShape Custom shape
513 : * @param[in] warnOnly Whether a failure to set this connection should only result in a warning
514 : */
515 : void addPostProcessConnection(const std::string& from, int fromLane, const std::string& to, int toLane, bool mayDefinitelyPass,
516 : KeepClear keepClear, double contPos, double visibility,
517 : double speed, double friction, double length,
518 : const PositionVector& customShape,
519 : bool uncontrolled,
520 : bool warnOnly,
521 : SVCPermissions permissions = SVC_UNSPECIFIED,
522 : bool indirectLeft = false,
523 : const std::string& edgeType = "",
524 : SVCPermissions changeLeft = SVC_UNSPECIFIED,
525 : SVCPermissions changeRight = SVC_UNSPECIFIED);
526 :
527 : /// @brief add post process connections
528 : bool hasPostProcessConnection(const std::string& from, const std::string& to = "");
529 :
530 : /// @brief Try to set any stored connections
531 : void recheckPostProcessConnections();
532 : /// @}
533 :
534 : /// @brief assigns street signs to edges based on toNode types
535 : void generateStreetSigns();
536 :
537 : /// @brief add sidwalks to edges within the given limits or permissions and return the number of edges affected
538 : int guessSpecialLanes(SUMOVehicleClass svc, double width, double minSpeed, double maxSpeed, bool fromPermissions, const std::string& excludeOpt,
539 : NBTrafficLightLogicCont& tlc);
540 :
541 : /** @brief Returns the determined roundabouts
542 : * @return The list of roundabout edges
543 : */
544 : const std::set<EdgeSet> getRoundabouts() const;
545 :
546 : /// @brief check if there is guessed roundabouts
547 : bool hasGuessedRoundabouts() const {
548 : return myGuessedRoundabouts.size() > 0;
549 : }
550 :
551 : /// @brief add user specified roundabout
552 : void addRoundabout(const EdgeSet& roundabout);
553 :
554 : /// @brief remove roundabout that contains the given node
555 : void removeRoundabout(const NBNode* node);
556 : /// @brief remove edges from all stored roundabouts
557 : void removeRoundaboutEdges(const EdgeSet& toRemove);
558 :
559 : /// @brief mark edge priorities and prohibit turn-arounds for all roundabout edges
560 : void markRoundabouts();
561 :
562 : /// @brief fix roundabout information after splitting an edge
563 : void patchRoundabouts(NBEdge* orig, NBEdge* part1, NBEdge* part2, std::set<EdgeSet>& roundabouts);
564 :
565 : /// @brief Returns true if this edge matches one of the removal criteria
566 : bool ignoreFilterMatch(NBEdge* edge);
567 :
568 : /// @brief remap node IDs accoring to options --numerical-ids and --reserved-ids
569 : int remapIDs(bool numericaIDs, bool reservedIDs, const std::string& prefix, NBPTStopCont& sc);
570 :
571 : /// @brief check whether edges overlap
572 : void checkOverlap(double threshold, double zThreshold) const;
573 :
574 : /// @brief check whether edges are to steep
575 : void checkGrade(double threshold) const;
576 :
577 : /** @brief Returns the edges which have been built by splitting the edge of the given id
578 : *
579 : * @param[in] id The id of the original edge
580 : * @return List of all edges which have been built by splitting the original edge
581 : * @todo Recheck usage
582 : */
583 : EdgeVector getGeneratedFrom(const std::string& id) const;
584 :
585 : /// @brief join adjacent lanes with the given permissions
586 : int joinLanes(SVCPermissions perms);
587 :
588 : /// @brief join tram edges into adjacent lanes
589 : int joinTramEdges(NBDistrictCont& dc, NBPTStopCont& sc, NBPTLineCont& lc, double maxDist);
590 :
591 : /// @brief return all edges
592 : EdgeVector getAllEdges() const;
593 :
594 : /// @brief return all router edges
595 : RouterEdgeVector getAllRouterEdges() const;
596 :
597 : /// @brief ensure that all edges have valid nodes
598 : bool checkConsistency(const NBNodeCont& nc);
599 :
600 : /// @brief modify all restrictions on lane changing for edges and connections
601 : void updateAllChangeRestrictions(SVCPermissions ignoring);
602 :
603 : /// @brief add prefix to all edges
604 : void addPrefix(const std::string& prefix);
605 :
606 : /// @brief adapt custom lengths of split edges to account for intersection size
607 : void fixSplitCustomLength();
608 :
609 : /// @brief compute all edge angles
610 : void computeAngles();
611 :
612 : /// @brief return all edge types in used
613 : std::set<std::string> getUsedTypes() const;
614 :
615 : /// @brief return number of edges removed
616 : int removeEdgesBySpeed(NBDistrictCont& dc);
617 : int removeEdgesByPermissions(NBDistrictCont& dc);
618 : int removeLanesByWidth(NBDistrictCont& dc, const double minWidth);
619 :
620 : private:
621 : /// @brief compute the form factor for a loop of edges
622 : static double formFactor(const EdgeVector& loopEdges);
623 :
624 : /// @brief remove roundabout edges
625 : void removeRoundaboutEdges(const EdgeSet& toRemove, std::set<EdgeSet>& roundabouts);
626 :
627 : /// @brief The network builder; used to obtain type information
628 : NBTypeCont& myTypeCont;
629 :
630 : /** @struct PostProcessConnection
631 : * @brief A structure representing a connection between two lanes
632 : */
633 : struct PostProcessConnection {
634 :
635 : public:
636 : /** @brief Constructor
637 : * @param[in] from The id of the edge the connection starts at
638 : * @param[in] fromLane The number of the lane the connection starts at
639 : * @param[in] to The id of the edge the connection ends at
640 : * @param[in] toLane The number of the lane the connection ends at
641 : * @param[in] mayDefinitelyPass Whether the connection may be passed without braking
642 : */
643 18 : PostProcessConnection(const std::string& from_, int fromLane_, const std::string& to_, int toLane_,
644 : bool mayDefinitelyPass_, KeepClear keepClear_, double contPos_, double visibility_, double speed_,
645 : double friction_, double length_,
646 : const PositionVector& customShape_,
647 : bool uncontrolled_,
648 : bool warnOnly_,
649 : SVCPermissions permissions_,
650 : bool indirectLeft_,
651 : const std::string& edgeType_,
652 : SVCPermissions changeLeft_,
653 18 : SVCPermissions changeRight_) :
654 18 : from(from_), fromLane(fromLane_), to(to_), toLane(toLane_), mayDefinitelyPass(mayDefinitelyPass_), keepClear(keepClear_), contPos(contPos_),
655 18 : visibility(visibility_),
656 18 : speed(speed_),
657 18 : friction(friction_),
658 18 : customLength(length_),
659 : customShape(customShape_),
660 18 : uncontrolled(uncontrolled_),
661 18 : permissions(permissions_),
662 18 : indirectLeft(indirectLeft_),
663 18 : edgeType(edgeType_),
664 18 : changeLeft(changeLeft_),
665 18 : changeRight(changeRight_),
666 18 : warnOnly(warnOnly_)
667 18 : {}
668 :
669 : /// @brief The id of the edge the connection starts at
670 : std::string from;
671 :
672 : /// @brief The number of the lane the connection starts at
673 : int fromLane;
674 :
675 : /// @brief The id of the edge the connection ends at
676 : std::string to;
677 :
678 : /// @brief The number of the lane the connection ends at
679 : int toLane;
680 :
681 : /// @brief Whether the connection may be passed without braking
682 : bool mayDefinitelyPass;
683 :
684 : /// @brief Whether the connection may be passed without braking
685 : KeepClear keepClear;
686 :
687 : /// @brief custom position for internal junction on this connection
688 : double contPos;
689 :
690 : /// @brief custom foe visiblity for connection
691 : double visibility;
692 :
693 : /// @brief custom speed for connection
694 : double speed;
695 :
696 : /// @brief custom friction for connection
697 : double friction;
698 :
699 : /// @brief custom length for connection
700 : double customLength;
701 :
702 : /// @brief custom shape for connection
703 : PositionVector customShape;
704 :
705 : /// @brief whether this connection shall not be controlled by a traffic light
706 : bool uncontrolled;
707 :
708 : /// @brief custom permissions for connection
709 : SVCPermissions permissions;
710 :
711 : /// @brief whether this connection is an indirect left turn
712 : bool indirectLeft;
713 :
714 : /// @brief custom edge type
715 : std::string edgeType;
716 :
717 : /// @brief custom lane changing permissions for connection
718 : SVCPermissions changeLeft;
719 :
720 : /// @brief custom lane changing permissions for connection
721 : SVCPermissions changeRight;
722 :
723 : /// @brief whether a failure to set this connection is a warning or an error
724 : bool warnOnly;
725 : };
726 :
727 : struct MinLaneComparatorIdLess {
728 : bool operator()(const std::pair<NBEdge*, int>& a, const std::pair<NBEdge*, int>& b) const;
729 : };
730 :
731 : /// @brief The list of connections to recheck
732 : std::map<std::string, std::vector<PostProcessConnection> > myConnections;
733 :
734 : /// @brief The type of the dictionary where an edge may be found by its id
735 : typedef std::map<std::string, NBEdge*> EdgeCont;
736 :
737 : /// @brief The instance of the dictionary (id->edge)
738 : EdgeCont myEdges;
739 :
740 : /// @brief The extracted edges which are kept for reference
741 : EdgeCont myExtractedEdges;
742 :
743 : /// @brief The edges which got extracted twice but may still be referenced somewhere TODO smart_ptr?
744 : std::set<NBEdge*> myEdgeCemetery;
745 :
746 : /// @brief The ids of ignored edges
747 : std::set<std::string> myIgnoredEdges;
748 :
749 : /// @brief the number of splits of edges during the building
750 : std::map<const NBEdge*, std::pair<NBEdge*, NBEdge*> > myEdgesSplit;
751 : /// @brief the edges that were created as result of splitting
752 : std::set<const NBEdge*> myWasSplit;
753 :
754 : /// @name Settings for accepting/dismissing edges
755 : /// @{
756 :
757 : /// @brief The minimum speed an edge may have in order to be kept (default: -1)
758 : double myEdgesMinSpeed;
759 :
760 : /// @brief Whether edges shall be joined and patched first, then removed
761 : bool myRemoveEdgesAfterLoading;
762 :
763 : /// @brief Set of ids of edges which shall explicitly be kept
764 : std::set<std::string> myEdges2Keep;
765 :
766 : /// @brief Set of ids of edges which shall explicitly be removed
767 : std::set<std::string> myEdges2Remove;
768 :
769 : /// @brief Set of vehicle types which must be allowed on edges in order to keep them
770 : SVCPermissions myVehicleClasses2Keep;
771 :
772 : /// @brief Set of vehicle types which need not be supported (edges which allow ONLY these are removed)
773 : SVCPermissions myVehicleClasses2Remove;
774 :
775 : /// @brief Set of edges types which shall be kept
776 : std::set<std::string> myTypes2Keep;
777 :
778 : /// @brief Set of edges types which shall be removed
779 : std::set<std::string> myTypes2Remove;
780 :
781 : /// @brief Boundary within which an edge must be located in order to be kept
782 : PositionVector myPruningBoundary;
783 :
784 : /// @brief whether a geo transform has been applied to the pruning boundary
785 : bool myNeedGeoTransformedPruningBoundary;
786 : /// @}
787 :
788 : /// @brief Edges marked as belonging to a roundabout by the user (each EdgeVector is a roundabout)
789 : std::set<EdgeSet> myRoundabouts;
790 :
791 : /// @brief Edges marked as belonging to a roundabout after guessing
792 : std::set<EdgeSet> myGuessedRoundabouts;
793 :
794 : /** @class split_sorter
795 : * @brief Sorts splits by their position (increasing)
796 : */
797 : class split_sorter {
798 : public:
799 : /// @brief Constructor
800 : explicit split_sorter() { }
801 :
802 : /// @brief Comparing operator
803 : int operator()(const Split& e1, const Split& e2) const {
804 154 : return e1.pos < e2.pos;
805 : }
806 : };
807 :
808 : /// @brief invalidated copy constructor
809 : NBEdgeCont(const NBEdgeCont& s) = delete;
810 :
811 : /// @brief invalidated assignment operator
812 : NBEdgeCont& operator=(const NBEdgeCont& s) = delete;
813 : };
|