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-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
22 // Instance responsible for building networks
23 /****************************************************************************/
24 
25 
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #ifdef _MSC_VER
30 #include <windows_config.h>
31 #else
32 #include <config.h>
33 #endif
34 
35 #include <string>
36 #include <fstream>
37 #include "NBNetBuilder.h"
38 #include "NBNodeCont.h"
39 #include "NBEdgeCont.h"
41 #include "NBDistrictCont.h"
42 #include "NBDistrict.h"
43 #include "NBRequest.h"
44 #include "NBTypeCont.h"
50 #include <utils/common/SysUtils.h>
51 #include <utils/common/ToString.h>
53 #include "NBAlgorithms.h"
54 #include "NBAlgorithms_Ramps.h"
55 #include "NBHeightMapper.h"
56 
57 
58 // ===========================================================================
59 // method definitions
60 // ===========================================================================
62  myEdgeCont(myTypeCont),
63  myHaveLoadedNetworkWithoutInternalEdges(false),
64  myNetworkHaveCrossings(false) {
65 }
66 
67 
69 
70 
71 void
73  // apply options to type control
74  myTypeCont.setDefaults(oc.getInt("default.lanenumber"), oc.getFloat("default.lanewidth"), oc.getFloat("default.speed"),
75  oc.getInt("default.priority"), parseVehicleClasses("", oc.getString("default.disallow")));
76  // apply options to edge control
78  // apply options to traffic light logics control
80 }
81 
82 
83 void
84 NBNetBuilder::compute(OptionsCont& oc, const std::set<std::string>& explicitTurnarounds, bool mayAddOrRemove) {
86 
87  const bool lefthand = oc.getBool("lefthand");
88  if (lefthand) {
89  mirrorX();
90  }
91 
92  // MODIFYING THE SETS OF NODES AND EDGES
93 
94  long before = SysUtils::getCurrentMillis();
95 
96 
97  // Removes edges that are connecting the same node
98  PROGRESS_BEGIN_MESSAGE("Removing self-loops");
100  PROGRESS_TIME_MESSAGE(before);
101  if (mayAddOrRemove && oc.exists("remove-edges.isolated") && oc.getBool("remove-edges.isolated")) {
102  before = SysUtils::getCurrentMillis();
103  PROGRESS_BEGIN_MESSAGE("Finding isolated roads");
105  PROGRESS_TIME_MESSAGE(before);
106  }
107  if (mayAddOrRemove && oc.exists("keep-edges.components") && oc.getInt("keep-edges.components") > 0) {
108  before = SysUtils::getCurrentMillis();
109  PROGRESS_BEGIN_MESSAGE("Finding largest components");
110  myNodeCont.removeComponents(myDistrictCont, myEdgeCont, oc.getInt("keep-edges.components"));
111  PROGRESS_TIME_MESSAGE(before);
112  }
113  if (mayAddOrRemove && oc.exists("keep-edges.postload") && oc.getBool("keep-edges.postload")) {
114  if (oc.isSet("keep-edges.explicit") || oc.isSet("keep-edges.input-file")) {
115  before = SysUtils::getCurrentMillis();
116  PROGRESS_BEGIN_MESSAGE("Removing unwished edges");
118  PROGRESS_TIME_MESSAGE(before);
119  }
120  }
121  // Processing pt stops and lines
122  if (oc.exists("ptstop-output") && oc.isSet("ptstop-output")) {
123  before = SysUtils::getCurrentMillis();
124  PROGRESS_BEGIN_MESSAGE("Processing public transport stops");
125  if (!(oc.exists("ptline-output") && oc.isSet("ptline-output"))) {
127  }
129  PROGRESS_TIME_MESSAGE(before);
130  }
131 
132  if (oc.exists("ptline-output") && oc.isSet("ptline-output")) {
133  before = SysUtils::getCurrentMillis();
134  PROGRESS_BEGIN_MESSAGE("Revising public transport stops based on pt lines");
136  PROGRESS_TIME_MESSAGE(before);
137  }
138 
139  if (oc.exists("ptline-output") && oc.isSet("ptline-output") && oc.exists("ptline-clean-up") && oc.getBool("ptline-clean-up")) {
140  before = SysUtils::getCurrentMillis();
141  PROGRESS_BEGIN_MESSAGE("Cleaning up public transport stops that are not served by any line");
143  PROGRESS_TIME_MESSAGE(before);
144  }
145 
146  if (oc.exists("ptstop-output") && oc.isSet("ptstop-output")) {
147  before = SysUtils::getCurrentMillis();
148  PROGRESS_BEGIN_MESSAGE("Align pt stop id signs with corresponding edge id signs");
150  PROGRESS_TIME_MESSAGE(before);
151  }
152 
153  if (oc.getBool("junctions.join") || (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))) {
154  // preliminary geometry computations to determine the length of edges
155  // This depends on turning directions and sorting of edge list
156  // in case junctions are joined geometry computations have to be repeated
157  // preliminary roundabout computations to avoid damaging roundabouts via junctions.join or ramps.guess
163  if (oc.getBool("roundabouts.guess")) {
165  }
166  const std::set<EdgeSet>& roundabouts = myEdgeCont.getRoundabouts();
167  for (std::set<EdgeSet>::const_iterator it_round = roundabouts.begin();
168  it_round != roundabouts.end(); ++it_round) {
169  std::vector<std::string> nodeIDs;
170  for (EdgeSet::const_iterator it_edge = it_round->begin(); it_edge != it_round->end(); ++it_edge) {
171  nodeIDs.push_back((*it_edge)->getToNode()->getID());
172  }
173  myNodeCont.addJoinExclusion(nodeIDs);
174  }
175  }
176  // join junctions (may create new "geometry"-nodes so it needs to come before removing these
177  if (mayAddOrRemove && oc.exists("junctions.join-exclude") && oc.isSet("junctions.join-exclude")) {
178  myNodeCont.addJoinExclusion(oc.getStringVector("junctions.join-exclude"));
179  }
181  if (mayAddOrRemove && oc.getBool("junctions.join")) {
182  before = SysUtils::getCurrentMillis();
183  PROGRESS_BEGIN_MESSAGE("Joining junction clusters");
184  numJoined += myNodeCont.joinJunctions(oc.getFloat("junctions.join-dist"), myDistrictCont, myEdgeCont, myTLLCont, myPTStopCont);
185  PROGRESS_TIME_MESSAGE(before);
186  }
187  if (oc.getBool("junctions.join") || (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))) {
188  // reset geometry to avoid influencing subsequent steps (ramps.guess)
190  }
191  if (numJoined > 0) {
192  // bit of a misnomer since we're already done
193  WRITE_MESSAGE(" Joined " + toString(numJoined) + " junction cluster(s).");
194  }
195  //
196  if (mayAddOrRemove) {
197  int no = 0;
198  const bool removeGeometryNodes = oc.exists("geometry.remove") && oc.getBool("geometry.remove");
199  before = SysUtils::getCurrentMillis();
200  PROGRESS_BEGIN_MESSAGE("Removing empty nodes" + std::string(removeGeometryNodes ? " and geometry nodes" : ""));
201  // removeUnwishedNodes needs turnDirections. @todo: try to call this less often
204  PROGRESS_TIME_MESSAGE(before);
205  WRITE_MESSAGE(" " + toString(no) + " nodes removed.");
206  }
207 
208  // MOVE TO ORIGIN
209  // compute new boundary after network modifications have taken place
210  Boundary boundary;
211  for (std::map<std::string, NBNode*>::const_iterator it = myNodeCont.begin(); it != myNodeCont.end(); ++it) {
212  boundary.add(it->second->getPosition());
213  }
214  for (std::map<std::string, NBEdge*>::const_iterator it = myEdgeCont.begin(); it != myEdgeCont.end(); ++it) {
215  boundary.add(it->second->getGeometry().getBoxBoundary());
216  }
217  geoConvHelper.setConvBoundary(boundary);
218 
219  if (!oc.getBool("offset.disable-normalization") && oc.isDefault("offset.x") && oc.isDefault("offset.y")) {
220  moveToOrigin(geoConvHelper, lefthand);
221  }
222  geoConvHelper.computeFinal(lefthand); // information needed for location element fixed at this point
223 
224  if (oc.exists("geometry.min-dist") && !oc.isDefault("geometry.min-dist")) {
225  before = SysUtils::getCurrentMillis();
226  PROGRESS_BEGIN_MESSAGE("Reducing geometries");
227  myEdgeCont.reduceGeometries(oc.getFloat("geometry.min-dist"));
228  PROGRESS_TIME_MESSAGE(before);
229  }
230  // @note: removing geometry can create similar edges so joinSimilarEdges must come afterwards
231  // @note: likewise splitting can destroy similarities so joinSimilarEdges must come before
232  if (mayAddOrRemove && oc.getBool("edges.join")) {
233  before = SysUtils::getCurrentMillis();
234  PROGRESS_BEGIN_MESSAGE("Joining similar edges");
236  PROGRESS_TIME_MESSAGE(before);
237  }
238  if (oc.getBool("opposites.guess")) {
239  PROGRESS_BEGIN_MESSAGE("guessing opposite direction edges");
242  }
243  //
244  if (mayAddOrRemove && oc.exists("geometry.split") && oc.getBool("geometry.split")) {
245  before = SysUtils::getCurrentMillis();
246  PROGRESS_BEGIN_MESSAGE("Splitting geometry edges");
248  PROGRESS_TIME_MESSAGE(before);
249  }
250  // turning direction
251  before = SysUtils::getCurrentMillis();
252  PROGRESS_BEGIN_MESSAGE("Computing turning directions");
254  PROGRESS_TIME_MESSAGE(before);
255  // correct edge geometries to avoid overlap
257  // guess ramps
258  if (mayAddOrRemove) {
259  if ((oc.exists("ramps.guess") && oc.getBool("ramps.guess")) || (oc.exists("ramps.set") && oc.isSet("ramps.set"))) {
260  before = SysUtils::getCurrentMillis();
261  PROGRESS_BEGIN_MESSAGE("Guessing and setting on-/off-ramps");
264  PROGRESS_TIME_MESSAGE(before);
265  }
266  }
267  // guess sidewalks
268  if (mayAddOrRemove && ((oc.getBool("sidewalks.guess") || oc.getBool("sidewalks.guess.from-permissions")))) {
269  const int sidewalks = myEdgeCont.guessSidewalks(oc.getFloat("default.sidewalk-width"),
270  oc.getFloat("sidewalks.guess.min-speed"),
271  oc.getFloat("sidewalks.guess.max-speed"),
272  oc.getBool("sidewalks.guess.from-permissions"));
273  WRITE_MESSAGE("Guessed " + toString(sidewalks) + " sidewalks.");
274  }
275 
276  // check whether any not previously setable connections may be set now
278 
279  // remap ids if wished
280  int numChangedEdges = myEdgeCont.remapIDs(oc.getBool("numerical-ids"), oc.isSet("reserved-ids"));
281  int numChangedNodes = myNodeCont.remapIDs(oc.getBool("numerical-ids"), oc.isSet("reserved-ids"));
282  if (numChangedEdges + numChangedNodes > 0) {
283  WRITE_MESSAGE("Remapped " + toString(numChangedEdges) + " edge IDs and " + toString(numChangedNodes) + " node IDs.");
284  }
285 
286  //
287  if (oc.exists("geometry.max-angle")) {
289  DEG2RAD(oc.getFloat("geometry.max-angle")),
290  oc.getFloat("geometry.min-radius"),
291  oc.getBool("geometry.min-radius.fix"));
292  }
293 
294  // GEOMETRY COMPUTATION
295  //
296  before = SysUtils::getCurrentMillis();
297  PROGRESS_BEGIN_MESSAGE("Sorting nodes' edges");
299  PROGRESS_TIME_MESSAGE(before);
301  //
302  before = SysUtils::getCurrentMillis();
303  PROGRESS_BEGIN_MESSAGE("Computing node shapes");
304  if (oc.exists("geometry.junction-mismatch-threshold")) {
305  myNodeCont.computeNodeShapes(oc.getFloat("geometry.junction-mismatch-threshold"));
306  } else {
308  }
309  PROGRESS_TIME_MESSAGE(before);
310  //
311  before = SysUtils::getCurrentMillis();
312  PROGRESS_BEGIN_MESSAGE("Computing edge shapes");
314  PROGRESS_TIME_MESSAGE(before);
315  // resort edges based on the node and edge shapes
318 
319  // APPLY SPEED MODIFICATIONS
320  if (oc.exists("speed.offset")) {
321  const double speedOffset = oc.getFloat("speed.offset");
322  const double speedFactor = oc.getFloat("speed.factor");
323  if (speedOffset != 0 || speedFactor != 1) {
324  const double speedMin = oc.getFloat("speed.minimum");
325  before = SysUtils::getCurrentMillis();
326  PROGRESS_BEGIN_MESSAGE("Applying speed modifications");
327  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
328  (*i).second->setSpeed(-1, MAX2((*i).second->getSpeed() * speedFactor + speedOffset, speedMin));
329  }
330  PROGRESS_TIME_MESSAGE(before);
331  }
332  }
333 
334  // CONNECTIONS COMPUTATION
335  //
336  before = SysUtils::getCurrentMillis();
337  PROGRESS_BEGIN_MESSAGE("Computing node types");
339  PROGRESS_TIME_MESSAGE(before);
340  //
341  myNetworkHaveCrossings = oc.getBool("walkingareas");
342  if (mayAddOrRemove && oc.getBool("crossings.guess")) {
343  myNetworkHaveCrossings = true;
344  int crossings = 0;
345  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
346  crossings += (*i).second->guessCrossings();
347  }
348  WRITE_MESSAGE("Guessed " + toString(crossings) + " pedestrian crossings.");
349  }
350  if (!myNetworkHaveCrossings) {
351  // recheck whether we had crossings in the input
352  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
353  if (i->second->getCrossingsIncludingInvalid().size() > 0) {
354  myNetworkHaveCrossings = true;
355  break;
356  }
357  }
358  }
359 
360  if (oc.isDefault("no-internal-links") && !myNetworkHaveCrossings && myHaveLoadedNetworkWithoutInternalEdges) {
361  oc.set("no-internal-links", "true");
362  } else if (!mayAddOrRemove && myNetworkHaveCrossings) {
363  // crossings added via netedit
364  oc.resetWritable();
365  oc.set("no-internal-links", "false");
366  }
367 
368  //
369  before = SysUtils::getCurrentMillis();
370  PROGRESS_BEGIN_MESSAGE("Computing priorities");
372  PROGRESS_TIME_MESSAGE(before);
373  //
374  before = SysUtils::getCurrentMillis();
375  PROGRESS_BEGIN_MESSAGE("Computing approached edges");
376  myEdgeCont.computeEdge2Edges(oc.getBool("no-left-connections"));
377  PROGRESS_TIME_MESSAGE(before);
378  //
379  if (mayAddOrRemove && oc.getBool("roundabouts.guess")) {
380  before = SysUtils::getCurrentMillis();
381  PROGRESS_BEGIN_MESSAGE("Guessing and setting roundabouts");
382  const int numGuessed = myEdgeCont.guessRoundabouts();
383  if (numGuessed > 0) {
384  WRITE_MESSAGE(" Guessed " + toString(numGuessed) + " roundabout(s).");
385  }
386  PROGRESS_TIME_MESSAGE(before);
387  }
389  //
390  before = SysUtils::getCurrentMillis();
391  PROGRESS_BEGIN_MESSAGE("Computing approaching lanes");
393  PROGRESS_TIME_MESSAGE(before);
394  //
395  before = SysUtils::getCurrentMillis();
396  PROGRESS_BEGIN_MESSAGE("Dividing of lanes on approached lanes");
399  PROGRESS_TIME_MESSAGE(before);
400  //
401  before = SysUtils::getCurrentMillis();
402  PROGRESS_BEGIN_MESSAGE("Processing turnarounds");
403  if (!oc.getBool("no-turnarounds")) {
404  myEdgeCont.appendTurnarounds(oc.getBool("no-turnarounds.tls"));
405  } else {
406  myEdgeCont.appendTurnarounds(explicitTurnarounds, oc.getBool("no-turnarounds.tls"));
407  }
408  PROGRESS_TIME_MESSAGE(before);
409  //
410  before = SysUtils::getCurrentMillis();
411  PROGRESS_BEGIN_MESSAGE("Rechecking of lane endings");
413  PROGRESS_TIME_MESSAGE(before);
414 
415  if (myNetworkHaveCrossings && !oc.getBool("no-internal-links")) {
416  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
417  i->second->buildCrossingsAndWalkingAreas();
418  }
419  } else if (oc.getBool("no-internal-links")) {
420  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
421  i->second->discardAllCrossings(false);
422  }
423  }
424 
425  // GUESS TLS POSITIONS
426  before = SysUtils::getCurrentMillis();
427  PROGRESS_BEGIN_MESSAGE("Assigning nodes to traffic lights");
428  if (oc.isSet("tls.set")) {
429  std::vector<std::string> tlControlledNodes = oc.getStringVector("tls.set");
431  for (std::vector<std::string>::const_iterator i = tlControlledNodes.begin(); i != tlControlledNodes.end(); ++i) {
432  NBNode* node = myNodeCont.retrieve(*i);
433  if (node == 0) {
434  WRITE_WARNING("Building a tl-logic for junction '" + *i + "' is not possible." + "\n The junction '" + *i + "' is not known.");
435  } else {
437  }
438  }
439  }
441  PROGRESS_TIME_MESSAGE(before);
442  //
443  if (oc.getBool("tls.join")) {
444  before = SysUtils::getCurrentMillis();
445  PROGRESS_BEGIN_MESSAGE("Joining traffic light nodes");
446  myNodeCont.joinTLS(myTLLCont, oc.getFloat("tls.join-dist"));
447  PROGRESS_TIME_MESSAGE(before);
448  }
449 
450 
451  // COMPUTING RIGHT-OF-WAY AND TRAFFIC LIGHT PROGRAMS
452  //
453  before = SysUtils::getCurrentMillis();
454  PROGRESS_BEGIN_MESSAGE("Computing traffic light control information");
456  PROGRESS_TIME_MESSAGE(before);
457  //
458  before = SysUtils::getCurrentMillis();
459  PROGRESS_BEGIN_MESSAGE("Computing node logics");
461  PROGRESS_TIME_MESSAGE(before);
462  //
463  before = SysUtils::getCurrentMillis();
464  PROGRESS_BEGIN_MESSAGE("Computing traffic light logics");
465  std::pair<int, int> numbers = myTLLCont.computeLogics(oc);
466  PROGRESS_TIME_MESSAGE(before);
467  std::string progCount = "";
468  if (numbers.first != numbers.second) {
469  progCount = "(" + toString(numbers.second) + " programs) ";
470  }
471  WRITE_MESSAGE(" " + toString(numbers.first) + " traffic light(s) " + progCount + "computed.");
472  //
473  if (oc.isSet("street-sign-output")) {
474  before = SysUtils::getCurrentMillis();
475  PROGRESS_BEGIN_MESSAGE("Generating street signs");
477  PROGRESS_TIME_MESSAGE(before);
478  }
479 
480  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
481  (*i).second->sortOutgoingConnectionsByIndex();
482  }
483  // FINISHING INNER EDGES
484  if (!oc.getBool("no-internal-links")) {
485  before = SysUtils::getCurrentMillis();
486  PROGRESS_BEGIN_MESSAGE("Building inner edges");
487  // walking areas shall only be built if crossings are wished as well
488  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
489  (*i).second->buildInnerEdges();
490  }
491  PROGRESS_TIME_MESSAGE(before);
492  }
493  // PATCH NODE SHAPES
494  if (oc.getFloat("junctions.scurve-stretch") > 0) {
495  // @note: nodes have collected correction hints in buildInnerEdges()
496  before = SysUtils::getCurrentMillis();
497  PROGRESS_BEGIN_MESSAGE("stretching junctions to smooth geometries");
501  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
502  (*i).second->buildInnerEdges();
503  }
504  PROGRESS_TIME_MESSAGE(before);
505  }
506  if (lefthand) {
507  mirrorX();
508  };
509 
510  if (oc.exists("geometry.check-overlap") && oc.getFloat("geometry.check-overlap") > 0) {
511  before = SysUtils::getCurrentMillis();
512  PROGRESS_BEGIN_MESSAGE("Checking overlapping edges");
513  myEdgeCont.checkOverlap(oc.getFloat("geometry.check-overlap"), oc.getFloat("geometry.check-overlap.vertical-threshold"));
514  PROGRESS_TIME_MESSAGE(before);
515  }
516  if (oc.exists("geometry.max-grade") && oc.getFloat("geometry.max-grade") > 0 && geoConvHelper.getConvBoundary().getZRange() > 0) {
517  before = SysUtils::getCurrentMillis();
518  PROGRESS_BEGIN_MESSAGE("Checking edge grade");
519  // user input is in %
520  myEdgeCont.checkGrade(oc.getFloat("geometry.max-grade") / 100);
521  PROGRESS_TIME_MESSAGE(before);
522  }
523 
524  //find accesses for pt rail stops
525  if (oc.exists("ptstop-output") && oc.isSet("ptstop-output")) {
526  before = SysUtils::getCurrentMillis();
527  PROGRESS_BEGIN_MESSAGE("Find accesses for pt rail stops");
528  double maxRadius = oc.getFloat("osm.stop-output.footway-access-distance");
529  int maxCount = oc.getInt("osm.stop-output.footway-max-accesses");
531  PROGRESS_TIME_MESSAGE(before);
532  }
533 
534  // report
535  WRITE_MESSAGE("-----------------------------------------------------");
536  WRITE_MESSAGE("Summary:");
538  WRITE_MESSAGE(" Network boundaries:");
539  WRITE_MESSAGE(" Original boundary : " + toString(geoConvHelper.getOrigBoundary()));
540  WRITE_MESSAGE(" Applied offset : " + toString(geoConvHelper.getOffsetBase()));
541  WRITE_MESSAGE(" Converted boundary : " + toString(geoConvHelper.getConvBoundary()));
542  WRITE_MESSAGE("-----------------------------------------------------");
544  // report on very large networks
545  if (MAX2(geoConvHelper.getConvBoundary().xmax(), geoConvHelper.getConvBoundary().ymax()) > 1000000 ||
546  MIN2(geoConvHelper.getConvBoundary().xmin(), geoConvHelper.getConvBoundary().ymin()) < -1000000) {
547  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");
548  }
549 }
550 
551 
552 /*
553 void
554 NBNetBuilder::computeSingleNode(NBNode* node, OptionsCont& oc, const std::set<std::string>& explicitTurnarounds, bool mayAddOrRemove) {
555  // for a single node do the following:
556  // sortEdges
557  // computeLaneShapes
558  // computeNodeShapes
559  // computeEdgeShapes
560 }
561 */
562 
563 
564 void
565 NBNetBuilder::moveToOrigin(GeoConvHelper& geoConvHelper, bool lefthand) {
566  long before = SysUtils::getCurrentMillis();
567  PROGRESS_BEGIN_MESSAGE("Moving network to origin");
568  Boundary boundary = geoConvHelper.getConvBoundary();
569  const double x = -boundary.xmin();
570  const double y = -(lefthand ? boundary.ymax() : boundary.ymin());
571  //if (lefthand) {
572  // y = boundary.ymax();
573  //}
574  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
575  (*i).second->reshiftPosition(x, y);
576  }
577  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
578  (*i).second->reshiftPosition(x, y);
579  }
580  for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) {
581  (*i).second->reshiftPosition(x, y);
582  }
583  for (std::map<std::string, NBPTStop*>::const_iterator i = myPTStopCont.begin(); i != myPTStopCont.end(); ++i) {
584  (*i).second->reshiftPostion(x, y);
585  }
586  geoConvHelper.moveConvertedBy(x, y);
587  PROGRESS_TIME_MESSAGE(before);
588 }
589 
590 
591 void
593  // mirror the network along the X-axis
594  for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
595  (*i).second->mirrorX();
596  }
597  for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
598  (*i).second->mirrorX();
599  }
600  for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) {
601  (*i).second->mirrorX();
602  }
603 }
604 
605 
606 bool
607 NBNetBuilder::transformCoordinate(Position& from, bool includeInBoundary, GeoConvHelper* from_srs) {
608  Position orig(from);
609  bool ok = GeoConvHelper::getProcessing().x2cartesian(from, includeInBoundary);
610  if (ok) {
611  const NBHeightMapper& hm = NBHeightMapper::get();
612  if (hm.ready()) {
613  if (from_srs != 0 && from_srs->usingGeoProjection()) {
614  from_srs->cartesian2geo(orig);
615  }
616  double z = hm.getZ(orig);
617  from = Position(from.x(), from.y(), z);
618  }
619  }
620  return ok;
621 }
622 
623 
624 bool
625 NBNetBuilder::transformCoordinates(PositionVector& from, bool includeInBoundary, GeoConvHelper* from_srs) {
626  const double maxLength = OptionsCont::getOptions().getFloat("geometry.max-segment-length");
627  if (maxLength > 0 && from.size() > 1) {
628  // transformation to cartesian coordinates must happen before we can check segment length
629  PositionVector copy = from;
630  for (int i = 0; i < (int) from.size(); i++) {
631  transformCoordinate(copy[i], false);
632  }
633  // check lengths and insert new points where needed (in the original
634  // coordinate system)
635  int inserted = 0;
636  for (int i = 0; i < (int)copy.size() - 1; i++) {
637  Position start = from[i + inserted];
638  Position end = from[i + inserted + 1];
639  double length = copy[i].distanceTo(copy[i + 1]);
640  const Position step = (end - start) * (maxLength / length);
641  int steps = 0;
642  while (length > maxLength) {
643  length -= maxLength;
644  steps++;
645  from.insert(from.begin() + i + inserted + 1, start + (step * steps));
646  inserted++;
647  }
648  }
649  // now perform the transformation again so that height mapping can be
650  // performed for the new points
651  }
652  bool ok = true;
653  for (int i = 0; i < (int) from.size(); i++) {
654  ok = ok && transformCoordinate(from[i], includeInBoundary, from_srs);
655  }
656  return ok;
657 }
658 
659 
660 /****************************************************************************/
NBNetBuilder()
Constructor.
NBTypeCont myTypeCont
The used container for street types.
Definition: NBNetBuilder.h:244
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:256
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:137
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:131
void sortOutgoingLanesConnections()
Sorts all lanes of all edges within the container by their direction.
Definition: NBEdgeCont.cpp:616
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)
void resetWritable()
Resets all options to be writeable.
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:117
void reduceGeometries(const double minDist)
Definition: NBEdgeCont.cpp:589
void addJoinExclusion(const std::vector< std::string > &ids, bool check=false)
Definition: NBNodeCont.cpp:503
int removeUnwishedNodes(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc, NBPTStopCont &sc, NBPTLineCont &lc, NBParkingCont &pc, bool removeGeometryNodes)
Removes "unwished" nodes.
Definition: NBNodeCont.cpp:369
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:122
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.
Definition: NBEdgeCont.cpp:943
void findAccessEdgesForRailStops(NBEdgeCont &cont, double d, int i)
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:90
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:67
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:799
double x() const
Returns the x-position.
Definition: Position.h:62
int joinLoadedClusters(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc)
Joins loaded junction clusters (see NIXMLNodesHandler)
Definition: NBNodeCont.cpp:537
T MAX2(T a, T b)
Definition: StdDefs.h:73
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.
Definition: NBEdgeCont.cpp:865
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.
Definition: NBNodeCont.cpp:910
std::map< std::string, NBEdge * >::const_iterator end() const
Returns the pointer to the end of the stored edges.
Definition: NBEdgeCont.h:198
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:443
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:632
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:47
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:199
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:64
void checkGeometries(const double maxAngle, const double minRadius, bool fix)
Definition: NBEdgeCont.cpp:597
void applyOptions(OptionsCont &oc)
Initialises the storage by applying given options.
void checkOverlap(double threshold, double zThreshold) const
check whether edges overlap
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)
static void reportWarnings()
reports warnings if any occured
Definition: NBRequest.cpp:773
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:203
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:561
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:53
std::map< std::string, NBEdge * >::const_iterator begin() const
Returns the pointer to the begin of the stored edges.
Definition: NBEdgeCont.h:190
static methods for processing the coordinates conversion for the current net
Definition: GeoConvHelper.h:59
void computeLanes2Lanes()
divides the incoming lanes on outgoing lanes
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
void removeUnwishedEdges(NBDistrictCont &dc)
Removes unwished edges (not in keep-edges)
Definition: NBEdgeCont.cpp:561
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:45
void setDefaults(int defaultNumLanes, double defaultLaneWidth, double defaultSpeed, int defaultPriority, SVCPermissions defaultPermissions)
Sets the default values.
Definition: NBTypeCont.cpp:46
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:77
NBEdgeCont myEdgeCont
The used container for edges.
Definition: NBNetBuilder.h:247
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:267
void computeEdge2Edges(bool noLeftMovers)
Computes for each edge the approached edges.
Definition: NBEdgeCont.cpp:624
void computeLaneShapes()
Computes the shapes of all lanes of all edges stored in the container.
Definition: NBEdgeCont.cpp:704
NBTrafficLightLogicCont myTLLCont
The used container for traffic light logics.
Definition: NBNetBuilder.h:250
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:67
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:125
void computeNodeShapes(double mismatchThreshold=-1)
Compute the junction shape for this node.
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:201
void splitGeometry(NBNodeCont &nc)
Splits edges into multiple if they have a complex geometry.
Definition: NBEdgeCont.cpp:578
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:44
std::map< std::string, NBPTStop * >::const_iterator end() const
Returns the pointer to the end of the stored pt stops.
Definition: NBPTStopCont.h:61
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
void setAsTLControlled(NBNode *node, NBTrafficLightLogicCont &tlc, TrafficLightType type, std::string id="")
Sets the given node as being controlled by a tls.
int guessSidewalks(double width, double minSpeed, double maxSpeed, bool fromPermissions)
add sidwalks to edges within the given limits or permissions and return the number of edges affected ...
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 appendTurnarounds(bool noTLSControlled)
Appends turnarounds to all edges stored in the container.
Definition: NBEdgeCont.cpp:680
int remapIDs(bool numericaIDs, bool reservedIDs)
remap node IDs accoring to options –numerical-ids and –reserved-ids
static void computeNodeTypes(NBNodeCont &nc)
Computes node types.
void moveToOrigin(GeoConvHelper &geoConvHelper, bool lefthand)
shift network so its lower left corner is at 0,0
A storage for options typed value containers)
Definition: OptionsCont.h:98
const Position getOffsetBase() const
Returns the network base.
void computeEdgeShapes()
Computes the shapes of all edges stored in the container.
Definition: NBEdgeCont.cpp:696
Represents a single node (junction) during network building.
Definition: NBNode.h:74
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:253
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:640
static long getCurrentMillis()
Returns the current time in milliseconds.
Definition: SysUtils.cpp:45
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:202
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:85
bool myHaveLoadedNetworkWithoutInternalEdges
whether a .net.xml without internal edges was loaded
Definition: NBNetBuilder.h:264
NBParkingCont myParkingCont
Definition: NBNetBuilder.h:261
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:143
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:200
double getZRange() const
Returns the elevation range of the boundary (z-axis)
Definition: Boundary.cpp:173
int remapIDs(bool numericaIDs, bool reservedIDs)
remap node IDs accoring to options –numerical-ids and –reserved-ids
NBNodeCont myNodeCont
The used container for nodes.
Definition: NBNetBuilder.h:241
void setTLControllingInformation(const NBEdgeCont &ec, const NBNodeCont &nc)
Informs the edges about being controlled by a tls.
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.
NBPTLineCont myPTLineCont
The used container for pt stops.
Definition: NBNetBuilder.h:259
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