示例#1
0
文件: roads.py 项目: t27/Scenic
 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)
示例#2
0
文件: workspace.py 项目: t27/Scenic
    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
示例#3
0
 def union(self, other, triedReversed=False, buf=0):
     poly = toPolygon(other)
     if not poly:
         return super().union(other, triedReversed)
     union = polygonUnion((self.polygons, poly), buf=buf)
     orientation = VectorField.forUnionOf((self, other))
     return PolygonalRegion(polygon=union, orientation=orientation)
示例#4
0
文件: interface.py 项目: yuul/Scenic
	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)
示例#5
0
 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
示例#6
0
文件: interface.py 项目: yuul/Scenic
	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)
示例#7
0
 def unionAll(regions, buf=0):
     regs, polys = [], []
     for reg in regions:
         if reg != nowhere:
             regs.append(reg)
             polys.append(toPolygon(reg))
     if not polys:
         return nowhere
     if any(not poly for poly in polys):
         raise RuntimeError(f'cannot take union of regions {regions}')
     union = polygonUnion(polys, buf=buf)
     orientation = VectorField.forUnionOf(regs)
     return PolygonalRegion(polygon=union, orientation=orientation)
示例#8
0
    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)
示例#9
0
 def roadDirection(self):
     return VectorField('roadDirection', self.roadHeadingAt)
示例#10
0
文件: roads.py 项目: t27/Scenic
class LinearElement(NetworkElement):
    """LinearElement()

    A part of a road network with (mostly) linear 1- or 2-way flow.

    Includes roads, lane groups, lanes, sidewalks, and pedestrian crossings,
    but not intersections.

    LinearElements have a direction, namely from the first point on their centerline
    to the last point. This is called 'forward', even for 2-way roads. The 'left' and
    'right' edges are interpreted with respect to this direction.

    The left/right edges are oriented along the direction of traffic near them; so
    for 2-way roads they will point opposite directions.
    """

    # Geometric info (on top of the overall polygon from PolygonalRegion)
    centerline: PolylineRegion
    leftEdge: PolylineRegion
    rightEdge: PolylineRegion

    # Links to next/previous element
    _successor: Union[NetworkElement, None] = None   # going forward
    _predecessor: Union[NetworkElement, None] = None # going backward

    @property
    def successor(self):
        return _rejectIfNonexistent(self._successor, 'successor')

    @property
    def predecessor(self):
        return _rejectIfNonexistent(self._predecessor, 'predecessor')

    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 _defaultHeadingAt(self, point):
        """Default orientation for this LinearElement.

        In general, we align along the nearest segment of the centerline.
        For roads, lane groups, etc., we align along the orientation of the
        lane containing the point.

        :meta private:
        """
        point = _toVector(point)
        start, end = self.centerline.nearestSegmentTo(point)
        return start.angleTo(end)

    @distributionFunction
    def flowFrom(self, point: Vectorlike, distance: float,
                 steps: Union[int, None] = None,
                 stepSize: float = 5) -> Vector:
        """Advance a point along this element by a given distance.

        Equivalent to ``follow element.orientation from point for distance``, but
        possibly more accurate. The default implementation uses the forward
        Euler approximation with a step size of 5 meters; subclasses may ignore
        the **steps** and **stepSize** parameters if they can compute the flow
        exactly.

        Arguments:
            point: point to start from.
            distance: distance to travel.
            steps: number of steps to take, or :obj:`None` to compute the
                number of steps based on the distance (default :obj:`None`).
            stepSize: length used to compute how many steps to take, if **steps** is not
                specified (default 5 meters).
        """
        return self.orientation.followFrom(_toVector(point), distance,
                                           steps=steps, stepSize=stepSize)