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