MSRouteHandler.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Parser and container for routes during their loading
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 DLR (http://www.dlr.de/) and contributors
00011 /****************************************************************************/
00012 //
00013 //   This program is free software; you can redistribute it and/or modify
00014 //   it under the terms of the GNU General Public License as published by
00015 //   the Free Software Foundation; either version 2 of the License, or
00016 //   (at your option) any later version.
00017 //
00018 /****************************************************************************/
00019 
00020 
00021 // ===========================================================================
00022 // included modules
00023 // ===========================================================================
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029 
00030 #include <string>
00031 #include <map>
00032 #include <vector>
00033 #include <microsim/MSRoute.h>
00034 #include <microsim/MSEdge.h>
00035 #include <microsim/MSVehicleType.h>
00036 #include <microsim/MSVehicle.h>
00037 #include <microsim/MSEdge.h>
00038 #include <microsim/MSEmitControl.h>
00039 #include <microsim/MSVehicleControl.h>
00040 #include <microsim/MSLane.h>
00041 #include "MSRouteHandler.h"
00042 #include <utils/xml/SUMOSAXHandler.h>
00043 #include <utils/xml/SUMOXMLDefinitions.h>
00044 #include <utils/common/MsgHandler.h>
00045 #include <utils/common/StringTokenizer.h>
00046 #include <utils/common/UtilExceptions.h>
00047 #include <utils/options/OptionsCont.h>
00048 #include "MSNet.h"
00049 
00050 #include <microsim/trigger/MSBusStop.h>
00051 #include <microsim/MSGlobals.h>
00052 #include <utils/xml/SUMOVehicleParserHelper.h>
00053 
00054 #ifdef CHECK_MEMORY_LEAKS
00055 #include <foreign/nvwa/debug_new.h>
00056 #endif // CHECK_MEMORY_LEAKS
00057 
00058 
00059 // ===========================================================================
00060 // method definitions
00061 // ===========================================================================
00062 MSRouteHandler::MSRouteHandler(const std::string &file,
00063                                bool addVehiclesDirectly)
00064         : SUMOSAXHandler(file), myVehicleParameter(0),
00065         myLastDepart(0), myLastReadVehicle(0),
00066         myAddVehiclesDirectly(addVehiclesDirectly),
00067         myRunningVehicleNumber(0),
00068         myCurrentVTypeDistribution(0),
00069         myCurrentRouteDistribution(0),
00070         myHaveWarned(false), myCurrentVType(0) {
00071     myIncrementalBase = OptionsCont::getOptions().getInt("incremental-dua-base");
00072     myIncrementalStage = OptionsCont::getOptions().getInt("incremental-dua-step");
00073     myAmUsingIncrementalDUA = (myIncrementalStage>0);
00074     myActiveRoute.reserve(100);
00075 }
00076 
00077 
00078 MSRouteHandler::~MSRouteHandler() throw() {
00079     delete myVehicleParameter;
00080 }
00081 
00082 
00083 SUMOTime
00084 MSRouteHandler::getLastDepart() const {
00085     return myLastDepart;
00086 }
00087 
00088 
00089 void
00090 MSRouteHandler::retrieveLastReadVehicle(MSEmitControl* into) {
00091     if (myLastReadVehicle != 0) {
00092         if (myLastReadVehicle->getParameter().departProcedure == DEPART_GIVEN) {
00093             into->add(myLastReadVehicle);
00094         }
00095         myLastReadVehicle = 0;
00096     }
00097     if (myVehicleParameter != 0 && myVehicleParameter->repetitionsDone>=0) {
00098         into->add(myVehicleParameter);
00099         myVehicleParameter = 0;
00100     }
00101 }
00102 
00103 
00104 void
00105 MSRouteHandler::myStartElement(SumoXMLTag element,
00106                                const SUMOSAXAttributes &attrs) throw(ProcessError) {
00107     switch (element) {
00108     case SUMO_TAG_VEHICLE:
00109         delete myVehicleParameter;
00110         myVehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(attrs);
00111         break;
00112     case SUMO_TAG_PERSON:
00113         delete myVehicleParameter;
00114         myVehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(attrs);
00115         myActivePlan = new MSPerson::MSPersonPlan();
00116         break;
00117     case SUMO_TAG_RIDE: {
00118         const std::string pid = myVehicleParameter->id;
00119         bool ok = true;
00120         MSEdge *from = 0;
00121         if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
00122             const std::string fromID = attrs.getStringReporting(SUMO_ATTR_FROM, "ride", pid.c_str(), ok);
00123             from = MSEdge::dictionary(fromID);
00124             if (from==0) {
00125                 throw ProcessError("The from edge '" + fromID + "' within a ride of person '" + pid + "' is not known.");
00126             }
00127             if (myActivePlan->empty() || &myActivePlan->back()->getDestination() != from) {
00128                 myActivePlan->push_back(new MSPerson::MSPersonStage_Waiting(*from, -1, myVehicleParameter->depart));
00129             }
00130         }
00131         const std::string toID = attrs.getStringReporting(SUMO_ATTR_TO, "ride", pid.c_str(), ok);
00132         MSEdge *to = MSEdge::dictionary(toID);
00133         if (to==0) {
00134             throw ProcessError("The to edge '" + toID + "' within a ride of person '" + pid + "' is not known.");
00135         }
00136         const std::string desc = attrs.getStringReporting(SUMO_ATTR_LINES, "ride", pid.c_str(), ok);
00137         StringTokenizer st(desc);
00138         myActivePlan->push_back(new MSPerson::MSPersonStage_Driving(*to, st.getVector()));
00139         break;
00140     }
00141     case SUMO_TAG_WALK: {
00142         myActiveRoute.clear();
00143         bool ok = true;
00144         MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_EDGES, "walk", myVehicleParameter->id.c_str(), ok), myActiveRoute, myActiveRouteID);
00145         if (myActiveRoute.empty()) {
00146             throw ProcessError("No edges to walk for person '" + myVehicleParameter->id + "'.");
00147         }
00148         if (myActivePlan->empty() || &myActivePlan->back()->getDestination() != myActiveRoute.front()) {
00149             myActivePlan->push_back(new MSPerson::MSPersonStage_Waiting(*myActiveRoute.front(), -1, myVehicleParameter->depart));
00150         }
00151         const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, "walk", 0, ok, -1);
00152         const SUMOReal speed = attrs.getOptSUMORealReporting(SUMO_ATTR_SPEED, "walk", 0, ok, -1);
00153         myActivePlan->push_back(new MSPerson::MSPersonStage_Walking(myActiveRoute, duration, speed));
00154         myActiveRoute.clear();
00155         break;
00156     }
00157     case SUMO_TAG_FLOW:
00158         delete myVehicleParameter;
00159         myVehicleParameter = SUMOVehicleParserHelper::parseFlowAttributes(attrs);
00160         if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
00161             myActiveRouteID = "!" + myVehicleParameter->id;
00162             bool ok = true;
00163             MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_FROM, "flow", myVehicleParameter->id.c_str(), ok), myActiveRoute, myActiveRouteID);
00164             MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_TO, "flow", myVehicleParameter->id.c_str(), ok), myActiveRoute, myActiveRouteID);
00165             closeRoute();
00166         }
00167         break;
00168     case SUMO_TAG_VTYPE:
00169         myCurrentVType = SUMOVehicleParserHelper::beginVTypeParsing(attrs);
00170         break;
00171     case SUMO_TAG_VTYPE_DISTRIBUTION:
00172         openVehicleTypeDistribution(attrs);
00173         break;
00174     case SUMO_TAG_ROUTE:
00175         openRoute(attrs);
00176         break;
00177     case SUMO_TAG_ROUTE_DISTRIBUTION:
00178         openRouteDistribution(attrs);
00179         break;
00180     case SUMO_TAG_TRIPDEF: {
00181         bool ok = true;
00182         myVehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(attrs);
00183         myActiveRouteID = "!" + myVehicleParameter->id;
00184         if (attrs.hasAttribute(SUMO_ATTR_FROM) || !myVehicleParameter->wasSet(VEHPARS_TAZ_SET)) {
00185             MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_FROM, "tripdef", myVehicleParameter->id.c_str(), ok), myActiveRoute, myActiveRouteID);
00186             MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_TO, "tripdef", myVehicleParameter->id.c_str(), ok), myActiveRoute, myActiveRouteID);
00187         } else {
00188             const MSEdge* fromTaz = MSEdge::dictionary(myVehicleParameter->fromTaz+"-source");
00189             if (fromTaz == 0) {
00190                 WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' not known for '" + myVehicleParameter->id + "'!");
00191             } else if (fromTaz->getNoFollowing() == 0) {
00192                 WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' has no outgoing edges for '" + myVehicleParameter->id + "'!");
00193             } else {
00194                 myActiveRoute.push_back(fromTaz->getFollower(0));
00195             }
00196         }
00197         closeRoute();
00198         closeVehicle();
00199     }
00200     break;
00201     default:
00202         break;
00203     }
00204     // parse embedded vtype information
00205     if (myCurrentVType!=0&&element!=SUMO_TAG_VTYPE) {
00206         SUMOVehicleParserHelper::parseVTypeEmbedded(*myCurrentVType, element, attrs);
00207         return;
00208     }
00209 
00210     if (element==SUMO_TAG_STOP) {
00211         bool ok = true;
00212         SUMOVehicleParameter::Stop stop;
00213         // try to parse the assigne bus stop
00214         stop.busstop = attrs.getOptStringReporting(SUMO_ATTR_BUS_STOP, "stop", 0, ok, "");
00215         if (stop.busstop!="") {
00216             // ok, we have obviously a bus stop
00217             MSBusStop *bs = MSNet::getInstance()->getBusStop(stop.busstop);
00218             if (bs!=0) {
00219                 const MSLane &l = bs->getLane();
00220                 stop.lane = l.getID();
00221                 stop.pos = bs->getEndLanePosition();
00222             } else {
00223                 MsgHandler::getErrorInstance()->inform("The bus stop '" + stop.busstop + "' is not known.");
00224                 return;
00225             }
00226         } else {
00227             // no, the lane and the position should be given
00228             // get the lane
00229             stop.lane = attrs.getOptStringReporting(SUMO_ATTR_LANE, "stop", 0, ok, "");
00230             if (stop.lane!="") {
00231                 if (MSLane::dictionary(stop.lane)==0) {
00232                     MsgHandler::getErrorInstance()->inform("The lane '" + stop.lane + "' for a stop is not known.");
00233                     return;
00234                 }
00235             } else {
00236                 MsgHandler::getErrorInstance()->inform("A stop must be placed on a bus stop or a lane.");
00237                 return;
00238             }
00239             // get the position
00240             bool ok = true;
00241             stop.pos = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, "stop", 0, ok);
00242             if (!ok) {
00243                 return;
00244             }
00245         }
00246 
00247         // get the standing duration
00248         if (!attrs.hasAttribute(SUMO_ATTR_DURATION) && !attrs.hasAttribute(SUMO_ATTR_UNTIL)) {
00249             MsgHandler::getErrorInstance()->inform("The duration of a stop is not defined.");
00250             return;
00251         } else {
00252             bool ok = true;
00253             stop.duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, "stop", 0, ok, -1);
00254             stop.until = attrs.getOptSUMOTimeReporting(SUMO_ATTR_UNTIL, "stop", 0, ok, -1);
00255             if (!ok) {
00256                 return;
00257             }
00258             if (stop.duration<0&&stop.until<0) {
00259                 MsgHandler::getErrorInstance()->inform("Neither the duration nor the end time is given for a stop.");
00260                 return;
00261             }
00262         }
00263         if (myActiveRouteID != "") {
00264             myActiveRouteStops.push_back(stop);
00265         } else {
00266             myVehicleParameter->stops.push_back(stop);
00267         }
00268     }
00269 }
00270 
00271 
00272 void
00273 MSRouteHandler::openVehicleTypeDistribution(const SUMOSAXAttributes &attrs) {
00274     if (attrs.setIDFromAttributes("vtypeDistribution", myCurrentVTypeDistributionID)) {
00275         myCurrentVTypeDistribution = new RandomDistributor<MSVehicleType*>();
00276         if (attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
00277             bool ok = true;
00278             StringTokenizer st(attrs.getStringReporting(SUMO_ATTR_VTYPES, "vtypeDistribution", myCurrentVTypeDistributionID.c_str(), ok));
00279             while (st.hasNext()) {
00280                 std::string vtypeID = st.next();
00281                 MSVehicleType *type = MSNet::getInstance()->getVehicleControl().getVType(vtypeID);
00282                 if (type==0) {
00283                     throw ProcessError("Unknown vtype '" + vtypeID + "' in distribution '" + myCurrentVTypeDistributionID + "'.");
00284                 }
00285                 myCurrentVTypeDistribution->add(type->getDefaultProbability(), type);
00286             }
00287         }
00288     }
00289 }
00290 
00291 
00292 void
00293 MSRouteHandler::closeVehicleTypeDistribution() {
00294     if (myCurrentVTypeDistribution != 0) {
00295         if (myCurrentVTypeDistribution->getOverallProb() == 0) {
00296             delete myCurrentVTypeDistribution;
00297             MsgHandler::getErrorInstance()->inform("Vehicle type distribution '" + myCurrentVTypeDistributionID + "' is empty.");
00298         } else if (!MSNet::getInstance()->getVehicleControl().addVTypeDistribution(myCurrentVTypeDistributionID, myCurrentVTypeDistribution)) {
00299             delete myCurrentVTypeDistribution;
00300             MsgHandler::getErrorInstance()->inform("Another vehicle type (or distribution) with the id '" + myCurrentVTypeDistributionID + "' exists.");
00301         }
00302         myCurrentVTypeDistribution = 0;
00303     }
00304 }
00305 
00306 
00307 void
00308 MSRouteHandler::openRoute(const SUMOSAXAttributes &attrs) {
00309     // check whether the id is really necessary
00310     if (myVehicleParameter!=0) {
00311         // ok, a vehicle is wrapping the route,
00312         //  we may use this vehicle's id as default
00313         myActiveRouteID = "!" + myVehicleParameter->id; // !!! document this
00314     } else {
00315         bool ok = true;
00316         myActiveRouteID = attrs.getStringReporting(SUMO_ATTR_ID, "route", 0, ok, false);
00317         if (!ok) {
00318             return;
00319         }
00320     }
00321     bool ok = true;
00322     if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
00323         MSEdge::parseEdgesList(attrs.getStringReporting(SUMO_ATTR_EDGES, "route", myActiveRouteID.c_str(), ok), myActiveRoute, myActiveRouteID);
00324     }
00325     myActiveRouteProbability = attrs.getOptSUMORealReporting(SUMO_ATTR_PROB, "route", myActiveRouteID.c_str(), ok, DEFAULT_VEH_PROB);
00326     myActiveRouteColor = attrs.hasAttribute(SUMO_ATTR_COLOR) ? RGBColor::parseColorReporting(attrs.getString(SUMO_ATTR_COLOR), "route", myActiveRouteID.c_str(), true, ok) : RGBColor::getDefaultColor();
00327 }
00328 
00329 
00330 // ----------------------------------
00331 
00332 
00333 void
00334 MSRouteHandler::myCharacters(SumoXMLTag element,
00335                              const std::string &chars) throw(ProcessError) {
00336     switch (element) {
00337     case SUMO_TAG_ROUTE: {
00338         size_t len = chars.length();
00339         size_t beg = 0;
00340         while (beg<len&&chars[beg]<=32) {
00341             beg++;
00342         }
00343         if (beg<len) {
00344             if (!myHaveWarned) {
00345                 MsgHandler::getWarningInstance()->inform("Defining routes as a nested string is deprecated, use the edges attribute instead.");
00346                 myHaveWarned = true;
00347             }
00348             MSEdge::parseEdgesList(chars, myActiveRoute, myActiveRouteID);
00349         }
00350         break;
00351     }
00352     default:
00353         break;
00354     }
00355 }
00356 
00357 
00358 // ----------------------------------
00359 
00360 void
00361 MSRouteHandler::myEndElement(SumoXMLTag element) throw(ProcessError) {
00362     switch (element) {
00363     case SUMO_TAG_ROUTE:
00364         closeRoute();
00365         break;
00366     case SUMO_TAG_PERSON:
00367         closePerson();
00368         delete myVehicleParameter;
00369         myVehicleParameter = 0;
00370         break;
00371     case SUMO_TAG_VEHICLE:
00372         if (myVehicleParameter->repetitionNumber>0) {
00373             myVehicleParameter->repetitionNumber++; // for backwards compatibility
00374             // it is a flow, thus no break here
00375         } else {
00376             closeVehicle();
00377             delete myVehicleParameter;
00378             myVehicleParameter = 0;
00379             break;
00380         }
00381     case SUMO_TAG_FLOW:
00382         closeFlow();
00383         break;
00384     case SUMO_TAG_VTYPE_DISTRIBUTION:
00385         closeVehicleTypeDistribution();
00386         break;
00387     case SUMO_TAG_ROUTE_DISTRIBUTION:
00388         closeRouteDistribution();
00389         break;
00390     case SUMO_TAG_VTYPE: {
00391         SUMOVehicleParserHelper::closeVTypeParsing(*myCurrentVType);
00392         MSVehicleType *vehType = MSVehicleType::build(*myCurrentVType);
00393         delete myCurrentVType;
00394         myCurrentVType = 0;
00395         if (!MSNet::getInstance()->getVehicleControl().addVType(vehType)) {
00396             std::string id = vehType->getID();
00397             delete vehType;
00398 #ifdef HAVE_MESOSIM
00399             if (!MSGlobals::gStateLoaded) {
00400 #endif
00401                 throw ProcessError("Another vehicle type (or distribution) with the id '" + id + "' exists.");
00402 #ifdef HAVE_MESOSIM
00403             }
00404 #endif
00405         } else {
00406             if (myCurrentVTypeDistribution != 0) {
00407                 myCurrentVTypeDistribution->add(vehType->getDefaultProbability(), vehType);
00408             }
00409         }
00410     }
00411     break;
00412     default:
00413         break;
00414     }
00415 }
00416 
00417 
00418 void
00419 MSRouteHandler::closeRoute() throw(ProcessError) {
00420     if (myActiveRoute.size()==0) {
00421         if (myVehicleParameter!=0) {
00422             throw ProcessError("Vehicle's '" + myVehicleParameter->id + "' route has no edges.");
00423         } else {
00424             throw ProcessError("Route '" + myActiveRouteID + "' has no edges.");
00425         }
00426     }
00427     MSRoute *route = new MSRoute(myActiveRouteID, myActiveRoute,
00428                                  myVehicleParameter==0||myVehicleParameter->repetitionNumber>=1,
00429                                  myActiveRouteColor, myActiveRouteStops);
00430     myActiveRoute.clear();
00431     if (!MSRoute::dictionary(myActiveRouteID, route)) {
00432         delete route;
00433 #ifdef HAVE_MESOSIM
00434         if (!MSGlobals::gStateLoaded) {
00435 #endif
00436             if (myVehicleParameter!=0) {
00437                 if (MSNet::getInstance()->getVehicleControl().getVehicle(myVehicleParameter->id)==0) {
00438                     throw ProcessError("Another route for vehicle '" + myVehicleParameter->id + "' exists.");
00439                 } else {
00440                     throw ProcessError("A vehicle with id '" + myVehicleParameter->id + "' already exists.");
00441                 }
00442             } else {
00443                 throw ProcessError("Another route (or distribution) with the id '" + myActiveRouteID + "' exists.");
00444             }
00445 #ifdef HAVE_MESOSIM
00446         }
00447 #endif
00448     } else {
00449         if (myCurrentRouteDistribution != 0) {
00450             myCurrentRouteDistribution->add(myActiveRouteProbability, route);
00451         }
00452     }
00453     myActiveRouteID = "";
00454     myActiveRouteStops.clear();
00455 }
00456 
00457 
00458 void
00459 MSRouteHandler::openRouteDistribution(const SUMOSAXAttributes &attrs) {
00460     if (attrs.setIDFromAttributes("routeDistribution", myCurrentRouteDistributionID)) {
00461         myCurrentRouteDistribution = new RandomDistributor<const MSRoute*>();
00462         if (attrs.hasAttribute(SUMO_ATTR_ROUTES)) {
00463             bool ok = true;
00464             StringTokenizer st(attrs.getStringReporting(SUMO_ATTR_ROUTES, "routeDistribution", myCurrentRouteDistributionID.c_str(), ok));
00465             while (st.hasNext()) {
00466                 std::string routeID = st.next();
00467                 const MSRoute *route = MSRoute::dictionary(routeID);
00468                 if (route==0) {
00469                     throw ProcessError("Unknown route '" + routeID + "' in distribution '" + myCurrentRouteDistributionID + "'.");
00470                 }
00471                 myCurrentRouteDistribution->add(1., route, false);
00472             }
00473         }
00474     }
00475 }
00476 
00477 
00478 void
00479 MSRouteHandler::closeRouteDistribution() {
00480     if (myCurrentRouteDistribution != 0) {
00481         if (myCurrentRouteDistribution->getOverallProb() == 0) {
00482             delete myCurrentRouteDistribution;
00483             MsgHandler::getErrorInstance()->inform("Route distribution '" + myCurrentRouteDistributionID + "' is empty.");
00484         } else if (!MSRoute::dictionary(myCurrentRouteDistributionID, myCurrentRouteDistribution)) {
00485             delete myCurrentRouteDistribution;
00486             MsgHandler::getErrorInstance()->inform("Another route (or distribution) with the id '" + myCurrentRouteDistributionID + "' exists.");
00487         }
00488         myCurrentRouteDistribution = 0;
00489     }
00490 }
00491 
00492 
00493 void
00494 MSRouteHandler::closeVehicle() throw(ProcessError) {
00495     if (myVehicleParameter->departProcedure == DEPART_GIVEN) {
00496         myLastDepart = myVehicleParameter->depart;
00497         // let's check whether this vehicle had to be emitted before the simulation starts
00498         if (myVehicleParameter->depart<string2time(OptionsCont::getOptions().getString("begin"))) {
00499             return;
00500         }
00501     }
00502     // get the vehicle's type
00503     MSVehicleType *vtype = 0;
00504     if (myVehicleParameter->vtypeid!="") {
00505         vtype = MSNet::getInstance()->getVehicleControl().getVType(myVehicleParameter->vtypeid);
00506         if (vtype==0) {
00507             throw ProcessError("The vehicle type '" + myVehicleParameter->vtypeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
00508         }
00509     } else {
00510         // there should be one (at least the default one)
00511         vtype = MSNet::getInstance()->getVehicleControl().getVType();
00512     }
00513     // get the vehicle's route
00514     //  maybe it was explicitely assigned to the vehicle
00515     const MSRoute *route = MSRoute::dictionary("!" + myVehicleParameter->id);
00516     if (route==0) {
00517         // if not, try via the (hopefully) given route-id
00518         route = MSRoute::dictionary(myVehicleParameter->routeid);
00519     }
00520     if (route==0) {
00521         // nothing found? -> error
00522         if (myVehicleParameter->routeid!="") {
00523             throw ProcessError("The route '" + myVehicleParameter->routeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
00524         } else {
00525             throw ProcessError("Vehicle '" + myVehicleParameter->id + "' has no route.");
00526         }
00527     }
00528     myActiveRouteID = "";
00529 
00530     // try to build the vehicle
00531     MSVehicle *vehicle = 0;
00532     if (MSNet::getInstance()->getVehicleControl().getVehicle(myVehicleParameter->id)==0) {
00533         // ok there was no other vehicle with the same id, yet
00534         // maybe we do not want this vehicle to be emitted due to using incremental dua
00535         bool add = true;
00536         if (myAmUsingIncrementalDUA) {
00537             if ((int)(myRunningVehicleNumber%myIncrementalBase)>=(int) myIncrementalStage) {
00538                 add = false;
00539             }
00540             myRunningVehicleNumber++;
00541         }
00542         if (add) {
00543             vehicle = MSNet::getInstance()->getVehicleControl().buildVehicle(myVehicleParameter, route, vtype);
00544             // add the vehicle to the vehicle control
00545             MSNet::getInstance()->getVehicleControl().addVehicle(myVehicleParameter->id, vehicle);
00546             if (myVehicleParameter->departProcedure == DEPART_TRIGGERED) {
00547                 MSNet::getInstance()->getVehicleControl().addWaiting(*route->begin(), vehicle);
00548             }
00549             myVehicleParameter = 0;
00550         }
00551     } else {
00552         // strange: another vehicle with the same id already exists
00553 #ifdef HAVE_MESOSIM
00554         if (!MSGlobals::gStateLoaded) {
00555 #endif
00556             // and was not loaded while loading a simulation state
00557             // -> error
00558             throw ProcessError("Another vehicle with the id '" + myVehicleParameter->id + "' exists.");
00559 #ifdef HAVE_MESOSIM
00560         } else {
00561             // ok, it seems to be loaded previously while loading a simulation state
00562             vehicle = 0;
00563         }
00564 #endif
00565     }
00566     // check whether the vehicle shall be added directly to the network or
00567     //  shall stay in the internal buffer
00568     if (myAddVehiclesDirectly&&vehicle!=0) {
00569         if (vehicle->getParameter().departProcedure == DEPART_GIVEN) {
00570             MSNet::getInstance()->getEmitControl().add(vehicle);
00571         }
00572     } else {
00573         myLastReadVehicle = vehicle;
00574     }
00575 }
00576 
00577 
00578 void
00579 MSRouteHandler::closePerson() throw(ProcessError) {
00580     MSPerson *person = new MSPerson(myVehicleParameter, myActivePlan);
00581     if (MSNet::getInstance()->getPersonControl().add(myVehicleParameter->id, person)) {
00582         MSNet::getInstance()->getPersonControl().setArrival(myVehicleParameter->depart, person);
00583     }
00584     myVehicleParameter = 0;
00585     myActivePlan = 0;
00586 }
00587 
00588 
00589 void
00590 MSRouteHandler::closeFlow() throw(ProcessError) {
00591     // let's check whether vehicles had to be emitted before the simulation starts
00592     myVehicleParameter->repetitionsDone = 0;
00593     SUMOReal offsetToBegin = string2time(OptionsCont::getOptions().getString("begin")) - myVehicleParameter->depart;
00594     while (myVehicleParameter->repetitionsDone * myVehicleParameter->repetitionOffset < offsetToBegin) {
00595         myVehicleParameter->repetitionsDone++;
00596         if (myVehicleParameter->repetitionsDone == myVehicleParameter->repetitionNumber) {
00597             return;
00598         }
00599     }
00600     if (MSNet::getInstance()->getVehicleControl().getVType(myVehicleParameter->vtypeid)==0) {
00601         throw ProcessError("The vehicle type '" + myVehicleParameter->vtypeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
00602     }
00603     if (MSRoute::dictionary("!" + myVehicleParameter->id)==0) {
00604         // if not, try via the (hopefully) given route-id
00605         if (MSRoute::dictionary(myVehicleParameter->routeid) == 0) {
00606             if (myVehicleParameter->routeid!="") {
00607                 throw ProcessError("The route '" + myVehicleParameter->routeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
00608             } else {
00609                 throw ProcessError("Vehicle '" + myVehicleParameter->id + "' has no route.");
00610             }
00611         }
00612     } else {
00613         myVehicleParameter->routeid = "!" + myVehicleParameter->id;
00614     }
00615     myActiveRouteID = "";
00616 
00617     // check whether the vehicle shall be added directly to the network or
00618     //  shall stay in the internal buffer
00619     if (myAddVehiclesDirectly) {
00620         MSNet::getInstance()->getEmitControl().add(myVehicleParameter);
00621         myVehicleParameter = 0;
00622     }
00623 }
00624 
00625 
00626 
00627 /****************************************************************************/

Generated on Wed May 5 00:06:32 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6