SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00012 // Instance responsible for building networks 00013 /****************************************************************************/ 00014 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00015 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors 00016 /****************************************************************************/ 00017 // 00018 // This file is part of SUMO. 00019 // SUMO is free software: you can redistribute it and/or modify 00020 // it under the terms of the GNU General Public License as published by 00021 // the Free Software Foundation, either version 3 of the License, or 00022 // (at your option) any later version. 00023 // 00024 /****************************************************************************/ 00025 00026 00027 // =========================================================================== 00028 // included modules 00029 // =========================================================================== 00030 #ifdef _MSC_VER 00031 #include <windows_config.h> 00032 #else 00033 #include <config.h> 00034 #endif 00035 00036 #include <string> 00037 #include <fstream> 00038 #include "NBNetBuilder.h" 00039 #include "NBNodeCont.h" 00040 #include "NBEdgeCont.h" 00041 #include "NBTrafficLightLogicCont.h" 00042 #include "NBDistrictCont.h" 00043 #include "NBDistrict.h" 00044 #include "NBDistribution.h" 00045 #include "NBRequest.h" 00046 #include "NBTypeCont.h" 00047 #include <utils/options/OptionsCont.h> 00048 #include <utils/common/MsgHandler.h> 00049 #include <utils/common/UtilExceptions.h> 00050 #include <utils/common/StringTokenizer.h> 00051 #include <utils/common/ToString.h> 00052 #include <utils/geom/GeoConvHelper.h> 00053 00054 #include "NBAlgorithms.h" 00055 00056 #ifdef CHECK_MEMORY_LEAKS 00057 #include <foreign/nvwa/debug_new.h> 00058 #endif // CHECK_MEMORY_LEAKS 00059 00060 00061 // =========================================================================== 00062 // method definitions 00063 // =========================================================================== 00064 NBNetBuilder::NBNetBuilder() 00065 : myEdgeCont(myTypeCont) {} 00066 00067 00068 NBNetBuilder::~NBNetBuilder() {} 00069 00070 00071 void 00072 NBNetBuilder::applyOptions(OptionsCont& oc) { 00073 // we possibly have to load the edges to keep 00074 if (oc.isSet("keep-edges.input-file")) { 00075 std::ifstream strm(oc.getString("keep-edges.input-file").c_str()); 00076 if (!strm.good()) { 00077 throw ProcessError("Could not load names of edges too keep from '" + oc.getString("keep-edges.input-file") + "'."); 00078 } 00079 std::ostringstream oss; 00080 bool first = true; 00081 while (strm.good()) { 00082 if (!first) { 00083 oss << ','; 00084 } 00085 std::string name; 00086 strm >> name; 00087 oss << name; 00088 first = false; 00089 } 00090 oc.set("keep-edges.explicit", oss.str()); 00091 } 00092 // apply options to type control 00093 myTypeCont.setDefaults(oc.getInt("default.lanenumber"), oc.getFloat("default.speed"), oc.getInt("default.priority")); 00094 // apply options to edge control 00095 myEdgeCont.applyOptions(oc); 00096 // apply options to traffic light logics control 00097 myTLLCont.applyOptions(oc); 00098 } 00099 00100 00101 void 00102 NBNetBuilder::compute(OptionsCont& oc, 00103 const std::set<std::string> &explicitTurnarounds, 00104 bool removeUnwishedNodes) { 00105 GeoConvHelper& geoConvHelper = GeoConvHelper::getProcessing(); 00106 00107 00108 // MODIFYING THE SETS OF NODES AND EDGES 00109 // join junctions 00110 00111 if (oc.exists("junctions.join-exclude") && oc.isSet("junctions.join-exclude")) { 00112 myNodeCont.addJoinExclusion(oc.getStringVector("junctions.join-exclude")); 00113 } 00114 unsigned int numJoined = myNodeCont.joinLoadedClusters(myDistrictCont, myEdgeCont, myTLLCont); 00115 if (oc.getBool("junctions.join")) { 00116 PROGRESS_BEGIN_MESSAGE("Joining junction clusters"); 00117 numJoined += myNodeCont.joinJunctions(oc.getFloat("junctions.join-dist"), myDistrictCont, myEdgeCont, myTLLCont); 00118 PROGRESS_DONE_MESSAGE(); 00119 } 00120 if (numJoined > 0) { 00121 // bit of a misnomer since we're already done 00122 WRITE_MESSAGE(" Joined " + toString(numJoined) + " junction cluster(s)."); 00123 } 00124 00125 // Removes edges that are connecting the same node 00126 PROGRESS_BEGIN_MESSAGE("Removing self-loops"); 00127 myNodeCont.removeSelfLoops(myDistrictCont, myEdgeCont, myTLLCont); 00128 PROGRESS_DONE_MESSAGE(); 00129 // 00130 if (oc.exists("remove-edges.isolated") && oc.getBool("remove-edges.isolated")) { 00131 PROGRESS_BEGIN_MESSAGE("Finding isolated roads"); 00132 myNodeCont.removeIsolatedRoads(myDistrictCont, myEdgeCont, myTLLCont); 00133 PROGRESS_DONE_MESSAGE(); 00134 } 00135 // 00136 if (oc.exists("keep-edges.postload") && oc.getBool("keep-edges.postload")) { 00137 if (oc.isSet("keep-edges.explicit")) { 00138 PROGRESS_BEGIN_MESSAGE("Removing unwished edges"); 00139 myEdgeCont.removeUnwishedEdges(myDistrictCont); 00140 PROGRESS_DONE_MESSAGE(); 00141 } 00142 } 00143 // 00144 if (removeUnwishedNodes) { 00145 unsigned int no = 0; 00146 const bool removeGeometryNodes = oc.exists("geometry.remove") && oc.getBool("geometry.remove"); 00147 PROGRESS_BEGIN_MESSAGE("Removing empty nodes" + std::string(removeGeometryNodes ? " and geometry nodes" : "")); 00148 no = myNodeCont.removeUnwishedNodes(myDistrictCont, myEdgeCont, myJoinedEdges, myTLLCont, removeGeometryNodes); 00149 PROGRESS_DONE_MESSAGE(); 00150 WRITE_MESSAGE(" " + toString(no) + " nodes removed."); 00151 } 00152 // @note: removing geometry can create similar edges so "Joining" must come afterwards 00153 // @note: likewise splitting can destroy similarities so "Joining" must come before 00154 PROGRESS_BEGIN_MESSAGE("Joining similar edges"); 00155 myJoinedEdges.init(myEdgeCont); 00156 myNodeCont.joinSimilarEdges(myDistrictCont, myEdgeCont, myTLLCont); 00157 PROGRESS_DONE_MESSAGE(); 00158 // 00159 if (oc.exists("geometry.split") && oc.getBool("geometry.split")) { 00160 PROGRESS_BEGIN_MESSAGE("Splitting geometry edges"); 00161 myEdgeCont.splitGeometry(myNodeCont); 00162 PROGRESS_DONE_MESSAGE(); 00163 } 00164 // guess ramps 00165 if ((oc.exists("ramps.guess") && oc.getBool("ramps.guess")) || (oc.exists("ramps.set") && oc.isSet("ramps.set"))) { 00166 PROGRESS_BEGIN_MESSAGE("Guessing and setting on-/off-ramps"); 00167 myNodeCont.guessRamps(oc, myEdgeCont, myDistrictCont); 00168 PROGRESS_DONE_MESSAGE(); 00169 } 00170 00171 00172 // MOVE TO ORIGIN 00173 if (!oc.getBool("offset.disable-normalization") && oc.isDefault("offset.x") && oc.isDefault("offset.y")) { 00174 PROGRESS_BEGIN_MESSAGE("Moving network to origin"); 00175 const SUMOReal x = -geoConvHelper.getConvBoundary().xmin(); 00176 const SUMOReal y = -geoConvHelper.getConvBoundary().ymin(); 00177 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) { 00178 (*i).second->reshiftPosition(x, y); 00179 } 00180 for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) { 00181 (*i).second->reshiftPosition(x, y); 00182 } 00183 for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) { 00184 (*i).second->reshiftPosition(x, y); 00185 } 00186 geoConvHelper.moveConvertedBy(x, y); 00187 PROGRESS_DONE_MESSAGE(); 00188 } 00189 geoConvHelper.computeFinal(); // information needed for location element fixed at this point 00190 00191 // @todo Why? 00192 myEdgeCont.recomputeLaneShapes(); 00193 00194 // APPLY SPEED MODIFICATIONS 00195 if (oc.exists("speed.offset")) { 00196 const SUMOReal speedOffset = oc.getFloat("speed.offset"); 00197 const SUMOReal speedFactor = oc.getFloat("speed.factor"); 00198 if (speedOffset != 0 || speedFactor != 1) { 00199 PROGRESS_BEGIN_MESSAGE("Applying speed modifications"); 00200 for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) { 00201 (*i).second->setSpeed(-1, (*i).second->getSpeed() * speedFactor + speedOffset); 00202 } 00203 PROGRESS_DONE_MESSAGE(); 00204 } 00205 } 00206 00207 // GUESS TLS POSITIONS 00208 PROGRESS_BEGIN_MESSAGE("Assigning nodes to traffic lights"); 00209 if (oc.isSet("tls.set")) { 00210 std::vector<std::string> tlControlledNodes = oc.getStringVector("tls.set"); 00211 for (std::vector<std::string>::const_iterator i = tlControlledNodes.begin(); i != tlControlledNodes.end(); ++i) { 00212 NBNode* node = myNodeCont.retrieve(*i); 00213 if (node == 0) { 00214 WRITE_WARNING("Building a tl-logic for node '" + *i + "' is not possible." + "\n The node '" + *i + "' is not known."); 00215 } else { 00216 myNodeCont.setAsTLControlled(node, myTLLCont); 00217 } 00218 } 00219 } 00220 myNodeCont.guessTLs(oc, myTLLCont); 00221 PROGRESS_DONE_MESSAGE(); 00222 // 00223 if (oc.getBool("tls.join")) { 00224 PROGRESS_BEGIN_MESSAGE("Joining traffic light nodes"); 00225 myNodeCont.joinTLS(myTLLCont); 00226 PROGRESS_DONE_MESSAGE(); 00227 } 00228 00229 00230 // CONNECTIONS COMPUTATION 00231 // 00232 PROGRESS_BEGIN_MESSAGE("Computing turning directions"); 00233 NBTurningDirectionsComputer::computeTurnDirections(myNodeCont); 00234 PROGRESS_DONE_MESSAGE(); 00235 // 00236 PROGRESS_BEGIN_MESSAGE("Sorting nodes' edges"); 00237 NBNodesEdgesSorter::sortNodesEdges(myNodeCont, oc.getBool("lefthand")); 00238 PROGRESS_DONE_MESSAGE(); 00239 // 00240 PROGRESS_BEGIN_MESSAGE("Computing node types"); 00241 NBNodeTypeComputer::computeNodeTypes(myNodeCont); 00242 PROGRESS_DONE_MESSAGE(); 00243 // 00244 PROGRESS_BEGIN_MESSAGE("Computing priorities"); 00245 NBEdgePriorityComputer::computeEdgePriorities(myNodeCont); 00246 PROGRESS_DONE_MESSAGE(); 00247 // 00248 if (oc.getBool("roundabouts.guess")) { 00249 PROGRESS_BEGIN_MESSAGE("Guessing and setting roundabouts"); 00250 myEdgeCont.guessRoundabouts(myRoundabouts); 00251 PROGRESS_DONE_MESSAGE(); 00252 } 00253 // 00254 PROGRESS_BEGIN_MESSAGE("Computing approached edges"); 00255 myEdgeCont.computeEdge2Edges(oc.getBool("no-left-connections")); 00256 PROGRESS_DONE_MESSAGE(); 00257 // 00258 PROGRESS_BEGIN_MESSAGE("Computing approaching lanes"); 00259 myEdgeCont.computeLanes2Edges(); 00260 PROGRESS_DONE_MESSAGE(); 00261 // 00262 PROGRESS_BEGIN_MESSAGE("Dividing of lanes on approached lanes"); 00263 myNodeCont.computeLanes2Lanes(); 00264 myEdgeCont.sortOutgoingLanesConnections(); 00265 PROGRESS_DONE_MESSAGE(); 00266 // 00267 PROGRESS_BEGIN_MESSAGE("Processing turnarounds"); 00268 if (!oc.getBool("no-turnarounds")) { 00269 myEdgeCont.appendTurnarounds(oc.getBool("no-turnarounds.tls")); 00270 } else { 00271 myEdgeCont.appendTurnarounds(explicitTurnarounds, oc.getBool("no-turnarounds.tls")); 00272 } 00273 PROGRESS_DONE_MESSAGE(); 00274 // 00275 PROGRESS_BEGIN_MESSAGE("Rechecking of lane endings"); 00276 myEdgeCont.recheckLanes(); 00277 PROGRESS_DONE_MESSAGE(); 00278 00279 00280 // GEOMETRY COMPUTATION 00281 // 00282 PROGRESS_BEGIN_MESSAGE("Computing node shapes"); 00283 myNodeCont.computeNodeShapes(oc.getBool("lefthand")); 00284 PROGRESS_DONE_MESSAGE(); 00285 // 00286 PROGRESS_BEGIN_MESSAGE("Computing edge shapes"); 00287 myEdgeCont.computeEdgeShapes(); 00288 PROGRESS_DONE_MESSAGE(); 00289 00290 00291 // COMPUTING RIGHT-OF-WAY AND TRAFFIC LIGHT PROGRAMS 00292 // 00293 PROGRESS_BEGIN_MESSAGE("Computing traffic light control information"); 00294 myTLLCont.setTLControllingInformation(myEdgeCont); 00295 PROGRESS_DONE_MESSAGE(); 00296 // 00297 PROGRESS_BEGIN_MESSAGE("Computing node logics"); 00298 myNodeCont.computeLogics(myEdgeCont, oc); 00299 PROGRESS_DONE_MESSAGE(); 00300 // 00301 PROGRESS_BEGIN_MESSAGE("Computing traffic light logics"); 00302 std::pair<unsigned int, unsigned int> numbers = myTLLCont.computeLogics(myEdgeCont, oc); 00303 PROGRESS_DONE_MESSAGE(); 00304 std::string progCount = ""; 00305 if (numbers.first != numbers.second) { 00306 progCount = "(" + toString(numbers.second) + " programs) "; 00307 } 00308 WRITE_MESSAGE(" " + toString(numbers.first) + " traffic light(s) " + progCount + "computed."); 00309 00310 00311 // FINISHING INNER EDGES 00312 if (!oc.getBool("no-internal-links")) { 00313 PROGRESS_BEGIN_MESSAGE("Building inner edges"); 00314 for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) { 00315 (*i).second->sortOutgoingConnectionsByIndex(); 00316 } 00317 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) { 00318 (*i).second->buildInnerEdges(); 00319 } 00320 PROGRESS_DONE_MESSAGE(); 00321 } 00322 00323 00324 // report 00325 WRITE_MESSAGE("-----------------------------------------------------"); 00326 WRITE_MESSAGE("Summary:"); 00327 myNodeCont.printBuiltNodesStatistics(); 00328 WRITE_MESSAGE(" Network boundaries:"); 00329 WRITE_MESSAGE(" Original boundary : " + toString(geoConvHelper.getOrigBoundary())); 00330 WRITE_MESSAGE(" Applied offset : " + toString(geoConvHelper.getOffsetBase())); 00331 WRITE_MESSAGE(" Converted boundary : " + toString(geoConvHelper.getConvBoundary())); 00332 WRITE_MESSAGE("-----------------------------------------------------"); 00333 NBRequest::reportWarnings(); 00334 } 00335 00336 00337 /****************************************************************************/