NBNodeCont Class Reference

#include <NBNodeCont.h>


Detailed Description

Container for nodes during the netbuilding process.

Definition at line 58 of file NBNodeCont.h.


Public Member Functions

void clear ()
void computeLanes2Lanes ()
 divides the incoming lanes on outgoing lanes
void computeLogics (const NBEdgeCont &ec, NBJunctionLogicCont &jc, OptionsCont &oc)
 build the list of outgoing edges and lanes
void computeNodeShapes (bool leftHand)
std::string getFreeID ()
void guessRamps (OptionsCont &oc, NBEdgeCont &ec, NBDistrictCont &dc)
 NBNodeCont () throw ()
 Constructor.
void printBuiltNodesStatistics () const throw ()
 Prints statistics about built nodes.
void recheckEdges (NBDistrictCont &dc, NBTrafficLightLogicCont &tlc, NBEdgeCont &ec)
 Joins edges connecting the same nodes.
void removeDummyEdges (NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tc)
 Removes dummy edges (edges lying completely within a node).
void removeIsolatedRoads (NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tc)
 Removes sequences of edges that are not connected with a junction. Simple roads without junctions sometimes remain when converting from OpenStreetMake, but they make no sense. Remaining empty nodes are also deleted.
void removeUnwishedNodes (NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc, bool removeGeometryNodes) throw ()
 Removes "unwished" nodes.
void reshiftNodePositions (const SUMOReal xoff, const SUMOReal yoff)
 resets the node positions by the specified offset
bool savePlain (const std::string &file)
unsigned int size () const throw ()
 Returns the number of known nodes.
void sortNodesEdges (bool leftHand, const NBTypeCont &tc)
 sorts the nodes' edges
void writeXML (OutputDevice &into)
 writes the nodes into the given ostream
void writeXMLInternalLinks (OutputDevice &into)
void writeXMLInternalNodes (OutputDevice &into)
void writeXMLInternalSuccInfos (OutputDevice &into)
 ~NBNodeCont () throw ()
 Destructor.
Insertion/removal/retrieval of nodes
bool erase (NBNode *node) throw ()
 Removes the given node, deleting it.
bool insert (NBNode *node) throw ()
 Inserts a node into the map.
Position2D insert (const std::string &id) throw ()
 Inserts a node into the map.
bool insert (const std::string &id, const Position2D &position) throw ()
 Inserts a node into the map.
bool insert (const std::string &id, const Position2D &position, NBDistrict *district) throw ()
 Inserts a node into the map.
NBNoderetrieve (const Position2D &position, SUMOReal offset=0.) const throw ()
 Returns the node with the given coordinates.
NBNoderetrieve (const std::string &id) const throw ()
 Returns the node with the given name.
Methods for guessing/computing traffic lights
void guessTLs (OptionsCont &oc, NBTrafficLightLogicCont &tlc)
 Guesses which junctions or junction clusters shall be controlled by tls.
void joinTLS (NBTrafficLightLogicCont &tlc)
 Builds clusters of tls-controlled junctions and joins the control if possible.
void setAsTLControlled (NBNode *node, NBTrafficLightLogicCont &tlc, std::string id="")
 Sets the given node as being controlled by a tls.

Private Types

typedef std::map< std::string,
NBNode * > 
NodeCont
 Definition of the map of names to nodes.

Private Member Functions

void buildOffRamp (OptionsCont &oc, NBNode *cur, NBEdgeCont &ec, NBDistrictCont &dc, std::vector< NBEdge * > &incremented)
bool buildOnRamp (OptionsCont &oc, NBNode *cur, NBEdgeCont &ec, NBDistrictCont &dc, std::vector< NBEdge * > &incremented)
void checkHighwayRampOrder (NBEdge *&pot_highway, NBEdge *&pot_ramp)
bool mayNeedOffRamp (OptionsCont &oc, NBNode *cur) const
bool mayNeedOnRamp (OptionsCont &oc, NBNode *cur) const
 NBNodeCont (const NBNodeCont &s)
 invalidated copy constructor
NBNodeContoperator= (const NBNodeCont &s)
 invalidated assignment operator
Helper methods for guessing/computing traffic lights
void generateNodeClusters (SUMOReal maxDist, std::vector< std::set< NBNode * > > &into) const throw ()
 Builds node clusters.
bool shouldBeTLSControlled (const std::set< NBNode * > &c) const throw ()
 Returns whethe the given node cluster should be controlled by a tls.

Private Attributes

int myInternalID
 The running internal id.
NodeCont myNodes
 The map of names to nodes.

Member Typedef Documentation

typedef std::map<std::string, NBNode*> NBNodeCont::NodeCont [private]

Definition of the map of names to nodes.

Definition at line 272 of file NBNodeCont.h.


Constructor & Destructor Documentation

NBNodeCont::NBNodeCont (  )  throw ()

Constructor.

Definition at line 61 of file NBNodeCont.cpp.

00062         : myInternalID(1) {}

NBNodeCont::~NBNodeCont (  )  throw ()

Destructor.

Definition at line 65 of file NBNodeCont.cpp.

References clear().

00065                                 {
00066     clear();
00067 }

NBNodeCont::NBNodeCont ( const NBNodeCont s  )  [private]

invalidated copy constructor


Member Function Documentation

void NBNodeCont::buildOffRamp ( OptionsCont oc,
NBNode cur,
NBEdgeCont ec,
NBDistrictCont dc,
std::vector< NBEdge * > &  incremented 
) [private]

Definition at line 891 of file NBNodeCont.cpp.

References NBEdge::addLane2LaneConnections(), MsgHandler::getErrorInstance(), OptionsCont::getFloat(), NBEdge::getGeometry(), NBEdge::getID(), NBNode::getIncomingEdges(), NBEdge::getLaneSpreadFunction(), NBEdge::getNoLanes(), NBNode::getOutgoingEdges(), NBNode::getPosition(), NBEdge::getSpeed(), NBEdge::getToNode(), MsgHandler::getWarningInstance(), NBEdge::incLaneNo(), MsgHandler::inform(), insert(), NBEdge::invalidateConnections(), NBEdge::L2L_VALIDATED, NBEdge::LANESPREAD_CENTER, Position2DVector::length(), MIN2(), Position2DVector::move2side(), Position2DVector::pop_front(), POSITION_EPS, Position2DVector::positionAtLengthPosition(), Position2DVector::push_front(), NBEdgeCont::retrieve(), NBEdge::setGeometry(), NBEdgeCont::splitAt(), SUMO_const_halfLaneAndOffset, SUMO_const_laneWidthAndOffset, and SUMOReal.

Referenced by guessRamps().

00893                                                           {
00894     NBEdge *pot_highway = cur->getOutgoingEdges()[0];
00895     NBEdge *pot_ramp = cur->getOutgoingEdges()[1];
00896     NBEdge *prev = cur->getIncomingEdges()[0];
00897     // assign highway/ramp properly
00898     if (pot_highway->getSpeed()<pot_ramp->getSpeed()) {
00899         std::swap(pot_highway, pot_ramp);
00900     } else if (pot_highway->getSpeed()==pot_ramp->getSpeed()
00901                &&
00902                pot_highway->getNoLanes()<pot_ramp->getNoLanes()) {
00903 
00904         std::swap(pot_highway, pot_ramp);
00905     }
00906     // compute the number of lanes to append
00907     int toAdd = (pot_ramp->getNoLanes() + pot_highway->getNoLanes()) - prev->getNoLanes();
00908     if (toAdd<=0) {
00909         return;
00910     }
00911     // append on-ramp
00912     if (prev->getGeometry().length()-POSITION_EPS<=oc.getFloat("ramp-guess.ramp-length")) {
00913         // the edge is shorter than the wished ramp
00914         //  append a lane only
00915         if (find(incremented.begin(), incremented.end(), prev)==incremented.end()) {
00916             incremented.push_back(prev);
00917             prev->incLaneNo(toAdd);
00918             prev->invalidateConnections(true);
00919             if (!prev->addLane2LaneConnections(pot_ramp->getNoLanes(), pot_highway, 0,
00920                                                MIN2(prev->getNoLanes()-1, pot_highway->getNoLanes()), NBEdge::L2L_VALIDATED, true)) {
00921 
00922                 throw ProcessError("Could not set connection!");
00923 
00924             }
00925             if (!prev->addLane2LaneConnections(0, pot_ramp, 0, pot_ramp->getNoLanes(), NBEdge::L2L_VALIDATED, false)) {
00926                 throw ProcessError("Could not set connection!");
00927 
00928             }
00929             if (prev->getLaneSpreadFunction()==NBEdge::LANESPREAD_CENTER) {
00930                 try {
00931                     Position2DVector g = prev->getGeometry();
00932                     g.move2side(SUMO_const_laneWidthAndOffset);
00933                     prev->setGeometry(g);
00934                 } catch (InvalidArgument &) {
00935                     MsgHandler::getWarningInstance()->inform("For edge '" + prev->getID() + "': could not compute shape.");
00936                 }
00937             }
00938         }
00939         Position2DVector p = pot_ramp->getGeometry();
00940         p.pop_front();
00941         p.push_front(prev->getToNode()->getPosition());//added_ramp->getLaneShape(0).at(-1));
00942         pot_ramp->setGeometry(p);
00943     } else {
00944         Position2D pos =
00945             prev->getGeometry().positionAtLengthPosition(
00946                 prev->getGeometry().length()-oc.getFloat("ramp-guess.ramp-length"));
00947         NBNode *rn = new NBNode(prev->getID() + "-AddedOffRampNode", pos);
00948         if (!insert(rn)) {
00949             throw ProcessError("Ups - could not build off-ramp for edge '" + pot_highway->getID() + "' (node could not be build)!");
00950 
00951         }
00952         std::string name = prev->getID();
00953         bool ok = ec.splitAt(dc, prev, rn,
00954                              prev->getID(), prev->getID()+"-AddedOffRampEdge",
00955                              prev->getNoLanes(), prev->getNoLanes()+toAdd);
00956         if (!ok) {
00957             MsgHandler::getErrorInstance()->inform("Ups - could not build on-ramp for edge '" + pot_highway->getID() + "'!");
00958             return;
00959         } else {
00960             NBEdge *added_ramp = ec.retrieve(name+"-AddedOffRampEdge");
00961             NBEdge *added = ec.retrieve(name);
00962             if (added_ramp->getNoLanes()!=added->getNoLanes()) {
00963                 incremented.push_back(added_ramp);
00964                 int off = added_ramp->getNoLanes()-added->getNoLanes();
00965                 if (!added->addLane2LaneConnections(0, added_ramp, off, added->getNoLanes(), NBEdge::L2L_VALIDATED, true)) {
00966                     throw ProcessError("Could not set connection!");
00967 
00968                 }
00969                 if (added_ramp->getLaneSpreadFunction()==NBEdge::LANESPREAD_CENTER) {
00970                     try {
00971                         Position2DVector g = added_ramp->getGeometry();
00972                         SUMOReal factor = SUMO_const_laneWidthAndOffset * (SUMOReal)(toAdd-1) + SUMO_const_halfLaneAndOffset * (SUMOReal)(toAdd%2);
00973                         g.move2side(factor);
00974                         added_ramp->setGeometry(g);
00975                     } catch (InvalidArgument &) {
00976                         MsgHandler::getWarningInstance()->inform("For edge '" + added_ramp->getID() + "': could not compute shape.");
00977                     }
00978                 }
00979             } else {
00980                 if (!added->addLane2LaneConnections(0, added_ramp, 0, added_ramp->getNoLanes(), NBEdge::L2L_VALIDATED, true)) {
00981                     throw ProcessError("Could not set connection!");
00982                 }
00983             }
00984             if (!added_ramp->addLane2LaneConnections(pot_ramp->getNoLanes(), pot_highway, 0,
00985                     MIN2(added_ramp->getNoLanes()-pot_ramp->getNoLanes(), pot_highway->getNoLanes()), NBEdge::L2L_VALIDATED, true)) {
00986                 throw ProcessError("Could not set connection!");
00987             }
00988             if (!added_ramp->addLane2LaneConnections(0, pot_ramp, 0, pot_ramp->getNoLanes(), NBEdge::L2L_VALIDATED, false)) {
00989                 throw ProcessError("Could not set connection!");
00990 
00991             }
00992             Position2DVector p = pot_ramp->getGeometry();
00993             p.pop_front();
00994             p.push_front(added_ramp->getToNode()->getPosition());//added_ramp->getLaneShape(0).at(-1));
00995             pot_ramp->setGeometry(p);
00996         }
00997     }
00998 }

bool NBNodeCont::buildOnRamp ( OptionsCont oc,
NBNode cur,
NBEdgeCont ec,
NBDistrictCont dc,
std::vector< NBEdge * > &  incremented 
) [private]

Definition at line 771 of file NBNodeCont.cpp.

References NBEdge::addLane2LaneConnections(), MsgHandler::getErrorInstance(), OptionsCont::getFloat(), NBEdge::getFromNode(), NBEdge::getGeometry(), NBEdge::getID(), NBNode::getIncomingEdges(), NBEdge::getLaneSpreadFunction(), NBEdge::getNoLanes(), NBNode::getOutgoingEdges(), NBNode::getPosition(), NBEdge::getSpeed(), NBEdge::getToNode(), MsgHandler::getWarningInstance(), NBEdge::incLaneNo(), MsgHandler::inform(), insert(), NBEdge::invalidateConnections(), NBEdge::L2L_VALIDATED, NBEdge::LANESPREAD_CENTER, Position2DVector::length(), MIN2(), Position2DVector::move2side(), Position2DVector::pop_back(), POSITION_EPS, Position2DVector::positionAtLengthPosition(), Position2DVector::push_back(), NBEdgeCont::retrieve(), NBEdge::setGeometry(), NBEdgeCont::splitAt(), SUMO_const_halfLaneAndOffset, SUMO_const_laneWidthAndOffset, and SUMOReal.

Referenced by guessRamps().

00773                                                          {
00774     NBEdge *pot_highway = cur->getIncomingEdges()[0];
00775     NBEdge *pot_ramp = cur->getIncomingEdges()[1];
00776     NBEdge *cont = cur->getOutgoingEdges()[0];
00777     bool bEdgeDeleted = false;
00778 
00779     // assign highway/ramp properly
00780     if (pot_highway->getSpeed()<pot_ramp->getSpeed()) {
00781         std::swap(pot_highway, pot_ramp);
00782     } else if (pot_highway->getSpeed()==pot_ramp->getSpeed()
00783                &&
00784                pot_highway->getNoLanes()<pot_ramp->getNoLanes()) {
00785 
00786         std::swap(pot_highway, pot_ramp);
00787     }
00788 
00789     // compute the number of lanes to append
00790     int toAdd = (pot_ramp->getNoLanes() + pot_highway->getNoLanes()) - cont->getNoLanes();
00791     if (toAdd<=0) {
00792         return false;
00793     }
00794 
00795     //
00796     if (cont->getGeometry().length()-POSITION_EPS<=oc.getFloat("ramp-guess.ramp-length")) {
00797         // the edge is shorter than the wished ramp
00798         //  append a lane only
00799         if (find(incremented.begin(), incremented.end(), cont)==incremented.end()) {
00800             cont->incLaneNo(toAdd);
00801             incremented.push_back(cont);
00802             if (!pot_highway->addLane2LaneConnections(0, cont, pot_ramp->getNoLanes(),
00803                     MIN2(cont->getNoLanes()-pot_ramp->getNoLanes(), pot_highway->getNoLanes()), NBEdge::L2L_VALIDATED, true, true)) {
00804                 throw ProcessError("Could not set connection!");
00805             }
00806             if (!pot_ramp->addLane2LaneConnections(0, cont, 0, pot_ramp->getNoLanes(), NBEdge::L2L_VALIDATED, true, true)) {
00807                 throw ProcessError("Could not set connection!");
00808             }
00809             //
00810             cont->invalidateConnections(true);
00811             const EdgeVector &o1 = cont->getToNode()->getOutgoingEdges();
00812             if (o1.size()==1&&o1[0]->getNoLanes()<cont->getNoLanes()) {
00813                 cont->addLane2LaneConnections(cont->getNoLanes()-o1[0]->getNoLanes(),
00814                                               o1[0], 0, o1[0]->getNoLanes(), NBEdge::L2L_VALIDATED);
00815             }
00816             //
00817             if (cont->getLaneSpreadFunction()==NBEdge::LANESPREAD_CENTER) {
00818                 try {
00819                     Position2DVector g = cont->getGeometry();
00820                     g.move2side(SUMO_const_laneWidthAndOffset);
00821                     cont->setGeometry(g);
00822                 } catch (InvalidArgument &) {
00823                     MsgHandler::getWarningInstance()->inform("For edge '" + cont->getID() + "': could not compute shape.");
00824                 }
00825             }
00826         }
00827         Position2DVector p = pot_ramp->getGeometry();
00828         p.pop_back();
00829         p.push_back(cont->getFromNode()->getPosition());
00830         pot_ramp->setGeometry(p);
00831     } else {
00832         bEdgeDeleted=true;
00833         // there is enough place to build a ramp; do it
00834         NBNode *rn =
00835             new NBNode(cont->getID() + "-AddedOnRampNode",
00836                        cont->getGeometry().positionAtLengthPosition(
00837                            oc.getFloat("ramp-guess.ramp-length")));
00838         if (!insert(rn)) {
00839             throw ProcessError("Ups - could not build on-ramp for edge '" + pot_highway->getID() + "' (node could not be build)!");
00840         }
00841         std::string name = cont->getID();
00842         bool ok = ec.splitAt(dc, cont, rn,
00843                              cont->getID()+"-AddedOnRampEdge", cont->getID(),
00844                              cont->getNoLanes()+toAdd, cont->getNoLanes());
00845         if (!ok) {
00846             MsgHandler::getErrorInstance()->inform("Ups - could not build on-ramp for edge '" + pot_highway->getID() + "'!");
00847             return true;
00848         } else {
00849             NBEdge *added_ramp = ec.retrieve(name+"-AddedOnRampEdge");
00850             NBEdge *added = ec.retrieve(name);
00851             incremented.push_back(added_ramp);
00852             if (added_ramp->getNoLanes()!=added->getNoLanes()) {
00853                 int off = added_ramp->getNoLanes()-added->getNoLanes();
00854                 if (!added_ramp->addLane2LaneConnections(off, added, 0, added->getNoLanes(), NBEdge::L2L_VALIDATED, true)) {
00855                     throw ProcessError("Could not set connection!");
00856                 }
00857                 if (added_ramp->getLaneSpreadFunction()==NBEdge::LANESPREAD_CENTER) {
00858                     try {
00859                         Position2DVector g = added_ramp->getGeometry();
00860                         SUMOReal factor = SUMO_const_laneWidthAndOffset * (SUMOReal)(toAdd-1) + SUMO_const_halfLaneAndOffset * (SUMOReal)(toAdd%2);
00861                         g.move2side(factor);
00862                         added_ramp->setGeometry(g);
00863                     } catch (InvalidArgument &) {
00864                         MsgHandler::getWarningInstance()->inform("For edge '" + added_ramp->getID() + "': could not compute shape.");
00865                     }
00866                 }
00867             } else {
00868                 if (!added_ramp->addLane2LaneConnections(0, added, 0, added_ramp->getNoLanes(), NBEdge::L2L_VALIDATED, true)) {
00869                     throw ProcessError("Could not set connection!");
00870                 }
00871             }
00872             if (!pot_highway->addLane2LaneConnections(0, added_ramp, pot_ramp->getNoLanes(),
00873                     MIN2(added_ramp->getNoLanes()-pot_ramp->getNoLanes(), pot_highway->getNoLanes()), NBEdge::L2L_VALIDATED, false, true)) {
00874                 throw ProcessError("Could not set connection!");
00875 
00876             }
00877             if (!pot_ramp->addLane2LaneConnections(0, added_ramp, 0, pot_ramp->getNoLanes(), NBEdge::L2L_VALIDATED, true, true)) {
00878                 throw ProcessError("Could not set connection!");
00879             }
00880             Position2DVector p = pot_ramp->getGeometry();
00881             p.pop_back();
00882             p.push_back(added_ramp->getFromNode()->getPosition());//added_ramp->getLaneShape(0).at(0));
00883             pot_ramp->setGeometry(p);
00884         }
00885     }
00886     return bEdgeDeleted;
00887 }

void NBNodeCont::checkHighwayRampOrder ( NBEdge *&  pot_highway,
NBEdge *&  pot_ramp 
) [private]

Definition at line 1050 of file NBNodeCont.cpp.

References NBEdge::getNoLanes(), and NBEdge::getSpeed().

Referenced by guessRamps().

01050                                                                          {
01051     if (pot_highway->getSpeed()<pot_ramp->getSpeed()) {
01052         std::swap(pot_highway, pot_ramp);
01053     } else if (pot_highway->getSpeed()==pot_ramp->getSpeed()
01054                &&
01055                pot_highway->getNoLanes()<pot_ramp->getNoLanes()) {
01056 
01057         std::swap(pot_highway, pot_ramp);
01058     }
01059 }

void NBNodeCont::clear (  ) 

deletes all nodes

Definition at line 459 of file NBNodeCont.cpp.

References myNodes.

Referenced by ~NBNodeCont().

00459                   {
00460     for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00461         delete((*i).second);
00462     }
00463     myNodes.clear();
00464 }

void NBNodeCont::computeLanes2Lanes (  ) 

divides the incoming lanes on outgoing lanes

Definition at line 397 of file NBNodeCont.cpp.

References myNodes.

Referenced by NBNetBuilder::compute().

00397                                {
00398     for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00399         (*i).second->computeLanes2Lanes();
00400     }
00401 }

void NBNodeCont::computeLogics ( const NBEdgeCont ec,
NBJunctionLogicCont jc,
OptionsCont oc 
)

build the list of outgoing edges and lanes

Definition at line 406 of file NBNodeCont.cpp.

References myNodes.

Referenced by NBNetBuilder::compute().

00407                                            {
00408     for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00409         (*i).second->computeLogic(ec, jc, oc);
00410     }
00411 }

void NBNodeCont::computeNodeShapes ( bool  leftHand  ) 

Definition at line 656 of file NBNodeCont.cpp.

References OutputDevice::createDeviceByOption(), and myNodes.

Referenced by NBNetBuilder::compute().

00656                                            {
00657     OutputDevice::createDeviceByOption("node-geometry-dump", "pois");
00658     for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00659         (*i).second->computeNodeShape(leftHand);
00660     }
00661 }

bool NBNodeCont::erase ( NBNode node  )  throw ()

Removes the given node, deleting it.

Parameters:
[in] node The node to delete and remove
Returns:
Whether the node could be removed (existed)

Definition at line 147 of file NBNodeCont.cpp.

References myNodes.

Referenced by NIVissimEdge::remapOneOfNodes(), removeIsolatedRoads(), and removeUnwishedNodes().

00147                                       {
00148     NodeCont::iterator i = myNodes.find(node->getID());
00149     if (i==myNodes.end()) {
00150         return false;
00151     }
00152     node->removeTrafficLights();
00153     myNodes.erase(i);
00154     delete node;
00155     return true;
00156 }

void NBNodeCont::generateNodeClusters ( SUMOReal  maxDist,
std::vector< std::set< NBNode * > > &  into 
) const throw () [private]

Builds node clusters.

A node cluster is made up from nodes which are near by (distance<maxDist) and connected.

Parameters:
[in] maxDist The maximum distance between two nodes for clustering
in,filled] into The container to store the clusters in

Definition at line 161 of file NBNodeCont.cpp.

References Position2D::distanceTo(), NBNode::getEdges(), NBEdge::getFromNode(), NBNode::getPosition(), NBEdge::getToNode(), NBNode::hasIncoming(), and myNodes.

Referenced by guessTLs(), and joinTLS().

00161                                                                                                  {
00162     std::set<NBNode*> visited;
00163     for (NodeCont::const_iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00164         std::vector<NBNode*> toProc;
00165         if (visited.find((*i).second)!=visited.end()) {
00166             continue;
00167         }
00168         toProc.push_back((*i).second);
00169         std::set<NBNode*> c;
00170         while (!toProc.empty()) {
00171             NBNode *n = toProc.back();
00172             toProc.pop_back();
00173             if (visited.find(n)!=visited.end()) {
00174                 continue;
00175             }
00176             c.insert(n);
00177             visited.insert(n);
00178             const EdgeVector &edges = n->getEdges();
00179             for (EdgeVector::const_iterator j=edges.begin(); j!=edges.end(); ++j) {
00180                 NBEdge *e = *j;
00181                 NBNode *s = 0;
00182                 if (n->hasIncoming(e)) {
00183                     s = e->getFromNode();
00184                 } else {
00185                     s = e->getToNode();
00186                 }
00187                 if (visited.find(s)!=visited.end()) {
00188                     continue;
00189                 }
00190                 if (n->getPosition().distanceTo(s->getPosition())<maxDist) {
00191                     toProc.push_back(s);
00192                 }
00193             }
00194         }
00195         if (c.size()<2) {
00196             continue;
00197         }
00198         into.push_back(c);
00199     }
00200 }

std::string NBNodeCont::getFreeID (  ) 

Definition at line 650 of file NBNodeCont.cpp.

References size().

Referenced by NIXMLEdgesHandler::insertNodeChecking().

00650                       {
00651     return "SUMOGenerated" + toString<int>(size());
00652 }

void NBNodeCont::guessRamps ( OptionsCont oc,
NBEdgeCont ec,
NBDistrictCont dc 
)

Definition at line 1063 of file NBNodeCont.cpp.

References NBNode::addIncomingEdge(), buildOffRamp(), buildOnRamp(), checkHighwayRampOrder(), Position2D::distanceTo(), Position2DVector::eraseAt(), OptionsCont::getBool(), OptionsCont::getFloat(), NBEdge::getFromNode(), NBEdge::getGeometry(), NBEdge::getID(), NBNode::getIncomingEdges(), NBEdge::getNoLanes(), NBNode::getOutgoingEdges(), NBNode::getPosition(), OptionsCont::getStringVector(), NBEdge::getToNode(), MsgHandler::getWarningInstance(), MsgHandler::inform(), insert(), OptionsCont::isSet(), mayNeedOffRamp(), mayNeedOnRamp(), myNodes, Position2DVector::nearest_position_on_line_to_point(), Position2DVector::positionAtLengthPosition(), NBNode::removeIncoming(), NBEdgeCont::retrieve(), NBEdge::setGeometry(), NBEdgeCont::splitAt(), and SUMOReal.

Referenced by NBNetBuilder::compute().

01064                                            {
01065     std::vector<NBEdge*> incremented;
01066     bool bEdgeDeleted=false;
01067     // check whether obsure highway connections shall be checked
01068     if (oc.getBool("guess-obscure-ramps")) {
01069         for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
01070             NBNode *cur = (*i).second;
01071             const EdgeVector &inc = cur->getIncomingEdges();
01072             const EdgeVector &out = cur->getOutgoingEdges();
01073             if (inc.size()!=2||out.size()!=2) {
01074                 continue;
01075             }
01076             {
01077                 bool hadInHighway = false;
01078                 for (EdgeVector::const_iterator j=inc.begin(); j!=inc.end(); ++j) {
01079                     if ((*j)->getSpeed()>oc.getFloat("obscure-ramps.min-highway-speed")) {
01080 
01081                         hadInHighway = true;
01082                     }
01083                 }
01084                 if (!hadInHighway) {
01085                     continue;
01086                 }
01087             }
01088             {
01089                 bool hadOutHighway = false;
01090                 for (EdgeVector::const_iterator j=out.begin(); j!=out.end(); ++j) {
01091                     if ((*j)->getSpeed()>oc.getFloat("obscure-ramps.min-highway-speed")) {
01092 
01093                         hadOutHighway = true;
01094                     }
01095                 }
01096                 if (!hadOutHighway) {
01097                     continue;
01098                 }
01099             }
01100             // ok, something is strange:
01101             //  we do have a highway, here with an off- and an on-ramp on the same node!?
01102             // try to place the incoming before...
01103             //  ... determine a possible position, first
01104             NBEdge *inc_highway = inc[0];
01105             NBEdge *inc_ramp = inc[1];
01106             NBEdge *out_highway = out[0];
01107             NBEdge *out_ramp = out[1];
01108             checkHighwayRampOrder(inc_highway, inc_ramp);
01109             checkHighwayRampOrder(out_highway, out_ramp);
01110 
01111             if (100>inc_highway->getToNode()->getPosition().distanceTo(inc_ramp->getGeometry()[-1])) {
01112                 Position2DVector tmp = inc_ramp->getGeometry();
01113                 tmp.eraseAt(-1);
01114                 inc_ramp->setGeometry(tmp);
01115             }
01116             SUMOReal pos =
01117                 inc_highway->getGeometry().nearest_position_on_line_to_point(
01118                     inc_ramp->getGeometry()[-1]);
01119             if (pos<0) {
01120                 continue;
01121             }
01122             Position2D p = inc_highway->getGeometry().positionAtLengthPosition(pos);
01123             NBNode *rn =
01124                 new NBNode(inc_highway->getID() + "-AddedAntiObscureNode", p);
01125             if (!insert(rn)) {
01126                 throw ProcessError("Ups - could not build anti-obscure node '" + inc_highway->getID() + "'!");
01127 
01128             }
01129             std::string name = inc_highway->getID();
01130             bool ok = ec.splitAt(dc, inc_highway, rn,
01131                                  inc_highway->getID(), inc_highway->getID()+"-AddedInBetweenEdge",
01132                                  inc_highway->getNoLanes(), inc_highway->getNoLanes());
01133             if (!ok) {
01134                 throw ProcessError("Ups - could not build anti-obscure edge '" + inc_highway->getID() + "'!");
01135 
01136             } else {
01137                 NBEdge *added_cont = ec.retrieve(name+"-AddedInBetweenEdge");
01138                 NBEdge *added = ec.retrieve(name);
01139                 added_cont->getToNode()->removeIncoming(out_ramp);
01140                 added->getToNode()->addIncomingEdge(out_ramp);
01141             }
01142         }
01143     }
01144     // check whether on-off ramps shall be guessed
01145     if (oc.getBool("guess-ramps")) {
01146         for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
01147             NBNode *cur = (*i).second;
01148             if (mayNeedOnRamp(oc, cur)) {
01149                 buildOnRamp(oc, cur, ec, dc, incremented);
01150             }
01151             if (mayNeedOffRamp(oc, cur)) {
01152                 buildOffRamp(oc, cur, ec, dc, incremented);
01153             }
01154         }
01155     }
01156     // check whether on-off ramps shall be guessed
01157     if (oc.isSet("ramp-guess.explicite")) {
01158         std::vector<std::string> edges = oc.getStringVector("ramp-guess.explicite");
01159         for (std::vector<std::string>::iterator i=edges.begin(); i!=edges.end(); ++i) {
01160             NBEdge *e = ec.retrieve(*i);
01161             if (e==0) {
01162                 MsgHandler::getWarningInstance()->inform("Can not build on ramp on edge '" + *i + "' - the edge is not known.");
01163                 continue;
01164             }
01165             NBNode *from = e->getFromNode();
01166             if (from->getIncomingEdges().size()==2&&from->getOutgoingEdges().size()==1) {
01167                 bEdgeDeleted = buildOnRamp(oc, from, ec, dc, incremented);
01168             }
01169             // load edge again to check offramps
01170             e = ec.retrieve(*i);
01171             if (e==0) {
01172                 MsgHandler::getWarningInstance()->inform("Can not build off ramp on edge '" + *i + "' - the edge is not known.");
01173                 continue;
01174             }
01175             NBNode *to = e->getToNode();
01176             if (to->getIncomingEdges().size()==1&&to->getOutgoingEdges().size()==2) {
01177                 buildOffRamp(oc, to, ec, dc, incremented);
01178             }
01179         }
01180     }
01181 }

void NBNodeCont::guessTLs ( OptionsCont oc,
NBTrafficLightLogicCont tlc 
)

Guesses which junctions or junction clusters shall be controlled by tls.

Parameters:
[in] oc The options that steer the guessing process
filled] tlc The traffic lights control into which new traffic light definitions shall be stored
Todo:
Recheck exception handling

Definition at line 232 of file NBNodeCont.cpp.

References generateNodeClusters(), OptionsCont::getBool(), NBNode::getControllingTLS(), NBNode::getIncomingEdges(), OptionsCont::getStringVector(), NBTrafficLightLogicCont::insert(), NBNode::isNearDistrict(), OptionsCont::isSet(), NBNode::isTLControlled(), myNodes, NBNode::removeTrafficLights(), retrieve(), setAsTLControlled(), shouldBeTLSControlled(), SUMOReal, toString(), and WRITE_WARNING.

Referenced by NBNetBuilder::compute().

00232                                                                   {
00233     // build list of definitely not tls-controlled junctions
00234     std::vector<NBNode*> ncontrolled;
00235     if (oc.isSet("explicite-no-tls")) {
00236         std::vector<std::string> notTLControlledNodes = oc.getStringVector("explicite-no-tls");
00237         for (std::vector<std::string>::const_iterator i=notTLControlledNodes.begin(); i!=notTLControlledNodes.end(); ++i) {
00238             NBNode *n = NBNodeCont::retrieve(*i);
00239             if (n==0) {
00240                 throw ProcessError(" The node '" + *i + "' to set as not-controlled is not known.");
00241             }
00242             std::set<NBTrafficLightDefinition*> tls = n->getControllingTLS();
00243             for (std::set<NBTrafficLightDefinition*>::const_iterator j=tls.begin(); j!=tls.end(); ++j) {
00244                 (*j)->removeNode(n);
00245             }
00246             n->removeTrafficLights();
00247             ncontrolled.push_back(n);
00248         }
00249     }
00250 
00251     // loop#1 checking whether the node shall be tls controlled,
00252     //  because it is assigned to a district
00253     if (oc.getBool("tls-guess.district-nodes")) {
00254         for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00255             NBNode *cur = (*i).second;
00256             if (cur->isNearDistrict()&&find(ncontrolled.begin(), ncontrolled.end(), cur)==ncontrolled.end()) {
00257                 setAsTLControlled(cur, tlc);
00258             }
00259         }
00260     }
00261 
00262     // maybe no tls shall be guessed
00263     if (!oc.getBool("guess-tls")) {
00264         return;
00265     }
00266 
00267     // guess joined tls first, if wished
00268     if (oc.getBool("tls-guess.joining")) {
00269         // get node clusters
00270         SUMOReal MAXDIST = 25;
00271         std::vector<std::set<NBNode*> > cands;
00272         generateNodeClusters(MAXDIST, cands);
00273         // check these candidates (clusters) whether they should be controlled by a tls
00274         for (std::vector<std::set<NBNode*> >::iterator i=cands.begin(); i!=cands.end();) {
00275             std::set<NBNode*> &c = (*i);
00276             // regard only junctions which are not yet controlled and are not
00277             //  forbidden to be controlled
00278             for (std::set<NBNode*>::iterator j=c.begin(); j!=c.end();) {
00279                 if ((*j)->isTLControlled()||find(ncontrolled.begin(), ncontrolled.end(), *j)!=ncontrolled.end()) {
00280                     c.erase(j++);
00281                 } else {
00282                     ++j;
00283                 }
00284             }
00285             // check whether the cluster should be controlled
00286             if (!shouldBeTLSControlled(c)) {
00287                 i = cands.erase(i);
00288             } else {
00289                 ++i;
00290             }
00291         }
00292         // cands now only contain sets of junctions that shall be joined into being tls-controlled
00293         unsigned int index = 0;
00294         for (std::vector<std::set<NBNode*> >::iterator i=cands.begin(); i!=cands.end(); ++i) {
00295             std::vector<NBNode*> nodes;
00296             for (std::set<NBNode*>::iterator j=(*i).begin(); j!=(*i).end(); j++) {
00297                 nodes.push_back(*j);
00298             }
00299             std::string id = "joinedG_" + toString(index++);
00300             NBTrafficLightDefinition *tlDef = new NBOwnTLDef(id, nodes);
00301             if (!tlc.insert(tlDef)) {
00302                 // actually, nothing should fail here
00303                 WRITE_WARNING("Could not build guessed, joined tls");
00304                 delete tlDef;
00305                 return;
00306             }
00307         }
00308     }
00309 
00310     // guess tls
00311     for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00312         NBNode *cur = (*i).second;
00313         //  do nothing if already is tl-controlled
00314         if (cur->isTLControlled()) {
00315             continue;
00316         }
00317         // do nothing if in the list of explicite non-controlled junctions
00318         if (find(ncontrolled.begin(), ncontrolled.end(), cur)!=ncontrolled.end()) {
00319             continue;
00320         }
00321         std::set<NBNode*> c;
00322         c.insert(cur);
00323         if (!shouldBeTLSControlled(c)||cur->getIncomingEdges().size()<3) {
00324             continue;
00325         }
00326         setAsTLControlled((*i).second, tlc);
00327     }
00328 }

bool NBNodeCont::insert ( NBNode node  )  throw ()

Inserts a node into the map.

Parameters:
[in] node The node to insert
Returns:
Whether the node could be added (no other with the same id or position is stored)

Definition at line 111 of file NBNodeCont.cpp.

References myNodes.

00111                                        {
00112     std::string id = node->getID();
00113     NodeCont::iterator i = myNodes.find(id);
00114     if (i!=myNodes.end()) {
00115         return false;
00116     }
00117     myNodes[id] = node;
00118     return true;
00119 }

Position2D NBNodeCont::insert ( const std::string &  id  )  throw ()

Inserts a node into the map.

Parameters:
[in] id The node's id
Returns:
Whether the node could be added (no other with the same id is stored)

Definition at line 97 of file NBNodeCont.cpp.

References myNodes.

00097                                               {
00098     std::pair<SUMOReal, SUMOReal> ret(-1.0, -1.0);
00099     NodeCont::iterator i = myNodes.find(id);
00100     if (i!=myNodes.end()) {
00101         return (*i).second->getPosition();
00102     } else {
00103         NBNode *node = new NBNode(id, Position2D(-1.0, -1.0));
00104         myNodes[id] = node;
00105     }
00106     return Position2D(-1, -1);
00107 }

bool NBNodeCont::insert ( const std::string &  id,
const Position2D position 
) throw ()

Inserts a node into the map.

Parameters:
[in] id The node's id
[in] position The node's position
Returns:
Whether the node could be added (no other with the same id or position is stored)

Definition at line 85 of file NBNodeCont.cpp.

References myNodes.

00085                                                                           {
00086     NodeCont::iterator i = myNodes.find(id);
00087     if (i!=myNodes.end()) {
00088         return false;
00089     }
00090     NBNode *node = new NBNode(id, position);
00091     myNodes[id] = node;
00092     return true;
00093 }

bool NBNodeCont::insert ( const std::string &  id,
const Position2D position,
NBDistrict district 
) throw ()

Inserts a node into the map.

Parameters:
[in] id The node's id
[in] position The node's position
[in] A district assigned to the node
Returns:
Whether the node could be added (no other with the same id or position is stored)

Definition at line 72 of file NBNodeCont.cpp.

References myNodes.

Referenced by NIImporter_SUMO::addJunction(), NIImporter_VISUM::buildDistrictNode(), NIVissimNodeCluster::buildNBNode(), buildOffRamp(), buildOnRamp(), NIVissimDistrictConnection::dict_BuildDistrictNodes(), NIVissimEdge::getFromNode(), NIVissimEdge::getToNode(), guessRamps(), NIXMLEdgesHandler::insertNodeChecking(), NIImporter_ArcView::load(), NIImporter_OpenDrive::loadNetwork(), NIImporter_RobocupRescue::loadNodes(), NIXMLEdgesHandler::myEndElement(), NIXMLNodesHandler::myStartElement(), NIImporter_VISUM::parse_Lanes(), NIImporter_VISUM::parse_Nodes(), NIVissimEdge::remapOneOfNodes(), NIImporter_DlrNavteq::NodesHandler::report(), NIVissimEdge::resolveSameNode(), NBEdge::splitGeometry(), and NGNet::toNB().

00073                                                  {
00074     NodeCont::iterator i = myNodes.find(id);
00075     if (i!=myNodes.end()) {
00076         return false;
00077     }
00078     NBNode *node = new NBNode(id, position, district);
00079     myNodes[id] = node;
00080     return true;
00081 }

void NBNodeCont::joinTLS ( NBTrafficLightLogicCont tlc  ) 

Builds clusters of tls-controlled junctions and joins the control if possible.

Parameters:
changed] tlc The traffic lights control for adding/removing new/prior tls
Todo:
Recheck exception handling

Definition at line 332 of file NBNodeCont.cpp.

References generateNodeClusters(), NBTrafficLightLogicCont::insert(), NBTrafficLightLogicCont::remove(), SUMOReal, toString(), and WRITE_WARNING.

Referenced by NBNetBuilder::compute().

00332                                                 {
00333     SUMOReal MAXDIST = 25;
00334     std::vector<std::set<NBNode*> > cands;
00335     generateNodeClusters(MAXDIST, cands);
00336     unsigned int index = 0;
00337     for (std::vector<std::set<NBNode*> >::iterator i=cands.begin(); i!=cands.end(); ++i) {
00338         std::set<NBNode*> &c = (*i);
00339         for (std::set<NBNode*>::iterator j=c.begin(); j!=c.end();) {
00340             if (!(*j)->isTLControlled()) {
00341                 c.erase(j++);
00342             } else {
00343                 ++j;
00344             }
00345         }
00346         if (c.size()<2) {
00347             continue;
00348         }
00349         for (std::set<NBNode*>::iterator j=c.begin(); j!=c.end(); ++j) {
00350             std::set<NBTrafficLightDefinition*> tls = (*j)->getControllingTLS();
00351             (*j)->removeTrafficLights();
00352             for (std::set<NBTrafficLightDefinition*>::iterator k=tls.begin(); k!=tls.end(); ++k) {
00353                 tlc.remove((*j)->getID());
00354             }
00355         }
00356         std::string id = "joinedS_" + toString(index++);
00357         std::vector<NBNode*> nodes;
00358         for (std::set<NBNode*>::iterator j=c.begin(); j!=c.end(); j++) {
00359             nodes.push_back(*j);
00360         }
00361         NBTrafficLightDefinition *tlDef = new NBOwnTLDef(id, nodes);
00362         if (!tlc.insert(tlDef)) {
00363             // actually, nothing should fail here
00364             WRITE_WARNING("Could not build a joined tls.");
00365             delete tlDef;
00366             return;
00367         }
00368     }
00369 }

bool NBNodeCont::mayNeedOffRamp ( OptionsCont oc,
NBNode cur 
) const [private]

Definition at line 1002 of file NBNodeCont.cpp.

References OptionsCont::getFloat(), NBNode::getIncomingEdges(), NBEdge::getNoLanes(), NBNode::getOutgoingEdges(), NBEdge::getSpeed(), and NBEdge::isMacroscopicConnector().

Referenced by guessRamps().

01002                                                              {
01003     if (cur->getIncomingEdges().size()==1&&cur->getOutgoingEdges().size()==2) {
01004         // may be an off-ramp
01005         NBEdge *pot_highway = cur->getOutgoingEdges()[0];
01006         NBEdge *pot_ramp = cur->getOutgoingEdges()[1];
01007         NBEdge *prev = cur->getIncomingEdges()[0];
01008 
01009         // do not build ramps on connectors
01010         if (pot_highway->isMacroscopicConnector()||pot_ramp->isMacroscopicConnector()||prev->isMacroscopicConnector()) {
01011             return false;
01012         }
01013 
01014         // check whether a lane is missing
01015         if (pot_highway->getNoLanes()+pot_ramp->getNoLanes()<=prev->getNoLanes()) {
01016             return false;
01017         }
01018 
01019         // assign highway/ramp properly
01020         if (pot_highway->getSpeed()<pot_ramp->getSpeed()) {
01021             std::swap(pot_highway, pot_ramp);
01022         } else if (pot_highway->getSpeed()==pot_ramp->getSpeed()
01023                    &&
01024                    pot_highway->getNoLanes()<pot_ramp->getNoLanes()) {
01025 
01026             std::swap(pot_highway, pot_ramp);
01027         }
01028 
01029         // check conditions
01030         // is it really a highway?
01031         if (pot_highway->getSpeed()<oc.getFloat("ramp-guess.min-highway-speed")
01032                 ||
01033                 prev->getSpeed()<oc.getFloat("ramp-guess.min-highway-speed")) {
01034             return false;
01035         }
01036         // is it really a ramp?
01037         if (oc.getFloat("ramp-guess.max-ramp-speed")>0
01038                 &&
01039                 oc.getFloat("ramp-guess.max-ramp-speed")<pot_ramp->getSpeed()) {
01040             return false;
01041         }
01042 
01043         return true;
01044     }
01045     return false;
01046 }

bool NBNodeCont::mayNeedOnRamp ( OptionsCont oc,
NBNode cur 
) const [private]

Definition at line 722 of file NBNodeCont.cpp.

References OptionsCont::getFloat(), NBNode::getIncomingEdges(), NBEdge::getNoLanes(), NBNode::getOutgoingEdges(), NBEdge::getSpeed(), and NBEdge::isMacroscopicConnector().

Referenced by guessRamps().

00722                                                             {
00723     if (cur->getIncomingEdges().size()==2&&cur->getOutgoingEdges().size()==1) {
00724         // may be an on-ramp
00725         NBEdge *pot_highway = cur->getIncomingEdges()[0];
00726         NBEdge *pot_ramp = cur->getIncomingEdges()[1];
00727         NBEdge *cont = cur->getOutgoingEdges()[0];
00728 
00729         // do not build ramps on connectors
00730         if (pot_highway->isMacroscopicConnector()||pot_ramp->isMacroscopicConnector()||cont->isMacroscopicConnector()) {
00731             return false;
00732         }
00733 
00734         // check whether a lane is missing
00735         if (pot_highway->getNoLanes()+pot_ramp->getNoLanes()<=cont->getNoLanes()) {
00736             return false;
00737         }
00738 
00739         // assign highway/ramp properly
00740         if (pot_highway->getSpeed()<pot_ramp->getSpeed()) {
00741             std::swap(pot_highway, pot_ramp);
00742         } else if (pot_highway->getSpeed()==pot_ramp->getSpeed()
00743                    &&
00744                    pot_highway->getNoLanes()<pot_ramp->getNoLanes()) {
00745 
00746             std::swap(pot_highway, pot_ramp);
00747         }
00748 
00749         // check conditions
00750         // is it really a highway?
00751         if (pot_highway->getSpeed()<oc.getFloat("ramp-guess.min-highway-speed")
00752                 ||
00753                 cont->getSpeed()<oc.getFloat("ramp-guess.min-highway-speed")) {
00754             return false;
00755         }
00756         // is it really a ramp?
00757         if (oc.getFloat("ramp-guess.max-ramp-speed")>0
00758                 &&
00759                 oc.getFloat("ramp-guess.max-ramp-speed")<pot_ramp->getSpeed()) {
00760             return false;
00761         }
00762 
00763         // ok, may be
00764         return true;
00765     }
00766     return false;
00767 }

NBNodeCont& NBNodeCont::operator= ( const NBNodeCont s  )  [private]

invalidated assignment operator

void NBNodeCont::printBuiltNodesStatistics (  )  const throw ()

Prints statistics about built nodes.

Goes through stored nodes, computes the numbers of unregulated, priority and right-before-left junctions and prints them.

Definition at line 1220 of file NBNodeCont.cpp.

References myNodes, NBNode::NODETYPE_DISTRICT, NBNode::NODETYPE_NOJUNCTION, NBNode::NODETYPE_PRIORITY_JUNCTION, NBNode::NODETYPE_RIGHT_BEFORE_LEFT, NBNode::NODETYPE_TRAFFIC_LIGHT, NBNode::NODETYPE_UNKNOWN, toString(), and WRITE_MESSAGE.

Referenced by NBNetBuilder::compute().

01220                                                     {
01221     int noDistricts = 0;
01222     int noUnregulatedJunctions = 0;
01223     int noPriorityJunctions = 0;
01224     int noRightBeforeLeftJunctions = 0;
01225     for (NodeCont::const_iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
01226         switch ((*i).second->getType()) {
01227         case NBNode::NODETYPE_NOJUNCTION:
01228             ++noUnregulatedJunctions;
01229             break;
01230         case NBNode::NODETYPE_PRIORITY_JUNCTION:
01231         case NBNode::NODETYPE_TRAFFIC_LIGHT:
01232             ++noPriorityJunctions;
01233             break;
01234         case NBNode::NODETYPE_RIGHT_BEFORE_LEFT:
01235             ++noRightBeforeLeftJunctions;
01236             break;
01237         case NBNode::NODETYPE_DISTRICT:
01238             ++noRightBeforeLeftJunctions;
01239             break;
01240         case NBNode::NODETYPE_UNKNOWN:
01241             break;
01242         default:
01243             break;
01244         }
01245     }
01246     WRITE_MESSAGE(" Node type statistics:");
01247     WRITE_MESSAGE("  Unregulated junctions       : " + toString(noUnregulatedJunctions));
01248     WRITE_MESSAGE("  Priority junctions          : " + toString(noPriorityJunctions));
01249     WRITE_MESSAGE("  Right-before-left junctions : " + toString(noRightBeforeLeftJunctions));
01250 }

void NBNodeCont::recheckEdges ( NBDistrictCont dc,
NBTrafficLightLogicCont tlc,
NBEdgeCont ec 
)

Joins edges connecting the same nodes.

Definition at line 468 of file NBNodeCont.cpp.

References NBEdge::getToNode(), NBEdgeCont::joinSameNodeConnectingEdges(), and myNodes.

Referenced by NBNetBuilder::compute().

00469                                          {
00470     for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00471         // count the edges to other nodes outgoing from the current
00472         //  node
00473         std::map<NBNode*, EdgeVector> connectionCount;
00474         const EdgeVector &outgoing = (*i).second->getOutgoingEdges();
00475         for (EdgeVector::const_iterator j=outgoing.begin(); j!=outgoing.end(); j++) {
00476             NBEdge *e = (*j);
00477             NBNode *connected = e->getToNode();
00478             if (connectionCount.find(connected)==connectionCount.end()) {
00479                 connectionCount[connected] = EdgeVector();
00480                 connectionCount[connected].push_back(e);
00481             } else {
00482                 connectionCount[connected].push_back(e);
00483             }
00484         }
00485         // check whether more than a single edge connect another node
00486         //  and join them
00487         std::map<NBNode*, EdgeVector>::iterator k;
00488         for (k=connectionCount.begin(); k!=connectionCount.end(); k++) {
00489             // possibly we do not have anything to join...
00490             if ((*k).second.size()<2) {
00491                 continue;
00492             }
00493             // for the edges that seem to be a single street,
00494             //  check whether the geometry is similar
00495             const EdgeVector &ev = (*k).second;
00496             typedef std::vector<EdgeVector> EdgeVV;
00497             EdgeVV geometryCombinations;
00498             for (EdgeVector::const_iterator l=ev.begin(); l!=ev.end(); ++l) {
00499                 // append the first one simply to the list of really joinable edges
00500                 if (geometryCombinations.size()==0) {
00501                     EdgeVector tmp;
00502                     tmp.push_back(*l);
00503                     geometryCombinations.push_back(tmp);
00504                     continue;
00505                 }
00506                 // check the lists of really joinable edges
00507                 bool wasPushed = false;
00508                 for (EdgeVV::iterator m=geometryCombinations.begin(); !wasPushed&&m!=geometryCombinations.end();) {
00509                     for (EdgeVector::iterator n=(*m).begin(); !wasPushed&&n!=(*m).end();) {
00510                         if ((*n)->isNearEnough2BeJoined2(*l)) {
00511                             (*m).push_back(*l);
00512                             wasPushed = true;
00513                         }
00514                         if (!wasPushed) {
00515                             ++n;
00516                         }
00517                     }
00518                     if (!wasPushed) {
00519                         ++m;
00520                     }
00521                 }
00522                 if (!wasPushed) {
00523                     EdgeVector tmp;
00524                     tmp.push_back(*l);
00525                     geometryCombinations.push_back(tmp);
00526                 }
00527             }
00528         }
00529         for (k=connectionCount.begin(); k!=connectionCount.end(); k++) {
00530             // join edges
00531             if ((*k).second.size()>1) {
00532                 ec.joinSameNodeConnectingEdges(dc, tlc, (*k).second);
00533             }
00534         }
00535     }
00536 }

void NBNodeCont::removeDummyEdges ( NBDistrictCont dc,
NBEdgeCont ec,
NBTrafficLightLogicCont tc 
)

Removes dummy edges (edges lying completely within a node).

Definition at line 637 of file NBNodeCont.cpp.

References myNodes, toString(), and WRITE_WARNING.

Referenced by NBNetBuilder::compute().

00638                                                           {
00639     unsigned int no = 0;
00640     for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00641         no += (*i).second->eraseDummies(dc, ec, tc);
00642     }
00643     if (no!=0) {
00644         WRITE_WARNING(toString(no) + " dummy edge(s) removed.");
00645     }
00646 }

void NBNodeCont::removeIsolatedRoads ( NBDistrictCont dc,
NBEdgeCont ec,
NBTrafficLightLogicCont tc 
)

Removes sequences of edges that are not connected with a junction. Simple roads without junctions sometimes remain when converting from OpenStreetMake, but they make no sense. Remaining empty nodes are also deleted.

Parameters:
[in] dc The district container needed if edges shall be removed
[in] ec The container with the edge to be tested

Definition at line 540 of file NBNodeCont.cpp.

References erase(), NBEdgeCont::erase(), NBEdgeCont::getAllNames(), NBEdge::getFromNode(), NBNode::getIncomingEdges(), OptionsCont::getOptions(), NBNode::getOutgoingEdges(), NBEdge::getToNode(), NBEdgeCont::retrieve(), and WRITE_WARNING.

Referenced by NBNetBuilder::compute().

00540                                                                                                {
00541     // Warn of isolated edges, i.e. a single edge with no connection to another edge
00542     int edgeCounter = 0;
00543     const std::vector<std::string> &edgeNames = ec.getAllNames();
00544     for (std::vector<std::string>::const_iterator it = edgeNames.begin(); it != edgeNames.end(); ++it) {
00545         // Test whether this node starts at a dead end, i.e. it has only one adjacent node
00546         // to which an edge exists and from which an edge may come.
00547         NBEdge *e = ec.retrieve(*it);
00548         if (e == 0) {
00549             continue;
00550         }
00551         NBNode* from = e->getFromNode();
00552         const EdgeVector &outgoingEdges = from->getOutgoingEdges();
00553         if (outgoingEdges.size() != 1) {
00554             // At this node, several edges or no edge start; so, this node is no dead end.
00555             continue;
00556         }
00557         const EdgeVector &incomingEdges = from->getIncomingEdges();
00558         if (incomingEdges.size() > 1) {
00559             // At this node, several edges end; so, this node is no dead end.
00560             continue;
00561         } else if (incomingEdges.size() == 1) {
00562             NBNode* fromNodeOfIncomingEdge = incomingEdges[0]->getFromNode();
00563             NBNode* toNodeOfOutgoingEdge = outgoingEdges[0]->getToNode();
00564             if (fromNodeOfIncomingEdge != toNodeOfOutgoingEdge) {
00565                 // At this node, an edge ends which is not the inverse direction of
00566                 // the starting node.
00567                 continue;
00568             }
00569         }
00570         // Now we know that the edge e starts a dead end.
00571         // Next we test if the dead end is isolated, i.e. does not lead to a junction
00572         bool hasJunction = false;
00573         std::vector<NBEdge*> road;
00574         NBEdge* eOld = 0;
00575         NBNode* to;
00576         std::set<NBNode*> adjacentNodes;
00577         do {
00578             road.push_back(e);
00579             eOld = e;
00580             from = e->getFromNode();
00581             to = e->getToNode();
00582             const EdgeVector &outgoingEdgesOfToNode = to->getOutgoingEdges();
00583             const EdgeVector &incomingEdgesOfToNode = to->getIncomingEdges();
00584             adjacentNodes.clear();
00585             for (EdgeVector::const_iterator itOfOutgoings=outgoingEdgesOfToNode.begin(); itOfOutgoings!=outgoingEdgesOfToNode.end(); ++itOfOutgoings) {
00586                 if ((*itOfOutgoings)->getToNode() != from        // The back path
00587                         && (*itOfOutgoings)->getToNode() != to   // A loop / dummy edge
00588                    ) {
00589                     e = *itOfOutgoings; // Probably the next edge
00590                 }
00591                 adjacentNodes.insert((*itOfOutgoings)->getToNode());
00592             }
00593             for (EdgeVector::const_iterator itOfIncomings=incomingEdgesOfToNode.begin(); itOfIncomings!=incomingEdgesOfToNode.end(); ++itOfIncomings) {
00594                 adjacentNodes.insert((*itOfIncomings)->getFromNode());
00595             }
00596             adjacentNodes.erase(to);  // Omit loops / dummy edges
00597             if (adjacentNodes.size() > 2) {
00598                 hasJunction = true;
00599             }
00600         } while (!hasJunction && eOld != e);
00601         if (!hasJunction) {
00602             edgeCounter += road.size();
00603             std::string warningString =
00604                 "Removed a road without junctions: ";
00605             for (std::vector<NBEdge*>::iterator roadIt = road.begin(); roadIt
00606                     != road.end(); ++roadIt) {
00607                 if (roadIt == road.begin()) {
00608                     warningString += (*roadIt)->getID();
00609                 } else {
00610                     warningString += ", " + (*roadIt)->getID();
00611                 }
00612 
00613                 NBNode* fromNode = (*roadIt)->getFromNode();
00614                 NBNode* toNode = (*roadIt)->getToNode();
00615                 ec.erase(dc, *roadIt);
00616                 if (fromNode->getIncomingEdges().size() == 0
00617                         && fromNode->getOutgoingEdges().size() == 0) {
00618                     // Node is empty; can be removed
00619                     erase(fromNode);
00620                 }
00621                 if (toNode->getIncomingEdges().size() == 0
00622                         && toNode->getOutgoingEdges().size() == 0) {
00623                     // Node is empty; can be removed
00624                     erase(toNode);
00625                 }
00626             }
00627             WRITE_WARNING(warningString);
00628         }
00629     }
00630     if (edgeCounter > 0 && !OptionsCont::getOptions().getBool("remove-isolated")) {
00631         WRITE_WARNING("Detected isolated roads. Use the option --remove-isolated to get a list of all affected edges.");
00632     }
00633 }

void NBNodeCont::removeUnwishedNodes ( NBDistrictCont dc,
NBEdgeCont ec,
NBTrafficLightLogicCont tlc,
bool  removeGeometryNodes 
) throw ()

Removes "unwished" nodes.

Removes nodes if a) no incoming/outgoing edges exist or b) if the node is a "geometry" node. In the second case, edges that participate at the node will be joined. Whether the node is a geometry node or not, is determined by a call to NBNode::checkIsRemovable. The node is removed from the list of tls-controlled nodes.

Parameters:
in,mod] dc The district container needed if a node shall be removed
in,mod] ec The edge container needed for joining edges
in,mod] tlc The traffic lights container to remove nodes from
[in] removeGeometryNodes Whether geometry nodes shall also be removed

Definition at line 665 of file NBNodeCont.cpp.

References NBEdge::append(), NBJoinedEdgesMap::appended(), NBNode::checkIsRemovable(), erase(), NBNode::getEdgesToJoin(), NBEdge::getID(), NBNode::getIncomingEdges(), NBNode::getOutgoingEdges(), NBEdge::getToNode(), gJoinedEdges, myNodes, NBNode::replaceIncoming(), toString(), and WRITE_MESSAGE.

Referenced by NBNetBuilder::compute().

00667                                                                   {
00668     unsigned int no = 0;
00669     std::vector<NBNode*> toRemove;
00670     for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00671         NBNode *current = (*i).second;
00672         bool remove = false;
00673         std::vector<std::pair<NBEdge*, NBEdge*> > toJoin;
00674         // check for completely empty nodes
00675         if (current->getOutgoingEdges().size()==0
00676                 &&
00677                 current->getIncomingEdges().size()==0) {
00678 
00679             // remove if empty
00680             remove = true;
00681         }
00682         // check for nodes which are only geometry nodes
00683         if (removeGeometryNodes) {
00684             if ((current->getOutgoingEdges().size()==1 && current->getIncomingEdges().size()==1)
00685                     ||
00686                     (current->getOutgoingEdges().size()==2 && current->getIncomingEdges().size()==2)) {
00687                 // ok, one in, one out or two in, two out
00688                 //  -> ask the node whether to join
00689                 remove = current->checkIsRemovable();
00690                 if (remove) {
00691                     toJoin = current->getEdgesToJoin();
00692                 }
00693             }
00694         }
00695         // remove the node and join the geometries when wished
00696         if (!remove) {
00697             continue;
00698         }
00699         for (std::vector<std::pair<NBEdge*, NBEdge*> >::iterator j=toJoin.begin(); j!=toJoin.end(); j++) {
00700             NBEdge *begin = (*j).first;
00701             NBEdge *continuation = (*j).second;
00702             begin->append(continuation);
00703             continuation->getToNode()->replaceIncoming(continuation, begin, 0);
00704             tlc.replaceRemoved(continuation, -1, begin, -1);
00705             gJoinedEdges.appended(begin->getID(), continuation->getID());
00706             ec.erase(dc, continuation);
00707         }
00708         toRemove.push_back(current);
00709         no++;
00710     }
00711     // erase all
00712     for (std::vector<NBNode*>::iterator j = toRemove.begin(); j
00713             != toRemove.end(); j++) {
00714         erase(*j);
00715     }
00716     WRITE_MESSAGE("   " + toString(no) + " nodes removed.");
00717 }

void NBNodeCont::reshiftNodePositions ( const SUMOReal  xoff,
const SUMOReal  yoff 
)

resets the node positions by the specified offset

Definition at line 389 of file NBNodeCont.cpp.

References myNodes.

Referenced by NBNetBuilder::compute().

00389                                                                          {
00390     for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00391         (*i).second->reshiftPosition(xoff, yoff);
00392     }
00393 }

NBNode * NBNodeCont::retrieve ( const Position2D position,
SUMOReal  offset = 0. 
) const throw ()

Returns the node with the given coordinates.

Parameters:
[in] position The position at which the node to retrieve lies
[in] offset An offset which can be applied in the case positions are blurred
Returns:
The node at the given position, or 0 if no such node exists

Definition at line 133 of file NBNodeCont.cpp.

References NBNode::getPosition(), myNodes, Position2D::x(), and Position2D::y().

00133                                                                               {
00134     for (NodeCont::const_iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00135         NBNode *node = (*i).second;
00136         if (fabs(node->getPosition().x()-position.x())<offset
00137                 &&
00138                 fabs(node->getPosition().y()-position.y())<offset) {
00139             return node;
00140         }
00141     }
00142     return 0;
00143 }

NBNode * NBNodeCont::retrieve ( const std::string &  id  )  const throw ()

bool NBNodeCont::savePlain ( const std::string &  file  ) 

Definition at line 1188 of file NBNodeCont.cpp.

References OutputDevice::close(), GEO_OUTPUT_ACCURACY, NBNode::getControllingTLS(), OutputDevice::getDevice(), NBNode::getID(), NBNode::getPosition(), NBNode::isTLControlled(), myNodes, OutputDevice::setPrecision(), GeoConvHelper::usingInverseGeoProjection(), OutputDevice::writeXMLHeader(), Position2D::x(), and Position2D::y().

Referenced by NBNetBuilder::compute().

01188                                            {
01189     OutputDevice& device = OutputDevice::getDevice(file);
01190     device.writeXMLHeader("nodes");
01191     for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
01192         NBNode *n = (*i).second;
01193         device << "   <node id=\"" << n->getID() << "\" ";
01194         if (GeoConvHelper::usingInverseGeoProjection()) {
01195             device.setPrecision(GEO_OUTPUT_ACCURACY);
01196             device << "x=\"" << n->getPosition().x() << "\" y=\"" << n->getPosition().y() << "\"";
01197             device.setPrecision();
01198         } else {
01199             device << "x=\"" << n->getPosition().x() << "\" y=\"" << n->getPosition().y() << "\"";
01200         }
01201         if (n->isTLControlled()) {
01202             device << " type=\"traffic_light\" tl=\"";
01203             const std::set<NBTrafficLightDefinition*> &tlss = n->getControllingTLS();
01204             for (std::set<NBTrafficLightDefinition*>::const_iterator t=tlss.begin(); t!=tlss.end(); ++t) {
01205                 if (t!=tlss.begin()) {
01206                     device << ",";
01207                 }
01208                 device << (*t)->getID();
01209             }
01210             device << "\"";
01211         }
01212         device << "/>\n";
01213     }
01214     device.close();
01215     return true;
01216 }

void NBNodeCont::setAsTLControlled ( NBNode node,
NBTrafficLightLogicCont tlc,
std::string  id = "" 
)

Sets the given node as being controlled by a tls.

Parameters:
[in] node The node that shall be controlled by a tls
[in] tlc The traffic lights control into which the new traffic light definition shall be stored
[in] id The id of the tls to add
Todo:
Recheck exception handling

Definition at line 373 of file NBNodeCont.cpp.

References NBNode::getID(), NBTrafficLightLogicCont::insert(), and WRITE_WARNING.

Referenced by NBNetBuilder::compute(), and guessTLs().

00373                                                                                       {
00374     if (id=="") {
00375         id = node->getID();
00376     }
00377     NBTrafficLightDefinition *tlDef = new NBOwnTLDef(id, node);
00378     if (!tlc.insert(tlDef)) {
00379         // actually, nothing should fail here
00380         WRITE_WARNING("Building a tl-logic for node '" + id + "' twice is not possible.");
00381         delete tlDef;
00382         return;
00383     }
00384 }

bool NBNodeCont::shouldBeTLSControlled ( const std::set< NBNode * > &  c  )  const throw () [private]

Returns whethe the given node cluster should be controlled by a tls.

Parameters:
[in] c The node cluster
Returns:
Whether this node cluster shall be controlled by a tls

Definition at line 204 of file NBNodeCont.cpp.

References SUMOReal.

Referenced by guessTLs().

00204                                                                         {
00205     unsigned int noIncoming = 0;
00206     unsigned int noOutgoing = 0;
00207     bool tooFast = false;
00208     SUMOReal f = 0;
00209     std::set<NBEdge*> seen;
00210     for (std::set<NBNode*>::const_iterator j=c.begin(); j!=c.end(); ++j) {
00211         const EdgeVector &edges = (*j)->getEdges();
00212         for (EdgeVector::const_iterator k=edges.begin(); k!=edges.end(); ++k) {
00213             if (c.find((*k)->getFromNode())!=c.end()&&c.find((*k)->getToNode())!=c.end()) {
00214                 continue;
00215             }
00216             if ((*j)->hasIncoming(*k)) {
00217                 ++noIncoming;
00218                 f += (SUMOReal)(*k)->getNoLanes() * (*k)->getLaneSpeed(0);
00219             } else {
00220                 ++noOutgoing;
00221             }
00222             if ((*k)->getLaneSpeed(0)*3.6>79) {
00223                 tooFast = true;
00224             }
00225         }
00226     }
00227     return !tooFast && f>=150./3.6 && c.size()!=0;
00228 }

unsigned int NBNodeCont::size (  )  const throw () [inline]

Returns the number of known nodes.

Returns:
The number of nodes stored in this container

Definition at line 178 of file NBNodeCont.h.

References myNodes.

Referenced by getFreeID(), NILoader::load(), and main().

00178                                       {
00179         return (unsigned int) myNodes.size();
00180     }

void NBNodeCont::sortNodesEdges ( bool  leftHand,
const NBTypeCont tc 
)

sorts the nodes' edges

Definition at line 415 of file NBNodeCont.cpp.

References myNodes.

Referenced by NBNetBuilder::compute().

00415                                                               {
00416     for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00417         (*i).second->sortNodesEdges(leftHand, tc);
00418     }
00419 }

void NBNodeCont::writeXML ( OutputDevice into  ) 

writes the nodes into the given ostream

Definition at line 450 of file NBNodeCont.cpp.

References myNodes.

Referenced by NBNetBuilder::save().

00450                                        {
00451     for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00452         (*i).second->writeXML(into);
00453     }
00454     into << "\n";
00455 }

void NBNodeCont::writeXMLInternalLinks ( OutputDevice into  ) 

Definition at line 423 of file NBNodeCont.cpp.

References myNodes.

Referenced by NBNetBuilder::save().

00423                                                     {
00424     for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00425         (*i).second->writeXMLInternalLinks(into);
00426     }
00427     into << "\n";
00428 }

void NBNodeCont::writeXMLInternalNodes ( OutputDevice into  ) 

Definition at line 441 of file NBNodeCont.cpp.

References myNodes.

Referenced by NBNetBuilder::save().

00441                                                     {
00442     for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00443         (*i).second->writeXMLInternalNodes(into);
00444     }
00445     into << "\n";
00446 }

void NBNodeCont::writeXMLInternalSuccInfos ( OutputDevice into  ) 

Definition at line 432 of file NBNodeCont.cpp.

References myNodes.

Referenced by NBNetBuilder::save().

00432                                                         {
00433     for (NodeCont::iterator i=myNodes.begin(); i!=myNodes.end(); i++) {
00434         (*i).second->writeXMLInternalSuccInfos(into);
00435     }
00436     into << "\n";
00437 }


Field Documentation

int NBNodeCont::myInternalID [private]

The running internal id.

Definition at line 269 of file NBNodeCont.h.


The documentation for this class was generated from the following files:

Generated on Wed May 5 00:06:52 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6