1 /****************************************************************************/ 2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others. 4 // This program and the accompanying materials 5 // are made available under the terms of the Eclipse Public License v2.0 6 // which accompanies this distribution, and is available at 7 // http://www.eclipse.org/legal/epl-v20.html 8 // SPDX-License-Identifier: EPL-2.0 9 /****************************************************************************/ 10 /// @file NBNodeCont.h 11 /// @author Daniel Krajzewicz 12 /// @author Jakob Erdmann 13 /// @author Yun-Pang Floetteroed 14 /// @author Michael Behrisch 15 /// @author Walter Bamberger 16 /// @date Tue, 20 Nov 2001 17 /// @version $Id$ 18 /// 19 // Container for nodes during the netbuilding process 20 /****************************************************************************/ 21 #ifndef NBNodeCont_h 22 #define NBNodeCont_h 23 24 25 // =========================================================================== 26 // included modules 27 // =========================================================================== 28 #include <config.h> 29 30 #include <string> 31 #include <map> 32 #include <vector> 33 #include <set> 34 #include <utils/common/NamedRTree.h> 35 #include <utils/geom/Position.h> 36 #include "NBEdgeCont.h" 37 #include "NBNode.h" 38 #include <utils/common/UtilExceptions.h> 39 40 41 // =========================================================================== 42 // class declarations 43 // =========================================================================== 44 class NBDistrict; 45 class OptionsCont; 46 class OutputDevice; 47 class NBParkingCont; 48 class NBPTLineCont; 49 class NBPTStopCont; 50 51 52 53 // =========================================================================== 54 // class definitions 55 // =========================================================================== 56 /** 57 * @class NBNodeCont 58 * @brief Container for nodes during the netbuilding process 59 */ 60 class NBNodeCont { 61 public: 62 /// @brief Definition of a node cluster container 63 typedef std::set<NBNode*, ComparatorIdLess> NodeSet; 64 typedef std::vector<NodeSet> NodeClusters; 65 typedef std::pair<NBNode*, double> NodeAndDist; 66 67 /// @brief Constructor 68 NBNodeCont(); 69 70 /// @brief Destructor 71 ~NBNodeCont(); 72 73 /// @name Insertion/removal/retrieval of nodes 74 /// @{ 75 /** @brief Inserts a node into the map 76 * @param[in] id The node's id 77 * @param[in] position The node's position 78 * @param[in] A district assigned to the node 79 * @return Whether the node could be added (no other with the same id or position is stored) 80 */ 81 bool insert(const std::string& id, const Position& position, NBDistrict* district = 0); 82 83 /** @brief Inserts a node into the map 84 * @param[in] node The node to insert 85 * @return Whether the node could be added (no other with the same id or position is stored) 86 */ 87 bool insert(NBNode* node); 88 89 /** @brief Removes the given node, deleting it 90 * @param[in] node The node to delete and remove 91 * @return Whether the node could be removed (existed) 92 */ 93 bool erase(NBNode* node); 94 95 /** @brief Removes the given node but does not delete it 96 * @param[in] node The node to delete and remove 97 * @param[in] remember Whether to keep the node for future reference 98 * @return Whether the node could be removed (existed) 99 */ 100 bool extract(NBNode* node, bool remember = false); 101 102 /** @brief Returns the node with the given name 103 * @param[in] id The id of the node to retrieve 104 * @return The node with the given id, or 0 if no such node exists 105 */ 106 NBNode* retrieve(const std::string& id) const; 107 108 /** @brief Returns the node with the given coordinates 109 * @param[in] position The position at which the node to retrieve lies 110 * @param[in] offset An offset which can be applied in the case positions are blurred 111 * @return The node at the given position, or 0 if no such node exists 112 */ 113 NBNode* retrieve(const Position& position, const double offset = 0.) const; 114 115 /// @brief Returns the pointer to the begin of the stored nodes begin()116 std::map<std::string, NBNode*>::const_iterator begin() const { 117 return myNodes.begin(); 118 } 119 120 /// @brief Returns the pointer to the end of the stored nodes end()121 std::map<std::string, NBNode*>::const_iterator end() const { 122 return myNodes.end(); 123 } 124 /// @} 125 126 /// @name Methods for for joining nodes 127 /// @{ 128 /* @brief add ids of nodes wich shall not be joined 129 * @param[in] ids A list of ids to exclude from joining 130 * @param[in] check Whether to check if these nodes are known 131 * @note checking is off by default because all nodes may not have been loaded yet 132 */ 133 void addJoinExclusion(const std::vector<std::string>& ids, bool check = false); 134 135 /** @brief add ids of nodes which shall be joined into a single node 136 * @param[in] cluster The cluster to add 137 */ 138 void addCluster2Join(std::set<std::string> cluster, NBNode* node); 139 140 /// @brief Joins loaded junction clusters (see NIXMLNodesHandler) 141 int joinLoadedClusters(NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc); 142 143 /// @brief Joins junctions that are very close together 144 int joinJunctions(double maxDist, NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc, NBPTStopCont& sc); 145 146 /// @brief remove geometry-like fringe nodes from cluster 147 void pruneClusterFringe(NodeSet& cluster) const; 148 149 /// @brief determine wether the cluster is not too complex for joining 150 bool feasibleCluster(const NodeSet& cluster, const NBEdgeCont& ec, const NBPTStopCont& sc, std::string& reason) const; 151 152 /// @brief try to find a joinable subset (recursively) 153 bool reduceToCircle(NodeSet& cluster, int circleSize, NodeSet startNodes, std::vector<NBNode*> cands = std::vector<NBNode*>()) const; 154 155 /// @brief find closest neighbor for building circle 156 NBEdge* shortestEdge(const NodeSet& cluster, const NodeSet& startNodes, const std::vector<NBNode*>& exclude) const; 157 /// @} 158 159 /// @name Adapting the input 160 /// @{ 161 /** @brief Removes self-loop edges (edges where the source and the destination node are the same) 162 * @param[in, opt. changed] dc The districts container to update 163 * @param[in, opt. changed] ec The edge container to remove the edges from 164 * @param[in, opt. changed] tc The traffic lights container to update 165 * @post Each edge is a uni-directional connection between two different nodes 166 */ 167 void removeSelfLoops(NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tc); 168 169 /** @brief Joins edges connecting the same nodes 170 * @param[in, opt. changed] dc The districts container to update 171 * @param[in, opt. changed] ec The edge container to remove the edges from 172 * @param[in, opt. changed] tc The traffic lights container to update 173 * @post No two edges with same geometry connecting same nodes exist 174 */ 175 void joinSimilarEdges(NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc); 176 177 /// @brief fix overlap 178 void avoidOverlap(); 179 180 /** @brief Removes sequences of edges that are not connected with a junction. 181 * Simple roads without junctions sometimes remain when converting from OpenStreetMap, 182 * but they make no sense. Remaining empty nodes are also deleted. 183 * 184 * @param[in, opt. changed] dc The district container needed if edges shall be removed 185 * @param[in, opt. changed] ec The container with the edge to be tested 186 */ 187 void removeIsolatedRoads(NBDistrictCont& dc, NBEdgeCont& ec); 188 189 /** @brief Checks the network for weak connectivity and removes all but the largest components. 190 * The connectivity check is done regardless of edge direction and vclass. 191 * 192 * @param[in, opt. changed] dc The district container needed if edges shall be removed 193 * @param[in, opt. changed] ec The container with the edge to be tested 194 * @param[in] numKeep The number of components to keep 195 */ 196 void removeComponents(NBDistrictCont& dc, NBEdgeCont& ec, const int numKeep); 197 198 /** @brief Removes "unwished" nodes 199 * 200 * Removes nodes if a) no incoming/outgoing edges exist or 201 * b) if the node is a "geometry" node. In the second case, 202 * edges that participate at the node will be joined. 203 * Whether the node is a geometry node or not, is determined 204 * by a call to NBNode::checkIsRemovable. 205 * The node is removed from the list of tls-controlled nodes. 206 * @param[in, opt. changed] dc The district container needed if a node shall be removed 207 * @param[in, opt. changed] ec The edge container needed for joining edges 208 * @param[in, opt. changed] tlc The traffic lights container to remove nodes from 209 * @param[in] removeGeometryNodes Whether geometry nodes shall also be removed 210 * @return The number of removed nodes 211 */ 212 int removeUnwishedNodes(NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc, 213 NBPTStopCont& sc, NBPTLineCont& lc, 214 NBParkingCont& pc, 215 bool removeGeometryNodes); 216 /// @} 217 218 /// @name Methods for guessing/computing traffic lights 219 /// @{ 220 /** @brief Guesses which junctions or junction clusters shall be controlled by tls 221 * @param[in] oc The options that steer the guessing process 222 * @param[filled] tlc The traffic lights control into which new traffic light definitions shall be stored 223 * @todo Recheck exception handling 224 */ 225 void guessTLs(OptionsCont& oc, NBTrafficLightLogicCont& tlc); 226 227 /** @brief Builds clusters of tls-controlled junctions and joins the control if possible 228 * @param[changed] tlc The traffic lights control for adding/removing new/prior tls 229 * @param[in] maxdist The maximum distance between nodes for clustering 230 * @todo Recheck exception handling 231 */ 232 void joinTLS(NBTrafficLightLogicCont& tlc, double maxdist); 233 234 /** @brief Sets the given node as being controlled by a tls 235 * @param[in] node The node that shall be controlled by a tls 236 * @param[in] tlc The traffic lights control into which the new traffic light definition shall be stored 237 * @param[in] type The type of the new tls 238 * @param[in] id The id of the tls to add 239 * @todo Recheck exception handling 240 */ 241 void setAsTLControlled(NBNode* node, NBTrafficLightLogicCont& tlc, TrafficLightType type, std::string id = ""); 242 /// @} 243 244 /** @brief Returns whether the node with the id was deleted explicitly 245 */ wasRemoved(std::string id)246 bool wasRemoved(std::string id) const { 247 return myExtractedNodes.count(id) != 0; 248 } 249 250 251 /// @brief Renames the node. Throws exception if newID already exists 252 void rename(NBNode* node, const std::string& newID); 253 254 /// divides the incoming lanes on outgoing lanes 255 void computeLanes2Lanes(); 256 257 /// @brief build the list of outgoing edges and lanes 258 void computeLogics(const NBEdgeCont& ec, OptionsCont& oc); 259 260 /// @brief compute right-of-way logic for all lane-to-lane connections 261 void computeLogics2(const NBEdgeCont& ec, OptionsCont& oc); 262 263 /// @brief Returns the number of nodes stored in this container size()264 int size() const { 265 return (int) myNodes.size(); 266 } 267 268 /// @brief deletes all nodes 269 void clear(); 270 271 /// @brief generates a new node ID 272 std::string getFreeID(); 273 274 /** @brief Compute the junction shape for this node 275 * @param[in] mismatchThreshold The threshold for warning about shapes which are away from myPosition 276 */ 277 void computeNodeShapes(double mismatchThreshold = -1); 278 279 /** @brief Prints statistics about built nodes 280 * 281 * Goes through stored nodes, computes the numbers of unregulated, priority and right-before-left 282 * junctions and prints them. 283 */ 284 void printBuiltNodesStatistics() const; 285 286 /// @brief get all node names 287 std::vector<std::string> getAllNames() const; 288 289 /* @brief analyzes a cluster of nodes which shall be joined 290 * @param[in] cluster The nodes to be joined 291 * @param[out] id The name for the new node 292 * @param[out] pos The position of the new node 293 * @param[out] hasTLS Whether the new node has a traffic light 294 * @param[out] tlType The type of traffic light (if any) 295 */ 296 void analyzeCluster(NodeSet cluster, std::string& id, Position& pos, 297 bool& hasTLS, TrafficLightType& type, SumoXMLNodeType& nodeType); 298 299 /// @brief gets all joined clusters (see doc for myClusters2Join) 300 void registerJoinedCluster(const NodeSet& cluster); 301 302 /// @brief gets all joined clusters (see doc for myClusters2Join) getJoinedClusters()303 const std::vector<std::set<std::string> >& getJoinedClusters() const { 304 return myJoinedClusters; 305 } 306 307 /* @brief discards traffic lights 308 * @param[in] geometryLike Whether only tls at geometry-like nodes shall be discarded 309 */ 310 void discardTrafficLights(NBTrafficLightLogicCont& tlc, bool geometryLike, bool guessSignals); 311 312 /* @brief discards rail signals 313 */ 314 void discardRailSignals(); 315 316 /// @brief mark a node as being created form a split markAsSplit(const NBNode * node)317 void markAsSplit(const NBNode* node) { 318 mySplit.insert(node); 319 } 320 321 /// @brief remap node IDs accoring to options --numerical-ids and --reserved-ids 322 int remapIDs(bool numericaIDs, bool reservedIDs, const std::string& prefix); 323 324 private: 325 326 /// @name Helper methods for for joining nodes 327 /// @{ 328 /** @brief Builds node clusters 329 * 330 * A node cluster is made up from nodes which are near by (distance<maxDist) and connected. 331 * 332 * @param[in] maxDist The maximum distance between two nodes for clustering 333 * @param[in, filled] into The container to store the clusters in 334 */ 335 void generateNodeClusters(double maxDist, NodeClusters& into) const; 336 337 /// @brief joins the given node clusters 338 void joinNodeClusters(NodeClusters clusters, NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc); 339 void joinNodeCluster(NodeSet clusters, NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc, NBNode* predefined = nullptr); 340 341 /// @} 342 343 /// @name Helper methods for guessing/computing traffic lights 344 /// @{ 345 /** @brief Returns whethe the given node cluster should be controlled by a tls 346 * @param[in] c The node cluster 347 * @param[in] laneSpeedThreshold threshold for determining whether a node or cluster should be tls controlled 348 * @return Whether this node cluster shall be controlled by a tls 349 */ 350 bool shouldBeTLSControlled(const NodeSet& c, double laneSpeedThreshold) const; 351 352 /// @brief check wheter the set of nodes only contains pedestrian crossings 353 bool onlyCrossings(const NodeSet& c) const; 354 355 /// @brief check wheter the set of nodes contains traffic lights with custom id 356 bool customTLID(const NodeSet& c) const; 357 /// @} 358 359 360 private: 361 /// @brief The running internal id 362 int myInternalID; 363 364 /// @brief Definition of the map of names to nodes 365 typedef std::map<std::string, NBNode*> NodeCont; 366 367 /// @brief The map of names to nodes 368 NodeCont myNodes; 369 370 /// @brief The extracted nodes which are kept for reference 371 NodeCont myExtractedNodes; 372 373 /// @brief set of node ids which should not be joined 374 std::set<std::string> myJoinExclusions; 375 376 /// @brief loaded sets of node ids to join (cleared after use) 377 std::vector<std::pair<std::set<std::string>, NBNode*> > myClusters2Join; 378 379 /// @brief sets of node ids which were joined 380 std::vector<std::set<std::string> > myJoinedClusters; 381 382 /// @brief ids found in loaded join clusters used for error checking 383 std::set<std::string> myJoined; 384 385 /// @brief nodes that were created when splitting an edge 386 std::set<const NBNode*> mySplit; 387 388 /// @brief node positions for faster lookup 389 NamedRTree myRTree; 390 391 private: 392 /// @brief invalidated copy constructor 393 NBNodeCont(const NBNodeCont& s); 394 395 /// @brief invalidated assignment operator 396 NBNodeCont& operator=(const NBNodeCont& s); 397 398 }; 399 400 401 #endif 402 403 /****************************************************************************/ 404 405