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()); } }