def __init__(self, path, n=20, tolerance=None): '''Initialize from OpenDRIVE file at @path, with @n points per lane section reference line.''' self.road_map = RoadMap(tolerance=tolerance) self.road_map.parse(path) self.road_map.calculate_geometry(n, calc_intersect=True) drivable_poly = self.road_map.drivable_region sidewalk_poly = self.road_map.sidewalk_region intersect_poly = self.road_map.intersection_region self.road_direction = VectorField('Road Direction', self.road_map.heading_at) self.drivable_region = regionFromShapelyObject( drivable_poly, orientation=self.road_direction) self.sidewalk_region = regionFromShapelyObject(sidewalk_poly) self.intersection_region = regionFromShapelyObject( intersect_poly, orientation=self.road_direction) super().__init__() # lane_sec_dict is dict of road id to list of dict of lane id to Region. self.lane_sec_dict = {} for id_ in self.road_map.roads: lane_dicts = [] for d in self.road_map.roads[id_].sec_lane_polys: lane_dicts.append({ i: regionFromShapelyObject(d[i], orientation=self.road_direction) for i in d.keys() }) self.lane_sec_dict[id_] = lane_dicts
def __attrs_post_init__(self): super().__attrs_post_init__() # Check that left and right edges lie inside the element. # (don't check centerline here since it can lie inside a median, for example) # (TODO reconsider the decision to have polygon only include drivable areas?) assert self.containsRegion(self.leftEdge, tolerance=0.5) assert self.containsRegion(self.rightEdge, tolerance=0.5) if self.orientation is None: self.orientation = VectorField(self.name, self._defaultHeadingAt)
def __init__(self, proj, data): super().__init__(proj, data) self.id = data['id'] self.direction = data['direction'] self.origin_lane = data['origin_lane']['lane_id'] medianPoints = localize(data['median'], proj) self.median = PolylineRegion(medianPoints) self.medianPoints = np.array(medianPoints) self.region.orientation = VectorField(f'Road{self.id}Direction', self.directionAt)
def __init__(self, points=None, polyline=None, orientation=True, name=None): if orientation is True: orientation = VectorField('Polyline', self.defaultOrientation) self.usingDefaultOrientation = True else: self.usingDefaultOrientation = False super().__init__(name, orientation=orientation) if points is not None: points = tuple(points) if len(points) < 2: raise RuntimeError( 'tried to create PolylineRegion with < 2 points') self.points = points self.lineString = shapely.geometry.LineString(points) elif polyline is not None: if isinstance(polyline, shapely.geometry.LineString): if len(polyline.coords) < 2: raise RuntimeError( 'tried to create PolylineRegion with <2-point LineString' ) elif isinstance(polyline, shapely.geometry.MultiLineString): if len(polyline) == 0: raise RuntimeError( 'tried to create PolylineRegion from empty MultiLineString' ) for line in polyline: assert len(line.coords) >= 2 else: raise RuntimeError( 'tried to create PolylineRegion from non-LineString') self.lineString = polyline self.points = None else: raise RuntimeError( 'must specify points or polyline for PolylineRegion') if not self.lineString.is_valid: raise RuntimeError('tried to create PolylineRegion with ' f'invalid LineString {self.lineString}') self.segments = self.segmentsOf(self.lineString) cumulativeLengths = [] total = 0 for p, q in self.segments: dx, dy = p[0] - q[0], p[1] - q[1] total += math.hypot(dx, dy) cumulativeLengths.append(total) self.cumulativeLengths = cumulativeLengths if self.points is None: pts = [] for p, q in self.segments: pts.append(p) pts.append(q) self.points = pts
def __init__(self, intersection): self.intersection = intersection drivablePoly = polygonUnion(gw.region.polygons for gw in intersection.vehicleGuideways) walkablePoly = polygonUnion(cw.region.polygons for cw in intersection.crosswalks) workspacePoly = polygonUnion((drivablePoly, walkablePoly)) self.roadDirection = VectorField('RoadDirection', intersection.directionAt) self.drivableRegion = PolygonalRegion(polygon=drivablePoly, orientation=self.roadDirection) self.workspaceRegion = PolygonalRegion(polygon=workspacePoly) super().__init__(self.workspaceRegion)
def __attrs_post_init__(self): proxy = weakref.proxy(self) for uid, elem in self.elements.items(): assert elem.uid == uid elem.network = proxy self.allRoads = self.roads + self.connectingRoads self.roadSections = tuple(sec for road in self.roads for sec in road.sections) self.laneSections = tuple(sec for lane in self.lanes for sec in lane.sections) if self.roadRegion is None: self.roadRegion = PolygonalRegion.unionAll(self.roads) if self.laneRegion is None: self.laneRegion = PolygonalRegion.unionAll(self.lanes) if self.intersectionRegion is None: self.intersectionRegion = PolygonalRegion.unionAll( self.intersections) if self.crossingRegion is None: self.crossingRegion = PolygonalRegion.unionAll(self.crossings) if self.sidewalkRegion is None: self.sidewalkRegion = PolygonalRegion.unionAll(self.sidewalks) if self.shoulderRegion is None: self.shoulderRegion = PolygonalRegion.unionAll(self.shoulders) if self.drivableRegion is None: self.drivableRegion = self.laneRegion.union( self.intersectionRegion) if self.walkableRegion is None: self.walkableRegion = self.sidewalkRegion.union( self.crossingRegion) if self.curbRegion is None: edges = [] for road in self.roads: # only include curbs of ordinary roads if road.forwardLanes: edges.append(road.forwardLanes.curb) if road.backwardLanes: edges.append(road.backwardLanes.curb) self.curbRegion = PolylineRegion.unionAll(edges) if self.roadDirection is None: # TODO replace with a PolygonalVectorField for better pruning self.roadDirection = VectorField('roadDirection', self._defaultRoadDirection)
def roadDirection(self): return VectorField('roadDirection', self.roadHeadingAt)