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 (
const auto& nodeIt : nc) {
172 NBNode*
const n = nodeIt.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 numNonRailIn = 0;
247 int numNonRailOut = 0;
248 std::set<const NBNode*> nonRailNodes;
249 int numNonRailwayNonPed = 0;
254 numNonRailwayNonPed++;
256 nonRailNodes.insert(e->getFromNode());
264 nonRailNodes.insert(e->getToNode());
267 if (numNonRailIn == 0 || numNonRailOut == 0 || numRailway == 0) {
270 }
else if (numNonRailwayNonPed > 2 || nonRailNodes.size() > 2) {
272 WRITE_WARNINGF(
TL(
"Converting invalid rail_crossing to traffic_light at junction '%'."), n->
getID());
291 bool hasRailway =
false;
307 for (
const auto& node : nc) {
309 for (
NBEdge*
const edge : node.second->myAllEdges) {
312 node.second->markBentPriority(
false);
314 if (node.second->myIncomingEdges.size() == 1 && node.second->myOutgoingEdges.size() == 1) {
324 e->setJunctionPriority(node.second, e->getPriority());
339 int minPrio = std::numeric_limits<int>::max();
340 int maxPrio = -std::numeric_limits<int>::max();
341 int maxNumLanes = -std::numeric_limits<int>::max();
342 double maxSpeed = -std::numeric_limits<double>::max();
360 NBEdge* bestIn = incoming[0];
361 while (incoming.size() > 0 && (forceStraight ||
samePriority(bestIn, incoming[0]))) {
362 bestIncoming.push_back(*incoming.begin());
363 incoming.erase(incoming.begin());
366 assert(outgoing.size() != 0);
369 const NBEdge*
const firstOut = outgoing[0];
370 while (outgoing.size() > 0 && (forceStraight ||
samePriority(firstOut, outgoing[0]))) {
371 bestOutgoing.push_back(*outgoing.begin());
372 outgoing.erase(outgoing.begin());
375 const bool mainDirectionExplicit = (
377 && (incoming.size() == 0 || bestIncoming[0]->getPriority() > incoming[0]->getPriority())
379 && (outgoing.size() == 0 || bestOutgoing[0]->getPriority() > outgoing[0]->getPriority())
380 && !bestIncoming[0]->isTurningDirectionAt(bestOutgoing[0]));
384 EdgeVector::iterator i;
385 std::map<NBEdge*, NBEdge*> counterIncomingEdges;
386 std::map<NBEdge*, NBEdge*> counterOutgoingEdges;
389 for (i = bestIncoming.begin(); i != bestIncoming.end(); ++i) {
391 counterIncomingEdges[*i] = *incoming.begin();
393 counterOutgoingEdges[*i] = *outgoing.begin();
395#ifdef DEBUG_SETPRIORITIES
397 std::map<std::string, std::string> tmp1;
398 for (
auto item : counterIncomingEdges) {
399 tmp1[item.first->getID()] = item.second->getID();
401 std::map<std::string, std::string> tmp2;
402 for (
auto item : counterOutgoingEdges) {
403 tmp2[item.first->getID()] = item.second->getID();
405 std::cout <<
"n=" << n.
getID() <<
" bestIn=" << bestIn->
getID() <<
" bestOut=" << bestOut->getID()
406 <<
" counterBest=" << counterIncomingEdges.find(bestIncoming[0])->second->getID()
407 <<
" mainExplicit=" << mainDirectionExplicit
408 <<
" forceStraight=" << forceStraight
409 <<
"\n bestIncoming=" <<
toString(bestIncoming) <<
" allIncoming=" <<
toString(incoming)
410 <<
"\n bestOutgoing=" <<
toString(bestOutgoing) <<
" allOutgoing=" <<
toString(outgoing)
411 <<
"\n counterIncomingEdges=" <<
toString(tmp1)
412 <<
"\n counterOutgoingEdges=" <<
toString(tmp2)
422 if (bestIncoming.size() == 1) {
425 if (!mainDirectionExplicit && counterIncomingEdges.find(best1) != counterIncomingEdges.end()) {
429 NBEdge* s = counterIncomingEdges.find(best1)->second;
431 if (minAngleDiff > 180 - 45
437 assert(bestOutgoing.size() != 0);
442 if (!mainDirectionExplicit && counterOutgoingEdges.find(bestOut) != counterOutgoingEdges.end()) {
443 NBEdge* s = counterOutgoingEdges.find(bestOut)->second;
449#ifdef DEBUG_SETPRIORITIES
451 std::cout <<
" best1=" << best1->
getID() <<
" bestOut=" << bestOut->
getID() <<
" bestOutgoing=" <<
toString(bestOutgoing) <<
" mainDirectionExplicit=" << mainDirectionExplicit <<
" isBent=" << isBent <<
"\n";
454 if (isBent && hasTLS && !forceStraight) {
467 double bestAngle = -1;
468 NBEdge* bestFirst =
nullptr;
469 NBEdge* bestSecond =
nullptr;
470 for (i = bestIncoming.begin(); i != bestIncoming.end(); ++i) {
471 EdgeVector::iterator j;
477 for (j = i + 1; j != bestIncoming.end(); ++j) {
483 double score = forceStraight ?
getScore(t1, t2, minPrio, maxPrio, maxNumLanes, maxSpeed) : 0;
485 if (angle > bestAngle) {
487 bestAngle =
MAX2(angle, bestAngle);
495#ifdef DEBUG_SETPRIORITIES
497 std::cout <<
" bestFirst=" << bestFirst->
getID() <<
" bestOutgoingFirst=" <<
toString(bestOutgoing) <<
"\n";
500 if (bestOutgoing.size() != 0) {
505#ifdef DEBUG_SETPRIORITIES
507 std::cout <<
" bestSecond=" << bestSecond->
getID() <<
" bestOutgoingSecond=" <<
toString(bestOutgoing) <<
"\n";
510 if (bestOutgoing.size() != 0) {
514 if (isBent && hasTLS && !forceStraight) {
526 double normPrio1 = 1;
527 double normPrio2 = 1;
528 if (minPrio != maxPrio) {
529 normPrio1 = ((e1->
getPriority() - minPrio) / (maxPrio - minPrio)) * 0.9 + 0.1;
530 normPrio2 = ((e2->
getPriority() - minPrio) / (maxPrio - minPrio)) * 0.9 + 0.1;
544 const double a2 = bestSecond ==
nullptr ? a1 : bestSecond->
getAngleAtNode(&n);
553 && (p1 & perm) == 0 && (p2 & perm) == 0) {
554 e->setJunctionPriority(&n, 1);
589 if (edges.size() < 2) {
592 int prio = edges[0] == excluded ? edges[1]->
getPriority() : edges[0]->getPriority();
593 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
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 getNumLanes() const
Returns the number of lanes.
NBNode * getFromNode() const
Returns the origin node 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.
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.
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)
EdgeVector myAllEdges
Vector of incoming and outgoing edges.
bool isDistrict() const
check if node is a district
const Position & getPosition() const
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node)
void markBentPriority(bool isBent)
mark whether a priority road turns at this node
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
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Stores the information about the angle between an incoming ("from") and an outgoing ("to") edge.