Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-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 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 513 : 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 3863 : 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 19281 : if (split == myEdgesSplit.end()) {
303 : return nullptr;
304 : }
305 5 : return &split->second;
306 : }
307 :
308 : NBEdge* getSplitBase(const std::string& edgeID) const;
309 :
310 : /** @brief Returns the number of edge splits
311 : * @return How often an edge was split
312 : */
313 : int getNumEdgeSplits() const {
314 3758 : return (int)myEdgesSplit.size();
315 : }
316 : /// @}
317 :
318 : /// @name Adapting the input
319 : /// @{
320 :
321 : /** @brief Removes unwished edges (not in keep-edges)
322 : * @param[in, opt. changed] dc The district container needed to remove edges
323 : * @todo Recheck usage; check whether keep-edges.postload is really useful
324 : * @return The number of removed edges
325 : */
326 : int removeUnwishedEdges(NBDistrictCont& dc);
327 :
328 : /** @brief Splits edges into multiple if they have a complex geometry
329 : *
330 : * Calls "NBEdge::splitGeometry" for all edges within the container which
331 : * have more than three positions in their geometry.
332 : *
333 : * @param[in] nc The node container needed to build (geometry) nodes
334 : * @see NBEdge::splitGeometry
335 : */
336 : void splitGeometry(NBDistrictCont& dc, NBNodeCont& nc);
337 :
338 : /** @brief
339 : * @param[in] nc The node container needed to build (geometry) nodes
340 : * @see NBEdge::reduceGeometry
341 : */
342 : void reduceGeometries(const double minDist);
343 :
344 : /** @brief
345 : * @param[in] maxAngle The maximum geometry angle allowed
346 : * @param[in] minRadius The minimum turning radius allowed at the start and end
347 : * @param[in] fix Whether to prune geometry points to avoid sharp turns at start and end
348 : * @see NBEdge::checkGeometry
349 : */
350 : void checkGeometries(const double maxAngle, bool fixAngle, const double minRadius, bool fix, bool fixRailways, bool silent = false);
351 : /// @}
352 :
353 : /// @name processing methods
354 : /// @{
355 :
356 : /** @brief Sorts all lanes of all edges within the container by their direction
357 : *
358 : * Calls "NBEdge::sortOutgoingLanesConnections" for all edges within the container.
359 : *
360 : * @todo Recheck whether a visitor-pattern should be used herefor
361 : * @see NBEdge::sortOutgoingLanesConnections
362 : */
363 : void sortOutgoingLanesConnections();
364 :
365 : /** @brief Computes for each edge the approached edges
366 : *
367 : * Calls "NBEdge::computeEdge2Edges" for all edges within the container.
368 : *
369 : * @param[in] noLeftMovers Whether left-moving connections shall be omitted
370 : * @todo Recheck whether a visitor-pattern should be used herefor
371 : * @see NBEdge::computeEdge2Edges
372 : */
373 : void computeEdge2Edges(bool noLeftMovers);
374 :
375 : /** @brief Computes for each edge which lanes approach the next edges
376 : *
377 : * Calls "NBEdge::computeLanes2Edges" for all edges within the container.
378 : *
379 : * @todo Recheck whether a visitor-pattern should be used herefor
380 : * @see NBEdge::computeLanes2Edges
381 : */
382 : void computeLanes2Edges();
383 :
384 : /** @brief Rechecks whether all lanes have a successor for each of the stored edges
385 : *
386 : * Calls "NBEdge::recheckLanes" for all edges within the container.
387 : *
388 : * @todo Recheck whether a visitor-pattern should be used herefor
389 : * @see NBEdge::recheckLanes
390 : */
391 : void recheckLanes();
392 :
393 : /** @brief Appends turnarounds to all edges stored in the container
394 : *
395 : * Calls "NBEdge::appendTurnaround" for all edges within the container.
396 : *
397 : * @param[in] noTLSControlled Whether the turnaround shall not be connected if the edge is controlled by a tls
398 : * @param[in] noFringe Whether the turnaround shall not be connected if the junction is at the (outer) fringe
399 : * @param[in] onlyDeadends Whether the turnaround shall only be built at deadends
400 : * @param[in] onlyTurnlane Whether the turnaround shall only be built when there is an exclusive (left) turn lane
401 : * @param[in] noGeometryLike Whether the turnaround shall be built at geometry-like nodes
402 : * @see NBEdge::appendTurnaround
403 : */
404 : void appendTurnarounds(bool noTLSControlled, bool noFringe, bool onlyDeadends, bool onlyTurnlane, bool noGeometryLike);
405 :
406 : /** @brief Appends turnarounds to all edges stored in the container
407 : * Calls "NBEdge::appendTurnaround" for edges with the given ids
408 : * @param[in] ids The list of ids for which to append a turnaround
409 : * @param[in] noTLSControlled Whether the turnaround shall not be connected if the edge is controlled by a tls
410 : * @see NBEdge::appendTurnaround
411 : */
412 : void appendTurnarounds(const std::set<std::string>& ids, bool noTLSControlled);
413 :
414 : /// @brief Appends turnarounds to all bidiRail edges with stops
415 : void appendRailwayTurnarounds(const NBPTStopCont& sc);
416 :
417 : /** @brief Computes the shapes of all edges stored in the container
418 : *
419 : * Calls "NBEdge::computeEdgeShape" for all edges within the container.
420 : *
421 : * @todo Recheck whether a visitor-pattern should be used herefor
422 : * @todo Recheck usage
423 : * @see NBEdge::computeEdgeShape
424 : */
425 : void computeEdgeShapes(double smoothElevationThreshold = -1);
426 :
427 : /** @brief Computes the shapes of all lanes of all edges stored in the container
428 : *
429 : * Calls "NBEdge::computeLaneShapes" for all edges within the container.
430 : *
431 : * @todo Recheck whether a visitor-pattern should be used herefor
432 : * @todo Recheck usage
433 : * @see NBEdge::computeLaneShapes
434 : */
435 : void computeLaneShapes();
436 :
437 : /// @brief Clears information about controlling traffic lights for all connenections of all edges
438 : void clearControllingTLInformation() const;
439 :
440 : /** @brief Joins the given edges because they connect the same nodes
441 : *
442 : * @param[in] dc The district container needed to remove edges
443 : * @param[in] tlc The tls container needed to remove edges
444 : * @param[in] edges The edges to join
445 : * @todo Recheck and describe usage
446 : */
447 : void joinSameNodeConnectingEdges(NBDistrictCont& dc,
448 : NBTrafficLightLogicCont& tlc, EdgeVector edges);
449 :
450 : /// @brief Sets opposite lane information for geometrically close edges
451 : void guessOpposites();
452 :
453 : /** @brief Rechecks whether the lane spread is proper
454 : *
455 : * @todo Recheck usage; check whether this is really needed and whether it works at all
456 : */
457 : void recheckLaneSpread();
458 :
459 : /// @}
460 :
461 : /// @brief Returns the edge with negated id if it exists
462 : NBEdge* getOppositeByID(const std::string& edgeID) const;
463 :
464 : /// @brief Returns the edge with id if it exists
465 : NBEdge* getByID(const std::string& edgeID) const;
466 :
467 : /** @brief Determines which edges belong to roundabouts and increases their priority
468 : * @return The number of guessed roundabouts
469 : */
470 : int guessRoundabouts();
471 :
472 : /** @brief Determines which edges have been marked as roundabouts and stores them internally
473 : * @return The number of found roundabouts
474 : */
475 : int extractRoundabouts();
476 :
477 : // brief ensure myRoundabouts only holds valid edges
478 : void cleanupRoundabouts();
479 :
480 : /** @brief Returns whether the edge with the id was ignored during parsing
481 : * @return Whether the edge with the id was ignored during parsing
482 : */
483 : bool wasIgnored(std::string id) const {
484 : return myIgnoredEdges.count(id) != 0;
485 : }
486 :
487 : /// @brief mark the given edge id as ignored
488 : void ignore(std::string id) {
489 : myIgnoredEdges.insert(id);
490 12 : }
491 :
492 : /// @brief Returns whether the edge with the id was deleted explicitly
493 : bool wasRemoved(std::string id) const {
494 : return myExtractedEdges.count(id) != 0;
495 : }
496 :
497 : /// @brief Renames the edge. Throws exception if newID already exists
498 : void rename(NBEdge* edge, const std::string& newID);
499 :
500 : /// @name Connections handling
501 : /// @{
502 :
503 : /** @brief Adds a connection which could not be set during loading
504 : * @param[in] from The id of the edge the connection starts at
505 : * @param[in] fromLane The number of the lane the connection starts at
506 : * @param[in] to The id of the edge the connection ends at
507 : * @param[in] toLane The number of the lane the connection ends at
508 : * @param[in] mayDefinitelyPass Whether the connection may be passed without braking
509 : * @param[in] keepClear Whether the connection must check to keep the junction clear
510 : * @param[in] contPos Custom position for internal junction
511 : * @param[in] visibility Custom foe visiblity connection
512 : * @param[in] speed Custom speed
513 : * @param[in] friction Custom friction
514 : * @param[in] customShape Custom shape
515 : * @param[in] warnOnly Whether a failure to set this connection should only result in a warning
516 : */
517 : void addPostProcessConnection(const std::string& from, int fromLane, const std::string& to, int toLane, bool mayDefinitelyPass,
518 : KeepClear keepClear, double contPos, double visibility,
519 : double speed, double friction, double length,
520 : const PositionVector& customShape,
521 : bool uncontrolled,
522 : bool warnOnly,
523 : SVCPermissions permissions = SVC_UNSPECIFIED,
524 : bool indirectLeft = false,
525 : const std::string& edgeType = "",
526 : SVCPermissions changeLeft = SVC_UNSPECIFIED,
527 : SVCPermissions changeRight = SVC_UNSPECIFIED);
528 :
529 : /// @brief add post process connections
530 : bool hasPostProcessConnection(const std::string& from, const std::string& to = "");
531 :
532 : /// @brief Try to set any stored connections
533 : void recheckPostProcessConnections();
534 : /// @}
535 :
536 : /// @brief assigns street signs to edges based on toNode types
537 : void generateStreetSigns();
538 :
539 : /// @brief add sidwalks to edges within the given limits or permissions and return the number of edges affected
540 : int guessSpecialLanes(SUMOVehicleClass svc, double width, double minSpeed, double maxSpeed, bool fromPermissions, const std::string& excludeOpt,
541 : NBTrafficLightLogicCont& tlc);
542 :
543 : /** @brief Returns the determined roundabouts
544 : * @return The list of roundabout edges
545 : */
546 : const std::set<EdgeSet> getRoundabouts() const;
547 :
548 : /// @brief check if there is guessed roundabouts
549 : bool hasGuessedRoundabouts() const {
550 : return myGuessedRoundabouts.size() > 0;
551 : }
552 :
553 : /// @brief add user specified roundabout
554 : void addRoundabout(const EdgeSet& roundabout);
555 :
556 : /// @brief remove roundabout that contains the given node
557 : void removeRoundabout(const NBNode* node);
558 : /// @brief remove edges from all stored roundabouts
559 : void removeRoundaboutEdges(const EdgeSet& toRemove);
560 :
561 : /// @brief mark edge priorities and prohibit turn-arounds for all roundabout edges
562 : void markRoundabouts();
563 :
564 : /// @brief fix roundabout information after splitting an edge
565 : void patchRoundabouts(NBEdge* orig, NBEdge* part1, NBEdge* part2, std::set<EdgeSet>& roundabouts);
566 :
567 : /// @brief Returns true if this edge matches one of the removal criteria
568 : bool ignoreFilterMatch(NBEdge* edge);
569 :
570 : /// @brief remap node IDs accoring to options --numerical-ids and --reserved-ids
571 : int remapIDs(bool numericaIDs, bool reservedIDs, bool keptIDs, const std::string& prefix, NBPTStopCont& sc);
572 :
573 : /// @brief check whether edges overlap
574 : void checkOverlap(double threshold, double zThreshold) const;
575 :
576 : /// @brief check whether edges are to steep
577 : void checkGrade(double threshold) const;
578 :
579 : /** @brief Returns the edges which have been built by splitting the edge of the given id
580 : *
581 : * @param[in] id The id of the original edge
582 : * @return List of all edges which have been built by splitting the original edge
583 : * @todo Recheck usage
584 : */
585 : EdgeVector getGeneratedFrom(const std::string& id) const;
586 :
587 : /// @brief join adjacent lanes with the given permissions
588 : int joinLanes(SVCPermissions perms);
589 :
590 : /// @brief join tram edges into adjacent lanes
591 : int joinTramEdges(NBDistrictCont& dc, NBPTStopCont& sc, NBPTLineCont& lc, double maxDist);
592 :
593 : /// @brief return all edges
594 : EdgeVector getAllEdges() const;
595 :
596 : /// @brief return all router edges
597 : RouterEdgeVector getAllRouterEdges() const;
598 :
599 : /// @brief ensure that all edges have valid nodes
600 : bool checkConsistency(const NBNodeCont& nc);
601 :
602 : /// @brief modify all restrictions on lane changing for edges and connections
603 : void updateAllChangeRestrictions(SVCPermissions ignoring);
604 :
605 : /// @brief add prefix to all edges
606 : void addPrefix(const std::string& prefix);
607 :
608 : /// @brief adapt custom lengths of split edges to account for intersection size
609 : void fixSplitCustomLength();
610 :
611 : /// @brief compute all edge angles
612 : void computeAngles();
613 :
614 : /// @brief return all edge types in used
615 : std::set<std::string> getUsedTypes() const;
616 :
617 : /// @brief return number of edges removed
618 : int removeEdgesBySpeed(NBDistrictCont& dc);
619 : int removeEdgesByPermissions(NBDistrictCont& dc);
620 : int removeLanesByWidth(NBDistrictCont& dc, const double minWidth);
621 :
622 : /// @brief return number of edges split
623 : int attachRemoved(NBNodeCont& nc, NBDistrictCont& dc, const double maxDist);
624 :
625 : private:
626 : /// @brief compute the form factor for a loop of edges
627 : static double formFactor(const EdgeVector& loopEdges);
628 :
629 : /// @brief remove roundabout edges
630 : void removeRoundaboutEdges(const EdgeSet& toRemove, std::set<EdgeSet>& roundabouts);
631 :
632 : /// @brief The network builder; used to obtain type information
633 : NBTypeCont& myTypeCont;
634 :
635 : /** @struct PostProcessConnection
636 : * @brief A structure representing a connection between two lanes
637 : */
638 : struct PostProcessConnection {
639 :
640 : public:
641 : /** @brief Constructor
642 : * @param[in] from The id of the edge the connection starts at
643 : * @param[in] fromLane The number of the lane the connection starts at
644 : * @param[in] to The id of the edge the connection ends at
645 : * @param[in] toLane The number of the lane the connection ends at
646 : * @param[in] mayDefinitelyPass Whether the connection may be passed without braking
647 : */
648 18 : PostProcessConnection(const std::string& from_, int fromLane_, const std::string& to_, int toLane_,
649 : bool mayDefinitelyPass_, KeepClear keepClear_, double contPos_, double visibility_, double speed_,
650 : double friction_, double length_,
651 : const PositionVector& customShape_,
652 : bool uncontrolled_,
653 : bool warnOnly_,
654 : SVCPermissions permissions_,
655 : bool indirectLeft_,
656 : const std::string& edgeType_,
657 : SVCPermissions changeLeft_,
658 18 : SVCPermissions changeRight_) :
659 18 : from(from_), fromLane(fromLane_), to(to_), toLane(toLane_), mayDefinitelyPass(mayDefinitelyPass_), keepClear(keepClear_), contPos(contPos_),
660 18 : visibility(visibility_),
661 18 : speed(speed_),
662 18 : friction(friction_),
663 18 : customLength(length_),
664 : customShape(customShape_),
665 18 : uncontrolled(uncontrolled_),
666 18 : permissions(permissions_),
667 18 : indirectLeft(indirectLeft_),
668 18 : edgeType(edgeType_),
669 18 : changeLeft(changeLeft_),
670 18 : changeRight(changeRight_),
671 18 : warnOnly(warnOnly_)
672 18 : {}
673 :
674 : /// @brief The id of the edge the connection starts at
675 : std::string from;
676 :
677 : /// @brief The number of the lane the connection starts at
678 : int fromLane;
679 :
680 : /// @brief The id of the edge the connection ends at
681 : std::string to;
682 :
683 : /// @brief The number of the lane the connection ends at
684 : int toLane;
685 :
686 : /// @brief Whether the connection may be passed without braking
687 : bool mayDefinitelyPass;
688 :
689 : /// @brief Whether the connection may be passed without braking
690 : KeepClear keepClear;
691 :
692 : /// @brief custom position for internal junction on this connection
693 : double contPos;
694 :
695 : /// @brief custom foe visiblity for connection
696 : double visibility;
697 :
698 : /// @brief custom speed for connection
699 : double speed;
700 :
701 : /// @brief custom friction for connection
702 : double friction;
703 :
704 : /// @brief custom length for connection
705 : double customLength;
706 :
707 : /// @brief custom shape for connection
708 : PositionVector customShape;
709 :
710 : /// @brief whether this connection shall not be controlled by a traffic light
711 : bool uncontrolled;
712 :
713 : /// @brief custom permissions for connection
714 : SVCPermissions permissions;
715 :
716 : /// @brief whether this connection is an indirect left turn
717 : bool indirectLeft;
718 :
719 : /// @brief custom edge type
720 : std::string edgeType;
721 :
722 : /// @brief custom lane changing permissions for connection
723 : SVCPermissions changeLeft;
724 :
725 : /// @brief custom lane changing permissions for connection
726 : SVCPermissions changeRight;
727 :
728 : /// @brief whether a failure to set this connection is a warning or an error
729 : bool warnOnly;
730 : };
731 :
732 : struct MinLaneComparatorIdLess {
733 : bool operator()(const std::pair<NBEdge*, int>& a, const std::pair<NBEdge*, int>& b) const;
734 : };
735 :
736 : /// @brief The list of connections to recheck
737 : std::map<std::string, std::vector<PostProcessConnection> > myConnections;
738 :
739 : /// @brief The type of the dictionary where an edge may be found by its id
740 : typedef std::map<std::string, NBEdge*> EdgeCont;
741 :
742 : /// @brief The instance of the dictionary (id->edge)
743 : EdgeCont myEdges;
744 :
745 : /// @brief The extracted edges which are kept for reference
746 : EdgeCont myExtractedEdges;
747 :
748 : /// @brief The edges which got extracted twice but may still be referenced somewhere TODO smart_ptr?
749 : std::set<NBEdge*> myEdgeCemetery;
750 :
751 : /// @brief The ids of ignored edges
752 : std::set<std::string> myIgnoredEdges;
753 :
754 : /// @brief the number of splits of edges during the building
755 : std::map<const NBEdge*, std::pair<NBEdge*, NBEdge*> > myEdgesSplit;
756 : /// @brief the edges that were created as result of splitting
757 : std::set<const NBEdge*> myWasSplit;
758 :
759 : /// @name Settings for accepting/dismissing edges
760 : /// @{
761 :
762 : /// @brief The minimum speed an edge may have in order to be kept (default: -1)
763 : double myEdgesMinSpeed;
764 :
765 : /// @brief Whether edges shall be joined and patched first, then removed
766 : bool myRemoveEdgesAfterLoading;
767 :
768 : /// @brief Set of ids of edges which shall explicitly be kept
769 : std::set<std::string> myEdges2Keep;
770 :
771 : /// @brief Set of ids of edges which shall explicitly be removed
772 : std::set<std::string> myEdges2Remove;
773 :
774 : /// @brief Set of vehicle types which must be allowed on edges in order to keep them
775 : SVCPermissions myVehicleClasses2Keep;
776 :
777 : /// @brief Set of vehicle types which need not be supported (edges which allow ONLY these are removed)
778 : SVCPermissions myVehicleClasses2Remove;
779 :
780 : /// @brief Set of edges types which shall be kept
781 : std::set<std::string> myTypes2Keep;
782 :
783 : /// @brief Set of edges types which shall be removed
784 : std::set<std::string> myTypes2Remove;
785 :
786 : /// @brief Boundary within which an edge must be located in order to be kept
787 : PositionVector myPruningBoundary;
788 :
789 : /// @brief whether a geo transform has been applied to the pruning boundary
790 : bool myNeedGeoTransformedPruningBoundary;
791 : /// @}
792 :
793 : /// @brief Edges marked as belonging to a roundabout by the user (each EdgeVector is a roundabout)
794 : std::set<EdgeSet> myRoundabouts;
795 :
796 : /// @brief Edges marked as belonging to a roundabout after guessing
797 : std::set<EdgeSet> myGuessedRoundabouts;
798 :
799 : /** @class split_sorter
800 : * @brief Sorts splits by their position (increasing)
801 : */
802 : class split_sorter {
803 : public:
804 : /// @brief Constructor
805 : explicit split_sorter() { }
806 :
807 : /// @brief Comparing operator
808 : int operator()(const Split& e1, const Split& e2) const {
809 168 : return e1.pos < e2.pos;
810 : }
811 : };
812 :
813 : /// @brief invalidated copy constructor
814 : NBEdgeCont(const NBEdgeCont& s) = delete;
815 :
816 : /// @brief invalidated assignment operator
817 : NBEdgeCont& operator=(const NBEdgeCont& s) = delete;
818 : };
|