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  // Processing pt stops and lines
133  if (!myPTStopCont.getStops().empty()) {
134  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Processing public transport stops"));
135  if (!(oc.exists("ptline-output") && oc.isSet("ptline-output"))
136  && !oc.getBool("ptstop-output.no-bidi")) {
138  }
141  PROGRESS_TIME_MESSAGE(before);
142  }
143  if (mayAddOrRemove && oc.exists("keep-edges.components") && oc.getInt("keep-edges.components") > 0) {
144  // post process rail components unless they have stops
146  }
147  // removal is done, clean up roundabouts
148  if (numRemovedEdges > 0) {
150  }
151 
152  if (!myPTLineCont.getLines().empty()) {
153  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Revising public transport stops based on pt lines"));
155  PROGRESS_TIME_MESSAGE(before);
156  }
157 
158  if (oc.exists("ptline-clean-up") && oc.getBool("ptline-clean-up")) {
159  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Cleaning up public transport stops that are not served by any line"));
161  PROGRESS_TIME_MESSAGE(before);
162  } else {
163  int numDeletedStops = myPTStopCont.cleanupDeleted(myEdgeCont);
164  if (numDeletedStops > 0) {
165  WRITE_WARNINGF(TL("Removed % pt stops because they could not be assigned to the network"), toString(numDeletedStops));
166  }
167  }
168 
169  if (!myPTStopCont.getStops().empty() && !oc.getBool("ptstop-output.no-bidi")) {
170  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Align pt stop id signs with corresponding edge id signs"));
172  PROGRESS_TIME_MESSAGE(before);
173  }
174  // analyze and fix railway topology
175  int numAddedBidi = 0;
176  if (oc.exists("railway.topology.all-bidi") && oc.getBool("railway.topology.all-bidi")) {
179  } else if (oc.exists("railway.topology.repair") && oc.getBool("railway.topology.repair")) {
180  // correct railway angles for angle-based connectivity heuristic
182  oc.getFloat("geometry.min-radius"), false,
183  oc.getBool("geometry.min-radius.fix.railways"), true);
186  }
188  if (numAddedBidi > 0) {
189  // update routes
191  }
192  if (oc.exists("railway.topology.direction-priority") && oc.getBool("railway.topology.direction-priority")) {
193  NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
195  } else if (oc.exists("railway.topology.extend-priority") && oc.getBool("railway.topology.extend-priority")) {
196  NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
198  }
199  if (oc.exists("railway.topology.output") && oc.isSet("railway.topology.output")) {
200  NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
202  }
203 
204 
205  if (mayAddOrRemove && oc.exists("edges.join-tram-dist") && oc.getFloat("edges.join-tram-dist") >= 0) {
206  // should come before joining junctions
207  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining tram edges"));
208  int numJoinedTramEdges = myEdgeCont.joinTramEdges(myDistrictCont, myPTStopCont, myPTLineCont, oc.getFloat("edges.join-tram-dist"));
209  PROGRESS_TIME_MESSAGE(before);
210  if (numJoinedTramEdges > 0) {
211  WRITE_MESSAGEF(TL(" Joined % tram edges into roads."), toString(numJoinedTramEdges));
212  }
213  }
214  if (oc.getBool("junctions.join")
215  || (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))
216  || oc.getBool("tls.guess.joining")
217  || (oc.exists("tls.guess-signals") && oc.getBool("tls.guess-signals"))) {
218  // preliminary geometry computations to determine the length of edges
219  // This depends on turning directions and sorting of edge list
220  // in case junctions are joined geometry computations have to be repeated
221  // preliminary roundabout computations to avoid damaging roundabouts via junctions.join or ramps.guess
227  if (oc.getBool("roundabouts.guess")) {
229  }
230  const std::set<EdgeSet>& roundabouts = myEdgeCont.getRoundabouts();
231  for (std::set<EdgeSet>::const_iterator it_round = roundabouts.begin();
232  it_round != roundabouts.end(); ++it_round) {
233  std::vector<std::string> nodeIDs;
234  for (EdgeSet::const_iterator it_edge = it_round->begin(); it_edge != it_round->end(); ++it_edge) {
235  nodeIDs.push_back((*it_edge)->getToNode()->getID());
236  }
237  myNodeCont.addJoinExclusion(nodeIDs);
238  }
240  } else if (myEdgeCont.hasGuessedRoundabouts() && oc.getBool("roundabouts.guess")) {
242  }
243  // join junctions (may create new "geometry"-nodes so it needs to come before removing these
244  if (mayAddOrRemove && oc.exists("junctions.join-exclude") && oc.isSet("junctions.join-exclude")) {
245  myNodeCont.addJoinExclusion(oc.getStringVector("junctions.join-exclude"));
246  }
248  if (mayAddOrRemove && oc.getBool("junctions.join")) {
249  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining junction clusters"));
250  numJoined += myNodeCont.joinJunctions(oc.getFloat("junctions.join-dist"), myDistrictCont, myEdgeCont, myTLLCont, myPTStopCont);
251  PROGRESS_TIME_MESSAGE(before);
252  }
253  if (numJoined > 0) {
254  WRITE_MESSAGEF(TL(" Joined % junction cluster(s)."), toString(numJoined));
255  }
256  if (mayAddOrRemove && oc.exists("junctions.join-same") && oc.getBool("junctions.join-same")) {
257  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining junctions with identical coordinates"));
259  PROGRESS_TIME_MESSAGE(before);
260  if (numJoined2 > 0) {
261  WRITE_MESSAGEF(TL(" Joined % junctions."), toString(numJoined2));
262  }
263  }
264  //
265  if (mayAddOrRemove && oc.exists("join-lanes") && oc.getBool("join-lanes")) {
266  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining lanes"));
268  PROGRESS_TIME_MESSAGE(before);
269  WRITE_MESSAGEF(TL(" Joined lanes on % edges."), toString(num));
270  }
271  //
272  if (mayAddOrRemove) {
273  const bool removeGeometryNodes = oc.exists("geometry.remove") && oc.getBool("geometry.remove");
274  before = PROGRESS_BEGIN_TIME_MESSAGE("Removing empty nodes" + std::string(removeGeometryNodes ? " and geometry nodes" : ""));
275  // removeUnwishedNodes needs turnDirections. @todo: try to call this less often
278  PROGRESS_TIME_MESSAGE(before);
279  WRITE_MESSAGEF(TL(" % nodes removed."), toString(numRemoved));
280  }
281 
282  // MOVE TO ORIGIN
283  // compute new boundary after network modifications have taken place
284  Boundary boundary;
285  for (std::map<std::string, NBNode*>::const_iterator it = myNodeCont.begin(); it != myNodeCont.end(); ++it) {
286  boundary.add(it->second->getPosition());
287  }
288  for (std::map<std::string, NBEdge*>::const_iterator it = myEdgeCont.begin(); it != myEdgeCont.end(); ++it) {
289  boundary.add(it->second->getGeometry().getBoxBoundary());
290  }
291  geoConvHelper.setConvBoundary(boundary);
292 
293  if (!oc.getBool("offset.disable-normalization") && oc.isDefault("offset.x") && oc.isDefault("offset.y")) {
294  moveToOrigin(geoConvHelper, lefthand);
295  }
296  geoConvHelper.computeFinal(lefthand); // information needed for location element fixed at this point
297 
298  if (oc.exists("geometry.min-dist") && !oc.isDefault("geometry.min-dist")) {
299  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Reducing geometries"));
300  myEdgeCont.reduceGeometries(oc.getFloat("geometry.min-dist"));
301  PROGRESS_TIME_MESSAGE(before);
302  }
303  // @note: removing geometry can create similar edges so joinSimilarEdges must come afterwards
304  // @note: likewise splitting can destroy similarities so joinSimilarEdges must come before
305  if (mayAddOrRemove && oc.getBool("edges.join")) {
306  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining similar edges"));
307  const bool removeDuplicates = oc.exists("junctions.join-same") && oc.getBool("junctions.join-same");
309  // now we may have new chances to remove geometry if wished
310  if (oc.exists("geometry.remove") && oc.getBool("geometry.remove")) {
312  }
313  PROGRESS_TIME_MESSAGE(before);
314  }
315  if (oc.getBool("opposites.guess")) {
316  PROGRESS_BEGIN_MESSAGE(TL("guessing opposite direction edges"));
319  }
320  //
321  if (mayAddOrRemove && oc.exists("geometry.split") && oc.getBool("geometry.split")) {
322  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Splitting geometry edges"));
324  // newly split junctions might also be joinable
325  PROGRESS_TIME_MESSAGE(before);
326  if (oc.getBool("junctions.join-same")) {
328  if (numJoined3 > 0) {
329  WRITE_MESSAGEF(TL(" Joined % junctions after splitting geometry."), toString(numJoined3));
330  }
331  }
332  }
333  // turning direction
334  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing turning directions"));
336  PROGRESS_TIME_MESSAGE(before);
337  // correct edge geometries to avoid overlap
338  if (oc.exists("geometry.avoid-overlap") && oc.getBool("geometry.avoid-overlap")) {
340  }
341 
342  // GUESS TLS POSITIONS
343  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Assigning nodes to traffic lights"));
344  if (oc.isSet("tls.set")) {
345  std::vector<std::string> tlControlledNodes = oc.getStringVector("tls.set");
347  for (std::vector<std::string>::const_iterator i = tlControlledNodes.begin(); i != tlControlledNodes.end(); ++i) {
348  NBNode* node = myNodeCont.retrieve(*i);
349  if (node == nullptr) {
350  WRITE_WARNING("Building a tl-logic for junction '" + *i + "' is not possible." + "\n The junction '" + *i + "' is not known.");
351  } else {
353  }
354  }
355  }
357  PROGRESS_TIME_MESSAGE(before);
358 
359  // guess ramps (after guessing tls because ramps should not be build at traffic lights)
360  const bool modifyRamps = mayAddOrRemove && (
361  (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))
362  || (oc.exists("ramps.set") && oc.isSet("ramps.set")));
363  if (modifyRamps || (oc.exists("ramps.guess-acceleration-lanes") && oc.getBool("ramps.guess-acceleration-lanes"))) {
364  before = SysUtils::getCurrentMillis();
365  if (modifyRamps) {
366  PROGRESS_BEGIN_MESSAGE(TL("Guessing and setting on-/off-ramps"));
367  }
369  NBRampsComputer rc;
370  rc.computeRamps(*this, oc, mayAddOrRemove);
371 
372  if (modifyRamps) {
373  PROGRESS_TIME_MESSAGE(before);
374  }
375  }
376  // guess bike lanes
377  if (mayAddOrRemove && ((oc.getBool("bikelanes.guess") || oc.getBool("bikelanes.guess.from-permissions")))) {
378  const int bikelanes = myEdgeCont.guessSpecialLanes(SVC_BICYCLE, oc.getFloat("default.bikelane-width"),
379  oc.getFloat("bikelanes.guess.min-speed"),
380  oc.getFloat("bikelanes.guess.max-speed"),
381  oc.getBool("bikelanes.guess.from-permissions"),
382  "bikelanes.guess.exclude",
383  myTLLCont);
384  WRITE_MESSAGEF(TL("Guessed % bike lanes."), toString(bikelanes));
385  }
386 
387  // guess sidewalks
388  if (mayAddOrRemove && ((oc.getBool("sidewalks.guess") || oc.getBool("sidewalks.guess.from-permissions")))) {
389  const int sidewalks = myEdgeCont.guessSpecialLanes(SVC_PEDESTRIAN, oc.getFloat("default.sidewalk-width"),
390  oc.getFloat("sidewalks.guess.min-speed"),
391  oc.getFloat("sidewalks.guess.max-speed"),
392  oc.getBool("sidewalks.guess.from-permissions"),
393  "sidewalks.guess.exclude",
394  myTLLCont);
395  WRITE_MESSAGEF(TL("Guessed % sidewalks."), toString(sidewalks));
396  }
397  // check whether any not previously setable connections may be set now
399 
400  // remap ids if wished
401  if (mayAddOrRemove) {
402  int numChangedEdges = myEdgeCont.remapIDs(oc.getBool("numerical-ids"), oc.isSet("reserved-ids"), oc.getString("prefix"), myPTStopCont);
403  int numChangedNodes = myNodeCont.remapIDs(oc.getBool("numerical-ids"), oc.isSet("reserved-ids"), oc.getString("prefix"), myTLLCont);
404  if (numChangedEdges + numChangedNodes > 0) {
405  WRITE_MESSAGEF(TL("Remapped % edge IDs and % node IDs."), toString(numChangedEdges), toString(numChangedNodes));
406  }
407  }
408 
409  //
410  if (oc.exists("geometry.max-angle")) {
412  DEG2RAD(oc.getFloat("geometry.max-angle")),
413  oc.getFloat("geometry.min-radius"),
414  oc.getBool("geometry.min-radius.fix"),
415  oc.getBool("geometry.min-radius.fix.railways"));
416  }
417 
418  // GEOMETRY COMPUTATION
419  //
420  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Sorting nodes' edges"));
422  PROGRESS_TIME_MESSAGE(before);
424  //
425  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing node shapes"));
426  if (oc.exists("geometry.junction-mismatch-threshold")) {
427  myNodeCont.computeNodeShapes(oc.getFloat("geometry.junction-mismatch-threshold"));
428  } else {
430  }
431  PROGRESS_TIME_MESSAGE(before);
432  //
433  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing edge shapes"));
434  myEdgeCont.computeEdgeShapes(oc.getBool("geometry.max-grade.fix") ? oc.getFloat("geometry.max-grade") / 100 : -1);
435  PROGRESS_TIME_MESSAGE(before);
436  // resort edges based on the node and edge shapes
439 
440  // APPLY SPEED MODIFICATIONS
441  if (oc.exists("speed.offset")) {
442  const double speedOffset = oc.getFloat("speed.offset");
443  const double speedFactor = oc.getFloat("speed.factor");
444  const double speedMin = oc.getFloat("speed.minimum");
445  if (speedOffset != 0 || speedFactor != 1 || speedMin > 0) {
446  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Applying speed modifications"));
447  for (const auto& it : myEdgeCont) {
448  NBEdge* const e = it.second;
449  for (int i = 0; i < e->getNumLanes(); i++) {
450  e->setSpeed(i, MAX2(e->getLaneSpeed(i) * speedFactor + speedOffset, speedMin));
451  }
452  }
453  PROGRESS_TIME_MESSAGE(before);
454  }
455  }
456 
457  // CONNECTIONS COMPUTATION
458  //
459  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing node types"));
461  PROGRESS_TIME_MESSAGE(before);
462  //
463  myNetworkHaveCrossings = oc.getBool("walkingareas");
464  if (mayAddOrRemove && oc.getBool("crossings.guess")) {
465  myNetworkHaveCrossings = true;
466  int crossings = 0;
467  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
468  crossings += (*i).second->guessCrossings();
469  }
470  WRITE_MESSAGEF(TL("Guessed % pedestrian crossings."), toString(crossings));
471  }
472  if (!myNetworkHaveCrossings) {
473  bool haveValidCrossings = false;
474  // recheck whether we had crossings in the input
475  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
476  if (i->second->getCrossings().size() > 0) {
477  myNetworkHaveCrossings = true;
478  haveValidCrossings = true;
479  break;
480  } else if (i->second->getCrossingsIncludingInvalid().size() > 0) {
481  myNetworkHaveCrossings = true;
482  }
483  }
484  if (myNetworkHaveCrossings && !haveValidCrossings) {
485  // initial crossings removed or invalidated, keep walkingareas
486  oc.resetWritable();
487  oc.set("walkingareas", "true");
488  }
489  }
490 
491  if (!mayAddOrRemove && myNetworkHaveCrossings) {
492  // crossings added via netedit
493  oc.resetWritable();
494  oc.set("no-internal-links", "false");
495  }
496 
497  //
498  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing priorities"));
500  PROGRESS_TIME_MESSAGE(before);
501  //
502  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing approached edges"));
503  myEdgeCont.computeEdge2Edges(oc.getBool("no-left-connections"));
504  PROGRESS_TIME_MESSAGE(before);
505  //
506  if (oc.getBool("roundabouts.guess")) {
507  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Guessing and setting roundabouts"));
508  const int numGuessed = myEdgeCont.guessRoundabouts();
509  if (numGuessed > 0) {
510  WRITE_MESSAGEF(TL(" Guessed % roundabout(s)."), toString(numGuessed));
511  }
512  PROGRESS_TIME_MESSAGE(before);
513  }
515  //
516  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing approaching lanes"));
518  PROGRESS_TIME_MESSAGE(before);
519  //
520  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Dividing of lanes on approached lanes"));
523  PROGRESS_TIME_MESSAGE(before);
524  //
525  if (oc.getBool("fringe.guess")) {
526  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Guessing Network fringe"));
527  const int numGuessed = myNodeCont.guessFringe();
528  if (numGuessed > 0) {
529  WRITE_MESSAGEF(TL(" Guessed % fringe nodes."), toString(numGuessed));
530  }
531  PROGRESS_TIME_MESSAGE(before);
532  }
533  //
534  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Processing turnarounds"));
535  if (!oc.getBool("no-turnarounds")) {
537  oc.getBool("no-turnarounds.tls"),
538  oc.getBool("no-turnarounds.fringe"),
539  oc.getBool("no-turnarounds.except-deadend"),
540  oc.getBool("no-turnarounds.except-turnlane"),
541  oc.getBool("no-turnarounds.geometry"));
542  } else {
543  myEdgeCont.appendTurnarounds(explicitTurnarounds, oc.getBool("no-turnarounds.tls"));
544  }
545  if (oc.exists("railway.topology.repair.stop-turn") && oc.getBool("railway.topology.repair.stop-turn")
546  && myPTStopCont.getStops().size() > 0) {
547  // allow direction reversal at all bidi-edges with stops
549  }
550  PROGRESS_TIME_MESSAGE(before);
551  //
552  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Rechecking of lane endings"));
554  PROGRESS_TIME_MESSAGE(before);
555 
556  if (myNetworkHaveCrossings && !oc.getBool("no-internal-links")) {
557  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
558  i->second->buildCrossingsAndWalkingAreas();
559  }
560  } else {
561  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
562  // needed by netedit if the last crossings was deleted from the network
563  // and walkingareas have been invalidated since the last call to compute()
564  i->second->discardWalkingareas();
565  }
566  if (oc.getBool("no-internal-links")) {
567  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
568  i->second->discardAllCrossings(false);
569  }
570  }
571  }
572  // join traffic lights (after building connections)
573  if (oc.getBool("tls.join")) {
574  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining traffic light nodes"));
575  myNodeCont.joinTLS(myTLLCont, oc.getFloat("tls.join-dist"));
576  PROGRESS_TIME_MESSAGE(before);
577  }
578 
579  // COMPUTING RIGHT-OF-WAY AND TRAFFIC LIGHT PROGRAMS
580  //
581  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing traffic light control information"));
583  if (oc.exists("opendrive-files") && oc.isSet("opendrive-files")) {
585  }
586  PROGRESS_TIME_MESSAGE(before);
587  //
588  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing node logics"));
590  PROGRESS_TIME_MESSAGE(before);
591 
592  //
593  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing traffic light logics"));
594  std::pair<int, int> numbers = myTLLCont.computeLogics(oc);
595  PROGRESS_TIME_MESSAGE(before);
596  std::string progCount = "";
597  if (numbers.first != numbers.second) {
598  progCount = "(" + toString(numbers.second) + " programs) ";
599  }
600  WRITE_MESSAGEF(TL(" % traffic light(s) %computed."), toString(numbers.first), progCount);
601  if (oc.exists("opendrive-files") && oc.isSet("opendrive-files") && oc.getBool("opendrive.signal-groups")) {
603  }
604 
605  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
606  (*i).second->sortOutgoingConnectionsByIndex();
607  }
608  // FINISHING INNER EDGES
609  std::set<NBTrafficLightDefinition*> largeNodeTLS;
610  if (!oc.getBool("no-internal-links")) {
611  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Building inner edges"));
612  // walking areas shall only be built if crossings are wished as well
613  for (const auto& item : myNodeCont) {
614  if (item.second->buildInnerEdges() > NBTrafficLightDefinition::MIN_YELLOW_SECONDS) {
615  const std::set<NBTrafficLightDefinition*>& tlDefs = item.second->getControllingTLS();
616  largeNodeTLS.insert(tlDefs.begin(), tlDefs.end());
617  }
618  }
619  PROGRESS_TIME_MESSAGE(before);
620  }
621  // PATCH NODE SHAPES
622  if (oc.getFloat("junctions.scurve-stretch") > 0) {
623  // @note: nodes have collected correction hints in buildInnerEdges()
624  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("stretching junctions to smooth geometries"));
627  myEdgeCont.computeEdgeShapes(oc.getBool("geometry.max-grade.fix") ? oc.getFloat("geometry.max-grade") / 100 : -1);
628  for (const auto& item : myNodeCont) {
629  item.second->buildInnerEdges();
630  }
631  PROGRESS_TIME_MESSAGE(before);
632  }
633  if (myEdgeCont.getNumEdgeSplits() > 0 && !oc.getBool("no-internal-links")) {
634  // edges with custom lengths were split, this has to take into account
635  // internal edge lengths (after geometry computation)
637  }
638  // recheck phases for large junctions
639  for (NBTrafficLightDefinition* def : largeNodeTLS) {
640  myTLLCont.computeSingleLogic(oc, def);
641  }
642  // compute lane-to-lane node logics (require traffic lights and inner edges to be done)
644 
645  // remove guessed traffic lights at junctions without conflicts (requires computeLogics2)
647 
648  // compute keepClear status (requires computeLogics2)
650 
651  //
652  if (oc.isSet("street-sign-output")) {
653  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Generating street signs"));
655  PROGRESS_TIME_MESSAGE(before);
656  }
657 
658 
659  if (lefthand != oc.getBool("flip-y-axis")) {
660  mirrorX();
661  }
662 
663  if (oc.exists("geometry.check-overlap") && oc.getFloat("geometry.check-overlap") > 0) {
664  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Checking overlapping edges"));
665  myEdgeCont.checkOverlap(oc.getFloat("geometry.check-overlap"), oc.getFloat("geometry.check-overlap.vertical-threshold"));
666  PROGRESS_TIME_MESSAGE(before);
667  }
668  if (geoConvHelper.getConvBoundary().getZRange() > 0 && oc.getFloat("geometry.max-grade") > 0) {
669  before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Checking edge grade"));
670  // user input is in %
671  myEdgeCont.checkGrade(oc.getFloat("geometry.max-grade") / 100);
672  PROGRESS_TIME_MESSAGE(before);
673  }
674 
675  // find accesses for pt rail stops and add bidi-stops
676  if (!myPTStopCont.getStops().empty()) {
677  // re-adapt stop lanes after adding special lanes and cutting edge shapes at junction
679  before = SysUtils::getCurrentMillis();
680  int numBidiStops = 0;
681  if (!oc.getBool("ptstop-output.no-bidi")) {
682  numBidiStops = myPTStopCont.generateBidiStops(myEdgeCont);
683  }
684  PROGRESS_BEGIN_MESSAGE(TL("Find accesses for pt rail stops"));
685  double maxRadius = oc.getFloat("railway.access-distance");
686  double accessFactor = oc.getFloat("railway.access-factor");
687  int maxCount = oc.getInt("railway.max-accesses");
688  myPTStopCont.findAccessEdgesForRailStops(myEdgeCont, maxRadius, maxCount, accessFactor);
689  PROGRESS_TIME_MESSAGE(before);
690  if (numBidiStops > 0) {
692  }
693  }
695  // ensure that all turning lanes have sufficient permissions
697 
698  if (oc.exists("ignore-change-restrictions") && !oc.isDefault("ignore-change-restrictions")) {
699  SVCPermissions ignoring = parseVehicleClasses(oc.getStringVector("ignore-change-restrictions"));
701  }
702 
704  // report on very large networks
705  if (MAX2(geoConvHelper.getConvBoundary().xmax(), geoConvHelper.getConvBoundary().ymax()) > 1000000 ||
706  MIN2(geoConvHelper.getConvBoundary().xmin(), geoConvHelper.getConvBoundary().ymin()) < -1000000) {
707  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"));
708  }
709 
710  // clean up OSM processing params
711  if (oc.exists("osm-files") && oc.isSet("osm-files")) {
712  for (auto item : myEdgeCont) {
713  item.second->unsetParameter(NBTrafficLightDefinition::OSM_DIRECTION);
714  }
715  }
716 }
717 
718 
719 void
720 NBNetBuilder::moveToOrigin(GeoConvHelper& geoConvHelper, bool lefthand) {
721  long before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Moving network to origin"));
722  Boundary boundary = geoConvHelper.getConvBoundary();
723  const double x = -boundary.xmin();
724  const double y = -(lefthand ? boundary.ymax() : boundary.ymin());
725  //if (lefthand) {
726  // y = boundary.ymax();
727  //}
728  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
729  (*i).second->reshiftPosition(x, y);
730  }
731  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
732  (*i).second->reshiftPosition(x, y);
733  }
734  for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) {
735  (*i).second->reshiftPosition(x, y);
736  }
737  for (const auto& stopIt : myPTStopCont.getStops()) {
738  stopIt.second->reshiftPosition(x, y);
739  }
740  geoConvHelper.moveConvertedBy(x, y);
741  PROGRESS_TIME_MESSAGE(before);
742 }
743 
744 
745 void
747  // mirror the network along the X-axis
748  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
749  (*i).second->mirrorX();
750  }
751  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
752  (*i).second->mirrorX();
753  }
754  for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) {
755  (*i).second->mirrorX();
756  }
757  for (const auto& stopIt : myPTStopCont.getStops()) {
758  stopIt.second->mirrorX();
759  }
760 }
761 
762 
763 bool
764 NBNetBuilder::transformCoordinate(Position& from, bool includeInBoundary, GeoConvHelper* from_srs) {
765  Position orig(from);
766  bool ok = true;
768  && GeoConvHelper::getLoaded().usingGeoProjection()
769  && from_srs != nullptr
770  && from_srs->usingGeoProjection()
771  && *from_srs != GeoConvHelper::getLoaded()) {
772  from_srs->cartesian2geo(from);
773  ok &= GeoConvHelper::getLoaded().x2cartesian(from, false);
774  }
775  if (from_srs == nullptr || !GeoConvHelper::getProcessing().usingGeoProjection()) {
776  // if getProcessing is not a geo-projection, assume it a cartesian transformation (i.e. shift)
777  ok &= GeoConvHelper::getProcessing().x2cartesian(from, includeInBoundary);
778 
779  if (from_srs == nullptr && GeoConvHelper::getProcessing().usingGeoProjection()
781  && GeoConvHelper::getLoaded().usingGeoProjection()) {
782  // apply geo patch to loaded geo-network (offset must match)
783  from = from + GeoConvHelper::getLoaded().getOffset();
784  }
785  }
786  if (ok) {
787  const NBHeightMapper& hm = NBHeightMapper::get();
788  if (hm.ready()) {
789  if (from_srs != nullptr && from_srs->usingGeoProjection()) {
790  from_srs->cartesian2geo(orig);
791  }
792  from.setz(hm.getZ(orig));
793  }
794  }
795  const double eps = 1e-6;
796  from.set(std::round(from.x() / eps) * eps, std::round(from.y() / eps) * eps, std::round(from.z() / eps) * eps);
797  return ok;
798 }
799 
800 
801 bool
802 NBNetBuilder::transformCoordinates(PositionVector& from, bool includeInBoundary, GeoConvHelper* from_srs) {
803  const double maxLength = OptionsCont::getOptions().getFloat("geometry.max-segment-length");
804  if (maxLength > 0 && from.size() > 1) {
805  // transformation to cartesian coordinates must happen before we can check segment length
806  PositionVector copy = from;
807  for (int i = 0; i < (int) from.size(); i++) {
808  transformCoordinate(copy[i], false);
809  }
810  addGeometrySegments(from, copy, maxLength);
811  }
812  bool ok = true;
813  for (int i = 0; i < (int) from.size(); i++) {
814  ok = ok && transformCoordinate(from[i], includeInBoundary, from_srs);
815  }
816  return ok;
817 }
818 
819 
820 int
821 NBNetBuilder::addGeometrySegments(PositionVector& from, const PositionVector& cartesian, const double maxLength) {
822  // check lengths and insert new points where needed (in the original
823  // coordinate system)
824  int inserted = 0;
825  for (int i = 0; i < (int)cartesian.size() - 1; i++) {
826  Position start = from[i + inserted];
827  Position end = from[i + inserted + 1];
828  double length = cartesian[i].distanceTo(cartesian[i + 1]);
829  const Position step = (end - start) * (maxLength / length);
830  int steps = 0;
831  while (length > maxLength) {
832  length -= maxLength;
833  steps++;
834  from.insert(from.begin() + i + inserted + 1, start + (step * steps));
835  inserted++;
836  }
837  }
838  return inserted;
839 }
840 
841 
842 bool
844  // see GNELoadThread::fillOptions
845  return OptionsCont::getOptions().exists("new");
846 }
847 
848 
849 /****************************************************************************/
#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.
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:978
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 checkGeometries(const double maxAngle, const double minRadius, bool fix, bool fixRailways, bool silent=false)
Definition: NBEdgeCont.cpp:822
void recheckLanes()
Rechecks whether all lanes have a successor for each of the stored edges.
Definition: NBEdgeCont.cpp:868
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:962
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 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:2160
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4223
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 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:1105
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