Eclipse SUMO - Simulation of Urban MObility
NIXMLEdgesHandler.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/****************************************************************************/
23// Importer for network edges stored in XML
24/****************************************************************************/
25#include <config.h>
26
27#include <string>
28#include <iostream>
29#include <map>
30#include <cmath>
31#include <xercesc/sax/HandlerBase.hpp>
32#include <xercesc/sax/AttributeList.hpp>
33#include <xercesc/sax/SAXParseException.hpp>
34#include <xercesc/sax/SAXException.hpp>
36#include <netbuild/NBNodeCont.h>
37#include <netbuild/NBTypeCont.h>
47#include "NIXMLNodesHandler.h"
48#include "NIXMLEdgesHandler.h"
49
50
51// ===========================================================================
52// method definitions
53// ===========================================================================
55 NBEdgeCont& ec,
56 NBTypeCont& tc,
59 OptionsCont& options) :
60 SUMOSAXHandler("xml-edges - file"),
61 myOptions(options),
62 myNodeCont(nc),
63 myEdgeCont(ec),
64 myTypeCont(tc),
65 myDistrictCont(dc),
66 myTLLogicCont(tlc),
67 myCurrentEdge(nullptr),
68 myCurrentLaneIndex(-1),
69 myHaveReportedAboutOverwriting(false),
70 myHaveReportedAboutTypeOverride(false),
71 myHaveWarnedAboutDeprecatedLaneId(false),
72 myKeepEdgeShape(!options.getBool("plain.extend-edge-shape")) {
73}
74
75
77
78
79void
81 const SUMOSAXAttributes& attrs) {
82 switch (element) {
83 case SUMO_TAG_EDGE:
84 addEdge(attrs);
85 break;
86 case SUMO_TAG_LANE:
87 addLane(attrs);
88 break;
89 case SUMO_TAG_NEIGH:
91 break;
92 case SUMO_TAG_SPLIT:
93 addSplit(attrs);
94 break;
95 case SUMO_TAG_DEL:
96 deleteEdge(attrs);
97 break;
99 addRoundabout(attrs);
100 break;
101 case SUMO_TAG_PARAM:
102 if (myLastParameterised.size() != 0 && myCurrentEdge != nullptr) {
103 bool ok = true;
104 const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
105 // circumventing empty string test
106 const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
107 myLastParameterised.back()->setParameter(key, val);
108 }
109 break;
110 case SUMO_TAG_STOPOFFSET: {
111 bool ok = true;
112 const StopOffset stopOffset(attrs, ok);
113 if (!ok) {
114 std::stringstream ss;
115 ss << "(Error encountered at lane " << myCurrentLaneIndex << " of edge '" << myCurrentID << "' while parsing stopOffsets.)";
116 WRITE_ERROR(ss.str());
117 } else {
119 std::stringstream ss;
120 ss << "Duplicate definition of stopOffset for ";
121 if (myCurrentLaneIndex != -1) {
122 ss << "lane " << myCurrentLaneIndex << " on ";
123 }
124 ss << "edge " << myCurrentEdge->getID() << ". Ignoring duplicate specification.";
125 WRITE_WARNING(ss.str());
126 } else if ((stopOffset.getOffset() > myCurrentEdge->getLength()) || (stopOffset.getOffset() < 0)) {
127 std::stringstream ss;
128 ss << "Ignoring invalid stopOffset for ";
129 if (myCurrentLaneIndex != -1) {
130 ss << "lane " << myCurrentLaneIndex << " on ";
131 }
132 ss << "edge " << myCurrentEdge->getID();
133 if (stopOffset.getOffset() > myCurrentEdge->getLength()) {
134 ss << " (offset larger than the edge length).";
135 } else {
136 ss << " (negative offset).";
137 }
138 WRITE_WARNING(ss.str());
139 } else {
141 }
142 }
143 }
144 break;
145 default:
146 break;
147 }
148}
149
150
151void
153 myIsUpdate = false;
154 bool ok = true;
155 // initialise the edge
156 myCurrentEdge = nullptr;
157 mySplits.clear();
158 // get the id, report an error if not given or empty...
159 myCurrentID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
160 if (!ok) {
161 return;
162 }
164 // check deprecated (unused) attributes
165 // use default values, first
166 myCurrentType = myOptions.getString("default.type");
170 if (myCurrentEdge != nullptr) {
171 // update existing edge. only update lane-specific settings when explicitly requested
172 myIsUpdate = true;
179 } else {
180 // this is a completely new edge. get the type specific defaults
186 }
190 myReinitKeepEdgeShape = false;
193 // check whether a type's values shall be used
194 if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
195 myCurrentType = attrs.get<std::string>(SUMO_ATTR_TYPE, myCurrentID.c_str(), ok);
196 if (!ok) {
197 return;
198 }
199 if (!myTypeCont.knows(myCurrentType) && !myOptions.getBool("ignore-errors.edge-type")) {
200 WRITE_ERRORF("Type '%' used by edge '%' was not defined (ignore with option --ignore-errors.edge-type).", myCurrentType, myCurrentID);
201 return;
202 }
211 }
212 // use values from the edge to overwrite if existing, then
213 if (myIsUpdate) {
215 WRITE_MESSAGE("Duplicate edge id occurred ('" + myCurrentID + "'); assuming overwriting is wished.");
217 }
220 WRITE_MESSAGE("Edge '" + myCurrentID + "' changed it's type; assuming type override is wished.");
222 }
223 }
224 if (attrs.getOpt<bool>(SUMO_ATTR_REMOVE, myCurrentID.c_str(), ok, false)) {
226 myCurrentEdge = nullptr;
227 return;
228 }
234 }
238 }
240 }
241 // speed, priority and the number of lanes have now default values;
242 // try to read the real values from the file
243 if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
244 myCurrentSpeed = attrs.get<double>(SUMO_ATTR_SPEED, myCurrentID.c_str(), ok);
245 }
246 if (myOptions.getBool("speed-in-kmh") && myCurrentSpeed != NBEdge::UNSPECIFIED_SPEED) {
247 myCurrentSpeed = myCurrentSpeed / (double) 3.6;
248 }
249 // try to read the friction value from file
250 if (attrs.hasAttribute(SUMO_ATTR_FRICTION)) {
251 myCurrentFriction = attrs.get<double>(SUMO_ATTR_FRICTION, myCurrentID.c_str(), ok);
252 }
253 // try to get the number of lanes
254 if (attrs.hasAttribute(SUMO_ATTR_NUMLANES)) {
255 myCurrentLaneNo = attrs.get<int>(SUMO_ATTR_NUMLANES, myCurrentID.c_str(), ok);
256 }
257 // try to get the priority
258 if (attrs.hasAttribute(SUMO_ATTR_PRIORITY)) {
259 myCurrentPriority = attrs.get<int>(SUMO_ATTR_PRIORITY, myCurrentID.c_str(), ok);
260 }
261 // try to get the width
262 if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
263 myCurrentWidth = attrs.get<double>(SUMO_ATTR_WIDTH, myCurrentID.c_str(), ok);
264 }
265 // try to get the offset of the stop line from the intersection
267 myCurrentEndOffset = attrs.get<double>(SUMO_ATTR_ENDOFFSET, myCurrentID.c_str(), ok);
268 }
269 // try to get the street name
270 if (attrs.hasAttribute(SUMO_ATTR_NAME)) {
271 myCurrentStreetName = attrs.get<std::string>(SUMO_ATTR_NAME, myCurrentID.c_str(), ok);
272 if (myCurrentStreetName != "" && myOptions.isDefault("output.street-names")) {
273 myOptions.set("output.street-names", "true");
274 }
275 }
276
277 // try to get the allowed/disallowed classes
279 std::string allowS = attrs.hasAttribute(SUMO_ATTR_ALLOW) ? attrs.getStringSecure(SUMO_ATTR_ALLOW, "") : "";
280 std::string disallowS = attrs.hasAttribute(SUMO_ATTR_DISALLOW) ? attrs.getStringSecure(SUMO_ATTR_DISALLOW, "") : "";
281 // XXX matter of interpretation: should updated permissions replace or extend previously set permissions?
282 myPermissions = parseVehicleClasses(allowS, disallowS);
283 }
284 // try to set the nodes
285 if (!setNodes(attrs)) {
286 // return if this failed
287 myCurrentEdge = nullptr;
288 return;
289 }
290 // try to get the shape
291 myShape = tryGetShape(attrs);
292 // try to get the spread type
294 // try to get the length
295 myLength = attrs.getOpt<double>(SUMO_ATTR_LENGTH, myCurrentID.c_str(), ok, myLength);
296 // try to get the sidewalkWidth
298 // try to get the bikeLaneWidth
300 // insert the parsed edge into the edges map
301 if (!ok) {
302 myCurrentEdge = nullptr;
303 return;
304 }
305 if (myFromNode == myToNode) {
306 // this might as well be an error. We make this a warning mostly for
307 // backward compatibility
308 WRITE_WARNINGF(TL("Ignoring self-looped edge '%' at junction '%'"), myCurrentID, myFromNode->getID());
309 myCurrentEdge = nullptr;
310 return;
311 }
312 // check whether a previously defined edge shall be overwritten
313 const bool applyLaneType = myCurrentEdge == nullptr;
314 if (myCurrentEdge != nullptr) {
320 } else {
321 // the edge must be allocated in dependence to whether a shape is given
322 if (myShape.size() == 0) {
326 } else {
331 }
332 }
336 }
337 // apply laneType if given
338 if (applyLaneType && myCurrentType != "" && myTypeCont.knows(myCurrentType)) {
340 if (eType->needsLaneType()) {
341 int lane = 0;
342 for (const NBTypeCont::LaneTypeDefinition& laneType : eType->laneTypeDefinitions) {
343 if (lane >= myCurrentLaneNo) {
344 break;
345 }
346 if (laneType.attrs.count(SUMO_ATTR_SPEED) > 0) {
347 myCurrentEdge->setSpeed(lane, laneType.speed);
348 }
349 if (laneType.attrs.count(SUMO_ATTR_FRICTION) > 0) {
350 myCurrentEdge->setFriction(lane, laneType.friction);
351 }
352 if (laneType.attrs.count(SUMO_ATTR_DISALLOW) > 0 || laneType.attrs.count(SUMO_ATTR_ALLOW) > 0) {
354 }
355 if (laneType.attrs.count(SUMO_ATTR_WIDTH) > 0) {
356 myCurrentEdge->setLaneWidth(lane, laneType.width);
357 }
358 lane++;
359 }
360 }
361 }
362 // try to get the kilometrage/mileage
364 // preserve bidi edge (only as boo, the actual edge will be recomputed)
365 const std::string bidi = attrs.getOpt<std::string>(SUMO_ATTR_BIDI, myCurrentID.c_str(), ok, "");
366 myCurrentEdge->setBidi(myCurrentEdge->getBidiEdge() != nullptr || bidi != "");
367
369}
370
371
372void
374 if (myCurrentEdge == nullptr) {
375 if (!OptionsCont::getOptions().isInStringVector("remove-edges.explicit", myCurrentID)) {
376 WRITE_ERRORF("Additional lane information could not be set - the edge with id '%s' is not known.", myCurrentID);
377 }
378 return;
379 }
380 bool ok = true;
381 int lane;
382 if (attrs.hasAttribute(SUMO_ATTR_ID)) {
383 lane = attrs.get<int>(SUMO_ATTR_ID, myCurrentID.c_str(), ok);
386 WRITE_WARNING("'" + toString(SUMO_ATTR_ID) + "' is deprecated, please use '" + toString(SUMO_ATTR_INDEX) + "' instead.");
387 }
388 } else {
389 lane = attrs.get<int>(SUMO_ATTR_INDEX, myCurrentID.c_str(), ok);
390 }
391 if (!ok) {
392 return;
393 }
394 // check whether this lane exists
395 if (lane >= myCurrentEdge->getNumLanes()) {
396 WRITE_ERROR("Lane index is larger than number of lanes (edge '" + myCurrentID + "').");
397 return;
398 }
399 myCurrentLaneIndex = lane;
400 // set information about allowed / disallowed vehicle classes (if specified)
402 const std::string allowed = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, nullptr, ok, "");
403 const std::string disallowed = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, nullptr, ok, "");
404 myCurrentEdge->setPermissions(parseVehicleClasses(allowed, disallowed), lane);
405 }
406 if (attrs.hasAttribute(SUMO_ATTR_PREFER)) {
407 const std::string preferred = attrs.get<std::string>(SUMO_ATTR_PREFER, nullptr, ok);
409 }
411 const std::string changeLeft = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_LEFT, nullptr, ok, "");
412 const std::string changeRight = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_RIGHT, nullptr, ok, "");
413 myCurrentEdge->setPermittedChanging(lane, parseVehicleClasses(changeLeft, ""), parseVehicleClasses(changeRight, ""));
414 }
415 // try to get the width
416 if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
417 myCurrentEdge->setLaneWidth(lane, attrs.get<double>(SUMO_ATTR_WIDTH, myCurrentID.c_str(), ok));
418 }
419 // try to get the end-offset (lane shortened due to pedestrian crossing etc..)
421 myCurrentEdge->setEndOffset(lane, attrs.get<double>(SUMO_ATTR_ENDOFFSET, myCurrentID.c_str(), ok));
422 }
423 // try to get lane specific speed (should not occur for german networks)
424 if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
425 myCurrentEdge->setSpeed(lane, attrs.get<double>(SUMO_ATTR_SPEED, myCurrentID.c_str(), ok));
426 }
427 // try to get lane specific friction
428 if (attrs.hasAttribute(SUMO_ATTR_FRICTION)) {
429 myCurrentEdge->setFriction(lane, attrs.get<double>(SUMO_ATTR_FRICTION, myCurrentID.c_str(), ok));
430 }
431 // check whether this is an acceleration lane
433 myCurrentEdge->setAcceleration(lane, attrs.get<bool>(SUMO_ATTR_ACCELERATION, myCurrentID.c_str(), ok));
434 }
435 // check whether this lane has a custom shape
436 if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
437 PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, myCurrentID.c_str(), ok);
439 const std::string laneID = myCurrentID + "_" + toString(lane);
440 WRITE_ERROR("Unable to project coordinates for lane '" + laneID + "'.");
441 }
442 if (shape.size() == 1) {
443 // lane shape of length 1 is not permitted
445 shape.push_back(myCurrentEdge->getToNode()->getPosition());
446 }
447 shape.removeDoublePoints();
448 if (shape.size() < 2) {
449 // ignore lane shape for very short lanes
450 shape.clear();
451 }
452 myCurrentEdge->setLaneShape(lane, shape);
453 }
454 // set custom lane type
455 if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
456 myCurrentEdge->setLaneType(lane, attrs.get<std::string>(SUMO_ATTR_TYPE, myCurrentID.c_str(), ok));
457 }
459}
460
461
463 if (myCurrentEdge == nullptr) {
464 if (!OptionsCont::getOptions().isInStringVector("remove-edges.explicit", myCurrentID)) {
465 WRITE_WARNING(TL("Ignoring 'split' because it cannot be assigned to an edge"));
466 }
467 return;
468 }
469 bool ok = true;
471 e.pos = attrs.get<double>(SUMO_ATTR_POSITION, nullptr, ok);
472 if (ok) {
473 if (fabs(e.pos) > myCurrentEdge->getGeometry().length()) {
474 WRITE_ERROR("Edge '" + myCurrentID + "' has a split at invalid position " + toString(e.pos) + ".");
475 return;
476 }
477 std::vector<NBEdgeCont::Split>::iterator i = find_if(mySplits.begin(), mySplits.end(), split_by_pos_finder(e.pos));
478 if (i != mySplits.end()) {
479 WRITE_ERROR("Edge '" + myCurrentID + "' has already a split at position " + toString(e.pos) + ".");
480 return;
481 }
482 // XXX rounding to int may duplicate the id of another split
483 e.nameID = myCurrentID + "." + toString((int)e.pos);
484 if (e.pos < 0) {
486 }
487 for (const std::string& id : attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_LANES, myCurrentID.c_str(), ok)) {
488 try {
489 int lane = StringUtils::toInt(id);
490 e.lanes.push_back(lane);
491 } catch (NumberFormatException&) {
492 WRITE_ERROR("Error on parsing a split (edge '" + myCurrentID + "').");
493 } catch (EmptyData&) {
494 WRITE_ERROR("Error on parsing a split (edge '" + myCurrentID + "').");
495 }
496 }
497 if (e.lanes.empty()) {
498 for (int l = 0; l < myCurrentEdge->getNumLanes(); ++l) {
499 e.lanes.push_back(l);
500 }
501 }
502 e.speed = attrs.getOpt(SUMO_ATTR_SPEED, nullptr, ok, myCurrentEdge->getSpeed());
503 if (attrs.hasAttribute(SUMO_ATTR_SPEED) && myOptions.getBool("speed-in-kmh")) {
504 e.speed /= 3.6;
505 }
506 e.idBefore = attrs.getOpt(SUMO_ATTR_ID_BEFORE, nullptr, ok, std::string(""));
507 e.idAfter = attrs.getOpt(SUMO_ATTR_ID_AFTER, nullptr, ok, std::string(""));
508 if (!ok) {
509 return;
510 }
511 const std::string nodeID = attrs.getOpt(SUMO_ATTR_ID, nullptr, ok, e.nameID);
512 if (nodeID == myCurrentEdge->getFromNode()->getID() || nodeID == myCurrentEdge->getToNode()->getID()) {
513 WRITE_ERROR("Invalid split node id for edge '" + myCurrentEdge->getID() + "' (from- and to-node are forbidden)");
514 return;
515 }
516 e.node = myNodeCont.retrieve(nodeID);
517 e.offsetFactor = OptionsCont::getOptions().getBool("lefthand") ? -1 : 1;
518 if (e.node == nullptr) {
521 }
524 mySplits.push_back(e);
525 }
526}
527
528
529bool
531 // the names and the coordinates of the beginning and the end node
532 // may be found, try
533 bool ok = true;
534 if (myIsUpdate) {
537 }
538 if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
539 const std::string begNodeID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
540 if (begNodeID != "") {
541 myFromNode = myNodeCont.retrieve(begNodeID);
542 if (myFromNode == nullptr) {
543 WRITE_ERROR("Edge's '" + myCurrentID + "' from-node '" + begNodeID + "' is not known.");
544 }
545 }
546 } else if (!myIsUpdate) {
547 WRITE_ERROR("The from-node is not given for edge '" + myCurrentID + "'.");
548 ok = false;
549 }
550 if (attrs.hasAttribute(SUMO_ATTR_TO)) {
551 const std::string endNodeID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
552 if (endNodeID != "") {
553 myToNode = myNodeCont.retrieve(endNodeID);
554 if (myToNode == nullptr) {
555 WRITE_ERROR("Edge's '" + myCurrentID + "' to-node '" + endNodeID + "' is not known.");
556 }
557 }
558 } else if (!myIsUpdate) {
559 WRITE_ERROR("The to-node is not given for edge '" + myCurrentID + "'.");
560 ok = false;
561 }
562 return ok && myFromNode != nullptr && myToNode != nullptr;
563}
564
565
568 if (!attrs.hasAttribute(SUMO_ATTR_SHAPE) && myShape.size() > 0) {
569 return myShape;
570 }
571 // try to build shape
572 bool ok = true;
573 if (!attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
574 const double maxSegmentLength = OptionsCont::getOptions().getFloat("geometry.max-segment-length");
575 if (maxSegmentLength > 0) {
576 PositionVector shape;
577 shape.push_back(myFromNode->getPosition());
578 shape.push_back(myToNode->getPosition());
579 // shape is already cartesian but we must use a copy because the original will be modified
580 NBNetBuilder::addGeometrySegments(shape, PositionVector(shape), maxSegmentLength);
581 return shape;
582 } else {
583 myReinitKeepEdgeShape = false;
584 return PositionVector();
585 }
586 }
587 PositionVector shape = attrs.getOpt<PositionVector>(SUMO_ATTR_SHAPE, nullptr, ok, PositionVector());
589 WRITE_ERROR("Unable to project coordinates for edge '" + myCurrentID + "'.");
590 }
592 return shape;
593}
594
595
598 bool ok = true;
600 std::string lsfS = toString(result);
601 lsfS = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, myCurrentID.c_str(), ok, lsfS);
602 if (SUMOXMLDefinitions::LaneSpreadFunctions.hasString(lsfS)) {
604 } else {
605 WRITE_WARNING("Ignoring unknown spreadType '" + lsfS + "' for edge '" + myCurrentID + "'.");
606 }
607 return result;
608}
609
610
611void
613 bool ok = true;
614 myCurrentID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
615 if (!ok) {
616 return;
617 }
619 if (edge == nullptr) {
620 WRITE_WARNING("Ignoring tag '" + toString(SUMO_TAG_DEL) + "' for unknown edge '" +
621 myCurrentID + "'");
622 return;
623 }
624 const int lane = attrs.getOpt<int>(SUMO_ATTR_INDEX, myCurrentID.c_str(), ok, -1);
625 if (lane < 0) {
626 myEdgeCont.extract(myDistrictCont, edge, true);
627 } else {
628 edge->deleteLane(lane, false, true);
629 }
630}
631
632
633void
635 if (myCurrentEdge == nullptr) {
636 return;
637 }
638 if (element == SUMO_TAG_EDGE) {
639 myLastParameterised.pop_back();
640 // add bike lane, wait until lanes are loaded to avoid building if it already exists
643 }
644 // add sidewalk, wait until lanes are loaded to avoid building if it already exists
647 }
648 // apply default stopOffsets of edge to all lanes without specified stopOffset.
649 const StopOffset stopOffsets = myCurrentEdge->getEdgeStopOffset();
650 if (stopOffsets.isDefined()) {
651 for (int i = 0; i < (int)myCurrentEdge->getLanes().size(); i++) {
652 myCurrentEdge->setEdgeStopOffset(i, stopOffsets, false);
653 }
654 }
655 if (!myIsUpdate) {
656 try {
658 WRITE_ERRORF(TL("Duplicate edge '%' occurred."), myCurrentID);
659 delete myCurrentEdge;
660 myCurrentEdge = nullptr;
661 return;
662 }
663 } catch (InvalidArgument& e) {
664 WRITE_ERROR(e.what());
665 throw;
666 } catch (...) {
667 WRITE_ERRORF(TL("An important information is missing in edge '%'."), myCurrentID);
668 }
669 }
671 myCurrentEdge = nullptr;
672 } else if (element == SUMO_TAG_LANE && myCurrentLaneIndex != -1) {
673 myLastParameterised.pop_back();
675 }
676}
677
678
679void
681 bool ok = true;
682 const std::vector<std::string>& edgeIDs = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, nullptr, ok);
683 if (ok) {
684 EdgeSet roundabout;
685 for (const std::string& eID : edgeIDs) {
686 NBEdge* edge = myEdgeCont.retrieve(eID);
687 if (edge == nullptr) {
688 if (!myEdgeCont.wasIgnored(eID)) {
689 WRITE_ERRORF(TL("Unknown edge '%' in roundabout."), eID);
690 }
691 } else {
692 roundabout.insert(edge);
693 }
694 }
695 myEdgeCont.addRoundabout(roundabout);
696 }
697}
698
699
700/****************************************************************************/
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:266
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:275
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:267
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:274
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:265
#define TL(string)
Definition: MsgHandler.h:282
std::set< NBEdge * > EdgeSet
container for unique edges
Definition: NBCont.h:50
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...
@ SUMO_TAG_STOPOFFSET
Information on vClass specific stop offsets at lane end.
@ SUMO_TAG_ROUNDABOUT
roundabout defined in 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_SPLIT
split something
@ SUMO_TAG_DEL
delete certain element (note: DELETE is a macro)
@ 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...
@ SUMO_ATTR_PREFER
@ SUMO_ATTR_DISALLOW
@ SUMO_ATTR_ALLOW
@ SUMO_ATTR_LANE
@ SUMO_ATTR_REMOVE
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_VALUE
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_BIDI
@ SUMO_ATTR_PRIORITY
@ SUMO_ATTR_NUMLANES
@ SUMO_ATTR_LANES
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_CHANGE_LEFT
@ SUMO_ATTR_INDEX
@ SUMO_ATTR_NAME
@ SUMO_ATTR_SPREADTYPE
The information about how to spread the lanes from the given position.
@ SUMO_ATTR_ENDOFFSET
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_ACCELERATION
@ SUMO_ATTR_BIKELANEWIDTH
@ SUMO_ATTR_CHANGE_RIGHT
@ SUMO_ATTR_DISTANCE
@ SUMO_ATTR_ID_AFTER
@ SUMO_ATTR_SIDEWALKWIDTH
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_ID
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_KEY
@ SUMO_ATTR_POSITION
@ SUMO_ATTR_FRICTION
@ SUMO_ATTR_ID_BEFORE
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A container for districts.
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:59
void addRoundabout(const EdgeSet &roundabout)
add user specified roundabout
void extract(NBDistrictCont &dc, NBEdge *edge, bool remember=false)
Removes the given edge from the container like erase but does not delete it.
Definition: NBEdgeCont.cpp:411
void processSplits(NBEdge *e, std::vector< Split > splits, NBNodeCont &nc, NBDistrictCont &dc, NBTrafficLightLogicCont &tlc)
Definition: NBEdgeCont.cpp:443
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 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 reinit(NBNode *from, NBNode *to, const std::string &type, double speed, double friction, int nolanes, int priority, PositionVector geom, double width, double endOffset, const std::string &streetName, LaneSpreadFunction spread, bool tryIgnoreNodePositions=false)
Resets initial values.
Definition: NBEdge.cpp:420
void setPreferredVehicleClass(SVCPermissions permissions, int lane=-1)
set preferred Vehicle Class
Definition: NBEdge.cpp:4114
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
double getLength() const
Returns the computed length of the edge.
Definition: NBEdge.h:599
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
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
Definition: NBEdge.h:608
void addBikeLane(double width)
add a bicycle lane of the given width and shift existing connctions
Definition: NBEdge.cpp:4342
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4052
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:552
static const double UNSPECIFIED_FRICTION
unspecified lane friction
Definition: NBEdge.h:366
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1426
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:787
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge's lanes' lateral offset is computed.
Definition: NBEdge.cpp:974
bool hasLoadedLength() const
Returns whether a length was set explicitly.
Definition: NBEdge.h:618
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
void setLaneType(int lane, const std::string &type)
set lane specific type (negative lane implies set for all lanes)
Definition: NBEdge.cpp:3938
double getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:625
const std::string & getID() const
Definition: NBEdge.h:1526
double getDistance() const
get distance
Definition: NBEdge.h:685
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 addSidewalk(double width)
add a pedestrian sidewalk of the given width and shift existing connctions
Definition: NBEdge.cpp:4330
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:526
void setFriction(int lane, double friction)
set lane specific friction (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4068
void deleteLane(int index, bool recompute, bool shiftIndices)
delete lane
Definition: NBEdge.cpp:3845
static const double UNSPECIFIED_SPEED
unspecified lane speed
Definition: NBEdge.h:363
const std::string & getTypeID() const
get ID of type
Definition: NBEdge.h:1183
const std::string & getStreetName() const
Returns the street name of this edge.
Definition: NBEdge.h:675
void setLaneShape(int lane, const PositionVector &shape)
sets a custom lane shape
Definition: NBEdge.cpp:4092
const NBEdge * getBidiEdge() const
Definition: NBEdge.h:1512
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:545
bool hasDefaultGeometry() const
Returns whether the geometry consists only of the node positions.
Definition: NBEdge.cpp:621
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:533
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:357
const StopOffset & getLaneStopOffset(int lane) const
Returns the stop offset to the specified lane's end.
Definition: NBEdge.cpp:3996
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
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
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:58
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
const Position & getPosition() const
Definition: NBNode.h:250
A container for traffic light definitions and built programs.
A storage for available edgeTypes of edges.
Definition: NBTypeCont.h:52
double getEdgeTypeFriction(const std::string &edgeType) const
Returns the default friction for the given edgeType [-].
Definition: NBTypeCont.cpp:505
double getEdgeTypeSpeed(const std::string &edgeType) const
Returns the maximal velocity for the given edgeType [m/s].
Definition: NBTypeCont.cpp:500
int getEdgeTypePriority(const std::string &edgeType) const
Returns the priority for the given edgeType.
Definition: NBTypeCont.cpp:511
int getEdgeTypeNumLanes(const std::string &edgeType) const
Returns the number of lanes for the given edgeType.
Definition: NBTypeCont.cpp:494
double getEdgeTypeWidth(const std::string &edgeType) const
Returns the lane width for the given edgeType [m].
Definition: NBTypeCont.cpp:561
SVCPermissions getEdgeTypePermissions(const std::string &edgeType) const
Returns allowed vehicle classes for the given edgeType.
Definition: NBTypeCont.cpp:549
bool knows(const std::string &edgeType) const
Returns whether the named edgeType is in the container.
Definition: NBTypeCont.cpp:303
double getEdgeTypeSidewalkWidth(const std::string &edgeType) const
Returns the lane width for a sidewalk to be added [m].
Definition: NBTypeCont.cpp:567
LaneSpreadFunction getEdgeTypeSpreadType(const std::string &edgeType) const
Returns spreadType for the given edgeType.
Definition: NBTypeCont.cpp:555
double getEdgeTypeBikeLaneWidth(const std::string &edgeType) const
Returns the lane width for a bike lane to be added [m].
Definition: NBTypeCont.cpp:573
const EdgeTypeDefinition * getEdgeType(const std::string &name) const
Retrieve the name or the default edgeType.
Definition: NBTypeCont.cpp:579
Finds a split at the given position.
std::string myCurrentID
The current edge's id.
SVCPermissions myPermissions
Information about lane permissions.
bool setNodes(const SUMOSAXAttributes &attrs)
Sets from/to node information of the currently parsed edge.
PositionVector myShape
The shape of the edge.
std::string myCurrentStreetName
The current edge's street name.
LaneSpreadFunction tryGetLaneSpread(const SUMOSAXAttributes &attrs)
Tries to parse the spread type.
double myCurrentSpeed
The current edge's maximum speed.
double myBikeLaneWidth
The width of the bike lane that shall be added to the current edge.
~NIXMLEdgesHandler()
Destructor.
int myCurrentLaneNo
The current edge's number of lanes.
OptionsCont & myOptions
A reference to the program's options.
void addRoundabout(const SUMOSAXAttributes &attrs)
Parses a roundabout and stores it in myEdgeCont.
double myCurrentWidth
The current edge's lane width.
NIXMLEdgesHandler(NBNodeCont &nc, NBEdgeCont &ec, NBTypeCont &tc, NBDistrictCont &dc, NBTrafficLightLogicCont &tlc, OptionsCont &options)
Constructor.
NBTypeCont & myTypeCont
The types container (for retrieval of type defaults)
double myCurrentEndOffset
The current edge's offset till the destination node.
double myLength
The current edge's length.
int myCurrentPriority
The current edge's priority.
NBNodeCont & myNodeCont
The nodes container (for retrieval of referenced nodes)
PositionVector tryGetShape(const SUMOSAXAttributes &attrs)
Tries to parse the shape definition.
bool myIsUpdate
Whether this edge definition is an update of a previously inserted edge.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
LaneSpreadFunction myLanesSpread
Information about how to spread the lanes.
NBDistrictCont & myDistrictCont
The districts container (needed if an edge must be split)
std::vector< Parameterised * > myLastParameterised
element to receive parameters
NBEdgeCont & myEdgeCont
The edges container (for insertion of build edges)
double mySidewalkWidth
The width of the sidewalk that shall be added to the current edge.
bool myHaveWarnedAboutDeprecatedLaneId
void addSplit(const SUMOSAXAttributes &attrs)
Parses a split and stores it in mySplits. Splits are executed Upon reading the end tag of an edge.
std::string myCurrentType
The current edge's type.
NBEdge * myCurrentEdge
The currently processed edge.
NBTrafficLightLogicCont & myTLLogicCont
The traffic lights container to add built tls to (when invalidating tls because of splits)
std::vector< NBEdgeCont::Split > mySplits
The list of this edge's splits.
double myCurrentFriction
The current edge's friction.
int myCurrentLaneIndex
The currently processed lane index.
bool myHaveReportedAboutTypeOverride
Information whether at least one edge's type was changed.
NBNode * myFromNode
The nodes the edge starts and ends at.
void addLane(const SUMOSAXAttributes &attrs)
Parses a lane and modifies myCurrentEdge according to the given attribures.
void myEndElement(int element)
Called when a closing tag occurs.
const bool myKeepEdgeShape
Whether the edge shape shall be kept generally.
bool myHaveReportedAboutOverwriting
Information whether at least one edge's attributes were overwritten.
void deleteEdge(const SUMOSAXAttributes &attrs)
parses delete tag and deletes the specified edge or lane
bool myReinitKeepEdgeShape
Whether the edge shape shall be kept at reinitilization.
void addEdge(const SUMOSAXAttributes &attrs)
Parses an edge and stores the values in "myCurrentEdge".
static NBNode * processNodeType(const SUMOSAXAttributes &attrs, NBNode *node, const std::string &nodeID, const Position &position, bool updateEdgeGeometries, NBNodeCont &nc, NBEdgeCont &ec, NBTrafficLightLogicCont &tlc)
parses node attributes (not related to positioning)
const std::string & getID() const
Returns the id.
Definition: Named.h:74
A storage for options typed value containers)
Definition: OptionsCont.h:89
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)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:59
A list of positions.
double length() const
Returns the length.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
void push_front(const Position &p)
insert in front a Position
void removeDoublePoints(double minDist=POSITION_EPS, bool assertLength=false, int beginOffset=0, int endOffset=0, bool resample=false)
Removes positions if too near.
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.
virtual std::string getStringSecure(int id, const std::string &def) const =0
Returns the string-value of the named (by its enum-value) attribute.
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.
SAX-handler base for SUMO-files.
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
lane spread functions
stop offset
bool isDefined() const
check if stopOffset was defined
double getOffset() const
get offset
T get(const std::string &str) const
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
std::string oppositeID
An opposite lane ID, if given.
Definition: NBEdge.h:179
A structure which describes changes of lane number or speed along the road.
Definition: NBEdgeCont.h:188
int offsetFactor
direction in which to apply the offset (used by netgenerate for lefthand networks)
Definition: NBEdgeCont.h:208
double speed
The speed after this change.
Definition: NBEdgeCont.h:194
std::string nameID
the default node id
Definition: NBEdgeCont.h:204
std::string idBefore
The id for the edge before the split.
Definition: NBEdgeCont.h:200
double pos
The position of this change.
Definition: NBEdgeCont.h:192
std::vector< int > lanes
The lanes after this change.
Definition: NBEdgeCont.h:190
std::string idAfter
The id for the edge after the split.
Definition: NBEdgeCont.h:202
NBNode * node
The new node that is created for this split.
Definition: NBEdgeCont.h:198
edgeType definition
Definition: NBTypeCont.h:93
bool needsLaneType() const
whether any lane attributes deviate from the edge attributes
Definition: NBTypeCont.cpp:137
std::vector< LaneTypeDefinition > laneTypeDefinitions
vector with LaneTypeDefinitions
Definition: NBTypeCont.h:158
laneType definition
Definition: NBTypeCont.h:59
double speed
The maximal velocity on a lane in m/s.
Definition: NBTypeCont.h:74
double friction
The default friction on a lane.
Definition: NBTypeCont.h:77
SVCPermissions permissions
List of vehicle edgeTypes that are allowed on this lane.
Definition: NBTypeCont.h:80
std::set< SumoXMLAttr > attrs
The attributes which have been set.
Definition: NBTypeCont.h:89
double width
lane width [m]
Definition: NBTypeCont.h:83