Line data Source code
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 : /****************************************************************************/
14 : /// @file NIImporter_OpenDrive.h
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @author Mirko Barthauer
19 : /// @date Mon, 14.04.2008
20 : ///
21 : // Importer for networks stored in openDrive format
22 : /****************************************************************************/
23 : #pragma once
24 : #include <config.h>
25 :
26 : #include <string>
27 : #include <map>
28 : #include <utils/xml/GenericSAXHandler.h>
29 : #include <utils/geom/PositionVector.h>
30 :
31 :
32 : // ===========================================================================
33 : // class declarations
34 : // ===========================================================================
35 : class NBNetBuilder;
36 : class NBEdge;
37 : class OptionsCont;
38 : class NBNode;
39 : class NBNodeCont;
40 :
41 :
42 : #define UNSET_CONNECTION 100000
43 : #define UNSET_LANEVALIDITY 100000
44 :
45 : // ===========================================================================
46 : // class definitions
47 : // ===========================================================================
48 : /**
49 : * @class NIImporter_OpenDrive
50 : * @brief Importer for networks stored in openDrive format
51 : *
52 : */
53 : class NIImporter_OpenDrive : public GenericSAXHandler {
54 : public:
55 : /** @brief Loads content of the optionally given SUMO file
56 : *
57 : * If the option "opendrive-files" is set, the file stored therein is read and
58 : * the network definition stored therein is stored within the given network
59 : * builder.
60 : *
61 : * If the option "opendrive-files" is not set, this method simply returns.
62 : *
63 : * The loading is done by parsing the network definition as an XML file
64 : * using the SAXinterface and handling the incoming data via this class'
65 : * methods.
66 : *
67 : * @param[in] oc The options to use
68 : * @param[in] nb The network builder to fill
69 : */
70 : static void loadNetwork(const OptionsCont& oc, NBNetBuilder& nb);
71 :
72 :
73 : protected:
74 :
75 : /**
76 : * @enum OpenDriveXMLTag
77 : * @brief Numbers representing openDrive-XML - element names
78 : * @see GenericSAXHandler
79 : */
80 : enum OpenDriveXMLTag {
81 : OPENDRIVE_TAG_NOTHING,
82 : OPENDRIVE_TAG_HEADER,
83 : OPENDRIVE_TAG_ROAD,
84 : OPENDRIVE_TAG_PREDECESSOR,
85 : OPENDRIVE_TAG_SUCCESSOR,
86 : /// @todo OPENDRIVE_TAG_NEIGHBOR,
87 : /// @todo OPENDRIVE_TAG_TYPE,
88 : OPENDRIVE_TAG_GEOMETRY,
89 : OPENDRIVE_TAG_LINE,
90 : OPENDRIVE_TAG_SPIRAL,
91 : OPENDRIVE_TAG_ARC,
92 : OPENDRIVE_TAG_POLY3,
93 : OPENDRIVE_TAG_PARAMPOLY3,
94 : OPENDRIVE_TAG_LANESECTION,
95 : OPENDRIVE_TAG_LANEOFFSET,
96 : OPENDRIVE_TAG_ACCESS,
97 : OPENDRIVE_TAG_LEFT,
98 : OPENDRIVE_TAG_CENTER,
99 : OPENDRIVE_TAG_RIGHT,
100 : OPENDRIVE_TAG_LANE,
101 : OPENDRIVE_TAG_SIGNAL,
102 : OPENDRIVE_TAG_SIGNALREFERENCE,
103 : OPENDRIVE_TAG_CONTROLLER,
104 : OPENDRIVE_TAG_CONTROL,
105 : OPENDRIVE_TAG_VALIDITY,
106 : OPENDRIVE_TAG_SEMANTICS,
107 : OPENDRIVE_TAG_PRIORITY,
108 : OPENDRIVE_TAG_JUNCTION,
109 : OPENDRIVE_TAG_CONNECTION,
110 : OPENDRIVE_TAG_LANELINK,
111 : OPENDRIVE_TAG_WIDTH,
112 : OPENDRIVE_TAG_SPEED,
113 : OPENDRIVE_TAG_ELEVATION,
114 : OPENDRIVE_TAG_GEOREFERENCE,
115 : OPENDRIVE_TAG_OFFSET,
116 : OPENDRIVE_TAG_OBJECT,
117 : OPENDRIVE_TAG_REPEAT,
118 : OPENDRIVE_TAG_INCLUDE
119 : };
120 :
121 :
122 : /**
123 : * @enum OpenDriveXMLAttr
124 : * @brief Numbers representing openDrive-XML - attributes
125 : * @see GenericSAXHandler
126 : */
127 : enum OpenDriveXMLAttr {
128 : OPENDRIVE_ATTR_NOTHING,
129 : OPENDRIVE_ATTR_REVMAJOR,
130 : OPENDRIVE_ATTR_REVMINOR,
131 : OPENDRIVE_ATTR_ID,
132 : OPENDRIVE_ATTR_LENGTH,
133 : OPENDRIVE_ATTR_WIDTH,
134 : OPENDRIVE_ATTR_RADIUS,
135 : OPENDRIVE_ATTR_DISTANCE,
136 : OPENDRIVE_ATTR_TSTART,
137 : OPENDRIVE_ATTR_TEND,
138 : OPENDRIVE_ATTR_WIDTHSTART,
139 : OPENDRIVE_ATTR_WIDTHEND,
140 : OPENDRIVE_ATTR_JUNCTION,
141 : OPENDRIVE_ATTR_ELEMENTTYPE,
142 : OPENDRIVE_ATTR_ELEMENTID,
143 : OPENDRIVE_ATTR_CONTACTPOINT,
144 : OPENDRIVE_ATTR_S,
145 : OPENDRIVE_ATTR_T,
146 : OPENDRIVE_ATTR_X,
147 : OPENDRIVE_ATTR_Y,
148 : OPENDRIVE_ATTR_Z,
149 : OPENDRIVE_ATTR_HDG,
150 : OPENDRIVE_ATTR_CURVSTART,
151 : OPENDRIVE_ATTR_CURVEND,
152 : OPENDRIVE_ATTR_CURVATURE,
153 : OPENDRIVE_ATTR_A,
154 : OPENDRIVE_ATTR_B,
155 : OPENDRIVE_ATTR_C,
156 : OPENDRIVE_ATTR_D,
157 : OPENDRIVE_ATTR_AU,
158 : OPENDRIVE_ATTR_BU,
159 : OPENDRIVE_ATTR_CU,
160 : OPENDRIVE_ATTR_DU,
161 : OPENDRIVE_ATTR_AV,
162 : OPENDRIVE_ATTR_BV,
163 : OPENDRIVE_ATTR_CV,
164 : OPENDRIVE_ATTR_DV,
165 : OPENDRIVE_ATTR_PRANGE,
166 : OPENDRIVE_ATTR_TYPE,
167 : OPENDRIVE_ATTR_LEVEL,
168 : OPENDRIVE_ATTR_ORIENTATION,
169 : OPENDRIVE_ATTR_DYNAMIC,
170 : OPENDRIVE_ATTR_INCOMINGROAD,
171 : OPENDRIVE_ATTR_CONNECTINGROAD,
172 : OPENDRIVE_ATTR_FROM,
173 : OPENDRIVE_ATTR_TO,
174 : OPENDRIVE_ATTR_FROMLANE,
175 : OPENDRIVE_ATTR_TOLANE,
176 : OPENDRIVE_ATTR_MAX,
177 : OPENDRIVE_ATTR_SOFFSET,
178 : OPENDRIVE_ATTR_RULE,
179 : OPENDRIVE_ATTR_RESTRICTION,
180 : OPENDRIVE_ATTR_NAME,
181 : OPENDRIVE_ATTR_UNIT, // xodr v1.4
182 : OPENDRIVE_ATTR_SIGNALID,
183 : OPENDRIVE_ATTR_FILE
184 : };
185 :
186 :
187 : /** @brief OpenDrive link type enumeration
188 : */
189 : enum LinkType {
190 : OPENDRIVE_LT_SUCCESSOR,
191 : OPENDRIVE_LT_PREDECESSOR
192 : };
193 :
194 :
195 : /** @brief OpenDrive element type enumeration
196 : */
197 : enum ElementType {
198 : OPENDRIVE_ET_UNKNOWN,
199 : OPENDRIVE_ET_ROAD,
200 : OPENDRIVE_ET_JUNCTION
201 : };
202 :
203 :
204 : /** @brief OpenDrive contact type enumeration
205 : */
206 : enum ContactPoint {
207 : OPENDRIVE_CP_UNKNOWN,
208 : OPENDRIVE_CP_START,
209 : OPENDRIVE_CP_END
210 : };
211 :
212 : /** @brief OpenDrive geometry type enumeration
213 : */
214 : enum GeometryType {
215 : OPENDRIVE_GT_UNKNOWN,
216 : OPENDRIVE_GT_LINE,
217 : OPENDRIVE_GT_SPIRAL,
218 : OPENDRIVE_GT_ARC,
219 : OPENDRIVE_GT_POLY3,
220 : OPENDRIVE_GT_PARAMPOLY3 // rev 1.4
221 : };
222 :
223 :
224 :
225 : /**
226 : * @struct OpenDriveLink
227 : * @brief Representation of an OpenDrive link
228 : */
229 5888 : struct OpenDriveLink {
230 : /** @brief Constructor
231 : * @param[in] linkTypeArg The link type
232 : * @param[in] elementIDArg The element id
233 : */
234 : OpenDriveLink(LinkType linkTypeArg, const std::string& elementIDArg)
235 1686 : : linkType(linkTypeArg), elementID(elementIDArg),
236 1686 : elementType(OPENDRIVE_ET_UNKNOWN), contactPoint(OPENDRIVE_CP_UNKNOWN) { }
237 :
238 : LinkType linkType;
239 : std::string elementID;
240 : ElementType elementType;
241 : ContactPoint contactPoint;
242 : };
243 :
244 :
245 : /**
246 : * @struct OpenDriveGeometry
247 : * @brief Representation of an OpenDrive geometry part
248 : */
249 7303 : struct OpenDriveGeometry {
250 : /** @brief Constructor
251 : * @param[in] lengthArg The length of this geometry part
252 : * @param[in] sArg The offset from the start, counted from the begin
253 : * @param[in] xArg x-position at this part's begin
254 : * @param[in] yArg y-position at this part's begin
255 : * @param[in] hdgArg heading at this part's begin
256 : */
257 : OpenDriveGeometry(double lengthArg, double sArg, double xArg, double yArg, double hdgArg)
258 1326 : : length(lengthArg), s(sArg), x(xArg), y(yArg), hdg(hdgArg),
259 1326 : type(OPENDRIVE_GT_UNKNOWN) { }
260 :
261 : double length;
262 : double s;
263 : double x;
264 : double y;
265 : double hdg;
266 : GeometryType type;
267 : std::vector<double> params;
268 : };
269 :
270 : /**
271 : * @struct OpenDriveElevation
272 : * @brief Coefficients of an elevation profile (3rd degree polynomial)
273 : */
274 : struct Poly3 {
275 : /** @brief Constructor
276 : * @param[in] s The start offset
277 : * @param[in] a constant
278 : * @param[in] b first order
279 : * @param[in] c second order
280 : * @param[in] d third order
281 : */
282 2956 : Poly3(double _s, double _a, double _b, double _c, double _d) :
283 2956 : s(_s), a(_a), b(_b), c(_c), d(_d) {}
284 :
285 : double computeAt(double pos) const {
286 19933 : const double ds = pos - s;
287 19933 : return a + b * ds + c * ds * ds + d * ds * ds * ds;
288 : }
289 :
290 : double s;
291 : double a;
292 : double b;
293 : double c;
294 : double d;
295 : };
296 :
297 : /// LaneOffset has the same fields as Elevation
298 : typedef Poly3 OpenDriveElevation;
299 : typedef Poly3 OpenDriveLaneOffset;
300 : typedef Poly3 OpenDriveWidth;
301 :
302 : /**
303 : * @struct LaneAttributeChange
304 : * @brief Attribute set applied at a certain position along a lane
305 : */
306 6328 : struct LaneAttributeChange {
307 : /** @brief Constructor
308 : * @param[in] speed The lane speed
309 : */
310 830 : LaneAttributeChange(double speed) : speed(speed) {}
311 :
312 : double speed;
313 : std::vector<std::string> allowed;
314 : std::vector<std::string> denied;
315 : };
316 :
317 :
318 :
319 : /**
320 : * @struct OpenDriveLane
321 : * @brief Representation of a lane
322 : */
323 : struct OpenDriveLane {
324 : /** @brief Constructor
325 : * @param[in] idArg The OpenDrive id of the lane
326 : * @param[in] levelArg The level
327 : * @param[in] typeArg type of the lane
328 : */
329 2721 : OpenDriveLane(int idArg, const std::string& levelArg, const std::string& typeArg) :
330 5442 : id(idArg), level(levelArg), type(typeArg), successor(UNSET_CONNECTION), predecessor(UNSET_CONNECTION),
331 2721 : speed(0), width(NBEdge::UNSPECIFIED_WIDTH), permission(0) { }
332 :
333 : /// @brief compute the actual SUMO lane permissions given the lane type as a start solution
334 : SVCPermissions computePermission(const NBTypeCont& tc, const std::vector<std::string>& allowed, const std::vector<std::string>& denied) const;
335 :
336 : int id; //!< The lane's id
337 : std::string level; //!< The lane's level (not used)
338 : std::string type; //!< The lane's type
339 : int successor; //!< The lane's successor lane
340 : int predecessor; //!< The lane's predecessor lane
341 : std::vector < std::pair<double, LaneAttributeChange> > attributeChanges; //!< List of permission and speed changes
342 : double speed; //!< The lane's speed (set in post-processing)
343 : double width; //The lane's maximum width
344 : SVCPermissions permission; //!< The access permissions (set in post-processing)
345 : std::vector<OpenDriveWidth> widthData;
346 : };
347 :
348 :
349 : /**
350 : * @struct OpenDriveLaneSection
351 : * @brief Representation of a lane section
352 : */
353 : struct OpenDriveLaneSection {
354 : /** @brief Constructor
355 : * @param[in] sArg The offset from the start, counted from the begin
356 : */
357 : OpenDriveLaneSection(double sArg);
358 :
359 :
360 : /** @brief Build the mapping from OpenDrive to SUMO lanes
361 : *
362 : * Not all lanes are converted to SUMO-lanes; the mapping includes only those
363 : * which are included in the SUMO network.
364 : * @param[in] tc The type container needed to determine whether a lane shall be imported by using the lane's type
365 : */
366 : void buildLaneMapping(const NBTypeCont& tc);
367 :
368 :
369 : /** @brief Returns the links from the previous to this lane section
370 : * @param[in] dir The OpenDrive-direction of drive
371 : * @param[in] pre The previous lane section
372 : * @return which lane is approached from which lane of the given previous lane section
373 : */
374 : std::map<int, int> getInnerConnections(OpenDriveXMLTag dir, const OpenDriveLaneSection& prev);
375 :
376 :
377 : bool buildAttributeChanges(const NBTypeCont& tc, std::vector<OpenDriveLaneSection>& newSections);
378 : OpenDriveLaneSection buildLaneSection(const NBTypeCont& tc, double startPos);
379 : /// @brief The starting offset of this lane section
380 : double s;
381 : /// @brief The original starting offset of this lane section (differs from s if the section had to be split)
382 : double sOrig;
383 : /// @brief The length of this lane section
384 : double length;
385 : /// @brief A mapping from OpenDrive to SUMO-index (the first is signed, the second unsigned)
386 : std::map<int, int> laneMap;
387 : /// @brief The lanes, sorted by their direction
388 : std::map<OpenDriveXMLTag, std::vector<OpenDriveLane> > lanesByDir;
389 : /// @brief The id (generic, without the optionally leading '-') of the edge generated for this section
390 : std::string sumoID;
391 : /// @brief The number of lanes on the right and on the left side, respectively
392 : int rightLaneNumber, leftLaneNumber;
393 : /// @brief the composite type built from all used lane types
394 : std::string rightType;
395 : std::string leftType;
396 : /// @brief average width of removed inside lanes
397 : double discardedInnerWidthLeft;
398 : double discardedInnerWidthRight;
399 : };
400 :
401 :
402 :
403 : /**
404 : * @struct OpenDriveSignal
405 : * @brief Representation of a signal
406 : */
407 : struct OpenDriveSignal {
408 : /** @brief Constructor
409 : * @param[in] idArg The OpenDrive id of the signal
410 : * @param[in] typeArg The type of the signal
411 : * @param[in] nameArg The type of the signal
412 : * @param[in] orientationArg The direction the signal belongs to
413 : * @param[in] dynamicArg Whether the signal is dynamic
414 : * @param[in] sArg The offset from the start, counted from the begin
415 : */
416 30 : OpenDriveSignal(const std::string& idArg, const std::string typeArg, const std::string nameArg,
417 30 : int orientationArg, bool dynamicArg, double sArg) :
418 60 : id(idArg), type(typeArg), name(nameArg),
419 30 : orientation(orientationArg), dynamic(dynamicArg), s(sArg),
420 30 : minLane(-UNSET_LANEVALIDITY), maxLane(UNSET_LANEVALIDITY)
421 30 : { }
422 :
423 : /// dummy constructor for use in maps
424 30 : OpenDriveSignal() {}
425 :
426 : std::string id;
427 : std::string type;
428 : std::string name;
429 : std::string priority;
430 : int orientation;
431 : bool dynamic;
432 : double s;
433 : /// @brief signal validity range
434 : int minLane;
435 : int maxLane;
436 : /// @brief the controller ID
437 : std::string controller;
438 : };
439 :
440 :
441 : /**
442 : * @struct OpenDriveController
443 : * @brief Representation of a signal group
444 : */
445 : struct OpenDriveController {
446 : /** @brief Constructor
447 : * @param[in] idArg The OpenDrive id of the signal group
448 : * @param[in] nameArg The type of the signal group
449 : */
450 2062 : OpenDriveController(const std::string& idArg, const std::string nameArg) :
451 4124 : id(idArg), name(nameArg) { }
452 :
453 : /// dummy constructor for use in maps
454 0 : OpenDriveController() {}
455 :
456 : std::string id;
457 : std::string name;
458 : std::vector<std::string> signalIDs;
459 : std::string junction;
460 : };
461 :
462 : /**
463 : * @struct Connection
464 : * @brief A connection between two roads
465 : */
466 : struct Connection {
467 : std::string fromEdge;
468 : std::string toEdge;
469 : int fromLane;
470 : int toLane;
471 : ContactPoint fromCP;
472 : ContactPoint toCP;
473 : bool all;
474 : std::string origID;
475 : int origLane;
476 : PositionVector shape;
477 :
478 : std::string getDescription() const {
479 : return "Connection from=" + fromEdge + "_" + toString(fromLane)
480 : + " to=" + toEdge + "_" + toString(toLane)
481 : + " fromCP=" + (fromCP == OPENDRIVE_CP_START ? "start" : fromCP == OPENDRIVE_CP_END ? "end" : "unknown")
482 : + " toCP=" + (toCP == OPENDRIVE_CP_START ? "start" : toCP == OPENDRIVE_CP_END ? "end" : "unknown")
483 : + " all=" + toString(all);
484 : //+ " origID=" + origID + " origLane=" + toString(origLane);
485 : }
486 : };
487 :
488 : /**
489 : * @struct Object
490 : * @brief A road object (e.g. parkingSpace)
491 : */
492 : struct OpenDriveObject {
493 : std::string type;
494 : std::string name;
495 : std::string id;
496 : double s;
497 : double t;
498 : double zOffset;
499 : double length;
500 : double width;
501 : double height;
502 : double radius;
503 : double hdg;
504 : double pitch;
505 : double roll;
506 : };
507 :
508 : /**
509 : * @struct OpenDriveEdge
510 : * @brief Representation of an openDrive "link"
511 : */
512 : struct OpenDriveEdge {
513 908 : OpenDriveEdge(const std::string& idArg, const std::string& streetNameArg, const std::string& junctionArg, double lengthArg) :
514 908 : id(idArg),
515 908 : streetName(streetNameArg),
516 908 : junction(junctionArg),
517 908 : length(lengthArg),
518 908 : from(0),
519 908 : to(0) {
520 908 : isInner = junction != "" && junction != "-1";
521 908 : }
522 :
523 :
524 : /** @brief Returns the edge's priority, regarding the direction
525 : *
526 : * The priority is determined by evaluating the signs located at the road
527 : * @param[in] dir The direction which priority shall be returned
528 : * @return The priority of the given direction
529 : */
530 : int getPriority(OpenDriveXMLTag dir) const;
531 :
532 :
533 : /// @brief The id of the edge
534 : std::string id;
535 : /// @brief The road name of the edge
536 : std::string streetName;
537 : /// @brief The id of the junction the edge belongs to
538 : std::string junction;
539 : /// @brief The length of the edge
540 : double length;
541 : std::vector<OpenDriveLink> links;
542 : std::vector<OpenDriveGeometry> geometries;
543 : std::vector<OpenDriveElevation> elevations;
544 : std::vector<OpenDriveLaneOffset> offsets;
545 : NBNode* from;
546 : NBNode* to;
547 : PositionVector geom;
548 : std::vector<double> laneOffsets;
549 : std::vector<OpenDriveLaneSection> laneSections;
550 : std::vector<OpenDriveSignal> signals;
551 : std::set<Connection> connections;
552 : std::vector<OpenDriveObject> objects;
553 : bool isInner;
554 : };
555 :
556 :
557 : /** @brief A class for sorting lane sections by their s-value */
558 : class sections_by_s_sorter {
559 : public:
560 : /// @brief Constructor
561 : explicit sections_by_s_sorter() { }
562 :
563 : /// @brief Sorting function; compares OpenDriveLaneSection::s
564 : int operator()(const OpenDriveLaneSection& ls1, const OpenDriveLaneSection& ls2) {
565 0 : return ls1.s < ls2.s;
566 : }
567 : };
568 :
569 : /* @brief A class for search in position/attribute change tuple vectors for the given position */
570 : class same_position_finder {
571 : public:
572 : /** @brief constructor */
573 834 : explicit same_position_finder(double pos) : myPosition(pos) { }
574 :
575 : /** @brief the comparing function */
576 : bool operator()(const std::pair<double, LaneAttributeChange>& ps) {
577 8 : return ps.first == myPosition;
578 : }
579 :
580 : private:
581 : /// @brief The position to search for
582 : double myPosition;
583 :
584 : };
585 :
586 : protected:
587 : /** @brief Constructor
588 : * @param[in] tc The type container used to determine whether a lane shall kept
589 : * @param[in] nc The edge map to fill
590 : */
591 : NIImporter_OpenDrive(const NBTypeCont& tc, std::map<std::string, OpenDriveEdge*>& edges);
592 :
593 :
594 : /// @brief Destructor
595 : ~NIImporter_OpenDrive();
596 :
597 :
598 :
599 : /// @name inherited from GenericSAXHandler
600 : //@{
601 :
602 : /** @brief Called on the opening of a tag;
603 : *
604 : * In dependence to the obtained type, an appropriate parsing
605 : * method is called ("addEdge" if an edge encounters, f.e.).
606 : *
607 : * @param[in] element ID of the currently opened element
608 : * @param[in] attrs Attributes within the currently opened element
609 : * @exception ProcessError If something fails
610 : * @see GenericSAXHandler::myStartElement
611 : */
612 : void myStartElement(int element, const SUMOSAXAttributes& attrs);
613 :
614 : /**
615 : * @brief Callback method for characters to implement by derived classes
616 : *
617 : * Called by "endElement" (see there).
618 : * @param[in] element The opened element, given as a int
619 : * @param[in] chars The complete embedded character string
620 : * @exceptions ProcessError These method may throw a ProcessError if something fails
621 : */
622 : void myCharacters(int element, const std::string& chars);
623 :
624 :
625 : /** @brief Called when a closing tag occurs
626 : *
627 : * @param[in] element ID of the currently opened element
628 : * @exception ProcessError If something fails
629 : * @see GenericSAXHandler::myEndElement
630 : */
631 : void myEndElement(int element);
632 : //@}
633 :
634 : std::map<std::string, OpenDriveSignal>& getSignals() {
635 : return mySignals;
636 : }
637 :
638 : std::map<std::string, OpenDriveController>& getControllers() {
639 : return myControllers;
640 : }
641 :
642 : std::map<std::string, std::vector<std::string>>& getJunctions2Controllers() {
643 : return myJunctions2Controllers;
644 : }
645 :
646 0 : const OpenDriveController& getController(std::string signalID) {
647 0 : if (mySignals.find(signalID) != mySignals.end() && myControllers.find(mySignals[signalID].controller) != myControllers.end()) {
648 0 : return myControllers[mySignals[signalID].controller];
649 : }
650 : return myDummyController;
651 : }
652 :
653 0 : int getTLIndexForController(std::string controllerID) {
654 : // sort them by their id
655 0 : std::string junctionID = myControllers[controllerID].junction;
656 : std::vector<std::string> junctionControllers;
657 0 : for (auto& it : myControllers) {
658 0 : if (it.second.junction == junctionID) {
659 0 : junctionControllers.push_back(it.first);
660 : }
661 : }
662 0 : std::sort(junctionControllers.begin(), junctionControllers.end());
663 0 : auto it = std::find(junctionControllers.begin(), junctionControllers.end(), controllerID);
664 0 : return (int)(it - junctionControllers.begin());
665 0 : }
666 :
667 :
668 : private:
669 : void addLink(LinkType lt, const std::string& elementType, const std::string& elementID,
670 : const std::string& contactPoint);
671 : void addGeometryShape(GeometryType type, const std::vector<double>& vals);
672 : static void setEdgeLinks2(OpenDriveEdge& e, const std::map<std::string, OpenDriveEdge*>& edges);
673 : static void buildConnectionsToOuter(const Connection& c,
674 : const std::map<std::string, OpenDriveEdge*>& innerEdges,
675 : const std::map<std::string, OpenDriveEdge*>& edges,
676 : const NBTypeCont& tc,
677 : std::vector<Connection>& into, std::set<Connection>& seen);
678 : static bool laneSectionsConnected(OpenDriveEdge* edge, int in, int out);
679 : friend bool operator<(const Connection& c1, const Connection& c2);
680 : static std::string reversedEdgeID(const std::string& id);
681 : const NBTypeCont& myTypeContainer;
682 : OpenDriveEdge myCurrentEdge;
683 : OpenDriveController myCurrentController;
684 :
685 : std::map<std::string, OpenDriveEdge*>& myEdges;
686 : std::vector<int> myElementStack;
687 : OpenDriveXMLTag myCurrentLaneDirection;
688 : std::string myCurrentJunctionID;
689 : std::string myCurrentIncomingRoad;
690 : std::string myCurrentConnectingRoad;
691 : ContactPoint myCurrentContactPoint;
692 : bool myConnectionWasEmpty;
693 : std::map<std::string, OpenDriveSignal> mySignals;
694 : std::map<std::string, OpenDriveController> myControllers;
695 : std::map<std::string, std::vector<std::string>> myJunctions2Controllers;
696 : Position myOffset;
697 : bool myUseCurrentNode;
698 :
699 : static bool myImportAllTypes;
700 : static bool myImportWidths;
701 : static double myMinWidth;
702 : static bool myImportInternalShapes;
703 : static bool myIgnoreMisplacedSignals;
704 : static OpenDriveController myDummyController;
705 :
706 :
707 : protected:
708 : /** @brief Builds a node or returns the already built
709 : *
710 : * If the node is already known, it is returned. Otherwise, the
711 : * node is built. If the newly built node can not be added to
712 : * the container, a ProcessError is thrown.
713 : * Otherwise this node is returned.
714 : *
715 : * @param[in] id The id of the node to build/get
716 : * @param[in, changed] pos The position of the node to build/get
717 : * @param[filled] nc The node container to retrieve/add the node to
718 : * @return The retrieved/built node
719 : * @exception ProcessError If the node could not be built/retrieved
720 : */
721 : static NBNode* getOrBuildNode(const std::string& id, const Position& pos, NBNodeCont& nc);
722 :
723 :
724 : static PositionVector geomFromLine(const OpenDriveEdge& e, const OpenDriveGeometry& g, double resolution);
725 : static PositionVector geomFromSpiral(const OpenDriveEdge& e, const OpenDriveGeometry& g, double resolution);
726 : static PositionVector geomFromArc(const OpenDriveEdge& e, const OpenDriveGeometry& g, double resolution);
727 : static PositionVector geomFromPoly(const OpenDriveEdge& e, const OpenDriveGeometry& g, double resolution);
728 : static PositionVector geomFromParamPoly(const OpenDriveEdge& e, const OpenDriveGeometry& g, double resolution);
729 : static Position calculateStraightEndPoint(double hdg, double length, const Position& start);
730 : static void calculateCurveCenter(double* ad_x, double* ad_y, double ad_radius, double ad_hdg);
731 : static void calcPointOnCurve(double* ad_x, double* ad_y, double ad_centerX, double ad_centerY,
732 : double ad_r, double ad_length);
733 :
734 :
735 : /** @brief Computes a polygon representation of each edge's geometry
736 : * @param[in] edges The edges which geometries shall be converted
737 : */
738 : static void computeShapes(std::map<std::string, OpenDriveEdge*>& edges);
739 :
740 : static bool hasNonLinearElevation(const OpenDriveEdge& e);
741 :
742 : /// transform Poly3 into a list of offsets, adding intermediate points to geom if needed
743 : static std::vector<double> discretizeOffsets(PositionVector& geom, const std::vector<OpenDriveLaneOffset>& offsets, const std::string& id);
744 :
745 : static void addOffsets(bool left, PositionVector& geom, const std::vector<OpenDriveLaneOffset>& offsets, const std::string& id, std::vector<double>& result);
746 :
747 : /** @brief Rechecks lane sections of the given edges
748 : *
749 : *
750 : * @param[in] edges The edges which lane sections shall be reviewed
751 : */
752 : static void revisitLaneSections(const NBTypeCont& tc, std::map<std::string, OpenDriveEdge*>& edges);
753 :
754 : static void setNodeSecure(NBNodeCont& nc, OpenDriveEdge& e,
755 : const std::string& nodeID, NIImporter_OpenDrive::LinkType lt, std::vector<NodeSet>& joinedNodeIDs);
756 :
757 : static NBTrafficLightDefinition* getTLSSecure(NBEdge* inEdge, /*const NBEdge::Connection& conn,*/ NBNetBuilder& nb);
758 :
759 :
760 : static std::pair<NBEdge*, NBEdge*> retrieveSignalEdges(NBNetBuilder& nb, const std::string& fromID, const std::string& toID, int signalMinLane);
761 :
762 : static void splitMinWidths(OpenDriveEdge* e, const NBTypeCont& tc, double minDist);
763 :
764 : static void findWidthSplit(const NBTypeCont& tc, std::vector<OpenDriveLane>& lanes,
765 : int section, double sectionStart, double sectionEnd,
766 : std::vector<double>& splitPositions);
767 :
768 : static void sanitizeWidths(OpenDriveEdge* e);
769 : static void sanitizeWidths(std::vector<OpenDriveLane>& lanes, double length);
770 :
771 : static void setStraightConnections(std::vector<OpenDriveLane>& lanes);
772 : static void recomputeWidths(OpenDriveLaneSection& sec, double start, double end, double sectionStart, double sectionEnd);
773 : static void recomputeWidths(std::vector<OpenDriveLane>& lanes, double start, double end, double sectionStart, double sectionEnd);
774 : static void setLaneAttributes(const OpenDriveEdge* e, NBEdge::Lane& sumoLane, const OpenDriveLane& odLane, bool saveOrigIDs, const NBTypeCont& tc);
775 : static void writeRoadObjects(const OpenDriveEdge* e);
776 :
777 : /// The names of openDrive-XML elements (for passing to GenericSAXHandler)
778 : static SequentialStringBijection::Entry openDriveTags[];
779 :
780 : /// The names of openDrive-XML attributes (for passing to GenericSAXHandler)
781 : static SequentialStringBijection::Entry openDriveAttrs[];
782 :
783 : class LaneSorter {
784 : public:
785 : /// constructor
786 : explicit LaneSorter() {}
787 :
788 : /// comparing operation
789 : int operator()(const OpenDriveLane& a, const OpenDriveLane& b) const {
790 : // sort from the reference line outwards (desceding order of sumo lane ids)
791 830 : return abs(a.id) < abs(b.id);
792 : }
793 :
794 : };
795 :
796 : };
|