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 (std::set<NBNode*>::iterator j = cluster.begin(); j != cluster.end(); ++j) {
652 if (cluster.count(edge->getToNode()) != 0 && edge->getLoadedLength() > maxDist ) {
653 #ifdef DEBUG_JOINJUNCTIONS 655 std::cout <<
"long edge " << edge->
getID() <<
" (" << edge->getLoadedLength() <<
", max=" << maxDist <<
")\n";
659 toRemove.insert(edge->getToNode());
663 for (std::set<NBNode*>::iterator j = toRemove.begin(); j != toRemove.end(); ++j) {
666 if (cluster.size() < 2) {
678 WRITE_WARNING(
"Reducing junction cluster " + origCluster +
" (" + reason +
")");
688 WRITE_WARNING(
"Reducing junction cluster " + origCluster +
" (" + reason +
")");
699 for (std::set<NBNode*>::iterator j = cluster.begin(); j != cluster.end(); ++j) {
704 newComp.insert(current);
705 for (NodeClusters::iterator it_comp = components.begin(); it_comp != components.end();) {
706 NodeClusters::iterator check = it_comp;
708 bool connected =
false;
709 for (std::set<NBNode*>::iterator k = (*check).begin(); k != (*check).end(); ++k) {
710 if (current->
getConnectionTo(*k) != 0 || (*k)->getConnectionTo(current) != 0) {
712 newComp.insert((*check).begin(), (*check).end());
713 it_comp = components.erase(check);
723 components.push_back(newComp);
725 for (NodeClusters::iterator it_comp = components.begin(); it_comp != components.end(); ++it_comp) {
726 if ((*it_comp).size() > 1) {
728 clusters.push_back(*it_comp);
733 return (
int)clusters.size();
739 #ifdef DEBUG_JOINJUNCTIONS 745 bool pruneFringe =
true;
748 while (pruneFringe) {
750 for (std::set<NBNode*>::iterator j = cluster.begin(); j != cluster.end();) {
751 std::set<NBNode*>::iterator check = j;
756 double clusterDist = std::numeric_limits<double>::max();
757 bool touchingCluster =
false;
759 NBNode* neighbor = (*it_edge)->getToNode();
760 if (cluster.count(neighbor) != 0) {
761 clusterDist =
MIN2(clusterDist, (*it_edge)->getLoadedLength());
766 NBNode* neighbor = (*it_edge)->getFromNode();
767 if (cluster.count(neighbor) != 0) {
768 clusterDist =
MIN2(clusterDist, (*it_edge)->getLoadedLength());
774 std::set<NBNode*> outsideNeighbors;
775 std::set<NBNode*> clusterNeighbors;
776 const double pedestrianFringeThreshold = 0.3;
778 NBNode* neighbor = e->getFromNode() == n ? e->getToNode() : e->getFromNode();
779 if (cluster.count(neighbor) == 0) {
780 if ((e->getPermissions() &
SVC_PASSENGER) != 0 || clusterDist <= pedestrianFringeThreshold || touchingCluster) {
781 outsideNeighbors.insert(neighbor);
784 clusterNeighbors.insert(neighbor);
787 #ifdef DEBUG_JOINJUNCTIONS 789 <<
" clusterDist=" << clusterDist
790 <<
" cd<th=" << (clusterDist <= pedestrianFringeThreshold)
791 <<
" touching=" << touchingCluster
796 if (outsideNeighbors.size() <= 1
797 && clusterNeighbors.size() == 1
799 cluster.erase(check);
801 #ifdef DEBUG_JOINJUNCTIONS 803 std::cout <<
" pruned n=" << n->
getID() <<
"\n";
816 std::map<std::string, double> finalIncomingAngles;
817 std::map<std::string, double> finalOutgoingAngles;
818 for (std::set<NBNode*>::const_iterator j = cluster.begin(); j != cluster.end(); ++j) {
819 for (EdgeVector::const_iterator it_edge = (*j)->getIncomingEdges().begin(); it_edge != (*j)->getIncomingEdges().end(); ++it_edge) {
826 for (EdgeVector::const_iterator it_edge = (*j)->getOutgoingEdges().begin(); it_edge != (*j)->getOutgoingEdges().end(); ++it_edge) {
835 #ifdef DEBUG_JOINJUNCTIONS 836 for (
NBNode* n : cluster) {
839 <<
"\n inAngles=" <<
joinToString(finalIncomingAngles,
' ',
':')
840 <<
"\n outAngles=" <<
joinToString(finalOutgoingAngles,
' ',
':')
845 if (finalIncomingAngles.size() > 4) {
846 reason =
toString(finalIncomingAngles.size()) +
" incoming edges";
850 const double PARALLEL_INCOMING_THRESHOLD = 10.0;
851 bool foundParallel =
false;
852 for (std::map<std::string, double>::const_iterator j = finalIncomingAngles.begin(); j != finalIncomingAngles.end() && !foundParallel; ++j) {
853 std::map<std::string, double>::const_iterator k = j;
854 for (++k; k != finalIncomingAngles.end() && !foundParallel; ++k) {
855 if (fabs(j->second - k->second) < PARALLEL_INCOMING_THRESHOLD) {
856 reason =
"parallel incoming " + j->first +
"," + k->first;
862 for (std::map<std::string, double>::const_iterator j = finalOutgoingAngles.begin(); j != finalOutgoingAngles.end() && !foundParallel; ++j) {
863 std::map<std::string, double>::const_iterator k = j;
864 for (++k; k != finalOutgoingAngles.end() && !foundParallel; ++k) {
865 if (fabs(j->second - k->second) < PARALLEL_INCOMING_THRESHOLD) {
866 reason =
"parallel outgoing " + j->first +
"," + k->first;
873 for (
auto it = sc.
begin(); it != sc.
end(); it++) {
875 if (edge != 0 && cluster.count(edge->
getFromNode()) != 0 && cluster.count(edge->
getToNode()) != 0) {
876 reason =
"it contains stop '" + it->first +
"'";
882 if (cluster.size() > 2) {
887 for (
NBNode* n1 : cluster) {
888 hasTLS |= n1->isTLControlled();
889 for (
NBNode* n2 : cluster) {
890 NBEdge* e1 = n1->getConnectionTo(n2);
891 NBEdge* e2 = n2->getConnectionTo(n1);
902 #ifdef DEBUG_JOINJUNCTIONS 903 for (
NBNode* n : cluster) {
905 std::cout <<
"feasible hasTLS=" << hasTLS <<
" maxDist=" << maxDist <<
" maxEdge=" << maxEdge->
getID() <<
"\n";
909 if (!hasTLS && maxDist > 5) {
911 std::vector<NBNode*> toCheck;
912 std::set<NBNode*> visited;
914 bool foundCircle =
false;
915 while (!toCheck.empty()) {
916 NBNode* n = toCheck.back();
925 NBNode* cand = e->getFromNode() == n ? e->getToNode() : e->getFromNode();
926 if (visited.count(cand) == 0 && cluster.count(cand) != 0) {
927 toCheck.push_back(cand);
933 reason =
"not compact (maxEdge=" + maxEdge->
getID() +
" length=" +
toString(maxDist) +
")";
945 assert(circleSize >= 2);
946 if ((
int)cands.size() == circleSize) {
947 if (cands.back()->getConnectionTo(cands.front()) != 0) {
950 cluster.insert(cands.begin(), cands.end());
956 if ((
int)cluster.size() <= circleSize || startNodes.size() == 0) {
960 if (cands.size() == 0) {
975 singleStart.insert(cands.back());
978 std::vector<NBNode*> cands2(cands);
991 double minDist = std::numeric_limits<double>::max();
993 for (
NBNode* n : startNodes) {
994 for (
NBEdge* e : n->getOutgoingEdges()) {
995 NBNode* neigh = e->getToNode();
996 if (cluster.count(neigh) != 0 && std::find(exclude.begin(), exclude.end(), neigh) == exclude.end()) {
999 if (dist < minDist) {
1013 for (NodeClusters::iterator i = clusters.begin(); i != clusters.end(); ++i) {
1015 assert(cluster.size() > 1);
1018 std::string
id =
"cluster";
1028 newNode->
reinit(pos, nodeType);
1031 if (!tlc.
insert(tlDef)) {
1034 throw ProcessError(
"Could not allocate tls '" +
id +
"'.");
1038 std::set<NBEdge*> allEdges;
1039 for (
NBNode* n : cluster) {
1041 allEdges.insert(edges.begin(), edges.end());
1045 for (std::set<NBEdge*>::iterator j = allEdges.begin(); j != allEdges.end();) {
1049 if (cluster.count(from) > 0 && cluster.count(to) > 0) {
1050 for (std::set<NBEdge*>::iterator l = allEdges.begin(); l != allEdges.end(); ++l) {
1056 allEdges.erase(j++);
1063 for (std::set<NBEdge*>::iterator j = allEdges.begin(); j != allEdges.end(); ++j) {
1066 const bool outgoing = cluster.count(e->
getFromNode()) > 0;
1072 for (std::vector<NBEdge::Connection>::iterator k = conns.begin(); k != conns.end(); ++k) {
1082 for (NodeSet::const_iterator j = cluster.begin(); j != cluster.end(); ++j) {
1091 std::set<std::string> ids;
1092 for (std::set<NBNode*>::const_iterator j = cluster.begin(); j != cluster.end(); j++) {
1093 ids.insert((*j)->getID());
1104 bool ambiguousType =
false;
1105 for (std::set<NBNode*>::const_iterator j = cluster.begin(); j != cluster.end(); j++) {
1106 pos.
add((*j)->getPosition());
1108 if ((*j)->isTLControlled()) {
1111 type = (*(*j)->getControllingTLS().begin())->getType();
1112 }
else if (type != (*(*j)->getControllingTLS().begin())->getType()) {
1113 ambiguousType =
true;
1119 nodeType = otherType;
1120 }
else if (nodeType != otherType) {
1132 pos.
mul(1.0 / cluster.size());
1133 if (ambiguousType) {
1135 WRITE_WARNING(
"Ambiguous traffic light type for node cluster '" +
id +
"' set to '" +
toString(type) +
"'");
1145 bool tooFast =
false;
1147 std::set<NBEdge*> seen;
1148 for (std::set<NBNode*>::const_iterator j = c.begin(); j != c.end(); ++j) {
1150 for (EdgeVector::const_iterator k = edges.begin(); k != edges.end(); ++k) {
1151 if (c.find((*k)->getFromNode()) != c.end() && c.find((*k)->getToNode()) != c.end()) {
1154 if ((*j)->hasIncoming(*k)) {
1156 f += (double)(*k)->getNumLanes() * (*k)->getLaneSpeed(0);
1160 if ((*k)->getLaneSpeed(0) * 3.6 > 79) {
1165 return !tooFast && f >= 150. / 3.6 && c.size() != 0;
1172 std::vector<NBNode*> ncontrolled;
1173 if (oc.
isSet(
"tls.unset")) {
1174 std::vector<std::string> notTLControlledNodes = oc.
getStringVector(
"tls.unset");
1175 for (std::vector<std::string>::const_iterator i = notTLControlledNodes.begin(); i != notTLControlledNodes.end(); ++i) {
1178 throw ProcessError(
" The junction '" + *i +
"' to set as not-controlled is not known.");
1181 for (std::set<NBTrafficLightDefinition*>::const_iterator j = tls.begin(); j != tls.end(); ++j) {
1182 (*j)->removeNode(n);
1185 ncontrolled.push_back(n);
1192 if (oc.
exists(
"tls.taz-nodes") && oc.
getBool(
"tls.taz-nodes")) {
1193 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
1194 NBNode* cur = (*i).second;
1195 if (cur->
isNearDistrict() && find(ncontrolled.begin(), ncontrolled.end(), cur) == ncontrolled.end()) {
1203 if (oc.
exists(
"tls.guess-signals") && oc.
getBool(
"tls.guess-signals")) {
1205 const double signalDist = oc.
getFloat(
"tls.guess-signals.dist");
1206 for (std::map<std::string, NBNode*>::const_iterator i =
myNodes.begin(); i !=
myNodes.end(); ++i) {
1207 NBNode* node = (*i).second;
1210 for (EdgeVector::const_iterator it_o = outgoing.begin(); it_o != outgoing.end(); ++it_o) {
1211 (*it_o)->setSignalOffset((*it_o)->getLength());
1216 for (std::map<std::string, NBNode*>::const_iterator i =
myNodes.begin(); i !=
myNodes.end(); ++i) {
1217 NBNode* node = i->second;
1218 if (find(ncontrolled.begin(), ncontrolled.end(), node) != ncontrolled.end()) {
1224 std::vector<NBNode*> signals;
1226 for (EdgeVector::const_iterator it_i = incoming.begin(); it_i != incoming.end(); ++it_i) {
1227 const NBEdge* inEdge = *it_i;
1238 for (EdgeVector::const_iterator it_i = outgoing.begin(); it_i != outgoing.end(); ++it_i) {
1239 const NBEdge* outEdge = *it_i;
1242 signals.push_back(cand);
1246 for (std::vector<NBNode*>::iterator j = signals.begin(); j != signals.end(); ++j) {
1249 for (std::set<NBTrafficLightDefinition*>::iterator k = tls.begin(); k != tls.end(); ++k) {
1255 if (!tlc.
insert(tlDef)) {
1267 if (!oc.
getBool(
"tls.guess")) {
1277 for (NodeClusters::iterator i = cands.begin(); i != cands.end();) {
1281 for (NodeSet::iterator j = c.begin(); j != c.end();) {
1282 if ((*j)->isTLControlled() || find(ncontrolled.begin(), ncontrolled.end(), *j) != ncontrolled.end()) {
1297 for (NodeClusters::iterator i = cands.begin(); i != cands.end(); ++i) {
1298 std::vector<NBNode*> nodes;
1299 for (NodeSet::iterator j = (*i).begin(); j != (*i).end(); j++) {
1300 nodes.push_back(*j);
1302 std::string
id =
"joinedG_" +
toString(index++);
1304 if (!tlc.
insert(tlDef)) {
1314 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
1315 NBNode* cur = (*i).second;
1321 if (find(ncontrolled.begin(), ncontrolled.end(), cur) != ncontrolled.end()) {
1340 for (NodeSet::iterator j = c.begin(); j != c.end();) {
1341 if (!(*j)->isTLControlled()) {
1353 std::string
id =
"joined";
1357 for (std::set<NBNode*>::iterator j = c.begin(); j != c.end(); ++j) {
1358 std::set<NBTrafficLightDefinition*> tls = (*j)->getControllingTLS();
1359 (*j)->removeTrafficLights();
1360 for (std::set<NBTrafficLightDefinition*>::iterator k = tls.begin(); k != tls.end(); ++k) {
1364 id =
"joinedS_" +
toString(index++);
1365 std::vector<NBNode*> nodes;
1366 for (NodeSet::iterator j = c.begin(); j != c.end(); j++) {
1367 nodes.push_back(*j);
1370 if (!tlc.
insert(tlDef)) {
1387 if (!tlc.
insert(tlDef)) {
1389 WRITE_WARNING(
"Building a tl-logic for junction '" +
id +
"' twice is not possible.");
1399 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
1400 (*i).second->computeLanes2Lanes();
1408 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
1409 (*i).second->computeLogic(ec, oc);
1416 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
1417 delete((*i).second);
1430 std::string freeID =
"SUMOGenerated" + toString<int>(counter);
1435 freeID =
"SUMOGenerated" + toString<int>(counter);
1443 for (NodeCont::iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
1444 (*i).second->computeNodeShape(mismatchThreshold);
1451 int numUnregulatedJunctions = 0;
1452 int numDeadEndJunctions = 0;
1453 int numPriorityJunctions = 0;
1454 int numRightBeforeLeftJunctions = 0;
1455 int numAllWayStopJunctions = 0;
1456 int numZipperJunctions = 0;
1457 int numRailSignals = 0;
1458 for (NodeCont::const_iterator i =
myNodes.begin(); i !=
myNodes.end(); i++) {
1459 switch ((*i).second->getType()) {
1462 ++numUnregulatedJunctions;
1465 ++numDeadEndJunctions;
1472 ++numPriorityJunctions;
1475 ++numRightBeforeLeftJunctions;
1478 ++numAllWayStopJunctions;
1481 ++numZipperJunctions;
1484 ++numRightBeforeLeftJunctions;
1497 if (numDeadEndJunctions > 0) {
1502 if (numAllWayStopJunctions > 0) {
1505 if (numZipperJunctions > 0) {
1508 if (numRailSignals > 0) {
1514 std::vector<std::string>
1516 std::vector<std::string> ret;
1517 for (NodeCont::const_iterator i =
myNodes.begin(); i !=
myNodes.end(); ++i) {
1518 ret.push_back((*i).first);
1526 if (
myNodes.count(newID) != 0) {
1527 throw ProcessError(
"Attempt to rename node using existing id '" + newID +
"'");
1537 for (NodeCont::const_iterator i =
myNodes.begin(); i !=
myNodes.end(); ++i) {
1538 NBNode* node = i->second;
1545 for (EdgeVector::const_iterator it_o = outgoing.begin(); it_o != outgoing.end(); ++it_o) {
1546 (*it_o)->setSignalOffset((*it_o)->getLength());
1549 for (std::set<NBTrafficLightDefinition*>::const_iterator it = tldefs.begin(); it != tldefs.end(); ++it) {
1564 NBNode* node = item.second;
1575 std::set<std::string> reserve;
1578 avoid.insert(avoid.end(), reserve.begin(), reserve.end());
1582 for (NodeCont::iterator it =
myNodes.begin(); it !=
myNodes.end(); it++) {
1587 toChange.insert(it->second);
1590 if (reservedIDs && reserve.count(it->first) > 0) {
1591 toChange.insert(it->second);
1595 for (
NBNode* node : toChange) {
1600 node->setID(idSupplier.
getNext());
1601 myNodes[node->getID()] = node;
1603 if (prefix.empty()) {
1604 return (
int)toChange.size();
1609 for (
auto item : oldNodes) {
1611 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.
NBEdge * getConnectionTo(NBNode *n) const
get connection to certain node
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.