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) {
81
82 const bool lefthand = oc.getBool("lefthand");
83 if (lefthand) {
84 mirrorX();
85 }
86
87 // MODIFYING THE SETS OF NODES AND EDGES
88 // Removes edges that are connecting the same node
89 long before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Removing self-loops"));
90 int numRemovedEdges = 0;
93 if (mayAddOrRemove && oc.exists("remove-edges.isolated") && oc.getBool("remove-edges.isolated")) {
94 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Finding isolated roads"));
97 }
98 if (mayAddOrRemove && oc.exists("keep-edges.components") && oc.getInt("keep-edges.components") > 0) {
99 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Finding largest components"));
100 const bool hasStops = oc.exists("ptstop-output") && oc.isSet("ptstop-output") && !myPTStopCont.getStops().empty();
101 numRemovedEdges += myNodeCont.removeComponents(myDistrictCont, myEdgeCont, oc.getInt("keep-edges.components"), hasStops);
102 PROGRESS_TIME_MESSAGE(before);
103 }
104 if (mayAddOrRemove && oc.exists("keep-edges.postload") && oc.getBool("keep-edges.postload")) {
105 // pre-process lines to set permissions
106 if (!myPTLineCont.getLines().empty()) {
107 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Revising public transport stops based on pt lines"));
109 PROGRESS_TIME_MESSAGE(before);
110 }
111 if (oc.isSet("keep-edges.explicit") || oc.isSet("keep-edges.input-file")) {
112 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Removing unwished edges"));
114 PROGRESS_TIME_MESSAGE(before);
115 }
116 const int removed = myEdgeCont.removeEdgesBySpeed(myDistrictCont);
117 if (removed > 0) {
118 numRemovedEdges += removed;
119 WRITE_MESSAGEF(TL(" Removed % edges because by minimum speed."), removed);
120 }
122 if (removed2 > 0) {
123 numRemovedEdges += removed2;
124 WRITE_MESSAGEF(TL(" Removed % edges based on vClass."), removed2);
125 }
126 }
127 if (mayAddOrRemove && oc.getFloat("keep-lanes.min-width") > 0.) {
128 const int removed = myEdgeCont.removeLanesByWidth(myDistrictCont, oc.getFloat("keep-lanes.min-width"));
129 if (removed > 0) {
130 numRemovedEdges += removed;
131 WRITE_MESSAGEF(TL(" Removed % edges because of lane width."), removed);
132 }
133 }
134 if (mayAddOrRemove && oc.exists("junctions.attach-removed") && oc.getFloat("junctions.attach-removed") >= 0) {
135 const int numSplit = myEdgeCont.attachRemoved(myNodeCont, myDistrictCont, oc.getFloat("junctions.attach-removed"));
136 if (numSplit > 0) {
137 WRITE_MESSAGEF(TL(" Split % edges to attach removed nodes"), numSplit);
138 }
139 }
140 // Processing pt stops and lines
141 if (!myPTStopCont.getStops().empty()) {
142 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Processing public transport stops"));
143 if (!(oc.exists("ptline-output") && oc.isSet("ptline-output"))
144 && !oc.getBool("ptstop-output.no-bidi")) {
146 }
149 PROGRESS_TIME_MESSAGE(before);
150 }
151 if (mayAddOrRemove && oc.exists("keep-edges.components") && oc.getInt("keep-edges.components") > 0) {
152 // post process rail components unless they have stops
154 }
155 // removal is done, clean up roundabouts
156 if (numRemovedEdges > 0) {
158 }
159
160 if (!myPTLineCont.getLines().empty()) {
161 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Revising public transport stops based on pt lines"));
163 PROGRESS_TIME_MESSAGE(before);
164 }
165
166 if (!myPTStopCont.getStops().empty() && !oc.getBool("ptstop-output.no-bidi")) {
167 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Align pt stop id signs with corresponding edge id signs"));
169 PROGRESS_TIME_MESSAGE(before);
170 }
171 // analyze and fix railway topology
172 int numAddedBidi = 0;
173 if (oc.exists("railway.topology.all-bidi") && oc.getBool("railway.topology.all-bidi")) {
176 } else if (oc.exists("railway.topology.repair") && oc.getBool("railway.topology.repair")) {
177 // correct railway angles for angle-based connectivity heuristic
179 oc.getFloat("geometry.min-radius"), false,
180 oc.getBool("geometry.min-radius.fix.railways"), true);
183 }
185 if (numAddedBidi > 0) {
186 // update routes
188 }
189 if (oc.exists("railway.topology.direction-priority") && oc.getBool("railway.topology.direction-priority")) {
190 NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
192 } else if (oc.exists("railway.topology.extend-priority") && oc.getBool("railway.topology.extend-priority")) {
193 NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
195 }
196 if (oc.exists("railway.topology.output") && oc.isSet("railway.topology.output")) {
197 NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
199 }
200 if (oc.exists("railway.geometry.straighten") && oc.getBool("railway.geometry.straighten")) {
201 NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
203 }
204
205
206 if (mayAddOrRemove && oc.exists("edges.join-tram-dist") && oc.getFloat("edges.join-tram-dist") >= 0) {
207 // should come before joining junctions
208 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining tram edges"));
209 int numJoinedTramEdges = myEdgeCont.joinTramEdges(myDistrictCont, myPTStopCont, myPTLineCont, oc.getFloat("edges.join-tram-dist"));
210 PROGRESS_TIME_MESSAGE(before);
211 if (numJoinedTramEdges > 0) {
212 WRITE_MESSAGEF(TL(" Joined % tram edges into roads."), toString(numJoinedTramEdges));
213 }
214 }
215 if (oc.getBool("junctions.join")
216 || (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))
217 || oc.getBool("tls.guess.joining")
218 || (oc.exists("tls.guess-signals") && oc.getBool("tls.guess-signals"))) {
219 // preliminary geometry computations to determine the length of edges
220 // This depends on turning directions and sorting of edge list
221 // in case junctions are joined geometry computations have to be repeated
222 // preliminary roundabout computations to avoid damaging roundabouts via junctions.join or ramps.guess
228 if (oc.getBool("roundabouts.guess")) {
230 }
231 const std::set<EdgeSet>& roundabouts = myEdgeCont.getRoundabouts();
232 for (std::set<EdgeSet>::const_iterator it_round = roundabouts.begin();
233 it_round != roundabouts.end(); ++it_round) {
234 std::vector<std::string> nodeIDs;
235 for (EdgeSet::const_iterator it_edge = it_round->begin(); it_edge != it_round->end(); ++it_edge) {
236 nodeIDs.push_back((*it_edge)->getToNode()->getID());
237 }
239 }
241 } else if ((myEdgeCont.hasGuessedRoundabouts() || oc.getBool("crossings.guess")) && oc.getBool("roundabouts.guess")) {
244 }
245 // join junctions (may create new "geometry"-nodes so it needs to come before removing these
246 if (mayAddOrRemove && oc.exists("junctions.join-exclude") && oc.isSet("junctions.join-exclude")) {
247 myNodeCont.addJoinExclusion(oc.getStringVector("junctions.join-exclude"));
248 }
250 if (mayAddOrRemove && oc.getBool("junctions.join")) {
251 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining junction clusters"));
252 numJoined += myNodeCont.joinJunctions(oc.getFloat("junctions.join-dist"), myDistrictCont, myEdgeCont, myTLLCont, myPTStopCont);
253 PROGRESS_TIME_MESSAGE(before);
254 }
255 if (numJoined > 0) {
256 WRITE_MESSAGEF(TL(" Joined % junction cluster(s)."), toString(numJoined));
257 }
258 if (mayAddOrRemove && oc.getFloat("junctions.join-same") >= 0) {
259 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining junctions with similar coordinates"));
260 int numJoined2 = myNodeCont.joinSameJunctions(myDistrictCont, myEdgeCont, myTLLCont, oc.getFloat("junctions.join-same"));
261 PROGRESS_TIME_MESSAGE(before);
262 if (numJoined2 > 0) {
263 WRITE_MESSAGEF(TL(" Joined % junctions."), toString(numJoined2));
264 }
265 }
266 //
267 if (mayAddOrRemove && oc.exists("join-lanes") && oc.getBool("join-lanes")) {
268 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining lanes"));
270 PROGRESS_TIME_MESSAGE(before);
271 WRITE_MESSAGEF(TL(" Joined lanes on % edges."), toString(num));
272 }
273 //
274 if (mayAddOrRemove) {
275 const bool removeGeometryNodes = oc.exists("geometry.remove") && oc.getBool("geometry.remove");
276 before = PROGRESS_BEGIN_TIME_MESSAGE("Removing empty nodes" + std::string(removeGeometryNodes ? " and geometry nodes" : ""));
277 // removeUnwishedNodes needs turnDirections. @todo: try to call this less often
280 PROGRESS_TIME_MESSAGE(before);
281 WRITE_MESSAGEF(TL(" % nodes removed."), toString(numRemoved));
282 }
283
284 // MOVE TO ORIGIN
285 // compute new boundary after network modifications have taken place
286 Boundary boundary;
287 for (std::map<std::string, NBNode*>::const_iterator it = myNodeCont.begin(); it != myNodeCont.end(); ++it) {
288 boundary.add(it->second->getPosition());
289 }
290 for (std::map<std::string, NBEdge*>::const_iterator it = myEdgeCont.begin(); it != myEdgeCont.end(); ++it) {
291 boundary.add(it->second->getGeometry().getBoxBoundary());
292 }
293 geoConvHelper.setConvBoundary(boundary);
294
295 if (!oc.getBool("offset.disable-normalization") && oc.isDefault("offset.x") && oc.isDefault("offset.y")) {
296 moveToOrigin(geoConvHelper, lefthand);
297 }
298 roundInputs();
299 geoConvHelper.computeFinal(lefthand); // information needed for location element fixed at this point
300
301 // reset shapes and angles for stable re-computation
304 }
305
306 if (oc.exists("geometry.min-dist") && !oc.isDefault("geometry.min-dist")) {
307 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Reducing geometries"));
308 myEdgeCont.reduceGeometries(oc.getFloat("geometry.min-dist"));
309 PROGRESS_TIME_MESSAGE(before);
310 }
311 // @note: removing geometry can create similar edges so joinSimilarEdges must come afterwards
312 // @note: likewise splitting can destroy similarities so joinSimilarEdges must come before
313 if (mayAddOrRemove && oc.getBool("edges.join")) {
314 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining similar edges"));
315 const bool removeDuplicates = oc.getFloat("junctions.join-same") >= 0;
317 // now we may have new chances to remove geometry if wished
318 if (oc.exists("geometry.remove") && oc.getBool("geometry.remove")) {
320 }
321 PROGRESS_TIME_MESSAGE(before);
322 }
323 if (oc.getBool("opposites.guess")) {
324 PROGRESS_BEGIN_MESSAGE(TL("guessing opposite direction edges"));
327 }
328 //
329 if (mayAddOrRemove && oc.exists("geometry.split") && oc.getBool("geometry.split")) {
330 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Splitting geometry edges"));
332 // newly split junctions might also be joinable
333 PROGRESS_TIME_MESSAGE(before);
334 if (oc.getFloat("junctions.join-same") >= 0) {
335 int numJoined3 = myNodeCont.joinSameJunctions(myDistrictCont, myEdgeCont, myTLLCont, oc.getFloat("junctions.join-same"));
336 if (numJoined3 > 0) {
337 WRITE_MESSAGEF(TL(" Joined % junctions after splitting geometry."), toString(numJoined3));
338 }
339 }
340 }
341 // turning direction
342 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing turning directions"));
344 PROGRESS_TIME_MESSAGE(before);
345 // correct edge geometries to avoid overlap
346 if (oc.exists("geometry.avoid-overlap") && oc.getBool("geometry.avoid-overlap")) {
348 }
349
350 // GUESS TLS POSITIONS
351 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Assigning nodes to traffic lights"));
352 if (oc.isSet("tls.set")) {
353 std::vector<std::string> tlControlledNodes = oc.getStringVector("tls.set");
355 for (std::vector<std::string>::const_iterator i = tlControlledNodes.begin(); i != tlControlledNodes.end(); ++i) {
356 NBNode* node = myNodeCont.retrieve(*i);
357 if (node == nullptr) {
358 WRITE_WARNING("Building a tl-logic for junction '" + *i + "' is not possible." + "\n The junction '" + *i + "' is not known.");
359 } else {
361 }
362 }
363 }
365 PROGRESS_TIME_MESSAGE(before);
366
367 // guess ramps (after guessing tls because ramps should not be build at traffic lights)
368 const bool modifyRamps = mayAddOrRemove && (
369 (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))
370 || (oc.exists("ramps.set") && oc.isSet("ramps.set")));
371 if (modifyRamps || (oc.exists("ramps.guess-acceleration-lanes") && oc.getBool("ramps.guess-acceleration-lanes"))) {
373 if (modifyRamps) {
374 PROGRESS_BEGIN_MESSAGE(TL("Guessing and setting on-/off-ramps"));
375 }
378 rc.computeRamps(*this, oc, mayAddOrRemove);
379
380 if (modifyRamps) {
381 PROGRESS_TIME_MESSAGE(before);
382 }
383 }
384 // guess bike lanes
385 if (mayAddOrRemove && ((oc.getBool("bikelanes.guess") || oc.getBool("bikelanes.guess.from-permissions")))) {
386 const int bikelanes = myEdgeCont.guessSpecialLanes(SVC_BICYCLE, oc.getFloat("default.bikelane-width"),
387 oc.getFloat("bikelanes.guess.min-speed"),
388 oc.getFloat("bikelanes.guess.max-speed"),
389 oc.getBool("bikelanes.guess.from-permissions"),
390 "bikelanes.guess.exclude",
391 myTLLCont);
392 WRITE_MESSAGEF(TL("Guessed % bike lanes."), toString(bikelanes));
393 }
394
395 // guess sidewalks
396 if (mayAddOrRemove && ((oc.getBool("sidewalks.guess") || oc.getBool("sidewalks.guess.from-permissions")))) {
397 const int sidewalks = myEdgeCont.guessSpecialLanes(SVC_PEDESTRIAN, oc.getFloat("default.sidewalk-width"),
398 oc.getFloat("sidewalks.guess.min-speed"),
399 oc.getFloat("sidewalks.guess.max-speed"),
400 oc.getBool("sidewalks.guess.from-permissions"),
401 "sidewalks.guess.exclude",
402 myTLLCont);
403 WRITE_MESSAGEF(TL("Guessed % sidewalks."), toString(sidewalks));
404 }
405 // check whether any not previously setable connections may be set now
407
408 // remap ids if wished
409 if (mayAddOrRemove) {
410 const bool numericalIDs = oc.getBool("numerical-ids");
411 const bool reservedIDs = oc.isSet("reserved-ids");
412 const bool keptIDs = oc.isSet("kept-ids");
413 int numChangedEdges = myEdgeCont.remapIDs(numericalIDs, reservedIDs, keptIDs, oc.getString("prefix.edge"), myPTStopCont);
414 int numChangedNodes = myNodeCont.remapIDs(numericalIDs, reservedIDs, keptIDs, oc.getString("prefix.junction"), myTLLCont);
415 if (numChangedEdges + numChangedNodes > 0) {
416 WRITE_MESSAGEF(TL("Remapped % edge IDs and % node IDs."), toString(numChangedEdges), toString(numChangedNodes));
417 }
418 }
419
420 //
421 if (oc.exists("geometry.max-angle")) {
423 DEG2RAD(oc.getFloat("geometry.max-angle")),
424 oc.getBool("geometry.max-angle.fix"),
425 oc.getFloat("geometry.min-radius"),
426 oc.getBool("geometry.min-radius.fix"),
427 oc.getBool("geometry.min-radius.fix.railways"));
428 }
429
430 // GEOMETRY COMPUTATION
431 //
432 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Sorting nodes' edges"));
434 PROGRESS_TIME_MESSAGE(before);
436 //
437 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing node shapes"));
438 if (oc.exists("geometry.junction-mismatch-threshold")) {
439 myNodeCont.computeNodeShapes(oc.getFloat("geometry.junction-mismatch-threshold"));
440 } else {
442 }
443 PROGRESS_TIME_MESSAGE(before);
444 //
445 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing edge shapes"));
446 myEdgeCont.computeEdgeShapes(oc.getBool("geometry.max-grade.fix") ? oc.getFloat("geometry.max-grade") / 100 : -1);
447 PROGRESS_TIME_MESSAGE(before);
448 // resort edges based on the node and edge shapes
451
452 // APPLY SPEED MODIFICATIONS
453 if (oc.exists("speed.offset")) {
454 const double speedOffset = oc.getFloat("speed.offset");
455 const double speedFactor = oc.getFloat("speed.factor");
456 const double speedMin = oc.getFloat("speed.minimum");
457 if (speedOffset != 0 || speedFactor != 1 || speedMin > 0) {
458 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Applying speed modifications"));
459 for (const auto& it : myEdgeCont) {
460 NBEdge* const e = it.second;
461 for (int i = 0; i < e->getNumLanes(); i++) {
462 e->setSpeed(i, MAX2(e->getLaneSpeed(i) * speedFactor + speedOffset, speedMin));
463 }
464 }
465 PROGRESS_TIME_MESSAGE(before);
466 }
467 }
468
469 // CONNECTIONS COMPUTATION
470 //
471 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing node types"));
474 PROGRESS_TIME_MESSAGE(before);
475 //
476 myNetworkHaveCrossings = oc.getBool("walkingareas");
477 if (mayAddOrRemove && oc.getBool("crossings.guess")) {
479 int crossings = 0;
480 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
481 crossings += (*i).second->guessCrossings();
482 }
483 WRITE_MESSAGEF(TL("Guessed % pedestrian crossings."), toString(crossings));
484 }
486 bool haveValidCrossings = false;
487 // recheck whether we had crossings in the input
488 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
489 if (i->second->getCrossings().size() > 0) {
491 haveValidCrossings = true;
492 break;
493 } else if (i->second->getCrossingsIncludingInvalid().size() > 0) {
495 }
496 }
497 if (myNetworkHaveCrossings && !haveValidCrossings) {
498 // initial crossings removed or invalidated, keep walkingareas
499 oc.resetWritable();
500 oc.set("walkingareas", "true");
501 }
502 }
503
504 if (!mayAddOrRemove && myNetworkHaveCrossings) {
505 // crossings added via netedit
506 oc.resetWritable();
507 oc.set("no-internal-links", "false");
508 }
509
510 //
511 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing priorities"));
513 PROGRESS_TIME_MESSAGE(before);
514 //
515 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing approached edges"));
516 myEdgeCont.computeEdge2Edges(oc.getBool("no-left-connections"));
517 PROGRESS_TIME_MESSAGE(before);
518 //
519 if (oc.getBool("roundabouts.guess")) {
520 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Guessing and setting roundabouts"));
521 const int numGuessed = myEdgeCont.guessRoundabouts();
522 if (numGuessed > 0) {
523 WRITE_MESSAGEF(TL(" Guessed % roundabout(s)."), toString(numGuessed));
524 }
525 PROGRESS_TIME_MESSAGE(before);
526 }
528 //
529 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing approaching lanes"));
531 PROGRESS_TIME_MESSAGE(before);
532 //
533 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Dividing of lanes on approached lanes"));
536 PROGRESS_TIME_MESSAGE(before);
537 //
538 if (oc.getBool("fringe.guess")) {
539 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Guessing Network fringe"));
540 const int numGuessed = myNodeCont.guessFringe();
541 if (numGuessed > 0) {
542 WRITE_MESSAGEF(TL(" Guessed % fringe nodes."), toString(numGuessed));
543 }
544 PROGRESS_TIME_MESSAGE(before);
545 }
546 //
547 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Processing turnarounds"));
548 if (!oc.getBool("no-turnarounds")) {
550 oc.getBool("no-turnarounds.tls"),
551 oc.getBool("no-turnarounds.fringe"),
552 oc.getBool("no-turnarounds.except-deadend"),
553 oc.getBool("no-turnarounds.except-turnlane"),
554 oc.getBool("no-turnarounds.geometry"));
555 } else {
556 myEdgeCont.appendTurnarounds(explicitTurnarounds, oc.getBool("no-turnarounds.tls"));
557 }
558 if (oc.exists("railway.topology.repair.stop-turn") && oc.getBool("railway.topology.repair.stop-turn")
559 && myPTStopCont.getStops().size() > 0) {
560 // allow direction reversal at all bidi-edges with stops
562 }
563 PROGRESS_TIME_MESSAGE(before);
564 //
565 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Rechecking of lane endings"));
567 PROGRESS_TIME_MESSAGE(before);
568
569 if (myNetworkHaveCrossings && !oc.getBool("no-internal-links")) {
570 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
571 i->second->buildCrossingsAndWalkingAreas();
572 }
573 } else {
574 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
575 // needed by netedit if the last crossings was deleted from the network
576 // and walkingareas have been invalidated since the last call to compute()
577 i->second->discardWalkingareas();
578 }
579 if (oc.getBool("no-internal-links")) {
580 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
581 i->second->discardAllCrossings(false);
582 }
583 }
584 }
585 // join traffic lights (after building connections)
586 if (oc.getBool("tls.join")) {
587 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining traffic light nodes"));
588 myNodeCont.joinTLS(myTLLCont, oc.getFloat("tls.join-dist"));
589 PROGRESS_TIME_MESSAGE(before);
590 }
591
592 // COMPUTING RIGHT-OF-WAY AND TRAFFIC LIGHT PROGRAMS
593 //
594 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing traffic light control information"));
596 if (oc.exists("opendrive-files") && oc.isSet("opendrive-files")) {
598 }
599 PROGRESS_TIME_MESSAGE(before);
600 //
601 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing node logics"));
603 PROGRESS_TIME_MESSAGE(before);
604
605 //
606 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing traffic light logics"));
607 std::pair<int, int> numbers = myTLLCont.computeLogics(oc);
608 PROGRESS_TIME_MESSAGE(before);
609 std::string progCount = "";
610 if (numbers.first != numbers.second) {
611 progCount = "(" + toString(numbers.second) + " programs) ";
612 }
613 WRITE_MESSAGEF(TL(" % traffic light(s) %computed."), toString(numbers.first), progCount);
614 if (oc.exists("opendrive-files") && oc.isSet("opendrive-files") && oc.getBool("opendrive.signal-groups")) {
616 }
617
618 for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
619 (*i).second->sortOutgoingConnectionsByIndex();
620 }
621 // FINISHING INNER EDGES
622 std::set<NBTrafficLightDefinition*> largeNodeTLS;
623 if (!oc.getBool("no-internal-links")) {
624 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Building inner edges"));
625 // walking areas shall only be built if crossings are wished as well
626 for (const auto& item : myNodeCont) {
627 if (item.second->buildInnerEdges() > NBTrafficLightDefinition::MIN_YELLOW_SECONDS) {
628 const std::set<NBTrafficLightDefinition*>& tlDefs = item.second->getControllingTLS();
629 largeNodeTLS.insert(tlDefs.begin(), tlDefs.end());
630 }
631 }
632 PROGRESS_TIME_MESSAGE(before);
633 }
634 // PATCH NODE SHAPES
635 if (oc.getFloat("junctions.scurve-stretch") > 0) {
636 // @note: nodes have collected correction hints in buildInnerEdges()
637 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("stretching junctions to smooth geometries"));
640 myEdgeCont.computeEdgeShapes(oc.getBool("geometry.max-grade.fix") ? oc.getFloat("geometry.max-grade") / 100 : -1);
641 for (const auto& item : myNodeCont) {
642 item.second->buildInnerEdges();
643 }
644 PROGRESS_TIME_MESSAGE(before);
645 }
646 if (myEdgeCont.getNumEdgeSplits() > 0 && !oc.getBool("no-internal-links")) {
647 // edges with custom lengths were split, this has to take into account
648 // internal edge lengths (after geometry computation)
650 }
651 // recheck phases for large junctions
652 for (NBTrafficLightDefinition* def : largeNodeTLS) {
654 }
655 // compute lane-to-lane node logics (require traffic lights and inner edges to be done)
657
658 // remove guessed traffic lights at junctions without conflicts (requires computeLogics2)
660
661 // compute keepClear status (requires computeLogics2)
663
664 //
665 if (oc.isSet("street-sign-output")) {
666 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Generating street signs"));
668 PROGRESS_TIME_MESSAGE(before);
669 }
670
671
672 if (lefthand != oc.getBool("flip-y-axis")) {
673 mirrorX();
674 }
675
676 if (oc.exists("geometry.check-overlap") && oc.getFloat("geometry.check-overlap") > 0) {
677 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Checking overlapping edges"));
678 myEdgeCont.checkOverlap(oc.getFloat("geometry.check-overlap"), oc.getFloat("geometry.check-overlap.vertical-threshold"));
679 PROGRESS_TIME_MESSAGE(before);
680 }
681 if (geoConvHelper.getConvBoundary().getZRange() > 0 && oc.getFloat("geometry.max-grade") > 0) {
682 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Checking edge grade"));
683 // user input is in %
684 myEdgeCont.checkGrade(oc.getFloat("geometry.max-grade") / 100);
685 PROGRESS_TIME_MESSAGE(before);
686 }
687
688 // find accesses for pt rail stops and add bidi-stops
689 if (!myPTStopCont.getStops().empty()) {
690 // re-adapt stop lanes after adding special lanes and cutting edge shapes at junction
693 int numBidiStops = 0;
694 if (!oc.getBool("ptstop-output.no-bidi")) {
696 } else {
697 numBidiStops = myPTStopCont.countBidiStops(myEdgeCont);
698 }
699 PROGRESS_BEGIN_MESSAGE(TL("Find accesses for pt rail stops"));
700 double maxRadius = oc.getFloat("railway.access-distance");
701 double accessFactor = oc.getFloat("railway.access-factor");
702 int maxCount = oc.getInt("railway.max-accesses");
703 myPTStopCont.findAccessEdgesForRailStops(myEdgeCont, maxRadius, maxCount, accessFactor);
704 PROGRESS_TIME_MESSAGE(before);
705 if (numBidiStops > 0) {
707 }
708 }
710 // ensure that all turning lanes have sufficient permissions
712 if (oc.exists("ptline-clean-up") && oc.getBool("ptline-clean-up")) {
713 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Cleaning up public transport stops that are not served by any line"));
714 std::set<std::string> usedStops = myPTLineCont.getServedPTStops();
715 myPTStopCont.postprocess(usedStops);
716 PROGRESS_TIME_MESSAGE(before);
717 } else {
718 int numDeletedStops = myPTStopCont.cleanupDeleted(myEdgeCont);
719 if (numDeletedStops > 0) {
720 WRITE_WARNINGF(TL("Removed % pt stops because they could not be assigned to the network"), toString(numDeletedStops));
721 }
722 }
723
724 if (oc.exists("ignore-change-restrictions") && !oc.isDefault("ignore-change-restrictions")) {
725 SVCPermissions ignoring = parseVehicleClasses(oc.getStringVector("ignore-change-restrictions"));
727 }
728
730 // report on very large networks
731 if (MAX2(geoConvHelper.getConvBoundary().xmax(), geoConvHelper.getConvBoundary().ymax()) > 1000000 ||
732 MIN2(geoConvHelper.getConvBoundary().xmin(), geoConvHelper.getConvBoundary().ymin()) < -1000000) {
733 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"));
734 }
735
736 // clean up OSM processing params
737 if (oc.exists("osm-files") && oc.isSet("osm-files")) {
738 for (auto item : myEdgeCont) {
739 item.second->unsetParameter(NBTrafficLightDefinition::OSM_DIRECTION);
740 }
741 }
742}
743
744
745void
746NBNetBuilder::moveToOrigin(GeoConvHelper& geoConvHelper, bool lefthand) {
747 long before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Moving network to origin"));
748 Boundary boundary = geoConvHelper.getConvBoundary();
749 const double x = -boundary.xmin();
750 const double y = -(lefthand ? boundary.ymax() : boundary.ymin());
751 //if (lefthand) {
752 // y = boundary.ymax();
753 //}
754 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
755 (*i).second->reshiftPosition(x, y);
756 }
757 for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
758 (*i).second->reshiftPosition(x, y);
759 }
760 for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) {
761 (*i).second->reshiftPosition(x, y);
762 }
763 for (const auto& stopIt : myPTStopCont.getStops()) {
764 stopIt.second->reshiftPosition(x, y);
765 }
766 geoConvHelper.moveConvertedBy(x, y);
767 PROGRESS_TIME_MESSAGE(before);
768}
769
770
771void
773 // ensure that computed speeds (using during right-of-way computation) are the same as the written speeds
774 for (auto item : myEdgeCont) {
775 item.second->roundSpeed();
776 }
777 // ensure that derived junction and lane geometry computation is done with the same input
778 // edge coordinates as those that will be written to the output.
779 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
780 (*i).second->roundGeometry();
781 }
782 for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
783 (*i).second->roundGeometry();
784 }
785}
786
787
788void
790 // mirror the network along the X-axis
791 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
792 (*i).second->mirrorX();
793 }
794 for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
795 (*i).second->mirrorX();
796 }
797 for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) {
798 (*i).second->mirrorX();
799 }
800 for (const auto& stopIt : myPTStopCont.getStops()) {
801 stopIt.second->mirrorX();
802 }
803}
804
805
806bool
807NBNetBuilder::transformCoordinate(Position& from, bool includeInBoundary, GeoConvHelper* from_srs) {
808 Position orig(from);
809 bool ok = true;
811 && GeoConvHelper::getLoaded().usingGeoProjection()
812 && from_srs != nullptr
813 && from_srs->usingGeoProjection()
814 && *from_srs != GeoConvHelper::getLoaded()) {
815 from_srs->cartesian2geo(from);
816 ok &= GeoConvHelper::getLoaded().x2cartesian(from, false);
817 }
818 if (from_srs == nullptr || !GeoConvHelper::getProcessing().usingGeoProjection()) {
819 // if getProcessing is not a geo-projection, assume it a cartesian transformation (i.e. shift)
820 ok &= GeoConvHelper::getProcessing().x2cartesian(from, includeInBoundary);
821
822 if (from_srs == nullptr && GeoConvHelper::getProcessing().usingGeoProjection()
824 && GeoConvHelper::getLoaded().usingGeoProjection()) {
825 // apply geo patch to loaded geo-network (offset must match)
826 from = from + GeoConvHelper::getLoaded().getOffset();
827 }
828 }
829 if (ok) {
831 if (hm.ready()) {
832 if (from_srs != nullptr && from_srs->usingGeoProjection()) {
833 from_srs->cartesian2geo(orig);
834 }
835 from.setz(hm.getZ(orig));
836 }
837 }
838 const double eps = 1e-6;
839 from.set(std::round(from.x() / eps) * eps, std::round(from.y() / eps) * eps, std::round(from.z() / eps) * eps);
840 return ok;
841}
842
843
844bool
845NBNetBuilder::transformCoordinates(PositionVector& from, bool includeInBoundary, GeoConvHelper* from_srs) {
846 const double maxLength = OptionsCont::getOptions().getFloat("geometry.max-segment-length");
847 if (maxLength > 0 && from.size() > 1) {
848 // transformation to cartesian coordinates must happen before we can check segment length
849 PositionVector copy = from;
850 for (int i = 0; i < (int) from.size(); i++) {
851 transformCoordinate(copy[i], false);
852 }
853 addGeometrySegments(from, copy, maxLength);
854 }
855 bool ok = true;
856 for (int i = 0; i < (int) from.size(); i++) {
857 ok = ok && transformCoordinate(from[i], includeInBoundary, from_srs);
858 }
859 return ok;
860}
861
862
863int
864NBNetBuilder::addGeometrySegments(PositionVector& from, const PositionVector& cartesian, const double maxLength) {
865 // check lengths and insert new points where needed (in the original
866 // coordinate system)
867 int inserted = 0;
868 for (int i = 0; i < (int)cartesian.size() - 1; i++) {
869 Position start = from[i + inserted];
870 Position end = from[i + inserted + 1];
871 double length = cartesian[i].distanceTo(cartesian[i + 1]);
872 const Position step = (end - start) * (maxLength / length);
873 int steps = 0;
874 while (length > maxLength) {
875 length -= maxLength;
876 steps++;
877 from.insert(from.begin() + i + inserted + 1, start + (step * steps));
878 inserted++;
879 }
880 }
881 return inserted;
882}
883
884
885bool
887 // see GNELoadThread::fillOptions
888 return OptionsCont::getOptions().exists("new");
889}
890
891
892/****************************************************************************/
#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:80
T MAX2(T a, T b)
Definition StdDefs.h:86
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:313
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:549
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 attachRemoved(NBNodeCont &nc, NBDistrictCont &dc, const double maxDist)
return number of edges split
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:2231
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition NBEdge.cpp:4438
int getNumLanes() const
Returns the number of lanes.
Definition NBEdge.h:526
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 roundInputs()
ensure consistency between input and output geometries and speeds
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 joinSameJunctions(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc, double maxDist)
Joins junctions with similar coordinates regardless of topology.
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
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:2638
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