Eclipse SUMO - Simulation of Urban MObility
NBNetBuilder.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
23 // Instance responsible for building networks
24 /****************************************************************************/
25 #include <config.h>
26 
27 #include <string>
28 #include <fstream>
34 #include <utils/common/SysUtils.h>
35 #include <utils/common/ToString.h>
37 #include "NBAlgorithms.h"
38 #include "NBAlgorithms_Ramps.h"
39 #include "NBAlgorithms_Railway.h"
40 #include "NBHeightMapper.h"
41 #include "NBNodeCont.h"
42 #include "NBEdgeCont.h"
43 #include "NBPTStop.h"
45 #include "NBDistrictCont.h"
46 #include "NBDistrict.h"
47 #include "NBRequest.h"
48 #include "NBTypeCont.h"
49 #include "NBNetBuilder.h"
50 
51 
52 // ===========================================================================
53 // method definitions
54 // ===========================================================================
56  myEdgeCont(myTypeCont),
57  myNetworkHaveCrossings(false) {
58 }
59 
60 
62 
63 
64 void
66  // apply options to type control
67  myTypeCont.setEdgeTypeDefaults(oc.getInt("default.lanenumber"), oc.getFloat("default.lanewidth"), oc.getFloat("default.speed"), oc.getFloat("default.friction"),
68  oc.getInt("default.priority"), parseVehicleClasses(oc.getString("default.allow"), oc.getString("default.disallow")),
69  SUMOXMLDefinitions::LaneSpreadFunctions.get(oc.getString("default.spreadtype")));
70  // apply options to edge control
72  // apply options to traffic light logics control
74  NBEdge::setDefaultConnectionLength(oc.getFloat("default.connection-length"));
75 }
76 
77 
78 void
79 NBNetBuilder::compute(OptionsCont& oc, const std::set<std::string>& explicitTurnarounds, bool mayAddOrRemove) {
80  // reset shapes and angles for stable netedit computation
83  }
84 
86 
87  const bool lefthand = oc.getBool("lefthand");
88  if (lefthand) {
89  mirrorX();
90  }
91 
92  // MODIFYING THE SETS OF NODES AND EDGES
93  // Removes edges that are connecting the same node
94  long before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Removing self-loops"));
95  int numRemovedEdges = 0;
97  PROGRESS_TIME_MESSAGE(before);
98  if (mayAddOrRemove && oc.exists("remove-edges.isolated") && oc.getBool("remove-edges.isolated")) {
99  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Finding isolated roads"));
101  PROGRESS_TIME_MESSAGE(before);
102  }
103  if (mayAddOrRemove && oc.exists("keep-edges.components") && oc.getInt("keep-edges.components") > 0) {
104  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Finding largest components"));
105  const bool hasStops = oc.exists("ptstop-output") && oc.isSet("ptstop-output") && !myPTStopCont.getStops().empty();
106  numRemovedEdges += myNodeCont.removeComponents(myDistrictCont, myEdgeCont, oc.getInt("keep-edges.components"), hasStops);
107  PROGRESS_TIME_MESSAGE(before);
108  }
109  if (mayAddOrRemove && oc.exists("keep-edges.postload") && oc.getBool("keep-edges.postload")) {
110  // pre-process lines to set permissions
111  if (!myPTLineCont.getLines().empty()) {
112  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Revising public transport stops based on pt lines"));
114  PROGRESS_TIME_MESSAGE(before);
115  }
116  if (oc.isSet("keep-edges.explicit") || oc.isSet("keep-edges.input-file")) {
117  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Removing unwished edges"));
118  numRemovedEdges += myEdgeCont.removeUnwishedEdges(myDistrictCont);
119  PROGRESS_TIME_MESSAGE(before);
120  }
121  const int removed = myEdgeCont.removeEdgesBySpeed(myDistrictCont);
122  if (removed > 0) {
123  numRemovedEdges += removed;
124  WRITE_MESSAGEF(TL(" Removed % edges because by minimum speed."), removed);
125  }
126  const int removed2 = myEdgeCont.removeEdgesByPermissions(myDistrictCont);
127  if (removed2 > 0) {
128  numRemovedEdges += removed2;
129  WRITE_MESSAGEF(TL(" Removed % edges based on vClass."), removed2);
130  }
131  }
132  if (mayAddOrRemove && oc.getFloat("keep-lanes.min-width") > 0.) {
133  const int removed = myEdgeCont.removeLanesByWidth(myDistrictCont, oc.getFloat("keep-lanes.min-width"));
134  if (removed > 0) {
135  numRemovedEdges += removed;
136  WRITE_MESSAGEF(TL(" Removed % edges because of lane width."), removed);
137  }
138  }
139  // Processing pt stops and lines
140  if (!myPTStopCont.getStops().empty()) {
141  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Processing public transport stops"));
142  if (!(oc.exists("ptline-output") && oc.isSet("ptline-output"))
143  && !oc.getBool("ptstop-output.no-bidi")) {
145  }
148  PROGRESS_TIME_MESSAGE(before);
149  }
150  if (mayAddOrRemove && oc.exists("keep-edges.components") && oc.getInt("keep-edges.components") > 0) {
151  // post process rail components unless they have stops
153  }
154  // removal is done, clean up roundabouts
155  if (numRemovedEdges > 0) {
157  }
158 
159  if (!myPTLineCont.getLines().empty()) {
160  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Revising public transport stops based on pt lines"));
162  PROGRESS_TIME_MESSAGE(before);
163  }
164 
165  if (oc.exists("ptline-clean-up") && oc.getBool("ptline-clean-up")) {
166  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Cleaning up public transport stops that are not served by any line"));
168  PROGRESS_TIME_MESSAGE(before);
169  } else {
170  int numDeletedStops = myPTStopCont.cleanupDeleted(myEdgeCont);
171  if (numDeletedStops > 0) {
172  WRITE_WARNINGF(TL("Removed % pt stops because they could not be assigned to the network"), toString(numDeletedStops));
173  }
174  }
175 
176  if (!myPTStopCont.getStops().empty() && !oc.getBool("ptstop-output.no-bidi")) {
177  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Align pt stop id signs with corresponding edge id signs"));
179  PROGRESS_TIME_MESSAGE(before);
180  }
181  // analyze and fix railway topology
182  int numAddedBidi = 0;
183  if (oc.exists("railway.topology.all-bidi") && oc.getBool("railway.topology.all-bidi")) {
186  } else if (oc.exists("railway.topology.repair") && oc.getBool("railway.topology.repair")) {
187  // correct railway angles for angle-based connectivity heuristic
188  myEdgeCont.checkGeometries(0, false,
189  oc.getFloat("geometry.min-radius"), false,
190  oc.getBool("geometry.min-radius.fix.railways"), true);
193  }
195  if (numAddedBidi > 0) {
196  // update routes
198  }
199  if (oc.exists("railway.topology.direction-priority") && oc.getBool("railway.topology.direction-priority")) {
200  NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
202  } else if (oc.exists("railway.topology.extend-priority") && oc.getBool("railway.topology.extend-priority")) {
203  NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
205  }
206  if (oc.exists("railway.topology.output") && oc.isSet("railway.topology.output")) {
207  NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
209  }
210  if (oc.exists("railway.geometry.straighten") && oc.getBool("railway.geometry.straighten")) {
211  NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
213  }
214 
215 
216  if (mayAddOrRemove && oc.exists("edges.join-tram-dist") && oc.getFloat("edges.join-tram-dist") >= 0) {
217  // should come before joining junctions
218  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining tram edges"));
219  int numJoinedTramEdges = myEdgeCont.joinTramEdges(myDistrictCont, myPTStopCont, myPTLineCont, oc.getFloat("edges.join-tram-dist"));
220  PROGRESS_TIME_MESSAGE(before);
221  if (numJoinedTramEdges > 0) {
222  WRITE_MESSAGEF(TL(" Joined % tram edges into roads."), toString(numJoinedTramEdges));
223  }
224  }
225  if (oc.getBool("junctions.join")
226  || (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))
227  || oc.getBool("tls.guess.joining")
228  || (oc.exists("tls.guess-signals") && oc.getBool("tls.guess-signals"))) {
229  // preliminary geometry computations to determine the length of edges
230  // This depends on turning directions and sorting of edge list
231  // in case junctions are joined geometry computations have to be repeated
232  // preliminary roundabout computations to avoid damaging roundabouts via junctions.join or ramps.guess
238  if (oc.getBool("roundabouts.guess")) {
240  }
241  const std::set<EdgeSet>& roundabouts = myEdgeCont.getRoundabouts();
242  for (std::set<EdgeSet>::const_iterator it_round = roundabouts.begin();
243  it_round != roundabouts.end(); ++it_round) {
244  std::vector<std::string> nodeIDs;
245  for (EdgeSet::const_iterator it_edge = it_round->begin(); it_edge != it_round->end(); ++it_edge) {
246  nodeIDs.push_back((*it_edge)->getToNode()->getID());
247  }
248  myNodeCont.addJoinExclusion(nodeIDs);
249  }
251  } else if (myEdgeCont.hasGuessedRoundabouts() && oc.getBool("roundabouts.guess")) {
253  }
254  // join junctions (may create new "geometry"-nodes so it needs to come before removing these
255  if (mayAddOrRemove && oc.exists("junctions.join-exclude") && oc.isSet("junctions.join-exclude")) {
256  myNodeCont.addJoinExclusion(oc.getStringVector("junctions.join-exclude"));
257  }
259  if (mayAddOrRemove && oc.getBool("junctions.join")) {
260  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining junction clusters"));
261  numJoined += myNodeCont.joinJunctions(oc.getFloat("junctions.join-dist"), myDistrictCont, myEdgeCont, myTLLCont, myPTStopCont);
262  PROGRESS_TIME_MESSAGE(before);
263  }
264  if (numJoined > 0) {
265  WRITE_MESSAGEF(TL(" Joined % junction cluster(s)."), toString(numJoined));
266  }
267  if (mayAddOrRemove && oc.exists("junctions.join-same") && oc.getBool("junctions.join-same")) {
268  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining junctions with identical coordinates"));
270  PROGRESS_TIME_MESSAGE(before);
271  if (numJoined2 > 0) {
272  WRITE_MESSAGEF(TL(" Joined % junctions."), toString(numJoined2));
273  }
274  }
275  //
276  if (mayAddOrRemove && oc.exists("join-lanes") && oc.getBool("join-lanes")) {
277  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining lanes"));
279  PROGRESS_TIME_MESSAGE(before);
280  WRITE_MESSAGEF(TL(" Joined lanes on % edges."), toString(num));
281  }
282  //
283  if (mayAddOrRemove) {
284  const bool removeGeometryNodes = oc.exists("geometry.remove") && oc.getBool("geometry.remove");
285  before = PROGRESS_BEGIN_TIME_MESSAGE("Removing empty nodes" + std::string(removeGeometryNodes ? " and geometry nodes" : ""));
286  // removeUnwishedNodes needs turnDirections. @todo: try to call this less often
289  PROGRESS_TIME_MESSAGE(before);
290  WRITE_MESSAGEF(TL(" % nodes removed."), toString(numRemoved));
291  }
292 
293  // MOVE TO ORIGIN
294  // compute new boundary after network modifications have taken place
295  Boundary boundary;
296  for (std::map<std::string, NBNode*>::const_iterator it = myNodeCont.begin(); it != myNodeCont.end(); ++it) {
297  boundary.add(it->second->getPosition());
298  }
299  for (std::map<std::string, NBEdge*>::const_iterator it = myEdgeCont.begin(); it != myEdgeCont.end(); ++it) {
300  boundary.add(it->second->getGeometry().getBoxBoundary());
301  }
302  geoConvHelper.setConvBoundary(boundary);
303 
304  if (!oc.getBool("offset.disable-normalization") && oc.isDefault("offset.x") && oc.isDefault("offset.y")) {
305  moveToOrigin(geoConvHelper, lefthand);
306  }
307  geoConvHelper.computeFinal(lefthand); // information needed for location element fixed at this point
308 
309  if (oc.exists("geometry.min-dist") && !oc.isDefault("geometry.min-dist")) {
310  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Reducing geometries"));
311  myEdgeCont.reduceGeometries(oc.getFloat("geometry.min-dist"));
312  PROGRESS_TIME_MESSAGE(before);
313  }
314  // @note: removing geometry can create similar edges so joinSimilarEdges must come afterwards
315  // @note: likewise splitting can destroy similarities so joinSimilarEdges must come before
316  if (mayAddOrRemove && oc.getBool("edges.join")) {
317  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining similar edges"));
318  const bool removeDuplicates = oc.exists("junctions.join-same") && oc.getBool("junctions.join-same");
320  // now we may have new chances to remove geometry if wished
321  if (oc.exists("geometry.remove") && oc.getBool("geometry.remove")) {
323  }
324  PROGRESS_TIME_MESSAGE(before);
325  }
326  if (oc.getBool("opposites.guess")) {
327  PROGRESS_BEGIN_MESSAGE(TL("guessing opposite direction edges"));
330  }
331  //
332  if (mayAddOrRemove && oc.exists("geometry.split") && oc.getBool("geometry.split")) {
333  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Splitting geometry edges"));
335  // newly split junctions might also be joinable
336  PROGRESS_TIME_MESSAGE(before);
337  if (oc.getBool("junctions.join-same")) {
339  if (numJoined3 > 0) {
340  WRITE_MESSAGEF(TL(" Joined % junctions after splitting geometry."), toString(numJoined3));
341  }
342  }
343  }
344  // turning direction
345  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing turning directions"));
347  PROGRESS_TIME_MESSAGE(before);
348  // correct edge geometries to avoid overlap
349  if (oc.exists("geometry.avoid-overlap") && oc.getBool("geometry.avoid-overlap")) {
351  }
352 
353  // GUESS TLS POSITIONS
354  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Assigning nodes to traffic lights"));
355  if (oc.isSet("tls.set")) {
356  std::vector<std::string> tlControlledNodes = oc.getStringVector("tls.set");
358  for (std::vector<std::string>::const_iterator i = tlControlledNodes.begin(); i != tlControlledNodes.end(); ++i) {
359  NBNode* node = myNodeCont.retrieve(*i);
360  if (node == nullptr) {
361  WRITE_WARNING("Building a tl-logic for junction '" + *i + "' is not possible." + "\n The junction '" + *i + "' is not known.");
362  } else {
364  }
365  }
366  }
368  PROGRESS_TIME_MESSAGE(before);
369 
370  // guess ramps (after guessing tls because ramps should not be build at traffic lights)
371  const bool modifyRamps = mayAddOrRemove && (
372  (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))
373  || (oc.exists("ramps.set") && oc.isSet("ramps.set")));
374  if (modifyRamps || (oc.exists("ramps.guess-acceleration-lanes") && oc.getBool("ramps.guess-acceleration-lanes"))) {
375  before = SysUtils::getCurrentMillis();
376  if (modifyRamps) {
377  PROGRESS_BEGIN_MESSAGE(TL("Guessing and setting on-/off-ramps"));
378  }
380  NBRampsComputer rc;
381  rc.computeRamps(*this, oc, mayAddOrRemove);
382 
383  if (modifyRamps) {
384  PROGRESS_TIME_MESSAGE(before);
385  }
386  }
387  // guess bike lanes
388  if (mayAddOrRemove && ((oc.getBool("bikelanes.guess") || oc.getBool("bikelanes.guess.from-permissions")))) {
389  const int bikelanes = myEdgeCont.guessSpecialLanes(SVC_BICYCLE, oc.getFloat("default.bikelane-width"),
390  oc.getFloat("bikelanes.guess.min-speed"),
391  oc.getFloat("bikelanes.guess.max-speed"),
392  oc.getBool("bikelanes.guess.from-permissions"),
393  "bikelanes.guess.exclude",
394  myTLLCont);
395  WRITE_MESSAGEF(TL("Guessed % bike lanes."), toString(bikelanes));
396  }
397 
398  // guess sidewalks
399  if (mayAddOrRemove && ((oc.getBool("sidewalks.guess") || oc.getBool("sidewalks.guess.from-permissions")))) {
400  const int sidewalks = myEdgeCont.guessSpecialLanes(SVC_PEDESTRIAN, oc.getFloat("default.sidewalk-width"),
401  oc.getFloat("sidewalks.guess.min-speed"),
402  oc.getFloat("sidewalks.guess.max-speed"),
403  oc.getBool("sidewalks.guess.from-permissions"),
404  "sidewalks.guess.exclude",
405  myTLLCont);
406  WRITE_MESSAGEF(TL("Guessed % sidewalks."), toString(sidewalks));
407  }
408  // check whether any not previously setable connections may be set now
410 
411  // remap ids if wished
412  if (mayAddOrRemove) {
413  int numChangedEdges = myEdgeCont.remapIDs(oc.getBool("numerical-ids"), oc.isSet("reserved-ids"), oc.getString("prefix"), myPTStopCont);
414  int numChangedNodes = myNodeCont.remapIDs(oc.getBool("numerical-ids"), oc.isSet("reserved-ids"), oc.getString("prefix"), myTLLCont);
415  if (numChangedEdges + numChangedNodes > 0) {
416  WRITE_MESSAGEF(TL("Remapped % edge IDs and % node IDs."), toString(numChangedEdges), toString(numChangedNodes));
417  }
418  }
419 
420  //
421  if (oc.exists("geometry.max-angle")) {
423  DEG2RAD(oc.getFloat("geometry.max-angle")),
424  oc.getBool("geometry.max-angle.fix"),
425  oc.getFloat("geometry.min-radius"),
426  oc.getBool("geometry.min-radius.fix"),
427  oc.getBool("geometry.min-radius.fix.railways"));
428  }
429 
430  // GEOMETRY COMPUTATION
431  //
432  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Sorting nodes' edges"));
434  PROGRESS_TIME_MESSAGE(before);
436  //
437  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing node shapes"));
438  if (oc.exists("geometry.junction-mismatch-threshold")) {
439  myNodeCont.computeNodeShapes(oc.getFloat("geometry.junction-mismatch-threshold"));
440  } else {
442  }
443  PROGRESS_TIME_MESSAGE(before);
444  //
445  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing edge shapes"));
446  myEdgeCont.computeEdgeShapes(oc.getBool("geometry.max-grade.fix") ? oc.getFloat("geometry.max-grade") / 100 : -1);
447  PROGRESS_TIME_MESSAGE(before);
448  // resort edges based on the node and edge shapes
451 
452  // APPLY SPEED MODIFICATIONS
453  if (oc.exists("speed.offset")) {
454  const double speedOffset = oc.getFloat("speed.offset");
455  const double speedFactor = oc.getFloat("speed.factor");
456  const double speedMin = oc.getFloat("speed.minimum");
457  if (speedOffset != 0 || speedFactor != 1 || speedMin > 0) {
458  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Applying speed modifications"));
459  for (const auto& it : myEdgeCont) {
460  NBEdge* const e = it.second;
461  for (int i = 0; i < e->getNumLanes(); i++) {
462  e->setSpeed(i, MAX2(e->getLaneSpeed(i) * speedFactor + speedOffset, speedMin));
463  }
464  }
465  PROGRESS_TIME_MESSAGE(before);
466  }
467  }
468 
469  // CONNECTIONS COMPUTATION
470  //
471  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing node types"));
473  PROGRESS_TIME_MESSAGE(before);
474  //
475  myNetworkHaveCrossings = oc.getBool("walkingareas");
476  if (mayAddOrRemove && oc.getBool("crossings.guess")) {
477  myNetworkHaveCrossings = true;
478  int crossings = 0;
479  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
480  crossings += (*i).second->guessCrossings();
481  }
482  WRITE_MESSAGEF(TL("Guessed % pedestrian crossings."), toString(crossings));
483  }
484  if (!myNetworkHaveCrossings) {
485  bool haveValidCrossings = false;
486  // recheck whether we had crossings in the input
487  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
488  if (i->second->getCrossings().size() > 0) {
489  myNetworkHaveCrossings = true;
490  haveValidCrossings = true;
491  break;
492  } else if (i->second->getCrossingsIncludingInvalid().size() > 0) {
493  myNetworkHaveCrossings = true;
494  }
495  }
496  if (myNetworkHaveCrossings && !haveValidCrossings) {
497  // initial crossings removed or invalidated, keep walkingareas
498  oc.resetWritable();
499  oc.set("walkingareas", "true");
500  }
501  }
502 
503  if (!mayAddOrRemove && myNetworkHaveCrossings) {
504  // crossings added via netedit
505  oc.resetWritable();
506  oc.set("no-internal-links", "false");
507  }
508 
509  //
510  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing priorities"));
512  PROGRESS_TIME_MESSAGE(before);
513  //
514  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing approached edges"));
515  myEdgeCont.computeEdge2Edges(oc.getBool("no-left-connections"));
516  PROGRESS_TIME_MESSAGE(before);
517  //
518  if (oc.getBool("roundabouts.guess")) {
519  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Guessing and setting roundabouts"));
520  const int numGuessed = myEdgeCont.guessRoundabouts();
521  if (numGuessed > 0) {
522  WRITE_MESSAGEF(TL(" Guessed % roundabout(s)."), toString(numGuessed));
523  }
524  PROGRESS_TIME_MESSAGE(before);
525  }
527  //
528  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing approaching lanes"));
530  PROGRESS_TIME_MESSAGE(before);
531  //
532  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Dividing of lanes on approached lanes"));
535  PROGRESS_TIME_MESSAGE(before);
536  //
537  if (oc.getBool("fringe.guess")) {
538  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Guessing Network fringe"));
539  const int numGuessed = myNodeCont.guessFringe();
540  if (numGuessed > 0) {
541  WRITE_MESSAGEF(TL(" Guessed % fringe nodes."), toString(numGuessed));
542  }
543  PROGRESS_TIME_MESSAGE(before);
544  }
545  //
546  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Processing turnarounds"));
547  if (!oc.getBool("no-turnarounds")) {
549  oc.getBool("no-turnarounds.tls"),
550  oc.getBool("no-turnarounds.fringe"),
551  oc.getBool("no-turnarounds.except-deadend"),
552  oc.getBool("no-turnarounds.except-turnlane"),
553  oc.getBool("no-turnarounds.geometry"));
554  } else {
555  myEdgeCont.appendTurnarounds(explicitTurnarounds, oc.getBool("no-turnarounds.tls"));
556  }
557  if (oc.exists("railway.topology.repair.stop-turn") && oc.getBool("railway.topology.repair.stop-turn")
558  && myPTStopCont.getStops().size() > 0) {
559  // allow direction reversal at all bidi-edges with stops
561  }
562  PROGRESS_TIME_MESSAGE(before);
563  //
564  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Rechecking of lane endings"));
566  PROGRESS_TIME_MESSAGE(before);
567 
568  if (myNetworkHaveCrossings && !oc.getBool("no-internal-links")) {
569  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
570  i->second->buildCrossingsAndWalkingAreas();
571  }
572  } else {
573  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
574  // needed by netedit if the last crossings was deleted from the network
575  // and walkingareas have been invalidated since the last call to compute()
576  i->second->discardWalkingareas();
577  }
578  if (oc.getBool("no-internal-links")) {
579  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
580  i->second->discardAllCrossings(false);
581  }
582  }
583  }
584  // join traffic lights (after building connections)
585  if (oc.getBool("tls.join")) {
586  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining traffic light nodes"));
587  myNodeCont.joinTLS(myTLLCont, oc.getFloat("tls.join-dist"));
588  PROGRESS_TIME_MESSAGE(before);
589  }
590 
591  // COMPUTING RIGHT-OF-WAY AND TRAFFIC LIGHT PROGRAMS
592  //
593  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing traffic light control information"));
595  if (oc.exists("opendrive-files") && oc.isSet("opendrive-files")) {
597  }
598  PROGRESS_TIME_MESSAGE(before);
599  //
600  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing node logics"));
602  PROGRESS_TIME_MESSAGE(before);
603 
604  //
605  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing traffic light logics"));
606  std::pair<int, int> numbers = myTLLCont.computeLogics(oc);
607  PROGRESS_TIME_MESSAGE(before);
608  std::string progCount = "";
609  if (numbers.first != numbers.second) {
610  progCount = "(" + toString(numbers.second) + " programs) ";
611  }
612  WRITE_MESSAGEF(TL(" % traffic light(s) %computed."), toString(numbers.first), progCount);
613  if (oc.exists("opendrive-files") && oc.isSet("opendrive-files") && oc.getBool("opendrive.signal-groups")) {
615  }
616 
617  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
618  (*i).second->sortOutgoingConnectionsByIndex();
619  }
620  // FINISHING INNER EDGES
621  std::set<NBTrafficLightDefinition*> largeNodeTLS;
622  if (!oc.getBool("no-internal-links")) {
623  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Building inner edges"));
624  // walking areas shall only be built if crossings are wished as well
625  for (const auto& item : myNodeCont) {
626  if (item.second->buildInnerEdges() > NBTrafficLightDefinition::MIN_YELLOW_SECONDS) {
627  const std::set<NBTrafficLightDefinition*>& tlDefs = item.second->getControllingTLS();
628  largeNodeTLS.insert(tlDefs.begin(), tlDefs.end());
629  }
630  }
631  PROGRESS_TIME_MESSAGE(before);
632  }
633  // PATCH NODE SHAPES
634  if (oc.getFloat("junctions.scurve-stretch") > 0) {
635  // @note: nodes have collected correction hints in buildInnerEdges()
636  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("stretching junctions to smooth geometries"));
639  myEdgeCont.computeEdgeShapes(oc.getBool("geometry.max-grade.fix") ? oc.getFloat("geometry.max-grade") / 100 : -1);
640  for (const auto& item : myNodeCont) {
641  item.second->buildInnerEdges();
642  }
643  PROGRESS_TIME_MESSAGE(before);
644  }
645  if (myEdgeCont.getNumEdgeSplits() > 0 && !oc.getBool("no-internal-links")) {
646  // edges with custom lengths were split, this has to take into account
647  // internal edge lengths (after geometry computation)
649  }
650  // recheck phases for large junctions
651  for (NBTrafficLightDefinition* def : largeNodeTLS) {
652  myTLLCont.computeSingleLogic(oc, def);
653  }
654  // compute lane-to-lane node logics (require traffic lights and inner edges to be done)
656 
657  // remove guessed traffic lights at junctions without conflicts (requires computeLogics2)
659 
660  // compute keepClear status (requires computeLogics2)
662 
663  //
664  if (oc.isSet("street-sign-output")) {
665  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Generating street signs"));
667  PROGRESS_TIME_MESSAGE(before);
668  }
669 
670 
671  if (lefthand != oc.getBool("flip-y-axis")) {
672  mirrorX();
673  }
674 
675  if (oc.exists("geometry.check-overlap") && oc.getFloat("geometry.check-overlap") > 0) {
676  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Checking overlapping edges"));
677  myEdgeCont.checkOverlap(oc.getFloat("geometry.check-overlap"), oc.getFloat("geometry.check-overlap.vertical-threshold"));
678  PROGRESS_TIME_MESSAGE(before);
679  }
680  if (geoConvHelper.getConvBoundary().getZRange() > 0 && oc.getFloat("geometry.max-grade") > 0) {
681  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Checking edge grade"));
682  // user input is in %
683  myEdgeCont.checkGrade(oc.getFloat("geometry.max-grade") / 100);
684  PROGRESS_TIME_MESSAGE(before);
685  }
686 
687  // find accesses for pt rail stops and add bidi-stops
688  if (!myPTStopCont.getStops().empty()) {
689  // re-adapt stop lanes after adding special lanes and cutting edge shapes at junction
691  before = SysUtils::getCurrentMillis();
692  int numBidiStops = 0;
693  if (!oc.getBool("ptstop-output.no-bidi")) {
694  numBidiStops = myPTStopCont.generateBidiStops(myEdgeCont);
695  }
696  PROGRESS_BEGIN_MESSAGE(TL("Find accesses for pt rail stops"));
697  double maxRadius = oc.getFloat("railway.access-distance");
698  double accessFactor = oc.getFloat("railway.access-factor");
699  int maxCount = oc.getInt("railway.max-accesses");
700  myPTStopCont.findAccessEdgesForRailStops(myEdgeCont, maxRadius, maxCount, accessFactor);
701  PROGRESS_TIME_MESSAGE(before);
702  if (numBidiStops > 0) {
704  }
705  }
707  // ensure that all turning lanes have sufficient permissions
709 
710  if (oc.exists("ignore-change-restrictions") && !oc.isDefault("ignore-change-restrictions")) {
711  SVCPermissions ignoring = parseVehicleClasses(oc.getStringVector("ignore-change-restrictions"));
713  }
714 
716  // report on very large networks
717  if (MAX2(geoConvHelper.getConvBoundary().xmax(), geoConvHelper.getConvBoundary().ymax()) > 1000000 ||
718  MIN2(geoConvHelper.getConvBoundary().xmin(), geoConvHelper.getConvBoundary().ymin()) < -1000000) {
719  WRITE_WARNING(TL("Network contains very large coordinates and will probably flicker in the GUI. Check for outlying nodes and make sure the network is shifted to the coordinate origin"));
720  }
721 
722  // clean up OSM processing params
723  if (oc.exists("osm-files") && oc.isSet("osm-files")) {
724  for (auto item : myEdgeCont) {
725  item.second->unsetParameter(NBTrafficLightDefinition::OSM_DIRECTION);
726  }
727  }
728 }
729 
730 
731 void
732 NBNetBuilder::moveToOrigin(GeoConvHelper& geoConvHelper, bool lefthand) {
733  long before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Moving network to origin"));
734  Boundary boundary = geoConvHelper.getConvBoundary();
735  const double x = -boundary.xmin();
736  const double y = -(lefthand ? boundary.ymax() : boundary.ymin());
737  //if (lefthand) {
738  // y = boundary.ymax();
739  //}
740  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
741  (*i).second->reshiftPosition(x, y);
742  }
743  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
744  (*i).second->reshiftPosition(x, y);
745  }
746  for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) {
747  (*i).second->reshiftPosition(x, y);
748  }
749  for (const auto& stopIt : myPTStopCont.getStops()) {
750  stopIt.second->reshiftPosition(x, y);
751  }
752  geoConvHelper.moveConvertedBy(x, y);
753  PROGRESS_TIME_MESSAGE(before);
754 }
755 
756 
757 void
759  // mirror the network along the X-axis
760  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
761  (*i).second->mirrorX();
762  }
763  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
764  (*i).second->mirrorX();
765  }
766  for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) {
767  (*i).second->mirrorX();
768  }
769  for (const auto& stopIt : myPTStopCont.getStops()) {
770  stopIt.second->mirrorX();
771  }
772 }
773 
774 
775 bool
776 NBNetBuilder::transformCoordinate(Position& from, bool includeInBoundary, GeoConvHelper* from_srs) {
777  Position orig(from);
778  bool ok = true;
780  && GeoConvHelper::getLoaded().usingGeoProjection()
781  && from_srs != nullptr
782  && from_srs->usingGeoProjection()
783  && *from_srs != GeoConvHelper::getLoaded()) {
784  from_srs->cartesian2geo(from);
785  ok &= GeoConvHelper::getLoaded().x2cartesian(from, false);
786  }
787  if (from_srs == nullptr || !GeoConvHelper::getProcessing().usingGeoProjection()) {
788  // if getProcessing is not a geo-projection, assume it a cartesian transformation (i.e. shift)
789  ok &= GeoConvHelper::getProcessing().x2cartesian(from, includeInBoundary);
790 
791  if (from_srs == nullptr && GeoConvHelper::getProcessing().usingGeoProjection()
793  && GeoConvHelper::getLoaded().usingGeoProjection()) {
794  // apply geo patch to loaded geo-network (offset must match)
795  from = from + GeoConvHelper::getLoaded().getOffset();
796  }
797  }
798  if (ok) {
799  const NBHeightMapper& hm = NBHeightMapper::get();
800  if (hm.ready()) {
801  if (from_srs != nullptr && from_srs->usingGeoProjection()) {
802  from_srs->cartesian2geo(orig);
803  }
804  from.setz(hm.getZ(orig));
805  }
806  }
807  const double eps = 1e-6;
808  from.set(std::round(from.x() / eps) * eps, std::round(from.y() / eps) * eps, std::round(from.z() / eps) * eps);
809  return ok;
810 }
811 
812 
813 bool
814 NBNetBuilder::transformCoordinates(PositionVector& from, bool includeInBoundary, GeoConvHelper* from_srs) {
815  const double maxLength = OptionsCont::getOptions().getFloat("geometry.max-segment-length");
816  if (maxLength > 0 && from.size() > 1) {
817  // transformation to cartesian coordinates must happen before we can check segment length
818  PositionVector copy = from;
819  for (int i = 0; i < (int) from.size(); i++) {
820  transformCoordinate(copy[i], false);
821  }
822  addGeometrySegments(from, copy, maxLength);
823  }
824  bool ok = true;
825  for (int i = 0; i < (int) from.size(); i++) {
826  ok = ok && transformCoordinate(from[i], includeInBoundary, from_srs);
827  }
828  return ok;
829 }
830 
831 
832 int
833 NBNetBuilder::addGeometrySegments(PositionVector& from, const PositionVector& cartesian, const double maxLength) {
834  // check lengths and insert new points where needed (in the original
835  // coordinate system)
836  int inserted = 0;
837  for (int i = 0; i < (int)cartesian.size() - 1; i++) {
838  Position start = from[i + inserted];
839  Position end = from[i + inserted + 1];
840  double length = cartesian[i].distanceTo(cartesian[i + 1]);
841  const Position step = (end - start) * (maxLength / length);
842  int steps = 0;
843  while (length > maxLength) {
844  length -= maxLength;
845  steps++;
846  from.insert(from.begin() + i + inserted + 1, start + (step * steps));
847  inserted++;
848  }
849  }
850  return inserted;
851 }
852 
853 
854 bool
856  // see GNELoadThread::fillOptions
857  return OptionsCont::getOptions().exists("new");
858 }
859 
860 
861 /****************************************************************************/
#define DEG2RAD(x)
Definition: GeomHelper.h:35
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define WRITE_MESSAGEF(...)
Definition: MsgHandler.h:298
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:295
#define PROGRESS_BEGIN_TIME_MESSAGE(msg)
Definition: MsgHandler.h:301
#define TL(string)
Definition: MsgHandler.h:315
#define PROGRESS_TIME_MESSAGE(before)
Definition: MsgHandler.h:302
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:300
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:299
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_PEDESTRIAN
pedestrian
TrafficLightType
T MIN2(T a, T b)
Definition: StdDefs.h:76
T MAX2(T a, T b)
Definition: StdDefs.h:82
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:78
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:130
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:118
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:136
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:124
double getZRange() const
Returns the elevation range of the boundary (z-axis)
Definition: Boundary.cpp:166
static methods for processing the coordinates conversion for the current net
Definition: GeoConvHelper.h:53
static GeoConvHelper & getProcessing()
the coordinate transformation to use for input conversion and processing
Definition: GeoConvHelper.h:84
const Position getOffset() const
Returns the network offset.
void setConvBoundary(const Boundary &boundary)
sets the converted boundary
bool x2cartesian(Position &from, bool includeInBoundary=true)
Converts the given coordinate into a cartesian and optionally update myConvBoundary.
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
void moveConvertedBy(double x, double y)
Shifts the converted boundary by the given amounts.
static GeoConvHelper & getLoaded()
the coordinate transformation that was loaded fron an input file
Definition: GeoConvHelper.h:89
static int getNumLoaded()
Definition: GeoConvHelper.h:93
static void computeFinal(bool lefthand=false)
compute the location attributes which will be used for output based on the loaded location data,...
bool usingGeoProjection() const
Returns whether a transformation from geo to metric coordinates will be performed.
const Boundary & getConvBoundary() const
Returns the converted boundary.
std::map< std::string, NBDistrict * >::const_iterator begin() const
Returns the pointer to the begin of the stored districts.
std::map< std::string, NBDistrict * >::const_iterator end() const
Returns the pointer to the end of the stored districts.
std::map< std::string, NBEdge * >::const_iterator begin() const
Returns the pointer to the begin of the stored edges.
Definition: NBEdgeCont.h:171
void computeEdgeShapes(double smoothElevationThreshold=-1)
Computes the shapes of all edges stored in the container.
Definition: NBEdgeCont.cpp:992
const std::set< EdgeSet > getRoundabouts() const
Returns the determined roundabouts.
void computeEdge2Edges(bool noLeftMovers)
Computes for each edge the approached edges.
Definition: NBEdgeCont.cpp:852
int guessRoundabouts()
Determines which edges belong to roundabouts and increases their priority.
void sortOutgoingLanesConnections()
Sorts all lanes of all edges within the container by their direction.
Definition: NBEdgeCont.cpp:844
void appendRailwayTurnarounds(const NBPTStopCont &sc)
Appends turnarounds to all bidiRail edges with stops.
Definition: NBEdgeCont.cpp:970
std::map< std::string, NBEdge * >::const_iterator end() const
Returns the pointer to the end of the stored edges.
Definition: NBEdgeCont.h:178
void updateAllChangeRestrictions(SVCPermissions ignoring)
modify all restrictions on lane changing for edges and connections
void recheckPostProcessConnections()
Try to set any stored connections.
void recheckLanes()
Rechecks whether all lanes have a successor for each of the stored edges.
Definition: NBEdgeCont.cpp:868
void checkGeometries(const double maxAngle, bool fixAngle, const double minRadius, bool fix, bool fixRailways, bool silent=false)
Definition: NBEdgeCont.cpp:822
void reduceGeometries(const double minDist)
Definition: NBEdgeCont.cpp:814
void cleanupRoundabouts()
void splitGeometry(NBDistrictCont &dc, NBNodeCont &nc)
Splits edges into multiple if they have a complex geometry.
Definition: NBEdgeCont.cpp:787
void computeLanes2Edges()
Computes for each edge which lanes approach the next edges.
Definition: NBEdgeCont.cpp:860
int getNumEdgeSplits() const
Returns the number of edge splits.
Definition: NBEdgeCont.h:311
int joinTramEdges(NBDistrictCont &dc, NBPTStopCont &sc, NBPTLineCont &lc, double maxDist)
join tram edges into adjacent lanes
int removeUnwishedEdges(NBDistrictCont &dc)
Removes unwished edges (not in keep-edges)
Definition: NBEdgeCont.cpp:769
void generateStreetSigns()
assigns street signs to edges based on toNode types
bool hasGuessedRoundabouts() const
check if there is guessed roundabouts
Definition: NBEdgeCont.h:547
void computeAngles()
compute all edge angles
void guessOpposites()
Sets opposite lane information for geometrically close edges.
void markRoundabouts()
mark edge priorities and prohibit turn-arounds for all roundabout edges
void applyOptions(OptionsCont &oc)
Initialises the storage by applying given options.
Definition: NBEdgeCont.cpp:78
int joinLanes(SVCPermissions perms)
join adjacent lanes with the given permissions
void checkOverlap(double threshold, double zThreshold) const
check whether edges overlap
int guessSpecialLanes(SUMOVehicleClass svc, double width, double minSpeed, double maxSpeed, bool fromPermissions, const std::string &excludeOpt, NBTrafficLightLogicCont &tlc)
add sidwalks to edges within the given limits or permissions and return the number of edges affected
void appendTurnarounds(bool noTLSControlled, bool noFringe, bool onlyDeadends, bool onlyTurnlane, bool noGeometryLike)
Appends turnarounds to all edges stored in the container.
Definition: NBEdgeCont.cpp:954
void computeLaneShapes()
Computes the shapes of all lanes of all edges stored in the container.
void fixSplitCustomLength()
adapt custom lengths of split edges to account for intersection size
int remapIDs(bool numericaIDs, bool reservedIDs, const std::string &prefix, NBPTStopCont &sc)
remap node IDs accoring to options –numerical-ids and –reserved-ids
int removeLanesByWidth(NBDistrictCont &dc, const double minWidth)
int removeEdgesBySpeed(NBDistrictCont &dc)
return number of edges removed
void checkGrade(double threshold) const
check whether edges are to steep
int removeEdgesByPermissions(NBDistrictCont &dc)
The representation of a single edge during network building.
Definition: NBEdge.h:92
double getLaneSpeed(int lane) const
get lane speed
Definition: NBEdge.cpp:2198
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4283
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:516
static void setDefaultConnectionLength(double length)
Definition: NBEdge.h:386
static void computeEdgePriorities(NBNodeCont &nc)
Computes edge priorities within a node.
Set z-values for all network positions based on data from a height map.
double getZ(const Position &geo) const
returns height for the given geo coordinate (WGS84)
static const NBHeightMapper & get()
return the singleton instance (maybe 0)
bool ready() const
returns whether the NBHeightMapper has data
static bool transformCoordinates(PositionVector &from, bool includeInBoundary=true, GeoConvHelper *from_srs=nullptr)
void mirrorX()
mirror the network along the X-axis
NBNetBuilder()
Constructor.
NBTrafficLightLogicCont myTLLCont
The used container for traffic light logics.
Definition: NBNetBuilder.h:237
void moveToOrigin(GeoConvHelper &geoConvHelper, bool lefthand)
shift network so its lower left corner is at 0,0
bool myNetworkHaveCrossings
flag to indicate that network has crossings
Definition: NBNetBuilder.h:254
NBDistrictCont myDistrictCont
The used container for districts.
Definition: NBNetBuilder.h:240
static int addGeometrySegments(PositionVector &from, const PositionVector &cartesian, const double maxLength)
insertion geometry points to ensure maximum segment length between points
NBPTLineCont myPTLineCont
The used container for pt stops.
Definition: NBNetBuilder.h:246
NBEdgeCont myEdgeCont
The used container for edges.
Definition: NBNetBuilder.h:234
NBParkingCont myParkingCont
Definition: NBNetBuilder.h:248
~NBNetBuilder()
Destructor.
NBTypeCont myTypeCont
The used container for street types.
Definition: NBNetBuilder.h:231
NBPTStopCont myPTStopCont
The used container for pt stops.
Definition: NBNetBuilder.h:243
void applyOptions(OptionsCont &oc)
Initialises the storage by applying given options.
static bool transformCoordinate(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=nullptr)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
void compute(OptionsCont &oc, const std::set< std::string > &explicitTurnarounds=std::set< std::string >(), bool mayAddOrRemove=true)
Performs the network building steps.
NBNodeCont myNodeCont
The used container for nodes.
Definition: NBNetBuilder.h:228
static bool runningNetedit()
whether netbuilding takes place in the context of netedit
std::map< std::string, NBNode * >::const_iterator begin() const
Returns the pointer to the begin of the stored nodes.
Definition: NBNodeCont.h:113
void avoidOverlap()
fix overlap
Definition: NBNodeCont.cpp:538
int removeRailComponents(NBDistrictCont &dc, NBEdgeCont &ec, NBPTStopCont &sc)
Definition: NBNodeCont.cpp:417
void recheckGuessedTLS(NBTrafficLightLogicCont &tlc)
recheck myGuessedTLS after node logics are computed
void computeKeepClear()
compute keepClear status for all connections
int removeSelfLoops(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tc)
Removes self-loop edges (edges where the source and the destination node are the same)
Definition: NBNodeCont.cpp:175
void addJoinExclusion(const std::vector< std::string > &ids)
Definition: NBNodeCont.cpp:691
int joinLoadedClusters(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc)
Joins loaded junction clusters (see NIXMLNodesHandler)
Definition: NBNodeCont.cpp:752
int remapIDs(bool numericaIDs, bool reservedIDs, const std::string &prefix, NBTrafficLightLogicCont &tlc)
remap node IDs according to options –numerical-ids and –reserved-ids
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:116
void joinTLS(NBTrafficLightLogicCont &tlc, double maxdist)
Builds clusters of tls-controlled junctions and joins the control if possible.
int removeUnwishedNodes(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc, NBPTStopCont &sc, NBPTLineCont &lc, NBParkingCont &pc, bool removeGeometryNodes)
Removes "unwished" nodes.
Definition: NBNodeCont.cpp:459
int removeComponents(NBDistrictCont &dc, NBEdgeCont &ec, const int numKeep, bool hasPTStops)
Checks the network for weak connectivity and removes all but the largest components....
Definition: NBNodeCont.cpp:330
void computeLogics2(const NBEdgeCont &ec, OptionsCont &oc)
compute right-of-way logic for all lane-to-lane connections
void joinSimilarEdges(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc, bool removeDuplicates)
Joins edges connecting the same nodes.
Definition: NBNodeCont.cpp:188
int removeIsolatedRoads(NBDistrictCont &dc, NBEdgeCont &ec)
Removes sequences of edges that are not connected with a junction. Simple roads without junctions som...
Definition: NBNodeCont.cpp:239
void setAsTLControlled(NBNode *node, NBTrafficLightLogicCont &tlc, TrafficLightType type, std::string id="")
Sets the given node as being controlled by a tls.
void computeLogics(const NBEdgeCont &ec)
build the list of outgoing edges and lanes
std::map< std::string, NBNode * >::const_iterator end() const
Returns the pointer to the end of the stored nodes.
Definition: NBNodeCont.h:118
void computeNodeShapes(double mismatchThreshold=-1)
Compute the junction shape for this node.
void guessTLs(OptionsCont &oc, NBTrafficLightLogicCont &tlc)
Guesses which junctions or junction clusters shall be controlled by tls.
int guessFringe()
guess and mark fringe nodes
int joinJunctions(double maxDist, NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc, NBPTStopCont &sc)
Joins junctions that are very close together.
Definition: NBNodeCont.cpp:777
void computeLanes2Lanes()
divides the incoming lanes on outgoing lanes
int joinSameJunctions(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc)
Joins junctions with the same coordinates regardless of topology.
Definition: NBNodeCont.cpp:925
bool resetNodeShapes()
reset all node shapes
Represents a single node (junction) during network building.
Definition: NBNode.h:66
static void computeNodeTypes(NBNodeCont &nc, NBTrafficLightLogicCont &tlc)
Computes node types.
static void validateRailCrossings(NBNodeCont &nc, NBTrafficLightLogicCont &tlc)
Checks rail_crossing for validity.
static void sortNodesEdges(NBNodeCont &nc, bool useNodeShape=false)
Sorts a node's edges clockwise regarding driving direction.
void fixPermissions()
ensure that all turn lanes have sufficient permissions
void process(NBEdgeCont &ec, NBPTStopCont &sc, bool routeOnly=false)
std::set< std::string > & getServedPTStops()
void removeInvalidEdges(const NBEdgeCont &ec)
filter out edges that were removed due to –geometry.remove
void fixBidiStops(const NBEdgeCont &ec)
select the correct stop on superposed rail edges
const std::map< std::string, NBPTLine * > & getLines() const
Definition: NBPTLineCont.h:43
int cleanupDeleted(NBEdgeCont &cont)
remove stops on non existing (removed) edges
void postprocess(std::set< std::string > &usedStops)
const std::map< std::string, std::shared_ptr< NBPTStop > > & getStops() const
Returns an unmodifiable reference to the stored pt stops.
Definition: NBPTStopCont.h:62
void localizePTStops(NBEdgeCont &cont)
void alignIdSigns()
void assignEdgeForFloatingStops(NBEdgeCont &cont, double maxRadius)
void findAccessEdgesForRailStops(NBEdgeCont &cont, double maxRadius, int maxCount, double accessFactor)
int generateBidiStops(NBEdgeCont &cont)
duplicate stops for superposed rail edges and return the number of generated stops
void assignLanes(NBEdgeCont &cont)
static int straigthenCorrdidor(NBEdgeCont &ec, double maxAngle)
static int guessRailSignals(NBEdgeCont &ec, NBPTStopCont &sc)
static int repairTopology(NBEdgeCont &ec, NBPTStopCont &sc, NBPTLineCont &lc)
static void extendDirectionPriority(NBEdgeCont &ec, bool fromUniDir)
static void analyzeTopology(NBEdgeCont &ec)
static int makeAllBidi(NBEdgeCont &ec)
void computeRamps(NBNetBuilder &nb, OptionsCont &oc, bool mayAddOrRemove)
static void reportWarnings()
reports warnings if any occurred
Definition: NBRequest.cpp:1108
The base class for traffic light logic definitions.
static const std::string OSM_DIRECTION
processing parameter for rail signal edges and nodes
void applyOptions(OptionsCont &oc)
Initialises the storage by applying given options.
void setOpenDriveSignalParameters()
set OpenDRIVE signal reference parameters after all link indices are known
bool computeSingleLogic(OptionsCont &oc, NBTrafficLightDefinition *def)
Computes a specific traffic light logic (using by netedit)
void applyOpenDriveControllers(OptionsCont &oc)
post processing of signal programs to group tl indices according to OpenDrive controllers (signal gro...
std::pair< int, int > computeLogics(OptionsCont &oc)
Computes the traffic light logics using the stored definitions and stores the results.
void setTLControllingInformation(const NBEdgeCont &ec, const NBNodeCont &nc)
Informs the edges about being controlled by a tls.
static void computeTurnDirections(NBNodeCont &nc, bool warn=true)
Computes turnaround destinations for all edges (if exist)
void setEdgeTypeDefaults(int defaultNumLanes, double defaultLaneWidth, double defaultSpeed, double defaultFriction, int defaultPriority, SVCPermissions defaultPermissions, LaneSpreadFunction defaultSpreadType)
Sets the default values.
Definition: NBTypeCont.cpp:185
A storage for options typed value containers)
Definition: OptionsCont.h:89
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
bool exists(const std::string &name) const
Returns the information whether the named option is known.
bool set(const std::string &name, const std::string &value, const bool append=false)
Sets the given value for the named option.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const StringVector & getStringVector(const std::string &name) const
Returns the list of string-value of the named option (only for Option_StringVector)
void resetWritable()
Resets all options to be writeable.
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
void set(double x, double y)
set positions x and y
Definition: Position.h:85
double x() const
Returns the x-position.
Definition: Position.h:55
void setz(double z)
set position z
Definition: Position.h:80
double z() const
Returns the z-position.
Definition: Position.h:65
double y() const
Returns the y-position.
Definition: Position.h:60
A list of positions.
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
lane spread functions
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
T get(const std::string &str) const
static long getCurrentMillis()
Returns the current time in milliseconds.
Definition: SysUtils.cpp:44