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-2023 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"));
97 if (mayAddOrRemove && oc.exists("remove-edges.isolated") && oc.getBool("remove-edges.isolated")) {
98 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Finding isolated roads"));
100 PROGRESS_TIME_MESSAGE(before);
101 }
102 if (mayAddOrRemove && oc.exists("keep-edges.components") && oc.getInt("keep-edges.components") > 0) {
103 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Finding largest components"));
104 const bool hasStops = oc.exists("ptstop-output") && oc.isSet("ptstop-output") && !myPTStopCont.getStops().empty();
105 myNodeCont.removeComponents(myDistrictCont, myEdgeCont, oc.getInt("keep-edges.components"), hasStops);
106 PROGRESS_TIME_MESSAGE(before);
107 }
108 if (mayAddOrRemove && oc.exists("keep-edges.postload") && oc.getBool("keep-edges.postload")) {
109 if (oc.isSet("keep-edges.explicit") || oc.isSet("keep-edges.input-file")) {
110 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Removing unwished edges"));
112 PROGRESS_TIME_MESSAGE(before);
113 }
114 }
115 // Processing pt stops and lines
116 if (!myPTStopCont.getStops().empty()) {
117 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Processing public transport stops"));
118 if (!(oc.exists("ptline-output") && oc.isSet("ptline-output"))
119 && !oc.getBool("ptstop-output.no-bidi")) {
121 }
124 PROGRESS_TIME_MESSAGE(before);
125 }
126 if (mayAddOrRemove && oc.exists("keep-edges.components") && oc.getInt("keep-edges.components") > 0) {
127 // post process rail components unless they have stops
129 }
130
131 if (!myPTLineCont.getLines().empty()) {
132 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Revising public transport stops based on pt lines"));
134 PROGRESS_TIME_MESSAGE(before);
135 }
136
137 if (oc.exists("ptline-clean-up") && oc.getBool("ptline-clean-up")) {
138 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Cleaning up public transport stops that are not served by any line"));
140 PROGRESS_TIME_MESSAGE(before);
141 } else {
142 int numDeletedStops = myPTStopCont.cleanupDeleted(myEdgeCont);
143 if (numDeletedStops > 0) {
144 WRITE_WARNINGF(TL("Removed % pt stops because they could not be assigned to the network"), toString(numDeletedStops));
145 }
146 }
147
148 if (!myPTStopCont.getStops().empty() && !oc.getBool("ptstop-output.no-bidi")) {
149 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Align pt stop id signs with corresponding edge id signs"));
151 PROGRESS_TIME_MESSAGE(before);
152 }
153 // analyze and fix railway topology
154 int numAddedBidi = 0;
155 if (oc.exists("railway.topology.all-bidi") && oc.getBool("railway.topology.all-bidi")) {
158 } else if (oc.exists("railway.topology.repair") && oc.getBool("railway.topology.repair")) {
159 // correct railway angles for angle-based connectivity heuristic
161 oc.getFloat("geometry.min-radius"), false,
162 oc.getBool("geometry.min-radius.fix.railways"), true);
165 }
167 if (numAddedBidi > 0) {
168 // update routes
170 }
171 if (oc.exists("railway.topology.direction-priority") && oc.getBool("railway.topology.direction-priority")) {
172 NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
174 } else if (oc.exists("railway.topology.extend-priority") && oc.getBool("railway.topology.extend-priority")) {
175 NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
177 }
178 if (oc.exists("railway.topology.output") && oc.isSet("railway.topology.output")) {
179 NBTurningDirectionsComputer::computeTurnDirections(myNodeCont, false); // recompute after new edges were added
181 }
182
183
184 if (mayAddOrRemove && oc.exists("edges.join-tram-dist") && oc.getFloat("edges.join-tram-dist") >= 0) {
185 // should come before joining junctions
186 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining tram edges"));
187 int numJoinedTramEdges = myEdgeCont.joinTramEdges(myDistrictCont, myPTStopCont, myPTLineCont, oc.getFloat("edges.join-tram-dist"));
188 PROGRESS_TIME_MESSAGE(before);
189 if (numJoinedTramEdges > 0) {
190 WRITE_MESSAGEF(TL(" Joined % tram edges into roads."), toString(numJoinedTramEdges));
191 }
192 }
193 if (oc.getBool("junctions.join")
194 || (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))
195 || oc.getBool("tls.guess.joining")
196 || (oc.exists("tls.guess-signals") && oc.getBool("tls.guess-signals"))) {
197 // preliminary geometry computations to determine the length of edges
198 // This depends on turning directions and sorting of edge list
199 // in case junctions are joined geometry computations have to be repeated
200 // preliminary roundabout computations to avoid damaging roundabouts via junctions.join or ramps.guess
206 if (oc.getBool("roundabouts.guess")) {
208 }
209 const std::set<EdgeSet>& roundabouts = myEdgeCont.getRoundabouts();
210 for (std::set<EdgeSet>::const_iterator it_round = roundabouts.begin();
211 it_round != roundabouts.end(); ++it_round) {
212 std::vector<std::string> nodeIDs;
213 for (EdgeSet::const_iterator it_edge = it_round->begin(); it_edge != it_round->end(); ++it_edge) {
214 nodeIDs.push_back((*it_edge)->getToNode()->getID());
215 }
217 }
219 } else if (myEdgeCont.hasGuessedRoundabouts() && oc.getBool("roundabouts.guess")) {
221 }
222 // join junctions (may create new "geometry"-nodes so it needs to come before removing these
223 if (mayAddOrRemove && oc.exists("junctions.join-exclude") && oc.isSet("junctions.join-exclude")) {
224 myNodeCont.addJoinExclusion(oc.getStringVector("junctions.join-exclude"));
225 }
227 if (mayAddOrRemove && oc.getBool("junctions.join")) {
228 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining junction clusters"));
229 numJoined += myNodeCont.joinJunctions(oc.getFloat("junctions.join-dist"), myDistrictCont, myEdgeCont, myTLLCont, myPTStopCont);
230 PROGRESS_TIME_MESSAGE(before);
231 }
232 if (numJoined > 0) {
233 WRITE_MESSAGEF(TL(" Joined % junction cluster(s)."), toString(numJoined));
234 }
235 if (mayAddOrRemove && oc.exists("junctions.join-same") && oc.getBool("junctions.join-same")) {
236 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining junctions with identical coordinates"));
238 PROGRESS_TIME_MESSAGE(before);
239 if (numJoined2 > 0) {
240 WRITE_MESSAGEF(TL(" Joined % junctions."), toString(numJoined2));
241 }
242 }
243 //
244 if (mayAddOrRemove && oc.exists("join-lanes") && oc.getBool("join-lanes")) {
245 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining lanes"));
247 PROGRESS_TIME_MESSAGE(before);
248 WRITE_MESSAGEF(TL(" Joined lanes on % edges."), toString(num));
249 }
250 //
251 if (mayAddOrRemove) {
252 const bool removeGeometryNodes = oc.exists("geometry.remove") && oc.getBool("geometry.remove");
253 before = PROGRESS_BEGIN_TIME_MESSAGE("Removing empty nodes" + std::string(removeGeometryNodes ? " and geometry nodes" : ""));
254 // removeUnwishedNodes needs turnDirections. @todo: try to call this less often
257 PROGRESS_TIME_MESSAGE(before);
258 WRITE_MESSAGEF(TL(" % nodes removed."), toString(numRemoved));
259 }
260
261 // MOVE TO ORIGIN
262 // compute new boundary after network modifications have taken place
263 Boundary boundary;
264 for (std::map<std::string, NBNode*>::const_iterator it = myNodeCont.begin(); it != myNodeCont.end(); ++it) {
265 boundary.add(it->second->getPosition());
266 }
267 for (std::map<std::string, NBEdge*>::const_iterator it = myEdgeCont.begin(); it != myEdgeCont.end(); ++it) {
268 boundary.add(it->second->getGeometry().getBoxBoundary());
269 }
270 geoConvHelper.setConvBoundary(boundary);
271
272 if (!oc.getBool("offset.disable-normalization") && oc.isDefault("offset.x") && oc.isDefault("offset.y")) {
273 moveToOrigin(geoConvHelper, lefthand);
274 }
275 geoConvHelper.computeFinal(lefthand); // information needed for location element fixed at this point
276
277 if (oc.exists("geometry.min-dist") && !oc.isDefault("geometry.min-dist")) {
278 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Reducing geometries"));
279 myEdgeCont.reduceGeometries(oc.getFloat("geometry.min-dist"));
280 PROGRESS_TIME_MESSAGE(before);
281 }
282 // @note: removing geometry can create similar edges so joinSimilarEdges must come afterwards
283 // @note: likewise splitting can destroy similarities so joinSimilarEdges must come before
284 if (mayAddOrRemove && oc.getBool("edges.join")) {
285 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining similar edges"));
286 const bool removeDuplicates = oc.exists("junctions.join-same") && oc.getBool("junctions.join-same");
288 // now we may have new chances to remove geometry if wished
289 if (oc.exists("geometry.remove") && oc.getBool("geometry.remove")) {
291 }
292 PROGRESS_TIME_MESSAGE(before);
293 }
294 if (oc.getBool("opposites.guess")) {
295 PROGRESS_BEGIN_MESSAGE(TL("guessing opposite direction edges"));
298 }
299 //
300 if (mayAddOrRemove && oc.exists("geometry.split") && oc.getBool("geometry.split")) {
301 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Splitting geometry edges"));
303 // newly split junctions might also be joinable
304 PROGRESS_TIME_MESSAGE(before);
305 if (oc.getBool("junctions.join-same")) {
307 if (numJoined3 > 0) {
308 WRITE_MESSAGEF(TL(" Joined % junctions after splitting geometry."), toString(numJoined3));
309 }
310 }
311 }
312 // turning direction
313 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing turning directions"));
315 PROGRESS_TIME_MESSAGE(before);
316 // correct edge geometries to avoid overlap
317 if (oc.exists("geometry.avoid-overlap") && oc.getBool("geometry.avoid-overlap")) {
319 }
320
321 // GUESS TLS POSITIONS
322 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Assigning nodes to traffic lights"));
323 if (oc.isSet("tls.set")) {
324 std::vector<std::string> tlControlledNodes = oc.getStringVector("tls.set");
326 for (std::vector<std::string>::const_iterator i = tlControlledNodes.begin(); i != tlControlledNodes.end(); ++i) {
327 NBNode* node = myNodeCont.retrieve(*i);
328 if (node == nullptr) {
329 WRITE_WARNING("Building a tl-logic for junction '" + *i + "' is not possible." + "\n The junction '" + *i + "' is not known.");
330 } else {
332 }
333 }
334 }
336 PROGRESS_TIME_MESSAGE(before);
337
338 // guess ramps (after guessing tls because ramps should not be build at traffic lights)
339 const bool modifyRamps = mayAddOrRemove && (
340 (oc.exists("ramps.guess") && oc.getBool("ramps.guess"))
341 || (oc.exists("ramps.set") && oc.isSet("ramps.set")));
342 if (modifyRamps || (oc.exists("ramps.guess-acceleration-lanes") && oc.getBool("ramps.guess-acceleration-lanes"))) {
344 if (modifyRamps) {
345 PROGRESS_BEGIN_MESSAGE(TL("Guessing and setting on-/off-ramps"));
346 }
348 NBRampsComputer::computeRamps(*this, oc, mayAddOrRemove);
349 if (modifyRamps) {
350 PROGRESS_TIME_MESSAGE(before);
351 }
352 }
353 // guess bike lanes
354 if (mayAddOrRemove && ((oc.getBool("bikelanes.guess") || oc.getBool("bikelanes.guess.from-permissions")))) {
355 const int bikelanes = myEdgeCont.guessSpecialLanes(SVC_BICYCLE, oc.getFloat("default.bikelane-width"),
356 oc.getFloat("bikelanes.guess.min-speed"),
357 oc.getFloat("bikelanes.guess.max-speed"),
358 oc.getBool("bikelanes.guess.from-permissions"),
359 "bikelanes.guess.exclude",
360 myTLLCont);
361 WRITE_MESSAGEF(TL("Guessed % bike lanes."), toString(bikelanes));
362 }
363
364 // guess sidewalks
365 if (mayAddOrRemove && ((oc.getBool("sidewalks.guess") || oc.getBool("sidewalks.guess.from-permissions")))) {
366 const int sidewalks = myEdgeCont.guessSpecialLanes(SVC_PEDESTRIAN, oc.getFloat("default.sidewalk-width"),
367 oc.getFloat("sidewalks.guess.min-speed"),
368 oc.getFloat("sidewalks.guess.max-speed"),
369 oc.getBool("sidewalks.guess.from-permissions"),
370 "sidewalks.guess.exclude",
371 myTLLCont);
372 WRITE_MESSAGEF(TL("Guessed % sidewalks."), toString(sidewalks));
373 }
374 // check whether any not previously setable connections may be set now
376
377 // remap ids if wished
378 if (mayAddOrRemove) {
379 int numChangedEdges = myEdgeCont.remapIDs(oc.getBool("numerical-ids"), oc.isSet("reserved-ids"), oc.getString("prefix"), myPTStopCont);
380 int numChangedNodes = myNodeCont.remapIDs(oc.getBool("numerical-ids"), oc.isSet("reserved-ids"), oc.getString("prefix"), myTLLCont);
381 if (numChangedEdges + numChangedNodes > 0) {
382 WRITE_MESSAGEF(TL("Remapped % edge IDs and % node IDs."), toString(numChangedEdges), toString(numChangedNodes));
383 }
384 }
385
386 //
387 if (oc.exists("geometry.max-angle")) {
389 DEG2RAD(oc.getFloat("geometry.max-angle")),
390 oc.getFloat("geometry.min-radius"),
391 oc.getBool("geometry.min-radius.fix"),
392 oc.getBool("geometry.min-radius.fix.railways"));
393 }
394
395 // GEOMETRY COMPUTATION
396 //
397 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Sorting nodes' edges"));
399 PROGRESS_TIME_MESSAGE(before);
401 //
402 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing node shapes"));
403 if (oc.exists("geometry.junction-mismatch-threshold")) {
404 myNodeCont.computeNodeShapes(oc.getFloat("geometry.junction-mismatch-threshold"));
405 } else {
407 }
408 PROGRESS_TIME_MESSAGE(before);
409 //
410 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing edge shapes"));
411 myEdgeCont.computeEdgeShapes(oc.getBool("geometry.max-grade.fix") ? oc.getFloat("geometry.max-grade") / 100 : -1);
412 PROGRESS_TIME_MESSAGE(before);
413 // resort edges based on the node and edge shapes
416
417 // APPLY SPEED MODIFICATIONS
418 if (oc.exists("speed.offset")) {
419 const double speedOffset = oc.getFloat("speed.offset");
420 const double speedFactor = oc.getFloat("speed.factor");
421 const double speedMin = oc.getFloat("speed.minimum");
422 if (speedOffset != 0 || speedFactor != 1 || speedMin > 0) {
423 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Applying speed modifications"));
424 for (const auto& it : myEdgeCont) {
425 NBEdge* const e = it.second;
426 for (int i = 0; i < e->getNumLanes(); i++) {
427 e->setSpeed(i, MAX2(e->getLaneSpeed(i) * speedFactor + speedOffset, speedMin));
428 }
429 }
430 PROGRESS_TIME_MESSAGE(before);
431 }
432 }
433
434 // CONNECTIONS COMPUTATION
435 //
436 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing node types"));
438 PROGRESS_TIME_MESSAGE(before);
439 //
440 myNetworkHaveCrossings = oc.getBool("walkingareas");
441 if (mayAddOrRemove && oc.getBool("crossings.guess")) {
443 int crossings = 0;
444 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
445 crossings += (*i).second->guessCrossings();
446 }
447 WRITE_MESSAGEF(TL("Guessed % pedestrian crossings."), toString(crossings));
448 }
450 bool haveValidCrossings = false;
451 // recheck whether we had crossings in the input
452 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
453 if (i->second->getCrossings().size() > 0) {
455 haveValidCrossings = true;
456 break;
457 } else if (i->second->getCrossingsIncludingInvalid().size() > 0) {
459 }
460 }
461 if (myNetworkHaveCrossings && !haveValidCrossings) {
462 // initial crossings removed or invalidated, keep walkingareas
463 oc.resetWritable();
464 oc.set("walkingareas", "true");
465 }
466 }
467
468 if (!mayAddOrRemove && myNetworkHaveCrossings) {
469 // crossings added via netedit
470 oc.resetWritable();
471 oc.set("no-internal-links", "false");
472 }
473
474 //
475 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing priorities"));
477 PROGRESS_TIME_MESSAGE(before);
478 //
479 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing approached edges"));
480 myEdgeCont.computeEdge2Edges(oc.getBool("no-left-connections"));
481 PROGRESS_TIME_MESSAGE(before);
482 //
483 if (oc.getBool("roundabouts.guess")) {
484 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Guessing and setting roundabouts"));
485 const int numGuessed = myEdgeCont.guessRoundabouts();
486 if (numGuessed > 0) {
487 WRITE_MESSAGEF(TL(" Guessed % roundabout(s)."), toString(numGuessed));
488 }
489 PROGRESS_TIME_MESSAGE(before);
490 }
492 //
493 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing approaching lanes"));
495 PROGRESS_TIME_MESSAGE(before);
496 //
497 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Dividing of lanes on approached lanes"));
500 PROGRESS_TIME_MESSAGE(before);
501 //
502 if (oc.getBool("fringe.guess")) {
503 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Guessing Network fringe"));
504 const int numGuessed = myNodeCont.guessFringe();
505 if (numGuessed > 0) {
506 WRITE_MESSAGEF(TL(" Guessed % fringe nodes."), toString(numGuessed));
507 }
508 PROGRESS_TIME_MESSAGE(before);
509 }
510 //
511 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Processing turnarounds"));
512 if (!oc.getBool("no-turnarounds")) {
514 oc.getBool("no-turnarounds.tls"),
515 oc.getBool("no-turnarounds.fringe"),
516 oc.getBool("no-turnarounds.except-deadend"),
517 oc.getBool("no-turnarounds.except-turnlane"),
518 oc.getBool("no-turnarounds.geometry"));
519 } else {
520 myEdgeCont.appendTurnarounds(explicitTurnarounds, oc.getBool("no-turnarounds.tls"));
521 }
522 if (oc.exists("railway.topology.repair.stop-turn") && oc.getBool("railway.topology.repair.stop-turn")
523 && myPTStopCont.getStops().size() > 0) {
524 // allow direction reversal at all bidi-edges with stops
526 }
527 PROGRESS_TIME_MESSAGE(before);
528 //
529 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Rechecking of lane endings"));
531 PROGRESS_TIME_MESSAGE(before);
532
533 if (myNetworkHaveCrossings && !oc.getBool("no-internal-links")) {
534 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
535 i->second->buildCrossingsAndWalkingAreas();
536 }
537 } else {
538 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
539 // needed by netedit if the last crossings was deleted from the network
540 // and walkingareas have been invalidated since the last call to compute()
541 i->second->discardWalkingareas();
542 }
543 if (oc.getBool("no-internal-links")) {
544 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
545 i->second->discardAllCrossings(false);
546 }
547 }
548 }
549 // join traffic lights (after building connections)
550 if (oc.getBool("tls.join")) {
551 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Joining traffic light nodes"));
552 myNodeCont.joinTLS(myTLLCont, oc.getFloat("tls.join-dist"));
553 PROGRESS_TIME_MESSAGE(before);
554 }
555
556 // COMPUTING RIGHT-OF-WAY AND TRAFFIC LIGHT PROGRAMS
557 //
558 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing traffic light control information"));
560 if (oc.exists("opendrive-files") && oc.isSet("opendrive-files")) {
562 }
563 PROGRESS_TIME_MESSAGE(before);
564 //
565 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing node logics"));
567 PROGRESS_TIME_MESSAGE(before);
568
569 //
570 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Computing traffic light logics"));
571 std::pair<int, int> numbers = myTLLCont.computeLogics(oc);
572 PROGRESS_TIME_MESSAGE(before);
573 std::string progCount = "";
574 if (numbers.first != numbers.second) {
575 progCount = "(" + toString(numbers.second) + " programs) ";
576 }
577 WRITE_MESSAGEF(TL(" % traffic light(s) %computed."), toString(numbers.first), progCount);
578 if (oc.exists("opendrive-files") && oc.isSet("opendrive-files") && oc.getBool("opendrive.signal-groups")) {
580 }
581
582 for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
583 (*i).second->sortOutgoingConnectionsByIndex();
584 }
585 // FINISHING INNER EDGES
586 std::set<NBTrafficLightDefinition*> largeNodeTLS;
587 if (!oc.getBool("no-internal-links")) {
588 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Building inner edges"));
589 // walking areas shall only be built if crossings are wished as well
590 for (const auto& item : myNodeCont) {
591 if (item.second->buildInnerEdges() > NBTrafficLightDefinition::MIN_YELLOW_SECONDS) {
592 const std::set<NBTrafficLightDefinition*>& tlDefs = item.second->getControllingTLS();
593 largeNodeTLS.insert(tlDefs.begin(), tlDefs.end());
594 }
595 }
596 PROGRESS_TIME_MESSAGE(before);
597 }
598 // PATCH NODE SHAPES
599 if (oc.getFloat("junctions.scurve-stretch") > 0) {
600 // @note: nodes have collected correction hints in buildInnerEdges()
601 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("stretching junctions to smooth geometries"));
604 myEdgeCont.computeEdgeShapes(oc.getBool("geometry.max-grade.fix") ? oc.getFloat("geometry.max-grade") / 100 : -1);
605 for (const auto& item : myNodeCont) {
606 item.second->buildInnerEdges();
607 }
608 PROGRESS_TIME_MESSAGE(before);
609 }
610 if (myEdgeCont.getNumEdgeSplits() > 0 && !oc.getBool("no-internal-links")) {
611 // edges with custom lengths were split, this has to take into account
612 // internal edge lengts (after geometry computation)
614 }
615 // recheck phases for large junctions
616 for (NBTrafficLightDefinition* def : largeNodeTLS) {
618 }
619 // compute lane-to-lane node logics (require traffic lights and inner edges to be done)
621
622 // remove guessed traffic lights at junctions without conflicts (requires computeLogics2)
624
625 // compute keepClear status (requires computeLogics2)
627
628 //
629 if (oc.isSet("street-sign-output")) {
630 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Generating street signs"));
632 PROGRESS_TIME_MESSAGE(before);
633 }
634
635
636 if (lefthand != oc.getBool("flip-y-axis")) {
637 mirrorX();
638 };
639
640 if (oc.exists("geometry.check-overlap") && oc.getFloat("geometry.check-overlap") > 0) {
641 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Checking overlapping edges"));
642 myEdgeCont.checkOverlap(oc.getFloat("geometry.check-overlap"), oc.getFloat("geometry.check-overlap.vertical-threshold"));
643 PROGRESS_TIME_MESSAGE(before);
644 }
645 if (geoConvHelper.getConvBoundary().getZRange() > 0 && oc.getFloat("geometry.max-grade") > 0) {
646 before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Checking edge grade"));
647 // user input is in %
648 myEdgeCont.checkGrade(oc.getFloat("geometry.max-grade") / 100);
649 PROGRESS_TIME_MESSAGE(before);
650 }
651
652 // find accesses for pt rail stops and add bidi-stops
653 if (!myPTStopCont.getStops().empty()) {
654 // re-adapt stop lanes after adding special lanes and cutting edge shapes at junction
657 int numBidiStops = 0;
658 if (!oc.getBool("ptstop-output.no-bidi")) {
660 }
661 PROGRESS_BEGIN_MESSAGE(TL("Find accesses for pt rail stops"));
662 double maxRadius = oc.getFloat("railway.access-distance");
663 double accessFactor = oc.getFloat("railway.access-factor");
664 int maxCount = oc.getInt("railway.max-accesses");
665 myPTStopCont.findAccessEdgesForRailStops(myEdgeCont, maxRadius, maxCount, accessFactor);
666 PROGRESS_TIME_MESSAGE(before);
667 if (numBidiStops > 0) {
669 }
670 }
672 // ensure that all turning lanes have sufficient permissions
674
675 if (oc.exists("ignore-change-restrictions") && !oc.isDefault("ignore-change-restrictions")) {
676 SVCPermissions ignoring = parseVehicleClasses(oc.getStringVector("ignore-change-restrictions"));
678 }
679
681 // report on very large networks
682 if (MAX2(geoConvHelper.getConvBoundary().xmax(), geoConvHelper.getConvBoundary().ymax()) > 1000000 ||
683 MIN2(geoConvHelper.getConvBoundary().xmin(), geoConvHelper.getConvBoundary().ymin()) < -1000000) {
684 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"));
685 }
686}
687
688
689void
690NBNetBuilder::moveToOrigin(GeoConvHelper& geoConvHelper, bool lefthand) {
691 long before = PROGRESS_BEGIN_TIME_MESSAGE(TL("Moving network to origin"));
692 Boundary boundary = geoConvHelper.getConvBoundary();
693 const double x = -boundary.xmin();
694 const double y = -(lefthand ? boundary.ymax() : boundary.ymin());
695 //if (lefthand) {
696 // y = boundary.ymax();
697 //}
698 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
699 (*i).second->reshiftPosition(x, y);
700 }
701 for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
702 (*i).second->reshiftPosition(x, y);
703 }
704 for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) {
705 (*i).second->reshiftPosition(x, y);
706 }
707 for (const auto& stopIt : myPTStopCont.getStops()) {
708 stopIt.second->reshiftPosition(x, y);
709 }
710 geoConvHelper.moveConvertedBy(x, y);
711 PROGRESS_TIME_MESSAGE(before);
712}
713
714
715void
717 // mirror the network along the X-axis
718 for (std::map<std::string, NBNode*>::const_iterator i = myNodeCont.begin(); i != myNodeCont.end(); ++i) {
719 (*i).second->mirrorX();
720 }
721 for (std::map<std::string, NBEdge*>::const_iterator i = myEdgeCont.begin(); i != myEdgeCont.end(); ++i) {
722 (*i).second->mirrorX();
723 }
724 for (std::map<std::string, NBDistrict*>::const_iterator i = myDistrictCont.begin(); i != myDistrictCont.end(); ++i) {
725 (*i).second->mirrorX();
726 }
727 for (const auto& stopIt : myPTStopCont.getStops()) {
728 stopIt.second->mirrorX();
729 }
730}
731
732
733bool
734NBNetBuilder::transformCoordinate(Position& from, bool includeInBoundary, GeoConvHelper* from_srs) {
735 Position orig(from);
736 bool ok = true;
738 && GeoConvHelper::getLoaded().usingGeoProjection()
739 && from_srs != nullptr
740 && from_srs->usingGeoProjection()
741 && *from_srs != GeoConvHelper::getLoaded()) {
742 from_srs->cartesian2geo(from);
743 ok &= GeoConvHelper::getLoaded().x2cartesian(from, false);
744 }
745 if (from_srs == nullptr || !GeoConvHelper::getProcessing().usingGeoProjection()) {
746 // if getProcessing is not a geo-projection, assume it a cartesian transformation (i.e. shift)
747 ok &= GeoConvHelper::getProcessing().x2cartesian(from, includeInBoundary);
748
749 if (from_srs == nullptr && GeoConvHelper::getProcessing().usingGeoProjection()
751 && GeoConvHelper::getLoaded().usingGeoProjection()) {
752 // apply geo patch to loaded geo-network (offset must match)
753 from = from + GeoConvHelper::getLoaded().getOffset();
754 }
755 }
756 if (ok) {
758 if (hm.ready()) {
759 if (from_srs != nullptr && from_srs->usingGeoProjection()) {
760 from_srs->cartesian2geo(orig);
761 }
762 from.setz(hm.getZ(orig));
763 }
764 }
765 return ok;
766}
767
768
769bool
770NBNetBuilder::transformCoordinates(PositionVector& from, bool includeInBoundary, GeoConvHelper* from_srs) {
771 const double maxLength = OptionsCont::getOptions().getFloat("geometry.max-segment-length");
772 if (maxLength > 0 && from.size() > 1) {
773 // transformation to cartesian coordinates must happen before we can check segment length
774 PositionVector copy = from;
775 for (int i = 0; i < (int) from.size(); i++) {
776 transformCoordinate(copy[i], false);
777 }
778 addGeometrySegments(from, copy, maxLength);
779 }
780 bool ok = true;
781 for (int i = 0; i < (int) from.size(); i++) {
782 ok = ok && transformCoordinate(from[i], includeInBoundary, from_srs);
783 }
784 return ok;
785}
786
787int
788NBNetBuilder::addGeometrySegments(PositionVector& from, const PositionVector& cartesian, const double maxLength) {
789 // check lengths and insert new points where needed (in the original
790 // coordinate system)
791 int inserted = 0;
792 for (int i = 0; i < (int)cartesian.size() - 1; i++) {
793 Position start = from[i + inserted];
794 Position end = from[i + inserted + 1];
795 double length = cartesian[i].distanceTo(cartesian[i + 1]);
796 const Position step = (end - start) * (maxLength / length);
797 int steps = 0;
798 while (length > maxLength) {
799 length -= maxLength;
800 steps++;
801 from.insert(from.begin() + i + inserted + 1, start + (step * steps));
802 inserted++;
803 }
804 }
805 return inserted;
806}
807
808
809bool
811 // see GNELoadThread::fillOptions
812 return OptionsCont::getOptions().exists("new");
813}
814
815
816/****************************************************************************/
#define DEG2RAD(x)
Definition GeomHelper.h:35
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:271
#define WRITE_MESSAGEF(...)
Definition MsgHandler.h:273
#define WRITE_WARNING(msg)
Definition MsgHandler.h:270
#define PROGRESS_BEGIN_TIME_MESSAGE(msg)
Definition MsgHandler.h:276
#define TL(string)
Definition MsgHandler.h:287
#define PROGRESS_TIME_MESSAGE(before)
Definition MsgHandler.h:277
#define PROGRESS_DONE_MESSAGE()
Definition MsgHandler.h:275
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition MsgHandler.h:274
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_PEDESTRIAN
pedestrian
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
T MIN2(T a, T b)
Definition StdDefs.h:76
T MAX2(T a, T b)
Definition StdDefs.h:82
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition Boundary.cpp:78
double ymin() const
Returns minimum y-coordinate.
Definition Boundary.cpp:130
double xmin() const
Returns minimum x-coordinate.
Definition Boundary.cpp:118
double ymax() const
Returns maximum y-coordinate.
Definition Boundary.cpp:136
double xmax() const
Returns maximum x-coordinate.
Definition Boundary.cpp:124
double getZRange() const
Returns the elevation range of the boundary (z-axis)
Definition Boundary.cpp:166
static methods for processing the coordinates conversion for the current net
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.
void removeUnwishedEdges(NBDistrictCont &dc)
Removes unwished edges (not in keep-edges)
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 checkGeometries(const double maxAngle, const double minRadius, bool fix, bool fixRailways, bool silent=false)
void recheckLanes()
Rechecks whether all lanes have a successor for each of the stored edges.
void reduceGeometries(const double minDist)
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
void generateStreetSigns()
assigns street signs to edges based on toNode types
bool hasGuessedRoundabouts() const
check if there is guessed roundabouts
Definition NBEdgeCont.h:539
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 remapIDs(bool numericaIDs, bool reservedIDs, 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
The representation of a single edge during network building.
Definition NBEdge.h:92
double getLaneSpeed(int lane) const
get lane speed
Definition NBEdge.cpp:2129
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition NBEdge.cpp:4147
int getNumLanes() const
Returns the number of lanes.
Definition NBEdge.h:510
static void setDefaultConnectionLength(double length)
Definition NBEdge.h:380
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 removeRailComponents(NBDistrictCont &dc, NBEdgeCont &ec, NBPTStopCont &sc)
remove rail components after ptstops are built
void avoidOverlap()
fix overlap
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
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, 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
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.
void 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
void removeSelfLoops(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tc)
Removes self-loop edges (edges where the source and the destination node are the same)
int joinSameJunctions(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc)
Joins junctions with the same coordinates regardless of topology.
bool resetNodeShapes()
reset all node shapes
void removeComponents(NBDistrictCont &dc, NBEdgeCont &ec, const int numKeep, bool hasPTStops)
Checks the network for weak connectivity and removes all but the largest components....
Represents a single node (junction) during network building.
Definition NBNode.h:66
static void computeNodeTypes(NBNodeCont &nc, NBTrafficLightLogicCont &tlc)
Computes node types.
static void validateRailCrossings(NBNodeCont &nc, NBTrafficLightLogicCont &tlc)
Checks rail_crossing for validity.
static void sortNodesEdges(NBNodeCont &nc, bool useNodeShape=false)
Sorts a node's edges clockwise regarding driving direction.
void fixPermissions()
ensure that all turn lanes have sufficient permissions
void process(NBEdgeCont &ec, NBPTStopCont &sc, bool routeOnly=false)
std::set< std::string > & getServedPTStops()
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)
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)
static void computeRamps(NBNetBuilder &nb, OptionsCont &oc, bool mayAddOrRemove)
Computes highway on-/off-ramps (if wished)
static void reportWarnings()
reports warnings if any occurred
The base class for traffic light logic definitions.
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 setz(double z)
set position z
Definition Position.h:80
A list of positions.
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
lane spread functions
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
T get(const std::string &str) const
static long getCurrentMillis()
Returns the current time in milliseconds.
Definition SysUtils.cpp:43