void MSRailSignal::collectConflictLinks(MSLane* toLane, double length, std::vector<MSLane*>& backwardBlock, std::vector<MSLink*>& conflictLinks, LaneSet& visited, bool checkFoes) { while (toLane != nullptr) { //std::cout << "collectConflictLinks " << getID() << " toLane=" << toLane->getID() << " length=" << length // << " backward=" << toString(backwardBlock) // << " conflictLinks=" << conflictLinks.size() // << " visited=" << visited.size() // << " checkFoes=" << checkFoes // << "\n"; const auto& incomingLaneInfos = toLane->getIncomingLanes(); MSLane* orig = toLane; toLane = nullptr; for (const auto& ili : incomingLaneInfos) { if (ili.viaLink->getDirection() == LINKDIR_TURN) { continue; } if (visited.count(ili.lane) != 0) { continue; } if (ili.viaLink->getTLLogic() != nullptr) { conflictLinks.push_back(ili.viaLink); continue; } backwardBlock.push_back(ili.lane); visited.insert(ili.lane); length += orig->getLength(); if (length > MAX_BLOCK_LENGTH) { if (myNumWarnings < MAX_SIGNAL_WARNINGS) { WRITE_WARNING("incoming conflict block after rail signal junction '" + getID() + "' exceeds maximum length (stopped searching after lane '" + orig->getID() + "' (length=" + toString(length) + "m)."); } myNumWarnings++; return; } if (toLane == nullptr) { toLane = ili.lane; } else { collectConflictLinks(ili.lane, length, backwardBlock, conflictLinks, visited, false); } } if (checkFoes && orig->isInternal()) { // check for crossed tracks MSLink* link = orig->getIncomingLanes().front().viaLink; if (link->getDirection() != LINKDIR_TURN) { for (const MSLane* foeConst : link->getFoeLanes()) { MSLane* foe = const_cast<MSLane*>(foeConst); if (visited.count(foe) == 0) { backwardBlock.push_back(foe); visited.insert(foe); collectConflictLinks(foe, length, backwardBlock, conflictLinks, visited, false); } } } } } }
const std::vector<MSLane*> MSLogicJunction::getInternalLanes() const { // Besides the lanes im myInternal lanes, which are only the last parts of the connections, // this collects all lanes on the junction std::vector<MSLane*> allInternalLanes; for (std::vector<MSLane*>::const_iterator i = myInternalLanes.begin(); i != myInternalLanes.end(); ++i) { MSLane* l = *i; while (l != nullptr) { allInternalLanes.push_back(l); const std::vector<MSLane::IncomingLaneInfo> incoming = l->getIncomingLanes(); if (incoming.size() == 0) { break; } assert(l->getIncomingLanes().size() == 1); l = l->getIncomingLanes()[0].lane; if (!l->isInternal()) { break; } } } return allInternalLanes; }