SUMO - Simulation of Urban MObility

RONet.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // The router's network representation
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright (C) 2001-2011 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 <iostream>
00032 #include <fstream>
00033 #include <deque>
00034 #include <queue>
00035 #include "ROEdge.h"
00036 #include "RONode.h"
00037 #include "RONet.h"
00038 #include "RORoute.h"
00039 #include "RORouteDef.h"
00040 #include "ROVehicle.h"
00041 #include <utils/common/SUMOVTypeParameter.h>
00042 #include <utils/common/SUMOAbstractRouter.h>
00043 #include <utils/options/OptionsCont.h>
00044 #include <utils/common/UtilExceptions.h>
00045 #include <utils/common/MsgHandler.h>
00046 #include <utils/common/ToString.h>
00047 #include <utils/common/RandHelper.h>
00048 #include <utils/common/SUMOVehicleClass.h>
00049 #include <utils/iodevices/OutputDevice.h>
00050 
00051 #ifdef CHECK_MEMORY_LEAKS
00052 #include <foreign/nvwa/debug_new.h>
00053 #endif // CHECK_MEMORY_LEAKS
00054 
00055 
00056 // ===========================================================================
00057 // method definitions
00058 // ===========================================================================
00059 RONet::RONet() throw()
00060     : myVehicleTypes(),
00061       myRoutesOutput(0), myRouteAlternativesOutput(0),
00062       myReadRouteNo(0), myDiscardedRouteNo(0), myWrittenRouteNo(0),
00063       myHaveRestrictions(false) {}
00064 
00065 
00066 RONet::~RONet() throw() {
00067     myNodes.clear();
00068     myEdges.clear();
00069     myVehicleTypes.clear();
00070     myRoutes.clear();
00071     myVehicles.clear();
00072 }
00073 
00074 
00075 bool
00076 RONet::addEdge(ROEdge* edge) throw() {
00077     if (!myEdges.add(edge->getID(), edge)) {
00078         WRITE_ERROR("The edge '" + edge->getID() + "' occurs at least twice.");
00079         delete edge;
00080         return false;
00081     }
00082     return true;
00083 }
00084 
00085 
00086 void
00087 RONet::addNode(RONode* node) throw() {
00088     if (!myNodes.add(node->getID(), node)) {
00089         WRITE_ERROR("The node '" + node->getID() + "' occurs at least twice.");
00090         delete node;
00091     }
00092 }
00093 
00094 
00095 bool
00096 RONet::addRouteDef(RORouteDef* def) throw() {
00097     return myRoutes.add(def->getID(), def);
00098 }
00099 
00100 
00101 void
00102 RONet::openOutput(const std::string& filename, bool useAlternatives) throw(IOError) {
00103     myRoutesOutput = &OutputDevice::getDevice(filename);
00104     myRoutesOutput->writeXMLHeader("routes", "", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/routes_file.xsd\"");
00105     if (useAlternatives) {
00106         size_t len = filename.length();
00107         if (len > 4 && filename.substr(len - 4) == ".xml") {
00108             myRouteAlternativesOutput = &OutputDevice::getDevice(filename.substr(0, len-4)+".alt.xml");
00109         } else {
00110             myRouteAlternativesOutput = &OutputDevice::getDevice(filename+".alt");
00111         }
00112         myRouteAlternativesOutput->writeXMLHeader("route-alternatives", "", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/routes_file.xsd\"");
00113     }
00114 }
00115 
00116 
00117 void
00118 RONet::closeOutput() throw() {
00119     // end writing
00120     if (myRoutesOutput!= 0) {
00121         myRoutesOutput->close();
00122     }
00123     // only if opened
00124     if (myRouteAlternativesOutput!=0) {
00125         myRouteAlternativesOutput->close();
00126     }
00127 }
00128 
00129 
00130 
00131 SUMOVTypeParameter*
00132 RONet::getVehicleTypeSecure(const std::string& id) throw() {
00133     // check whether the type was already known
00134     SUMOVTypeParameter* type = myVehicleTypes.get(id);
00135     if (type!=0) {
00136         return type;
00137     }
00138     if (id=="") {
00139         // ok, no vehicle type was given within the user input
00140         //  return the default type
00141         return 0;
00142     }
00143     // Assume, the user will define the type somewhere else
00144     //  return a type which contains the id only
00145     type = new SUMOVTypeParameter();
00146     type->id = id;
00147     type->onlyReferenced = true;
00148     addVehicleType(type);
00149     return type;
00150 }
00151 
00152 
00153 bool
00154 RONet::addVehicleType(SUMOVTypeParameter* type) throw() {
00155     if (!myVehicleTypes.add(type->id, type)) {
00156         WRITE_ERROR("The vehicle type '" + type->id + "' occurs at least twice.");
00157         delete type;
00158         return false;
00159     }
00160     return true;
00161 }
00162 
00163 
00164 bool
00165 RONet::addVehicle(const std::string& id, ROVehicle* veh) throw() {
00166     if (myVehIDs.find(id)==myVehIDs.end()&&myVehicles.add(id, veh)) {
00167         myVehIDs.insert(id);
00168         myReadRouteNo++;
00169         return true;
00170     }
00171     WRITE_ERROR("The vehicle '" + id + "' occurs at least twice.");
00172     return false;
00173 }
00174 
00175 
00176 bool
00177 RONet::computeRoute(OptionsCont& options, SUMOAbstractRouter<ROEdge,ROVehicle> &router,
00178                     const ROVehicle* const veh) {
00179     MsgHandler* mh = MsgHandler::getErrorInstance();
00180     std::string noRouteMsg = "The vehicle '" + veh->getID() + "' has no valid route.";
00181     if (options.getBool("ignore-errors")) {
00182         mh = MsgHandler::getWarningInstance();
00183     }
00184     RORouteDef* const routeDef = veh->getRouteDefinition();
00185     // check if the route definition is valid
00186     if (routeDef==0) {
00187         mh->inform(noRouteMsg);
00188         return false;
00189     }
00190     // check whether the route was already saved
00191     if (routeDef->isSaved()) {
00192         return true;
00193     }
00194     //
00195     RORoute* current = routeDef->buildCurrentRoute(router, veh->getDepartureTime(), *veh);
00196     if (current==0||current->size()==0) {
00197         delete current;
00198         mh->inform(noRouteMsg);
00199         return false;
00200     }
00201     // check whether we have to evaluate the route for not containing loops
00202     if (options.getBool("remove-loops")) {
00203         current->recheckForLoops();
00204     }
00205     // check whether the route is still valid
00206     if (current->size()==0) {
00207         delete current;
00208         mh->inform(noRouteMsg + " (after removing loops)");
00209         return false;
00210     }
00211     // add built route
00212     routeDef->addAlternative(router, veh, current, veh->getDepartureTime());
00213     return true;
00214 }
00215 
00216 
00217 SUMOTime
00218 RONet::saveAndRemoveRoutesUntil(OptionsCont& options, SUMOAbstractRouter<ROEdge,ROVehicle> &router,
00219                                 SUMOTime time) {
00220     SUMOTime lastTime = -1;
00221     // write all vehicles (and additional structures)
00222     while (myVehicles.size()!=0) {
00223         // get the next vehicle
00224         const ROVehicle* const veh = myVehicles.getTopVehicle();
00225         SUMOTime currentTime = veh->getDepartureTime();
00226         // check whether it shall not yet be computed
00227         if (currentTime>time) {
00228             lastTime = currentTime;
00229             break;
00230         }
00231         // check whether to print the output
00232         if (lastTime!=currentTime&&lastTime!=-1) {
00233             // report writing progress
00234             if (options.getInt("stats-period")>=0 && ((int) currentTime%options.getInt("stats-period"))==0) {
00235                 WRITE_MESSAGE("Read: " + toString(myReadRouteNo) + ",  Discarded: " + toString(myDiscardedRouteNo) + ",  Written: " + toString(myWrittenRouteNo));
00236             }
00237         }
00238         lastTime = currentTime;
00239 
00240         // ok, compute the route (try it)
00241         if (computeRoute(options, router, veh)) {
00242             // write the route
00243             veh->saveAllAsXML(router, *myRoutesOutput, myRouteAlternativesOutput, options.getBool("exit-times"));
00244             myWrittenRouteNo++;
00245             // remove the route if it is not longer used
00246             /*
00247             if (!myRoutes.erase(route->getID())) {
00248                 WRITE_WARNING("Could not remove " + route->getID());
00249             }
00250             */
00251         } else {
00252             myDiscardedRouteNo++;
00253         }
00254         // and the vehicle
00255         myVehicles.erase(veh->getID());
00256     }
00257     return lastTime;
00258 }
00259 
00260 
00261 bool
00262 RONet::furtherStored() {
00263     return myVehicles.size()>0;
00264 }
00265 
00266 
00267 ROEdge*
00268 RONet::getRandomSource() throw() {
00269     // check whether an edge may be returned
00270     checkSourceAndDestinations();
00271     if (mySourceEdges.size()==0) {
00272         return 0;
00273     }
00274     // choose a random edge
00275     return RandHelper::getRandomFrom(mySourceEdges);
00276 }
00277 
00278 
00279 const ROEdge*
00280 RONet::getRandomSource() const throw() {
00281     // check whether an edge may be returned
00282     checkSourceAndDestinations();
00283     if (mySourceEdges.size()==0) {
00284         return 0;
00285     }
00286     // choose a random edge
00287     return RandHelper::getRandomFrom(mySourceEdges);
00288 }
00289 
00290 
00291 
00292 ROEdge*
00293 RONet::getRandomDestination() throw() {
00294     // check whether an edge may be returned
00295     checkSourceAndDestinations();
00296     if (myDestinationEdges.size()==0) {
00297         return 0;
00298     }
00299     // choose a random edge
00300     return RandHelper::getRandomFrom(myDestinationEdges);
00301 }
00302 
00303 
00304 const ROEdge*
00305 RONet::getRandomDestination() const throw() {
00306     // check whether an edge may be returned
00307     checkSourceAndDestinations();
00308     if (myDestinationEdges.size()==0) {
00309         return 0;
00310     }
00311     // choose a random edge
00312     return RandHelper::getRandomFrom(myDestinationEdges);
00313 }
00314 
00315 
00316 void
00317 RONet::checkSourceAndDestinations() const {
00318     if (myDestinationEdges.size()!=0||mySourceEdges.size()!=0) {
00319         return;
00320     }
00321     const std::map<std::string, ROEdge*> &edges = myEdges.getMyMap();
00322     for (std::map<std::string, ROEdge*>::const_iterator i=edges.begin(); i!=edges.end(); ++i) {
00323         ROEdge* e = (*i).second;
00324         ROEdge::EdgeType type = e->getType();
00325         // !!! add something like "classified edges only" for using only sources or sinks
00326         if (type!=ROEdge::ET_SOURCE) {
00327             myDestinationEdges.push_back(e);
00328         }
00329         if (type!=ROEdge::ET_SINK) {
00330             mySourceEdges.push_back(e);
00331         }
00332     }
00333 }
00334 
00335 
00336 unsigned int
00337 RONet::getEdgeNo() const {
00338     return (unsigned int) myEdges.size();
00339 }
00340 
00341 
00342 const std::map<std::string, ROEdge*> &
00343 RONet::getEdgeMap() const {
00344     return myEdges.getMyMap();
00345 }
00346 
00347 
00348 bool
00349 RONet::hasRestrictions() const {
00350     return myHaveRestrictions;
00351 }
00352 
00353 
00354 void
00355 RONet::setRestrictionFound() {
00356     myHaveRestrictions = true;
00357 }
00358 
00359 
00360 
00361 /****************************************************************************/
00362 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines