void NLHandler::addConnection(const SUMOSAXAttributes& attrs) { bool ok = true; std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, 0, ok); if (!MSGlobals::gUsingInternalLanes && fromID[0] == ':') { return; } try { bool ok = true; const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, 0, ok); const int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, 0, ok); const int toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, 0, ok); LinkDirection dir = parseLinkDir(attrs.get<std::string>(SUMO_ATTR_DIR, 0, ok)); LinkState state = parseLinkState(attrs.get<std::string>(SUMO_ATTR_STATE, 0, ok)); std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, 0, ok, ""); #ifdef HAVE_INTERNAL_LANES std::string viaID = attrs.getOpt<std::string>(SUMO_ATTR_VIA, 0, ok, ""); #endif MSEdge* from = MSEdge::dictionary(fromID); if (from == 0) { WRITE_ERROR("Unknown from-edge '" + fromID + "' in connection"); return; } MSEdge* to = MSEdge::dictionary(toID); if (to == 0) { WRITE_ERROR("Unknown to-edge '" + toID + "' in connection"); return; } if (fromLaneIdx < 0 || static_cast<unsigned int>(fromLaneIdx) >= from->getLanes().size() || toLaneIdx < 0 || static_cast<unsigned int>(toLaneIdx) >= to->getLanes().size()) { WRITE_ERROR("Invalid lane index in connection from '" + from->getID() + "' to '" + to->getID() + "'."); return; } MSLane* fromLane = from->getLanes()[fromLaneIdx]; MSLane* toLane = to->getLanes()[toLaneIdx]; assert(fromLane); assert(toLane); int tlLinkIdx = -1; if (tlID != "") { tlLinkIdx = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, 0, ok); // make sure that the index is in range MSTrafficLightLogic* logic = myJunctionControlBuilder.getTLLogic(tlID).getActive(); if (tlLinkIdx < 0 || tlLinkIdx >= (int)logic->getCurrentPhaseDef().getState().size()) { WRITE_ERROR("Invalid " + toString(SUMO_ATTR_TLLINKINDEX) + " '" + toString(tlLinkIdx) + "' in connection controlled by '" + tlID + "'"); return; } if (!ok) { return; } } SUMOReal length = fromLane->getShape()[-1].distanceTo(toLane->getShape()[0]); MSLink* link = 0; // build the link #ifdef HAVE_INTERNAL_LANES MSLane* via = 0; if (viaID != "" && MSGlobals::gUsingInternalLanes) { via = MSLane::dictionary(viaID); if (via == 0) { WRITE_ERROR("An unknown lane ('" + viaID + "') should be set as a via-lane for lane '" + toLane->getID() + "'."); return; } length = via->getLength(); } link = new MSLink(toLane, via, dir, state, length); if (via != 0) { via->addIncomingLane(fromLane, link); } else { toLane->addIncomingLane(fromLane, link); } #else link = new MSLink(toLane, dir, state, length); toLane->addIncomingLane(fromLane, link); #endif toLane->addApproachingLane(fromLane); // if a traffic light is responsible for it, inform the traffic light // check whether this link is controlled by a traffic light if (tlID != "") { myJunctionControlBuilder.getTLLogic(tlID).addLink(link, fromLane, tlLinkIdx); } // add the link fromLane->addLink(link); } catch (InvalidArgument& e) { WRITE_ERROR(e.what()); } }
void NLSucceedingLaneBuilder::addSuccLane(bool yield, const std::string &laneId, #ifdef HAVE_INTERNAL_LANES const std::string &viaID, SUMOReal pass, #endif MSLink::LinkDirection dir, MSLink::LinkState state, bool internalEnd, const std::string &tlid, unsigned int linkNo) throw(InvalidArgument) { // check whether the link is a dead link if (laneId=="SUMO_NO_DESTINATION") { // build the dead link and add it to the container #ifdef HAVE_INTERNAL_LANES MSLink *link = new MSLink(0, 0, yield, MSLink::LINKDIR_NODIR, MSLink::LINKSTATE_DEADEND, false, 0.); #else MSLink *link = new MSLink(0, yield, MSLink::LINKDIR_NODIR, MSLink::LINKSTATE_DEADEND, 0.); #endif mySuccLanes->push_back(link); if (tlid!="") { MSTLLogicControl::TLSLogicVariants &logics = myJunctionControlBuilder.getTLLogic(tlid); MSLane *current = MSLane::dictionary(myCurrentLane); if (current==0) { throw InvalidArgument("An unknown lane ('" + myCurrentLane + "') should be assigned to a tl-logic."); } logics.addLink(link, current, linkNo); } return; } // get the lane the link belongs to MSLane *lane = MSLane::dictionary(laneId); if (lane==0) { throw InvalidArgument("An unknown lane ('" + laneId + "') should be set as a follower for lane '" + myCurrentLane + "'."); } #ifdef HAVE_INTERNAL_LANES MSLane *via = 0; if (viaID!="" && MSGlobals::gUsingInternalLanes) { via = MSLane::dictionary(viaID); if (via==0) { throw InvalidArgument("An unknown lane ('" + viaID + "') should be set as a via-lane for lane '" + myCurrentLane + "'."); } } if (pass>=0) { static_cast<MSInternalLane*>(lane)->setPassPosition(pass); } #endif MSLane *orig = MSLane::dictionary(myCurrentLane); if (orig==0) { return; } // build the link SUMOReal length = orig!=0&&lane!=0 ? orig->getShape()[-1].distanceTo(lane->getShape()[0]) : 0; #ifdef HAVE_INTERNAL_LANES if (via!=0) { length = via->getLength(); } MSLink *link = new MSLink(lane, via, yield, dir, state, internalEnd, length); #else MSLink *link = new MSLink(lane, yield, dir, state, length); #endif if (MSLane::dictionary(myCurrentLane)!=0) { #ifdef HAVE_INTERNAL_LANES if (via!=0) { // from a normal in to a normal out via // --> via incomes in out lane->addIncomingLane(via, link); // --> in incomes in via via->addIncomingLane(MSLane::dictionary(myCurrentLane), link); } else { if (myCurrentLane[0]!=':') { // internal not wished; other case already set lane->addIncomingLane(MSLane::dictionary(myCurrentLane), link); } } #else lane->addIncomingLane(MSLane::dictionary(myCurrentLane), link); #endif } // if a traffic light is responsible for it, inform the traffic light // check whether this link is controlled by a traffic light if (tlid!="") { MSTLLogicControl::TLSLogicVariants &logics = myJunctionControlBuilder.getTLLogic(tlid); MSLane *current = MSLane::dictionary(myCurrentLane); if (current==0) { throw InvalidArgument("An unknown lane ('" + myCurrentLane + "') should be assigned to a tl-logic."); } logics.addLink(link, current, linkNo); } // add the link to the container mySuccLanes->push_back(link); }