class StraightRoadBuilder: def __init__(self, country=CountryCodes.US): self.STD_ROADMARK = pyodrx.RoadMark(pyodrx.RoadMarkType.solid, 0.2, rule=pyodrx.MarkRule.no_passing) self.STD_START_CLOTH = 1 / 1000000000 self.country = country self.laneBuilder = LaneBuilder() self.configuration = Configuration() self.name = 'StraightRoadBuilder' pass def createPVForLine(self, length): line1 = pyodrx.Line(length) # create planviews pv = extensions.ExtendedPlanview() pv.add_geometry(line1) return pv def createRandom(self, roadId, randomState=None, length=20, junction=-1, lane_offset=None, maxLanePerSide=2, minLanePerSide=0, turns=False, merges=False, medianType=None, medianWidth=3, skipEndpoint=None, force3Section=False): if randomState is not None: np.random.set_state(randomState) if lane_offset is None: lane_offset = self.configuration.get("default_lane_width") if maxLanePerSide < 1: raise Exception( f"{self.name}: createRandom: maxLanePerSide cannot be less than 1" ) laneRange = np.arange(minLanePerSide, maxLanePerSide + 1) n_lanes_left = np.random.choice(laneRange) n_lanes_right = np.random.choice(laneRange) if (n_lanes_left == 0) and (n_lanes_right == 0): return self.createRandom(roadId, randomState=randomState, length=length, junction=junction, lane_offset=lane_offset, maxLanePerSide=maxLanePerSide, minLanePerSide=minLanePerSide, turns=turns, merges=merges, medianType=medianType, medianWidth=3, skipEndpoint=skipEndpoint, force3Section=force3Section) numLeftTurnsOnLeft = 0 numRightTurnsOnRight = 0 numLeftMergeOnLeft = 0 numRightMergeOnRight = 0 numberOfLeftTurnLanesOnRight = 0 numberOfRightTurnLanesOnLeft = 0 mergeLaneOnTheOppositeSideForInternalTurn = np.random.choice( [True, False]) if turns: numLeftTurnsOnLeft = np.random.choice([0, 1]) numRightTurnsOnRight = np.random.choice([0, 1]) numberOfLeftTurnLanesOnRight = np.random.choice([0, 1]) numberOfRightTurnLanesOnLeft = np.random.choice([0, 1]) elif merges: numLeftMergeOnLeft = np.random.choice([0, 1]) numRightMergeOnRight = np.random.choice([0, 1]) if medianType is None: return self.create( roadId, n_lanes_left=n_lanes_left, n_lanes_right=n_lanes_right, length=length, junction=junction, lane_offset=lane_offset, laneSides=LaneSides.BOTH, numLeftTurnsOnLeft=numLeftTurnsOnLeft, numRightTurnsOnRight=numRightTurnsOnRight, numLeftMergeOnLeft=numLeftMergeOnLeft, numRightMergeOnRight=numRightMergeOnRight, numberOfLeftTurnLanesOnRight=numberOfLeftTurnLanesOnRight, numberOfRightTurnLanesOnLeft=numberOfRightTurnLanesOnLeft, mergeLaneOnTheOppositeSideForInternalTurn= mergeLaneOnTheOppositeSideForInternalTurn, force3Section=force3Section) else: return self.createWithMedianRestrictedLane( roadId, n_lanes_left=n_lanes_left, n_lanes_right=n_lanes_right, length=length, junction=junction, lane_offset=lane_offset, laneSides=LaneSides.BOTH, numLeftTurnsOnLeft=numLeftTurnsOnLeft, numRightTurnsOnRight=numRightTurnsOnRight, numLeftMergeOnLeft=numLeftMergeOnLeft, numRightMergeOnRight=numRightMergeOnRight, numberOfLeftTurnLanesOnRight=numberOfLeftTurnLanesOnRight, numberOfRightTurnLanesOnLeft=numberOfRightTurnLanesOnLeft, mergeLaneOnTheOppositeSideForInternalTurn= mergeLaneOnTheOppositeSideForInternalTurn, medianType=medianType, medianWidth=medianWidth, skipEndpoint=skipEndpoint) pass def create(self, roadId, n_lanes_left=1, n_lanes_right=1, length=20, junction=-1, lane_offset=3, laneSides=LaneSides.BOTH, numLeftTurnsOnLeft=0, numRightTurnsOnRight=0, numLeftMergeOnLeft=0, numRightMergeOnRight=0, numberOfLeftTurnLanesOnRight=0, numberOfRightTurnLanesOnLeft=0, mergeLaneOnTheOppositeSideForInternalTurn=True, force3Section=False): # create geometry pv = self.createPVForLine(length) # laneSections = self.laneBuilder.getStandardLanes(n_lanes, lane_offset, laneSides, # roadLength=length, # isLeftTurnLane=isLeftTurnLane, isRightTurnLane=isRightTurnLane, # isLeftMergeLane=isLeftMergeLane, isRightMergeLane=isRightMergeLane) singleSide = False if laneSides != LaneSides.BOTH: singleSide = True laneSections = self.laneBuilder.getLanes( n_lanes_left, n_lanes_right, lane_offset=lane_offset, singleSide=singleSide, roadLength=length, numLeftTurnsOnLeft=numLeftTurnsOnLeft, numRightTurnsOnRight=numRightTurnsOnRight, numLeftMergeOnLeft=numLeftMergeOnLeft, numRightMergeOnRight=numRightMergeOnRight, numberOfLeftTurnLanesOnRight=numberOfLeftTurnLanesOnRight, numberOfRightTurnLanesOnLeft=numberOfRightTurnLanesOnLeft, mergeLaneOnTheOppositeSideForInternalTurn= mergeLaneOnTheOppositeSideForInternalTurn, force3Section=force3Section) road = ExtendedRoad(roadId, pv, laneSections, road_type=junction) return road def createWithMedianRestrictedLane( self, roadId, n_lanes_left=1, n_lanes_right=1, length=20, junction=-1, lane_offset=3, laneSides=LaneSides.BOTH, numLeftTurnsOnLeft=0, numRightTurnsOnRight=0, numLeftMergeOnLeft=0, numRightMergeOnRight=0, numberOfLeftTurnLanesOnRight=0, numberOfRightTurnLanesOnLeft=0, mergeLaneOnTheOppositeSideForInternalTurn=True, medianType='partial', medianWidth=3, skipEndpoint=None): road = self.create( roadId, n_lanes_left=n_lanes_left, n_lanes_right=n_lanes_right, length=length, junction=junction, lane_offset=lane_offset, laneSides=laneSides, numLeftTurnsOnLeft=numLeftTurnsOnLeft, numRightTurnsOnRight=numRightTurnsOnRight, numLeftMergeOnLeft=numLeftMergeOnLeft, numRightMergeOnRight=numRightMergeOnRight, numberOfLeftTurnLanesOnRight=numberOfLeftTurnLanesOnRight, numberOfRightTurnLanesOnLeft=numberOfRightTurnLanesOnLeft, mergeLaneOnTheOppositeSideForInternalTurn= mergeLaneOnTheOppositeSideForInternalTurn, force3Section=True) if medianType == 'partial': if skipEndpoint is None: raise Exception( f"{self.name}: createWithMedianRestrictedLane skipEndpoint cannot be None for partial median lanes." ) self.laneBuilder.addMedianIslandsTo2Of3Sections( road, roadLength=length, skipEndpoint=skipEndpoint, width=medianWidth) else: self.laneBuilder.addMedianIslandsToAllSections(road, width=medianWidth) return road def createWithRightTurnLanesOnLeft( self, roadId, length=100, junction=-1, n_lanes=1, lane_offset=3, laneSides=LaneSides.BOTH, isLeftTurnLane=False, isRightTurnLane=False, isLeftMergeLane=False, isRightMergeLane=False, numberOfRightTurnLanesOnLeft=1, mergeLaneOnTheOppositeSideForInternalTurn=True): # create geometry pv = self.createPVForLine(length) laneSections = self.laneBuilder.getStandardLanesWithInternalTurns( n_lanes, lane_offset, laneSides, roadLength=length, isLeftTurnLane=isLeftTurnLane, isRightTurnLane=isRightTurnLane, isLeftMergeLane=isLeftMergeLane, isRightMergeLane=isRightMergeLane, numberOfRightTurnLanesOnLeft=numberOfRightTurnLanesOnLeft, mergeLaneOnTheOppositeSideForInternalTurn= mergeLaneOnTheOppositeSideForInternalTurn) road = ExtendedRoad(roadId, pv, laneSections, road_type=junction) return road def createWithLeftTurnLanesOnRight( self, roadId, length=100, junction=-1, n_lanes=1, lane_offset=3, laneSides=LaneSides.BOTH, isLeftTurnLane=False, isRightTurnLane=False, isLeftMergeLane=False, isRightMergeLane=False, numberOfLeftTurnLanesOnRight=1, mergeLaneOnTheOppositeSideForInternalTurn=True): """Will create numberOfLeftTurnLanesOnRight left turn lanes on the right side of the center line. Equal number of mergelanes will be created on the left side of the center lane, too. Args: roadId ([type]): [description] length (int, optional): [description]. Defaults to 100. junction (int, optional): [description]. Defaults to -1. n_lanes (int, optional): [description]. Defaults to 1. lane_offset (int, optional): [description]. Defaults to 3. laneSides ([type], optional): [description]. Defaults to LaneSides.BOTH. isLeftTurnLane (bool, optional): [description]. Defaults to False. isRightTurnLane (bool, optional): [description]. Defaults to False. isLeftMergeLane (bool, optional): [description]. Defaults to False. isRightMergeLane (bool, optional): [description]. Defaults to False. numberOfLeftTurnLanesOnRight (int, optional): [description]. Defaults to 1. Returns: [type]: [description] """ # create geometry pv = self.createPVForLine(length) laneSections = self.laneBuilder.getStandardLanesWithInternalTurns( n_lanes, lane_offset, laneSides, roadLength=length, isLeftTurnLane=isLeftTurnLane, isRightTurnLane=isRightTurnLane, isLeftMergeLane=isLeftMergeLane, isRightMergeLane=isRightMergeLane, numberOfLeftTurnLanesOnRight=numberOfLeftTurnLanesOnRight, mergeLaneOnTheOppositeSideForInternalTurn= mergeLaneOnTheOppositeSideForInternalTurn) road = ExtendedRoad(roadId, pv, laneSections, road_type=junction) return road def createWithDifferentLanes(self, roadId, length=100, junction=-1, n_lanes_left=1, n_lanes_right=1, lane_offset=3, force3Section=False): return self.create(roadId, n_lanes_left=n_lanes_left, n_lanes_right=n_lanes_right, length=length, junction=junction, lane_offset=lane_offset, force3Section=force3Section)
class test_LaneBuilder(unittest.TestCase): def setUp(self): self.configuration = Configuration() self.laneBuilder = LaneBuilder() def test_widths(self): roadLength = 10 #1 simple Lanes lanes = self.laneBuilder.getStandardLanes(1, 3) for laneSec in lanes.lanesections: widths = laneSec.widths(roadLength) assert widths[0] == 6 assert widths[1] == 6 #1 turn lanes lanes = self.laneBuilder.getStandardLanes(1, 3, roadLength=roadLength, isLeftTurnLane=True, isRightTurnLane=True) widths = lanes.lanesections[0].widths(roadLength, LaneOffset(s=0), LaneOffset(s=1)) print(widths) assert widths[0] == 6 assert widths[1] == 6 widths = lanes.lanesections[1].widths(roadLength, LaneOffset(s=1), LaneOffset(s=roadLength - 1)) print(widths) assert widths[0] == 6 assert widths[1] == 12 widths = lanes.lanesections[2].widths(roadLength, LaneOffset(s=roadLength - 1)) print(widths) assert widths[0] == 12 assert widths[1] == 12 #2 merge lanes lanes = self.laneBuilder.getStandardLanes(1, 3, roadLength=roadLength, isLeftMergeLane=True, isRightMergeLane=True) widths = lanes.lanesections[0].widths(roadLength, LaneOffset(s=0), LaneOffset(s=1)) print(widths) assert widths[0] == 12 assert widths[1] == 12 widths = lanes.lanesections[1].widths(roadLength, LaneOffset(s=1), LaneOffset(s=roadLength - 1)) print(widths) assert widths[0] == 12 assert widths[1] == 6 widths = lanes.lanesections[2].widths(roadLength, LaneOffset(s=roadLength - 1)) print(widths) assert widths[0] == 6 assert widths[1] == 6 #2 internal lanes lanes = self.laneBuilder.getStandardLanesWithInternalTurns( 1, 3, roadLength=roadLength, numberOfLeftTurnLanesOnRight=2) widths = lanes.lanesections[0].widths(roadLength, LaneOffset(s=0), LaneOffset(s=1)) print(widths) assert widths[0] == 12 assert widths[1] == 12 widths = lanes.lanesections[1].widths(roadLength, LaneOffset(s=1), LaneOffset(s=roadLength - 1)) print(widths) assert widths[0] == 12 assert widths[1] == 12 widths = lanes.lanesections[2].widths(roadLength, LaneOffset(s=roadLength - 1)) print(widths) assert widths[0] == 12 assert widths[1] == 12