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 #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 /****************************************************************************/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines