40 #define DEBUGCOND (n.getID() == "C")
50 for (std::map<std::string, NBNode*>::const_iterator i = nc.
begin(); i != nc.
end(); ++i) {
60 for (std::vector<NBEdge*>::const_iterator k = incoming.begin(); k != incoming.end(); ++k) {
61 (*k)->setTurningDestination(
nullptr);
63 std::vector<Combination> combinations;
65 for (std::vector<NBEdge*>::const_iterator j = outgoing.begin(); j != outgoing.end(); ++j) {
67 for (std::vector<NBEdge*>::const_iterator k = incoming.begin(); k != incoming.end(); ++k) {
71 if (signedAngle > 0 && signedAngle < 177 && e->getGeometry().back().distanceTo2D(outedge->
getGeometry().front()) < POSITION_EPS) {
76 double angle = fabs(signedAngle);
107 combinations.push_back(c);
112 std::set<NBEdge*> seen;
114 for (std::vector<Combination>::const_iterator j = combinations.begin(); j != combinations.end(); ++j) {
116 if (seen.find((*j).from) != seen.end() || seen.find((*j).to) != seen.end()) {
118 if ((*j).angle > 360 && warn) {
126 seen.insert((*j).from);
127 seen.insert((*j).to);
129 bool onlyPossible = (*j).from->getConnections().size() != 0 && !(*j).from->isConnectedTo((*j).to);
131 (*j).from->setTurningDestination((*j).to, onlyPossible);
141 for (std::map<std::string, NBNode*>::const_iterator i = nc.
begin(); i != nc.
end(); ++i) {
142 i->second->sortEdges(useNodeShape);
149 const std::vector<NBEdge*>::iterator& i1,
150 const std::vector<NBEdge*>::iterator& i2) {
170 const double rightBeforeLeftSpeed = oc.
getFloat(
"junctions.right-before-left.speed-threshold");
171 for (std::map<std::string, NBNode*>::const_iterator i = nc.
begin(); i != nc.
end(); ++i) {
172 NBNode*
const n = (*i).second;
185 bool waterway =
true;
215 for (EdgeVector::const_iterator j = i + 1; j != n->
myIncomingEdges.end(); j++) {
222 const double s1 = (*i)->getSpeed();
223 const double s2 = (*j)->getSpeed();
224 const int p1 = (*i)->getPriority();
225 const int p2 = (*j)->getPriority();
226 if (fabs(s1 - s2) > (9.5 / 3.6) ||
MAX2(s1, s2) >= rightBeforeLeftSpeed || p1 != p2) {
241 for (std::map<std::string, NBNode*>::const_iterator i = nc.
begin(); i != nc.
end(); ++i) {
246 int numNonRailway = 0;
247 int numNonRailwayNonPed = 0;
252 numNonRailwayNonPed++;
263 if (numNonRailway == 0 || numRailway == 0) {
266 }
else if (numNonRailwayNonPed > 2) {
268 WRITE_WARNINGF(
"Converting invalid rail_crossing to traffic_light at junction '%'.", n->
getID());
287 bool hasRailway =
false;
303 for (
const auto& node : nc) {
305 for (
NBEdge*
const edge : node.second->myAllEdges) {
308 node.second->markBentPriority(
false);
310 if (node.second->myIncomingEdges.size() == 1 && node.second->myOutgoingEdges.size() == 1) {
317 e->setJunctionPriority(node.second, e->getPriority());
332 int minPrio = std::numeric_limits<int>::max();
333 int maxPrio = -std::numeric_limits<int>::max();
334 int maxNumLanes = -std::numeric_limits<int>::max();
335 double maxSpeed = -std::numeric_limits<double>::max();
353 NBEdge* bestIn = incoming[0];
354 while (incoming.size() > 0 && (forceStraight ||
samePriority(bestIn, incoming[0]))) {
355 bestIncoming.push_back(*incoming.begin());
356 incoming.erase(incoming.begin());
359 assert(outgoing.size() != 0);
362 NBEdge* bestOut = outgoing[0];
363 while (outgoing.size() > 0 && (forceStraight ||
samePriority(bestOut, outgoing[0]))) {
364 bestOutgoing.push_back(*outgoing.begin());
365 outgoing.erase(outgoing.begin());
368 const bool mainDirectionExplicit = (
370 && (incoming.size() == 0 || bestIncoming[0]->getPriority() > incoming[0]->getPriority())
372 && (outgoing.size() == 0 || bestOutgoing[0]->getPriority() > outgoing[0]->getPriority())
373 && !bestIncoming[0]->isTurningDirectionAt(bestOutgoing[0]));
377 EdgeVector::iterator i;
378 std::map<NBEdge*, NBEdge*> counterIncomingEdges;
379 std::map<NBEdge*, NBEdge*> counterOutgoingEdges;
382 for (i = bestIncoming.begin(); i != bestIncoming.end(); ++i) {
384 counterIncomingEdges[*i] = *incoming.begin();
386 counterOutgoingEdges[*i] = *outgoing.begin();
388 #ifdef DEBUG_SETPRIORITIES
390 std::map<std::string, std::string> tmp1;
391 for (
auto item : counterIncomingEdges) {
392 tmp1[item.first->getID()] = item.second->getID();
394 std::map<std::string, std::string> tmp2;
395 for (
auto item : counterOutgoingEdges) {
396 tmp2[item.first->getID()] = item.second->getID();
398 std::cout <<
"n=" << n.
getID() <<
" bestIn=" << bestIn->
getID() <<
" bestOut=" << bestOut->
getID()
399 <<
" counterBest=" << counterIncomingEdges.find(bestIncoming[0])->second->getID()
400 <<
" mainExplicit=" << mainDirectionExplicit
401 <<
" forceStraight=" << forceStraight
402 <<
"\n bestIncoming=" <<
toString(bestIncoming) <<
" allIncoming=" <<
toString(incoming)
403 <<
"\n bestOutgoing=" <<
toString(bestOutgoing) <<
" allOutgoing=" <<
toString(outgoing)
404 <<
"\n counterIncomingEdges=" <<
toString(tmp1)
405 <<
"\n counterOutgoingEdges=" <<
toString(tmp2)
415 if (bestIncoming.size() == 1) {
418 if (!mainDirectionExplicit && counterIncomingEdges.find(best1) != counterIncomingEdges.end()) {
422 NBEdge* s = counterIncomingEdges.find(best1)->second;
424 if (minAngleDiff > 180 - 45
430 assert(bestOutgoing.size() != 0);
435 if (!mainDirectionExplicit && counterOutgoingEdges.find(bestOut) != counterOutgoingEdges.end()) {
436 NBEdge* s = counterOutgoingEdges.find(bestOut)->second;
442 #ifdef DEBUG_SETPRIORITIES
444 std::cout <<
" best1=" << best1->
getID() <<
" bestOut=" << bestOut->
getID() <<
" bestOutgoing=" <<
toString(bestOutgoing) <<
" mainDirectionExplicit=" << mainDirectionExplicit <<
" isBent=" << isBent <<
"\n";
447 if (isBent && hasTLS && !forceStraight) {
460 double bestAngle = -1;
461 NBEdge* bestFirst =
nullptr;
462 NBEdge* bestSecond =
nullptr;
463 for (i = bestIncoming.begin(); i != bestIncoming.end(); ++i) {
464 EdgeVector::iterator j;
470 for (j = i + 1; j != bestIncoming.end(); ++j) {
476 double score = forceStraight ?
getScore(t1, t2, minPrio, maxPrio, maxNumLanes, maxSpeed) : 0;
478 if (angle > bestAngle) {
480 bestAngle =
MAX2(angle, bestAngle);
488 #ifdef DEBUG_SETPRIORITIES
490 std::cout <<
" bestFirst=" << bestFirst->
getID() <<
" bestOutgoingFirst=" <<
toString(bestOutgoing) <<
"\n";
493 if (bestOutgoing.size() != 0) {
498 #ifdef DEBUG_SETPRIORITIES
500 std::cout <<
" bestSecond=" << bestSecond->
getID() <<
" bestOutgoingSecond=" <<
toString(bestOutgoing) <<
"\n";
503 if (bestOutgoing.size() != 0) {
507 if (isBent && hasTLS && !forceStraight) {
519 double normPrio1 = 1;
520 double normPrio2 = 1;
521 if (minPrio != maxPrio) {
522 normPrio1 = ((e1->
getPriority() - minPrio) / (maxPrio - minPrio)) * 0.9 + 0.1;
523 normPrio2 = ((e2->
getPriority() - minPrio) / (maxPrio - minPrio)) * 0.9 + 0.1;
537 const double a2 = bestSecond ==
nullptr ? a1 : bestSecond->
getAngleAtNode(&n);
546 && (p1 & perm) == 0 && (p2 & perm) == 0) {
547 e->setJunctionPriority(&n, 1);
582 if (edges.size() < 2) {
585 int prio = edges[0] == excluded ? edges[1]->
getPriority() : edges[0]->getPriority();
586 for (
auto e : edges) {
#define WRITE_WARNINGF(...)
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
bool isWaterway(SVCPermissions permissions)
Returns whether an edge with the given permission is a waterway edge.
@ SVC_RAIL_CLASSES
classes which drive on tracks
@ SVC_PEDESTRIAN
pedestrian
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ STRAIGHT
The link is a straight direction.
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static double getMinAngleDiff(double angle1, double angle2)
Returns the minimum distance (clockwise/counter-clockwise) between both angles.
Class to sort edges by their angle in relation to the given edge.
The representation of a single edge during network building.
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
const std::string & getID() const
NBNode * getToNode() const
Returns the destination node of the edge.
double getSpeed() const
Returns the speed allowed on this edge.
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
int getNumLanes() const
Returns the number of lanes.
const PositionVector & getGeometry() const
Returns the geometry of the edge.
double getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge's geometry at the given node.
int getPriority() const
Returns the priority of the edge.
void setJunctionPriority(const NBNode *const node, int prio)
Sets the junction priority of the edge.
NBNode * getFromNode() const
Returns the origin node of the edge.
EdgeVector getIncomingEdges() const
Returns the list of incoming edges unsorted.
static double getScore(const NBEdge *e1, const NBEdge *e2, int minPrio, int maxPrio, int maxNumLanes, double maxSpeed)
score pair of edges for multi-criteria evaluatoin of angle, priority, laneNumber and speed
static void markBestParallel(const NBNode &n, NBEdge *bestFirst, NBEdge *bestSecond)
set priority for edges that are parallel to the best edges
static NBEdge * extractAndMarkFirst(NBNode &n, std::vector< NBEdge * > &s, int prio=1)
Sets the priorites in case of a priority junction.
static bool hasDifferentPriorities(const EdgeVector &edges, const NBEdge *excluded)
return whether the priorite attribute can be used to distinguish the edges
static void computeEdgePriorities(NBNodeCont &nc)
Computes edge priorities within a node.
static void setPriorityJunctionPriorities(NBNode &n, bool forceStraight=false)
Sets the priorites in case of a priority junction.
static bool samePriority(const NBEdge *const e1, const NBEdge *const e2)
Returns whether both edges have the same priority.
static double normRelAngle(double angle1, double angle2)
ensure that reverse relAngles (>=179.999) always count as turnarounds (-180)
Container for nodes during the netbuilding process.
std::map< std::string, NBNode * >::const_iterator begin() const
Returns the pointer to the begin of the stored nodes.
std::map< std::string, NBNode * >::const_iterator end() const
Returns the pointer to the end of the stored nodes.
Represents a single node (junction) during network building.
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream's direction.
bool isSimpleContinuation(bool checkLaneNumbers=true, bool checkWidth=false) const
check if node is a simple continuation
bool myTypeWasGuessed
whether the node type was guessed rather than loaded
SumoXMLNodeType myType
The type of the junction.
EdgeVector myOutgoingEdges
Vector of outgoing edges.
EdgeVector myAllEdges
Vector of incoming and outgoing edges.
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node)
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
bool isDistrict() const
check if node is a district
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
void markBentPriority(bool isBent)
mark whether a priority road turns at this node
const Position & getPosition() const
bool geometryLike() const
whether this is structurally similar to a geometry node
bool isNearDistrict() const
@chech if node is near district
EdgeVector myIncomingEdges
Vector of incoming edges.
bool isTLControlled() const
Returns whether this node is controlled by any tls.
NBEdge * getOppositeIncoming(NBEdge *e) const
returns the opposite incoming edge of certain edge
static bool isRailwayNode(const NBNode *n)
whether the given node only has rail edges
static void computeNodeTypes(NBNodeCont &nc, NBTrafficLightLogicCont &tlc)
Computes node types.
static void validateRailCrossings(NBNodeCont &nc, NBTrafficLightLogicCont &tlc)
Checks rail_crossing for validity.
crossing_by_junction_angle_sorter(const NBNode *node, const EdgeVector &ordering)
static void swapWhenReversed(const NBNode *const n, const std::vector< NBEdge * >::iterator &i1, const std::vector< NBEdge * >::iterator &i2)
Assures correct order for same-angle opposite-direction edges.
static void sortNodesEdges(NBNodeCont &nc, bool useNodeShape=false)
Sorts a node's edges clockwise regarding driving direction.
A traffic light logics which must be computed (only nodes/edges are given)
The base class for traffic light logic definitions.
A container for traffic light definitions and built programs.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
Sorts "Combination"s by decreasing angle.
static void computeTurnDirections(NBNodeCont &nc, bool warn=true)
Computes turnaround destinations for all edges (if exist)
static void computeTurnDirectionsForNode(NBNode *node, bool warn)
Computes turnaround destinations for all incoming edges of the given nodes (if any)
const std::string & getID() const
Returns the id.
A storage for options typed value containers)
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
bool isInStringVector(const std::string &optionName, const std::string &itemName) const
Returns the named option is a list of string values containing the specified item.
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
T get(const std::string &str) const
Stores the information about the angle between an incoming ("from") and an outgoing ("to") edge.