예제 #1
0
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);
}