SUMO - Simulation of Urban MObility

NBNetBuilder.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Instance responsible for building networks
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright (C) 2001-2011 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 <fstream>
00032 #include "NBNetBuilder.h"
00033 #include "NBNodeCont.h"
00034 #include "NBEdgeCont.h"
00035 #include "NBTrafficLightLogicCont.h"
00036 #include "NBDistrictCont.h"
00037 #include "NBDistrict.h"
00038 #include "NBDistribution.h"
00039 #include "NBRequest.h"
00040 #include "NBTypeCont.h"
00041 #include <utils/options/OptionsCont.h>
00042 #include <utils/common/MsgHandler.h>
00043 #include <utils/common/UtilExceptions.h>
00044 #include <utils/common/StringTokenizer.h>
00045 #include <utils/common/ToString.h>
00046 #include <utils/geom/GeoConvHelper.h>
00047 
00048 #ifdef CHECK_MEMORY_LEAKS
00049 #include <foreign/nvwa/debug_new.h>
00050 #endif // CHECK_MEMORY_LEAKS
00051 
00052 
00053 // ===========================================================================
00054 // method definitions
00055 // ===========================================================================
00056 NBNetBuilder::NBNetBuilder() throw()
00057     : myEdgeCont(myTypeCont) {}
00058 
00059 
00060 NBNetBuilder::~NBNetBuilder() throw() {}
00061 
00062 
00063 void
00064 NBNetBuilder::applyOptions(OptionsCont& oc) throw(ProcessError) {
00065     // we possibly have to load the edges to keep
00066     if (oc.isSet("keep-edges.input-file")) {
00067         std::ifstream strm(oc.getString("keep-edges.input-file").c_str());
00068         if (!strm.good()) {
00069             throw ProcessError("Could not load names of edges too keep from '" + oc.getString("keep-edges.input-file") + "'.");
00070         }
00071         std::ostringstream oss;
00072         bool first = true;
00073         while (strm.good()) {
00074             if (!first) {
00075                 oss << ',';
00076             }
00077             std::string name;
00078             strm >> name;
00079             oss << name;
00080             first = false;
00081         }
00082         oc.set("keep-edges.explicit", oss.str());
00083     }
00084     // apply options to type control
00085     myTypeCont.setDefaults(oc.getInt("default.lanenumber"), oc.getFloat("default.speed"), oc.getInt("default.priority"));
00086     // apply options to edge control
00087     myEdgeCont.applyOptions(oc);
00088     // apply options to traffic light logics control
00089     myTLLCont.applyOptions(oc);
00090 }
00091 
00092 
00093 void
00094 NBNetBuilder::compute(OptionsCont& oc,
00095                       const std::set<std::string> &explicitTurnarounds,
00096                       bool removeUnwishedNodes) {
00097     GeoConvHelper& geoConvHelper = GeoConvHelper::getDefaultInstance();
00098     // join junctions
00099     if (oc.exists("junctions.join-exclude") && oc.isSet("junctions.join-exclude")) {
00100         myNodeCont.addJoinExclusion(oc.getStringVector("junctions.join-exclude"));
00101     }
00102     unsigned int numJoined = myNodeCont.joinLoadedClusters(myDistrictCont, myEdgeCont, myTLLCont);
00103     if (oc.getBool("junctions.join")) {
00104         PROGRESS_BEGIN_MESSAGE("Joining junction clusters");
00105         numJoined += myNodeCont.joinJunctions(oc.getFloat("junctions.join-dist"), myDistrictCont, myEdgeCont, myTLLCont);
00106         PROGRESS_DONE_MESSAGE();
00107     }
00108     if (numJoined > 0) {
00109         // bit of a misnomer since we're already done
00110         WRITE_MESSAGE(" Joined " + toString(numJoined) + " junction cluster(s).");
00111     }
00112 
00113 
00114     // ADAPTING THE INPUT
00115     // Removes edges that are connecting the same node
00116     PROGRESS_BEGIN_MESSAGE("Removing dummy edges");
00117     myNodeCont.removeDummyEdges(myDistrictCont, myEdgeCont, myTLLCont);
00118     PROGRESS_DONE_MESSAGE();
00119     //
00120     PROGRESS_BEGIN_MESSAGE("Joining double connections");
00121     myJoinedEdges.init(myEdgeCont);
00122     myNodeCont.joinDoubleNodeConnections(myDistrictCont, myEdgeCont, myTLLCont);
00123     PROGRESS_DONE_MESSAGE();
00124     //
00125     if (oc.exists("remove-edges.isolated") && oc.getBool("remove-edges.isolated")) {
00126         PROGRESS_BEGIN_MESSAGE("Finding isolated roads");
00127         myNodeCont.removeIsolatedRoads(myDistrictCont, myEdgeCont, myTLLCont);
00128         PROGRESS_DONE_MESSAGE();
00129     }
00130     //
00131     if (oc.exists("keep-edges.postload") && oc.getBool("keep-edges.postload")) {
00132         if (oc.isSet("keep-edges.explicit")) {
00133             PROGRESS_BEGIN_MESSAGE("Removing unwished edges");
00134             myEdgeCont.removeUnwishedEdges(myDistrictCont);
00135             PROGRESS_DONE_MESSAGE();
00136         }
00137     }
00138     //
00139     if (removeUnwishedNodes) {
00140         unsigned int no = 0;
00141         if (oc.exists("geometry.remove")&&oc.getBool("geometry.remove")) {
00142             PROGRESS_BEGIN_MESSAGE("Removing empty nodes and geometry nodes");
00143             no = myNodeCont.removeUnwishedNodes(myDistrictCont, myEdgeCont, myJoinedEdges, myTLLCont, true);
00144         } else {
00145             PROGRESS_BEGIN_MESSAGE("Removing empty nodes");
00146             no = myNodeCont.removeUnwishedNodes(myDistrictCont, myEdgeCont, myJoinedEdges, myTLLCont, false);
00147         }
00148         PROGRESS_DONE_MESSAGE();
00149         WRITE_MESSAGE("   " + toString(no) + " nodes removed.");
00150     }
00151     //
00152     if (oc.exists("geometry.split") && oc.getBool("geometry.split")) {
00153         PROGRESS_BEGIN_MESSAGE("Splitting geometry edges");
00154         myEdgeCont.splitGeometry(myNodeCont);
00155         PROGRESS_DONE_MESSAGE();
00156     }
00157 
00158 
00159     // MOVE TO ORIGIN
00160     //
00161     if (!oc.getBool("offset.disable-normalization") && oc.isDefault("offset.x") && oc.isDefault("offset.y")) {
00162         PROGRESS_BEGIN_MESSAGE("Moving network to origin");
00163         const SUMOReal x = -geoConvHelper.getConvBoundary().xmin();
00164         const SUMOReal y = -geoConvHelper.getConvBoundary().ymin();
00165         for (std::map<std::string, NBNode*>::const_iterator i=myNodeCont.begin(); i!=myNodeCont.end(); ++i) {
00166             (*i).second->reshiftPosition(x, y);
00167         }
00168         for (std::map<std::string, NBEdge*>::const_iterator i=myEdgeCont.begin(); i!=myEdgeCont.end(); ++i) {
00169             (*i).second->reshiftPosition(x, y);
00170         }
00171         for (std::map<std::string, NBDistrict*>::const_iterator i=myDistrictCont.begin(); i!=myDistrictCont.end(); ++i) {
00172             (*i).second->reshiftPosition(x, y);
00173         }
00174         geoConvHelper.moveConvertedBy(x, y);
00175         PROGRESS_DONE_MESSAGE();
00176     }
00177 
00178     // @todo Why?
00179     myEdgeCont.recomputeLaneShapes();
00180 
00181 
00182     // GUESS RAMPS
00183     if ((oc.exists("ramps.guess")&&oc.getBool("ramps.guess"))||(oc.exists("ramps.set")&&oc.isSet("ramps.set"))) {
00184         PROGRESS_BEGIN_MESSAGE("Guessing and setting on-/off-ramps");
00185         myNodeCont.guessRamps(oc, myEdgeCont, myDistrictCont);
00186         PROGRESS_DONE_MESSAGE();
00187     }
00188 
00189 
00190     // GUESS TLS POSITIONS
00191     PROGRESS_BEGIN_MESSAGE("Assigning nodes to traffic lights");
00192     if (oc.isSet("tls.set")) {
00193         std::vector<std::string> tlControlledNodes = oc.getStringVector("tls.set");
00194         for (std::vector<std::string>::const_iterator i=tlControlledNodes.begin(); i!=tlControlledNodes.end(); ++i) {
00195             NBNode* node = myNodeCont.retrieve(*i);
00196             if (node==0) {
00197                 WRITE_WARNING("Building a tl-logic for node '" + *i + "' is not possible." + "\n The node '" + *i + "' is not known.");
00198             } else {
00199                 myNodeCont.setAsTLControlled(node, myTLLCont);
00200             }
00201         }
00202     }
00203     myNodeCont.guessTLs(oc, myTLLCont);
00204     PROGRESS_DONE_MESSAGE();
00205     //
00206     if (oc.getBool("tls.join")) {
00207         PROGRESS_BEGIN_MESSAGE("Joining traffic light nodes");
00208         myNodeCont.joinTLS(myTLLCont);
00209         PROGRESS_DONE_MESSAGE();
00210     }
00211 
00212 
00213     //
00214     PROGRESS_BEGIN_MESSAGE("Computing turning directions");
00215     myEdgeCont.computeTurningDirections();
00216     PROGRESS_DONE_MESSAGE();
00217     //
00218     PROGRESS_BEGIN_MESSAGE("Sorting nodes' edges");
00219     myNodeCont.sortNodesEdges(oc.getBool("lefthand"));
00220     PROGRESS_DONE_MESSAGE();
00221     //
00222     PROGRESS_BEGIN_MESSAGE("Computing node types");
00223     myNodeCont.computeNodeTypes(myTypeCont);
00224     PROGRESS_DONE_MESSAGE();
00225     //
00226     PROGRESS_BEGIN_MESSAGE("Computing priorities");
00227     myNodeCont.computePriorities();
00228     PROGRESS_DONE_MESSAGE();
00229     //
00230     if (oc.getBool("roundabouts.guess")) {
00231         PROGRESS_BEGIN_MESSAGE("Guessing and setting roundabouts");
00232         myEdgeCont.guessRoundabouts(myRoundabouts);
00233         PROGRESS_DONE_MESSAGE();
00234     }
00235     //
00236     PROGRESS_BEGIN_MESSAGE("Computing approached edges");
00237     myEdgeCont.computeEdge2Edges(oc.getBool("no-left-connections"));
00238     PROGRESS_DONE_MESSAGE();
00239     //
00240     PROGRESS_BEGIN_MESSAGE("Computing approaching lanes");
00241     myEdgeCont.computeLanes2Edges();
00242     PROGRESS_DONE_MESSAGE();
00243     //
00244     PROGRESS_BEGIN_MESSAGE("Dividing of lanes on approached lanes");
00245     myNodeCont.computeLanes2Lanes();
00246     myEdgeCont.sortOutgoingLanesConnections();
00247     PROGRESS_DONE_MESSAGE();
00248     //
00249     PROGRESS_BEGIN_MESSAGE("Processing turnarounds");
00250     if (!oc.getBool("no-turnarounds")) {
00251         myEdgeCont.appendTurnarounds(oc.getBool("no-turnarounds.tls"));
00252     } else {
00253         myEdgeCont.appendTurnarounds(explicitTurnarounds, oc.getBool("no-turnarounds.tls"));
00254     }
00255     PROGRESS_DONE_MESSAGE();
00256     //
00257     PROGRESS_BEGIN_MESSAGE("Rechecking of lane endings");
00258     myEdgeCont.recheckLanes();
00259     PROGRESS_DONE_MESSAGE();
00260     //
00261     PROGRESS_BEGIN_MESSAGE("Computing node shapes");
00262     myNodeCont.computeNodeShapes(oc.getBool("lefthand"));
00263     PROGRESS_DONE_MESSAGE();
00264     //
00265     PROGRESS_BEGIN_MESSAGE("Computing edge shapes");
00266     myEdgeCont.computeEdgeShapes();
00267     PROGRESS_DONE_MESSAGE();
00268     //
00269     PROGRESS_BEGIN_MESSAGE("Computing traffic light control information");
00270     myTLLCont.setTLControllingInformation(myEdgeCont);
00271     PROGRESS_DONE_MESSAGE();
00272     //
00273     PROGRESS_BEGIN_MESSAGE("Computing node logics");
00274     myNodeCont.computeLogics(myEdgeCont, oc);
00275     PROGRESS_DONE_MESSAGE();
00276     //
00277     PROGRESS_BEGIN_MESSAGE("Computing traffic light logics");
00278     std::pair<unsigned int, unsigned int> numbers = myTLLCont.computeLogics(myEdgeCont, oc);
00279     PROGRESS_DONE_MESSAGE();
00280     std::string progCount = "";
00281     if (numbers.first != numbers.second) {
00282         progCount = "(" + toString(numbers.second) + " programs) ";
00283     }
00284     WRITE_MESSAGE(" " + toString(numbers.first) + " traffic light(s) " + progCount + "computed.");
00285     if (!oc.getBool("no-internal-links")) {
00286         PROGRESS_BEGIN_MESSAGE("Building inner edges");
00287         for (std::map<std::string, NBEdge*>::const_iterator i=myEdgeCont.begin(); i!=myEdgeCont.end(); ++i) {
00288             (*i).second->sortOutgoingConnectionsByIndex();
00289         }
00290         for (std::map<std::string, NBNode*>::const_iterator i=myNodeCont.begin(); i!=myNodeCont.end(); ++i) {
00291             (*i).second->buildInnerEdges();
00292         }
00293         PROGRESS_DONE_MESSAGE();
00294     }
00295 
00296     // report
00297     WRITE_MESSAGE("-----------------------------------------------------");
00298     WRITE_MESSAGE("Summary:");
00299     if (!gSuppressMessages) {
00300         myNodeCont.printBuiltNodesStatistics();
00301     }
00302     WRITE_MESSAGE(" Network boundaries:");
00303     WRITE_MESSAGE("  Original boundary  : " + toString(geoConvHelper.getOrigBoundary()));
00304     WRITE_MESSAGE("  Applied offset     : " + toString(geoConvHelper.getOffsetBase()));
00305     WRITE_MESSAGE("  Converted boundary : " + toString(geoConvHelper.getConvBoundary()));
00306     WRITE_MESSAGE("-----------------------------------------------------");
00307     NBRequest::reportWarnings();
00308 }
00309 
00310 
00311 /****************************************************************************/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines