@@ -26,42 +26,49 @@ class MapOdr(Map):
2626 proj_string : str | None = None
2727 proj_offset : ProjectionOffset | None = None
2828 projection : pyproj .CRS | None = None
29-
29+
3030 @classmethod
31- def from_file (cls , filename , topic = 'ground_truth_map' , is_odr_xml : bool = False , is_mcap : bool = False , step_size = 0.1 , skip_parse : bool = False ):
32- if Path (filename ).suffix in ['.xodr' , '.odr' ] or is_odr_xml :
31+ def from_file (
32+ cls ,
33+ filename ,
34+ topic = "ground_truth_map" ,
35+ is_odr_xml : bool = False ,
36+ is_mcap : bool = False ,
37+ step_size = 0.1 ,
38+ skip_parse : bool = False ,
39+ ):
40+ if Path (filename ).suffix in [".xodr" , ".odr" ] or is_odr_xml :
3341 with open (filename ) as f :
34- self = cls .create (odr_xml = f .read (), name = Path (filename ).stem , step_size = step_size , skip_parse = skip_parse )
42+ self = cls .create (
43+ odr_xml = f .read (), name = Path (filename ).stem , step_size = step_size , skip_parse = skip_parse
44+ )
3545 return self
36- elif Path (filename ).suffix in [' .mcap' ] or is_mcap :
46+ elif Path (filename ).suffix in [" .mcap" ] or is_mcap :
3747 map = next (iter (betterosi .read (filename , mcap_topics = [topic ], osi_message_type = betterosi .MapAsamOpenDrive )))
38- return cls .create (odr_xml = map .open_drive_xml_content , name = map .map_reference , step_size = step_size , skip_parse = skip_parse )
39-
48+ return cls .create (
49+ odr_xml = map .open_drive_xml_content , name = map .map_reference , step_size = step_size , skip_parse = skip_parse
50+ )
51+
4052 @classmethod
41- def create (cls , odr_xml , name , step_size = .1 , skip_parse : bool = False ):
42- self = cls (
43- odr_xml = odr_xml ,
44- name = name ,
45- lane_boundaries = {},
46- lanes = {},
47- step_size = step_size ,
48- _odr_object = None
49- )
53+ def create (cls , odr_xml , name , step_size = 0.1 , skip_parse : bool = False ):
54+ self = cls (odr_xml = odr_xml , name = name , lane_boundaries = {}, lanes = {}, step_size = step_size , _odr_object = None )
5055 if not skip_parse :
5156 self .parse ()
5257 return self
53-
58+
5459 def parse (self ):
5560 if self ._odr_object is not None :
56- return
61+ return
5762 xml = etree .fromstring (self .odr_xml .encode ("utf-8" ))
5863 self ._odr_object = parse_opendrive (xml )
5964 self .proj_string = self ._odr_object .header .geo_reference
6065 if self .proj_string is not None :
6166 try :
6267 self .projection = pyproj .CRS .from_proj4 (self .proj_string )
6368 except pyproj .exceptions .CRSError as e :
64- raise pyproj .exceptions .CRSError ('Povided ASAM OpenDRIVE XML does not contain a valid georeference!' ) from e
69+ raise pyproj .exceptions .CRSError (
70+ "Povided ASAM OpenDRIVE XML does not contain a valid georeference!"
71+ ) from e
6572 self .proj_offsets = self ._odr_object .header .offset
6673 self .roads = convert_opendrive (self ._odr_object , step_size = self .step_size )
6774 self .lane_boundaries = {}
@@ -71,71 +78,83 @@ def parse(self):
7178 self .lane_boundaries [(rid , bid )] = b
7279 for lid , l in r .lanes .items ():
7380 self .lanes [(rid , lid )] = l
74-
75- def to_file (self , filename : Path | None = None ):
81+
82+ def to_file (self , filename : Path | None = None ):
7683 if filename is None :
7784 p = Path (self .name )
7885 else :
7986 p = Path (filename )
8087 if p .is_dir ():
81- p = p / f' { self .name } '
82- if p .suffix == '' :
83- p = Path (str (p ) + ' .xodr' )
84- with open (p , 'w' ) as f :
88+ p = p / f" { self .name } "
89+ if p .suffix == "" :
90+ p = Path (str (p ) + " .xodr" )
91+ with open (p , "w" ) as f :
8592 f .write (self .odr_xml )
86- print (f' Extracted { p } ' )
87-
93+ print (f" Extracted { p } " )
94+
8895 def to_osi (self ):
8996 return betterosi .MapAsamOpenDrive (map_reference = self .name , open_drive_xml_content = self .odr_xml )
90-
97+
9198 def to_hdf (self , filename ):
9299 import tables
100+
93101 with tables .open_file (filename , mode = "a" ) as h5file :
94102 try :
95- gmap = h5file .get_node (' /map' )
103+ gmap = h5file .get_node (" /map" )
96104 except tables .NoSuchNodeError :
97- gmap = h5file .create_group ('/' , ' map' )
105+ gmap = h5file .create_group ("/" , " map" )
98106 atom = tables .StringAtom (itemsize = len (self .odr_xml ))
99107 ds = h5file .create_carray (gmap , "odr_xml" , atom , shape = (1 ,))
100- ds [0 ] = self .odr_xml .encode (' utf-8' )
101-
108+ ds [0 ] = self .odr_xml .encode (" utf-8" )
109+
102110 @classmethod
103111 def from_hdf (cls , filename ):
104112 import tables
113+
105114 with tables .open_file (filename , mode = "r" ) as h5file :
106- odr_xml = h5file .get_node (' /map' ).odr_xml [0 ].decode ()
115+ odr_xml = h5file .get_node (" /map" ).odr_xml [0 ].decode ()
107116 return cls .create (odr_xml , str (filename ))
108117
109-
110118 def plot (self , ax = None ):
111119 if ax is None :
112- _ , ax = plt .subplots (1 ,1 )
113-
120+ _ , ax = plt .subplots (1 , 1 )
121+
114122 for rid , r in self .roads .items ():
115- ax .plot (* r .centerline_points [:,1 :3 ].T , c = ' black' )
123+ ax .plot (* r .centerline_points [:, 1 :3 ].T , c = " black" )
116124 for lid , l in self .lanes .items ():
117- c = ' blue' if l .type == betterosi .LaneClassificationType .TYPE_UNKNOWN else ' green'
125+ c = " blue" if l .type == betterosi .LaneClassificationType .TYPE_UNKNOWN else " green"
118126 lb = self .lane_boundaries [l .left_boundary_id ]
119127 rb = self .lane_boundaries [l .right_boundary_id ]
120- ax .add_patch (PltPolygon (np .concatenate ([lb .polyline [:,:2 ], np .flip (rb .polyline [:,:2 ], axis = 0 )]), fc = c , alpha = 0.5 , ec = 'black' ))
128+ ax .add_patch (
129+ PltPolygon (
130+ np .concatenate ([lb .polyline [:, :2 ], np .flip (rb .polyline [:, :2 ], axis = 0 )]),
131+ fc = c ,
132+ alpha = 0.5 ,
133+ ec = "black" ,
134+ )
135+ )
121136 ax .autoscale ()
122137 ax .set_aspect (1 )
123138 return ax
124-
125139
126140 def setup_lanes_and_boundaries (self ):
127141 self .parse ()
128142 for lid , l in self .lanes .items ():
129143 l .idx = lid
130144 l .left_boundary = self .lane_boundaries [l .left_boundary_id ]
131145 l .right_boundary = self .lane_boundaries [l .right_boundary_id ]
132-
133- l .centerline = l .left_boundary .polyline + (np .diff (np .stack ([l .left_boundary .polyline , l .right_boundary .polyline ]),axis = 0 )/ 2 )[0 ,...]
134- #l.centerline = shapely.LineString(l.centerline)
135-
136- poly_points = np .concatenate ([l .left_boundary .polyline [:,:2 ], np .flip (l .right_boundary .polyline [:,:2 ], axis = 0 )])
146+
147+ l .centerline = (
148+ l .left_boundary .polyline
149+ + (np .diff (np .stack ([l .left_boundary .polyline , l .right_boundary .polyline ]), axis = 0 ) / 2 )[0 , ...]
150+ )
151+ # l.centerline = shapely.LineString(l.centerline)
152+
153+ poly_points = np .concatenate (
154+ [l .left_boundary .polyline [:, :2 ], np .flip (l .right_boundary .polyline [:, :2 ], axis = 0 )]
155+ )
137156 l .polygon = shapely .Polygon (poly_points )
138157 if not l .polygon .is_valid :
139158 l .polygon = shapely .convex_hull (l .polygon )
140- l .start_points = np .stack ([l .left_boundary .polyline [0 ,:2 ], l .right_boundary .polyline [0 ,:2 ]])
141- l .end_points = np .stack ([l .left_boundary .polyline [- 1 ,:2 ], l .right_boundary .polyline [- 1 ,:2 ]])
159+ l .start_points = np .stack ([l .left_boundary .polyline [0 , :2 ], l .right_boundary .polyline [0 , :2 ]])
160+ l .end_points = np .stack ([l .left_boundary .polyline [- 1 , :2 ], l .right_boundary .polyline [- 1 , :2 ]])
0 commit comments