Eclipse SUMO - Simulation of Urban MObility
NIImporter_SUMO.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3// Copyright (C) 2001-2022 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/****************************************************************************/
21// Importer for networks stored in SUMO format
22/****************************************************************************/
23#include <config.h>
24#include <string>
34#include <utils/xml/XMLSubSys.h>
38#include <netbuild/NBEdge.h>
39#include <netbuild/NBEdgeCont.h>
40#include <netbuild/NBNode.h>
41#include <netbuild/NBNodeCont.h>
44#include "NILoader.h"
45#include "NIXMLTypesHandler.h"
46#include "NIImporter_SUMO.h"
47
48
49// ===========================================================================
50// method definitions
51// ===========================================================================
52// ---------------------------------------------------------------------------
53// static methods (interface in this case)
54// ---------------------------------------------------------------------------
55void
57 NIImporter_SUMO importer(nb);
58 importer._loadNetwork(oc);
59}
60
61
62// ---------------------------------------------------------------------------
63// loader methods
64// ---------------------------------------------------------------------------
66 : SUMOSAXHandler("sumo-network"),
67 myNetBuilder(nb),
68 myNodeCont(nb.getNodeCont()),
69 myTLLCont(nb.getTLLogicCont()),
70 myTypesHandler(nb.getTypeCont()),
71 myCurrentEdge(nullptr),
72 myCurrentLane(nullptr),
73 myCurrentTL(nullptr),
74 myLocation(nullptr),
75 myNetworkVersion(0),
76 myHaveSeenInternalEdge(false),
77 myAmLefthand(false),
78 myChangeLefthand(false),
79 myCornerDetail(0),
80 myLinkDetail(-1),
81 myRectLaneCut(false),
82 myWalkingAreas(false),
83 myLimitTurnSpeed(-1),
84 myCheckLaneFoesAll(false),
85 myCheckLaneFoesRoundabout(true),
86 myTlsIgnoreInternalJunctionJam(false),
87 myDefaultSpreadType(toString(LaneSpreadFunction::RIGHT)),
88 myGeomAvoidOverlap(true),
89 myJunctionsHigherSpeed(false),
90 myInternalJunctionsVehicleWidth(OptionsCont::getOptions().getFloat("internal-junctions.vehicle-width")) {
91}
92
93
95 for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
96 EdgeAttrs* ed = (*i).second;
97 for (std::vector<LaneAttrs*>::const_iterator j = ed->lanes.begin(); j != ed->lanes.end(); ++j) {
98 delete *j;
99 }
100 delete ed;
101 }
102 delete myLocation;
103}
104
105
106void
108 // check whether the option is set (properly)
109 if (!oc.isUsableFileList("sumo-net-file")) {
110 return;
111 }
112 const std::vector<std::string> discardableParams = oc.getStringVector("discard-params");
113 myDiscardableParams.insert(discardableParams.begin(), discardableParams.end());
114 // parse file(s)
115 const std::vector<std::string> files = oc.getStringVector("sumo-net-file");
116 for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
117 if (!FileHelpers::isReadable(*file)) {
118 WRITE_ERROR("Could not open sumo-net-file '" + *file + "'.");
119 return;
120 }
121 setFileName(*file);
122 const long before = PROGRESS_BEGIN_TIME_MESSAGE("Parsing sumo-net from '" + *file + "'");
123 XMLSubSys::runParser(*this, *file, true);
124 PROGRESS_TIME_MESSAGE(before);
125 }
126 // build edges
127 const double maxSegmentLength = oc.getFloat("geometry.max-segment-length");
128 for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
129 EdgeAttrs* ed = (*i).second;
130 // skip internal edges
132 continue;
133 }
134 // get and check the nodes
135 NBNode* from = myNodeCont.retrieve(ed->fromNode);
136 NBNode* to = myNodeCont.retrieve(ed->toNode);
137 if (from == nullptr) {
138 WRITE_ERROR("Edge's '" + ed->id + "' from-node '" + ed->fromNode + "' is not known.");
139 continue;
140 }
141 if (to == nullptr) {
142 WRITE_ERROR("Edge's '" + ed->id + "' to-node '" + ed->toNode + "' is not known.");
143 continue;
144 }
145 if (from == to) {
146 WRITE_ERROR("Edge's '" + ed->id + "' from-node and to-node '" + ed->toNode + "' are identical.");
147 continue;
148 }
149 if (ed->shape.size() == 0 && maxSegmentLength > 0) {
150 ed->shape.push_back(from->getPosition());
151 ed->shape.push_back(to->getPosition());
152 // shape is already cartesian but we must use a copy because the original will be modified
153 NBNetBuilder::addGeometrySegments(ed->shape, PositionVector(ed->shape), maxSegmentLength);
154 }
155 // build and insert the edge
156 NBEdge* e = new NBEdge(ed->id, from, to,
158 (int) ed->lanes.size(),
160 ed->shape, ed->lsf, ed->streetName, "", true); // always use tryIgnoreNodePositions to keep original shape
161 e->setLoadedLength(ed->length);
163 e->setDistance(ed->distance);
164 if (!myNetBuilder.getEdgeCont().insert(e)) {
165 WRITE_ERROR("Could not insert edge '" + ed->id + "'.");
166 delete e;
167 continue;
168 }
170 if (ed->builtEdge != nullptr) {
172 ed->builtEdge->setBidi(ed->bidi != "");
173 }
174 }
175 // assign further lane attributes (edges are built)
176 EdgeVector toRemove;
177 const bool dismissVclasses = oc.getBool("dismiss-vclasses");
178 for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) {
179 EdgeAttrs* ed = (*i).second;
180 NBEdge* nbe = ed->builtEdge;
181 if (nbe == nullptr) { // inner edge or removed by explicit list, vclass, ...
182 continue;
183 }
184 const SumoXMLNodeType toType = nbe->getToNode()->getType();
185 for (int fromLaneIndex = 0; fromLaneIndex < (int) ed->lanes.size(); ++fromLaneIndex) {
186 LaneAttrs* lane = ed->lanes[fromLaneIndex];
187 // connections
188 const std::vector<Connection>& connections = lane->connections;
189 for (const Connection& c : connections) {
190 if (myEdges.count(c.toEdgeID) == 0) {
191 WRITE_ERROR("Unknown edge '" + c.toEdgeID + "' given in connection.");
192 continue;
193 }
194 NBEdge* toEdge = myEdges[c.toEdgeID]->builtEdge;
195 if (toEdge == nullptr) { // removed by explicit list, vclass, ...
196 continue;
197 }
198 // patch attribute uncontrolled for legacy networks where it is not set explicitly
199 bool uncontrolled = c.uncontrolled;
200
202 && c.tlLinkIndex == NBConnection::InvalidTlIndex) {
203 uncontrolled = true;
204 }
206 fromLaneIndex, toEdge, c.toLaneIdx, NBEdge::Lane2LaneInfoType::VALIDATED,
207 true, c.mayDefinitelyPass, c.keepClear ? KEEPCLEAR_TRUE : KEEPCLEAR_FALSE,
208 c.contPos, c.visibility, c.speed, c.friction, c.customLength, c.customShape, uncontrolled, c.permissions, c.indirectLeft, c.edgeType, c.changeLeft, c.changeRight);
209 if (c.getParametersMap().size() > 0) {
210 nbe->getConnectionRef(fromLaneIndex, toEdge, c.toLaneIdx).updateParameters(c.getParametersMap());
211 }
212 // maybe we have a tls-controlled connection
213 if (c.tlID != "" && myRailSignals.count(c.tlID) == 0) {
214 const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(c.tlID);
215 if (programs.size() > 0) {
216 std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
217 for (it = programs.begin(); it != programs.end(); it++) {
218 NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
219 if (tlDef) {
220 tlDef->addConnection(nbe, toEdge, fromLaneIndex, c.toLaneIdx, c.tlLinkIndex, c.tlLinkIndex2, false);
221 } else {
222 throw ProcessError("Corrupt traffic light definition '" + c.tlID + "' (program '" + it->first + "')");
223 }
224 }
225 } else {
226 WRITE_ERROR("The traffic light '" + c.tlID + "' is not known.");
227 }
228 }
229 }
230 // allow/disallow XXX preferred
231 if (!dismissVclasses) {
232 nbe->setPermissions(parseVehicleClasses(lane->allow, lane->disallow, myNetworkVersion), fromLaneIndex);
233 }
234 nbe->setPermittedChanging(fromLaneIndex, parseVehicleClasses(lane->changeLeft, ""), parseVehicleClasses(lane->changeRight, ""));
235 // width, offset
236 nbe->setLaneWidth(fromLaneIndex, lane->width);
237 nbe->setEndOffset(fromLaneIndex, lane->endOffset);
238 nbe->setSpeed(fromLaneIndex, lane->maxSpeed);
239 nbe->setFriction(fromLaneIndex, lane->friction);
240 nbe->setAcceleration(fromLaneIndex, lane->accelRamp);
241 nbe->getLaneStruct(fromLaneIndex).oppositeID = lane->oppositeID;
242 nbe->getLaneStruct(fromLaneIndex).type = lane->type;
243 nbe->getLaneStruct(fromLaneIndex).updateParameters(lane->getParametersMap());
244 if (lane->customShape) {
245 nbe->setLaneShape(fromLaneIndex, lane->shape);
246 }
247 // stop offset for lane
248 bool stopOffsetSet = false;
249 if (lane->laneStopOffset.isDefined() || nbe->getEdgeStopOffset().isDefined()) {
250 // apply lane-specific stopOffset (might be none as well)
251 stopOffsetSet = nbe->setEdgeStopOffset(fromLaneIndex, lane->laneStopOffset);
252 }
253 if (!stopOffsetSet) {
254 // apply default stop offset to lane
255 nbe->setEdgeStopOffset(fromLaneIndex, nbe->getEdgeStopOffset());
256 }
257 }
259 if (!nbe->hasLaneSpecificWidth() && nbe->getLanes()[0].width != NBEdge::UNSPECIFIED_WIDTH) {
260 nbe->setLaneWidth(-1, nbe->getLaneWidth(0));
261 }
263 nbe->setEndOffset(-1, nbe->getEndOffset(0));
264 }
266 nbe->setEdgeStopOffset(-1, nbe->getEdgeStopOffset());
267 }
268 // check again after permissions are set
271 toRemove.push_back(nbe);
272 }
273 }
274 for (EdgeVector::iterator i = toRemove.begin(); i != toRemove.end(); ++i) {
276 }
277 // insert loaded prohibitions
278 for (std::vector<Prohibition>::const_iterator it = myProhibitions.begin(); it != myProhibitions.end(); it++) {
279 NBEdge* prohibitedFrom = myEdges[it->prohibitedFrom]->builtEdge;
280 NBEdge* prohibitedTo = myEdges[it->prohibitedTo]->builtEdge;
281 NBEdge* prohibitorFrom = myEdges[it->prohibitorFrom]->builtEdge;
282 NBEdge* prohibitorTo = myEdges[it->prohibitorTo]->builtEdge;
283 if (prohibitedFrom == nullptr) {
284 WRITE_WARNINGF(TL("Edge '%' in prohibition was not built."), it->prohibitedFrom);
285 } else if (prohibitedTo == nullptr) {
286 WRITE_WARNINGF(TL("Edge '%' in prohibition was not built."), it->prohibitedTo);
287 } else if (prohibitorFrom == nullptr) {
288 WRITE_WARNINGF(TL("Edge '%' in prohibition was not built."), it->prohibitorFrom);
289 } else if (prohibitorTo == nullptr) {
290 WRITE_WARNINGF(TL("Edge '%' in prohibition was not built."), it->prohibitorTo);
291 } else {
292 NBNode* n = prohibitedFrom->getToNode();
294 NBConnection(prohibitorFrom, prohibitorTo),
295 NBConnection(prohibitedFrom, prohibitedTo));
296 }
297 }
298 if (!myHaveSeenInternalEdge && oc.isWriteable("no-internal-links")) {
299 oc.set("no-internal-links", "true");
300 }
301 if (oc.isWriteable("lefthand")) {
302 oc.set("lefthand", toString(myAmLefthand));
303 }
304 if (oc.isWriteable("junctions.corner-detail")) {
305 oc.set("junctions.corner-detail", toString(myCornerDetail));
306 }
307 if (oc.isWriteable("junctions.internal-link-detail") && myLinkDetail > 0) {
308 oc.set("junctions.internal-link-detail", toString(myLinkDetail));
309 }
310 if (oc.isWriteable("rectangular-lane-cut")) {
311 oc.set("rectangular-lane-cut", toString(myRectLaneCut));
312 }
313 if (oc.isWriteable("walkingareas")) {
314 oc.set("walkingareas", toString(myWalkingAreas));
315 }
316 if (oc.isWriteable("junctions.limit-turn-speed")) {
317 oc.set("junctions.limit-turn-speed", toString(myLimitTurnSpeed));
318 }
319 if (oc.isWriteable("check-lane-foes.all") && oc.getBool("check-lane-foes.all") != myCheckLaneFoesAll) {
320 oc.set("check-lane-foes.all", toString(myCheckLaneFoesAll));
321 }
322 if (oc.isWriteable("check-lane-foes.roundabout") && oc.getBool("check-lane-foes.roundabout") != myCheckLaneFoesRoundabout) {
323 oc.set("check-lane-foes.roundabout", toString(myCheckLaneFoesRoundabout));
324 }
325 if (oc.isWriteable("tls.ignore-internal-junction-jam") && oc.getBool("tls.ignore-internal-junction-jam") != myTlsIgnoreInternalJunctionJam) {
326 oc.set("tls.ignore-internal-junction-jam", toString(myTlsIgnoreInternalJunctionJam));
327 }
328 if (oc.isWriteable("default.spreadtype") && oc.getString("default.spreadtype") != myDefaultSpreadType) {
329 oc.set("default.spreadtype", myDefaultSpreadType);
330 }
331 if (oc.isWriteable("geometry.avoid-overlap") && oc.getBool("geometry.avoid-overlap") != myGeomAvoidOverlap) {
332 oc.set("geometry.avoid-overlap", toString(myGeomAvoidOverlap));
333 }
334 if (oc.isWriteable("junctions.higher-speed") && oc.getBool("junctions.higher-speed") != myJunctionsHigherSpeed) {
335 oc.set("junctions.higher-speed", toString(myJunctionsHigherSpeed));
336 }
337 if (oc.isWriteable("internal-junctions.vehicle-width") && oc.getFloat("internal-junctions.vehicle-width") != myInternalJunctionsVehicleWidth) {
338 oc.set("internal-junctions.vehicle-width", toString(myInternalJunctionsVehicleWidth));
339 }
340 if (!deprecatedVehicleClassesSeen.empty()) {
341 WRITE_WARNING("Deprecated vehicle class(es) '" + toString(deprecatedVehicleClassesSeen) + "' in input network.");
343 }
344 if (!oc.getBool("no-internal-links")) {
345 // add loaded crossings
346 for (std::map<std::string, std::vector<Crossing> >::const_iterator it = myPedestrianCrossings.begin(); it != myPedestrianCrossings.end(); ++it) {
347 NBNode* node = myNodeCont.retrieve((*it).first);
348 for (std::vector<Crossing>::const_iterator it_c = (*it).second.begin(); it_c != (*it).second.end(); ++it_c) {
349 const Crossing& crossing = (*it_c);
350 EdgeVector edges;
351 for (std::vector<std::string>::const_iterator it_e = crossing.crossingEdges.begin(); it_e != crossing.crossingEdges.end(); ++it_e) {
352 NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_e);
353 // edge might have been removed due to options
354 if (edge != nullptr) {
355 edges.push_back(edge);
356 }
357 }
358 if (edges.size() > 0) {
359 node->addCrossing(edges, crossing.width, crossing.priority, crossing.customTLIndex, crossing.customTLIndex2, crossing.customShape, true);
360 }
361 }
362 }
363 // add walking area custom shapes
364 for (auto item : myWACustomShapes) {
365 std::string nodeID = SUMOXMLDefinitions::getJunctionIDFromInternalEdge(item.first);
366 NBNode* node = myNodeCont.retrieve(nodeID);
367 std::vector<std::string> edgeIDs;
368 if (item.second.fromEdges.size() + item.second.toEdges.size() == 0) {
369 // must be a split crossing
370 assert(item.second.fromCrossed.size() > 0);
371 assert(item.second.toCrossed.size() > 0);
372 edgeIDs = item.second.fromCrossed;
373 edgeIDs.insert(edgeIDs.end(), item.second.toCrossed.begin(), item.second.toCrossed.end());
374 } else if (item.second.fromEdges.size() > 0) {
375 edgeIDs = item.second.fromEdges;
376 } else {
377 edgeIDs = item.second.toEdges;
378 }
379 EdgeVector edges;
380 for (std::string edgeID : edgeIDs) {
381 NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(edgeID);
382 // edge might have been removed due to options
383 if (edge != nullptr) {
384 edges.push_back(edge);
385 }
386 }
387 if (edges.size() > 0) {
388 node->addWalkingAreaShape(edges, item.second.shape, item.second.width);
389 }
390 }
391 }
392 // add roundabouts
393 for (std::vector<std::vector<std::string> >::const_iterator it = myRoundabouts.begin(); it != myRoundabouts.end(); ++it) {
394 EdgeSet roundabout;
395 for (std::vector<std::string>::const_iterator it_r = it->begin(); it_r != it->end(); ++it_r) {
396 NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_r);
397 if (edge == nullptr) {
398 if (!myNetBuilder.getEdgeCont().wasIgnored(*it_r)) {
399 WRITE_ERROR("Unknown edge '" + (*it_r) + "' in roundabout");
400 }
401 } else {
402 roundabout.insert(edge);
403 }
404 }
406 }
407}
408
409
410
411void
413 const SUMOSAXAttributes& attrs) {
414 /* our goal is to reproduce the input net faithfully
415 * there are different types of objects in the netfile:
416 * 1) those which must be loaded into NBNetBuilder-Containers for processing
417 * 2) those which can be ignored because they are recomputed based on group 1
418 * 3) those which are of no concern to NBNetBuilder but should be exposed to
419 * NETEDIT. We will probably have to patch NBNetBuilder to contain them
420 * and hand them over to NETEDIT
421 * alternative idea: those shouldn't really be contained within the
422 * network but rather in separate files. teach NETEDIT how to open those
423 * (POI?)
424 * 4) those which are of concern neither to NBNetBuilder nor NETEDIT and
425 * must be copied over - need to patch NBNetBuilder for this.
426 * copy unknown by default
427 */
428 switch (element) {
429 case SUMO_TAG_NET: {
430 bool ok;
431 myNetworkVersion = attrs.getOpt<double>(SUMO_ATTR_VERSION, nullptr, ok, 0);
432 myAmLefthand = attrs.getOpt<bool>(SUMO_ATTR_LEFTHAND, nullptr, ok, false);
433 myCornerDetail = attrs.getOpt<int>(SUMO_ATTR_CORNERDETAIL, nullptr, ok, 0);
434 myLinkDetail = attrs.getOpt<int>(SUMO_ATTR_LINKDETAIL, nullptr, ok, -1);
435 myRectLaneCut = attrs.getOpt<bool>(SUMO_ATTR_RECTANGULAR_LANE_CUT, nullptr, ok, false);
436 myWalkingAreas = attrs.getOpt<bool>(SUMO_ATTR_WALKINGAREAS, nullptr, ok, false);
437 myLimitTurnSpeed = attrs.getOpt<double>(SUMO_ATTR_LIMIT_TURN_SPEED, nullptr, ok, -1);
438 myCheckLaneFoesAll = attrs.getOpt<bool>(SUMO_ATTR_CHECKLANEFOES_ALL, nullptr, ok, false);
441 myDefaultSpreadType = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, nullptr, ok, myDefaultSpreadType);
445 // derived
447 myChangeLefthand = !oc.isDefault("lefthand") && (oc.getBool("lefthand") != myAmLefthand);
448
449 break;
450 }
451 case SUMO_TAG_EDGE:
452 addEdge(attrs);
453 break;
454 case SUMO_TAG_LANE:
455 addLane(attrs);
456 break;
457 case SUMO_TAG_STOPOFFSET: {
458 bool ok = true;
459 addStopOffsets(attrs, ok);
460 }
461 break;
462 case SUMO_TAG_NEIGH:
464 break;
466 addJunction(attrs);
467 break;
468 case SUMO_TAG_REQUEST:
469 addRequest(attrs);
470 break;
472 addConnection(attrs);
473 break;
474 case SUMO_TAG_TLLOGIC:
476 if (myCurrentTL) {
478 }
479 break;
480 case SUMO_TAG_PHASE:
481 addPhase(attrs, myCurrentTL);
482 break;
484 delete myLocation;
485 myLocation = loadLocation(attrs);
486 break;
488 addProhibition(attrs);
489 break;
491 addRoundabout(attrs);
492 break;
493 case SUMO_TAG_PARAM:
494 if (myLastParameterised.size() != 0) {
495 bool ok = true;
496 const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
497 if (myDiscardableParams.count(key) == 0) {
498 // circumventing empty string test
499 const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
500 myLastParameterised.back()->setParameter(key, val);
501 }
502 }
503 break;
504 default:
505 myTypesHandler.myStartElement(element, attrs);
506 break;
507 }
508}
509
510
511void
513 switch (element) {
514 case SUMO_TAG_EDGE:
515 if (myCurrentEdge != nullptr) {
516 if (myEdges.find(myCurrentEdge->id) != myEdges.end()) {
517 WRITE_WARNINGF(TL("Edge '%' occurred at least twice in the input."), myCurrentEdge->id);
518 } else {
520 }
521 myCurrentEdge = nullptr;
522 myLastParameterised.pop_back();
523 }
524 break;
525 case SUMO_TAG_LANE:
526 if (myCurrentEdge != nullptr && myCurrentLane != nullptr) {
529 myLastParameterised.pop_back();
530 }
531 myCurrentLane = nullptr;
532 break;
533 case SUMO_TAG_TLLOGIC:
534 if (!myCurrentTL) {
535 WRITE_ERROR(TL("Unmatched closing tag for tl-logic."));
536 } else {
538 WRITE_WARNING("Could not add program '" + myCurrentTL->getProgramID() + "' for traffic light '" + myCurrentTL->getID() + "'");
539 delete myCurrentTL;
540 }
541 myCurrentTL = nullptr;
542 myLastParameterised.pop_back();
543 }
544 break;
546 if (myCurrentJunction.node != nullptr) {
547 myLastParameterised.pop_back();
548 }
549 break;
551 // !!! this just avoids a crash but is not a real check that it was a connection
552 if (!myLastParameterised.empty()) {
553 myLastParameterised.pop_back();
554 }
555 break;
556 default:
557 break;
558 }
559}
560
561
562void
564 // get the id, report an error if not given or empty...
565 bool ok = true;
566 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
567 if (!ok) {
568 return;
569 }
570 myCurrentEdge = new EdgeAttrs();
572 myCurrentEdge->builtEdge = nullptr;
573 myCurrentEdge->id = id;
574 // get the function
577 // add the crossing but don't do anything else
578 Crossing c(id);
579 c.crossingEdges = attrs.get<std::vector<std::string> >(SUMO_ATTR_CROSSING_EDGES, nullptr, ok);
581 return;
584 return; // skip internal edges
585 }
586 // get the type
587 myCurrentEdge->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
588 // get the origin and the destination node
589 myCurrentEdge->fromNode = attrs.getOpt<std::string>(SUMO_ATTR_FROM, id.c_str(), ok, "");
590 myCurrentEdge->toNode = attrs.getOpt<std::string>(SUMO_ATTR_TO, id.c_str(), ok, "");
591 myCurrentEdge->priority = attrs.getOpt<int>(SUMO_ATTR_PRIORITY, id.c_str(), ok, -1);
592 myCurrentEdge->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
597 myCurrentEdge->streetName = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
598 myCurrentEdge->distance = attrs.getOpt<double>(SUMO_ATTR_DISTANCE, id.c_str(), ok, 0);
599 myCurrentEdge->bidi = attrs.getOpt<std::string>(SUMO_ATTR_BIDI, id.c_str(), ok, "");
600 if (myCurrentEdge->streetName != "" && OptionsCont::getOptions().isDefault("output.street-names")) {
601 OptionsCont::getOptions().set("output.street-names", "true");
602 }
603
604 std::string lsfS = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, id.c_str(), ok, myDefaultSpreadType);
605 if (SUMOXMLDefinitions::LaneSpreadFunctions.hasString(lsfS)) {
607 } else {
608 WRITE_ERROR("Unknown spreadType '" + lsfS + "' for edge '" + id + "'.");
609 }
610}
611
612
613void
615 bool ok = true;
616 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
617 if (!ok) {
618 return;
619 }
620 if (!myCurrentEdge) {
621 WRITE_ERROR("Found lane '" + id + "' not within edge element.");
622 return;
623 }
624 const std::string expectedID = myCurrentEdge->id + "_" + toString(myCurrentEdge->lanes.size());
625 if (id != expectedID) {
626 WRITE_WARNING("Renaming lane '" + id + "' to '" + expectedID + "'.");
627 }
628 myCurrentLane = new LaneAttrs();
630 myCurrentLane->customShape = attrs.getOpt<bool>(SUMO_ATTR_CUSTOMSHAPE, nullptr, ok, false);
631 myCurrentLane->shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
632 myCurrentLane->width = attrs.getOpt<double>(SUMO_ATTR_WIDTH, id.c_str(), ok, (double) NBEdge::UNSPECIFIED_WIDTH);
633 myCurrentLane->type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
635 // save the width and the lane id of the crossing but don't do anything else
637 assert(crossings.size() > 0);
638 crossings.back().width = attrs.get<double>(SUMO_ATTR_WIDTH, id.c_str(), ok);
640 crossings.back().customShape = myCurrentLane->shape;
641 NBNetBuilder::transformCoordinates(crossings.back().customShape, true, myLocation);
642 }
644 // save custom shape if needed but don't do anything else
647 wacs.shape = myCurrentLane->shape;
648 wacs.width = myCurrentLane->width;
651 }
652 return;
654 return; // skip internal edges
655 }
656 if (attrs.hasAttribute("maxspeed")) {
657 // !!! deprecated
658 myCurrentLane->maxSpeed = attrs.getFloat("maxspeed");
659 } else {
660 myCurrentLane->maxSpeed = attrs.get<double>(SUMO_ATTR_SPEED, id.c_str(), ok);
661 }
662 myCurrentLane->friction = attrs.getOpt<double>(SUMO_ATTR_FRICTION, id.c_str(), ok, NBEdge::UNSPECIFIED_FRICTION, false); //sets 1 on empty
663 try {
664 myCurrentLane->allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "", false);
665 } catch (EmptyData&) {
666 // !!! deprecated
667 myCurrentLane->allow = "";
668 }
669 myCurrentLane->disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
670 myCurrentLane->endOffset = attrs.getOpt<double>(SUMO_ATTR_ENDOFFSET, id.c_str(), ok, (double) NBEdge::UNSPECIFIED_OFFSET);
671 myCurrentLane->accelRamp = attrs.getOpt<bool>(SUMO_ATTR_ACCELERATION, id.c_str(), ok, false);
672 myCurrentLane->changeLeft = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_LEFT, id.c_str(), ok, "");
673 myCurrentLane->changeRight = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_RIGHT, id.c_str(), ok, "");
674 if (myChangeLefthand) {
676 }
677
678 // lane coordinates are derived (via lane spread) do not include them in convex boundary
680}
681
682
683void
685 const StopOffset offset(attrs, ok);
686 if (!ok) {
687 return;
688 }
689 // Admissibility of value will be checked in _loadNetwork(), when lengths are known
690 if (myCurrentLane == nullptr) {
692 WRITE_WARNING("Duplicate definition of stopOffset for edge " + myCurrentEdge->id + ".\nIgnoring duplicate specification.");
693 } else {
695 }
696 } else {
698 WRITE_WARNING("Duplicate definition of lane's stopOffset on edge " + myCurrentEdge->id + ".\nIgnoring duplicate specifications.");
699 } else {
701 }
702 }
703}
704
705
706void
708 // get the id, report an error if not given or empty...
709 myCurrentJunction.node = nullptr;
712 bool ok = true;
713 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
714 if (!ok) {
715 return;
716 }
717 if (id[0] == ':') { // internal node
718 return;
719 }
721 if (ok) {
723 // dead end is a computed status. Reset this to unknown so it will
724 // be corrected if additional connections are loaded
726 }
727 }
728 Position pos = readPosition(attrs, id, ok);
730 NBNode* node = new NBNode(id, pos, type);
731 if (!myNodeCont.insert(node)) {
732 WRITE_WARNINGF(TL("Junction '%' occurred at least twice in the input."), id);
733 delete node;
735 return;
736 } else {
737 myLastParameterised.push_back(node);
738 }
739 myCurrentJunction.node = node;
740 myCurrentJunction.intLanes = attrs.get<std::vector<std::string> >(SUMO_ATTR_INTLANES, nullptr, ok, false);
741 // set optional radius
742 if (attrs.hasAttribute(SUMO_ATTR_RADIUS)) {
743 node->setRadius(attrs.get<double>(SUMO_ATTR_RADIUS, id.c_str(), ok));
744 }
745 // handle custom shape
746 if (attrs.getOpt<bool>(SUMO_ATTR_CUSTOMSHAPE, id.c_str(), ok, false)) {
747 PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
749 node->setCustomShape(shape);
750 }
752 // both types of nodes come without a tlLogic
753 myRailSignals.insert(id);
754 }
755 node->setRightOfWay(attrs.getOpt<RightOfWay>(SUMO_ATTR_RIGHT_OF_WAY, id.c_str(), ok, node->getRightOfWay()));
756 node->setFringeType(attrs.getOpt<FringeType>(SUMO_ATTR_FRINGE, id.c_str(), ok, node->getFringeType()));
757 if (attrs.hasAttribute(SUMO_ATTR_NAME)) {
758 node->setName(attrs.get<std::string>(SUMO_ATTR_NAME, id.c_str(), ok));
759 }
760}
761
762
763void
765 if (myCurrentJunction.node != nullptr) {
766 bool ok = true;
767 myCurrentJunction.response.push_back(attrs.get<std::string>(SUMO_ATTR_RESPONSE, nullptr, ok));
768 }
769}
770
771
772void
774 bool ok = true;
775 std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
776 if (myEdges.count(fromID) == 0) {
777 WRITE_ERROR("Unknown edge '" + fromID + "' given in connection.");
778 return;
779 }
780 EdgeAttrs* from = myEdges[fromID];
781 Connection conn;
782 conn.toEdgeID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
783 int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
784 conn.toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
785 conn.tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, nullptr, ok, "");
786 conn.mayDefinitelyPass = attrs.getOpt<bool>(SUMO_ATTR_PASS, nullptr, ok, false);
787 conn.keepClear = attrs.getOpt<bool>(SUMO_ATTR_KEEP_CLEAR, nullptr, ok, true);
788 conn.indirectLeft = attrs.getOpt<bool>(SUMO_ATTR_INDIRECT, nullptr, ok, false);
789 conn.edgeType = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, nullptr, ok, "");
790 conn.contPos = attrs.getOpt<double>(SUMO_ATTR_CONTPOS, nullptr, ok, NBEdge::UNSPECIFIED_CONTPOS);
792 std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, nullptr, ok, "", false);
793 std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, nullptr, ok, "", false);
794 if (allow == "" && disallow == "") {
796 } else {
797 conn.permissions = parseVehicleClasses(allow, disallow, myNetworkVersion);
798 }
800 conn.changeLeft = parseVehicleClasses(attrs.get<std::string>(SUMO_ATTR_CHANGE_LEFT, nullptr, ok), "");
801 } else {
803 }
805 conn.changeRight = parseVehicleClasses(attrs.get<std::string>(SUMO_ATTR_CHANGE_RIGHT, nullptr, ok), "");
806 } else {
808 }
809 if (myChangeLefthand) {
810 std::swap(conn.changeLeft, conn.changeRight);
811 }
812 conn.speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, nullptr, ok, NBEdge::UNSPECIFIED_SPEED);
813 conn.friction = attrs.getOpt<double>(SUMO_ATTR_FRICTION, nullptr, ok, NBEdge::UNSPECIFIED_FRICTION);
814 conn.customLength = attrs.getOpt<double>(SUMO_ATTR_LENGTH, nullptr, ok, NBEdge::UNSPECIFIED_LOADED_LENGTH);
818 if (conn.tlID != "") {
819 conn.tlLinkIndex = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok);
820 conn.tlLinkIndex2 = attrs.getOpt<int>(SUMO_ATTR_TLLINKINDEX2, nullptr, ok, -1);
821 } else {
823 }
824 if ((int)from->lanes.size() <= fromLaneIdx) {
825 WRITE_ERROR("Invalid lane index '" + toString(fromLaneIdx) + "' for connection from '" + fromID + "'.");
826 return;
827 }
828 from->lanes[fromLaneIdx]->connections.push_back(conn);
829 myLastParameterised.push_back(&from->lanes[fromLaneIdx]->connections.back());
830
831 // determine crossing priority and tlIndex
832 if (myPedestrianCrossings.size() > 0) {
834 // connection from walkingArea to crossing
835 std::vector<Crossing>& crossings = myPedestrianCrossings[SUMOXMLDefinitions::getJunctionIDFromInternalEdge(fromID)];
836 for (std::vector<Crossing>::iterator it = crossings.begin(); it != crossings.end(); ++it) {
837 if (conn.toEdgeID == (*it).edgeID) {
838 if (conn.tlID != "") {
839 (*it).priority = true;
840 (*it).customTLIndex = conn.tlLinkIndex;
841 } else {
842 LinkState state = SUMOXMLDefinitions::LinkStates.get(attrs.get<std::string>(SUMO_ATTR_STATE, nullptr, ok));
843 (*it).priority = state == LINKSTATE_MAJOR;
844 }
845 }
846 }
847 } else if (from->func == SumoXMLEdgeFunc::CROSSING && myEdges[conn.toEdgeID]->func == SumoXMLEdgeFunc::WALKINGAREA) {
848 // connection from crossing to walkingArea (set optional linkIndex2)
850 if (fromID == c.edgeID) {
851 c.customTLIndex2 = attrs.getOpt<int>(SUMO_ATTR_TLLINKINDEX, nullptr, ok, -1);
852 }
853 }
854 }
855 }
856 // determine walking area reference edges
857 if (myWACustomShapes.size() > 0) {
858 EdgeAttrs* to = myEdges[conn.toEdgeID];
859 if (from->func == SumoXMLEdgeFunc::WALKINGAREA) {
860 std::map<std::string, WalkingAreaParsedCustomShape>::iterator it = myWACustomShapes.find(fromID);
861 if (it != myWACustomShapes.end()) {
862 if (to->func == SumoXMLEdgeFunc::NORMAL) {
863 // add target sidewalk as reference
864 it->second.toEdges.push_back(conn.toEdgeID);
865 } else if (to->func == SumoXMLEdgeFunc::CROSSING) {
866 // add target crossing edges as reference
868 if (conn.toEdgeID == crossing.edgeID) {
869 it->second.toCrossed.insert(it->second.toCrossed.end(), crossing.crossingEdges.begin(), crossing.crossingEdges.end());
870 }
871 }
872 }
873 }
874 } else if (to->func == SumoXMLEdgeFunc::WALKINGAREA) {
875 std::map<std::string, WalkingAreaParsedCustomShape>::iterator it = myWACustomShapes.find(conn.toEdgeID);
876 if (it != myWACustomShapes.end()) {
877 if (from->func == SumoXMLEdgeFunc::NORMAL) {
878 // add origin sidewalk as reference
879 it->second.fromEdges.push_back(fromID);
880 } else if (from->func == SumoXMLEdgeFunc::CROSSING) {
881 // add origin crossing edges as reference
883 if (fromID == crossing.edgeID) {
884 it->second.fromCrossed.insert(it->second.fromCrossed.end(), crossing.crossingEdges.begin(), crossing.crossingEdges.end());
885 }
886 }
887 }
888 }
889 }
890 }
891}
892
893
894void
896 bool ok = true;
897 std::string prohibitor = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITOR, nullptr, ok, "");
898 std::string prohibited = attrs.getOpt<std::string>(SUMO_ATTR_PROHIBITED, nullptr, ok, "");
899 if (!ok) {
900 return;
901 }
902 Prohibition p;
905 if (!ok) {
906 return;
907 }
908 myProhibitions.push_back(p);
909}
910
911
914 if (currentTL) {
915 WRITE_ERROR("Definition of tl-logic '" + currentTL->getID() + "' was not finished.");
916 return nullptr;
917 }
918 bool ok = true;
919 std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
920 SUMOTime offset = TIME2STEPS(attrs.get<double>(SUMO_ATTR_OFFSET, id.c_str(), ok));
921 std::string programID = attrs.getOpt<std::string>(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
922 std::string typeS = attrs.get<std::string>(SUMO_ATTR_TYPE, nullptr, ok);
923 TrafficLightType type;
924 if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
926 } else {
927 WRITE_ERROR("Unknown traffic light type '" + typeS + "' for tlLogic '" + id + "'.");
928 return nullptr;
929 }
930 if (ok) {
931 return new NBLoadedSUMOTLDef(id, programID, offset, type);
932 } else {
933 return nullptr;
934 }
935}
936
937
938void
940 if (!currentTL) {
941 WRITE_ERROR(TL("found phase without tl-logic"));
942 return;
943 }
944 const std::string& id = currentTL->getID();
945 bool ok = true;
946 std::string state = attrs.get<std::string>(SUMO_ATTR_STATE, id.c_str(), ok);
947 SUMOTime duration = TIME2STEPS(attrs.get<double>(SUMO_ATTR_DURATION, id.c_str(), ok));
948 if (duration < 0) {
949 WRITE_ERROR("Phase duration for tl-logic '" + id + "/" + currentTL->getProgramID() + "' must be positive.");
950 return;
951 }
952 // if the traffic light is an actuated traffic light, try to get the minimum and maximum durations and ends
953 std::vector<int> nextPhases = attrs.getOpt<std::vector<int> >(SUMO_ATTR_NEXT, id.c_str(), ok);
954 const std::string name = attrs.getOpt<std::string>(SUMO_ATTR_NAME, nullptr, ok);
955 // Specific from actuated
960 // specific von NEMA
964 if (ok) {
965 currentTL->addPhase(duration, state, minDuration, maxDuration, earliestEnd, latestEnd, vehExt, yellow, red, nextPhases, name);
966 }
967}
968
969
972 // @todo refactor parsing of location since its duplicated in NLHandler and PCNetProjectionLoader
973 bool ok = true;
974 GeoConvHelper* result = nullptr;
975 PositionVector s = attrs.get<PositionVector>(SUMO_ATTR_NET_OFFSET, nullptr, ok);
976 Boundary convBoundary = attrs.get<Boundary>(SUMO_ATTR_CONV_BOUNDARY, nullptr, ok);
977 Boundary origBoundary = attrs.get<Boundary>(SUMO_ATTR_ORIG_BOUNDARY, nullptr, ok);
978 std::string proj = attrs.get<std::string>(SUMO_ATTR_ORIG_PROJ, nullptr, ok);
979 if (ok) {
980 Position networkOffset = s[0];
981 result = new GeoConvHelper(proj, networkOffset, origBoundary, convBoundary);
983 }
984 return result;
985}
986
987
989NIImporter_SUMO::readPosition(const SUMOSAXAttributes& attrs, const std::string& id, bool& ok) {
990 const double x = attrs.get<double>(SUMO_ATTR_X, id.c_str(), ok);
991 const double y = attrs.get<double>(SUMO_ATTR_Y, id.c_str(), ok);
992 const double z = attrs.getOpt<double>(SUMO_ATTR_Z, id.c_str(), ok, 0.);
993 return Position(x, y, z);
994}
995
996
997void
998NIImporter_SUMO::parseProhibitionConnection(const std::string& attr, std::string& from, std::string& to, bool& ok) {
999 // split from/to
1000 const std::string::size_type div = attr.find("->");
1001 if (div == std::string::npos) {
1002 WRITE_ERROR("Missing connection divider in prohibition attribute '" + attr + "'");
1003 ok = false;
1004 }
1005 from = attr.substr(0, div);
1006 to = attr.substr(div + 2);
1007 // check whether the definition includes a lane information and discard it
1008 if (from.find('_') != std::string::npos) {
1009 from = from.substr(0, from.find('_'));
1010 }
1011 if (to.find('_') != std::string::npos) {
1012 to = to.substr(0, to.find('_'));
1013 }
1014 // check whether the edges are known
1015 if (myEdges.count(from) == 0) {
1016 WRITE_ERROR("Unknown edge prohibition '" + from + "'");
1017 ok = false;
1018 }
1019 if (myEdges.count(to) == 0) {
1020 WRITE_ERROR("Unknown edge prohibition '" + to + "'");
1021 ok = false;
1022 }
1023}
1024
1025
1026void
1028 bool ok = true;
1029 const std::vector<std::string>& edgeIDs = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, nullptr, ok);
1030 if (ok) {
1031 myRoundabouts.push_back(edgeIDs);
1032 }
1033}
1034
1035
1036/****************************************************************************/
long long int SUMOTime
Definition: GUI.h:36
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:266
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:274
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:265
#define PROGRESS_BEGIN_TIME_MESSAGE(msg)
Definition: MsgHandler.h:271
#define TL(string)
Definition: MsgHandler.h:282
#define PROGRESS_TIME_MESSAGE(before)
Definition: MsgHandler.h:272
std::set< NBEdge * > EdgeSet
container for unique edges
Definition: NBCont.h:50
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:42
@ KEEPCLEAR_FALSE
Definition: NBCont.h:59
@ KEEPCLEAR_TRUE
Definition: NBCont.h:60
#define TIME2STEPS(x)
Definition: SUMOTime.h:56
std::set< std::string > deprecatedVehicleClassesSeen
const SVCPermissions SVC_UNSPECIFIED
permissions not specified
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
@ RIGHT
At the rightmost side of the lane.
TrafficLightType
@ SUMO_TAG_PHASE
a single phase description
@ SUMO_TAG_NET
root element of a network file
@ SUMO_TAG_STOPOFFSET
Information on vClass specific stop offsets at lane end.
@ SUMO_TAG_REQUEST
description of a logic request within the junction
@ SUMO_TAG_PROHIBITION
prohibition of circulation between two edges
@ SUMO_TAG_LOCATION
@ SUMO_TAG_CONNECTION
connectio between two lanes
@ SUMO_TAG_ROUNDABOUT
roundabout defined in junction
@ SUMO_TAG_TLLOGIC
a traffic light logic
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ SUMO_TAG_PARAM
parameter associated to a certain key
@ SUMO_TAG_NEIGH
begin/end of the description of a neighboring lane
@ SUMO_TAG_EDGE
begin/end of the description of an edge
LaneSpreadFunction
Numbers representing special SUMO-XML-attribute values Information how the edge's lateral offset shal...
FringeType
classifying boundary nodes
SumoXMLEdgeFunc
Numbers representing special SUMO-XML-attribute values for representing edge functions used in netbui...
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
@ LINKSTATE_MAJOR
This is an uncontrolled, major link, may pass.
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
RightOfWay
algorithms for computing right of way
@ SUMO_ATTR_DISALLOW
@ SUMO_ATTR_CONV_BOUNDARY
@ SUMO_ATTR_ALLOW
@ SUMO_ATTR_LANE
@ SUMO_ATTR_NET_OFFSET
@ SUMO_ATTR_ORIG_BOUNDARY
@ SUMO_ATTR_LATEST_END
The maximum time within the cycle for switching (for coordinated actuation)
@ SUMO_ATTR_TLLINKINDEX2
link: the index of the opposite direction link of a pedestrian crossing
@ SUMO_ATTR_RED
red duration of a phase
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_LINKDETAIL
@ SUMO_ATTR_VALUE
@ SUMO_ATTR_CORNERDETAIL
@ SUMO_ATTR_RADIUS
The turning radius at an intersection in m.
@ SUMO_ATTR_INDIRECT
Whether this connection is an indirect (left) turn.
@ SUMO_ATTR_RECTANGULAR_LANE_CUT
@ SUMO_ATTR_Y
@ SUMO_ATTR_FROM_LANE
@ SUMO_ATTR_Z
@ SUMO_ATTR_RESPONSE
@ SUMO_ATTR_LIMIT_TURN_SPEED
@ SUMO_ATTR_CHECKLANEFOES_ROUNDABOUT
@ SUMO_ATTR_OFFSET
@ SUMO_ATTR_X
@ SUMO_ATTR_AVOID_OVERLAP
@ SUMO_ATTR_YELLOW
yellow duration of a phase
@ SUMO_ATTR_CUSTOMSHAPE
whether a given shape is user-defined
@ SUMO_ATTR_INTLANES
@ SUMO_ATTR_VEHICLEEXTENSION
vehicle extension time of a phase
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_FRINGE
Fringe type of node.
@ SUMO_ATTR_BIDI
@ SUMO_ATTR_PROHIBITED
@ SUMO_ATTR_PRIORITY
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_LEFTHAND
@ SUMO_ATTR_NEXT
succesor phase index
@ SUMO_ATTR_CHANGE_LEFT
@ SUMO_ATTR_NAME
@ SUMO_ATTR_ORIG_PROJ
@ SUMO_ATTR_CHECKLANEFOES_ALL
@ SUMO_ATTR_SPREADTYPE
The information about how to spread the lanes from the given position.
@ SUMO_ATTR_PASS
@ SUMO_ATTR_ENDOFFSET
@ SUMO_ATTR_HIGHER_SPEED
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_ACCELERATION
@ SUMO_ATTR_CHANGE_RIGHT
@ SUMO_ATTR_TLID
link,node: the traffic light id responsible for this link
@ SUMO_ATTR_DISTANCE
@ SUMO_ATTR_TO_LANE
@ SUMO_ATTR_UNCONTROLLED
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_VERSION
@ SUMO_ATTR_ID
@ SUMO_ATTR_MAXDURATION
maximum duration of a phase
@ SUMO_ATTR_RIGHT_OF_WAY
How to compute right of way.
@ SUMO_ATTR_PROGRAMID
@ SUMO_ATTR_FUNCTION
@ SUMO_ATTR_VISIBILITY_DISTANCE
foe visibility distance of a link
@ SUMO_ATTR_PROHIBITOR
@ SUMO_ATTR_DURATION
@ SUMO_ATTR_CONTPOS
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_CROSSING_EDGES
the edges crossed by a pedestrian crossing
@ SUMO_ATTR_TLS_IGNORE_INTERNAL_JUNCTION_JAM
@ SUMO_ATTR_TLLINKINDEX
link: the index of the link within the traffic light
@ SUMO_ATTR_MINDURATION
@ SUMO_ATTR_KEY
@ SUMO_ATTR_KEEP_CLEAR
Whether vehicles must keep the junction clear.
@ SUMO_ATTR_INTERNAL_JUNCTIONS_VEHICLE_WIDTH
@ SUMO_ATTR_STATE
The state of a link.
@ SUMO_ATTR_FRICTION
@ SUMO_ATTR_WALKINGAREAS
@ SUMO_ATTR_EARLIEST_END
The minimum time within the cycle for switching (for coordinated actuation)
T MAX2(T a, T b)
Definition: StdDefs.h:77
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
static bool isReadable(std::string path)
Checks whether the given file is readable.
Definition: FileHelpers.cpp:51
void setFileName(const std::string &name)
Sets the current file name.
static methods for processing the coordinates conversion for the current net
Definition: GeoConvHelper.h:53
static void setLoaded(const GeoConvHelper &loaded)
sets the coordinate transformation loaded from a location element
static const int InvalidTlIndex
Definition: NBConnection.h:123
void addRoundabout(const EdgeSet &roundabout)
add user specified roundabout
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
Definition: NBEdgeCont.cpp:404
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:274
bool ignoreFilterMatch(NBEdge *edge)
Returns true if this edge matches one of the removal criteria.
Definition: NBEdgeCont.cpp:198
void ignore(std::string id)
mark the given edge id as ignored
Definition: NBEdgeCont.h:500
bool wasIgnored(std::string id) const
Returns whether the edge with the id was ignored during parsing.
Definition: NBEdgeCont.h:495
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:177
The representation of a single edge during network building.
Definition: NBEdge.h:92
void setPermittedChanging(int lane, SVCPermissions changeLeft, SVCPermissions changeRight)
set allowed classes for changing to the left and right from the given lane
Definition: NBEdge.cpp:4128
void setPermissions(SVCPermissions permissions, int lane=-1)
set allowed/disallowed classes for the given lane or for all lanes if -1 is given
Definition: NBEdge.cpp:4100
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4052
double getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:648
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:552
Connection & getConnectionRef(int fromLane, const NBEdge *to, int toLane)
Returns reference to the specified connection This method goes through "myConnections" and returns th...
Definition: NBEdge.cpp:1267
static const double UNSPECIFIED_FRICTION
unspecified lane friction
Definition: NBEdge.h:366
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1426
static const bool UNSPECIFIED_CONNECTION_UNCONTROLLED
TLS-controlled despite its node controlled not specified.
Definition: NBEdge.h:387
bool addLane2LaneConnection(int fromLane, NBEdge *dest, int toLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, KeepClear keepClear=KEEPCLEAR_UNSPECIFIED, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE, double speed=UNSPECIFIED_SPEED, double friction=UNSPECIFIED_FRICTION, double length=myDefaultConnectionLength, const PositionVector &customShape=PositionVector::EMPTY, const bool uncontrolled=UNSPECIFIED_CONNECTION_UNCONTROLLED, SVCPermissions permissions=SVC_UNSPECIFIED, const bool indirectLeft=false, const std::string &edgeType="", SVCPermissions changeLeft=SVC_UNSPECIFIED, SVCPermissions changeRight=SVC_UNSPECIFIED, bool postProcess=false)
Adds a connection between the specified this edge's lane and an approached one.
Definition: NBEdge.cpp:1092
void setDistance(double distance)
set kilometrage at start of edge (negative value implies couting down along the edge)
Definition: NBEdge.h:1416
bool setEdgeStopOffset(int lane, const StopOffset &offset, bool overwrite=false)
set lane and vehicle class specific stopOffset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4022
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:736
bool hasLaneSpecificStopOffsets() const
whether lanes differ in stopOffsets
Definition: NBEdge.cpp:2430
const std::string & getID() const
Definition: NBEdge.h:1526
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
Definition: NBEdge.h:375
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3923
void setAcceleration(int lane, bool accelRamp)
marks one lane as acceleration lane
Definition: NBEdge.cpp:4084
const StopOffset & getEdgeStopOffset() const
Returns the stopOffset to the end of the edge.
Definition: NBEdge.cpp:3990
void setBidi(bool isBidi)
mark this edge as a bidi edge
Definition: NBEdge.h:1421
void setFriction(int lane, double friction)
set lane specific friction (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4068
static const double UNSPECIFIED_CONTPOS
unspecified internal junction position
Definition: NBEdge.h:369
static const double UNSPECIFIED_VISIBILITY_DISTANCE
unspecified foe visibility for connections
Definition: NBEdge.h:372
bool hasLaneSpecificWidth() const
whether lanes differ in width
Definition: NBEdge.cpp:2397
static const double UNSPECIFIED_SPEED
unspecified lane speed
Definition: NBEdge.h:363
@ VALIDATED
The connection was computed and validated.
bool hasLaneSpecificEndOffset() const
whether lanes differ in offset
Definition: NBEdge.cpp:2419
void setLaneShape(int lane, const PositionVector &shape)
sets a custom lane shape
Definition: NBEdge.cpp:4092
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:357
void declareConnectionsAsLoaded(EdgeBuildingStep step=EdgeBuildingStep::LANES2LANES_USER)
declares connections as fully loaded. This is needed to avoid recomputing connections if an edge has ...
Definition: NBEdge.h:1440
double getEndOffset() const
Returns the offset to the destination node.
Definition: NBEdge.h:695
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4006
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:360
void setLoadedLength(double val)
set loaded length
Definition: NBEdge.cpp:4152
A loaded (complete) traffic light logic.
void addPhase(const SUMOTime duration, const std::string &state, const SUMOTime minDur, const SUMOTime maxDur, const SUMOTime earliestEnd, const SUMOTime latestEnd, const SUMOTime vehExt, const SUMOTime yellow, const SUMOTime red, const std::vector< int > &next, const std::string &name)
Adds a phase to the logic the new phase is inserted at the end of the list of already added phases.
void addConnection(NBEdge *from, NBEdge *to, int fromLane, int toLane, int linkIndex, int linkIndex2, bool reconstruct=true)
Adds a connection and immediately informs the edges.
Instance responsible for building networks.
Definition: NBNetBuilder.h:107
static bool transformCoordinates(PositionVector &from, bool includeInBoundary=true, GeoConvHelper *from_srs=nullptr)
static int addGeometrySegments(PositionVector &from, const PositionVector &cartesian, const double maxLength)
insertion geometry points to ensure maximum segment length between points
NBEdgeCont & getEdgeCont()
Definition: NBNetBuilder.h:139
NBDistrictCont & getDistrictCont()
Returns a reference the districts container.
Definition: NBNetBuilder.h:159
static bool transformCoordinate(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=nullptr)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:91
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:120
Represents a single node (junction) during network building.
Definition: NBNode.h:66
void addWalkingAreaShape(EdgeVector edges, const PositionVector &shape, double width)
add custom shape for walkingArea
Definition: NBNode.cpp:3458
RightOfWay getRightOfWay() const
Returns hint on how to compute right of way.
Definition: NBNode.h:290
FringeType getFringeType() const
Returns fringe type.
Definition: NBNode.h:295
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:275
void setRightOfWay(RightOfWay rightOfWay)
set method for computing right-of-way
Definition: NBNode.h:545
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition: NBNode.cpp:2453
static bool isTrafficLight(SumoXMLNodeType type)
return whether the given type is a traffic light
Definition: NBNode.cpp:3689
NBNode::Crossing * addCrossing(EdgeVector edges, double width, bool priority, int tlIndex=-1, int tlIndex2=-1, const PositionVector &customShape=PositionVector::EMPTY, bool fromSumoNet=false)
add a pedestrian crossing to this node
Definition: NBNode.cpp:3524
void addSortedLinkFoes(const NBConnection &mayDrive, const NBConnection &mustStop)
add shorted link FOES
Definition: NBNode.cpp:1776
void setRadius(double radius)
set the turning radius
Definition: NBNode.h:535
void setName(const std::string &name)
set intersection name
Definition: NBNode.h:555
const Position & getPosition() const
Definition: NBNode.h:250
void setFringeType(FringeType fringeType)
set method for computing right-of-way
Definition: NBNode.h:550
const std::string & getProgramID() const
Returns the ProgramID.
static const SUMOTime UNSPECIFIED_DURATION
const std::map< std::string, NBTrafficLightDefinition * > & getPrograms(const std::string &id) const
Returns all programs for the given tl-id.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
A connection description.
PositionVector customShape
custom shape connection
std::string tlID
The id of the traffic light that controls this connection.
double speed
custom speed for connection
std::string edgeType
optional edge type
std::string toEdgeID
The id of the target edge.
double customLength
custom length for connection
double contPos
custom position for internal junction on this connection
int toLaneIdx
The index of the target lane.
double friction
custom friction for connection
int tlLinkIndex
The index of this connection within the controlling traffic light.
bool indirectLeft
Whether this connection is an indirect left turn.
double visibility
custom foe visibility for connection
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
SVCPermissions changeLeft
custom lane changing permissions for connection
SVCPermissions changeRight
custom lane changing permissions for connection
bool uncontrolled
if set to true, This connection will not be TLS-controlled despite its node being controlled.
SVCPermissions permissions
custom permissions for connection
Describes the values found in an edge's definition and this edge's lanes.
std::string bidi
the bidi edge
LaneSpreadFunction lsf
The lane spread function.
std::vector< LaneAttrs * > lanes
The friction on this edge.
StopOffset edgeStopOffset
This edge's vehicle specific stop offsets (used for lanes, that do not have a specified stopOffset)
PositionVector shape
This edges's shape.
int priority
This edge's priority.
std::string toNode
The node this edge ends at.
std::string type
This edge's type.
double maxSpeed
The maximum velocity allowed on this edge (!!!)
NBEdge * builtEdge
The built edge.
SumoXMLEdgeFunc func
This edge's function.
std::string streetName
This edge's street name.
std::string fromNode
The node this edge starts at.
double length
The length of the edge if set explicitly.
std::string id
This edge's id.
double distance
The position at the start of this edge (kilometrage/mileage)
Describes the values found in a lane's definition.
double maxSpeed
The maximum velocity allowed on this lane.
double friction
The friction on this lane.
std::string changeRight
This lane's vehicle classes allowed to change right.
double endOffset
This lane's offset from the intersection.
bool accelRamp
Whether this lane is an acceleration lane.
std::string oppositeID
This lane's opposite lane.
std::string type
the type of this lane
std::vector< Connection > connections
This lane's connections.
bool customShape
Whether this lane has a custom shape.
StopOffset laneStopOffset
This lane's vehicle specific stop offsets.
PositionVector shape
This lane's shape (may be custom)
std::string changeLeft
This lane's vehicle classes allowed to change left.
double width
The width of this lane.
std::string disallow
This lane's disallowed vehicle classes.
std::string allow
This lane's allowed vehicle classes.
Importer for networks stored in SUMO format.
GeoConvHelper * myLocation
The coordinate transformation which was used to build the loaded network.
static NBLoadedSUMOTLDef * initTrafficLightLogic(const SUMOSAXAttributes &attrs, NBLoadedSUMOTLDef *currentTL)
begins the reading of a traffic lights logic
void parseProhibitionConnection(const std::string &attr, std::string &from, std::string &to, bool &ok)
parses connection string of a prohibition (very old school)
~NIImporter_SUMO()
Destructor.
NIXMLTypesHandler myTypesHandler
The handler for parsing edge types and restrictions.
int myCornerDetail
the level of corner detail in the loaded network
bool myCheckLaneFoesAll
whether foe-relationships where checked at lane-level
double myLimitTurnSpeed
whether turning speed was limited in the network
std::set< std::string > myRailSignals
list of node id with rail signals (no NBTrafficLightDefinition exists)
bool myGeomAvoidOverlap
overlap option for loaded network
std::map< std::string, std::vector< Crossing > > myPedestrianCrossings
The pedestrian crossings found in the network.
bool myCheckLaneFoesRoundabout
JunctionAttrs myCurrentJunction
The currently parsed junction definition to help in reconstructing crossings.
void addJunction(const SUMOSAXAttributes &attrs)
Parses a junction and saves it in the node control.
bool myAmLefthand
whether the loaded network was built for lefthand traffic
bool myRectLaneCut
whether all lanes of an edge should have the same stop line
std::vector< Parameterised * > myLastParameterised
element to receive parameters
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
double myInternalJunctionsVehicleWidth
custom settings for internal junction computation
std::string myDefaultSpreadType
default spreadType defined in the network
bool myJunctionsHigherSpeed
higherSpeed option for loaded network
NBLoadedSUMOTLDef * myCurrentTL
The currently parsed traffic light.
static void loadNetwork(OptionsCont &oc, NBNetBuilder &nb)
Loads content of the optionally given SUMO file.
std::vector< std::vector< std::string > > myRoundabouts
loaded roundabout edges
bool myChangeLefthand
whether the the written network should have a different "handedness" (LHT/RHT) than the loaded networ...
void addConnection(const SUMOSAXAttributes &attrs)
Parses a connection and saves it into the lane's definition stored in "myCurrentLane".
void addEdge(const SUMOSAXAttributes &attrs)
Parses an edge and stores the values in "myCurrentEdge".
LaneAttrs * myCurrentLane
The currently parsed lanes's definition (to add the shape to)
void addLane(const SUMOSAXAttributes &attrs)
Parses a lane and stores the values in "myCurrentLane".
NBNodeCont & myNodeCont
The node container to fill.
EdgeAttrs * myCurrentEdge
The currently parsed edge's definition (to add loaded lanes to)
NBNetBuilder & myNetBuilder
The network builder to fill.
void addRoundabout(const SUMOSAXAttributes &attrs)
Parses a roundabout and stores it in myEdgeCont.
std::vector< Prohibition > myProhibitions
Loaded prohibitions.
double myNetworkVersion
the loaded network version
void _loadNetwork(OptionsCont &oc)
load the network
void myEndElement(int element)
Called when a closing tag occurs.
bool myTlsIgnoreInternalJunctionJam
whether some right-of-way checks at traffic light junctions should be disabled
void addStopOffsets(const SUMOSAXAttributes &attrs, bool &ok)
parses stop offsets for the current lane or edge
static Position readPosition(const SUMOSAXAttributes &attrs, const std::string &id, bool &ok)
read position from the given attributes, attribute errors to id
static void addPhase(const SUMOSAXAttributes &attrs, NBLoadedSUMOTLDef *currentTL)
adds a phase to the traffic lights logic currently build
int myLinkDetail
the level of geometry detail for internal lanes in the loaded network
std::map< std::string, WalkingAreaParsedCustomShape > myWACustomShapes
Map from walkingArea edge IDs to custom shapes.
bool myWalkingAreas
whether walkingareas must be built
NBTrafficLightLogicCont & myTLLCont
The node container to fill.
NIImporter_SUMO(NBNetBuilder &nb)
Constructor.
void addProhibition(const SUMOSAXAttributes &attrs)
Parses a prohibition and saves it.
void addRequest(const SUMOSAXAttributes &attrs)
Parses a reques and saves selected attributes in myCurrentJunction.
std::set< std::string > myDiscardableParams
list of parameter keys to discard
static GeoConvHelper * loadLocation(const SUMOSAXAttributes &attrs)
Parses network location description and registers it with GeoConveHelper::setLoaded.
std::map< std::string, EdgeAttrs * > myEdges
Loaded edge definitions.
bool myHaveSeenInternalEdge
whether the loaded network contains internal lanes
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag; Parses edge type information.
const std::string & getID() const
Returns the id.
Definition: Named.h:74
A storage for options typed value containers)
Definition: OptionsCont.h:89
bool isWriteable(const std::string &name)
Returns the information whether the named option may be set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
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 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)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:59
bool isUsableFileList(const std::string &name) const
Checks whether the named option is usable as a file list (with at least a single file)
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
void updateParameters(const Parameterised::Map &mapArg)
Adds or updates all given parameters from the map.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
A list of positions.
static const PositionVector EMPTY
empty Vector
Encapsulated SAX-Attributes.
virtual std::string getString(int id, bool *isPresent=nullptr) const =0
Returns the string-value of the named (by its enum-value) attribute.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue=T(), bool report=true) const
Tries to read given attribute assuming it is an int.
SUMOTime getOptSUMOTimeReporting(int attr, const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
double getFloat(int id) const
Returns the double-value of the named (by its enum-value) attribute.
SAX-handler base for SUMO-files.
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
lane spread functions
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
static StringBijection< LinkState > LinkStates
link states
static std::string getJunctionIDFromInternalEdge(const std::string internalEdge)
return the junction id when given an edge of type internal, crossing or WalkingArea
stop offset
bool isDefined() const
check if stopOffset was defined
T get(const std::string &str) const
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false)
Runs the given handler on the given file; returns if everything's ok.
Definition: XMLSubSys.cpp:137
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:21884
std::string type
the type of this lane
Definition: NBEdge.h:192
std::string oppositeID
An opposite lane ID, if given.
Definition: NBEdge.h:179
Describes a pedestrian crossing.
std::vector< std::string > crossingEdges
std::vector< std::string > response
std::vector< std::string > intLanes
Describes the values found in a prohibition.
Describes custom shape for a walking area during parsing.