def phase1n3(diffusion_coeff, breed_coeff, z, delta, slope, excld, slope_weights, sng, sdc): TimerUtility.start_timer("spr_phase1n3") diffusion_value = Spread.calculate_diffusion_value(diffusion_coeff) nrows = IGrid.nrows ncols = IGrid.ncols for k in range(1 + int(diffusion_value)): # get a random row and col index i = Random.get_int(0, nrows - 1) j = Random.get_int(0, ncols - 1) # check if it is an interior point if 0 < i < nrows - 1 and 0 < j < ncols - 1: success, sng = Spread.urbanize(i, j, z, delta, slope, excld, slope_weights, UGMDefines.PHASE1G, sng) if success and Random.get_int(0, 100) < breed_coeff: count = 0 max_tries = 8 for tries in range(max_tries): urbanized, sdc, i_neigh, j_neigh = Spread.urbanize_neighbor( i, j, z, delta, slope, excld, slope_weights, UGMDefines.PHASE3G, sdc) if urbanized: count += 1 if count == UGMDefines.MIN_NGHBR_TO_SPREAD: break TimerUtility.stop_timer('spr_phase1n3') return sng, sdc
def get_rand_landuse_offset(): nrows = IGrid.nrows ncols = IGrid.ncols i_center = Random.get_int(0, nrows - 1) j_center = Random.get_int(0, ncols - 1) return int(i_center * ncols + j_center), i_center, j_center
def phase4(spread_coeff, z, excld, delta, slope, slope_weights, og): TimerUtility.start_timer('spr_phase4') nrows = IGrid.nrows ncols = IGrid.ncols neighbor_options = [(-1, -1), (0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1)] # Loop over the interior pixels looking for urban from which to perform organic growth for row in range(1, nrows - 1): for col in range(1, ncols - 1): offset = row * ncols + col # Is this an urban pixel and do we pass the random spread coefficient test? if z[offset] > 0 and Random.get_int(0, 100) < spread_coeff: # Examine the eight cell neighbors # Spread at random if at least 2 are urban # Pixel itself must be urban (3) urb_count = Spread.count_neighbor(z, row, col) if 2 <= urb_count < 8: x_neigh, y_neigh = Random.get_element(neighbor_options) row_neighbor = row + x_neigh col_neighbor = col + y_neigh success, og = Spread.urbanize(row_neighbor, col_neighbor, z, delta, slope, excld, slope_weights, UGMDefines.PHASE4G, og) TimerUtility.stop_timer('spr_phase4') return og
def get_neighbor(row, col): neighbor_options = [(-1, -1), (0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1)] idx = Random.get_int(0, 7) idx_x, idx_y = neighbor_options[idx] neigh_row = row + idx_x neigh_col = col + idx_y return idx, int(neigh_row), int(neigh_col)
def get_valid_neighbor(row, col): nrows = IGrid.nrows ncols = IGrid.ncols neighbor_options = [(-1, -1), (0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1)] idx = Random.get_int(0, 7) valid = False neigh_row = 0 neigh_col = 0 while not valid: idx_x, idx_y = neighbor_options[idx] neigh_row = row + idx_x neigh_col = col + idx_y if 0 <= neigh_row < nrows and 0 <= neigh_col < ncols: valid = True else: # The neighbor chosen isn't valid, go to next index in neighbor list and try again idx = (idx + 1) % 8 return neigh_row, neigh_col
def urbanize(row, col, z, delta, slope, excld, slope_weights, pixel_val, stat): nrows = IGrid.nrows ncols = IGrid.ncols offset = row * ncols + col flag = False if z[offset] == 0: if delta[offset] == 0: if Random.get_float() > slope_weights[slope[offset]]: if excld[offset] < Random.get_int(0, 99): flag = True delta[offset] = pixel_val stat += 1 else: Stats.increment_excluded_failure() else: Stats.increment_slope_failure() else: Stats.increment_delta_failure() else: Stats.increment_z_failure() return flag, stat
def phase1(drive, urban_land, slope, deltatron, landuse_classes, class_indices, new_indices, class_slope, ftransition): TimerUtility.start_timer('delta_phase1') nrows = IGrid.nrows ncols = IGrid.ncols phase1_land = [] # Copy input land grid into output land grid for urban in urban_land: phase1_land.append(urban) # Try to make Transitions for tries in range(drive): # Select a transition pixel to e center of spreading cluster offset, i_center, j_center = Deltatron.get_rand_landuse_offset() index = new_indices[urban_land[offset]] while not landuse_classes[index].trans: offset, i_center, j_center = Deltatron.get_rand_landuse_offset( ) index = new_indices[urban_land[offset]] # Randomly choose new landuse number new_landuse = Deltatron.get_new_landuse(class_indices, landuse_classes, slope[offset], class_slope) # Test transition probability for new cluster new_i = new_indices[urban_land[offset]] new_j = new_indices[new_landuse] trans_offset = new_i * LandClass.get_num_landclasses() + new_j if Random.get_float() < ftransition[trans_offset]: # Transition the center pixel phase1_land[offset] = new_landuse deltatron[offset] = 1 # Try building up cluster around this center pixel i = i_center j = j_center for regions in range(UGMDefines.REGION_SIZE): # Occasionally Reset to center of cluster random_int = Random.get_int(0, 7) if random_int == 7: i = i_center j = j_center # Get a neighbor i, j = Utilities.get_neighbor(i, j) if 0 <= i < nrows and 0 <= j < ncols: # Test new pixel against transition probability offset = i * ncols + j # print(f"{len(urban_land)} | {i} {j} -> {offset}") urban_index = urban_land[offset] new_i = new_indices[urban_index] new_j = new_indices[new_landuse] trans_offset = new_i * LandClass.get_num_landclasses( ) + new_j if Random.get_float() < ftransition[trans_offset]: # If the immediate pixel is allowed to transition, then change it index = new_indices[urban_land[offset]] if landuse_classes[index].trans: phase1_land[offset] = new_landuse deltatron[offset] = 1 # Try to transition a neighboring pixel i, j = Utilities.get_neighbor(i, j) if 0 <= i < nrows and 0 <= j < ncols: offset = i * ncols + j index = new_indices[urban_land[offset]] if landuse_classes[index].trans: phase1_land[offset] = new_landuse deltatron[offset] = 1 TimerUtility.stop_timer('delta_phase1') return phase1_land
def phase2(urban_land, phase1_land, deltatron, landuse_classes, new_indices, ftransition): TimerUtility.start_timer('delta_phase2') nrows = IGrid.nrows ncols = IGrid.ncols phase2_land = [] # Copy current land to phase2_land for pixel in phase1_land: phase2_land.append(pixel) # For each interior point for i in range(1, nrows - 1): for j in range(1, ncols - 1): offset = i * ncols + j index = new_indices[phase1_land[offset]] if landuse_classes[index].trans and deltatron[offset] == 0: """ I,J is a Transitional Pixel which was not transitioned within the last min_years_between_transitions years; count its neighbors which have transitioned in previous year (IE Deltatron == 2) """ deltatron_neighbors = Deltatron.count_neighbor( deltatron, i, j) random_int = 1 + Random.get_int(0, 1) if deltatron_neighbors >= random_int: max_tries = 16 for tries in range(max_tries): i_neigh, j_neigh = Utilities.get_neighbor(i, j) offset_neigh = i_neigh * ncols + j_neigh index = new_indices[phase1_land[offset_neigh]] if deltatron[offset_neigh] == 2 and landuse_classes[ index]: trans_i = new_indices[phase2_land[offset]] trans_j = new_indices[urban_land[offset_neigh]] offset_trans = trans_i * LandClass.get_num_landclasses( ) + trans_j if Random.get_float( ) < ftransition[offset_trans]: phase2_land[offset] = urban_land[ offset_neigh] deltatron[offset] = 1 break if Scenario.get_scen_value('view_deltatron_aging'): if IGrid.using_gif: filename = f"{Scenario.get_scen_value('output_dir')}deltatron_{Processing.get_current_run()}_" \ f"{Processing.get_current_monte()}_{Processing.get_current_year()}.gif" else: filename = f"{Scenario.get_scen_value('output_dir')}deltatron_{Processing.get_current_run()}_" \ f"{Processing.get_current_monte()}_{Processing.get_current_year()}.tif" date = f"{Processing.get_current_year()}" ImageIO.write_gif(deltatron, Color.get_deltatron_table(), filename, date, nrows, ncols) # Age the Deltatrons for i in range(nrows * ncols): if deltatron[i] > 0: deltatron[i] += 1 # Kill old deltatrons Utilities.condition_gt_gif(deltatron, UGMDefines.MIN_YEARS_BETWEEN_TRANSITIONS, deltatron, 0) TimerUtility.stop_timer("delta_phase2") return phase2_land