52 for (std::map<std::string, NBNode*>::const_iterator i = nc.
begin(); i != nc.
end(); ++i) {
62 for (std::vector<NBEdge*>::const_iterator k = incoming.begin(); k != incoming.end(); ++k) {
63 (*k)->setTurningDestination(0);
65 std::vector<Combination> combinations;
66 for (std::vector<NBEdge*>::const_iterator j = outgoing.begin(); j != outgoing.end(); ++j) {
68 for (std::vector<NBEdge*>::const_iterator k = incoming.begin(); k != incoming.end(); ++k) {
72 if (signedAngle > 0 && signedAngle < 177 && e->getGeometry().back().distanceTo2D(outedge->
getGeometry().front()) <
POSITION_EPS) {
77 double angle = fabs(signedAngle);
99 combinations.push_back(c);
104 std::set<NBEdge*> seen;
105 for (std::vector<Combination>::const_iterator j = combinations.begin(); j != combinations.end(); ++j) {
106 if (seen.find((*j).from) != seen.end() || seen.find((*j).to) != seen.end()) {
108 if ((*j).angle > 360 && warn) {
109 WRITE_WARNING(
"Ambiguity in turnarounds computation at junction '" + node->
getID() +
"'.");
115 seen.insert((*j).from);
116 seen.insert((*j).to);
118 bool onlyPossible = (*j).from->getConnections().size() != 0 && !(*j).from->isConnectedTo((*j).to);
120 (*j).from->setTurningDestination((*j).to, onlyPossible);
130 for (std::map<std::string, NBNode*>::const_iterator i = nc.
begin(); i != nc.
end(); ++i) {
131 i->second->sortEdges(useNodeShape);
138 const std::vector<NBEdge*>::iterator& i1,
139 const std::vector<NBEdge*>::iterator& i2) {
157 for (std::map<std::string, NBNode*>::const_iterator i = nc.
begin(); i != nc.
end(); ++i) {
164 bool waterway =
true;
165 for (EdgeVector::const_iterator i = n->
getEdges().begin(); i != n->
getEdges().end(); ++i) {
189 for (EdgeVector::const_iterator j = i + 1; j != n->
myIncomingEdges.end(); j++) {
196 const double s1 = (*i)->getSpeed() * (double) 3.6;
197 const double s2 = (*j)->getSpeed() * (double) 3.6;
198 const int p1 = (*i)->getPriority();
199 const int p2 = (*j)->getPriority();
200 if (fabs(s1 - s2) > (
double) 9.5 ||
MAX2(s1, s2) >= (
double) 49. || p1 != p2) {
218 bool waterway =
true;
219 for (EdgeVector::const_iterator i = node->
getEdges().begin(); i != node->
getEdges().end(); ++i) {
240 for (EdgeVector::const_iterator j = i + 1; j != node->
myIncomingEdges.end(); j++) {
247 const double s1 = (*i)->getSpeed() * (double) 3.6;
248 const double s2 = (*j)->getSpeed() * (double) 3.6;
249 const int p1 = (*i)->getPriority();
250 const int p2 = (*j)->getPriority();
251 if (fabs(s1 - s2) > (
double) 9.5 ||
MAX2(s1, s2) >= (
double) 49. || p1 != p2) {
266 for (std::map<std::string, NBNode*>::const_iterator i = nc.
begin(); i != nc.
end(); ++i) {
267 computeEdgePrioritiesSingleNode((*i).second);
284 setPriorityJunctionPriorities(*node);
301 NBEdge* best = incoming[0];
302 while (incoming.size() > 0 && samePriority(best, incoming[0])) {
303 bestIncoming.push_back(*incoming.begin());
304 incoming.erase(incoming.begin());
307 assert(outgoing.size() != 0);
311 while (outgoing.size() > 0 && samePriority(best, outgoing[0])) {
312 bestOutgoing.push_back(*outgoing.begin());
313 outgoing.erase(outgoing.begin());
316 const bool mainDirectionExplicit = (
318 && (incoming.size() == 0 || bestIncoming[0]->getPriority() > incoming[0]->getPriority())
320 && (outgoing.size() == 0 || bestOutgoing[0]->getPriority() > outgoing[0]->getPriority())
321 && !bestIncoming[0]->isTurningDirectionAt(bestOutgoing[0]));
325 EdgeVector::iterator i;
326 std::map<NBEdge*, NBEdge*> counterIncomingEdges;
327 std::map<NBEdge*, NBEdge*> counterOutgoingEdges;
330 for (i = bestIncoming.begin(); i != bestIncoming.end(); ++i) {
332 counterIncomingEdges[*i] = *incoming.begin();
334 counterOutgoingEdges[*i] = *outgoing.begin();
339 if (bestIncoming.size() == 1) {
341 NBEdge* best1 = extractAndMarkFirst(n, bestIncoming);
342 if (!mainDirectionExplicit && counterIncomingEdges.find(best1) != counterIncomingEdges.end()) {
346 NBEdge* s = counterIncomingEdges.find(best1)->second;
348 if (minAngleDiff > 180 - 45
349 || (minAngleDiff > 75 && s->
getPriority() == best1->
getPriority() && hasDifferentPriorities(incoming, best1))) {
353 assert(bestOutgoing.size() != 0);
357 best1 = extractAndMarkFirst(n, bestOutgoing);
358 if (!mainDirectionExplicit && counterOutgoingEdges.find(best1) != counterOutgoingEdges.end()) {
359 NBEdge* s = counterOutgoingEdges.find(best1)->second;
371 double bestAngle = 0;
374 bool hadBest =
false;
375 for (i = bestIncoming.begin(); i != bestIncoming.end(); ++i) {
376 EdgeVector::iterator j;
382 for (j = i + 1; j != bestIncoming.end(); ++j) {
389 if (!hadBest || angle > bestAngle) {
399 if (bestOutgoing.size() != 0) {
400 extractAndMarkFirst(n, bestOutgoing);
404 if (bestOutgoing.size() != 0) {
405 extractAndMarkFirst(n, bestOutgoing);
439 if (edges.size() < 2) {
442 int prio = edges[0] == excluded ? edges[1]->
getPriority() : edges[0]->getPriority();
443 for (
auto e : edges) {
454 myOrdering = ordering;
457 rotate(myOrdering.begin(), std::find(myOrdering.begin(), myOrdering.end(), ordering.front()), myOrdering.end());
static double getMinAngleDiff(double angle1, double angle2)
Returns the minimum distance (clockwise/counter-clockwise) between both angles.
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.
static double normRelAngle(double angle1, double angle2)
ensure that reverse relAngles (>=179.999) always count as turnarounds (-180)
SumoXMLNodeType myType
The type of the junction.
int getPriority() const
Returns the priority of the edge.
The representation of a single edge during network building.
Class to sort edges by their angle in relation to the given edge.
static void computeSingleNodeType(NBNode *node)
Computes a single node type.
const std::string & getID() const
Returns the id.
static void sortNodesEdges(NBNodeCont &nc, bool useNodeShape=false)
Sorts a node's edges clockwise regarding driving direction.
Stores the information about the angle between an incoming ("from") and an outgoing ("to") edge...
#define WRITE_WARNING(msg)
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
static bool hasDifferentPriorities(const EdgeVector &edges, const NBEdge *excluded)
return whether the priorite attribute can be used to distinguish the edges
EdgeVector myAllEdges
Vector of incoming and outgoing edges.
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.
int getNumLanes() const
Returns the number of lanes.
static void computeEdgePriorities(NBNodeCont &nc)
Computes edge priorities within a node.
bool isWaterway(SVCPermissions permissions)
Returns whether an edge with the given permission is a waterway edge.
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node) ...
double getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge's geometry at the given node.
crossing_by_junction_angle_sorter(const NBNode *node, const EdgeVector &ordering)
EdgeVector myIncomingEdges
Vector of incoming edges.
static void computeTurnDirectionsForNode(NBNode *node, bool warn)
Computes turnaround destinations for all incoming edges of the given nodes (if any) ...
static bool samePriority(const NBEdge *const e1, const NBEdge *const e2)
Returns whether both edges have the same priority.
double getSpeed() const
Returns the speed allowed on this edge.
const PositionVector & getGeometry() const
Returns the geometry of the edge.
EdgeVector myOutgoingEdges
Vector of outgoing edges.
static void computeEdgePrioritiesSingleNode(NBNode *node)
Computes edge priorities within a single node.
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
static void computeNodeTypes(NBNodeCont &nc)
Computes node types.
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
void setJunctionPriority(const NBNode *const node, int prio)
Sets the junction priority of the edge.
SumoXMLNodeType getType() const
Returns the type of this node.
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
Represents a single node (junction) during network building.
static void computeTurnDirections(NBNodeCont &nc, bool warn=true)
Computes turnaround destinations for all edges (if exist)
static NBEdge * extractAndMarkFirst(NBNode &n, std::vector< NBEdge *> &s, int prio=1)
Sets the priorites in case of a priority junction.
NBEdge * getOppositeIncoming(NBEdge *e) const
returns the opposite incoming edge of certain edge
Sorts "Combination"s by decreasing angle.
static void setPriorityJunctionPriorities(NBNode &n)
Sets the priorites in case of a priority junction.
NBNode * getFromNode() const
Returns the origin node of the edge.
Container for nodes during the netbuilding process.
NBNode * getToNode() const
Returns the destination node of the edge.
bool isSimpleContinuation(bool checkLaneNumbers=true) const
check if node is a simple continuation