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

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