def __init__(self, base_init, **kwargs): for k, v in kwargs.items(): if hasattr(self, k.upper()): setattr(self, k.upper(), v) else: raise ValueError("Invalid settings item: %s" % k) self.max_lane = len(base_init) self.codes = base_init self.base = [ find_base(i + 1, codes=base_init[i], mode=self.MODE) for i in range(self.max_lane) ] for i in range(1, self.MAX_UNDIVIDED + 1): self.base[i - 1].insert(0, BaseAsset(0, i)) # add centered one-way nC modules with n<max_undivided if self.ADD_LEFT: for i in range(1, 3): self.base[i - 1].insert(0, BaseAsset(-SW.LANE * i / 2, i)) self.built = False self.comp = [] self.triplex = [] self.shift = [] self.trans = [] self.ramp = [] self.twoway = []
def combine(express, local): n_median = (local.x0() - express.x1()) / SW.MEDIAN nl_comb = [x.nlanes for x in express.get_blocks() + local.get_blocks()] if int(n_median) == n_median and n_median > 0: return BaseAsset(express.x0(), *nl_comb, median=int(n_median)) else: raise ValueError("Invalid parallel combination!", express, local)
def find_base(nlane, codes=['5', '5P', '6P', '7P', '8P'], mode=DEFAULT_MODE): roads = [] lefts = [offset_x(k) - nlane * SW.LANE for k in codes] for x in lefts: v = BaseAsset(x, nlane) roads.append(v) return roads
def asset_from_blocks(block_start, block_end=None): if block_end: x0, n0, m0 = parse_blocks(block_start) x1, n1, m1 = parse_blocks(block_end) return Asset(x0, n0, x1, n1, medians=[m0, m1]) else: x, n, m = parse_blocks(block_start) return BaseAsset(x, *n, median=m)
def _find_asym(self): # asym (2n+1)DC for i in range(1, self.MAX_UNDIVIDED): l = BaseAsset(SW.MEDIAN, i) r = BaseAsset(-SW.MEDIAN, i + 1) self.twoway.append(TwoWayAsset(l, r)) # asym (n-1)Rn-nR for i in range(1, self.MAX_UNDIVIDED): l = BaseAsset(3 * SW.MEDIAN, i) r = BaseAsset(SW.MEDIAN, i + 1) self.twoway.append(TwoWayAsset(l, r)) # asym (n-1)Rn-(n+1)Rn for i in range(1, self.MAX_UNDIVIDED): l = BaseAsset(3 * SW.MEDIAN, i) r = BaseAsset(-SW.MEDIAN, i + 2) self.twoway.append(TwoWayAsset(l, r))
def get_packages(assets, variants): packages = {} for i in range(1, 5): packages['R%i' % i] = [] for i in range(1, 7): packages['M%i' % i] = [] packages['B'] = [] assets = deepcopy(assets) variants = deepcopy(variants) x_max = lambda a: max(a._blocks[0][-1].x_right, a._blocks[1][-1].x_right) for a in assets['base'] + assets['comp']: if a.x0() + a.x1() == 0: packages['R1' if a.nl() < 4 else 'R2'].append(a) elif a.nl() == 1 and 2.5 * SW.LANE <= a.x0() <= 4.5 * SW.LANE: packages['M1'].append(a) elif a.nblock() == 2 and a.nl() == 2 and a.x0() <= 4.5 * SW.LANE: packages['M1'].append(a) elif a.nblock() == 2 and 3 <= a.nl() <= 5 and a.x0() == 0.5 * SW.LANE: packages['M1'].append(a) elif a.x1() < 5.5 * SW.LANE: packages['M2'].append(a) elif a.x1() <= 6.5 * SW.LANE: packages['M4'].append(a) else: packages['M5'].append(a) for a in assets['shift']: if a.nl_min() == 2 and x_max(a) <= 6 * SW.LANE: packages['M1'].append(a) elif x_max(a) < 5.5 * SW.LANE: packages['M2'].append(a) elif x_max(a) <= 6.5 * SW.LANE: packages['M4'].append(a) else: packages['M5'].append(a) for a in assets['trans']: if BaseAsset(a.xleft[0], *a.nlanes[0]) in packages['M1'] \ and BaseAsset(a.xleft[1], *a.nlanes[1]) in packages['M1']: packages['M1'].append(a) elif x_max(a) < 5.5 * SW.LANE: packages['M2'].append(a) elif x_max(a) <= 6.5 * SW.LANE: packages['M4'].append(a) else: packages['M5'].append(a) anchors = ['2R4P', '3R', '4R', '5R'] anchors2 = ['1R31R4P', '2R1R3P', '2R2R4P', '3R1R4P', '3R2R5P'] for a in assets['ramp']: if a.nblock() < 5: if (str(a).split('=')[0] in anchors and str(a).split('=')[1] in anchors2) \ or (str(a).split('=')[1] in anchors and str(a).split('=')[0] in anchors2) \ or str(a) in ['3R2R5P=4R1R5P', '4R1R5P=3R2R5P']: packages['M1'].append(a) elif x_max(a) < 5.5 * SW.LANE: packages['M2'].append(a) elif x_max(a) <= 6.5 * SW.LANE: packages['M4'].append(a) else: packages['M5'].append(a) else: packages['M6'].append(a) for a in assets['twoway'] + variants['uturn'] + variants['brt']: if a.roadtype == 'b' and a.is_symmetric(): if a.is_undivided(): if a.nblock() == 4: if a.nl_min() <= 2: packages['R1'].append(a) elif a.nl_min() == 3: packages['R2'].append(a) else: packages['R3'].append(a) else: packages['B'].append(a) else: # a.nblock() == 4 for regular two-way, 8 for local-express if a.nblock() == 4: if a.get_dim()[0] <= 12 * SW.LANE: if a.nl_min() >= 2 and a.n_median_min() == 2: packages['R1'].append(a) else: packages['R2'].append(a) else: packages['R3'].append(a) else: if a.get_dim()[0] <= 12 * SW.LANE: if a.n_median_min( ) == 2 and a.right.nlanes[0][0] > a.right.nlanes[0][1]: packages['R1'].append(a) elif a.n_median_min() == 0: packages['B'].append(a) else: packages['R2'].append(a) else: packages['R3'].append(a) elif a.roadtype == 'b' and not a.is_symmetric(): if a.has_trafficlight(): packages['R4'].append(a) else: packages['M3'].append(a) else: if a.left.always_undivided() and a.right.always_undivided(): packages['M3'].append(a) elif str(a) in ['4DR5P=6DR5P', '4DR4P=6DR4P']: packages['M1'].append(a) elif max(a.get_dim()) < 11 * SW.LANE: packages['M2'].append(a) elif max(a.get_dim()) <= 13 * SW.LANE: packages['M4'].append(a) else: packages['M5'].append(a) return packages
def _find_twoway(self): for i in range(3, self.MAX_UNDIVIDED + 1): self.base[i - 1].insert(0, BaseAsset(-SW.LANE * i / 2, i)) # first resolve undivided base segments, # remove all but 1R0P undivided_base = [] for l in self.base: for i, r in enumerate(l.copy()[::-1]): if r.is_undivided(): if r.nl() > 1: l.pop(len(l) - i - 1) undivided_base.append(r) # remove all local-express undivided segments # we can always build them using two base segments for l in self.comp: ntot = len(l.copy()) for i, r in enumerate(l.copy()[::-1]): if r.is_undivided() and r.get_blocks()[0].nlanes > 1: l.pop(ntot - i - 1) for r in undivided_base: self.twoway.append(TwoWayAsset(r, r)) if self.ASYM_SLIPLANE: for r1, r2 in product(undivided_base, repeat=2): if r2.nl() - r1.nl() == 1: self.twoway.append(TwoWayAsset(r1, r2)) for r in flatten(self.base): # make base segments less than 1.5u median two-way # make other > 2 lanes also twoway: if r.x0() > 0 and (r.nl() > 1 or r.x0() <= self.MAX_TWOWAY_MEDIAN * SW.LANE): self.twoway.append(TwoWayAsset(r, r)) # make comp segments with more than 4 lanes two-way for r in flatten([[x for x in self.comp[2] if x.x0() == 0]] + self.comp[3:]): if 0 <= r.x0() <= self.MAX_TWOWAY_MEDIAN * SW.LANE and ( r.x0() == 0 or r.get_blocks()[0].nlanes > 1): self.twoway.append(TwoWayAsset(r, r)) # find all undivided interface segments # need to account for double counting undivided_interface = [] undivided_interface_sorted = [] for i in range(len(self.shift) - 1, -1, -1): if self.shift[i].is_undivided(): r = self.shift.pop(i) undivided_interface.append(r) if 0 <= r.xleft[0] < r.xleft[1]: undivided_interface_sorted.append(r) for i in range(len(self.trans) - 1, -1, -1): if self.trans[i].is_undivided(): r = self.trans.pop(i) undivided_interface.append(r) if min(r.xleft) >= 0 and r.ntot_start() < r.ntot_end(): undivided_interface_sorted.append(r) for i in range(len(self.ramp) - 1, -1, -1): if self.ramp[i].is_undivided(): r = self.ramp.pop(i) if self.ramp[i].nblock() < 5: undivided_interface.append(r) if min( r.xleft ) >= 0 and r not in undivided_interface_sorted and reverse( r) not in undivided_interface_sorted: undivided_interface_sorted.append(reverse(r)) for r in undivided_interface_sorted: self.twoway.append(TwoWayAsset(r, r)) # add 1R0P-associated left exist assets back for r in undivided_interface: if (str(r._blocks[0][0]) == '1R0P' and r.xleft[1] != 0)\ or (str(r._blocks[1][0]) == '1R0P' and r.xleft[0] != 0): if r.roadtype == 's': self.shift.append(r) elif r.roadtype == 't': self.trans.append(r) else: self.ramp.append(r) #print(undivided_interface, len(undivided_interface)) #print(undivided_interface_sorted) if self.ASYM_SLIPLANE: for r1, r2 in product(undivided_base, undivided_interface): if r2.always_undivided(): r_t = TwoWayAsset(r1, r2) if abs(r_t.asym()[0]) + abs( r_t.asym()[1]) <= 1 and r2.nblock() < 4: if sum(r_t.asym()) > 0: self.twoway.append(r_t) else: self.twoway.append(TwoWayAsset(r2, r1))