|
SUMO - Simulation of Urban MObility
|
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