SUMO - Simulation of Urban MObility

NBNetBuilder.cpp

Go to the documentation of this file.
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 /****************************************************************************/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines