void
MSRouteHandler::myEndElement(SumoXMLTag element) throw(ProcessError) {
    switch (element) {
    case SUMO_TAG_ROUTE:
        closeRoute();
        break;
    case SUMO_TAG_PERSON:
        closePerson();
        delete myVehicleParameter;
        myVehicleParameter = 0;
        break;
    case SUMO_TAG_VEHICLE:
        if (myVehicleParameter->repetitionNumber>0) {
            myVehicleParameter->repetitionNumber++; // for backwards compatibility
            // it is a flow, thus no break here
        } else {
            closeVehicle();
            delete myVehicleParameter;
            myVehicleParameter = 0;
            break;
        }
    case SUMO_TAG_FLOW:
        closeFlow();
        break;
    case SUMO_TAG_VTYPE_DISTRIBUTION:
        closeVehicleTypeDistribution();
        break;
    case SUMO_TAG_ROUTE_DISTRIBUTION:
        closeRouteDistribution();
        break;
    case SUMO_TAG_VTYPE: {
        SUMOVehicleParserHelper::closeVTypeParsing(*myCurrentVType);
        MSVehicleType *vehType = MSVehicleType::build(*myCurrentVType);
        delete myCurrentVType;
        myCurrentVType = 0;
        if (!MSNet::getInstance()->getVehicleControl().addVType(vehType)) {
            std::string id = vehType->getID();
            delete vehType;
#ifdef HAVE_MESOSIM
            if (!MSGlobals::gStateLoaded) {
#endif
                throw ProcessError("Another vehicle type (or distribution) with the id '" + id + "' exists.");
#ifdef HAVE_MESOSIM
            }
#endif
        } else {
            if (myCurrentVTypeDistribution != 0) {
                myCurrentVTypeDistribution->add(vehType->getDefaultProbability(), vehType);
            }
        }
    }
    break;
    default:
        break;
    }
}
Esempio n. 2
0
void
SUMORouteHandler::myEndElement(int element) {
    switch (element) {
        case SUMO_TAG_ROUTE:
            closeRoute();
            break;
        case SUMO_TAG_PERSON:
            closePerson();
            delete myVehicleParameter;
            myVehicleParameter = 0;
            break;
        case SUMO_TAG_CONTAINER:
            closeContainer();
            delete myVehicleParameter;
            myVehicleParameter = 0;
            break;
        case SUMO_TAG_VEHICLE:
            if (myVehicleParameter->repetitionNumber > 0) {
                myVehicleParameter->repetitionNumber++; // for backwards compatibility
                // it is a flow, thus no break here
            } else {
                closeVehicle();
                delete myVehicleParameter;
                myVehicleParameter = 0;
                break;
            }
        case SUMO_TAG_FLOW:
            closeFlow();
            break;
        case SUMO_TAG_VTYPE_DISTRIBUTION:
            closeVehicleTypeDistribution();
            break;
        case SUMO_TAG_ROUTE_DISTRIBUTION:
            closeRouteDistribution();
            break;
        case SUMO_TAG_VTYPE:
            SUMOVehicleParserHelper::closeVTypeParsing(*myCurrentVType);
            break;
        case SUMO_TAG_INTERVAL:
            myBeginDefault = string2time(OptionsCont::getOptions().getString("begin"));
            myEndDefault = string2time(OptionsCont::getOptions().getString("end"));
            break;
        default:
            break;
    }
}
Esempio n. 3
0
void
RORouteHandler::closeFlow() {
    // @todo: consider myScale?
    if (myVehicleParameter->repetitionNumber == 0) {
        delete myVehicleParameter;
        myVehicleParameter = 0;
        return;
    }
    // let's check whether vehicles had to depart before the simulation starts
    myVehicleParameter->repetitionsDone = 0;
    const SUMOTime offsetToBegin = myBegin - myVehicleParameter->depart;
    while (myVehicleParameter->repetitionsDone * myVehicleParameter->repetitionOffset < offsetToBegin) {
        myVehicleParameter->repetitionsDone++;
        if (myVehicleParameter->repetitionsDone == myVehicleParameter->repetitionNumber) {
            delete myVehicleParameter;
            myVehicleParameter = 0;
            return;
        }
    }
    if (myNet.getVehicleTypeSecure(myVehicleParameter->vtypeid) == 0) {
        myErrorOutput->inform("The vehicle type '" + myVehicleParameter->vtypeid + "' for flow '" + myVehicleParameter->id + "' is not known.");
    }
    if (myVehicleParameter->routeid[0] == '!' && myNet.getRouteDef(myVehicleParameter->routeid) == 0) {
        closeRoute(true);
    }
    if (myNet.getRouteDef(myVehicleParameter->routeid) == 0) {
        myErrorOutput->inform("The route '" + myVehicleParameter->routeid + "' for flow '" + myVehicleParameter->id + "' is not known.");
        delete myVehicleParameter;
        myVehicleParameter = 0;
        return;
    }
    myActiveRouteID = "";
    if (!MsgHandler::getErrorInstance()->wasInformed()) {
        if (myNet.addFlow(myVehicleParameter, OptionsCont::getOptions().getBool("randomize-flows"))) {
            registerLastDepart();
        } else {
            myErrorOutput->inform("Another flow with the id '" + myVehicleParameter->id + "' exists.");
        }
    } else {
        delete myVehicleParameter;
    }
    myVehicleParameter = 0;
    myInsertStopEdgesAt = -1;
}
Esempio n. 4
0
void
RORouteHandler::parseFromViaTo(std::string element,
                               const SUMOSAXAttributes& attrs) {
    bool useTaz = OptionsCont::getOptions().getBool("with-taz");
    if (useTaz && !myVehicleParameter->wasSet(VEHPARS_TAZ_SET)) {
        WRITE_WARNING("Taz usage was requested but no taz present in " + element + " '" + myVehicleParameter->id + "'!");
        useTaz = false;
    } else if (!useTaz && !attrs.hasAttribute(SUMO_ATTR_FROM) && myVehicleParameter->wasSet(VEHPARS_TAZ_SET)) {
        WRITE_WARNING("'from' attribute missing using taz for " + element + " '" + myVehicleParameter->id + "'!");
        useTaz = true;
    }
    if (useTaz) {
        const ROEdge* fromTaz = myNet.getEdge(myVehicleParameter->fromTaz + "-source");
        if (fromTaz == 0) {
            myErrorOutput->inform("Source taz '" + myVehicleParameter->fromTaz + "' not known for " + element + " '" + myVehicleParameter->id + "'!");
        } else if (fromTaz->getNoFollowing() == 0) {
            myErrorOutput->inform("Source taz '" + myVehicleParameter->fromTaz + "' has no outgoing edges for " + element + " '" + myVehicleParameter->id + "'!");
        } else {
            myActiveRoute.push_back(fromTaz);
        }
        const ROEdge* toTaz = myNet.getEdge(myVehicleParameter->toTaz + "-sink");
        if (toTaz == 0) {
            myErrorOutput->inform("Sink taz '" + myVehicleParameter->toTaz + "' not known for " + element + " '" + myVehicleParameter->id + "'!");
        } else {
            myActiveRoute.push_back(toTaz);
        }
    } else {
        bool ok = true;
        parseEdges(attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok),
                   myActiveRoute, "for " + element + " '" + myVehicleParameter->id + "'");
        parseEdges(attrs.getOpt<std::string>(SUMO_ATTR_VIA, myVehicleParameter->id.c_str(), ok, "", true),
                   myActiveRoute, "for " + element + " '" + myVehicleParameter->id + "'");
        parseEdges(attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok, !myEmptyDestinationsAllowed),
                   myActiveRoute, "for " + element + " '" + myVehicleParameter->id + "'");
    }
    myActiveRouteID = "!" + myVehicleParameter->id;
    if (myVehicleParameter->routeid == "") {
        myVehicleParameter->routeid = myActiveRouteID;
    }
    closeRoute(true);
}
Esempio n. 5
0
void
RORouteHandler::myEndElement(int element) {
    SUMORouteHandler::myEndElement(element);
    switch (element) {
        case SUMO_TAG_VTYPE:
            if (myNet.addVehicleType(myCurrentVType)) {
                if (myCurrentVTypeDistribution != 0) {
                    myCurrentVTypeDistribution->add(myCurrentVType, myCurrentVType->defaultProbability);
                }
            }
            myCurrentVType = 0;
            break;
        case SUMO_TAG_TRIP:
            closeRoute(true);
            closeVehicle();
            delete myVehicleParameter;
            myVehicleParameter = 0;
            myInsertStopEdgesAt = -1;
            break;
        default:
            break;
    }
}
void
SUMORouteHandler::myEndElement(int element) {
    switch (element) {
        case SUMO_TAG_ROUTE:
            closeRoute();
            break;
        case SUMO_TAG_PERSON:
            closePerson();
            delete myVehicleParameter;
            myVehicleParameter = 0;
            break;
        case SUMO_TAG_VEHICLE:
            if (myVehicleParameter->repetitionNumber > 0) {
                myVehicleParameter->repetitionNumber++; // for backwards compatibility
                // it is a flow, thus no break here
            } else {
                closeVehicle();
                delete myVehicleParameter;
                myVehicleParameter = 0;
                break;
            }
        case SUMO_TAG_FLOW:
            closeFlow();
            break;
        case SUMO_TAG_VTYPE_DISTRIBUTION:
            closeVehicleTypeDistribution();
            break;
        case SUMO_TAG_ROUTE_DISTRIBUTION:
            closeRouteDistribution();
            break;
        case SUMO_TAG_VTYPE:
            SUMOVehicleParserHelper::closeVTypeParsing(*myCurrentVType);
            break;
        default:
            break;
    }
}
Esempio n. 7
0
void MSRouteHandler::myStartElement
 (int element, const SUMOSAXAttributes& attrs)
{
  if(oc.getLoadVerbosity()>1)
    std::cout << "----> MSRouteHandler::myStartElement" << std::endl;
    switch (element) {
        case SUMO_TAG_VEHICLE:
            delete myVehicleParameter;
            myVehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(attrs);
            if(oc.getLoadVerbosity()>1)
              std::cout << "[110] MSRouteHandler::myStartElement\n  myVehiclePar"
                           "ameter->vtypeid=" << myVehicleParameter->vtypeid
                        << "\n  myVehicleParameter->id=" << myVehicleParameter
                           ->id << std::endl;
            /*TASK
             *   This could be the first place where we can process the
             * electric or nonelectric characteristics of the vehicles
             */
            if((myVehicleParameter->id.substr(0, 4)=="elec")  ||//DEPRECATED(MANTAIN)
               (myVehicleParameter->id.substr(0, 6)=="SHelec")||//DEPRECATED(MANTAIN)
               (myVehicleParameter->id.substr(0, 6)=="SHElec")||
               (myVehicleParameter->id.substr(0, 9)=="SHItaElec")||
               (myVehicleParameter->id.substr(0, 9)=="SHGerElec")||
               (myVehicleParameter->id.substr(0, 3)=="fev"))               
            {
              //TASK (uprego) This should be safe, but I'm not completely sure
              myVehicleParameter->vtypeid = DEFAULT_ELECVTYPE_ID;
              // Electric cars turn green
              myVehicleParameter->color = HIB_CAR_COLOR_GREEN;
            }
            else if((myVehicleParameter->id.substr(0, 4)=="norm")||//DEPRECATED(MANTAIN)
                    (myVehicleParameter->id.substr(0, 6)=="SHnorm")||//DEPRECATED(MANTAIN)
                    (myVehicleParameter->id.substr(0, 6)=="SHItaNorm")||
                    (myVehicleParameter->id.substr(0, 6)=="SHGerNorm")||
                    (myVehicleParameter->id.substr(0, 6)=="SHNorm"))
            {
              // Normal cars remain yellow
              myVehicleParameter->color = HIB_CAR_COLOR_YELLOW_TRY;
            }
            else 
            {
              /*
              BUSCARLO EN LOS VEHICLES TO TRACK LIST !!!
              IF ESTA
                // CREARLE EL VTYPEID
              ELSE
                // Default yellow
                myVehicleParameter->color = HIB_CAR_COLOR_YELLOW_TRY;
              */
              myVehicleParameter->color=HIB_CAR_COLOR_YELLOW_TRY; // TASK TODO FIXME ALERT DANGER DELETEME
            }            
            break;
        case SUMO_TAG_PERSON:
            delete myVehicleParameter;
            myVehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(attrs);
            myActivePlan = new MSPerson::MSPersonPlan();
            break;
        case SUMO_TAG_RIDE: {
            const std::string pid = myVehicleParameter->id;
            bool ok = true;
            MSEdge* from = 0;
            if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
                const std::string fromID = attrs.getStringReporting(SUMO_ATTR_FROM, pid.c_str(), ok);
                from = MSEdge::dictionary(fromID);
                if (from == 0) {
                    throw ProcessError("The from edge '" + fromID + "' within a ride of person '" + pid + "' is not known.");
                }
                if (!myActivePlan->empty() && &myActivePlan->back()->getDestination() != from) {
                    throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + fromID + "!=" + myActivePlan->back()->getDestination().getID() + ").");
                }
                if (myActivePlan->empty()) {
                    myActivePlan->push_back(new MSPerson::MSPersonStage_Waiting(*from, -1, myVehicleParameter->depart));
                }
            }
            const std::string toID = attrs.getStringReporting(SUMO_ATTR_TO, pid.c_str(), ok);
            MSEdge* to = MSEdge::dictionary(toID);
            if (to == 0) {
                throw ProcessError("The to edge '" + toID + "' within a ride of person '" + pid + "' is not known.");
            }
            const std::string desc = attrs.getStringReporting(SUMO_ATTR_LINES, pid.c_str(), ok);
            StringTokenizer st(desc);
            myActivePlan->push_back(new MSPerson::MSPersonStage_Driving(*to, st.getVector()));
            break;
        }
        case SUMO_TAG_WALK: {
            myActiveRoute.clear();
            bool ok = true;
            MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_EDGES, myVehicleParameter->id.c_str(), ok), myActiveRoute, myActiveRouteID);
            if (myActiveRoute.empty()) {
                throw ProcessError("No edges to walk for person '" + myVehicleParameter->id + "'.");
            }
            if (!myActivePlan->empty() && &myActivePlan->back()->getDestination() != myActiveRoute.front()) {
                throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + myActiveRoute.front()->getID() + "!=" + myActivePlan->back()->getDestination().getID() + ").");
            }
            if (myActivePlan->empty()) {
                myActivePlan->push_back(new MSPerson::MSPersonStage_Waiting(*myActiveRoute.front(), -1, myVehicleParameter->depart));
            }
            const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, 0, ok, -1);
            const SUMOReal speed = attrs.getOptSUMORealReporting(SUMO_ATTR_SPEED, 0, ok, -1);
            myActivePlan->push_back(new MSPerson::MSPersonStage_Walking(myActiveRoute, duration, speed));
            myActiveRoute.clear();
            break;
        }
        case SUMO_TAG_FLOW:
            delete myVehicleParameter;
            myVehicleParameter = SUMOVehicleParserHelper::parseFlowAttributes(attrs);
            if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
                myActiveRouteID = "!" + myVehicleParameter->id;
                bool ok = true;
                MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok),
                                       myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
                MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok),
                                       myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
                closeRoute();
            }
            break;
        case SUMO_TAG_VTYPE__DEPRECATED:
            if (!myHaveWarnedAboutDeprecatedVType) {
                myHaveWarnedAboutDeprecatedVType = true;
                WRITE_WARNING("'" + toString(SUMO_TAG_VTYPE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_VTYPE) + "'.");
            }
        case SUMO_TAG_VTYPE:
            myCurrentVType = SUMOVehicleParserHelper::beginVTypeParsing(attrs);
            break;
        case SUMO_TAG_VTYPE_DISTRIBUTION__DEPRECATED:
            if (!myHaveWarnedAboutDeprecatedVTypeDistribution) {
                myHaveWarnedAboutDeprecatedVTypeDistribution = true;
                WRITE_WARNING("'" + toString(SUMO_TAG_VTYPE_DISTRIBUTION__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_VTYPE_DISTRIBUTION) + "'.");
            }
        case SUMO_TAG_VTYPE_DISTRIBUTION:
            openVehicleTypeDistribution(attrs);
            break;
        case SUMO_TAG_ROUTE:
            openRoute(attrs);
            break;
        case SUMO_TAG_ROUTE_DISTRIBUTION:
            openRouteDistribution(attrs);
            break;
        case SUMO_TAG_STOP:
            addStop(attrs);
            break;
        case SUMO_TAG_TRIP__DEPRECATED:
        case SUMO_TAG_TRIP: {
            bool ok = true;
            myVehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(attrs);
            myVehicleParameter->setParameter |= VEHPARS_FORCE_REROUTE;
            myActiveRouteID = "!" + myVehicleParameter->id;
            if (attrs.hasAttribute(SUMO_ATTR_FROM) || !myVehicleParameter->wasSet(VEHPARS_TAZ_SET)) {
                MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok),
                                       myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
                MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok),
                                       myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
            } else {
                const MSEdge* fromTaz = MSEdge::dictionary(myVehicleParameter->fromTaz + "-source");
                if (fromTaz == 0) {
                    WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' not known for '" + myVehicleParameter->id + "'!");
                } else if (fromTaz->getNoFollowing() == 0) {
                    WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' has no outgoing edges for '" + myVehicleParameter->id + "'!");
                } else {
                    myActiveRoute.push_back(fromTaz->getFollower(0));
                }
            }
            closeRoute();
            closeVehicle();
        }
        break;
        default:
            break;
    }
    // parse embedded vtype information
    if (myCurrentVType != 0 && element != SUMO_TAG_VTYPE && element != SUMO_TAG_VTYPE__DEPRECATED) {
        SUMOVehicleParserHelper::parseVTypeEmbedded(*myCurrentVType, element, attrs);
        return;
    }
}
Esempio n. 8
0
void
MSRouteHandler::myStartElement(int element,
                               const SUMOSAXAttributes& attrs) {
    SUMORouteHandler::myStartElement(element, attrs);
    switch (element) {
        case SUMO_TAG_PERSON:
            myActivePlan = new MSPerson::MSPersonPlan();
            break;
        case SUMO_TAG_RIDE: {
            const std::string pid = myVehicleParameter->id;
            bool ok = true;
            MSEdge* from = 0;
            const std::string desc = attrs.get<std::string>(SUMO_ATTR_LINES, pid.c_str(), ok);
            StringTokenizer st(desc);
            std::string bsID = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, 0, ok, "");
            MSBusStop* bs = 0;
            if (bsID != "") {
                bs = MSNet::getInstance()->getBusStop(bsID);
                if (bs == 0) {
                    throw ProcessError("Unknown bus stop '" + bsID + "' for person '" + myVehicleParameter->id + "'.");
                }
            }
            if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
                const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, pid.c_str(), ok);
                from = MSEdge::dictionary(fromID);
                if (from == 0) {
                    throw ProcessError("The from edge '" + fromID + "' within a ride of person '" + pid + "' is not known.");
                }
                if (!myActivePlan->empty() && &myActivePlan->back()->getDestination() != from) {
                    throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + fromID + "!=" + myActivePlan->back()->getDestination().getID() + ").");
                }
                if (myActivePlan->empty()) {
                    myActivePlan->push_back(new MSPerson::MSPersonStage_Waiting(
                                                *from, -1, myVehicleParameter->depart, myVehicleParameter->departPos, "start"));
                }
            } else if (myActivePlan->empty()) {
                throw ProcessError("The start edge within for person '" + pid + "' is not known.");
            }
            const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, pid.c_str(), ok);
            MSEdge* to = MSEdge::dictionary(toID);
            if (to == 0) {
                throw ProcessError("The to edge '" + toID + "' within a ride of person '" + pid + "' is not known.");
            }
            myActivePlan->push_back(new MSPerson::MSPersonStage_Driving(*to, bs, st.getVector()));
            break;
        }
        case SUMO_TAG_WALK: {
            myActiveRoute.clear();
            bool ok = true;
            if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
                MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_EDGES, myVehicleParameter->id.c_str(), ok), myActiveRoute, myActiveRouteID);
            } else {
                if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
                    const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok);
                    MSEdge* from = MSEdge::dictionary(fromID);
                    if (from == 0) {
                        throw ProcessError("The from edge '" + fromID + "' within a walk of person '" + myVehicleParameter->id + "' is not known.");
                    }
                    const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok);
                    MSEdge* to = MSEdge::dictionary(toID);
                    if (to == 0) {
                        throw ProcessError("The to edge '" + toID + "' within a walk of person '" + myVehicleParameter->id + "' is not known.");
                    }
                    MSNet::getInstance()->getRouterTT().compute(from, to, 0, 0, myActiveRoute); // @todo: only footways, current time?
                }
            }
            if (myActiveRoute.empty()) {
                throw ProcessError("No edges to walk for person '" + myVehicleParameter->id + "'.");
            }
            if (!myActivePlan->empty() && &myActivePlan->back()->getDestination() != myActiveRoute.front()) {
                throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + myActiveRoute.front()->getID() + "!=" + myActivePlan->back()->getDestination().getID() + ").");
            }
            SUMOReal departPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_DEPARTPOS, myVehicleParameter->id.c_str(), ok, 0);
            SUMOReal arrivalPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_ARRIVALPOS, myVehicleParameter->id.c_str(), ok, -1);
            const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, 0, ok, -1);
            SUMOReal speed = DEFAULT_PERSON_SPEED;
            if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
                speed = attrs.getOpt<SUMOReal>(SUMO_ATTR_SPEED, 0, ok, speed);
                if (speed < 0) {
                    throw ProcessError("Negative walking speed for  '" + myVehicleParameter->id + "'.");
                }
            }
            std::string bsID = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, 0, ok, "");
            MSBusStop* bs = 0;
            if (bsID != "") {
                bs = MSNet::getInstance()->getBusStop(bsID);
                if (bs == 0) {
                    throw ProcessError("Unknown bus stop '" + bsID + "' for person '" + myVehicleParameter->id + "'.");
                }
            }
            if (myActivePlan->empty()) {
                myActivePlan->push_back(new MSPerson::MSPersonStage_Waiting(
                                            *myActiveRoute.front(), -1, myVehicleParameter->depart, departPos, "start"));
            }
            myActivePlan->push_back(new MSPerson::MSPersonStage_Walking(myActiveRoute, bs, duration, speed, departPos, arrivalPos));
            myActiveRoute.clear();
            break;
        }
        case SUMO_TAG_FLOW:
            if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
                myActiveRouteID = "!" + myVehicleParameter->id;
                bool ok = true;
                MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok),
                                       myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
                MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok),
                                       myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
                closeRoute(true);
            }
            break;
        case SUMO_TAG_TRIP: {
            bool ok = true;
            if (attrs.hasAttribute(SUMO_ATTR_FROM) || !myVehicleParameter->wasSet(VEHPARS_TAZ_SET)) {
                MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok),
                                       myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
                MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok),
                                       myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
            } else {
                const MSEdge* fromTaz = MSEdge::dictionary(myVehicleParameter->fromTaz + "-source");
                if (fromTaz == 0) {
                    WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' not known for '" + myVehicleParameter->id + "'!");
                } else if (fromTaz->getNoFollowing() == 0) {
                    WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' has no outgoing edges for '" + myVehicleParameter->id + "'!");
                } else {
                    myActiveRoute.push_back(fromTaz->getFollower(0));
                }
            }
            closeRoute(true);
            closeVehicle();
        }
        break;
        default:
            break;
    }
    // parse embedded vtype information
    if (myCurrentVType != 0 && element != SUMO_TAG_VTYPE && element != SUMO_TAG_PARAM) {
        SUMOVehicleParserHelper::parseVTypeEmbedded(*myCurrentVType, element, attrs);
        return;
    }
}
void
MSRouteHandler::myStartElement(SumoXMLTag element,
                               const SUMOSAXAttributes &attrs) throw(ProcessError) {
    switch (element) {
    case SUMO_TAG_VEHICLE:
        delete myVehicleParameter;
        myVehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(attrs);
        break;
    case SUMO_TAG_PERSON:
        delete myVehicleParameter;
        myVehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(attrs);
        myActivePlan = new MSPerson::MSPersonPlan();
        break;
    case SUMO_TAG_RIDE: {
        const std::string pid = myVehicleParameter->id;
        bool ok = true;
        MSEdge *from = 0;
        if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
            const std::string fromID = attrs.getStringReporting(SUMO_ATTR_FROM, "ride", pid.c_str(), ok);
            from = MSEdge::dictionary(fromID);
            if (from==0) {
                throw ProcessError("The from edge '" + fromID + "' within a ride of person '" + pid + "' is not known.");
            }
            if (myActivePlan->empty() || &myActivePlan->back()->getDestination() != from) {
                myActivePlan->push_back(new MSPerson::MSPersonStage_Waiting(*from, -1, myVehicleParameter->depart));
            }
        }
        const std::string toID = attrs.getStringReporting(SUMO_ATTR_TO, "ride", pid.c_str(), ok);
        MSEdge *to = MSEdge::dictionary(toID);
        if (to==0) {
            throw ProcessError("The to edge '" + toID + "' within a ride of person '" + pid + "' is not known.");
        }
        const std::string desc = attrs.getStringReporting(SUMO_ATTR_LINES, "ride", pid.c_str(), ok);
        StringTokenizer st(desc);
        myActivePlan->push_back(new MSPerson::MSPersonStage_Driving(*to, st.getVector()));
        break;
    }
    case SUMO_TAG_WALK: {
        myActiveRoute.clear();
        bool ok = true;
        MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_EDGES, "walk", myVehicleParameter->id.c_str(), ok), myActiveRoute, myActiveRouteID);
        if (myActiveRoute.empty()) {
            throw ProcessError("No edges to walk for person '" + myVehicleParameter->id + "'.");
        }
        if (myActivePlan->empty() || &myActivePlan->back()->getDestination() != myActiveRoute.front()) {
            myActivePlan->push_back(new MSPerson::MSPersonStage_Waiting(*myActiveRoute.front(), -1, myVehicleParameter->depart));
        }
        const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, "walk", 0, ok, -1);
        const SUMOReal speed = attrs.getOptSUMORealReporting(SUMO_ATTR_SPEED, "walk", 0, ok, -1);
        myActivePlan->push_back(new MSPerson::MSPersonStage_Walking(myActiveRoute, duration, speed));
        myActiveRoute.clear();
        break;
    }
    case SUMO_TAG_FLOW:
        delete myVehicleParameter;
        myVehicleParameter = SUMOVehicleParserHelper::parseFlowAttributes(attrs);
        if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
            myActiveRouteID = "!" + myVehicleParameter->id;
            bool ok = true;
            MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_FROM, "flow", myVehicleParameter->id.c_str(), ok), myActiveRoute, myActiveRouteID);
            MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_TO, "flow", myVehicleParameter->id.c_str(), ok), myActiveRoute, myActiveRouteID);
            closeRoute();
        }
        break;
    case SUMO_TAG_VTYPE:
        myCurrentVType = SUMOVehicleParserHelper::beginVTypeParsing(attrs);
        break;
    case SUMO_TAG_VTYPE_DISTRIBUTION:
        openVehicleTypeDistribution(attrs);
        break;
    case SUMO_TAG_ROUTE:
        openRoute(attrs);
        break;
    case SUMO_TAG_ROUTE_DISTRIBUTION:
        openRouteDistribution(attrs);
        break;
    case SUMO_TAG_TRIPDEF: {
        bool ok = true;
        myVehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(attrs);
        myActiveRouteID = "!" + myVehicleParameter->id;
        if (attrs.hasAttribute(SUMO_ATTR_FROM) || !myVehicleParameter->wasSet(VEHPARS_TAZ_SET)) {
            MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_FROM, "tripdef", myVehicleParameter->id.c_str(), ok), myActiveRoute, myActiveRouteID);
            MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_TO, "tripdef", myVehicleParameter->id.c_str(), ok), myActiveRoute, myActiveRouteID);
        } else {
            const MSEdge* fromTaz = MSEdge::dictionary(myVehicleParameter->fromTaz+"-source");
            if (fromTaz == 0) {
                WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' not known for '" + myVehicleParameter->id + "'!");
            } else if (fromTaz->getNoFollowing() == 0) {
                WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' has no outgoing edges for '" + myVehicleParameter->id + "'!");
            } else {
                myActiveRoute.push_back(fromTaz->getFollower(0));
            }
        }
        closeRoute();
        closeVehicle();
    }
    break;
    default:
        break;
    }
    // parse embedded vtype information
    if (myCurrentVType!=0&&element!=SUMO_TAG_VTYPE) {
        SUMOVehicleParserHelper::parseVTypeEmbedded(*myCurrentVType, element, attrs);
        return;
    }

    if (element==SUMO_TAG_STOP) {
        bool ok = true;
        SUMOVehicleParameter::Stop stop;
        // try to parse the assigne bus stop
        stop.busstop = attrs.getOptStringReporting(SUMO_ATTR_BUS_STOP, "stop", 0, ok, "");
        if (stop.busstop!="") {
            // ok, we have obviously a bus stop
            MSBusStop *bs = MSNet::getInstance()->getBusStop(stop.busstop);
            if (bs!=0) {
                const MSLane &l = bs->getLane();
                stop.lane = l.getID();
                stop.pos = bs->getEndLanePosition();
            } else {
                MsgHandler::getErrorInstance()->inform("The bus stop '" + stop.busstop + "' is not known.");
                return;
            }
        } else {
            // no, the lane and the position should be given
            // get the lane
            stop.lane = attrs.getOptStringReporting(SUMO_ATTR_LANE, "stop", 0, ok, "");
            if (stop.lane!="") {
                if (MSLane::dictionary(stop.lane)==0) {
                    MsgHandler::getErrorInstance()->inform("The lane '" + stop.lane + "' for a stop is not known.");
                    return;
                }
            } else {
                MsgHandler::getErrorInstance()->inform("A stop must be placed on a bus stop or a lane.");
                return;
            }
            // get the position
            bool ok = true;
            stop.pos = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, "stop", 0, ok);
            if (!ok) {
                return;
            }
        }

        // get the standing duration
        if (!attrs.hasAttribute(SUMO_ATTR_DURATION) && !attrs.hasAttribute(SUMO_ATTR_UNTIL)) {
            MsgHandler::getErrorInstance()->inform("The duration of a stop is not defined.");
            return;
        } else {
            bool ok = true;
            stop.duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, "stop", 0, ok, -1);
            stop.until = attrs.getOptSUMOTimeReporting(SUMO_ATTR_UNTIL, "stop", 0, ok, -1);
            if (!ok) {
                return;
            }
            if (stop.duration<0&&stop.until<0) {
                MsgHandler::getErrorInstance()->inform("Neither the duration nor the end time is given for a stop.");
                return;
            }
        }
        if (myActiveRouteID != "") {
            myActiveRouteStops.push_back(stop);
        } else {
            myVehicleParameter->stops.push_back(stop);
        }
    }
}