SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NBNetBuilder.cpp
Go to the documentation of this file.
1 /****************************************************************************/
12 // Instance responsible for building networks
13 /****************************************************************************/
14 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
15 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
16 /****************************************************************************/
17 //
18 // This file is part of SUMO.
19 // SUMO is free software: you can redistribute it and/or modify
20 // it under the terms of the GNU General Public License as published by
21 // the Free Software Foundation, either version 3 of the License, or
22 // (at your option) any later version.
23 //
24 /****************************************************************************/
25 
26 
27 // ===========================================================================
28 // included modules
29 // ===========================================================================
30 #ifdef _MSC_VER
31 #include <windows_config.h>
32 #else
33 #include <config.h>
34 #endif
35 
36 #include <string>
37 #include <fstream>
38 #include "NBNetBuilder.h"
39 #include "NBNodeCont.h"
40 #include "NBEdgeCont.h"
42 #include "NBDistrictCont.h"
43 #include "NBDistrict.h"
44 #include "NBDistribution.h"
45 #include "NBRequest.h"
46 #include "NBTypeCont.h"
51 #include <utils/common/ToString.h>
53 #include "NBAlgorithms.h"
54 #include "NBAlgorithms_Ramps.h"
55 
56 
57 #ifdef CHECK_MEMORY_LEAKS
58 #include <foreign/nvwa/debug_new.h>
59 #endif // CHECK_MEMORY_LEAKS
60 
61 
62 // ===========================================================================
63 // method definitions
64 // ===========================================================================
66  : myEdgeCont(myTypeCont) {}
67 
68 
70 
71 
72 void
74  // we possibly have to load the edges to keep
75  if (oc.isSet("keep-edges.input-file")) {
76  std::ifstream strm(oc.getString("keep-edges.input-file").c_str());
77  if (!strm.good()) {
78  throw ProcessError("Could not load names of edges too keep from '" + oc.getString("keep-edges.input-file") + "'.");
79  }
80  std::ostringstream oss;
81  bool first = true;
82  while (strm.good()) {
83  if (!first) {
84  oss << ',';
85  }
86  std::string name;
87  strm >> name;
88  oss << name;
89  first = false;
90  }
91  oc.set("keep-edges.explicit", oss.str());
92  }
93  // apply options to type control
94  myTypeCont.setDefaults(oc.getInt("default.lanenumber"), oc.getFloat("default.speed"), oc.getInt("default.priority"));
95  // apply options to edge control
97  // apply options to traffic light logics control
99 }
100 
101 
102 void
104  const std::set<std::string>& explicitTurnarounds,
105  bool removeUnwishedNodes) {
106  GeoConvHelper& geoConvHelper = GeoConvHelper::getProcessing();
107 
108 
109  // MODIFYING THE SETS OF NODES AND EDGES
110  // join junctions
111 
112  if (oc.exists("junctions.join-exclude") && oc.isSet("junctions.join-exclude")) {
113  myNodeCont.addJoinExclusion(oc.getStringVector("junctions.join-exclude"));
114  }
116  if (oc.getBool("junctions.join")) {
117  PROGRESS_BEGIN_MESSAGE("Joining junction clusters");
118  // preliminary geometry computations to determine the length of edges
119  // This depends on turning directions and sorting of edge list
120  // in case junctions are joined geometry computations have to be repeated
123  myNodeCont.computeNodeShapes(oc.getBool("lefthand"));
125  numJoined += myNodeCont.joinJunctions(oc.getFloat("junctions.join-dist"), myDistrictCont, myEdgeCont, myTLLCont);
127  }
128  if (numJoined > 0) {
129  // bit of a misnomer since we're already done
130  WRITE_MESSAGE(" Joined " + toString(numJoined) + " junction cluster(s).");
131  }
132 
133  // Removes edges that are connecting the same node
134  PROGRESS_BEGIN_MESSAGE("Removing self-loops");
137  //
138  if (oc.exists("remove-edges.isolated") && oc.getBool("remove-edges.isolated")) {
139  PROGRESS_BEGIN_MESSAGE("Finding isolated roads");
142  }
143  //
144  if (oc.exists("keep-edges.postload") && oc.getBool("keep-edges.postload")) {
145  if (oc.isSet("keep-edges.explicit")) {
146  PROGRESS_BEGIN_MESSAGE("Removing unwished edges");
149  }
150  }
151  //
152  if (removeUnwishedNodes) {
153  unsigned int no = 0;
154  const bool removeGeometryNodes = oc.exists("geometry.remove") && oc.getBool("geometry.remove");
155  PROGRESS_BEGIN_MESSAGE("Removing empty nodes" + std::string(removeGeometryNodes ? " and geometry nodes" : ""));
158  WRITE_MESSAGE(" " + toString(no) + " nodes removed.");
159  }
160  // @note: removing geometry can create similar edges so "Joining" must come afterwards
161  // @note: likewise splitting can destroy similarities so "Joining" must come before
162  PROGRESS_BEGIN_MESSAGE("Joining similar edges");
166  //
167  if (oc.exists("geometry.split") && oc.getBool("geometry.split")) {
168  PROGRESS_BEGIN_MESSAGE("Splitting geometry edges");
171  }
172  // guess ramps
173  if ((oc.exists("ramps.guess") && oc.getBool("ramps.guess")) || (oc.exists("ramps.set") && oc.isSet("ramps.set"))) {
174  PROGRESS_BEGIN_MESSAGE("Guessing and setting on-/off-ramps");
178  }
179 
180  // check whether any not previously setable connections may be set now
182 
183  // MOVE TO ORIGIN
184  if (!oc.getBool("offset.disable-normalization") && oc.isDefault("offset.x") && oc.isDefault("offset.y")) {
185  PROGRESS_BEGIN_MESSAGE("Moving network to origin");
186  const SUMOReal x = -geoConvHelper.getConvBoundary().xmin();
187  const SUMOReal y = -geoConvHelper.getConvBoundary().ymin();
188  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
189  (*i).second->reshiftPosition(x, y);
190  }
191  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
192  (*i).second->reshiftPosition(x, y);
193  }
194  for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) {
195  (*i).second->reshiftPosition(x, y);
196  }
197  geoConvHelper.moveConvertedBy(x, y);
199  }
200  geoConvHelper.computeFinal(); // information needed for location element fixed at this point
201 
202  // @todo Why?
204 
205  // APPLY SPEED MODIFICATIONS
206  if (oc.exists("speed.offset")) {
207  const SUMOReal speedOffset = oc.getFloat("speed.offset");
208  const SUMOReal speedFactor = oc.getFloat("speed.factor");
209  if (speedOffset != 0 || speedFactor != 1) {
210  PROGRESS_BEGIN_MESSAGE("Applying speed modifications");
211  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
212  (*i).second->setSpeed(-1, (*i).second->getSpeed() * speedFactor + speedOffset);
213  }
215  }
216  }
217 
218  // CONNECTIONS COMPUTATION
219  //
220  PROGRESS_BEGIN_MESSAGE("Computing turning directions");
223  //
224  PROGRESS_BEGIN_MESSAGE("Sorting nodes' edges");
227  //
228  PROGRESS_BEGIN_MESSAGE("Computing node types");
231  //
232  PROGRESS_BEGIN_MESSAGE("Computing priorities");
235  //
236  PROGRESS_BEGIN_MESSAGE("Computing approached edges");
237  myEdgeCont.computeEdge2Edges(oc.getBool("no-left-connections"));
239  //
240  if (oc.getBool("roundabouts.guess")) {
241  PROGRESS_BEGIN_MESSAGE("Guessing and setting roundabouts");
244  }
245  //
246  PROGRESS_BEGIN_MESSAGE("Computing approaching lanes");
249  //
250  PROGRESS_BEGIN_MESSAGE("Dividing of lanes on approached lanes");
254  //
255  PROGRESS_BEGIN_MESSAGE("Processing turnarounds");
256  if (!oc.getBool("no-turnarounds")) {
257  myEdgeCont.appendTurnarounds(oc.getBool("no-turnarounds.tls"));
258  } else {
259  myEdgeCont.appendTurnarounds(explicitTurnarounds, oc.getBool("no-turnarounds.tls"));
260  }
262  //
263  PROGRESS_BEGIN_MESSAGE("Rechecking of lane endings");
266 
267 
268  // GEOMETRY COMPUTATION
269  //
270  PROGRESS_BEGIN_MESSAGE("Computing node shapes");
271  myNodeCont.computeNodeShapes(oc.getBool("lefthand"));
273  //
274  PROGRESS_BEGIN_MESSAGE("Computing edge shapes");
277 
278 
279  // GUESS TLS POSITIONS
280  PROGRESS_BEGIN_MESSAGE("Assigning nodes to traffic lights");
281  if (oc.isSet("tls.set")) {
282  std::vector<std::string> tlControlledNodes = oc.getStringVector("tls.set");
283  for (std::vector<std::string>::const_iterator i = tlControlledNodes.begin(); i != tlControlledNodes.end(); ++i) {
284  NBNode* node = myNodeCont.retrieve(*i);
285  if (node == 0) {
286  WRITE_WARNING("Building a tl-logic for node '" + *i + "' is not possible." + "\n The node '" + *i + "' is not known.");
287  } else {
289  }
290  }
291  }
294  //
295  if (oc.getBool("tls.join")) {
296  PROGRESS_BEGIN_MESSAGE("Joining traffic light nodes");
297  myNodeCont.joinTLS(myTLLCont, oc.getFloat("tls.join-dist"));
299  }
300 
301 
302  // COMPUTING RIGHT-OF-WAY AND TRAFFIC LIGHT PROGRAMS
303  //
304  PROGRESS_BEGIN_MESSAGE("Computing traffic light control information");
307  //
308  PROGRESS_BEGIN_MESSAGE("Computing node logics");
311  //
312  PROGRESS_BEGIN_MESSAGE("Computing traffic light logics");
313  std::pair<unsigned int, unsigned int> numbers = myTLLCont.computeLogics(myEdgeCont, oc);
315  std::string progCount = "";
316  if (numbers.first != numbers.second) {
317  progCount = "(" + toString(numbers.second) + " programs) ";
318  }
319  WRITE_MESSAGE(" " + toString(numbers.first) + " traffic light(s) " + progCount + "computed.");
320  //
321  if (oc.isSet("street-sign-output")) {
322  PROGRESS_BEGIN_MESSAGE("Generating street signs");
325  }
326 
327  // FINISHING INNER EDGES
328  if (!oc.getBool("no-internal-links")) {
329  PROGRESS_BEGIN_MESSAGE("Building inner edges");
330  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
331  (*i).second->sortOutgoingConnectionsByIndex();
332  }
333  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
334  (*i).second->buildInnerEdges();
335  }
337  }
338 
339 
340  // report
341  WRITE_MESSAGE("-----------------------------------------------------");
342  WRITE_MESSAGE("Summary:");
344  WRITE_MESSAGE(" Network boundaries:");
345  WRITE_MESSAGE(" Original boundary : " + toString(geoConvHelper.getOrigBoundary()));
346  WRITE_MESSAGE(" Applied offset : " + toString(geoConvHelper.getOffsetBase()));
347  WRITE_MESSAGE(" Converted boundary : " + toString(geoConvHelper.getConvBoundary()));
348  WRITE_MESSAGE("-----------------------------------------------------");
350 }
351 
352 
353 /****************************************************************************/