def process_map(lookupobj, csvfilename): """Produce a CSV file of areas per country from a dataset.""" shapefilename = 'data/ne_10m_admin_0_countries/ne_10m_admin_0_countries.shp' df = pd.DataFrame(columns=lookupobj.get_columns(), dtype=float) df.index.name = 'Country' shapefile = osgeo.ogr.Open(shapefilename) assert shapefile.GetLayerCount() == 1 layer = shapefile.GetLayerByIndex(0) for idx, feature in enumerate(layer): admin = admin_names.lookup(feature.GetField("ADMIN")) if admin is None: continue a3 = feature.GetField("SOV_A3") if admin not in df.index: df.loc[admin] = [0] * len(df.columns) print(f"Processing {admin:<41} #{a3}_{idx}") maskfilename = f"masks/{a3}_{idx}_{lookupobj.maskdim}_mask._tif" maskimg = osgeo.gdal.Open(maskfilename, osgeo.gdal.GA_ReadOnly) maskband = maskimg.GetRasterBand(1) x_siz = maskband.XSize y_siz = maskband.YSize x_blksiz, y_blksiz = maskband.GetBlockSize() for y in range(0, y_siz, y_blksiz): nrows = geoutil.blklim(coord=y, blksiz=y_blksiz, totsiz=y_siz) for x in range(0, x_siz, x_blksiz): ncols = geoutil.blklim(coord=x, blksiz=x_blksiz, totsiz=x_siz) if geoutil.is_sparse(band=maskband, x=x, y=y, ncols=ncols, nrows=nrows): # sparse hole in image, no data to process continue maskblock = maskband.ReadAsArray(x, y, ncols, nrows) km2block = geoutil.km2_block(nrows=nrows, ncols=ncols, y_off=y, img=maskimg) lookupobj.km2(x=x, y=y, ncols=ncols, nrows=nrows, maskblock=maskblock, km2block=km2block, df=df, admin=admin) outputfilename = os.path.join('results', csvfilename) df.sort_index(axis='index').to_csv(outputfilename, float_format='%.2f') return df
def produce_GeoTIFF(): """Produce a GeoTIFF file of Thermal Moisture Regime + Agro-Ecological Zone.""" kg_filename = 'data/Beck_KG_V1/Beck_KG_V1_present_0p0083.tif' lc_filename = 'data/copernicus/C3S-LC-L4-LCCS-Map-300m-P1Y-2018-v2.1.1.tif' sl_filename = 'data/ConsolidatedSlope.tif' wk_filename = 'data/FAO/workability_FAO_sq7_1km.tif' kg_img = osgeo.gdal.Open(kg_filename, osgeo.gdal.GA_ReadOnly) kg_band = kg_img.GetRasterBand(1) lc_img = osgeo.gdal.Open(lc_filename, osgeo.gdal.GA_ReadOnly) lc_band = lc_img.GetRasterBand(1) sl_img = osgeo.gdal.Open(sl_filename, osgeo.gdal.GA_ReadOnly) sl_band = {} for idx in range(1, 9): sl_band[idx] = sl_img.GetRasterBand(idx) wk_img = osgeo.gdal.Open(wk_filename, osgeo.gdal.GA_ReadOnly) wk_band = wk_img.GetRasterBand(1) aez_f = create_AEZ_GeoTIFF(ref_img=lc_img, filename='results/AEZ.tif') slope_f = create_slope_GeoTIFF(ref_img=lc_img, filename='results/Slope.tif') land_use_f = create_land_use_GeoTIFF(ref_img=lc_img, filename='results/LandUse.tif') soil_health_f = create_soil_health_GeoTIFF( ref_img=lc_img, filename='results/SoilHealth.tif') x_siz = lc_band.XSize y_siz = lc_band.YSize x_blksiz, y_blksiz = (768, 768) for y in range(0, y_siz, y_blksiz): print('.', end='', flush=True) nrows = geoutil.blklim(coord=y, blksiz=y_blksiz, totsiz=y_siz) for x in range(0, x_siz, x_blksiz): ncols = geoutil.blklim(coord=x, blksiz=x_blksiz, totsiz=x_siz) x3 = int(x / 3) y3 = int(y / 3) ncols3 = int(ncols / 3) nrows3 = int(nrows / 3) k = kg_band.ReadAsArray(x3, y3, ncols3, nrows3) kg_blk = np.repeat(np.repeat(k, 3, axis=1), 3, axis=0) regime = populate_tmr(kg_blk) sl_blk = {} for idx in range(1, 9): s = sl_band[idx].ReadAsArray(x3, y3, ncols3, nrows3) sl_blk[idx] = np.repeat(np.repeat(s, 3, axis=1), 3, axis=0) slope = populate_slope(sl_blk) plurality = {} plurality['steep'] = ((slope['steep'] >= slope['moderate']) & (slope['steep'] >= slope['minimal'])) plurality['moderate'] = ((slope['moderate'] > slope['steep']) & (slope['moderate'] >= slope['minimal'])) plurality['minimal'] = ((slope['minimal'] > slope['steep']) & (slope['minimal'] >= slope['moderate'])) slope = plurality lc_blk = lc_band.ReadAsArray(x, y, ncols, nrows) land_use = populate_land_use(lc_blk) k = wk_band.ReadAsArray(x3, y3, ncols3, nrows3) wk_blk = np.repeat(np.repeat(k, 3, axis=1), 3, axis=0) soil_health = populate_soil_health(wk_blk) outarray = np.full((nrows, ncols), C_TMR_BLNK) for tmr, color in tmr_state.items(): for aez in yield_AEZs(regime=regime, tmr=tmr, slope=slope, land_use=land_use, soil_health=soil_health): outarray[aez.astype(bool)] = color color += 1 aez_f.GetRasterBand(1).WriteArray(outarray, xoff=x, yoff=y) outarray = np.full((nrows, ncols), C_SLP_BLNK) outarray[slope['minimal'].astype(bool)] = C_SLP_MIN outarray[slope['moderate'].astype(bool)] = C_SLP_MOD outarray[slope['steep'].astype(bool)] = C_SLP_STP slope_f.GetRasterBand(1).WriteArray(outarray, xoff=x, yoff=y) outarray = np.full((nrows, ncols), C_LUS_BLNK) outarray[land_use['forest'].astype(bool)] = C_LUS_FRST outarray[land_use['cropland_rainfed'].astype(bool)] = C_LUS_CRRF outarray[land_use['cropland_irrigated'].astype(bool)] = C_LUS_CRIR outarray[land_use['grassland'].astype(bool)] = C_LUS_GRSS outarray[land_use['bare'].astype(bool)] = C_LUS_BARE outarray[land_use['urban'].astype(bool)] = C_LUS_URBN outarray[land_use['water'].astype(bool)] = C_LUS_WATR outarray[land_use['ice'].astype(bool)] = C_LUS_ICE land_use_f.GetRasterBand(1).WriteArray(outarray, xoff=x, yoff=y) outarray = np.full((nrows, ncols), C_SLP_BLNK) outarray[soil_health['prime'].astype(bool)] = C_SLH_GOOD outarray[soil_health['good'].astype(bool)] = C_SLH_MRGN outarray[soil_health['marginal'].astype(bool)] = C_SLH_POOR outarray[soil_health['barren'].astype(bool)] = C_SLH_BARE outarray[soil_health['water'].astype(bool)] = C_SLH_WATR soil_health_f.GetRasterBand(1).WriteArray(outarray, xoff=x, yoff=y) aez_f = None slope_f = None land_use_f = None soil_health_f = None
def produce_CSV(): """Produce a CSV file of Thermal Moisture Regime + Agro-Ecological Zone per country.""" columns = [] for tmr in tmr_state.keys(): columns.extend([f"{tmr}|AEZ{x}" for x in range(1, 30)]) df = pd.DataFrame(columns=columns, dtype='float') df.index.name = 'Country' countrycsvfilename = 'results/AEZ-by-country.csv' shapefilename = 'data/ne_10m_admin_0_countries/ne_10m_admin_0_countries.shp' kg_filename = 'data/Beck_KG_V1/Beck_KG_V1_present_0p0083.tif' lc_filename = 'data/copernicus/C3S-LC-L4-LCCS-Map-300m-P1Y-2018-v2.1.1.tif' sl_filename = 'data/ConsolidatedSlope.tif' wk_filename = 'data/FAO/workability_FAO_sq7_1km.tif' shapefile = osgeo.ogr.Open(shapefilename) assert shapefile.GetLayerCount() == 1 features = shapefile.GetLayerByIndex(0) kg_img = osgeo.gdal.Open(kg_filename, osgeo.gdal.GA_ReadOnly) kg_band = kg_img.GetRasterBand(1) lc_img = osgeo.gdal.Open(lc_filename, osgeo.gdal.GA_ReadOnly) lc_band = lc_img.GetRasterBand(1) sl_img = osgeo.gdal.Open(sl_filename, osgeo.gdal.GA_ReadOnly) sl_band = {} for idx in range(1, 9): sl_band[idx] = sl_img.GetRasterBand(idx) wk_img = osgeo.gdal.Open(wk_filename, osgeo.gdal.GA_ReadOnly) wk_band = wk_img.GetRasterBand(1) for idx, feature in enumerate(features): admin = admin_names.lookup(feature.GetField("ADMIN")) if admin is None: continue a3 = feature.GetField("SOV_A3") if admin not in df.index: df.loc[admin] = [0] * len(df.columns) print(f"Processing {admin:<41} #{a3}_{idx}") maskfilename = f"masks/{a3}_{idx}_1km_mask._tif" maskimg = osgeo.gdal.Open(maskfilename, osgeo.gdal.GA_ReadOnly) mask_band = maskimg.GetRasterBand(1) x_siz = mask_band.XSize y_siz = mask_band.YSize x_blksiz, y_blksiz = mask_band.GetBlockSize() for y in range(0, y_siz, y_blksiz): nrows = geoutil.blklim(coord=y, blksiz=y_blksiz, totsiz=y_siz) for x in range(0, x_siz, x_blksiz): ncols = geoutil.blklim(coord=x, blksiz=x_blksiz, totsiz=x_siz) if geoutil.is_sparse(band=mask_band, x=x, y=y, ncols=ncols, nrows=nrows): # sparse hole in image, no data to process continue mask_blk = mask_band.ReadAsArray(x, y, ncols, nrows) k = geoutil.km2_block(nrows=nrows, ncols=ncols, y_off=y, img=maskimg) k[np.logical_not(mask_blk)] = 0.0 km2_blk = (np.repeat(np.repeat(k, 3, axis=1), 3, axis=0)) / 9.0 k = kg_band.ReadAsArray(x, y, ncols, nrows) kg_blk = np.repeat(np.repeat(k, 3, axis=1), 3, axis=0) regime = populate_tmr(kg_blk) sl_blk = {} for idx in range(1, 9): s = sl_band[idx].ReadAsArray(x, y, ncols, nrows) sl_blk[idx] = np.repeat(np.repeat(s, 3, axis=1), 3, axis=0) slope = populate_slope(sl_blk) lc_blk = lc_band.ReadAsArray(3 * x, 3 * y, 3 * ncols, 3 * nrows) land_use = populate_land_use(lc_blk) w = wk_band.ReadAsArray(x, y, ncols, nrows) wk_blk = np.repeat(np.repeat(w, 3, axis=1), 3, axis=0) soil_health = populate_soil_health(wk_blk) for tmr in tmr_state.keys(): n = 1 for aez in yield_AEZs(regime=regime, tmr=tmr, slope=slope, land_use=land_use, soil_health=soil_health): df.loc[admin, f"{tmr}|AEZ{n}"] += (aez * km2_blk).sum() n += 1 df.sort_index(axis='index').to_csv(countrycsvfilename, float_format='%.2f') regions = [ 'OECD90', 'Eastern Europe', 'Asia (Sans Japan)', 'Middle East and Africa', 'Latin America', 'China', 'India', 'EU', 'USA' ] df_region = pd.DataFrame(0, index=regions, columns=df.columns.copy()) df_region.index.name = 'Region' for country, row in df.iterrows(): region = admin_names.region_mapping[country] if region is not None: df_region.loc[region, :] += row for tmr in [ 'Tropical-Humid', 'Arid', 'Tropical-Semiarid', 'Temperate-Humid', 'Temperate-Semiarid', 'Boreal-Humid', 'Boreal-Semiarid', 'Arctic' ]: tmrfilename = tmr.translate(str.maketrans('/', '-')) filename = f"results/AEZ-{tmrfilename}-by-region.csv" df_region.filter(regex=f'^{tmr.lower()}', axis=1).to_csv(filename, float_format='%.2f')
def test_blklim(): assert geoutil.blklim(coord=0, blksiz=256, totsiz=1024) == 256 assert geoutil.blklim(coord=768, blksiz=256, totsiz=1024) == 256 assert geoutil.blklim(coord=900, blksiz=256, totsiz=1024) == 124
def produce_CSV(): """Produce a CSV file of degraded land for {forest, cropland, grassland}.""" columns = [ 'forest:good:degraded', 'forest:marginal:degraded', 'forest:poor:degraded', 'forest:verypoor:degraded', 'forest:good:nondegraded', 'forest:marginal:nondegraded', 'forest:poor:nondegraded', 'forest:verypoor:nondegraded', 'cropland:good:degraded', 'cropland:marginal:degraded', 'cropland:poor:degraded', 'cropland:verypoor:degraded', 'cropland:good:nondegraded', 'cropland:marginal:nondegraded', 'cropland:poor:nondegraded', 'cropland:verypoor:nondegraded', 'grassland:good:degraded', 'grassland:marginal:degraded', 'grassland:poor:degraded', 'grassland:verypoor:degraded', 'grassland:good:nondegraded', 'grassland:marginal:nondegraded', 'grassland:poor:nondegraded', 'grassland:verypoor:nondegraded', 'bare:good:degraded', 'bare:marginal:degraded', 'bare:poor:degraded', 'bare:verypoor:degraded', 'bare:good:nondegraded', 'bare:marginal:nondegraded', 'bare:poor:nondegraded', 'bare:verypoor:nondegraded', 'urban:good:degraded', 'urban:marginal:degraded', 'urban:poor:degraded', 'urban:verypoor:degraded', 'urban:good:nondegraded', 'urban:marginal:nondegraded', 'urban:poor:nondegraded', 'urban:verypoor:nondegraded', 'water:good:degraded', 'water:marginal:degraded', 'water:poor:degraded', 'water:verypoor:degraded', 'water:good:nondegraded', 'water:marginal:nondegraded', 'water:poor:nondegraded', 'water:verypoor:nondegraded', 'ice:good:degraded', 'ice:marginal:degraded', 'ice:poor:degraded', 'ice:verypoor:degraded', 'ice:good:nondegraded', 'ice:marginal:nondegraded', 'ice:poor:nondegraded', 'ice:verypoor:nondegraded', ] df = pd.DataFrame(columns=columns, dtype='float') df.index.name = 'Country' shapefilename = 'data/ne_10m_admin_0_countries/ne_10m_admin_0_countries.shp' shapefile = osgeo.ogr.Open(shapefilename) assert shapefile.GetLayerCount() == 1 features = shapefile.GetLayerByIndex(0) lc_filename = 'data/copernicus/ESACCI-LC-L4-LCCS-Map-300m-P1Y-2015-v2.0.7.tif' lc_img = osgeo.gdal.Open(lc_filename, osgeo.gdal.GA_ReadOnly) lc_band = lc_img.GetRasterBand(1) lpd_filename = 'data/lpd_int2/lpd_int2.tif' lpd_img = osgeo.gdal.Open(lpd_filename, osgeo.gdal.GA_ReadOnly) lpd_band = lpd_img.GetRasterBand(1) wk_filename = 'data/FAO/workability_FAO_sq7_1km.tif' wk_img = osgeo.gdal.Open(wk_filename, osgeo.gdal.GA_ReadOnly) wk_band = wk_img.GetRasterBand(1) for idx, feature in enumerate(features): admin = admin_names.lookup(feature.GetField("ADMIN")) if admin is None: continue a3 = feature.GetField("SOV_A3") if admin not in df.index: df.loc[admin] = [0] * len(df.columns) print(f"Processing {admin:<41} #{a3}_{idx}") maskfilename = f"masks/{a3}_{idx}_1km_mask._tif" maskimg = osgeo.gdal.Open(maskfilename, osgeo.gdal.GA_ReadOnly) mask_band = maskimg.GetRasterBand(1) x_siz = mask_band.XSize y_siz = mask_band.YSize x_blksiz, y_blksiz = mask_band.GetBlockSize() for y in range(0, y_siz, y_blksiz): nrows = geoutil.blklim(coord=y, blksiz=y_blksiz, totsiz=y_siz) for x in range(0, x_siz, x_blksiz): ncols = geoutil.blklim(coord=x, blksiz=x_blksiz, totsiz=x_siz) if geoutil.is_sparse(band=mask_band, x=x, y=y, ncols=ncols, nrows=nrows): # sparse hole in image, no data to process continue mask_blk = mask_band.ReadAsArray(x, y, ncols, nrows) k = geoutil.km2_block(nrows=nrows, ncols=ncols, y_off=y, img=maskimg) k[np.logical_not(mask_blk)] = 0.0 km2_blk = (np.repeat(np.repeat(k, 3, axis=1), 3, axis=0)) / 9.0 lc_blk = lc_band.ReadAsArray(3 * x, 3 * y, 3 * ncols, 3 * nrows) lc = {} lc['forest'] = np.logical_or.reduce( (lc_blk == 12, lc_blk == 50, lc_blk == 60, lc_blk == 61, lc_blk == 62, lc_blk == 70, lc_blk == 71, lc_blk == 72, lc_blk == 80, lc_blk == 81, lc_blk == 82, lc_blk == 90, lc_blk == 160, lc_blk == 170)) lc['cropland'] = np.logical_or.reduce( (lc_blk == 10, lc_blk == 30, lc_blk == 20)) lc['grassland'] = np.logical_or.reduce( (lc_blk == 11, lc_blk == 40, lc_blk == 100, lc_blk == 110, lc_blk == 120, lc_blk == 121, lc_blk == 122, lc_blk == 130, lc_blk == 150, lc_blk == 151, lc_blk == 152, lc_blk == 153, lc_blk == 180)) lc['bare'] = np.logical_or.reduce( (lc_blk == 140, lc_blk == 200, lc_blk == 201, lc_blk == 202)) lc['urban'] = (lc_blk == 190) lc['water'] = (lc_blk == 210) lc['ice'] = (lc_blk == 220) k = lpd_band.ReadAsArray(x, y, ncols, nrows) lpd = {} lpd_blk = np.repeat(np.repeat(k, 3, axis=1), 3, axis=0) lpd['degraded'] = (lpd_blk != 0.0) lpd['nondegraded'] = (lpd_blk == 0.0) k = wk_band.ReadAsArray(x, y, ncols, nrows) wk_blk = np.repeat(np.repeat(k, 3, axis=1), 3, axis=0) work = {} work['good'] = (wk_blk == 1) work['marginal'] = (wk_blk == 2) work['poor'] = (wk_blk == 3) work['verypoor'] = (wk_blk == 4) for cover in lc.keys(): for degraded in lpd.keys(): for soil in work.keys(): key = f'{cover}:{soil}:{degraded}' df.loc[admin, key] += (np.logical_and.reduce( (lc[cover], lpd[degraded], work[soil])) * km2_blk).sum() csvfilename = 'results/degraded-cover-by-country.csv' df.sort_index(axis='index').to_csv(csvfilename, float_format='%.2f') regions = [ 'OECD90', 'Eastern Europe', 'Asia (Sans Japan)', 'Middle East and Africa', 'Latin America', 'China', 'India', 'EU', 'USA' ] df_region = pd.DataFrame(0, index=regions, columns=df.columns.copy()) df_region.index.name = 'Region' for country, row in df.iterrows(): region = admin_names.region_mapping[country] if region is not None: df_region.loc[region, :] += row csvfilename = f"results/degraded-cover-by-region.csv" df_region.to_csv(csvfilename, float_format='%.2f')