def build_exclusions(): """ Build exclusion file for the WETO rent map.""" # Using the 'core exclusions raster' that antyhony put together. excl = xr.open_rasterio(EXL_PATH, chunks=CHUNKS) roads = xr.open_rasterio(ROAD_PATH, chunks=CHUNKS) conus = xr.open_rasterio(CONUS_PATH, chunks=CHUNKS) rails = xr.open_rasterio(RAIL_PATH, chunks=CHUNKS) # Different na values every time :/ roadsna = roads.attrs["nodatavals"][0] conusna = conus.attrs["nodatavals"][0] railsna = rails.attrs["nodatavals"][0] # Get just the data arrays excl = excl[0].data roads = roads[0].data conus = conus[0].data rails = rails[0].data # Set nodata values to 0 excl[da.isnan(excl)] = 0 roads[roads == roadsna] = 0 conus[conus == conusna] = 0 rails[rails == railsna] = 0 # We need to reverse the original exclusions excl = (excl - 1) * -1 # Combine roads excl = da.stack([excl, roads, rails], axis=0).max(axis=0) # And let's make exclusion values 9999 since 1 will be a code excl[excl == 1] = 9999 # And cut out just CONUS for mapping excl = excl * conus # Compute print("Combining exclusion layers...") with Client(): excl = excl.compute() # save to raster print("Saving to 90 meter reV grid...") to_raster(excl, DP.join("rasters", "rent_exclusions.tif"), template=EXL_PATH, compress="deflate") # warp to acre grid in north american albers equal area conic print("Warping to acre grid...") res = 63.614907234075254 warp(DP.join("rasters", "rent_exclusions.tif"), DP.join("rasters", "albers", "acre", "rent_exclusions.tif"), xRes=res, yRes=res, overwrite=True) print("Done.")
def conus_mask(): if not os.path.exists(DPM.join("conus.tif")): print("Creating CONUS mask...") template = DP.join("rasters/albers/acre/nlcd.tif") conus = xr.open_rasterio(template, chunks=CHUNKS)[0].data conus = conus.astype("float32") conus[conus == 0.] = np.nan conus = (conus * 0) + 1 with Client(): conus = conus.compute() to_raster(conus, DPM.join("conus.tif"), PROJ, GEOM, dtype="float32")
def main(): # Get lookup table with all of the codes lookup = pd.read_csv(DP.join("tables", "conus_cbe_lookup.csv")) lookup["category"] = lookup.apply(categorize, axis=1) # Get all codes for each category cat_codes = {} for cat in CATEGORIES.keys(): code_vals = lookup["code"][lookup["category"] == cat].values cat_codes[cat] = code_vals # Open the rasters code_path = DP.join("rasters", "albers", "acre", "cost_codes.tif") cost_path = DP.join("rasters", "albers", "acre", "rent_map.tif") template = rasterio.open(code_path) codes = xr.open_rasterio(code_path, chunks=CHUNKS)[0].data costs = xr.open_rasterio(cost_path, chunks=CHUNKS)[0].data new_costs = costs.copy() new_codes = codes.copy() # Okay, change all of the values for cat, code_vals in cat_codes.items(): minc = np.nanmin(code_vals) maxc = np.nanmax(code_vals) # new_costs[(codes >= minc) & (codes <= maxc) & (costs > 0)] = cat new_codes[(codes >= minc) & (codes <= maxc)] = cat # Now compute the results with Client(): # new_costs = new_costs.compute() new_codes = new_codes.compute() # Save proj = template.crs.to_wkt() geom = template.transform.to_gdal() new_cost_path = DP.join("rasters", "albers", "acre", "cost_cats.tif") new_code_path = DP.join("rasters", "albers", "acre", "code_cats.tif") to_raster(new_costs, new_cost_path, proj, geom, dtype="int16", compress="LZW") to_raster(new_codes, new_code_path, proj, geom, dtype="int16", compress="LZW")
def composite(masked_paths): # Too much at once, read the precomputd masked layers from file excl_path = DP.join("rasters/albers/acre/rent_exclusions.tif") excl = xr.open_rasterio(excl_path, chunks=CHUNKS)[0].data mblm = xr.open_rasterio(masked_paths["blm"], chunks=CHUNKS)[0].data mtribes = xr.open_rasterio(masked_paths["tribes"], chunks=CHUNKS)[0].data mstate = xr.open_rasterio(masked_paths["state"], chunks=CHUNKS)[0].data mnlcd = xr.open_rasterio(masked_paths["nlcd"], chunks=CHUNKS)[0].data mconus = xr.open_rasterio(DPM.join("conus.tif"), chunks=CHUNKS)[0].data print("Merging layers ...") with Client(): layers = [excl, mblm, mtribes, mstate, mnlcd] composite_layer = da.stack(layers, axis=0).max(axis=0) composite_layer = composite_layer * mconus final = composite_layer.compute() # Save to file save = DP.join("rasters/albers/acre/cost_codes.tif") print("Saving file to " + save + " ...") to_raster(final, save, PROJ, GEOM)
def build_masks(): # Pull paths out paths = code_paths() nlcd_path = paths["nlcd_path"] blm_path = paths["blm_path"] tribal_path = paths["tribal_path"] state_path = paths["state_path"] excl_path = paths["excl_path"] # Get each array, remove band dimension nlcd = xr.open_rasterio(nlcd_path, chunks=CHUNKS)[0].data blm = xr.open_rasterio(blm_path, chunks=CHUNKS)[0].data tribes = xr.open_rasterio(tribal_path, chunks=CHUNKS)[0].data state = xr.open_rasterio(state_path, chunks=CHUNKS)[0].data excl = xr.open_rasterio(excl_path, chunks=CHUNKS)[0].data # I need to fix this...nlcd's shape is off by one cell if nlcd.shape != blm.shape: # One too many on top nlcd = nlcd[1:, :] # Now we need two on bottom x = da.from_array(np.zeros((1, nlcd.shape[1]))) nlcd = np.vstack((nlcd, x, x)) # and one extra on the side y = da.from_array(np.zeros((nlcd.shape[0], 1))) nlcd = np.hstack((nlcd, y)) with Client(): nlcd = nlcd.compute() to_raster(nlcd, nlcd_path, PROJ, GEOM) # Make a mask of each higher priority layer emask = gmask(excl) bmask = gmask(blm) tmask = gmask(tribes) smask = gmask(state) # Make four composite masks, the max will bring 1s to the front mask1 = da.stack([emask, bmask, tmask, smask], axis=0).max(axis=0) mask2 = da.stack([emask, bmask, tmask], axis=0).max(axis=0) mask3 = da.stack([emask, bmask], axis=0).max(axis=0) mask4 = emask # Now we actually want the inverse of these (1 -> 0 -> 0 ; 0 -> -1 -> 1) mask1 = (mask1 - 1) * -1 mask2 = (mask2 - 1) * -1 mask3 = (mask3 - 1) * -1 mask4 = (mask4 - 1) * -1 # We'll need to setup interim files, I can't handle the memory useage layers = {"nlcd": nlcd, "state": state, "tribes": tribes, "blm": blm} masked_paths = { "nlcd": DPM.join("nlcd.tif"), "state": DPM.join("state.tif"), "tribes": DPM.join("tribes.tif"), "blm": DPM.join("blm.tif") } masks = {"nlcd": mask1, "state": mask2, "tribes": mask3, "blm": mask4} # Loop through, the lowest priority layers are masked by the largest mask <---- This is obviously not the best way to do this print("Masking individual layers...") for key, layer in tqdm(layers.items(), position=0): layer_path = masked_paths[key] mask = masks[key] mlayer = layer * mask with Client(): masked_layer = mlayer.compute() to_raster(masked_layer, layer_path, PROJ, GEOM) del masked_layer return masked_paths