World Settlement Footprint - Evolution
Products used: wsf_evolution
Keywords: data used; World Settlement Footprint,:index:data used; World Settlement Footprint - Evolution, datasets; wsf_evolution
Background
According to the UN Department of Economics and Social Affairs, 9.7 billion people will inhabit the planet by the year 2050. 55% of the world’s population presently resides in urban areas, and by 2050, that number is projected to increase to 68%. Rapid and haphazard urbanization, when paired with the problems posed by climate change, can increase air pollution, make people more susceptible to catastrophes, and cause problems with the management of resources like water, raw materials, and energy (Mapping Our Human Footprint From Space, 2023).
To improve the understanding of current trends in global urbanisation, ESA and the German Aerospace Center (DLR), in collaboration with the Google Earth Engine team, are jointly developing the World Settlement Footprint – the world’s most comprehensive dataset on human settlement.
The World Settlement Footprint Evolution was produced by processing seven million images from the US Landsat satellite collected between 1985 and 2015 and shows the annual growth of human settlements globally (Mapping Our Human Footprint From Space, 2023). It is worth noting that past Landsat-5/7 availability considerably varies across the world and over time. Independently from the implemented approach, this might then result in a lower quality of the final product where few/no scenes have been collected. To provide users with a suitable and intuitive measure that accounts for the availabilty of Landsat imagery, the Input Data Consistency (IDC) score was implemented. It ranges from 6 to 1 with: 6) very good; 5) good; 4) fair; 3) moderate; 2) low; 1) very low. The IDC score supports a proper interpretation of the WSF evolution product (Marconcini et al., 2021).
The World Settlement Footprint evolution data are now indexed in the DE Africa platform.
Description
This notebook is a walkthrough on how to use the World Settlement Footprint Evolution data in the data cube. The worked example takes users through the code required to:
Inspecting the WSF Evolution data in the datacube
Use
dc.load()
function to load in WSF dataPlotting of results for WSF Evolution data
Getting started
To run this analysis, run all the cells in the notebook, starting with the « Load packages » cell.
Load packages
[1]:
%matplotlib inline
import datacube
import numpy as np
import pandas as pd
import geopandas as gpd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from matplotlib.colors import ListedColormap
from matplotlib.patches import Patch
import matplotlib.animation as animation
from mpl_toolkits.axes_grid1 import make_axes_locatable
from IPython.display import Image
from datacube.utils.geometry import Geometry
from deafrica_tools.plotting import display_map
from deafrica_tools.areaofinterest import define_area
Connect to the datacube
[2]:
dc = datacube.Datacube(app="wsf")
List measurements
We can inspect the data available for WSF using datacube’s list_measurements
functionality. The table below lists the products and measurements available for the three WSF datasets indexed within DE Africa’s datacube.
[3]:
product_name = ['wsf_evolution']
dc_measurements = dc.list_measurements()
dc_measurements.loc[product_name].drop('flags_definition', axis=1)
[3]:
name | dtype | units | nodata | aliases | ||
---|---|---|---|---|---|---|
product | measurement | |||||
wsf_evolution | wsfevolution | wsfevolution | int32 | 1 | 0.0 | [wsfevolution] |
idc_score | idc_score | uint8 | 1 | 0.0 | [idc, idcscore, idcs] |
Analysis parameters
To define the area of interest, there are two methods available:
By specifying the latitude, longitude, and buffer. This method requires you to input the central latitude, central longitude, and the buffer value in square degrees around the center point you want to analyze. For example,
lat = 10.338
,lon = -1.055
, andbuffer = 0.1
will select an area with a radius of 0.1 square degrees around the point with coordinates (10.338, -1.055).By uploading a polygon as a
GeoJSON or Esri Shapefile
. If you choose this option, you will need to upload the geojson or ESRI shapefile into the Sandbox using Upload Files button in the top left corner of the Jupyter Notebook interface. ESRI shapefiles must be uploaded with all the related files(.cpg, .dbf, .shp, .shx)
. Once uploaded, you can use the shapefile or geojson to define the area of interest. Remember to update the code to call the file you have uploaded.
To use one of these methods, you can uncomment the relevant line of code and comment out the other one. To comment out a line, add the "#"
symbol before the code you want to comment out. By default, the first option which defines the location using latitude, longitude, and buffer is being used.
The default location is Mansoura, Egypt.
[4]:
# Method 1: Specify the latitude, longitude, and buffer
aoi = define_area(lat= 31.0412, lon=31.3845, buffer=0.2)
# Method 2: Use a polygon as a GeoJSON or Esri Shapefile.
#aoi = define_area(vector_path='aoi.shp')
#Create a geopolygon and geodataframe of the area of interest
geopolygon = Geometry(aoi["features"][0]["geometry"], crs="epsg:4326")
geopolygon_gdf = gpd.GeoDataFrame(geometry=[geopolygon], crs=geopolygon.crs)
# Get the latitude and longitude range of the geopolygon
lat_range = (geopolygon_gdf.total_bounds[1], geopolygon_gdf.total_bounds[3])
lon_range = (geopolygon_gdf.total_bounds[0], geopolygon_gdf.total_bounds[2])
View the selected location
The next cell will display the selected area on an interactive map. Feel free to zoom in and out to get a better understanding of the area you’ll be analysing. Clicking on any point of the map will reveal the latitude and longitude coordinates of that point.
[5]:
display_map(x=lon_range, y=lat_range)
[5]:
Loading of the WSF Evolution Dataset
The WSF Evolution dataset will be loaded using the dc.load
function. For more discussion on how to load data using the datacube, refer to the Introduction to loading data notebook.
The cell below loads the WSF Evolution dataset. Notice the product
and measurements
values. These will be updated for the subsequent data when they are being loaded.
[6]:
#create reusable datacube query object
query = {
'x': lon_range,
'y': lat_range,
'resolution':(-30, 30),
'output_crs': 'epsg:6933',
}
#loading the data using dc.load
wsf_evolution = dc.load(product='wsf_evolution',
measurements=['wsfevolution', 'idc_score'],
**query).squeeze()
display(wsf_evolution)
<xarray.Dataset> Dimensions: (y: 1463, x: 1288) Coordinates: time datetime64[ns] 2000-07-01T23:59:59.999500 * y (y) float64 3.796e+06 3.795e+06 ... 3.752e+06 3.752e+06 * x (x) float64 3.009e+06 3.009e+06 ... 3.047e+06 3.047e+06 spatial_ref int32 6933 Data variables: wsfevolution (y, x) int32 0 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 0 idc_score (y, x) uint8 6 6 6 6 6 6 6 6 6 6 6 6 ... 6 6 6 6 6 6 6 6 6 6 6 Attributes: crs: epsg:6933 grid_mapping: spatial_ref
Spatial Plotting of WSF Evolution data
Spatial plot enable us to visualise the areas where there was development of settlements. To identify evolution of the area from 1985 to 2015.
The IDC score supports a proper interpretation of the WSF Evolution product. Input Data Consistency (IDC) score,which ranges from 6 to 1 with: 6 - very good; 5 - good; 4 - fair; 3 - moderate; 2 - low; 1 - very low.
[7]:
fig, ax = plt.subplots(1, 2, figsize=(10, 6), sharey=True)
#in plotting of te data zero(no-data) is marked out
wsf_plt = wsf_evolution.where(wsf_evolution != 0
).wsfevolution.plot(cmap=ListedColormap(
sns.color_palette('rocket_r').as_hex()), ax=ax[0], add_colorbar= False)
ax[0].set_title('WSF Evolution from 1985 to 2015')
divider = make_axes_locatable(ax[0])
cax = divider.new_vertical(size='2%', pad=0.6, pack_start = True)
fig.add_axes(cax)
fig.colorbar(wsf_plt, cax = cax, orientation = 'horizontal', label='Year')
#in plotting of the IDC score to support interpretation of the data
wsf_plt = wsf_evolution.where(wsf_evolution != 0
).idc_score.plot(cmap=ListedColormap(
sns.color_palette('hls', 6).as_hex()), ax=ax[1], add_colorbar= False, vmin=1, vmax=6)
ax[1].set_title('IDC score')
divider = make_axes_locatable(ax[1])
cax = divider.new_vertical(size='2%', pad=0.6, pack_start = True)
fig.add_axes(cax)
fig.colorbar(wsf_plt, cax = cax, orientation = 'horizontal', label='IDC score')
plt.show()
From the spatial plotting above, the left image shows the evolution from 1985 to 2015, while the right image indicates the IDC score for the study area. Looking at the IDC score of 6 for the area of study, the values obtained from the WSF Evolution data can be classified as very good, and one can rely on it for further analysis.
Calculate the area of settlement footprint
The number of pixels can be used for the area of the building if the pixel area is known. Run the following cell to generate the necessary constants for performing this conversion.
[8]:
pixel_length = query["resolution"][1] # in metres
m_per_km = 1000 # conversion from metres to kilometres
area_per_pixel = pixel_length**2 / m_per_km**2
Plotting of the WSF Evolution data
Each pixel represents the year value of the WSF evolution dataset; to get the area of the evolution, the year pixel has to be counted and saved in a Pandas dataframe to enable calculation of the area. The cumulative sum of area will be calculated based on how it has increased over the period.
Note that there is a discrepancy between the area calculated for 2015 from the WSF 2015 product and the Evolution product. This may be because the Evolution product is derived from Landsat-5 and Landsat-7, whereas WSF 2015 and 2019 are derived from Sentinel-1 and Landsat-8.
[9]:
evolution_period = {}
#running a for loop to extract year and calculate the area based on the year
for evolution_year in np.unique(wsf_evolution.wsfevolution.values):
if evolution_year != 0:
evolution_area = wsf_evolution.where(
wsf_evolution.wsfevolution ==evolution_year).wsfevolution.count() * area_per_pixel
evolution_period[evolution_year] = evolution_area
#convert dict to dataframe
evolution_data = pd.DataFrame.from_dict(evolution_period, orient='index', dtype=float)
#Cummulative sum of the data
evolution_data['evolve'] = evolution_data[0].cumsum()
fig, ax = plt.subplots(figsize=(12,6))
evolution_data.evolve.plot(ax=ax, color='#B5784A')
ax.set_ylabel("Area (Sq. km)")
ax.set_title(f"World Settlement Footprint \n Evolution from 1985 to 2015 for the Study Area")
ax.grid(linewidth=0.3)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
plt.show()
It is worth noting that past Landsat-5/7 availability considerably varies across the world and over time. Independently from the implemented approach, this might then result in a lower quality of the final product where few/no scenes have been collected. The IDC score supports a proper interpretation of the WSF evolution product.
Animation of WSF Evolution data from 1985 to 2015
The cell below plots out the dataset and shows the animation of how the building footprint has evolved over the years from 1985 to 2015.
[20]:
evolution_year = evolution_data.index.values
fig, ax = plt.subplots()
#Generating the color scheme based on the number of years
lenyear=len(evolution_year)
palette = list(reversed(sns.color_palette("rocket", lenyear).as_hex()))
wsf = []
color_index = 0
for i in range(1, len(evolution_year) + 1):
evo_list= (evolution_year[:i])
color = palette[:color_index]
wsf_plt = wsf_evolution.where(
wsf_evolution.isin(evo_list)).wsfevolution.plot(cmap=ListedColormap(color),
add_colorbar= False, ax=ax)
color_index += 1
t = ax.annotate(evolution_year[i-1], (1,1), xycoords='axes pixels', size='x-large',
weight='bold')
wsf.append([wsf_plt, t])
ax.set_title(f'World Settlement Footprint \n Evolution from 1985 to 2015 for the Study Area')
divider = make_axes_locatable(ax)
cax = divider.new_vertical(size='2%', pad=0.6, pack_start = True)
fig.add_axes(cax)
fig.colorbar(wsf_plt, cax = cax, orientation = 'horizontal')
ani = animation.ArtistAnimation(fig=fig, artists=wsf, interval=500, blit=True)
ani.save('wsf.gif')
plt.close()
Image(filename='wsf.gif')
[20]:
<IPython.core.display.Image object>
Conclusion
The World Settlement Footprint offers a knowledge base that can help researchers, governmental organizations, and other stakeholders, such as urban planners, better understand how urbanization is happening and, concurrently, put in place sustainable urban development strategies for informed policy decisions at local and national levels.
Note
To run for different area go to cell Analysis parameters, change the lat and lon values in the define_area_function.
Referencing
Mapping our human footprint from space(Accessed on 2023 August). ESA - Mapping Our Human Footprint From Space. https://www.esa.int/Applications/Observing_the_Earth/Mapping_our_human_footprint_from_space
Mattia Marconcini, Annekatrin Metz-Marconcini, Thomas Esch and Noel Gorelick. Understanding Current Trends in Global Urbanisation - The World Settlement Footprint Suite. GI_Forum 2021, Issue 1, 33-38 (2021) https://austriaca.at/0xc1aa5576%200x003c9b4c.pdf
Additional information
License: The code in this notebook is licensed under the Apache License, Version 2.0. Digital Earth Africa data is licensed under the Creative Commons by Attribution 4.0 license.
Contact: If you need assistance, please post a question on the Open Data Cube Slack channel or on the GIS Stack Exchange using the open-data-cube
tag (you can view previously asked questions here). If you would like to report an issue with this notebook, you can file one on
Github.
Compatible datacube version:
[11]:
print(datacube.__version__)
1.8.15
Last tested:
[12]:
from datetime import datetime
datetime.today().strftime('%Y-%m-%d')
[12]:
'2023-10-31'