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