60 #define DEBUGNODEID "1311774270" 62 #define DEBUGCOND(obj) ((obj != 0 && (obj)->getID() == DEBUGNODEID)) 81 NodeCont::iterator i =
myNodes.find(
id);
87 const float pos[2] = {(float)position.
x(), (float)position.
y()};
95 std::string
id = node->
getID();
96 NodeCont::iterator i =
myNodes.find(
id);
109 NodeCont::const_iterator i =
myNodes.find(
id);
120 const float cmin[2] = {(float)(position.
x() - extOffset), (
float)(position.
y() - extOffset)};
121 const float cmax[2] = {(float)(position.
x() + extOffset), (
float)(position.
y() + extOffset)};
122 std::set<std::string> into;
125 for (std::set<std::string>::const_iterator i = into.begin(); i != into.end(); i++) {
169 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
170 no += (*i).second->removeSelfLoops(dc, ec, tc);
181 const double distanceThreshold = 7.;
182 const double lengthThreshold = 0.10;
184 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
186 std::map<NBNode*, EdgeVector> connectionCount;
187 const EdgeVector& outgoing = (*i).second->getOutgoingEdges();
188 for (EdgeVector::const_iterator j = outgoing.begin(); j != outgoing.end(); j++) {
189 connectionCount[(*j)->getToNode()].push_back(*j);
192 std::map<NBNode*, EdgeVector>::iterator k;
193 for (k = connectionCount.begin(); k != connectionCount.end(); k++) {
195 if ((*k).second.size() < 2) {
201 const NBEdge*
const first = ev.front();
202 EdgeVector::const_iterator jci;
203 for (jci = ev.begin() + 1; jci != ev.end(); ++jci) {
206 (relativeLengthDifference > lengthThreshold) ||
207 (fabs(first->
getSpeed() - (*jci)->getSpeed()) >= 0.01) ||
215 if (jci == ev.end()) {
226 const std::vector<std::string>& edgeNames = ec.
getAllNames();
227 for (std::vector<std::string>::const_iterator it = edgeNames.begin(); it != edgeNames.end(); ++it) {
236 if (outgoingEdges.size() != 1) {
241 if (incomingEdges.size() > 1) {
244 }
else if (incomingEdges.size() == 1) {
245 NBNode* fromNodeOfIncomingEdge = incomingEdges[0]->getFromNode();
246 NBNode* toNodeOfOutgoingEdge = outgoingEdges[0]->getToNode();
247 if (fromNodeOfIncomingEdge != toNodeOfOutgoingEdge) {
255 bool hasJunction =
false;
267 adjacentNodes.clear();
268 for (EdgeVector::const_iterator itOfOutgoings = outgoingEdgesOfToNode.begin(); itOfOutgoings != outgoingEdgesOfToNode.end(); ++itOfOutgoings) {
269 if ((*itOfOutgoings)->getToNode() != from
270 && (*itOfOutgoings)->getToNode() != to
274 adjacentNodes.insert((*itOfOutgoings)->getToNode());
276 for (EdgeVector::const_iterator itOfIncomings = incomingEdgesOfToNode.begin(); itOfIncomings != incomingEdgesOfToNode.end(); ++itOfIncomings) {
277 adjacentNodes.insert((*itOfIncomings)->getFromNode());
279 adjacentNodes.erase(to);
280 if (adjacentNodes.size() > 2) {
283 }
while (!hasJunction && eOld != e);
285 std::string warningString =
"Removed a road without junctions: ";
286 for (EdgeVector::iterator roadIt = road.begin(); roadIt != road.end(); ++roadIt) {
287 if (roadIt == road.begin()) {
288 warningString += (*roadIt)->
getID();
290 warningString +=
", " + (*roadIt)->getID();
293 NBNode* fromNode = (*roadIt)->getFromNode();
294 NBNode* toNode = (*roadIt)->getToNode();
295 ec.
erase(dc, *roadIt);
313 std::vector<std::set<NBEdge*> > components;
315 std::set<std::string> edgesLeft;
316 for (std::map<std::string, NBEdge*>::const_iterator edgeIt = ec.
begin(); edgeIt != ec.
end(); ++edgeIt) {
317 edgesLeft.insert(edgeIt->first);
320 std::set<NBEdge*> toRemove;
321 while (!edgesLeft.empty()) {
322 queue.push_back(ec.
getByID(*edgesLeft.begin()));
323 std::set<NBEdge*> component;
324 while (!queue.empty()) {
325 NBEdge*
const e = queue.back();
328 std::vector<EdgeVector> edgeLists;
333 for (std::vector<EdgeVector>::const_iterator listIt = edgeLists.begin(); listIt != edgeLists.end(); ++listIt) {
334 for (EdgeVector::const_iterator edgeIt = listIt->begin(); edgeIt != listIt->end(); ++edgeIt) {
335 std::set<std::string>::iterator leftIt = edgesLeft.find((*edgeIt)->getID());
336 if (leftIt != edgesLeft.end()) {
337 queue.push_back(*edgeIt);
338 edgesLeft.erase(leftIt);
343 std::vector<std::set<NBEdge*> >::iterator cIt;
344 for (cIt = components.begin(); cIt != components.end(); ++cIt) {
345 if (cIt->size() < component.size()) {
349 components.insert(cIt, component);
350 if ((
int)components.size() > numKeep) {
351 toRemove.insert(components.back().begin(), components.back().end());
352 components.pop_back();
355 for (std::set<NBEdge*>::iterator edgeIt = toRemove.begin(); edgeIt != toRemove.end(); ++edgeIt) {
356 NBNode*
const fromNode = (*edgeIt)->getFromNode();
357 NBNode*
const toNode = (*edgeIt)->getToNode();
358 ec.
erase(dc, *edgeIt);
373 bool removeGeometryNodes) {
375 std::set<std::string> edges2keep;
376 if (removeGeometryNodes) {
378 if (oc.
isSet(
"geometry.remove.keep-edges.input-file")) {
381 if (oc.
isSet(
"geometry.remove.keep-edges.explicit")) {
382 const std::vector<std::string> edges = oc.
getStringVector(
"geometry.remove.keep-edges.explicit");
383 edges2keep.insert(edges.begin(), edges.end());
390 std::vector<NBNode*> toRemove;
391 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
392 NBNode* current = (*i).second;
394 std::vector<std::pair<NBEdge*, NBEdge*> > toJoin;
401 if (removeGeometryNodes &&
mySplit.count(current) == 0) {
409 for (EdgeVector::const_iterator it_edge = current->
getEdges().begin(); it_edge != current->
getEdges().end(); ++it_edge) {
410 if (edges2keep.find((*it_edge)->getID()) != edges2keep.end()) {
424 for (std::vector<std::pair<NBEdge*, NBEdge*> >::iterator j = toJoin.begin(); j != toJoin.end(); j++) {
426 NBEdge* continuation = (*j).second;
427 begin->
append(continuation);
430 ec.
extract(dc, continuation,
true);
432 toRemove.push_back(current);
436 for (std::vector<NBNode*>::iterator j = toRemove.begin(); j != toRemove.end(); ++j) {
445 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
446 (*i).second->avoidOverlap();
453 std::set<NBNode*> visited;
454 for (NodeCont::const_iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
455 std::vector<NodeAndDist> toProc;
456 if (visited.find((*i).second) != visited.end()) {
459 toProc.push_back(std::make_pair((*i).second, 0));
461 while (!toProc.empty()) {
463 NBNode* n = nodeAndDist.first;
464 double dist = nodeAndDist.second;
466 if (visited.find(n) != visited.end()) {
470 bool pureRail =
true;
471 bool railAndPeds =
true;
487 #ifdef DEBUG_JOINJUNCTIONS 489 std::cout <<
"generateNodeClusters: consider n=" << n->
getID() <<
" edges=" <<
toString(n->
getEdges(),
' ') <<
" with cluster " <<
joinNamedToString(c,
' ') <<
" pureRail=" << pureRail <<
"\n";
495 bool railAndPeds2 =
true;
498 railAndPeds2 =
false;
509 const double length = e->getLoadedLength();
510 #ifdef DEBUG_JOINJUNCTIONS 512 std::cout <<
"generateNodeClusters edge=" << e->getID() <<
" length=" << length <<
"\n";
516 const bool joinPedCrossings = bothCrossing && e->getPermissions() ==
SVC_PEDESTRIAN;
518 !joinPedCrossings && (
530 bool foundRail =
false;
533 if ((e2->getPermissions() & railNoTram) != 0) {
546 if (visited.find(s) != visited.end()) {
549 if (length + dist < maxDist) {
551 toProc.push_back(std::make_pair(s, dist + length));
553 toProc.push_back(std::make_pair(s, 0));
561 #ifdef DEBUG_JOINJUNCTIONS 571 for (std::vector<std::string>::const_iterator it = ids.begin(); it != ids.end(); it++) {
575 WRITE_WARNING(
"Ignoring join exclusion for junction '" + *it +
"' since it already occurred in a list of nodes to be joined");
576 }
else if (check &&
retrieve(*it) == 0) {
577 WRITE_WARNING(
"Ignoring join exclusion for unknown junction '" + *it +
"'");
588 for (std::set<std::string>::const_iterator it = cluster.begin(); it != cluster.end(); it++) {
590 WRITE_WARNING(
"Ignoring join-cluster because junction '" + *it +
"' was already excluded from joining");
592 }
else if (
myJoined.count(*it) > 0) {
593 WRITE_WARNING(
"Ignoring join-cluster because junction '" + *it +
"' already occurred in another join-cluster");
609 for (std::set<std::string>::iterator it_id = it->begin(); it_id != it->end(); it_id++) {
612 WRITE_WARNING(
"Ignoring unknown junction '" + *it_id +
"' while joining");
614 cluster.insert(node);
617 if (cluster.size() > 1) {
618 clusters.push_back(cluster);
623 return (
int)clusters.size();
629 #ifdef DEBUG_JOINJUNCTIONS 630 std::cout <<
"joinJunctions...\n";
635 for (NodeClusters::iterator i = cands.begin(); i != cands.end(); ++i) {
638 for (NodeSet::iterator j = cluster.begin(); j != cluster.end();) {
639 NodeSet::iterator check = j;
642 cluster.erase(check);
648 std::set<NBNode*> toRemove;
649 for (
NBNode* n : cluster) {
650 for (
NBEdge* edge : n->getOutgoingEdges()) {
651 if (cluster.count(edge->getToNode()) != 0 && edge->getLoadedLength() > maxDist ) {
652 #ifdef DEBUG_JOINJUNCTIONS 654 std::cout <<
"long edge " << edge->getID() <<
" (" << edge->getLoadedLength() <<
", max=" << maxDist <<
")\n";
658 toRemove.insert(edge->getToNode());
662 for (std::set<NBNode*>::iterator j = toRemove.begin(); j != toRemove.end(); ++j) {
665 if (cluster.size() < 2) {
677 WRITE_WARNING(
"Reducing junction cluster " + origCluster +
" (" + reason +
")");
687 WRITE_WARNING(
"Reducing junction cluster " + origCluster +
" (" + reason +
")");
698 for (
NBNode* current : cluster) {
702 newComp.insert(current);
703 for (NodeClusters::iterator it_comp = components.begin(); it_comp != components.end();) {
704 NodeClusters::iterator check = it_comp;
706 bool connected =
false;
707 for (
NBNode* k : *check) {
708 if (current->getConnectionTo(k) != 0 || k->getConnectionTo(current) != 0) {
710 newComp.insert((*check).begin(), (*check).end());
711 it_comp = components.erase(check);
721 components.push_back(newComp);
723 for (NodeClusters::iterator it_comp = components.begin(); it_comp != components.end(); ++it_comp) {
724 if ((*it_comp).size() > 1) {
726 clusters.push_back(*it_comp);
731 return (
int)clusters.size();
737 #ifdef DEBUG_JOINJUNCTIONS 743 bool pruneFringe =
true;
746 while (pruneFringe) {
748 for (NodeSet::iterator j = cluster.begin(); j != cluster.end();) {
749 NodeSet::iterator check = j;
754 double clusterDist = std::numeric_limits<double>::max();
755 bool touchingCluster =
false;
757 NBNode* neighbor = (*it_edge)->getToNode();
758 if (cluster.count(neighbor) != 0) {
759 clusterDist =
MIN2(clusterDist, (*it_edge)->getLoadedLength());
764 NBNode* neighbor = (*it_edge)->getFromNode();
765 if (cluster.count(neighbor) != 0) {
766 clusterDist =
MIN2(clusterDist, (*it_edge)->getLoadedLength());
772 std::set<NBNode*> outsideNeighbors;
773 std::set<NBNode*> clusterNeighbors;
774 const double pedestrianFringeThreshold = 0.3;
776 NBNode* neighbor = e->getFromNode() == n ? e->getToNode() : e->getFromNode();
777 if (cluster.count(neighbor) == 0) {
778 if ((e->getPermissions() &
SVC_PASSENGER) != 0 || clusterDist <= pedestrianFringeThreshold || touchingCluster) {
779 outsideNeighbors.insert(neighbor);
782 clusterNeighbors.insert(neighbor);
785 #ifdef DEBUG_JOINJUNCTIONS 787 <<
" clusterDist=" << clusterDist
788 <<
" cd<th=" << (clusterDist <= pedestrianFringeThreshold)
789 <<
" touching=" << touchingCluster
794 if (outsideNeighbors.size() <= 1
795 && clusterNeighbors.size() == 1
797 cluster.erase(check);
799 #ifdef DEBUG_JOINJUNCTIONS 801 std::cout <<
" pruned n=" << n->
getID() <<
"\n";
814 std::map<std::string, double> finalIncomingAngles;
815 std::map<std::string, double> finalOutgoingAngles;
816 for (NodeSet::const_iterator j = cluster.begin(); j != cluster.end(); ++j) {
817 for (EdgeVector::const_iterator it_edge = (*j)->getIncomingEdges().begin(); it_edge != (*j)->getIncomingEdges().end(); ++it_edge) {
824 for (EdgeVector::const_iterator it_edge = (*j)->getOutgoingEdges().begin(); it_edge != (*j)->getOutgoingEdges().end(); ++it_edge) {
833 #ifdef DEBUG_JOINJUNCTIONS 834 for (
NBNode* n : cluster) {
837 <<
"\n inAngles=" <<
joinToString(finalIncomingAngles,
' ',
':')
838 <<
"\n outAngles=" <<
joinToString(finalOutgoingAngles,
' ',
':')
843 if (finalIncomingAngles.size() > 4) {
844 reason =
toString(finalIncomingAngles.size()) +
" incoming edges";
848 const double PARALLEL_INCOMING_THRESHOLD = 10.0;
849 bool foundParallel =
false;
850 for (std::map<std::string, double>::const_iterator j = finalIncomingAngles.begin(); j != finalIncomingAngles.end() && !foundParallel; ++j) {
851 std::map<std::string, double>::const_iterator k = j;
852 for (++k; k != finalIncomingAngles.end() && !foundParallel; ++k) {
853 if (fabs(j->second - k->second) < PARALLEL_INCOMING_THRESHOLD) {
854 reason =
"parallel incoming " + j->first +
"," + k->first;
860 for (std::map<std::string, double>::const_iterator j = finalOutgoingAngles.begin(); j != finalOutgoingAngles.end() && !foundParallel; ++j) {
861 std::map<std::string, double>::const_iterator k = j;
862 for (++k; k != finalOutgoingAngles.end() && !foundParallel; ++k) {
863 if (fabs(j->second - k->second) < PARALLEL_INCOMING_THRESHOLD) {
864 reason =
"parallel outgoing " + j->first +
"," + k->first;
871 for (
auto it = sc.
begin(); it != sc.
end(); it++) {
873 if (edge != 0 && cluster.count(edge->
getFromNode()) != 0 && cluster.count(edge->
getToNode()) != 0) {
874 reason =
"it contains stop '" + it->first +
"'";
880 if (cluster.size() > 2) {
885 for (
NBNode* n1 : cluster) {
886 hasTLS |= n1->isTLControlled();
887 for (
NBNode* n2 : cluster) {
888 NBEdge* e1 = n1->getConnectionTo(n2);
889 NBEdge* e2 = n2->getConnectionTo(n1);
900 #ifdef DEBUG_JOINJUNCTIONS 901 for (
NBNode* n : cluster) {
903 std::cout <<
"feasible hasTLS=" << hasTLS <<
" maxDist=" << maxDist <<
" maxEdge=" << maxEdge->
getID() <<
"\n";
907 if (!hasTLS && maxDist > 5) {
909 std::vector<NBNode*> toCheck;
910 std::set<NBNode*> visited;
912 bool foundCircle =
false;
913 while (!toCheck.empty()) {
914 NBNode* n = toCheck.back();
923 NBNode* cand = e->getFromNode() == n ? e->getToNode() : e->getFromNode();
924 if (visited.count(cand) == 0 && cluster.count(cand) != 0) {
925 toCheck.push_back(cand);
931 reason =
"not compact (maxEdge=" + maxEdge->
getID() +
" length=" +
toString(maxDist) +
")";
943 assert(circleSize >= 2);
944 if ((
int)cands.size() == circleSize) {
945 if (cands.back()->getConnectionTo(cands.front()) != 0) {
948 cluster.insert(cands.begin(), cands.end());
954 if ((
int)cluster.size() <= circleSize || startNodes.size() == 0) {
958 if (cands.size() == 0) {
973 singleStart.insert(cands.back());
976 std::vector<NBNode*> cands2(cands);
989 double minDist = std::numeric_limits<double>::max();
991 for (
NBNode* n : startNodes) {
992 for (
NBEdge* e : n->getOutgoingEdges()) {
993 NBNode* neigh = e->getToNode();
994 if (cluster.count(neigh) != 0 && std::find(exclude.begin(), exclude.end(), neigh) == exclude.end()) {
997 if (dist < minDist) {
1011 for (NodeClusters::iterator i = clusters.begin(); i != clusters.end(); ++i) {
1013 assert(cluster.size() > 1);
1016 std::string
id =
"cluster";
1026 newNode->
reinit(pos, nodeType);
1029 if (!tlc.
insert(tlDef)) {
1032 throw ProcessError(
"Could not allocate tls '" +
id +
"'.");
1036 std::set<NBEdge*> allEdges;
1037 for (
NBNode* n : cluster) {
1039 allEdges.insert(edges.begin(), edges.end());
1043 for (std::set<NBEdge*>::iterator j = allEdges.begin(); j != allEdges.end();) {
1047 if (cluster.count(from) > 0 && cluster.count(to) > 0) {
1048 for (std::set<NBEdge*>::iterator l = allEdges.begin(); l != allEdges.end(); ++l) {
1054 allEdges.erase(j++);
1061 for (std::set<NBEdge*>::iterator j = allEdges.begin(); j != allEdges.end(); ++j) {
1064 const bool outgoing = cluster.count(e->
getFromNode()) > 0;
1070 for (std::vector<NBEdge::Connection>::iterator k = conns.begin(); k != conns.end(); ++k) {
1080 for (NodeSet::const_iterator j = cluster.begin(); j != cluster.end(); ++j) {
1089 std::set<std::string> ids;
1090 for (
NBNode* n : cluster) {
1091 ids.insert(n->getID());
1102 bool ambiguousType =
false;
1103 for (
NBNode* j : cluster) {
1104 pos.
add(j->getPosition());
1106 if (j->isTLControlled()) {
1109 type = (*j->getControllingTLS().begin())->getType();
1110 }
else if (type != (*j->getControllingTLS().begin())->getType()) {
1111 ambiguousType =
true;
1117 nodeType = otherType;
1118 }
else if (nodeType != otherType) {
1130 pos.
mul(1.0 / cluster.size());
1131 if (ambiguousType) {
1133 WRITE_WARNING(
"Ambiguous traffic light type for node cluster '" +
id +
"' set to '" +
toString(type) +
"'");
1143 bool tooFast =
false;
1145 std::set<NBEdge*> seen;
1148 for (EdgeVector::const_iterator k = edges.begin(); k != edges.end(); ++k) {
1149 if (c.find((*k)->getFromNode()) != c.end() && c.find((*k)->getToNode()) != c.end()) {
1152 if (j->hasIncoming(*k)) {
1154 f += (double)(*k)->getNumLanes() * (*k)->getLaneSpeed(0);
1158 if ((*k)->getLaneSpeed(0) * 3.6 > 79) {
1163 return !tooFast && f >= 150. / 3.6 && c.size() != 0;
1170 std::vector<NBNode*> ncontrolled;
1171 if (oc.
isSet(
"tls.unset")) {
1172 std::vector<std::string> notTLControlledNodes = oc.
getStringVector(
"tls.unset");
1173 for (std::vector<std::string>::const_iterator i = notTLControlledNodes.begin(); i != notTLControlledNodes.end(); ++i) {
1176 throw ProcessError(
" The junction '" + *i +
"' to set as not-controlled is not known.");
1179 for (std::set<NBTrafficLightDefinition*>::const_iterator j = tls.begin(); j != tls.end(); ++j) {
1180 (*j)->removeNode(n);
1183 ncontrolled.push_back(n);
1190 if (oc.
exists(
"tls.taz-nodes") && oc.
getBool(
"tls.taz-nodes")) {
1191 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
1192 NBNode* cur = (*i).second;
1193 if (cur->
isNearDistrict() && find(ncontrolled.begin(), ncontrolled.end(), cur) == ncontrolled.end()) {
1201 if (oc.
exists(
"tls.guess-signals") && oc.
getBool(
"tls.guess-signals")) {
1203 const double signalDist = oc.
getFloat(
"tls.guess-signals.dist");
1204 for (std::map<std::string, NBNode*>::const_iterator i =
myNodes.begin(); i !=
myNodes.end(); ++i) {
1205 NBNode* node = (*i).second;
1208 for (EdgeVector::const_iterator it_o = outgoing.begin(); it_o != outgoing.end(); ++it_o) {
1209 (*it_o)->setSignalOffset((*it_o)->getLength());
1214 for (std::map<std::string, NBNode*>::const_iterator i =
myNodes.begin(); i !=
myNodes.end(); ++i) {
1215 NBNode* node = i->second;
1216 if (find(ncontrolled.begin(), ncontrolled.end(), node) != ncontrolled.end()) {
1222 std::vector<NBNode*> signals;
1224 for (EdgeVector::const_iterator it_i = incoming.begin(); it_i != incoming.end(); ++it_i) {
1225 const NBEdge* inEdge = *it_i;
1236 for (EdgeVector::const_iterator it_i = outgoing.begin(); it_i != outgoing.end(); ++it_i) {
1237 const NBEdge* outEdge = *it_i;
1240 signals.push_back(cand);
1244 for (std::vector<NBNode*>::iterator j = signals.begin(); j != signals.end(); ++j) {
1247 for (std::set<NBTrafficLightDefinition*>::iterator k = tls.begin(); k != tls.end(); ++k) {
1253 if (!tlc.
insert(tlDef)) {
1265 if (!oc.
getBool(
"tls.guess")) {
1275 for (NodeClusters::iterator i = cands.begin(); i != cands.end();) {
1279 for (NodeSet::iterator j = c.begin(); j != c.end();) {
1280 if ((*j)->isTLControlled() || find(ncontrolled.begin(), ncontrolled.end(), *j) != ncontrolled.end()) {
1295 for (NodeClusters::iterator i = cands.begin(); i != cands.end(); ++i) {
1296 std::vector<NBNode*> nodes;
1297 for (NodeSet::iterator j = (*i).begin(); j != (*i).end(); j++) {
1298 nodes.push_back(*j);
1300 std::string
id =
"joinedG_" +
toString(index++);
1302 if (!tlc.
insert(tlDef)) {
1312 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
1313 NBNode* cur = (*i).second;
1319 if (find(ncontrolled.begin(), ncontrolled.end(), cur) != ncontrolled.end()) {
1338 for (NodeSet::iterator j = c.begin(); j != c.end();) {
1339 if (!(*j)->isTLControlled()) {
1351 std::string
id =
"joined";
1356 std::set<NBTrafficLightDefinition*> tls = j->getControllingTLS();
1357 j->removeTrafficLights();
1358 for (std::set<NBTrafficLightDefinition*>::iterator k = tls.begin(); k != tls.end(); ++k) {
1362 id =
"joinedS_" +
toString(index++);
1363 std::vector<NBNode*> nodes;
1368 if (!tlc.
insert(tlDef)) {
1385 if (!tlc.
insert(tlDef)) {
1387 WRITE_WARNING(
"Building a tl-logic for junction '" +
id +
"' twice is not possible.");
1397 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
1398 (*i).second->computeLanes2Lanes();
1406 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
1407 (*i).second->computeLogic(ec, oc);
1414 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
1415 delete((*i).second);
1428 std::string freeID =
"SUMOGenerated" + toString<int>(counter);
1433 freeID =
"SUMOGenerated" + toString<int>(counter);
1441 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
1442 (*i).second->computeNodeShape(mismatchThreshold);
1449 int numUnregulatedJunctions = 0;
1450 int numDeadEndJunctions = 0;
1451 int numPriorityJunctions = 0;
1452 int numRightBeforeLeftJunctions = 0;
1453 int numAllWayStopJunctions = 0;
1454 int numZipperJunctions = 0;
1455 int numRailSignals = 0;
1456 for (NodeCont::const_iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
1457 switch ((*i).second->getType()) {
1460 ++numUnregulatedJunctions;
1463 ++numDeadEndJunctions;
1470 ++numPriorityJunctions;
1473 ++numRightBeforeLeftJunctions;
1476 ++numAllWayStopJunctions;
1479 ++numZipperJunctions;
1482 ++numRightBeforeLeftJunctions;
1495 if (numDeadEndJunctions > 0) {
1500 if (numAllWayStopJunctions > 0) {
1503 if (numZipperJunctions > 0) {
1506 if (numRailSignals > 0) {
1512 std::vector<std::string>
1514 std::vector<std::string> ret;
1515 for (NodeCont::const_iterator i =
myNodes.begin(); i !=
myNodes.end(); ++i) {
1516 ret.push_back((*i).first);
1524 if (
myNodes.count(newID) != 0) {
1525 throw ProcessError(
"Attempt to rename node using existing id '" + newID +
"'");
1535 for (NodeCont::const_iterator i =
myNodes.begin(); i !=
myNodes.end(); ++i) {
1536 NBNode* node = i->second;
1543 for (EdgeVector::const_iterator it_o = outgoing.begin(); it_o != outgoing.end(); ++it_o) {
1544 (*it_o)->setSignalOffset((*it_o)->getLength());
1547 for (std::set<NBTrafficLightDefinition*>::const_iterator it = tldefs.begin(); it != tldefs.end(); ++it) {
1562 NBNode* node = item.second;
1573 std::set<std::string> reserve;
1576 avoid.insert(avoid.end(), reserve.begin(), reserve.end());
1580 for (NodeCont::iterator it =
myNodes.begin(); it !=
myNodes.end(); it++) {
1585 toChange.insert(it->second);
1588 if (reservedIDs && reserve.count(it->first) > 0) {
1589 toChange.insert(it->second);
1593 for (
NBNode* node : toChange) {
1598 node->setID(idSupplier.
getNext());
1599 myNodes[node->getID()] = node;
1601 if (prefix.empty()) {
1602 return (
int)toChange.size();
1607 for (
auto item : oldNodes) {
1609 rename(item.second, prefix + item.first);
std::string getFreeID()
generates a new node ID
std::set< std::string > myJoinExclusions
set of node ids which should not be joined
NodeCont myNodes
The map of names to nodes.
void Insert(const float a_min[2], const float a_max[2], Named *const &a_data)
Insert entry.
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
void joinSimilarEdges(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc)
Joins edges connecting the same nodes.
double getLength() const
Returns the computed length of the edge.
NBEdge * getByID(const std::string &edgeID) const
Returns the edge with id if it exists.
void removeSelfLoops(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tc)
Removes self-loop edges (edges where the source and the destination node are the same) ...
bool feasibleCluster(const NodeSet &cluster, const NBEdgeCont &ec, const NBPTStopCont &sc, std::string &reason) const
determine wether the cluster is not too complex for joining
std::string joinNamedToString(const std::set< T *, C > &ns, const T_BETWEEN &between)
bool reduceToCircle(NodeSet &cluster, int circleSize, NodeSet startNodes, std::vector< NBNode *> cands=std::vector< NBNode *>()) const
try to find a joinable subset (recursively)
void addEdges2Keep(const OptionsCont &oc, std::set< std::string > &into)
add edges that must be kept
std::map< std::string, NBNode * >::const_iterator begin() const
Returns the pointer to the begin of the stored nodes.
void addJoinExclusion(const std::vector< std::string > &ids, bool check=false)
int removeUnwishedNodes(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc, NBPTStopCont &sc, NBPTLineCont &lc, NBParkingCont &pc, bool removeGeometryNodes)
Removes "unwished" nodes.
static void loadPrefixedIDsFomFile(const std::string &file, const std::string prefix, std::set< std::string > &into)
Add prefixed ids defined in file.
void add(const Position &pos)
Adds the given position to this one.
void addEdges2Keep(const OptionsCont &oc, std::set< std::string > &into)
add edges that must be kept
void removeIsolatedRoads(NBDistrictCont &dc, NBEdgeCont &ec)
Removes sequences of edges that are not connected with a junction. Simple roads without junctions som...
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
A container for traffic light definitions and built programs.
void joinTLS(NBTrafficLightLogicCont &tlc, double maxdist)
Builds clusters of tls-controlled junctions and joins the control if possible.
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
double getSignalOffset() const
Returns the offset of a traffic signal from the end of this edge.
std::vector< std::set< std::string > > myJoinedClusters
sets of node ids which were joined
const double SUMO_const_laneWidth
double y() const
Returns the y-position.
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
The representation of a single edge during network building.
void reinitNodes(NBNode *from, NBNode *to)
Resets nodes but keeps all other values the same (used when joining)
static const double UNSPECIFIED_SIGNAL_OFFSET
unspecified signal offset
double x() const
Returns the x-position.
A container for districts.
The base class for traffic light logic definitions.
std::vector< NodeSet > NodeClusters
int joinLoadedClusters(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc)
Joins loaded junction clusters (see NIXMLNodesHandler)
NamedRTree myRTree
node positions for faster lookup
static long long int _str2long(const std::string &sData)
converts a string into the long value described by it by calling the char-type converter, which
void guessTLs(OptionsCont &oc, NBTrafficLightLogicCont &tlc)
Guesses which junctions or junction clusters shall be controlled by tls.
std::map< std::string, NBEdge * >::const_iterator end() const
Returns the pointer to the end of the stored edges.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
bool connectionsDone
Whether connection information for this lane is already completed.
void avoidOverlap()
fix overlap
const std::string & getID() const
Returns the id.
Lane & getLaneStruct(int lane)
static void loadEdgesFromFile(const std::string &file, std::set< std::string > &into)
Add edge ids defined in file (either ID or edge:ID per line) into the given set.
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
void extract(NBTrafficLightDefinition *definition)
Extracts a traffic light definition from myDefinitions but keeps it in myExtracted for eventual * del...
bool shouldBeTLSControlled(const NodeSet &c) const
Returns whethe the given node cluster should be controlled by a tls.
void discardRailSignals()
#define WRITE_WARNING(msg)
static OptionsCont & getOptions()
Retrieves the options.
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
The edge has been loaded, nothing is computed yet.
void computeLogics(const NBEdgeCont &ec, OptionsCont &oc)
build the list of outgoing edges and lanes
bool addLane2LaneConnection(int fromLane, NBEdge *dest, int toLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, bool keepClear=true, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE, double speed=UNSPECIFIED_SPEED, const PositionVector &customShape=PositionVector::EMPTY, const bool uncontrolled=UNSPECIFIED_CONNECTION_UNCONTROLLED)
Adds a connection between the specified this edge's lane and an approached one.
A class representing a single district.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
void Remove(const float a_min[2], const float a_max[2], Named *const &a_data)
Remove entry.
void registerJoinedCluster(const NodeSet &cluster)
gets all joined clusters (see doc for myClusters2Join)
bool isTLControlled() const
Returns whether this node is controlled by any tls.
int joinJunctions(double maxDist, NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc, NBPTStopCont &sc)
Joins junctions that are very close together.
std::map< std::string, NBPTStop * >::const_iterator begin() const
Returns the pointer to the begin of the stored pt stops.
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
std::map< std::string, NBEdge * >::const_iterator begin() const
Returns the pointer to the begin of the stored edges.
std::string getNext()
Returns the next id.
void computeLanes2Lanes()
divides the incoming lanes on outgoing lanes
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
NBEdge * shortestEdge(const NodeSet &cluster, const NodeSet &startNodes, const std::vector< NBNode *> &exclude) const
find closest neighbor for building circle
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
void extract(NBDistrictCont &dc, NBEdge *edge, bool remember=false)
Removes the given edge from the container like erase but does not delete it.
int getNumLanes() const
Returns the number of lanes.
A point in 2D or 3D with translation and scaling methods.
classes which drive on tracks
std::pair< NBNode *, double > NodeAndDist
static bool isRailwayNode(NBNode *n)
whether the given node only has rail edges
void generateNodeClusters(double maxDist, NodeClusters &into) const
Builds node clusters.
T get(const std::string &str) const
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node) ...
bool exists(const std::string &name) const
Returns the information whether the named option is known.
void removeTrafficLights()
Removes all references to traffic lights that control this tls.
bool geometryLike() const
whether this is structurally similar to a geometry node
Storage for edges, including some functionality operating on multiple edges.
std::vector< std::string > getStringVector(const std::string &name) const
Returns the list of string-vector-value of the named option (only for Option_String) ...
void computeNodeShapes(double mismatchThreshold=-1)
Compute the junction shape for this node.
double getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge's geometry at the given node.
void joinNodeClusters(NodeClusters clusters, NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc)
joins the given node clusters
std::set< NBNode * > myExtractedNodes
The extracted nodes which are kept for reference.
The connection was given by the user.
void addEdges2Keep(const OptionsCont &oc, std::set< std::string > &into)
add edges that must be kept
int Search(const float a_min[2], const float a_max[2], const Named::StoringVisitor &c) const
Find all within search rectangle.
std::map< std::string, NBPTStop * >::const_iterator end() const
Returns the pointer to the end of the stored pt stops.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
vehicle is a passenger car (a "normal" car)
int remapIDs(bool numericaIDs, bool reservedIDs, const std::string &prefix)
remap node IDs accoring to options –numerical-ids and –reserved-ids
void rename(NBNode *node, const std::string &newID)
Renames the node. Throws exception if newID already exists.
bool hasIncoming(const NBEdge *const e) const
Returns whether the given edge ends at this node.
void joinSameNodeConnectingEdges(NBDistrictCont &dc, NBTrafficLightLogicCont &tlc, EdgeVector edges)
Joins the given edges because they connect the same nodes.
std::set< NBNode *, ComparatorIdLess > NodeSet
Definition of a node cluster container.
double getSpeed() const
Returns the speed allowed on this edge.
void setAsTLControlled(NBNode *node, NBTrafficLightLogicCont &tlc, TrafficLightType type, std::string id="")
Sets the given node as being controlled by a tls.
Allows to store the object; used as context while traveling the rtree in TraCI.
std::vector< std::string > getAllNames() const
get all node names
void setID(const std::string &newID)
resets the id
void addCluster2Join(std::set< std::string > cluster)
add ids of nodes which shall be joined into a single node
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
const std::vector< Connection > & getConnections() const
Returns the connections.
void replaceIncoming(NBEdge *which, NBEdge *by, int laneOff)
Replaces occurences of the first edge within the list of incoming by the second Connections are remap...
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
bool isNearDistrict() const
if node is near district
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node (The set of tls that control this node) ...
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
std::set< std::string > myJoined
ids found in loaded join clusters used for error checking
A storage for options typed value containers)
SumoXMLNodeType getType() const
Returns the type of this node.
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
void clear()
deletes all nodes
const std::string SUMO_PARAM_ORIGID
void append(NBEdge *continuation)
append another edge
std::vector< std::set< std::string > > myClusters2Join
loaded sets of node ids to join (cleared after use)
void discardTrafficLights(NBTrafficLightLogicCont &tlc, bool geometryLike, bool guessSignals)
void declareConnectionsAsLoaded(EdgeBuildingStep step=LANES2LANES_USER)
declares connections as fully loaded. This is needed to avoid recomputing connections if an edge has ...
const Position & getPosition() const
Represents a single node (junction) during network building.
bool removeFully(const std::string id)
Removes a logic definition (and all programs) from the dictionary.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
std::set< const NBNode * > mySplit
nodes that were created when splitting an edge
void printBuiltNodesStatistics() const
Prints statistics about built nodes.
NBNode * getFromNode() const
Returns the origin node of the edge.
void analyzeCluster(NodeSet cluster, std::string &id, Position &pos, bool &hasTLS, TrafficLightType &type, SumoXMLNodeType &nodeType)
void mul(double val)
Multiplies both positions with the given value.
void replaceRemoved(NBEdge *removed, int removedLane, NBEdge *by, int byLane)
Replaces occurences of the removed edge/lane in all definitions by the given edge.
A traffic light logics which must be computed (only nodes/edges are given)
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
bool extract(NBNode *node, bool remember=false)
Removes the given node but does not delete it.
#define WRITE_MESSAGE(msg)
bool erase(NBNode *node)
Removes the given node, deleting it.
bool checkIsRemovable() const
check if node is removable
std::vector< std::string > getAllNames() const
Returns all ids of known edges.
std::vector< std::pair< NBEdge *, NBEdge * > > getEdgesToJoin() const
get edges to join
bool isNearEnough2BeJoined2(NBEdge *e, double threshold) const
Check if edge is near enought to be joined to another edge.
NBNode * getToNode() const
Returns the destination node of the edge.
void pruneClusterFringe(NodeSet &cluster) const
remove geometry-like fringe nodes from cluster
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
void removeComponents(NBDistrictCont &dc, NBEdgeCont &ec, const int numKeep)
Checks the network for weak connectivity and removes all but the largest components. The connectivity check is done regardless of edge direction and vclass.