Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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-2025 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>
37#include "NBAlgorithms.h"
38#include "NBAlgorithms_Ramps.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
64void
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
78void
79NBNetBuilder::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;
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"));
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 }
127 if (removed2 > 0) {
128 numRemovedEdges += removed2;
129 WRITE_MESSAGEF(TL(" Removed % edges based on vClass."), removed2);
130 }
131 }
132 if (mayAddOrRemove && oc.getFloat("keep-lanes.min-width") > 0.) {
133 const int removed = myEdgeCont.removeLanesByWidth(myDistrictCont, oc.getFloat("keep-lanes.min-width"));
134 if (removed > 0) {
135 numRemovedEdges += removed;
136 WRITE_MESSAGEF(TL(" Removed % edges because of lane width."), removed);
137 }
138 }
139 // Processing pt stops and lines
140 if (!myPTStopCont.getStops().empty()) {
141 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Processing public transport stops"));
142 if (!(oc.exists("ptline-output") && oc.isSet("ptline-output"))
143 && !oc.getBool("ptstop-output.no-bidi")) {
145 }
148 PROGRESS_TIME_MESSAGE(before);
149 }
150 if (mayAddOrRemove && oc.exists("keep-edges.components") && oc.getInt("keep-edges.components") > 0) {
151 // post process rail components unless they have stops
153 }
154 // removal is done, clean up roundabouts
155 if (numRemovedEdges > 0) {
157 }
158
159 if (!myPTLineCont.getLines().empty()) {
160 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Revising public transport stops based on pt lines"));
162 PROGRESS_TIME_MESSAGE(before);
163 }
164
165 if (!myPTStopCont.getStops().empty() && !oc.getBool("ptstop-output.no-bidi")) {
166 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Align pt stop id signs with corresponding edge id signs"));
168 PROGRESS_TIME_MESSAGE(before);
169 }
170 // analyze and fix railway topology
171 int numAddedBidi = 0;
172 if (oc.exists("railway.topology.all-bidi") && oc.getBool("railway.topology.all-bidi")) {
175 } else if (oc.exists("railway.topology.repair") && oc.getBool("railway.topology.repair")) {
176 // correct railway angles for angle-based connectivity heuristic
178 oc.getFloat("geometry.min-radius"), false,
179 oc.getBool("geometry.min-radius.fix.railways"), true);
182 }
184 if (numAddedBidi > 0) {
185 // update routes
187 }
188 if (oc.exists("railway.topology.direction-priority") && oc.getBool("railway.topology.direction-priority")) {
189 NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
191 } else if (oc.exists("railway.topology.extend-priority") && oc.getBool("railway.topology.extend-priority")) {
192 NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
194 }
195 if (oc.exists("railway.topology.output") && oc.isSet("railway.topology.output")) {
196 NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
198 }
199 if (oc.exists("railway.geometry.straighten") && oc.getBool("railway.geometry.straighten")) {
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 }
238 }
240 } else if ((myEdgeCont.hasGuessedRoundabouts() || oc.getBool("crossings.guess")) && oc.getBool("roundabouts.guess")) {
243 }
244 // join junctions (may create new "geometry"-nodes so it needs to come before removing these
245 if (mayAddOrRemove && oc.exists("junctions.join-exclude") && oc.isSet("junctions.join-exclude")) {
246 myNodeCont.addJoinExclusion(oc.getStringVector("junctions.join-exclude"));
247 }
249 if (mayAddOrRemove && oc.getBool("junctions.join")) {
250 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining junction clusters"));
251 numJoined += myNodeCont.joinJunctions(oc.getFloat("junctions.join-dist"), myDistrictCont, myEdgeCont, myTLLCont, myPTStopCont);
252 PROGRESS_TIME_MESSAGE(before);
253 }
254 if (numJoined > 0) {
255 WRITE_MESSAGEF(TL(" Joined % junction cluster(s)."), toString(numJoined));
256 }
257 if (mayAddOrRemove && oc.exists("junctions.join-same") && oc.getBool("junctions.join-same")) {
258 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining junctions with identical coordinates"));
260 PROGRESS_TIME_MESSAGE(before);
261 if (numJoined2 > 0) {
262 WRITE_MESSAGEF(TL(" Joined % junctions."), toString(numJoined2));
263 }
264 }
265 //
266 if (mayAddOrRemove && oc.exists("join-lanes") && oc.getBool("join-lanes")) {
267 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining lanes"));
269 PROGRESS_TIME_MESSAGE(before);
270 WRITE_MESSAGEF(TL(" Joined lanes on % edges."), toString(num));
271 }
272 //
273 if (mayAddOrRemove) {
274 const bool removeGeometryNodes = oc.exists("geometry.remove") && oc.getBool("geometry.remove");
275 before = PROGRESS_BEGIN_TIME_MESSAGE("Removing empty nodes" + std::string(removeGeometryNodes ? " and geometry nodes" : ""));
276 // removeUnwishedNodes needs turnDirections. @todo: try to call this less often
279 PROGRESS_TIME_MESSAGE(before);
280 WRITE_MESSAGEF(TL(" % nodes removed."), toString(numRemoved));
281 }
282
283 // MOVE TO ORIGIN
284 // compute new boundary after network modifications have taken place
285 Boundary boundary;
286 for (std::map<std::string, NBNode*>::const_iterator it = myNodeCont.begin(); it != myNodeCont.end(); ++it) {
287 boundary.add(it->second->getPosition());
288 }
289 for (std::map<std::string, NBEdge*>::const_iterator it = myEdgeCont.begin(); it != myEdgeCont.end(); ++it) {
290 boundary.add(it->second->getGeometry().getBoxBoundary());
291 }
292 geoConvHelper.setConvBoundary(boundary);
293
294 if (!oc.getBool("offset.disable-normalization") && oc.isDefault("offset.x") && oc.isDefault("offset.y")) {
295 moveToOrigin(geoConvHelper, lefthand);
296 }
297 geoConvHelper.computeFinal(lefthand); // information needed for location element fixed at this point
298
299 if (oc.exists("geometry.min-dist") && !oc.isDefault("geometry.min-dist")) {
300 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Reducing geometries"));
301 myEdgeCont.reduceGeometries(oc.getFloat("geometry.min-dist"));
302 PROGRESS_TIME_MESSAGE(before);
303 }
304 // @note: removing geometry can create similar edges so joinSimilarEdges must come afterwards
305 // @note: likewise splitting can destroy similarities so joinSimilarEdges must come before
306 if (mayAddOrRemove && oc.getBool("edges.join")) {
307 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining similar edges"));
308 const bool removeDuplicates = oc.exists("junctions.join-same") && oc.getBool("junctions.join-same");
310 // now we may have new chances to remove geometry if wished
311 if (oc.exists("geometry.remove") && oc.getBool("geometry.remove")) {
313 }
314 PROGRESS_TIME_MESSAGE(before);
315 }
316 if (oc.getBool("opposites.guess")) {
317 PROGRESS_BEGIN_MESSAGE(TL("guessing opposite direction edges"));
320 }
321 //
322 if (mayAddOrRemove && oc.exists("geometry.split") && oc.getBool("geometry.split")) {
323 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Splitting geometry edges"));
325 // newly split junctions might also be joinable
326 PROGRESS_TIME_MESSAGE(before);
327 if (oc.getBool("junctions.join-same")) {
329 if (numJoined3 > 0) {
330 WRITE_MESSAGEF(TL(" Joined % junctions after splitting geometry."), toString(numJoined3));
331 }
332 }
333 }
334 // turning direction
335 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing turning directions"));
337 PROGRESS_TIME_MESSAGE(before);
338 // correct edge geometries to avoid overlap
339 if (oc.exists("geometry.avoid-overlap") && oc.getBool("geometry.avoid-overlap")) {
341 }
342
343 // GUESS TLS POSITIONS
344 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Assigning nodes to traffic lights"));
345 if (oc.isSet("tls.set")) {
346 std::vector<std::string> tlControlledNodes = oc.getStringVector("tls.set");
348 for (std::vector<std::string>::const_iterator i = tlControlledNodes.begin(); i != tlControlledNodes.end(); ++i) {
349 NBNode* node = myNodeCont.retrieve(*i);
350 if (node == nullptr) {
351 WRITE_WARNING("Building a tl-logic for junction '" + *i + "' is not possible." + "\n The junction '" + *i + "' is not known.");
352 } else {
354 }
355 }
356 }
358 PROGRESS_TIME_MESSAGE(before);
359
360 // guess ramps (after guessing tls because ramps should not be build at traffic lights)
361 const bool modifyRamps = mayAddOrRemove && (
362 (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))
363 || (oc.exists("ramps.set") && oc.isSet("ramps.set")));
364 if (modifyRamps || (oc.exists("ramps.guess-acceleration-lanes") && oc.getBool("ramps.guess-acceleration-lanes"))) {
366 if (modifyRamps) {
367 PROGRESS_BEGIN_MESSAGE(TL("Guessing and setting on-/off-ramps"));
368 }
371 rc.computeRamps(*this, oc, mayAddOrRemove);
372
373 if (modifyRamps) {
374 PROGRESS_TIME_MESSAGE(before);
375 }
376 }
377 // guess bike lanes
378 if (mayAddOrRemove && ((oc.getBool("bikelanes.guess") || oc.getBool("bikelanes.guess.from-permissions")))) {
379 const int bikelanes = myEdgeCont.guessSpecialLanes(SVC_BICYCLE, oc.getFloat("default.bikelane-width"),
380 oc.getFloat("bikelanes.guess.min-speed"),
381 oc.getFloat("bikelanes.guess.max-speed"),
382 oc.getBool("bikelanes.guess.from-permissions"),
383 "bikelanes.guess.exclude",
384 myTLLCont);
385 WRITE_MESSAGEF(TL("Guessed % bike lanes."), toString(bikelanes));
386 }
387
388 // guess sidewalks
389 if (mayAddOrRemove && ((oc.getBool("sidewalks.guess") || oc.getBool("sidewalks.guess.from-permissions")))) {
390 const int sidewalks = myEdgeCont.guessSpecialLanes(SVC_PEDESTRIAN, oc.getFloat("default.sidewalk-width"),
391 oc.getFloat("sidewalks.guess.min-speed"),
392 oc.getFloat("sidewalks.guess.max-speed"),
393 oc.getBool("sidewalks.guess.from-permissions"),
394 "sidewalks.guess.exclude",
395 myTLLCont);
396 WRITE_MESSAGEF(TL("Guessed % sidewalks."), toString(sidewalks));
397 }
398 // check whether any not previously setable connections may be set now
400
401 // remap ids if wished
402 if (mayAddOrRemove) {
403 const bool numericalIDs = oc.getBool("numerical-ids");
404 const bool reservedIDs = oc.isSet("reserved-ids");
405 const bool keptIDs = oc.isSet("kept-ids");
406 int numChangedEdges = myEdgeCont.remapIDs(numericalIDs, reservedIDs, keptIDs, oc.getString("prefix.edge"), myPTStopCont);
407 int numChangedNodes = myNodeCont.remapIDs(numericalIDs, reservedIDs, keptIDs, oc.getString("prefix.junction"), myTLLCont);
408 if (numChangedEdges + numChangedNodes > 0) {
409 WRITE_MESSAGEF(TL("Remapped % edge IDs and % node IDs."), toString(numChangedEdges), toString(numChangedNodes));
410 }
411 }
412
413 //
414 if (oc.exists("geometry.max-angle")) {
416 DEG2RAD(oc.getFloat("geometry.max-angle")),
417 oc.getBool("geometry.max-angle.fix"),
418 oc.getFloat("geometry.min-radius"),
419 oc.getBool("geometry.min-radius.fix"),
420 oc.getBool("geometry.min-radius.fix.railways"));
421 }
422
423 // GEOMETRY COMPUTATION
424 //
425 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Sorting nodes' edges"));
427 PROGRESS_TIME_MESSAGE(before);
429 //
430 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing node shapes"));
431 if (oc.exists("geometry.junction-mismatch-threshold")) {
432 myNodeCont.computeNodeShapes(oc.getFloat("geometry.junction-mismatch-threshold"));
433 } else {
435 }
436 PROGRESS_TIME_MESSAGE(before);
437 //
438 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing edge shapes"));
439 myEdgeCont.computeEdgeShapes(oc.getBool("geometry.max-grade.fix") ? oc.getFloat("geometry.max-grade") / 100 : -1);
440 PROGRESS_TIME_MESSAGE(before);
441 // resort edges based on the node and edge shapes
444
445 // APPLY SPEED MODIFICATIONS
446 if (oc.exists("speed.offset")) {
447 const double speedOffset = oc.getFloat("speed.offset");
448 const double speedFactor = oc.getFloat("speed.factor");
449 const double speedMin = oc.getFloat("speed.minimum");
450 if (speedOffset != 0 || speedFactor != 1 || speedMin > 0) {
451 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Applying speed modifications"));
452 for (const auto& it : myEdgeCont) {
453 NBEdge* const e = it.second;
454 for (int i = 0; i < e->getNumLanes(); i++) {
455 e->setSpeed(i, MAX2(e->getLaneSpeed(i) * speedFactor + speedOffset, speedMin));
456 }
457 }
458 PROGRESS_TIME_MESSAGE(before);
459 }
460 }
461
462 // CONNECTIONS COMPUTATION
463 //
464 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing node types"));
467 PROGRESS_TIME_MESSAGE(before);
468 //
469 myNetworkHaveCrossings = oc.getBool("walkingareas");
470 if (mayAddOrRemove && oc.getBool("crossings.guess")) {
472 int crossings = 0;
473 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
474 crossings += (*i).second->guessCrossings();
475 }
476 WRITE_MESSAGEF(TL("Guessed % pedestrian crossings."), toString(crossings));
477 }
479 bool haveValidCrossings = false;
480 // recheck whether we had crossings in the input
481 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
482 if (i->second->getCrossings().size() > 0) {
484 haveValidCrossings = true;
485 break;
486 } else if (i->second->getCrossingsIncludingInvalid().size() > 0) {
488 }
489 }
490 if (myNetworkHaveCrossings && !haveValidCrossings) {
491 // initial crossings removed or invalidated, keep walkingareas
492 oc.resetWritable();
493 oc.set("walkingareas", "true");
494 }
495 }
496
497 if (!mayAddOrRemove && myNetworkHaveCrossings) {
498 // crossings added via netedit
499 oc.resetWritable();
500 oc.set("no-internal-links", "false");
501 }
502
503 //
504 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing priorities"));
506 PROGRESS_TIME_MESSAGE(before);
507 //
508 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing approached edges"));
509 myEdgeCont.computeEdge2Edges(oc.getBool("no-left-connections"));
510 PROGRESS_TIME_MESSAGE(before);
511 //
512 if (oc.getBool("roundabouts.guess")) {
513 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Guessing and setting roundabouts"));
514 const int numGuessed = myEdgeCont.guessRoundabouts();
515 if (numGuessed > 0) {
516 WRITE_MESSAGEF(TL(" Guessed % roundabout(s)."), toString(numGuessed));
517 }
518 PROGRESS_TIME_MESSAGE(before);
519 }
521 //
522 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing approaching lanes"));
524 PROGRESS_TIME_MESSAGE(before);
525 //
526 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Dividing of lanes on approached lanes"));
529 PROGRESS_TIME_MESSAGE(before);
530 //
531 if (oc.getBool("fringe.guess")) {
532 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Guessing Network fringe"));
533 const int numGuessed = myNodeCont.guessFringe();
534 if (numGuessed > 0) {
535 WRITE_MESSAGEF(TL(" Guessed % fringe nodes."), toString(numGuessed));
536 }
537 PROGRESS_TIME_MESSAGE(before);
538 }
539 //
540 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Processing turnarounds"));
541 if (!oc.getBool("no-turnarounds")) {
543 oc.getBool("no-turnarounds.tls"),
544 oc.getBool("no-turnarounds.fringe"),
545 oc.getBool("no-turnarounds.except-deadend"),
546 oc.getBool("no-turnarounds.except-turnlane"),
547 oc.getBool("no-turnarounds.geometry"));
548 } else {
549 myEdgeCont.appendTurnarounds(explicitTurnarounds, oc.getBool("no-turnarounds.tls"));
550 }
551 if (oc.exists("railway.topology.repair.stop-turn") && oc.getBool("railway.topology.repair.stop-turn")
552 && myPTStopCont.getStops().size() > 0) {
553 // allow direction reversal at all bidi-edges with stops
555 }
556 PROGRESS_TIME_MESSAGE(before);
557 //
558 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Rechecking of lane endings"));
560 PROGRESS_TIME_MESSAGE(before);
561
562 if (myNetworkHaveCrossings && !oc.getBool("no-internal-links")) {
563 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
564 i->second->buildCrossingsAndWalkingAreas();
565 }
566 } else {
567 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
568 // needed by netedit if the last crossings was deleted from the network
569 // and walkingareas have been invalidated since the last call to compute()
570 i->second->discardWalkingareas();
571 }
572 if (oc.getBool("no-internal-links")) {
573 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
574 i->second->discardAllCrossings(false);
575 }
576 }
577 }
578 // join traffic lights (after building connections)
579 if (oc.getBool("tls.join")) {
580 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining traffic light nodes"));
581 myNodeCont.joinTLS(myTLLCont, oc.getFloat("tls.join-dist"));
582 PROGRESS_TIME_MESSAGE(before);
583 }
584
585 // COMPUTING RIGHT-OF-WAY AND TRAFFIC LIGHT PROGRAMS
586 //
587 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing traffic light control information"));
589 if (oc.exists("opendrive-files") && oc.isSet("opendrive-files")) {
591 }
592 PROGRESS_TIME_MESSAGE(before);
593 //
594 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing node logics"));
596 PROGRESS_TIME_MESSAGE(before);
597
598 //
599 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing traffic light logics"));
600 std::pair<int, int> numbers = myTLLCont.computeLogics(oc);
601 PROGRESS_TIME_MESSAGE(before);
602 std::string progCount = "";
603 if (numbers.first != numbers.second) {
604 progCount = "(" + toString(numbers.second) + " programs) ";
605 }
606 WRITE_MESSAGEF(TL(" % traffic light(s) %computed."), toString(numbers.first), progCount);
607 if (oc.exists("opendrive-files") && oc.isSet("opendrive-files") && oc.getBool("opendrive.signal-groups")) {
609 }
610
611 for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
612 (*i).second->sortOutgoingConnectionsByIndex();
613 }
614 // FINISHING INNER EDGES
615 std::set<NBTrafficLightDefinition*> largeNodeTLS;
616 if (!oc.getBool("no-internal-links")) {
617 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Building inner edges"));
618 // walking areas shall only be built if crossings are wished as well
619 for (const auto& item : myNodeCont) {
620 if (item.second->buildInnerEdges() > NBTrafficLightDefinition::MIN_YELLOW_SECONDS) {
621 const std::set<NBTrafficLightDefinition*>& tlDefs = item.second->getControllingTLS();
622 largeNodeTLS.insert(tlDefs.begin(), tlDefs.end());
623 }
624 }
625 PROGRESS_TIME_MESSAGE(before);
626 }
627 // PATCH NODE SHAPES
628 if (oc.getFloat("junctions.scurve-stretch") > 0) {
629 // @note: nodes have collected correction hints in buildInnerEdges()
630 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("stretching junctions to smooth geometries"));
633 myEdgeCont.computeEdgeShapes(oc.getBool("geometry.max-grade.fix") ? oc.getFloat("geometry.max-grade") / 100 : -1);
634 for (const auto& item : myNodeCont) {
635 item.second->buildInnerEdges();
636 }
637 PROGRESS_TIME_MESSAGE(before);
638 }
639 if (myEdgeCont.getNumEdgeSplits() > 0 && !oc.getBool("no-internal-links")) {
640 // edges with custom lengths were split, this has to take into account
641 // internal edge lengths (after geometry computation)
643 }
644 // recheck phases for large junctions
645 for (NBTrafficLightDefinition* def : largeNodeTLS) {
647 }
648 // compute lane-to-lane node logics (require traffic lights and inner edges to be done)
650
651 // remove guessed traffic lights at junctions without conflicts (requires computeLogics2)
653
654 // compute keepClear status (requires computeLogics2)
656
657 //
658 if (oc.isSet("street-sign-output")) {
659 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Generating street signs"));
661 PROGRESS_TIME_MESSAGE(before);
662 }
663
664
665 if (lefthand != oc.getBool("flip-y-axis")) {
666 mirrorX();
667 }
668
669 if (oc.exists("geometry.check-overlap") && oc.getFloat("geometry.check-overlap") > 0) {
670 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Checking overlapping edges"));
671 myEdgeCont.checkOverlap(oc.getFloat("geometry.check-overlap"), oc.getFloat("geometry.check-overlap.vertical-threshold"));
672 PROGRESS_TIME_MESSAGE(before);
673 }
674 if (geoConvHelper.getConvBoundary().getZRange() > 0 && oc.getFloat("geometry.max-grade") > 0) {
675 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Checking edge grade"));
676 // user input is in %
677 myEdgeCont.checkGrade(oc.getFloat("geometry.max-grade") / 100);
678 PROGRESS_TIME_MESSAGE(before);
679 }
680
681 // find accesses for pt rail stops and add bidi-stops
682 if (!myPTStopCont.getStops().empty()) {
683 // re-adapt stop lanes after adding special lanes and cutting edge shapes at junction
686 int numBidiStops = 0;
687 if (!oc.getBool("ptstop-output.no-bidi")) {
689 } else {
690 numBidiStops = myPTStopCont.countBidiStops(myEdgeCont);
691 }
692 PROGRESS_BEGIN_MESSAGE(TL("Find accesses for pt rail stops"));
693 double maxRadius = oc.getFloat("railway.access-distance");
694 double accessFactor = oc.getFloat("railway.access-factor");
695 int maxCount = oc.getInt("railway.max-accesses");
696 myPTStopCont.findAccessEdgesForRailStops(myEdgeCont, maxRadius, maxCount, accessFactor);
697 PROGRESS_TIME_MESSAGE(before);
698 if (numBidiStops > 0) {
700 }
701 }
703 // ensure that all turning lanes have sufficient permissions
705 if (oc.exists("ptline-clean-up") && oc.getBool("ptline-clean-up")) {
706 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Cleaning up public transport stops that are not served by any line"));
707 std::set<std::string> usedStops = myPTLineCont.getServedPTStops();
708 myPTStopCont.postprocess(usedStops);
709 PROGRESS_TIME_MESSAGE(before);
710 } else {
711 int numDeletedStops = myPTStopCont.cleanupDeleted(myEdgeCont);
712 if (numDeletedStops > 0) {
713 WRITE_WARNINGF(TL("Removed % pt stops because they could not be assigned to the network"), toString(numDeletedStops));
714 }
715 }
716
717 if (oc.exists("ignore-change-restrictions") && !oc.isDefault("ignore-change-restrictions")) {
718 SVCPermissions ignoring = parseVehicleClasses(oc.getStringVector("ignore-change-restrictions"));
720 }
721
723 // report on very large networks
724 if (MAX2(geoConvHelper.getConvBoundary().xmax(), geoConvHelper.getConvBoundary().ymax()) > 1000000 ||
725 MIN2(geoConvHelper.getConvBoundary().xmin(), geoConvHelper.getConvBoundary().ymin()) < -1000000) {
726 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"));
727 }
728
729 // clean up OSM processing params
730 if (oc.exists("osm-files") && oc.isSet("osm-files")) {
731 for (auto item : myEdgeCont) {
732 item.second->unsetParameter(NBTrafficLightDefinition::OSM_DIRECTION);
733 }
734 }
735}
736
737
738void
739NBNetBuilder::moveToOrigin(GeoConvHelper& geoConvHelper, bool lefthand) {
740 long before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Moving network to origin"));
741 Boundary boundary = geoConvHelper.getConvBoundary();
742 const double x = -boundary.xmin();
743 const double y = -(lefthand ? boundary.ymax() : boundary.ymin());
744 //if (lefthand) {
745 // y = boundary.ymax();
746 //}
747 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
748 (*i).second->reshiftPosition(x, y);
749 }
750 for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
751 (*i).second->reshiftPosition(x, y);
752 }
753 for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) {
754 (*i).second->reshiftPosition(x, y);
755 }
756 for (const auto& stopIt : myPTStopCont.getStops()) {
757 stopIt.second->reshiftPosition(x, y);
758 }
759 geoConvHelper.moveConvertedBy(x, y);
760 PROGRESS_TIME_MESSAGE(before);
761}
762
763
764void
766 // mirror the network along the X-axis
767 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
768 (*i).second->mirrorX();
769 }
770 for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
771 (*i).second->mirrorX();
772 }
773 for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) {
774 (*i).second->mirrorX();
775 }
776 for (const auto& stopIt : myPTStopCont.getStops()) {
777 stopIt.second->mirrorX();
778 }
779}
780
781
782bool
783NBNetBuilder::transformCoordinate(Position& from, bool includeInBoundary, GeoConvHelper* from_srs) {
784 Position orig(from);
785 bool ok = true;
787 && GeoConvHelper::getLoaded().usingGeoProjection()
788 && from_srs != nullptr
789 && from_srs->usingGeoProjection()
790 && *from_srs != GeoConvHelper::getLoaded()) {
791 from_srs->cartesian2geo(from);
792 ok &= GeoConvHelper::getLoaded().x2cartesian(from, false);
793 }
794 if (from_srs == nullptr || !GeoConvHelper::getProcessing().usingGeoProjection()) {
795 // if getProcessing is not a geo-projection, assume it a cartesian transformation (i.e. shift)
796 ok &= GeoConvHelper::getProcessing().x2cartesian(from, includeInBoundary);
797
798 if (from_srs == nullptr && GeoConvHelper::getProcessing().usingGeoProjection()
800 && GeoConvHelper::getLoaded().usingGeoProjection()) {
801 // apply geo patch to loaded geo-network (offset must match)
802 from = from + GeoConvHelper::getLoaded().getOffset();
803 }
804 }
805 if (ok) {
807 if (hm.ready()) {
808 if (from_srs != nullptr && from_srs->usingGeoProjection()) {
809 from_srs->cartesian2geo(orig);
810 }
811 from.setz(hm.getZ(orig));
812 }
813 }
814 const double eps = 1e-6;
815 from.set(std::round(from.x() / eps) * eps, std::round(from.y() / eps) * eps, std::round(from.z() / eps) * eps);
816 return ok;
817}
818
819
820bool
821NBNetBuilder::transformCoordinates(PositionVector& from, bool includeInBoundary, GeoConvHelper* from_srs) {
822 const double maxLength = OptionsCont::getOptions().getFloat("geometry.max-segment-length");
823 if (maxLength > 0 && from.size() > 1) {
824 // transformation to cartesian coordinates must happen before we can check segment length
825 PositionVector copy = from;
826 for (int i = 0; i < (int) from.size(); i++) {
827 transformCoordinate(copy[i], false);
828 }
829 addGeometrySegments(from, copy, maxLength);
830 }
831 bool ok = true;
832 for (int i = 0; i < (int) from.size(); i++) {
833 ok = ok && transformCoordinate(from[i], includeInBoundary, from_srs);
834 }
835 return ok;
836}
837
838
839int
840NBNetBuilder::addGeometrySegments(PositionVector& from, const PositionVector& cartesian, const double maxLength) {
841 // check lengths and insert new points where needed (in the original
842 // coordinate system)
843 int inserted = 0;
844 for (int i = 0; i < (int)cartesian.size() - 1; i++) {
845 Position start = from[i + inserted];
846 Position end = from[i + inserted + 1];
847 double length = cartesian[i].distanceTo(cartesian[i + 1]);
848 const Position step = (end - start) * (maxLength / length);
849 int steps = 0;
850 while (length > maxLength) {
851 length -= maxLength;
852 steps++;
853 from.insert(from.begin() + i + inserted + 1, start + (step * steps));
854 inserted++;
855 }
856 }
857 return inserted;
858}
859
860
861bool
863 // see GNELoadThread::fillOptions
864 return OptionsCont::getOptions().exists("new");
865}
866
867
868/****************************************************************************/
#define DEG2RAD(x)
Definition GeomHelper.h:35
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:288
#define WRITE_MESSAGEF(...)
Definition MsgHandler.h:290
#define WRITE_WARNING(msg)
Definition MsgHandler.h:287
#define PROGRESS_BEGIN_TIME_MESSAGE(msg)
Definition MsgHandler.h:293
#define TL(string)
Definition MsgHandler.h:305
#define PROGRESS_TIME_MESSAGE(before)
Definition MsgHandler.h:294
#define PROGRESS_DONE_MESSAGE()
Definition MsgHandler.h:292
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition MsgHandler.h:291
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
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:75
double ymin() const
Returns minimum y-coordinate.
Definition Boundary.cpp:127
double xmin() const
Returns minimum x-coordinate.
Definition Boundary.cpp:115
double ymax() const
Returns maximum y-coordinate.
Definition Boundary.cpp:133
double xmax() const
Returns maximum x-coordinate.
Definition Boundary.cpp:121
double getZRange() const
Returns the elevation range of the boundary (z-axis)
Definition Boundary.cpp:163
static methods for processing the coordinates conversion for the current net
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 & getProcessing()
the coordinate transformation to use for input conversion and processing
static int getNumLoaded()
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.
static GeoConvHelper & getLoaded()
the coordinate transformation that was loaded fron an input file
std::map< std::string, NBDistrict * >::const_iterator end() const
Returns the pointer to the end of the stored districts.
std::map< std::string, NBDistrict * >::const_iterator begin() const
Returns the pointer to the begin of the stored districts.
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.
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.
void appendRailwayTurnarounds(const NBPTStopCont &sc)
Appends turnarounds to all bidiRail edges with stops.
std::map< std::string, NBEdge * >::const_iterator begin() const
Returns the pointer to the begin of the stored edges.
Definition NBEdgeCont.h:171
void updateAllChangeRestrictions(SVCPermissions ignoring)
modify all restrictions on lane changing for edges and connections
void recheckPostProcessConnections()
Try to set any stored connections.
void recheckLanes()
Rechecks whether all lanes have a successor for each of the stored edges.
void checkGeometries(const double maxAngle, bool fixAngle, const double minRadius, bool fix, bool fixRailways, bool silent=false)
void reduceGeometries(const double minDist)
void cleanupRoundabouts()
std::map< std::string, NBEdge * >::const_iterator end() const
Returns the pointer to the end of the stored edges.
Definition NBEdgeCont.h:178
void splitGeometry(NBDistrictCont &dc, NBNodeCont &nc)
Splits edges into multiple if they have a complex geometry.
void computeLanes2Edges()
Computes for each edge which lanes approach the next edges.
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)
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.
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.
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 removeLanesByWidth(NBDistrictCont &dc, const double minWidth)
int removeEdgesBySpeed(NBDistrictCont &dc)
return number of edges removed
int remapIDs(bool numericaIDs, bool reservedIDs, bool keptIDs, const std::string &prefix, NBPTStopCont &sc)
remap node IDs accoring to options –numerical-ids and –reserved-ids
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:2210
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition NBEdge.cpp:4403
int getNumLanes() const
Returns the number of lanes.
Definition NBEdge.h:520
static void setDefaultConnectionLength(double length)
Definition NBEdge.h:390
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.
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
NBDistrictCont myDistrictCont
The used container for districts.
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.
NBEdgeCont myEdgeCont
The used container for edges.
NBParkingCont myParkingCont
~NBNetBuilder()
Destructor.
NBTypeCont myTypeCont
The used container for street types.
NBPTStopCont myPTStopCont
The used container for pt stops.
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.
static bool runningNetedit()
whether netbuilding takes place in the context of netedit
void avoidOverlap()
fix overlap
int removeRailComponents(NBDistrictCont &dc, NBEdgeCont &ec, NBPTStopCont &sc)
std::map< std::string, NBNode * >::const_iterator begin() const
Returns the pointer to the begin of the stored nodes.
Definition NBNodeCont.h:113
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)
void addJoinExclusion(const std::vector< std::string > &ids)
int joinLoadedClusters(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc)
Joins loaded junction clusters (see NIXMLNodesHandler)
int remapIDs(bool numericaIDs, bool reservedIDs, bool keptIDs, 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.
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.
std::map< std::string, NBNode * >::const_iterator end() const
Returns the pointer to the end of the stored nodes.
Definition NBNodeCont.h:118
int removeComponents(NBDistrictCont &dc, NBEdgeCont &ec, const int numKeep, bool hasPTStops)
Checks the network for weak connectivity and removes all but the largest components....
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.
int removeIsolatedRoads(NBDistrictCont &dc, NBEdgeCont &ec)
Removes sequences of edges that are not connected with a junction. Simple roads without junctions som...
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
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.
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.
bool resetNodeShapes()
reset all node shapes
Represents a single node (junction) during network building.
Definition NBNode.h:66
static void initRailSignalClasses(const NBNodeCont &nc)
initialize signalized rail classes
Definition NBNode.cpp:2623
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()
const std::map< std::string, NBPTLine * > & getLines() const
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
int cleanupDeleted(NBEdgeCont &cont)
remove stops on non existing (removed) edges
const std::map< std::string, std::shared_ptr< NBPTStop > > & getStops() const
Returns an unmodifiable reference to the stored pt stops.
void postprocess(std::set< std::string > &usedStops)
void localizePTStops(NBEdgeCont &cont)
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)
int countBidiStops(NBEdgeCont &cont) const
count number of stop-pairs for superposed rail-edges
static int straigthenCorrdidor(NBEdgeCont &ec, double maxAngle)
static int guessRailSignals(NBEdgeCont &ec, NBPTStopCont &sc)
static int repairTopology(NBEdgeCont &ec, NBPTStopCont &sc, NBPTLineCont &lc)
static void extendDirectionPriority(NBEdgeCont &ec, bool fromUniDir)
static void analyzeTopology(NBEdgeCont &ec)
static int makeAllBidi(NBEdgeCont &ec)
void computeRamps(NBNetBuilder &nb, OptionsCont &oc, bool mayAddOrRemove)
static void reportWarnings()
reports warnings if any occurred
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.
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.
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:82
double x() const
Returns the x-position.
Definition Position.h:52
void setz(double z)
set position z
Definition Position.h:77
double z() const
Returns the z-position.
Definition Position.h:62
double y() const
Returns the y-position.
Definition Position.h:57
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
get key
static long getCurrentMillis()
Returns the current time in milliseconds.
Definition SysUtils.cpp:44