41#define DEBUGCOND (n.getID() == "C")
43#define DEBUGCOND2(obj) (true)
53 for (std::map<std::string, NBNode*>::const_iterator i = nc.
begin(); i != nc.
end(); ++i) {
63 for (std::vector<NBEdge*>::const_iterator k = incoming.begin(); k != incoming.end(); ++k) {
64 (*k)->setTurningDestination(
nullptr);
66 std::vector<Combination> combinations;
68 for (
NBEdge* outedge : outgoing) {
69 for (
NBEdge* e : incoming) {
72 if (signedAngle > 0 && signedAngle < 177 && e->getGeometry().back().distanceTo2D(outedge->getGeometry().front()) < POSITION_EPS) {
75#ifdef DEBUG_TURNAROUNDS
77 std::cout <<
"incoming=" << e->getID() <<
" outgoing=" << outedge->getID() <<
" signedAngle=" << signedAngle <<
" skipped\n";
82 double angle = fabs(signedAngle);
83#ifdef DEBUG_TURNAROUNDS
85 std::cout <<
"incoming=" << e->getID() <<
" outgoing=" << outedge->getID() <<
" relAngle=" <<
NBHelpers::relAngle(e->getAngleAtNode(node), outedge->getAngleAtNode(node)) <<
"\n";
88 const bool badPermissions = ((outedge->getPermissions() & e->getPermissions() & ~
SVC_PEDESTRIAN) == 0
90 && outedge->getPermissions() != e->getPermissions());
91 if (e->getFromNode() == outedge->getToNode()
92 && (angle > 120 || e->getFromNode()->getPosition() == e->getToNode()->getPosition())
113#ifdef DEBUG_TURNAROUNDS
115 std::cout <<
" inFA=" << inFA <<
" outFA=" << outFA <<
" sFA=" << signedFarAngle <<
"\n";
118 if (signedFarAngle > -160) {
125 if (badPermissions) {
133 combinations.push_back(c);
138 std::set<NBEdge*> seen;
139#ifdef DEBUG_TURNAROUNDS
141 std::cout <<
"check combinations at " << node->
getID() <<
"\n";
144 for (std::vector<Combination>::const_iterator j = combinations.begin(); j != combinations.end(); ++j) {
145#ifdef DEBUG_TURNAROUNDS
147 std::cout <<
" from=" << (*j).from->getID() <<
" to=" << (*j).to->getID() <<
" a=" << (*j).angle <<
"\n";
150 if (seen.find((*j).from) != seen.end() || seen.find((*j).to) != seen.end()) {
152 if ((*j).angle > 360 && warn) {
160 seen.insert((*j).from);
161 seen.insert((*j).to);
163 bool onlyPossible = (*j).from->getConnections().size() != 0 && !(*j).from->isConnectedTo((*j).to);
164#ifdef DEBUG_TURNAROUNDS
166 std::cout <<
" setTurningDestination from=" << (*j).from->getID() <<
" to=" << (*j).to->getID() <<
" onlyPossible=" << onlyPossible <<
"\n";
169 (*j).from->setTurningDestination((*j).to, onlyPossible);
185 if (dist <= length) {
205 if (dist <= length) {
230 for (std::map<std::string, NBNode*>::const_iterator i = nc.
begin(); i != nc.
end(); ++i) {
231 i->second->sortEdges(useNodeShape);
238 const std::vector<NBEdge*>::iterator& i1,
239 const std::vector<NBEdge*>::iterator& i2) {
259 const double rightBeforeLeftSpeed = oc.
getFloat(
"junctions.right-before-left.speed-threshold");
260 for (
const auto& nodeIt : nc) {
261 NBNode*
const n = nodeIt.second;
264 n->myTypeWasGuessed =
false;
269 || (oc.
getBool(
"keep-nodes-unregulated.district-nodes") && (
n->isNearDistrict() ||
n->isDistrict()))) {
274 bool waterway =
true;
275 for (
NBEdge* e :
n->getEdges()) {
287 if (
n->myIncomingEdges.size() == 1) {
292 if (
n->isSimpleContinuation()) {
297 if (
n->unsignalizedOperation()
298 && (
int)
n->getIncomingEdges().size() == 2
299 && (
int)
n->getOutgoingEdges().size() == 1) {
310 for (EdgeVector::const_iterator i =
n->myIncomingEdges.begin(); i !=
n->myIncomingEdges.end(); i++) {
311 for (EdgeVector::const_iterator j = i + 1; j !=
n->myIncomingEdges.end(); j++) {
313 if (
n->getOppositeIncoming(*j) == *i &&
n->myIncomingEdges.size() > 2) {
318 const double s1 = (*i)->getSpeed();
319 const double s2 = (*j)->getSpeed();
320 const int p1 = (*i)->getPriority();
321 const int p2 = (*j)->getPriority();
322 if (fabs(s1 - s2) > (9.5 / 3.6) ||
MAX2(s1, s2) >= rightBeforeLeftSpeed || p1 != p2) {
330 n->myTypeWasGuessed =
true;
337 for (std::map<std::string, NBNode*>::const_iterator i = nc.
begin(); i != nc.
end(); ++i) {
342 int numNonRailIn = 0;
343 int numNonRailOut = 0;
344 std::set<const NBNode*> nonRailNodes;
345 int numNonRailwayNonPed = 0;
346 for (
NBEdge* e :
n->getIncomingEdges()) {
350 numNonRailwayNonPed++;
352 nonRailNodes.insert(e->getFromNode());
357 for (
NBEdge* e :
n->getOutgoingEdges()) {
360 nonRailNodes.insert(e->getToNode());
363 if (numNonRailIn == 0 || numNonRailOut == 0 || numRailway == 0) {
365 WRITE_WARNINGF(
TL(
"Converting invalid rail_crossing to priority junction '%'."),
n->getID());
367 }
else if (numNonRailwayNonPed > 2 || nonRailNodes.size() > 2) {
369 WRITE_WARNINGF(
TL(
"Converting invalid rail_crossing to traffic_light at junction '%'."),
n->getID());
375 n->removeTrafficLight(tlDef);
388 bool hasRailway =
false;
389 for (
NBEdge* e :
n->getIncomingEdges()) {
404 for (
const auto& node : nc) {
406 for (
NBEdge*
const edge : node.second->myAllEdges) {
409 node.second->markBentPriority(
false);
411 if (node.second->myIncomingEdges.size() == 1 && node.second->myOutgoingEdges.size() == 1) {
421 e->setJunctionPriority(node.second, e->getPriority());
433 if (
n.myIncomingEdges.size() == 0 ||
n.myOutgoingEdges.size() == 0) {
436 int minPrio = std::numeric_limits<int>::max();
437 int maxPrio = -std::numeric_limits<int>::max();
438 int maxNumLanes = -std::numeric_limits<int>::max();
439 double maxSpeed = -std::numeric_limits<double>::max();
442 for (
NBEdge*
const edge :
n.myAllEdges) {
452 for (
NBEdge*
const edge :
n.myAllEdges) {
467 NBEdge* bestIn = incoming[0];
468 while (incoming.size() > 0 && (forceStraight ||
samePriority(bestIn, incoming[0], all))) {
469 bestIncoming.push_back(*incoming.begin());
470 incoming.erase(incoming.begin());
473 assert(outgoing.size() != 0);
476 const NBEdge*
const firstOut = outgoing[0];
477 while (outgoing.size() > 0 && (forceStraight ||
samePriority(firstOut, outgoing[0], all))) {
478 bestOutgoing.push_back(*outgoing.begin());
479 outgoing.erase(outgoing.begin());
482 const bool mainDirectionExplicit = (
483 bestIncoming.size() == 1 &&
n.myIncomingEdges.size() <= 2
484 && (incoming.size() == 0 || bestIncoming[0]->getPriority() > incoming[0]->getPriority())
485 && bestOutgoing.size() == 1 &&
n.myOutgoingEdges.size() <= 2
486 && (outgoing.size() == 0 || bestOutgoing[0]->getPriority() > outgoing[0]->getPriority())
487 && !bestIncoming[0]->isTurningDirectionAt(bestOutgoing[0]));
491 EdgeVector::iterator i;
492 std::map<NBEdge*, NBEdge*> counterIncomingEdges;
493 std::map<NBEdge*, NBEdge*> counterOutgoingEdges;
494 incoming =
n.myIncomingEdges;
495 outgoing =
n.myOutgoingEdges;
496 for (i = bestIncoming.begin(); i != bestIncoming.end(); ++i) {
498 counterIncomingEdges[*i] = *incoming.begin();
500 counterOutgoingEdges[*i] = *outgoing.begin();
502#ifdef DEBUG_SETPRIORITIES
504 std::map<std::string, std::string> tmp1;
505 for (
auto item : counterIncomingEdges) {
506 tmp1[item.first->getID()] = item.second->getID();
508 std::map<std::string, std::string> tmp2;
509 for (
auto item : counterOutgoingEdges) {
510 tmp2[item.first->getID()] = item.second->getID();
512 std::cout <<
"n=" <<
n.getID() <<
" forceStraight=" << forceStraight <<
" bestIn=" << bestIn->
getID() <<
" bestOut=" <<
toString(bestOutgoing)
513 <<
" counterBest=" << counterIncomingEdges.find(bestIncoming[0])->second->getID()
514 <<
" mainExplicit=" << mainDirectionExplicit
515 <<
" forceStraight=" << forceStraight
516 <<
"\n bestIncoming=" <<
toString(bestIncoming) <<
" allIncoming=" <<
toString(incoming)
517 <<
"\n bestOutgoing=" <<
toString(bestOutgoing) <<
" allOutgoing=" <<
toString(outgoing)
518 <<
"\n counterIncomingEdges=" <<
toString(tmp1)
519 <<
"\n counterOutgoingEdges=" <<
toString(tmp2)
526 const bool hasTLS =
n.isTLControlled();
529 if (bestIncoming.size() == 1) {
532 if (!mainDirectionExplicit && counterIncomingEdges.find(best1) != counterIncomingEdges.end()) {
536 NBEdge* s = counterIncomingEdges.find(best1)->second;
538 if (minAngleDiff > 180 - 45
544 assert(bestOutgoing.size() != 0);
549 if (!mainDirectionExplicit && counterOutgoingEdges.find(bestOut) != counterOutgoingEdges.end()) {
550 NBEdge* s = counterOutgoingEdges.find(bestOut)->second;
556#ifdef DEBUG_SETPRIORITIES
558 std::cout <<
" best1=" << best1->
getID() <<
" bestOut=" << bestOut->
getID() <<
" bestOutgoing=" <<
toString(bestOutgoing) <<
" mainDirectionExplicit=" << mainDirectionExplicit <<
" isBent=" << isBent <<
"\n";
561 if (isBent && hasTLS && !forceStraight) {
565 n.markBentPriority(isBent);
574 double bestAngle = -1;
575 NBEdge* bestFirst =
nullptr;
576 NBEdge* bestSecond =
nullptr;
577 for (i = bestIncoming.begin(); i != bestIncoming.end(); ++i) {
578 EdgeVector::iterator j;
584 for (j = i + 1; j != bestIncoming.end(); ++j) {
590 double score = forceStraight ?
getScore(t1, t2, minPrio, maxPrio, maxNumLanes, maxSpeed, all) : 0;
592 if (angle > bestAngle) {
594 bestAngle =
MAX2(angle, bestAngle);
602#ifdef DEBUG_SETPRIORITIES
604 std::cout <<
" bestFirst=" << bestFirst->
getID() <<
" bestOutgoingFirst=" <<
toString(bestOutgoing) <<
"\n";
607 if (bestOutgoing.size() != 0) {
612#ifdef DEBUG_SETPRIORITIES
614 std::cout <<
" bestSecond=" << bestSecond->
getID() <<
" bestOutgoingSecond=" <<
toString(bestOutgoing) <<
"\n";
617 if (bestOutgoing.size() != 0) {
621 if (isBent && hasTLS && !forceStraight) {
625 n.markBentPriority(isBent);
633 double normPrio1 = 1;
634 double normPrio2 = 1;
635 if (minPrio != maxPrio) {
636 normPrio1 = ((e1->
getPriority() - minPrio) / (maxPrio - minPrio)) * 0.9 + 0.1;
637 normPrio2 = ((e2->
getPriority() - minPrio) / (maxPrio - minPrio)) * 0.9 + 0.1;
651 const double a2 = bestSecond ==
nullptr ? a1 : bestSecond->
getAngleAtNode(&
n);
654 for (
NBEdge* e :
n.getIncomingEdges()) {
660 && (p1 & perm) == 0 && (p2 & perm) == 0) {
696 if (edges.size() < 2) {
699 int prio = edges[0] == excluded ? edges[1]->getPriority() : edges[0]->getPriority();
700 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 permissions is a waterway edge.
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ SVC_RAIL_CLASSES
classes which drive on tracks
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_TRAM
vehicle is a light rail
@ SVC_TAXI
vehicle is a taxi
@ SVC_BUS
vehicle is a bus
@ SVC_PEDESTRIAN
pedestrian
@ 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 legacyDegree(const double angle, const bool positive=false)
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
NBNode * getToNode() const
Returns the destination node of the edge.
const PositionVector & getGeometry() const
Returns the geometry of the edge.
double getSpeed() const
Returns the speed allowed on this edge.
const std::string & getID() const
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
int getNumLanesThatAllow(SVCPermissions permissions, bool allPermissions=true) const
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.
EdgeVector getIncomingEdges() const
Returns the list of incoming edges unsorted.
static void markBestParallel(const NBNode &n, NBEdge *bestFirst, NBEdge *bestSecond)
set priority for edges that are parallel to the best edges
static bool samePriority(const NBEdge *const e1, const NBEdge *const e2, SVCPermissions permissions)
Returns whether both edges have the same priority.
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 double getScore(const NBEdge *e1, const NBEdge *e2, int minPrio, int maxPrio, int maxNumLanes, double maxSpeed, SVCPermissions permissions)
score pair of edges for multi-criteria evaluatoin of angle, priority, laneNumber and speed
static double relAngle(double angle1, double angle2)
computes the relative angle between the two angles
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.
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node).
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node).
bool geometryLike() const
whether this is structurally similar to a geometry node
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 double getFarAngleAtNode(const NBEdge *e, const NBNode *n, double dist=50)
compute angle to junction at a point further away
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.
A point in 2D or 3D with translation and scaling methods.
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position (in radians bet...
double length() const
Returns the length.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
*brief user defined string literal for JSON values *sa std::size_t n
Stores the information about the angle between an incoming ("from") and an outgoing ("to") edge.