SUMO - Simulation of Urban MObility

RONet.cpp

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