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.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
20 // Instance responsible for building networks
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #include <config.h>
28 
29 #include <string>
30 #include <fstream>
31 #include "NBNetBuilder.h"
32 #include "NBNodeCont.h"
33 #include "NBEdgeCont.h"
35 #include "NBDistrictCont.h"
36 #include "NBDistrict.h"
37 #include "NBRequest.h"
38 #include "NBTypeCont.h"
44 #include <utils/common/SysUtils.h>
45 #include <utils/common/ToString.h>
47 #include "NBAlgorithms.h"
48 #include "NBAlgorithms_Ramps.h"
49 #include "NBAlgorithms_Railway.h"
50 #include "NBHeightMapper.h"
51 
52 
53 // ===========================================================================
54 // method definitions
55 // ===========================================================================
57  myEdgeCont(myTypeCont),
58  myNetworkHaveCrossings(false) {
59 }
60 
61 
63 
64 
65 void
67  // apply options to type control
68  myTypeCont.setDefaults(oc.getInt("default.lanenumber"), oc.getFloat("default.lanewidth"), oc.getFloat("default.speed"),
69  oc.getInt("default.priority"), parseVehicleClasses("", oc.getString("default.disallow")));
70  // apply options to edge control
72  // apply options to traffic light logics control
74 }
75 
76 
77 void
78 NBNetBuilder::compute(OptionsCont& oc, const std::set<std::string>& explicitTurnarounds, bool mayAddOrRemove) {
80 
81  const bool lefthand = oc.getBool("lefthand");
82  if (lefthand) {
83  mirrorX();
84  }
85 
86  // MODIFYING THE SETS OF NODES AND EDGES
87 
88  long before = SysUtils::getCurrentMillis();
89 
90 
91  // Removes edges that are connecting the same node
92  PROGRESS_BEGIN_MESSAGE("Removing self-loops");
94  PROGRESS_TIME_MESSAGE(before);
95  if (mayAddOrRemove && oc.exists("remove-edges.isolated") && oc.getBool("remove-edges.isolated")) {
96  before = SysUtils::getCurrentMillis();
97  PROGRESS_BEGIN_MESSAGE("Finding isolated roads");
99  PROGRESS_TIME_MESSAGE(before);
100  }
101  if (mayAddOrRemove && oc.exists("keep-edges.components") && oc.getInt("keep-edges.components") > 0) {
102  before = SysUtils::getCurrentMillis();
103  PROGRESS_BEGIN_MESSAGE("Finding largest components");
104  myNodeCont.removeComponents(myDistrictCont, myEdgeCont, oc.getInt("keep-edges.components"));
105  PROGRESS_TIME_MESSAGE(before);
106  }
107  if (mayAddOrRemove && oc.exists("keep-edges.postload") && oc.getBool("keep-edges.postload")) {
108  if (oc.isSet("keep-edges.explicit") || oc.isSet("keep-edges.input-file")) {
109  before = SysUtils::getCurrentMillis();
110  PROGRESS_BEGIN_MESSAGE("Removing unwished edges");
112  PROGRESS_TIME_MESSAGE(before);
113  }
114  }
115  // Processing pt stops and lines
116  if (oc.exists("ptstop-output") && oc.isSet("ptstop-output")) {
117  before = SysUtils::getCurrentMillis();
118  PROGRESS_BEGIN_MESSAGE("Processing public transport stops");
119  if (!(oc.exists("ptline-output") && oc.isSet("ptline-output"))) {
121  }
123  PROGRESS_TIME_MESSAGE(before);
124  }
125 
126  if (oc.exists("ptline-output") && oc.isSet("ptline-output")) {
127  before = SysUtils::getCurrentMillis();
128  PROGRESS_BEGIN_MESSAGE("Revising public transport stops based on pt lines");
130  PROGRESS_TIME_MESSAGE(before);
131  }
132 
133  if (oc.exists("ptline-output") && oc.isSet("ptline-output") && oc.exists("ptline-clean-up") && oc.getBool("ptline-clean-up")) {
134  before = SysUtils::getCurrentMillis();
135  PROGRESS_BEGIN_MESSAGE("Cleaning up public transport stops that are not served by any line");
137  PROGRESS_TIME_MESSAGE(before);
138  }
139 
140  if (oc.exists("ptstop-output") && oc.isSet("ptstop-output")) {
141  before = SysUtils::getCurrentMillis();
142  PROGRESS_BEGIN_MESSAGE("Align pt stop id signs with corresponding edge id signs");
144  PROGRESS_TIME_MESSAGE(before);
145  }
146 
147  // analyse and fix railway topology
148  if (oc.exists("railway.topology.all-bidi") && oc.getBool("railway.topology.all-bidi")) {
151  } else if (oc.exists("railway.topology.repair") && oc.getBool("railway.topology.repair")) {
154  }
155  if (oc.exists("railway.topology.output") && oc.isSet("railway.topology.output")) {
156  NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
158  }
159 
160  if (oc.getBool("junctions.join") || (oc.exists("ramps.guess") && oc.getBool("ramps.guess")) || oc.getBool("tls.guess.joining")) {
161  // preliminary geometry computations to determine the length of edges
162  // This depends on turning directions and sorting of edge list
163  // in case junctions are joined geometry computations have to be repeated
164  // preliminary roundabout computations to avoid damaging roundabouts via junctions.join or ramps.guess
170  if (oc.getBool("roundabouts.guess")) {
172  }
173  const std::set<EdgeSet>& roundabouts = myEdgeCont.getRoundabouts();
174  for (std::set<EdgeSet>::const_iterator it_round = roundabouts.begin();
175  it_round != roundabouts.end(); ++it_round) {
176  std::vector<std::string> nodeIDs;
177  for (EdgeSet::const_iterator it_edge = it_round->begin(); it_edge != it_round->end(); ++it_edge) {
178  nodeIDs.push_back((*it_edge)->getToNode()->getID());
179  }
180  myNodeCont.addJoinExclusion(nodeIDs);
181  }
183  }
184  // join junctions (may create new "geometry"-nodes so it needs to come before removing these
185  if (mayAddOrRemove && oc.exists("junctions.join-exclude") && oc.isSet("junctions.join-exclude")) {
186  myNodeCont.addJoinExclusion(oc.getStringVector("junctions.join-exclude"));
187  }
189  if (mayAddOrRemove && oc.getBool("junctions.join")) {
190  before = SysUtils::getCurrentMillis();
191  PROGRESS_BEGIN_MESSAGE("Joining junction clusters");
192  numJoined += myNodeCont.joinJunctions(oc.getFloat("junctions.join-dist"), myDistrictCont, myEdgeCont, myTLLCont, myPTStopCont);
193  PROGRESS_TIME_MESSAGE(before);
194  }
195  if (oc.getBool("junctions.join") || (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))) {
196  // reset geometry to avoid influencing subsequent steps (ramps.guess)
198  }
199  if (numJoined > 0) {
200  // bit of a misnomer since we're already done
201  WRITE_MESSAGE(" Joined " + toString(numJoined) + " junction cluster(s).");
202  }
203  //
204  if (mayAddOrRemove && oc.exists("join-lanes") && oc.getBool("join-lanes")) {
205  before = SysUtils::getCurrentMillis();
206  PROGRESS_BEGIN_MESSAGE("Joining lanes");
208  PROGRESS_TIME_MESSAGE(before);
209  WRITE_MESSAGE(" Joined lanes on " + toString(num) + " edges.");
210  }
211  //
212  if (mayAddOrRemove) {
213  int no = 0;
214  const bool removeGeometryNodes = oc.exists("geometry.remove") && oc.getBool("geometry.remove");
215  before = SysUtils::getCurrentMillis();
216  PROGRESS_BEGIN_MESSAGE("Removing empty nodes" + std::string(removeGeometryNodes ? " and geometry nodes" : ""));
217  // removeUnwishedNodes needs turnDirections. @todo: try to call this less often
220  PROGRESS_TIME_MESSAGE(before);
221  WRITE_MESSAGE(" " + toString(no) + " nodes removed.");
222  }
223 
224  // MOVE TO ORIGIN
225  // compute new boundary after network modifications have taken place
226  Boundary boundary;
227  for (std::map<std::string, NBNode*>::const_iterator it = myNodeCont.begin(); it != myNodeCont.end(); ++it) {
228  boundary.add(it->second->getPosition());
229  }
230  for (std::map<std::string, NBEdge*>::const_iterator it = myEdgeCont.begin(); it != myEdgeCont.end(); ++it) {
231  boundary.add(it->second->getGeometry().getBoxBoundary());
232  }
233  geoConvHelper.setConvBoundary(boundary);
234 
235  if (!oc.getBool("offset.disable-normalization") && oc.isDefault("offset.x") && oc.isDefault("offset.y")) {
236  moveToOrigin(geoConvHelper, lefthand);
237  }
238  geoConvHelper.computeFinal(lefthand); // information needed for location element fixed at this point
239 
240  if (oc.exists("geometry.min-dist") && !oc.isDefault("geometry.min-dist")) {
241  before = SysUtils::getCurrentMillis();
242  PROGRESS_BEGIN_MESSAGE("Reducing geometries");
243  myEdgeCont.reduceGeometries(oc.getFloat("geometry.min-dist"));
244  PROGRESS_TIME_MESSAGE(before);
245  }
246  // @note: removing geometry can create similar edges so joinSimilarEdges must come afterwards
247  // @note: likewise splitting can destroy similarities so joinSimilarEdges must come before
248  if (mayAddOrRemove && oc.getBool("edges.join")) {
249  before = SysUtils::getCurrentMillis();
250  PROGRESS_BEGIN_MESSAGE("Joining similar edges");
252  PROGRESS_TIME_MESSAGE(before);
253  }
254  if (oc.getBool("opposites.guess")) {
255  PROGRESS_BEGIN_MESSAGE("guessing opposite direction edges");
258  }
259  //
260  if (mayAddOrRemove && oc.exists("geometry.split") && oc.getBool("geometry.split")) {
261  before = SysUtils::getCurrentMillis();
262  PROGRESS_BEGIN_MESSAGE("Splitting geometry edges");
264  PROGRESS_TIME_MESSAGE(before);
265  }
266  // turning direction
267  before = SysUtils::getCurrentMillis();
268  PROGRESS_BEGIN_MESSAGE("Computing turning directions");
270  PROGRESS_TIME_MESSAGE(before);
271  // correct edge geometries to avoid overlap
272  if (oc.exists("geometry.avoid-overlap") && oc.getBool("geometry.avoid-overlap")) {
274  }
275 
276  // GUESS TLS POSITIONS
277  before = SysUtils::getCurrentMillis();
278  PROGRESS_BEGIN_MESSAGE("Assigning nodes to traffic lights");
279  if (oc.isSet("tls.set")) {
280  std::vector<std::string> tlControlledNodes = oc.getStringVector("tls.set");
282  for (std::vector<std::string>::const_iterator i = tlControlledNodes.begin(); i != tlControlledNodes.end(); ++i) {
283  NBNode* node = myNodeCont.retrieve(*i);
284  if (node == nullptr) {
285  WRITE_WARNING("Building a tl-logic for junction '" + *i + "' is not possible." + "\n The junction '" + *i + "' is not known.");
286  } else {
288  }
289  }
290  }
292  PROGRESS_TIME_MESSAGE(before);
293 
294  // guess ramps (after guessing tls because ramps should not be build at traffic lights)
295  if (mayAddOrRemove) {
296  const bool modifyRamps = (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))
297  || (oc.exists("ramps.set") && oc.isSet("ramps.set"));
298  if (modifyRamps
299  || (oc.exists("ramps.guess-acceleration-lanes") && oc.getBool("ramps.guess-acceleration-lanes"))) {
300  before = SysUtils::getCurrentMillis();
301  if (modifyRamps) {
302  PROGRESS_BEGIN_MESSAGE("Guessing and setting on-/off-ramps");
303  }
306  if (modifyRamps) {
307  PROGRESS_TIME_MESSAGE(before);
308  }
309  }
310  }
311  // guess bike lanes
312  if (mayAddOrRemove && ((oc.getBool("bikelanes.guess") || oc.getBool("bikelanes.guess.from-permissions")))) {
313  const int bikelanes = myEdgeCont.guessSpecialLanes(SVC_BICYCLE, oc.getFloat("default.bikelane-width"),
314  oc.getFloat("bikelanes.guess.min-speed"),
315  oc.getFloat("bikelanes.guess.max-speed"),
316  oc.getBool("bikelanes.guess.from-permissions"),
317  "bikelanes.guess.exclude");
318  WRITE_MESSAGE("Guessed " + toString(bikelanes) + " bike lanes.");
319  }
320 
321  // guess sidewalks
322  if (mayAddOrRemove && ((oc.getBool("sidewalks.guess") || oc.getBool("sidewalks.guess.from-permissions")))) {
323  const int sidewalks = myEdgeCont.guessSpecialLanes(SVC_PEDESTRIAN, oc.getFloat("default.sidewalk-width"),
324  oc.getFloat("sidewalks.guess.min-speed"),
325  oc.getFloat("sidewalks.guess.max-speed"),
326  oc.getBool("sidewalks.guess.from-permissions"),
327  "sidewalks.guess.exclude");
328  WRITE_MESSAGE("Guessed " + toString(sidewalks) + " sidewalks.");
329  }
330 
331  // check whether any not previously setable connections may be set now
333 
334  // remap ids if wished
335  int numChangedEdges = myEdgeCont.remapIDs(oc.getBool("numerical-ids"), oc.isSet("reserved-ids"), oc.getString("prefix"), myPTStopCont);
336  int numChangedNodes = myNodeCont.remapIDs(oc.getBool("numerical-ids"), oc.isSet("reserved-ids"), oc.getString("prefix"));
337  if (numChangedEdges + numChangedNodes > 0) {
338  WRITE_MESSAGE("Remapped " + toString(numChangedEdges) + " edge IDs and " + toString(numChangedNodes) + " node IDs.");
339  }
340 
341  //
342  if (oc.exists("geometry.max-angle")) {
344  DEG2RAD(oc.getFloat("geometry.max-angle")),
345  oc.getFloat("geometry.min-radius"),
346  oc.getBool("geometry.min-radius.fix"));
347  }
348 
349  // GEOMETRY COMPUTATION
350  //
351  before = SysUtils::getCurrentMillis();
352  PROGRESS_BEGIN_MESSAGE("Sorting nodes' edges");
354  PROGRESS_TIME_MESSAGE(before);
356  //
357  before = SysUtils::getCurrentMillis();
358  PROGRESS_BEGIN_MESSAGE("Computing node shapes");
359  if (oc.exists("geometry.junction-mismatch-threshold")) {
360  myNodeCont.computeNodeShapes(oc.getFloat("geometry.junction-mismatch-threshold"));
361  } else {
363  }
364  PROGRESS_TIME_MESSAGE(before);
365  //
366  before = SysUtils::getCurrentMillis();
367  PROGRESS_BEGIN_MESSAGE("Computing edge shapes");
368  myEdgeCont.computeEdgeShapes(oc.getBool("geometry.max-grade.fix") ? oc.getFloat("geometry.max-grade") / 100 : -1);
369  PROGRESS_TIME_MESSAGE(before);
370  // resort edges based on the node and edge shapes
373 
374  // APPLY SPEED MODIFICATIONS
375  if (oc.exists("speed.offset")) {
376  const double speedOffset = oc.getFloat("speed.offset");
377  const double speedFactor = oc.getFloat("speed.factor");
378  const double speedMin = oc.getFloat("speed.minimum");
379  if (speedOffset != 0 || speedFactor != 1 || speedMin > 0) {
380  before = SysUtils::getCurrentMillis();
381  PROGRESS_BEGIN_MESSAGE("Applying speed modifications");
382  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
383  (*i).second->setSpeed(-1, MAX2((*i).second->getSpeed() * speedFactor + speedOffset, speedMin));
384  }
385  PROGRESS_TIME_MESSAGE(before);
386  }
387  }
388 
389  // CONNECTIONS COMPUTATION
390  //
391  before = SysUtils::getCurrentMillis();
392  PROGRESS_BEGIN_MESSAGE("Computing node types");
394  PROGRESS_TIME_MESSAGE(before);
395  //
396  myNetworkHaveCrossings = oc.getBool("walkingareas");
397  if (mayAddOrRemove && oc.getBool("crossings.guess")) {
398  myNetworkHaveCrossings = true;
399  int crossings = 0;
400  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
401  crossings += (*i).second->guessCrossings();
402  }
403  WRITE_MESSAGE("Guessed " + toString(crossings) + " pedestrian crossings.");
404  }
405  if (!myNetworkHaveCrossings) {
406  // recheck whether we had crossings in the input
407  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
408  if (i->second->getCrossingsIncludingInvalid().size() > 0) {
409  myNetworkHaveCrossings = true;
410  break;
411  }
412  }
413  }
414 
415  if (!mayAddOrRemove && myNetworkHaveCrossings) {
416  // crossings added via netedit
417  oc.resetWritable();
418  oc.set("no-internal-links", "false");
419  }
420 
421  //
422  before = SysUtils::getCurrentMillis();
423  PROGRESS_BEGIN_MESSAGE("Computing priorities");
425  PROGRESS_TIME_MESSAGE(before);
426  //
427  before = SysUtils::getCurrentMillis();
428  PROGRESS_BEGIN_MESSAGE("Computing approached edges");
429  myEdgeCont.computeEdge2Edges(oc.getBool("no-left-connections"));
430  PROGRESS_TIME_MESSAGE(before);
431  //
432  if (oc.getBool("roundabouts.guess")) {
433  before = SysUtils::getCurrentMillis();
434  PROGRESS_BEGIN_MESSAGE("Guessing and setting roundabouts");
435  const int numGuessed = myEdgeCont.guessRoundabouts();
436  if (numGuessed > 0) {
437  WRITE_MESSAGE(" Guessed " + toString(numGuessed) + " roundabout(s).");
438  }
439  PROGRESS_TIME_MESSAGE(before);
440  }
442  //
443  before = SysUtils::getCurrentMillis();
444  PROGRESS_BEGIN_MESSAGE("Computing approaching lanes");
446  PROGRESS_TIME_MESSAGE(before);
447  //
448  before = SysUtils::getCurrentMillis();
449  PROGRESS_BEGIN_MESSAGE("Dividing of lanes on approached lanes");
452  PROGRESS_TIME_MESSAGE(before);
453  //
454  before = SysUtils::getCurrentMillis();
455  PROGRESS_BEGIN_MESSAGE("Processing turnarounds");
456  if (!oc.getBool("no-turnarounds")) {
457  myEdgeCont.appendTurnarounds(oc.getBool("no-turnarounds.tls"), oc.getBool("no-turnarounds.except-deadend"), oc.getBool("no-turnarounds.geometry"));
458  } else {
459  myEdgeCont.appendTurnarounds(explicitTurnarounds, oc.getBool("no-turnarounds.tls"));
460  }
461  if (oc.exists("railway.topology.repair") && oc.getBool("railway.topology.repair")
462  && myPTStopCont.getStops().size() > 0) {
463  // allow direction reversal at all bidi-edges with stops
465  }
466  PROGRESS_TIME_MESSAGE(before);
467  //
468  before = SysUtils::getCurrentMillis();
469  PROGRESS_BEGIN_MESSAGE("Rechecking of lane endings");
471  PROGRESS_TIME_MESSAGE(before);
472 
473  if (myNetworkHaveCrossings && !oc.getBool("no-internal-links")) {
474  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
475  i->second->buildCrossingsAndWalkingAreas();
476  }
477  } else {
478  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
479  // needed by netedit if the last crossings was deleted from the network
480  // and walkingareas have been invalidated since the last call to compute()
481  i->second->discardWalkingareas();
482  }
483  if (oc.getBool("no-internal-links")) {
484  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
485  i->second->discardAllCrossings(false);
486  }
487  }
488  }
489  // join traffic lights (after building connections)
490  if (oc.getBool("tls.join")) {
491  before = SysUtils::getCurrentMillis();
492  PROGRESS_BEGIN_MESSAGE("Joining traffic light nodes");
493  myNodeCont.joinTLS(myTLLCont, oc.getFloat("tls.join-dist"));
494  PROGRESS_TIME_MESSAGE(before);
495  }
496 
497  // COMPUTING RIGHT-OF-WAY AND TRAFFIC LIGHT PROGRAMS
498  //
499  before = SysUtils::getCurrentMillis();
500  PROGRESS_BEGIN_MESSAGE("Computing traffic light control information");
502  PROGRESS_TIME_MESSAGE(before);
503  //
504  before = SysUtils::getCurrentMillis();
505  PROGRESS_BEGIN_MESSAGE("Computing node logics");
507  PROGRESS_TIME_MESSAGE(before);
508  //
509  before = SysUtils::getCurrentMillis();
510  PROGRESS_BEGIN_MESSAGE("Computing traffic light logics");
511  std::pair<int, int> numbers = myTLLCont.computeLogics(oc);
512  PROGRESS_TIME_MESSAGE(before);
513  std::string progCount = "";
514  if (numbers.first != numbers.second) {
515  progCount = "(" + toString(numbers.second) + " programs) ";
516  }
517  WRITE_MESSAGE(" " + toString(numbers.first) + " traffic light(s) " + progCount + "computed.");
518  //
519  if (oc.isSet("street-sign-output")) {
520  before = SysUtils::getCurrentMillis();
521  PROGRESS_BEGIN_MESSAGE("Generating street signs");
523  PROGRESS_TIME_MESSAGE(before);
524  }
525 
526  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
527  (*i).second->sortOutgoingConnectionsByIndex();
528  }
529  // FINISHING INNER EDGES
530  if (!oc.getBool("no-internal-links")) {
531  before = SysUtils::getCurrentMillis();
532  PROGRESS_BEGIN_MESSAGE("Building inner edges");
533  // walking areas shall only be built if crossings are wished as well
534  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
535  (*i).second->buildInnerEdges();
536  }
537  PROGRESS_TIME_MESSAGE(before);
538  }
539  // PATCH NODE SHAPES
540  if (oc.getFloat("junctions.scurve-stretch") > 0) {
541  // @note: nodes have collected correction hints in buildInnerEdges()
542  before = SysUtils::getCurrentMillis();
543  PROGRESS_BEGIN_MESSAGE("stretching junctions to smooth geometries");
546  myEdgeCont.computeEdgeShapes(oc.getBool("geometry.max-grade.fix") ? oc.getFloat("geometry.max-grade") / 100 : -1);
547  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
548  (*i).second->buildInnerEdges();
549  }
550  PROGRESS_TIME_MESSAGE(before);
551  }
552  // compute lane-to-lane node logics (require traffic lights and inner edges to be done)
554 
555  if (lefthand) {
556  mirrorX();
557  };
558 
559  if (oc.exists("geometry.check-overlap") && oc.getFloat("geometry.check-overlap") > 0) {
560  before = SysUtils::getCurrentMillis();
561  PROGRESS_BEGIN_MESSAGE("Checking overlapping edges");
562  myEdgeCont.checkOverlap(oc.getFloat("geometry.check-overlap"), oc.getFloat("geometry.check-overlap.vertical-threshold"));
563  PROGRESS_TIME_MESSAGE(before);
564  }
565  if (geoConvHelper.getConvBoundary().getZRange() > 0 && oc.getFloat("geometry.max-grade") > 0) {
566  before = SysUtils::getCurrentMillis();
567  PROGRESS_BEGIN_MESSAGE("Checking edge grade");
568  // user input is in %
569  myEdgeCont.checkGrade(oc.getFloat("geometry.max-grade") / 100);
570  PROGRESS_TIME_MESSAGE(before);
571  }
572 
573  //find accesses for pt rail stops and add bidi-stops
574  if (oc.exists("ptstop-output") && oc.isSet("ptstop-output")) {
575  before = SysUtils::getCurrentMillis();
576  const int numBidiStops = myPTStopCont.generateBidiStops(myEdgeCont);
577  PROGRESS_BEGIN_MESSAGE("Find accesses for pt rail stops");
578  double maxRadius = oc.getFloat("railway.access-distance");
579  double accessFactor = oc.getFloat("railway.access-factor");
580  int maxCount = oc.getInt("railway.max-accesses");
581  myPTStopCont.findAccessEdgesForRailStops(myEdgeCont, maxRadius, maxCount, accessFactor);
582  PROGRESS_TIME_MESSAGE(before);
583  if (numBidiStops > 0) {
584  if (oc.exists("ptline-output") && oc.isSet("ptline-output")) {
586  }
587  }
588  }
589 
590  // report
591  WRITE_MESSAGE("-----------------------------------------------------");
592  WRITE_MESSAGE("Summary:");
594  WRITE_MESSAGE(" Network boundaries:");
595  WRITE_MESSAGE(" Original boundary : " + toString(geoConvHelper.getOrigBoundary()));
596  WRITE_MESSAGE(" Applied offset : " + toString(geoConvHelper.getOffsetBase()));
597  WRITE_MESSAGE(" Converted boundary : " + toString(geoConvHelper.getConvBoundary()));
598  WRITE_MESSAGE("-----------------------------------------------------");
600  // report on very large networks
601  if (MAX2(geoConvHelper.getConvBoundary().xmax(), geoConvHelper.getConvBoundary().ymax()) > 1000000 ||
602  MIN2(geoConvHelper.getConvBoundary().xmin(), geoConvHelper.getConvBoundary().ymin()) < -1000000) {
603  WRITE_WARNING("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");
604  }
605 }
606 
607 
608 /*
609 void
610 NBNetBuilder::computeSingleNode(NBNode* node, OptionsCont& oc, const std::set<std::string>& explicitTurnarounds, bool mayAddOrRemove) {
611  // for a single node do the following:
612  // sortEdges
613  // computeLaneShapes
614  // computeNodeShapes
615  // computeEdgeShapes
616 }
617 */
618 
619 
620 void
621 NBNetBuilder::moveToOrigin(GeoConvHelper& geoConvHelper, bool lefthand) {
622  long before = SysUtils::getCurrentMillis();
623  PROGRESS_BEGIN_MESSAGE("Moving network to origin");
624  Boundary boundary = geoConvHelper.getConvBoundary();
625  const double x = -boundary.xmin();
626  const double y = -(lefthand ? boundary.ymax() : boundary.ymin());
627  //if (lefthand) {
628  // y = boundary.ymax();
629  //}
630  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
631  (*i).second->reshiftPosition(x, y);
632  }
633  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
634  (*i).second->reshiftPosition(x, y);
635  }
636  for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) {
637  (*i).second->reshiftPosition(x, y);
638  }
639  for (std::map<std::string, NBPTStop*>::const_iterator i = myPTStopCont.begin(); i != myPTStopCont.end(); ++i) {
640  (*i).second->reshiftPosition(x, y);
641  }
642  geoConvHelper.moveConvertedBy(x, y);
643  PROGRESS_TIME_MESSAGE(before);
644 }
645 
646 
647 void
649  // mirror the network along the X-axis
650  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
651  (*i).second->mirrorX();
652  }
653  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
654  (*i).second->mirrorX();
655  }
656  for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) {
657  (*i).second->mirrorX();
658  }
659 }
660 
661 
662 bool
663 NBNetBuilder::transformCoordinate(Position& from, bool includeInBoundary, GeoConvHelper* from_srs) {
664  Position orig(from);
665  bool ok = true;
667  && GeoConvHelper::getLoaded().usingGeoProjection()
668  && from_srs != nullptr
669  && from_srs->usingGeoProjection()
670  && *from_srs != GeoConvHelper::getLoaded()) {
671  from_srs->cartesian2geo(from);
672  ok &= GeoConvHelper::getLoaded().x2cartesian(from, false);
673  }
674  ok &= GeoConvHelper::getProcessing().x2cartesian(from, includeInBoundary);
675  if (ok) {
676  const NBHeightMapper& hm = NBHeightMapper::get();
677  if (hm.ready()) {
678  if (from_srs != nullptr && from_srs->usingGeoProjection()) {
679  from_srs->cartesian2geo(orig);
680  }
681  double z = hm.getZ(orig);
682  from = Position(from.x(), from.y(), z);
683  }
684  }
685  return ok;
686 }
687 
688 
689 bool
690 NBNetBuilder::transformCoordinates(PositionVector& from, bool includeInBoundary, GeoConvHelper* from_srs) {
691  const double maxLength = OptionsCont::getOptions().getFloat("geometry.max-segment-length");
692  if (maxLength > 0 && from.size() > 1) {
693  // transformation to cartesian coordinates must happen before we can check segment length
694  PositionVector copy = from;
695  for (int i = 0; i < (int) from.size(); i++) {
696  transformCoordinate(copy[i], false);
697  }
698  // check lengths and insert new points where needed (in the original
699  // coordinate system)
700  int inserted = 0;
701  for (int i = 0; i < (int)copy.size() - 1; i++) {
702  Position start = from[i + inserted];
703  Position end = from[i + inserted + 1];
704  double length = copy[i].distanceTo(copy[i + 1]);
705  const Position step = (end - start) * (maxLength / length);
706  int steps = 0;
707  while (length > maxLength) {
708  length -= maxLength;
709  steps++;
710  from.insert(from.begin() + i + inserted + 1, start + (step * steps));
711  inserted++;
712  }
713  }
714  // now perform the transformation again so that height mapping can be
715  // performed for the new points
716  }
717  bool ok = true;
718  for (int i = 0; i < (int) from.size(); i++) {
719  ok = ok && transformCoordinate(from[i], includeInBoundary, from_srs);
720  }
721  return ok;
722 }
723 
724 
725 bool
727  // see GNELoadThread::fillOptions
728  return OptionsCont::getOptions().exists("new");
729 }
730 
731 
732 /****************************************************************************/
NBNetBuilder()
Constructor.
NBTypeCont myTypeCont
The used container for street types.
Definition: NBNetBuilder.h:241
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:108
void joinSimilarEdges(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc)
Joins edges connecting the same nodes.
Definition: NBNodeCont.cpp:179
NBPTStopCont myPTStopCont
The used container for pt stops.
Definition: NBNetBuilder.h:253
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:131
void 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:167
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:125
void sortOutgoingLanesConnections()
Sorts all lanes of all edges within the container by their direction.
Definition: NBEdgeCont.cpp:754
void markRoundabouts()
mark edge priorities and prohibit turn-arounds for all roundabout edges
void setConvBoundary(const Boundary &boundary)
sets the converted boundary
void alignIdSigns()
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
static void validateRailCrossings(NBNodeCont &nc, NBTrafficLightLogicCont &tlc)
Checks rail_crossing for validity.
void resetWritable()
Resets all options to be writeable.
int generateBidiStops(NBEdgeCont &cont)
duplicate stops for superposed rail edges and return the number of generated stops ...
void computeLogics2(const NBEdgeCont &ec, OptionsCont &oc)
compute right-of-way logic for all lane-to-lane connections
static bool transformCoordinate(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
std::map< std::string, NBNode * >::const_iterator begin() const
Returns the pointer to the begin of the stored nodes.
Definition: NBNodeCont.h:116
void reduceGeometries(const double minDist)
Definition: NBEdgeCont.cpp:727
void addJoinExclusion(const std::vector< std::string > &ids, bool check=false)
Definition: NBNodeCont.cpp:565
int removeUnwishedNodes(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc, NBPTStopCont &sc, NBPTLineCont &lc, NBParkingCont &pc, bool removeGeometryNodes)
Removes "unwished" nodes.
Definition: NBNodeCont.cpp:370
const Boundary & getConvBoundary() const
Returns the converted boundary.
std::map< std::string, NBNode * >::const_iterator end() const
Returns the pointer to the end of the stored nodes.
Definition: NBNodeCont.h:121
void mirrorX()
mirror the network along the X-axis
void removeIsolatedRoads(NBDistrictCont &dc, NBEdgeCont &ec)
Removes sequences of edges that are not connected with a junction. Simple roads without junctions som...
Definition: NBNodeCont.cpp:224
void joinTLS(NBTrafficLightLogicCont &tlc, double maxdist)
Builds clusters of tls-controlled junctions and joins the control if possible.
int guessRoundabouts()
Determines which edges belong to roundabouts and increases their priority.
static void repairTopology(NBNetBuilder &nb)
static void computeFinal(bool lefthand=false)
compute the location attributes which will be used for output based on the loaded location data...
~NBNetBuilder()
Destructor.
void postprocess(std::set< std::string > &usedStops)
static GeoConvHelper & getProcessing()
the coordinate transformation to use for input conversion and processing
Definition: GeoConvHelper.h:87
vehicle is a bicycle
bool x2cartesian(Position &from, bool includeInBoundary=true)
Converts the given coordinate into a cartesian and optionally update myConvBoundary.
double y() const
Returns the y-position.
Definition: Position.h:62
std::map< std::string, NBDistrict * >::const_iterator end() const
Returns the pointer to the end of the stored districts.
bool usingGeoProjection() const
Returns whether a transformation from geo to metric coordinates will be performed.
void guessOpposites()
Sets opposite lane information for geometrically close edges.
Definition: NBEdgeCont.cpp:958
double x() const
Returns the x-position.
Definition: Position.h:57
static GeoConvHelper & getLoaded()
the coordinate transformation that was loaded fron an input file
Definition: GeoConvHelper.h:92
void findAccessEdgesForRailStops(NBEdgeCont &cont, double maxRadius, int maxCount, double accessFactor)
int joinLoadedClusters(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc)
Joins loaded junction clusters (see NIXMLNodesHandler)
Definition: NBNodeCont.cpp:621
T MAX2(T a, T b)
Definition: StdDefs.h:80
const Boundary & getOrigBoundary() const
Returns the original boundary.
void generateStreetSigns()
assigns street signs to edges based on toNode types
void recheckPostProcessConnections()
Try to set any stored connections.
static bool transformCoordinates(PositionVector &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
void guessTLs(OptionsCont &oc, NBTrafficLightLogicCont &tlc)
Guesses which junctions or junction clusters shall be controlled by tls.
std::map< std::string, NBEdge * >::const_iterator end() const
Returns the pointer to the end of the stored edges.
Definition: NBEdgeCont.h:193
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
void avoidOverlap()
fix overlap
Definition: NBNodeCont.cpp:444
std::map< std::string, NBDistrict * >::const_iterator begin() const
Returns the pointer to the begin of the stored districts.
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
static void sortNodesEdges(NBNodeCont &nc, bool useNodeShape=false)
Sorts a node&#39;s edges clockwise regarding driving direction.
void computeLanes2Edges()
Computes for each edge which lanes approach the next edges.
Definition: NBEdgeCont.cpp:770
void moveConvertedBy(double x, double y)
Shifts the converted boundary by the given amounts.
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:42
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:239
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
void checkGeometries(const double maxAngle, const double minRadius, bool fix)
Definition: NBEdgeCont.cpp:735
void applyOptions(OptionsCont &oc)
Initialises the storage by applying given options.
void fixBidiStops(const NBEdgeCont &ec)
select the correct stop on superposed rail edges
void checkOverlap(double threshold, double zThreshold) const
check whether edges overlap
int joinLanes(SVCPermissions perms)
join adjacent lanes with the given permissions
void computeLogics(const NBEdgeCont &ec, OptionsCont &oc)
build the list of outgoing edges and lanes
void localizePTStops(NBEdgeCont &cont)
void checkGrade(double threshold) const
check whether edges are to steep
static const NBHeightMapper & get()
return the singleton instance (maybe 0)
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
void process(NBEdgeCont &cont)
int guessSpecialLanes(SUMOVehicleClass svc, double width, double minSpeed, double maxSpeed, bool fromPermissions, const std::string &excludeOpt)
add sidwalks to edges within the given limits or permissions and return the number of edges affected ...
static void reportWarnings()
reports warnings if any occurred
Definition: NBRequest.cpp:1011
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
#define PROGRESS_TIME_MESSAGE(before)
Definition: MsgHandler.h:243
static void analyzeTopology(NBNetBuilder &nb)
Computes highway on-/off-ramps (if wished)
std::set< std::string > & getServedPTStops()
int joinJunctions(double maxDist, NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc, NBPTStopCont &sc)
Joins junctions that are very close together.
Definition: NBNodeCont.cpp:646
void assignLanes(NBEdgeCont &cont)
std::map< std::string, NBPTStop * >::const_iterator begin() const
Returns the pointer to the begin of the stored pt stops.
Definition: NBPTStopCont.h:51
std::map< std::string, NBEdge * >::const_iterator begin() const
Returns the pointer to the begin of the stored edges.
Definition: NBEdgeCont.h:185
static methods for processing the coordinates conversion for the current net
Definition: GeoConvHelper.h:56
void computeLanes2Lanes()
divides the incoming lanes on outgoing lanes
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
void removeUnwishedEdges(NBDistrictCont &dc)
Removes unwished edges (not in keep-edges)
Definition: NBEdgeCont.cpp:699
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
void setDefaults(int defaultNumLanes, double defaultLaneWidth, double defaultSpeed, int defaultPriority, SVCPermissions defaultPermissions)
Sets the default values.
Definition: NBTypeCont.cpp:40
void applyOptions(OptionsCont &oc)
Initialises the storage by applying given options.
static void computeEdgePriorities(NBNodeCont &nc)
Computes edge priorities within a node.
A list of positions.
void applyOptions(OptionsCont &oc)
Initialises the storage by applying given options.
Definition: NBEdgeCont.cpp:72
NBEdgeCont myEdgeCont
The used container for edges.
Definition: NBNetBuilder.h:244
T get(const std::string &str) const
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool myNetworkHaveCrossings
flag to indicate that network has crossings
Definition: NBNetBuilder.h:264
void computeEdge2Edges(bool noLeftMovers)
Computes for each edge the approached edges.
Definition: NBEdgeCont.cpp:762
void computeLaneShapes()
Computes the shapes of all lanes of all edges stored in the container.
Definition: NBEdgeCont.cpp:863
NBTrafficLightLogicCont myTLLCont
The used container for traffic light logics.
Definition: NBNetBuilder.h:247
bool exists(const std::string &name) const
Returns the information whether the named option is known.
std::vector< std::string > getStringVector(const std::string &name) const
Returns the list of string-vector-value of the named option (only for Option_String) ...
T MIN2(T a, T b)
Definition: StdDefs.h:74
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:119
void computeNodeShapes(double mismatchThreshold=-1)
Compute the junction shape for this node.
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:241
void splitGeometry(NBNodeCont &nc)
Splits edges into multiple if they have a complex geometry.
Definition: NBEdgeCont.cpp:716
static void makeAllBidi(NBNetBuilder &nb)
const std::set< EdgeSet > getRoundabouts() const
Returns the determined roundabouts.
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
#define DEG2RAD(x)
Definition: GeomHelper.h:38
std::map< std::string, NBPTStop * >::const_iterator end() const
Returns the pointer to the end of the stored pt stops.
Definition: NBPTStopCont.h:58
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
int remapIDs(bool numericaIDs, bool reservedIDs, const std::string &prefix)
remap node IDs accoring to options –numerical-ids and –reserved-ids
const std::map< std::string, NBPTStop * > & getStops() const
Definition: NBPTStopCont.h:62
void setAsTLControlled(NBNode *node, NBTrafficLightLogicCont &tlc, TrafficLightType type, std::string id="")
Sets the given node as being controlled by a tls.
static void computeRamps(NBNetBuilder &nb, OptionsCont &oc)
Computes highway on-/off-ramps (if wished)
bool set(const std::string &name, const std::string &value)
Sets the given value for the named option.
void moveToOrigin(GeoConvHelper &geoConvHelper, bool lefthand)
shift network so its lower left corner is at 0,0
static int getNumLoaded()
Definition: GeoConvHelper.h:96
static bool runningNetedit()
whether netbuilding takes place in the context of NETEDIT
A storage for options typed value containers)
Definition: OptionsCont.h:90
const Position getOffsetBase() const
Returns the network base.
void appendRailwayTurnarounds(const NBPTStopCont &sc)
Appends turnarounds to all bidiRail edges with stops.
Definition: NBEdgeCont.cpp:834
Represents a single node (junction) during network building.
Definition: NBNode.h:68
static void computeTurnDirections(NBNodeCont &nc, bool warn=true)
Computes turnaround destinations for all edges (if exist)
NBDistrictCont myDistrictCont
The used container for districts.
Definition: NBNetBuilder.h:250
void computeEdgeShapes(double smoothElevationThreshold=-1)
Computes the shapes of all edges stored in the container.
Definition: NBEdgeCont.cpp:855
void printBuiltNodesStatistics() const
Prints statistics about built nodes.
double getZ(const Position &geo) const
returns height for the given geo coordinate (WGS84)
void compute(OptionsCont &oc, const std::set< std::string > &explicitTurnarounds=std::set< std::string >(), bool mayAddOrRemove=true)
Performs the network building steps.
void recheckLanes()
Rechecks whether all lanes have a successor for each of the stored edges.
Definition: NBEdgeCont.cpp:778
static void computeNodeTypes(NBNodeCont &nc, NBTrafficLightLogicCont &tlc)
Computes node types.
static long getCurrentMillis()
Returns the current time in milliseconds.
Definition: SysUtils.cpp:39
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:242
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:79
NBParkingCont myParkingCont
Definition: NBNetBuilder.h:258
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:137
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:240
double getZRange() const
Returns the elevation range of the boundary (z-axis)
Definition: Boundary.cpp:167
NBNodeCont myNodeCont
The used container for nodes.
Definition: NBNetBuilder.h:238
void setTLControllingInformation(const NBEdgeCont &ec, const NBNodeCont &nc)
Informs the edges about being controlled by a tls.
int remapIDs(bool numericaIDs, bool reservedIDs, const std::string &prefix, NBPTStopCont &sc)
remap node IDs accoring to options –numerical-ids and –reserved-ids
std::pair< int, int > computeLogics(OptionsCont &oc)
Computes the traffic light logics using the stored definitions and stores the results.
bool ready() const
returns whether the NBHeightMapper has data
Set z-values for all network positions based on data from a height map.
vehicles ignoring classes
void appendTurnarounds(bool noTLSControlled, bool onlyDeadends, bool noGeometryLike)
Appends turnarounds to all edges stored in the container.
Definition: NBEdgeCont.cpp:818
NBPTLineCont myPTLineCont
The used container for pt stops.
Definition: NBNetBuilder.h:256
TrafficLightType
void removeComponents(NBDistrictCont &dc, NBEdgeCont &ec, const int numKeep)
Checks the network for weak connectivity and removes all but the largest components. The connectivity check is done regardless of edge direction and vclass.
Definition: NBNodeCont.cpp:312