Landscape Expansion Index#
More details on the wiki - worldbank/GOST_Urban
The Landscape Expansion Index measures the nature of urbanization, quantifying the new urban landscape as one of the following three categories. The process works by isolating the areas of new urban footprint in your study area, buffering those by a set amount (300 m) and intersecting the buffer donut with the original urban area. LEI is calculated as the ratio of the area of the buffer to the area of the old built area within the buffer (the threshold for each class is customizable).
Expansion Type |
Description |
---|---|
Infill |
> 80% of the donut is in the old urban area |
Expansion |
> 20% and < 80% of the donut is in the old urban area |
Leapfrog |
< 20% of the donut is in the old urban area |
import os
import rasterio
import rasterio.features
import geopandas as gpd
import pandas as pd
import GOSTRocks.rasterMisc as rMisc
import GOSTRocks.ghslMisc as ghslMisc
import GOSTurban.LEI as lei
import GOSTRocks.mapMisc as mapMisc
%load_ext autoreload
%autoreload 2
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Cell In[1], line 8
5 import geopandas as gpd
6 import pandas as pd
----> 8 import GOSTRocks.rasterMisc as rMisc
9 import GOSTRocks.ghslMisc as ghslMisc
10 import GOSTurban.LEI as lei
ModuleNotFoundError: No module named 'GOSTRocks'
# Define input variables
tutorial_folder = "../../data/tutorial_data"
aoi_file = os.path.join(tutorial_folder, "AOI_GHSL.geojson")
input_ghsl = os.path.join(tutorial_folder, "GHSL.tif")
# This section will extract GHSL data from global data, if you have the GHSL for the AOI extracted
# define above as input_ghsl
if not os.path.exists(input_ghsl):
temp_folder = "C:/Temp"
# clip from global GHSL file
ghsl_folder = "J:/Data/GLOBAL/GHSL/built"
ghsl_files = [
os.path.join(ghsl_folder, x)
for x in os.listdir(ghsl_folder)
if x.endswith(".tif")
]
inA = gpd.read_file(aoi_file)
temp_ghsl_files = []
for ghsl_file in ghsl_files:
temp_file = os.path.join(temp_folder, os.path.basename(ghsl_file))
temp_ghsl_files.append(temp_file)
if not os.path.exists(temp_file):
rMisc.clipRaster(rasterio.open(ghsl_file), inA, temp_file)
ghsl_res, ghsl_profile = ghslMisc.combine_ghsl_annual(temp_ghsl_files)
with rasterio.open(input_ghsl, "w", **ghsl_profile) as outR:
outR.write_band(1, ghsl_res)
GHSL data#
This tutorial relies on the Global Human Settlement Layer (GHSL) produced by the European Commission ([download the data here])(https://ghsl.jrc.ec.europa.eu/download.php).
The current release of the data provides individual layers ber annum of fractional area built per 1 hectare cell. For the LEI examples, we need binary data of existing built and new built. We leverage a function from the GOSTrocks library to combine these multiple yearly layers into a single geotiff with each pixel labelled with the year it was built.
ghsl_r = rasterio.open(input_ghsl)
ghsl_d = ghsl_r.read()
ghsl_d[ghsl_d == ghsl_r.meta["nodata"]] = 0
thresh = list(range(1975, 2031, 5))
with rMisc.create_rasterio_inmemory(ghsl_r.profile, ghsl_d) as temp_ghsl:
mapMisc.static_map_raster(temp_ghsl, thresh=thresh)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[4], line 6
3 ghsl_d[ghsl_d == ghsl_r.meta["nodata"]] = 0
5 thresh = list(range(1975, 2031, 5))
----> 6 with rMisc.create_rasterio_inmemory(ghsl_r.profile, ghsl_d) as temp_ghsl:
7 mapMisc.static_map_raster(temp_ghsl, thresh=thresh)
NameError: name 'rMisc' is not defined
Calculate LEI between 1990 and 2000#
# This calculates the change from 1990 and 2000
lei_raw = lei.calculate_LEI(
input_ghsl, old_list=list(range(1975, 1991, 5)), new_list=list(range(1995, 2001, 5))
)
lei_90_00 = gpd.GeoDataFrame(
pd.DataFrame(lei_raw, columns=["geometry", "old", "total"]),
geometry="geometry",
crs=ghsl_r.crs,
)
lei_90_00["LEI"] = lei_90_00["old"] / lei_90_00["total"]
lei_90_00.head()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[5], line 2
1 # This calculates the change from 1990 and 2000
----> 2 lei_raw = lei.calculate_LEI(
3 input_ghsl, old_list=list(range(1975, 1991, 5)), new_list=list(range(1995, 2001, 5))
4 )
5 lei_90_00 = gpd.GeoDataFrame(
6 pd.DataFrame(lei_raw, columns=["geometry", "old", "total"]),
7 geometry="geometry",
8 crs=ghsl_r.crs,
9 )
10 lei_90_00["LEI"] = lei_90_00["old"] / lei_90_00["total"]
NameError: name 'lei' is not defined
# Map LEI results
leap_val = 0.30
exp_val = 0.70
lei_90_00["area"] = lei_90_00["geometry"].apply(lambda x: x.area)
def calculate_LEI(val, leap_val, exp_val):
if val <= leap_val:
return 3
elif val < exp_val:
return 2
else:
return 1
lei_90_00["class"] = lei_90_00["LEI"].apply(
lambda x: calculate_LEI(x, leap_val, exp_val)
)
mapMisc.static_map_vector(
lei_90_00, "class", edgecolor="match", colormap="Dark2"
) # , basemap=ctx.providers.CartoDB.Voyager)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[6], line 4
2 leap_val = 0.30
3 exp_val = 0.70
----> 4 lei_90_00["area"] = lei_90_00["geometry"].apply(lambda x: x.area)
7 def calculate_LEI(val, leap_val, exp_val):
8 if val <= leap_val:
NameError: name 'lei_90_00' is not defined
# Calculate summaries of lei as area (km2) in each class
lei.summarize_LEI(lei_90_00, leap_val=0.05, exp_val=0.75) / 1000000
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[7], line 2
1 # Calculate summaries of lei as area (km2) in each class
----> 2 lei.summarize_LEI(lei_90_00, leap_val=0.05, exp_val=0.75) / 1000000
NameError: name 'lei' is not defined
Calculate LEI between 2000 and 2030#
# This calculates the change from 2000 and 2014
lei_raw = lei.calculate_LEI(
input_ghsl, old_list=list(range(1975, 2011, 5)), new_list=list(range(2015, 2030, 5))
)
lei_00_14 = pd.DataFrame(lei_raw, columns=["geometry", "old", "total"])
lei_00_14["LEI"] = lei_00_14["old"] / lei_00_14["total"]
lei_00_14.head()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[8], line 2
1 # This calculates the change from 2000 and 2014
----> 2 lei_raw = lei.calculate_LEI(
3 input_ghsl, old_list=list(range(1975, 2011, 5)), new_list=list(range(2015, 2030, 5))
4 )
5 lei_00_14 = pd.DataFrame(lei_raw, columns=["geometry", "old", "total"])
6 lei_00_14["LEI"] = lei_00_14["old"] / lei_00_14["total"]
NameError: name 'lei' is not defined
# Map LEI results
leap_val = 0.30
exp_val = 0.70
lei_90_00["area"] = lei_90_00["geometry"].apply(lambda x: x.area)
# def calculate_LEI(val, leap_val, exp_val):
# if val <= leap_val:
# return 3
# elif val < exp_val:
# return 2
# else:
# return 1
lei_90_00["class"] = lei_90_00["LEI"].apply(
lambda x: calculate_LEI(x, leap_val, exp_val)
)
mapMisc.static_map_vector(
lei_90_00, "class", edgecolor="match", colormap="Dark2"
) # , basemap=ctx.providers.CartoDB.Voyager)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[9], line 4
2 leap_val = 0.30
3 exp_val = 0.70
----> 4 lei_90_00["area"] = lei_90_00["geometry"].apply(lambda x: x.area)
7 # def calculate_LEI(val, leap_val, exp_val):
8 # if val <= leap_val:
9 # return 3
(...)
12 # else:
13 # return 1
16 lei_90_00["class"] = lei_90_00["LEI"].apply(
17 lambda x: calculate_LEI(x, leap_val, exp_val)
18 )
NameError: name 'lei_90_00' is not defined
# Calculate summaries of lei
lei.summarize_LEI(lei_00_14, leap_val=0.05, exp_val=0.75) / 1000000
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[10], line 2
1 # Calculate summaries of lei
----> 2 lei.summarize_LEI(lei_00_14, leap_val=0.05, exp_val=0.75) / 1000000
NameError: name 'lei' is not defined
# write raw LEI results to file
input_folder = "."
lei_90_00.to_csv(os.path.join(input_folder, "GHSL_LEI_90_00.csv"))
lei_00_14.to_csv(os.path.join(input_folder, "GHSL_LEI_00_14.csv"))
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[11], line 3
1 # write raw LEI results to file
2 input_folder = "."
----> 3 lei_90_00.to_csv(os.path.join(input_folder, "GHSL_LEI_90_00.csv"))
4 lei_00_14.to_csv(os.path.join(input_folder, "GHSL_LEI_00_14.csv"))
NameError: name 'lei_90_00' is not defined