Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
NIXMLEdgesHandler.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
23// 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>
32#include <netbuild/NBNodeCont.h>
33#include <netbuild/NBTypeCont.h>
43#include "NIXMLNodesHandler.h"
44#include "NIXMLEdgesHandler.h"
45#include "NIImporter_SUMO.h"
46
47
48// ===========================================================================
49// method definitions
50// ===========================================================================
52 NBEdgeCont& ec,
53 NBTypeCont& tc,
56 OptionsCont& options) :
57 SUMOSAXHandler("xml-edges - file"),
58 myOptions(options),
59 myNodeCont(nc),
60 myEdgeCont(ec),
61 myTypeCont(tc),
62 myDistrictCont(dc),
63 myTLLogicCont(tlc),
64 myCurrentEdge(nullptr),
65 myCurrentLaneIndex(-1),
66 myHaveReportedAboutOverwriting(false),
67 myHaveReportedAboutTypeOverride(false),
68 myHaveWarnedAboutDeprecatedLaneId(false),
69 myKeepEdgeShape(!options.getBool("plain.extend-edge-shape")) {
70}
71
72
76
77
78void
80 const SUMOSAXAttributes& attrs) {
81 switch (element) {
83 // infer location for legacy networks that don't have location information
85 break;
87 delete myLocation;
89 break;
90 case SUMO_TAG_EDGE:
91 addEdge(attrs);
92 break;
93 case SUMO_TAG_LANE:
94 addLane(attrs);
95 break;
96 case SUMO_TAG_NEIGH:
98 break;
99 case SUMO_TAG_SPLIT:
100 addSplit(attrs);
101 break;
102 case SUMO_TAG_DEL:
103 deleteEdge(attrs);
104 break;
106 addRoundabout(attrs);
107 break;
108 case SUMO_TAG_PARAM:
109 if (myLastParameterised.size() != 0 && myCurrentEdge != nullptr) {
110 bool ok = true;
111 const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
112 // circumventing empty string test
113 const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
114 myLastParameterised.back()->setParameter(key, val);
115 }
116 break;
117 case SUMO_TAG_STOPOFFSET: {
118 bool ok = true;
119 const StopOffset stopOffset(attrs, ok);
120 if (!ok) {
121 std::stringstream ss;
122 ss << "(Error encountered at lane " << myCurrentLaneIndex << " of edge '" << myCurrentID << "' while parsing stopOffsets.)";
123 WRITE_ERROR(ss.str());
124 } else {
126 std::stringstream ss;
127 ss << "Duplicate definition of stopOffset for ";
128 if (myCurrentLaneIndex != -1) {
129 ss << "lane " << myCurrentLaneIndex << " on ";
130 }
131 ss << "edge " << myCurrentEdge->getID() << ". Ignoring duplicate specification.";
132 WRITE_WARNING(ss.str());
133 } else if ((stopOffset.getOffset() > myCurrentEdge->getLength()) || (stopOffset.getOffset() < 0)) {
134 std::stringstream ss;
135 ss << "Ignoring invalid stopOffset for ";
136 if (myCurrentLaneIndex != -1) {
137 ss << "lane " << myCurrentLaneIndex << " on ";
138 }
139 ss << "edge " << myCurrentEdge->getID();
140 if (stopOffset.getOffset() > myCurrentEdge->getLength()) {
141 ss << " (offset larger than the edge length).";
142 } else {
143 ss << " (negative offset).";
144 }
145 WRITE_WARNING(ss.str());
146 } else {
148 }
149 }
150 }
151 break;
152 default:
153 break;
154 }
155}
156
157
158void
160 myIsUpdate = false;
161 bool ok = true;
162 // initialise the edge
163 myCurrentEdge = nullptr;
164 mySplits.clear();
165 // get the id, report an error if not given or empty...
166 myCurrentID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
167 if (!ok) {
168 return;
169 }
171 // check deprecated (unused) attributes
172 // use default values, first
173 myCurrentType = myOptions.getString("default.type");
177 if (myCurrentEdge != nullptr) {
178 // update existing edge. only update lane-specific settings when explicitly requested
179 myIsUpdate = true;
186 } else {
187 // this is a completely new edge. get the type specific defaults
193 }
197 myReinitKeepEdgeShape = false;
200 // check whether a type's values shall be used
201 if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
202 myCurrentType = attrs.get<std::string>(SUMO_ATTR_TYPE, myCurrentID.c_str(), ok);
203 if (!ok) {
204 return;
205 }
206 if (!myTypeCont.knows(myCurrentType) && !myOptions.getBool("ignore-errors.edge-type")) {
207 WRITE_ERRORF("Type '%' used by edge '%' was not defined (ignore with option --ignore-errors.edge-type).", myCurrentType, myCurrentID);
208 return;
209 }
218 }
219 // use values from the edge to overwrite if existing, then
220 if (myIsUpdate) {
222 WRITE_MESSAGEF(TL("Duplicate edge id occurred ('%'); assuming overwriting is wished."), myCurrentID);
224 }
227 WRITE_MESSAGEF(TL("Edge '%' changed its type; assuming type override is wished."), myCurrentID);
229 }
230 }
231 if (attrs.getOpt<bool>(SUMO_ATTR_REMOVE, myCurrentID.c_str(), ok, false)) {
233 myCurrentEdge = nullptr;
234 return;
235 }
241 }
245 }
247 }
248 // speed, priority and the number of lanes have now default values;
249 // try to read the real values from the file
250 if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
251 myCurrentSpeed = attrs.get<double>(SUMO_ATTR_SPEED, myCurrentID.c_str(), ok);
252 }
253 if (myOptions.getBool("speed-in-kmh") && myCurrentSpeed != NBEdge::UNSPECIFIED_SPEED) {
254 myCurrentSpeed = myCurrentSpeed / (double) 3.6;
255 }
256 // try to read the friction value from file
257 if (attrs.hasAttribute(SUMO_ATTR_FRICTION)) {
258 myCurrentFriction = attrs.get<double>(SUMO_ATTR_FRICTION, myCurrentID.c_str(), ok);
259 }
260 // try to get the number of lanes
261 if (attrs.hasAttribute(SUMO_ATTR_NUMLANES)) {
262 myCurrentLaneNo = attrs.get<int>(SUMO_ATTR_NUMLANES, myCurrentID.c_str(), ok);
263 }
264 // try to get the priority
265 if (attrs.hasAttribute(SUMO_ATTR_PRIORITY)) {
266 myCurrentPriority = attrs.get<int>(SUMO_ATTR_PRIORITY, myCurrentID.c_str(), ok);
267 }
268 // try to get the width
269 if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
270 myCurrentWidth = attrs.get<double>(SUMO_ATTR_WIDTH, myCurrentID.c_str(), ok);
271 }
272 // try to get the offset of the stop line from the intersection
274 myCurrentEndOffset = attrs.get<double>(SUMO_ATTR_ENDOFFSET, myCurrentID.c_str(), ok);
275 }
276 // try to get the street name
277 if (attrs.hasAttribute(SUMO_ATTR_NAME)) {
278 myCurrentStreetName = attrs.get<std::string>(SUMO_ATTR_NAME, myCurrentID.c_str(), ok);
279 if (myCurrentStreetName != "" && myOptions.isDefault("output.street-names")) {
280 myOptions.set("output.street-names", "true");
281 }
282 }
283
284 // try to get the allowed/disallowed classes
286 std::string allowS = attrs.hasAttribute(SUMO_ATTR_ALLOW) ? attrs.getStringSecure(SUMO_ATTR_ALLOW, "") : "";
287 std::string disallowS = attrs.hasAttribute(SUMO_ATTR_DISALLOW) ? attrs.getStringSecure(SUMO_ATTR_DISALLOW, "") : "";
288 // XXX matter of interpretation: should updated permissions replace or extend previously set permissions?
289 myPermissions = parseVehicleClasses(allowS, disallowS);
290 }
291 // try to set the nodes
292 if (!setNodes(attrs)) {
293 // return if this failed
294 myCurrentEdge = nullptr;
295 return;
296 }
297 // try to get the shape
298 myShape = tryGetShape(attrs);
299 // try to get the spread type
301 // try to get the length
302 myLength = attrs.getOpt<double>(SUMO_ATTR_LENGTH, myCurrentID.c_str(), ok, myLength);
303 // try to get the sidewalkWidth
305 // try to get the bikeLaneWidth
307 // insert the parsed edge into the edges map
308 if (!ok) {
309 myCurrentEdge = nullptr;
310 return;
311 }
312 if (myFromNode == myToNode) {
313 // this might as well be an error. We make this a warning mostly for
314 // backward compatibility
315 WRITE_WARNINGF(TL("Ignoring self-looped edge '%' at junction '%'"), myCurrentID, myFromNode->getID());
316 myCurrentEdge = nullptr;
317 return;
318 }
319 // check whether a previously defined edge shall be overwritten
320 const bool applyLaneType = myCurrentEdge == nullptr;
321 if (myCurrentEdge != nullptr) {
327 } else {
328 // the edge must be allocated in dependence to whether a shape is given
329 if (myShape.size() == 0) {
333 } else {
338 }
339 }
343 }
344 // apply laneType if given
345 if (applyLaneType && myCurrentType != "" && myTypeCont.knows(myCurrentType)) {
347 if (eType->needsLaneType()) {
348 int lane = 0;
349 for (const NBTypeCont::LaneTypeDefinition& laneType : eType->laneTypeDefinitions) {
350 if (lane >= myCurrentLaneNo) {
351 break;
352 }
353 if (laneType.attrs.count(SUMO_ATTR_SPEED) > 0) {
354 myCurrentEdge->setSpeed(lane, laneType.speed);
355 }
356 if (laneType.attrs.count(SUMO_ATTR_FRICTION) > 0) {
357 myCurrentEdge->setFriction(lane, laneType.friction);
358 }
359 if (laneType.attrs.count(SUMO_ATTR_DISALLOW) > 0 || laneType.attrs.count(SUMO_ATTR_ALLOW) > 0) {
360 myCurrentEdge->setPermissions(laneType.permissions, lane);
361 }
362 if (laneType.attrs.count(SUMO_ATTR_WIDTH) > 0) {
363 myCurrentEdge->setLaneWidth(lane, laneType.width);
364 }
365 lane++;
366 }
367 }
368 }
369 // try to get the kilometrage/mileage
372 // preserve bidi edge (only as bool, the actual edge will be recomputed)
373 const std::string bidi = attrs.getOpt<std::string>(SUMO_ATTR_BIDI, myCurrentID.c_str(), ok, "");
374 myCurrentEdge->setBidi(myCurrentEdge->getBidiEdge() != nullptr || myCurrentEdge->isBidi() || bidi != "");
375
377}
378
379
380void
382 if (myCurrentEdge == nullptr) {
383 if (!OptionsCont::getOptions().isInStringVector("remove-edges.explicit", myCurrentID)) {
384 WRITE_ERRORF("Additional lane information could not be set - the edge with id '%s' is not known.", myCurrentID);
385 }
386 return;
387 }
388 bool ok = true;
389 int lane;
390 if (attrs.hasAttribute(SUMO_ATTR_ID)) {
391 lane = attrs.get<int>(SUMO_ATTR_ID, myCurrentID.c_str(), ok);
394 WRITE_WARNINGF(TL("'%' is deprecated, please use '%' instead."), toString(SUMO_ATTR_ID), toString(SUMO_ATTR_INDEX));
395 }
396 } else {
397 lane = attrs.get<int>(SUMO_ATTR_INDEX, myCurrentID.c_str(), ok);
398 }
399 if (!ok) {
400 return;
401 }
402 // check whether this lane exists
403 if (lane >= myCurrentEdge->getNumLanes()) {
404 WRITE_ERRORF(TL("Lane index is larger than number of lanes (edge '%')."), myCurrentID);
405 return;
406 }
407 myCurrentLaneIndex = lane;
408 // set information about allowed / disallowed vehicle classes (if specified)
410 const std::string allowed = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, nullptr, ok, "");
411 const std::string disallowed = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, nullptr, ok, "");
412 myCurrentEdge->setPermissions(parseVehicleClasses(allowed, disallowed), lane);
413 }
414 if (attrs.hasAttribute(SUMO_ATTR_PREFER)) {
415 const std::string preferred = attrs.get<std::string>(SUMO_ATTR_PREFER, nullptr, ok);
417 }
419 const std::string changeLeft = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_LEFT, nullptr, ok, "");
420 const std::string changeRight = attrs.getOpt<std::string>(SUMO_ATTR_CHANGE_RIGHT, nullptr, ok, "");
421 myCurrentEdge->setPermittedChanging(lane, parseVehicleClasses(changeLeft, ""), parseVehicleClasses(changeRight, ""));
422 }
423 // try to get the width
424 if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
425 myCurrentEdge->setLaneWidth(lane, attrs.get<double>(SUMO_ATTR_WIDTH, myCurrentID.c_str(), ok));
426 }
427 // try to get the end-offset (lane shortened due to pedestrian crossing etc..)
429 myCurrentEdge->setEndOffset(lane, attrs.get<double>(SUMO_ATTR_ENDOFFSET, myCurrentID.c_str(), ok));
430 }
431 // try to get lane specific speed (should not occur for german networks)
432 if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
433 myCurrentEdge->setSpeed(lane, attrs.get<double>(SUMO_ATTR_SPEED, myCurrentID.c_str(), ok));
434 }
435 // try to get lane specific friction
436 if (attrs.hasAttribute(SUMO_ATTR_FRICTION)) {
437 myCurrentEdge->setFriction(lane, attrs.get<double>(SUMO_ATTR_FRICTION, myCurrentID.c_str(), ok));
438 }
439 // check whether this is an acceleration lane
441 myCurrentEdge->setAcceleration(lane, attrs.get<bool>(SUMO_ATTR_ACCELERATION, myCurrentID.c_str(), ok));
442 }
443 // check whether this lane has a custom shape
444 if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
445 PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, myCurrentID.c_str(), ok);
447 const std::string laneID = myCurrentID + "_" + toString(lane);
448 WRITE_ERRORF(TL("Unable to project coordinates for lane '%'."), laneID);
449 }
450 if (shape.size() == 1) {
451 // lane shape of length 1 is not permitted
453 shape.push_back(myCurrentEdge->getToNode()->getPosition());
454 }
455 shape.removeDoublePoints();
456 if (shape.size() < 2) {
457 // ignore lane shape for very short lanes
458 shape.clear();
459 }
460 myCurrentEdge->setLaneShape(lane, shape);
461 }
462 // set custom lane type
463 if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
464 myCurrentEdge->setLaneType(lane, attrs.get<std::string>(SUMO_ATTR_TYPE, myCurrentID.c_str(), ok));
465 }
467}
468
469
471 if (myCurrentEdge == nullptr) {
472 if (!OptionsCont::getOptions().isInStringVector("remove-edges.explicit", myCurrentID)) {
473 WRITE_WARNING(TL("Ignoring 'split' because it cannot be assigned to an edge"));
474 }
475 return;
476 }
477 bool ok = true;
479 e.pos = attrs.get<double>(SUMO_ATTR_POSITION, nullptr, ok);
480 if (ok) {
481 if (fabs(e.pos) > myCurrentEdge->getLoadedLength()) {
482 WRITE_ERRORF(TL("Edge '%' has a split at invalid position %."), myCurrentID, toString(e.pos));
483 return;
484 }
485 std::vector<NBEdgeCont::Split>::iterator i = find_if(mySplits.begin(), mySplits.end(), split_by_pos_finder(e.pos));
486 if (i != mySplits.end()) {
487 WRITE_ERRORF(TL("Edge '%' has already a split at position %."), myCurrentID, toString(e.pos));
488 return;
489 }
490 // XXX rounding to int may duplicate the id of another split
491 e.nameID = myCurrentID + "." + toString((int)e.pos);
492 if (e.pos < 0) {
494 }
495 for (const std::string& id : attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_LANES, myCurrentID.c_str(), ok)) {
496 try {
497 int lane = StringUtils::toInt(id);
498 e.lanes.push_back(lane);
499 } catch (NumberFormatException&) {
500 WRITE_ERRORF(TL("Error on parsing a split (edge '%')."), myCurrentID);
501 } catch (EmptyData&) {
502 WRITE_ERRORF(TL("Error on parsing a split (edge '%')."), myCurrentID);
503 }
504 }
505 if (e.lanes.empty()) {
506 for (int l = 0; l < myCurrentEdge->getNumLanes(); ++l) {
507 e.lanes.push_back(l);
508 }
509 }
510 e.speed = attrs.getOpt(SUMO_ATTR_SPEED, nullptr, ok, myCurrentEdge->getSpeed());
511 if (attrs.hasAttribute(SUMO_ATTR_SPEED) && myOptions.getBool("speed-in-kmh")) {
512 e.speed /= 3.6;
513 }
514 e.idBefore = attrs.getOpt(SUMO_ATTR_ID_BEFORE, nullptr, ok, std::string(""));
515 e.idAfter = attrs.getOpt(SUMO_ATTR_ID_AFTER, nullptr, ok, std::string(""));
516 if (!ok) {
517 return;
518 }
519 const std::string nodeID = attrs.getOpt(SUMO_ATTR_ID, nullptr, ok, e.nameID);
520 if (nodeID == myCurrentEdge->getFromNode()->getID() || nodeID == myCurrentEdge->getToNode()->getID()) {
521 WRITE_ERRORF(TL("Invalid split node id for edge '%' (from- and to-node are forbidden)"), myCurrentEdge->getID());
522 return;
523 }
524 e.node = myNodeCont.retrieve(nodeID);
525 e.offset = attrs.getOpt(SUMO_ATTR_OFFSET, nullptr, ok, 0.0);
526 e.offsetFactor = OptionsCont::getOptions().getBool("lefthand") ? -1 : 1;
527 if (e.node == nullptr) {
528 double geomPos = e.pos;
531 }
532 e.node = new NBNode(nodeID, myCurrentEdge->getGeometry().positionAtOffset(geomPos));
534 }
537 mySplits.push_back(e);
538 }
539}
540
541
542bool
544 // the names and the coordinates of the beginning and the end node
545 // may be found, try
546 bool ok = true;
547 if (myIsUpdate) {
550 }
551 if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
552 const std::string begNodeID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
553 if (begNodeID != "") {
554 myFromNode = myNodeCont.retrieve(begNodeID);
555 if (myFromNode == nullptr) {
556 WRITE_ERRORF(TL("Edge's '%' from-node '%' is not known."), myCurrentID, begNodeID);
557 }
558 }
559 } else if (!myIsUpdate) {
560 WRITE_ERRORF(TL("The from-node is not given for edge '%'."), myCurrentID);
561 ok = false;
562 }
563 if (attrs.hasAttribute(SUMO_ATTR_TO)) {
564 const std::string endNodeID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
565 if (endNodeID != "") {
566 myToNode = myNodeCont.retrieve(endNodeID);
567 if (myToNode == nullptr) {
568 WRITE_ERRORF(TL("Edge's '%' to-node '%' is not known."), myCurrentID, endNodeID);
569 }
570 }
571 } else if (!myIsUpdate) {
572 WRITE_ERRORF(TL("The to-node is not given for edge '%'."), myCurrentID);
573 ok = false;
574 }
575 return ok && myFromNode != nullptr && myToNode != nullptr;
576}
577
578
581 if (!attrs.hasAttribute(SUMO_ATTR_SHAPE) && myShape.size() > 0) {
582 return myShape;
583 }
584 // try to build shape
585 bool ok = true;
586 if (!attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
587 const double maxSegmentLength = OptionsCont::getOptions().getFloat("geometry.max-segment-length");
588 if (maxSegmentLength > 0) {
589 PositionVector shape;
590 shape.push_back(myFromNode->getPosition());
591 shape.push_back(myToNode->getPosition());
592 // shape is already cartesian but we must use a copy because the original will be modified
593 NBNetBuilder::addGeometrySegments(shape, PositionVector(shape), maxSegmentLength);
594 return shape;
595 } else {
596 myReinitKeepEdgeShape = false;
597 return PositionVector();
598 }
599 }
600 PositionVector shape = attrs.getOpt<PositionVector>(SUMO_ATTR_SHAPE, nullptr, ok, PositionVector());
602 WRITE_ERRORF(TL("Unable to project coordinates for edge '%'."), myCurrentID);
603 }
605 return shape;
606}
607
608
611 bool ok = true;
613 std::string lsfS = toString(result);
614 lsfS = attrs.getOpt<std::string>(SUMO_ATTR_SPREADTYPE, myCurrentID.c_str(), ok, lsfS);
615 if (SUMOXMLDefinitions::LaneSpreadFunctions.hasString(lsfS)) {
617 } else {
618 WRITE_WARNINGF(TL("Ignoring unknown spreadType '%' for edge '%'."), lsfS, myCurrentID);
619 }
620 return result;
621}
622
623
624void
626 bool ok = true;
627 myCurrentID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
628 if (!ok) {
629 return;
630 }
632 if (edge == nullptr) {
633 WRITE_WARNING("Ignoring tag '" + toString(SUMO_TAG_DEL) + "' for unknown edge '" +
634 myCurrentID + "'");
635 return;
636 }
637 const int lane = attrs.getOpt<int>(SUMO_ATTR_INDEX, myCurrentID.c_str(), ok, -1);
638 if (lane < 0) {
639 myEdgeCont.extract(myDistrictCont, edge, true);
640 } else {
641 edge->deleteLane(lane, false, true);
642 }
643}
644
645
646void
648 if (element == SUMO_TAG_VIEWSETTINGS_EDGES) {
649 delete myLocation;
650 myLocation = nullptr;
651 return;
652 }
653 if (myCurrentEdge == nullptr) {
654 return;
655 }
656 if (element == SUMO_TAG_EDGE) {
657 myLastParameterised.pop_back();
658 // add bike lane, wait until lanes are loaded to avoid building if it already exists
661 }
662 // add sidewalk, wait until lanes are loaded to avoid building if it already exists
665 }
666 // apply default stopOffsets of edge to all lanes without specified stopOffset.
667 const StopOffset stopOffsets = myCurrentEdge->getEdgeStopOffset();
668 if (stopOffsets.isDefined()) {
669 for (int i = 0; i < (int)myCurrentEdge->getLanes().size(); i++) {
670 myCurrentEdge->setEdgeStopOffset(i, stopOffsets, false);
671 }
672 }
673 if (!myIsUpdate) {
674 try {
676 WRITE_ERRORF(TL("Duplicate edge '%' occurred."), myCurrentID);
677 delete myCurrentEdge;
678 myCurrentEdge = nullptr;
679 return;
680 }
681 } catch (InvalidArgument& e) {
682 WRITE_ERROR(e.what());
683 throw;
684 } catch (...) {
685 WRITE_ERRORF(TL("An important information is missing in edge '%'."), myCurrentID);
686 }
687 }
689 myCurrentEdge = nullptr;
690 } else if (element == SUMO_TAG_LANE && myCurrentLaneIndex != -1) {
691 myLastParameterised.pop_back();
693 }
694}
695
696
697void
699 bool ok = true;
700 const std::vector<std::string>& edgeIDs = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, nullptr, ok);
701 if (ok) {
702 EdgeSet roundabout;
703 for (const std::string& eID : edgeIDs) {
704 NBEdge* edge = myEdgeCont.retrieve(eID);
705 if (edge == nullptr) {
706 if (!myEdgeCont.wasIgnored(eID)) {
707 WRITE_ERRORF(TL("Unknown edge '%' in roundabout."), eID);
708 }
709 } else {
710 roundabout.insert(edge);
711 }
712 }
713 myEdgeCont.addRoundabout(roundabout);
714 }
715}
716
717
718/****************************************************************************/
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define WRITE_MESSAGEF(...)
Definition MsgHandler.h:289
#define WRITE_ERRORF(...)
Definition MsgHandler.h:296
#define WRITE_ERROR(msg)
Definition MsgHandler.h:295
#define WRITE_WARNING(msg)
Definition MsgHandler.h:286
#define TL(string)
Definition MsgHandler.h:304
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_LOCATION
@ SUMO_TAG_ROUNDABOUT
roundabout defined in junction
@ SUMO_TAG_VIEWSETTINGS_EDGES
@ 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_OFFSET
@ 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
@ SUMO_ATTR_ROUTINGTYPE
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
const std::string & getFileName() const
returns the current file name
static GeoConvHelper * getLoadedPlain(const std::string &plainFile, const std::string &suffix=".edg.xml")
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.
void processSplits(NBEdge *e, std::vector< Split > splits, NBNodeCont &nc, NBDistrictCont &dc, NBTrafficLightLogicCont &tlc)
process splits
void erase(NBDistrictCont &dc, NBEdge *edge)
Removes the given edge from the container (deleting it)
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
bool wasIgnored(std::string id) const
Returns whether the edge with the id was ignored during parsing.
Definition NBEdgeCont.h:483
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
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:386
void setPreferredVehicleClass(SVCPermissions permissions, int lane=-1)
set preferred Vehicle Class
Definition NBEdge.cpp:4517
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:4531
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:4503
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:4746
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition NBEdge.cpp:4455
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:355
Lane & getLaneStruct(int lane)
Definition NBEdge.h:1451
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition NBEdge.h:789
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge's lanes' lateral offset is computed.
Definition NBEdge.cpp:1021
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:1425
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:4425
const std::string & getRoutingType() const
return whether this edge should be a bidi edge
Definition NBEdge.h:1446
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:4341
double getSpeed() const
Returns the speed allowed on this edge.
Definition NBEdge.h:625
const std::string & getID() const
Definition NBEdge.h:1551
double getDistance() const
get distance
Definition NBEdge.h:685
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
Definition NBEdge.h:364
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition NBEdge.cpp:4326
void setAcceleration(int lane, bool accelRamp)
marks one lane as acceleration lane
Definition NBEdge.cpp:4487
const StopOffset & getEdgeStopOffset() const
Returns the stopOffset to the end of the edge.
Definition NBEdge.cpp:4393
void setBidi(bool isBidi)
mark this edge as a bidi edge
Definition NBEdge.h:1430
void addSidewalk(double width)
add a pedestrian sidewalk of the given width and shift existing connctions
Definition NBEdge.cpp:4734
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:4471
void deleteLane(int index, bool recompute, bool shiftIndices)
delete lane
Definition NBEdge.cpp:4247
static const double UNSPECIFIED_SPEED
unspecified lane speed
Definition NBEdge.h:352
const std::string & getTypeID() const
get ID of type
Definition NBEdge.h:1187
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:4495
const NBEdge * getBidiEdge() const
Definition NBEdge.h:1537
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:619
bool isBidi() const
return whether this edge should be a bidi edge
Definition NBEdge.h:1435
int getPriority() const
Returns the priority of the edge.
Definition NBEdge.h:533
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition NBEdge.h:346
const StopOffset & getLaneStopOffset(int lane) const
Returns the stop offset to the specified lane's end.
Definition NBEdge.cpp:4399
void setRoutingType(const std::string &routingType)
mark this edge as a bidi edge
Definition NBEdge.h:1441
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition NBEdge.cpp:4409
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition NBEdge.h:349
void setLoadedLength(double val)
set loaded length
Definition NBEdge.cpp:4555
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:57
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Represents a single node (junction) during network building.
Definition NBNode.h:66
const Position & getPosition() const
Definition NBNode.h:260
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 [-].
double getEdgeTypeSpeed(const std::string &edgeType) const
Returns the maximal velocity for the given edgeType [m/s].
int getEdgeTypePriority(const std::string &edgeType) const
Returns the priority for the given edgeType.
int getEdgeTypeNumLanes(const std::string &edgeType) const
Returns the number of lanes for the given edgeType.
double getEdgeTypeWidth(const std::string &edgeType) const
Returns the lane width for the given edgeType [m].
SVCPermissions getEdgeTypePermissions(const std::string &edgeType) const
Returns allowed vehicle classes for the given edgeType.
bool knows(const std::string &edgeType) const
Returns whether the named edgeType is in the container.
double getEdgeTypeSidewalkWidth(const std::string &edgeType) const
Returns the lane width for a sidewalk to be added [m].
LaneSpreadFunction getEdgeTypeSpreadType(const std::string &edgeType) const
Returns spreadType for the given edgeType.
double getEdgeTypeBikeLaneWidth(const std::string &edgeType) const
Returns the lane width for a bike lane to be added [m].
const EdgeTypeDefinition * getEdgeType(const std::string &name) const
Retrieve the name or the default edgeType.
static GeoConvHelper * loadLocation(const SUMOSAXAttributes &attrs, bool setLoaded=true)
Parses network location description and registers it with GeoConveHelper::setLoaded.
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.
GeoConvHelper * myLocation
The coordinate transformation which was used compute the node coordinates.
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.
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, GeoConvHelper *from_srs=nullptr)
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.
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
get key
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:189
int offsetFactor
direction in which to apply the offset (used by netgenerate for lefthand networks)
Definition NBEdgeCont.h:209
double speed
The speed after this change.
Definition NBEdgeCont.h:195
double offset
lateral offset to edge geometry
Definition NBEdgeCont.h:207
std::string nameID
the default node id
Definition NBEdgeCont.h:205
std::string idBefore
The id for the edge before the split.
Definition NBEdgeCont.h:201
double pos
The position of this change.
Definition NBEdgeCont.h:193
std::vector< int > lanes
The lanes after this change.
Definition NBEdgeCont.h:191
std::string idAfter
The id for the edge after the split.
Definition NBEdgeCont.h:203
NBNode * node
The new node that is created for this split.
Definition NBEdgeCont.h:199
edgeType definition
Definition NBTypeCont.h:93
bool needsLaneType() const
whether any lane attributes deviate from the edge attributes
std::vector< LaneTypeDefinition > laneTypeDefinitions
vector with LaneTypeDefinitions
Definition NBTypeCont.h:158
laneType definition
Definition NBTypeCont.h:59