Practical Course 33

Global Population Vulnerability Mapping for Public Health Risk Assessment

Construct a composite spatial vulnerability index integrating demographics, heat stress, and air pollution exposure using Google Earth Engine.
Global ~2 hours Intermediate
Dataset: WorldPop/GP/100m/pop WorldPop Global Project Population Data

📖 Key Terms for Beginners

Before starting, make sure you understand these terms. They appear throughout all code blocks in this course.

TermFull NameWhat it means in simple words
PopDensityPopulation DensityThe concentration of human individuals living within a defined spatial area unit.
VulnerabilityIndexComposite Vulnerability IndexA mathematical metric combining sensitivity, exposure, and adaptive capacity variables into a single score.
EnvExposureEnvironmental ExposureThe extent to which human populations come into contact with harmful ambient conditions such as air pollution or extreme thermal heat.
HeatStressThermal Heat StressPhysiological strain on the human body caused by prolonged exposure to elevated environmental temperatures.
AirPollutionAmbient Air PollutionAtmospheric contamination by harmful gases and particulate matter that adversely impact respiratory health.
SensitivityPopulation SensitivityPre-existing biological or demographic factors that increase susceptibility to adverse health impacts.
AdaptiveCapacityCommunity Adaptive CapacityThe ability of systems, institutions, and individuals to respond to and recover from health risks.
SpatialHarmonizationSpatial Data HarmonizationThe process of aligning datasets with different spatial resolutions, projections, and formats into a common grid.
RasterMinMaxMin-Max Raster NormalizationA scaling technique that rescales continuous raster layer values into a standardized range between 0 and 1.
CompositeIndicatorMulti-Criteria Composite IndicatorAn aggregated spatial layer constructed by weighting multiple normalized risk indicators.
SpatialAutocorrelationSpatial AutocorrelationThe formal statistical measure of spatial dependency where nearby locations share similar value distributions.
GeographicUnitSpatial Aggregation UnitThe specific boundary or raster grid cell size used to summarize spatial observations for epidemiological analysis.

Contents

  1. 1. Introduction to Public Health Vulnerability Mapping
  2. 2. Conceptual Framework for Health Vulnerability Index
  3. 3. Spatial Data Acquisition and Quality Filtering
  4. 4. Spatial Harmonization and Resampling Workflows
  5. 5. Normalization Techniques for Multi-Source Datasets
  6. 6. Integrating Demographics and Environmental Exposure
  7. 7. Weighting and Constructing Composite Risk Surfaces
  8. 8. Aggregating Indicators to Administrative Health Districts
  9. 9. Visualizing High-Risk Population Hotspots
  10. 10. Methodological Limitations and Ethical Considerations
1
Introduction
10 min

Mapping global population vulnerability requires integrating high-resolution demographic distribution, ambient air pollution, and severe thermal heat stress parameters. Public health organizations rely on spatial decision-support tools to identify communities at disproportionate risk from climate and environmental hazards. This course demonstrates how to leverage Google Earth Engine to harmonize heterogeneous global datasets, calculate spatial exposure indicators, and construct reproducible health vulnerability maps.

GEE Asset ID
WorldPop/GP/100m/pop
Dataset Name
WorldPop Global Project Population Data
Study Area
Global
AI Tool
DeepSeek (free, no API key needed)
🌍
What you will build: By the end of this course you will have a working GEE script that analyzes Global Population Vulnerability Mapping for Public Health Risk Assessment, computes statistics, visualizes results on an interactive map, and exports data to Google Drive.

2
Setup: GEE + DeepSeek
5 min

You need two browser tabs open side by side throughout this course.

1
Open chat.deepseek.com -- free account, no API key needed
2
Open code.earthengine.google.com in a second tab
3
Create a new GEE script named Course33_Global Population Vulnerability Mapping for Public Health Risk Assessment
💡
Workflow: Write a prompt in DeepSeek describing your task with exact dataset IDs and requirements. Copy the generated GEE JavaScript. Paste into GEE code editor. Click Run. Inspect results. Iterate.

3
Crafting the DeepSeek Prompt
15 min

The prompt is the core skill of this course. A good prompt includes the exact dataset ID, band names, study area coordinates, dates, preprocessing steps, and desired outputs.

📋 Main Prompt -- copy and paste this into DeepSeek
Act as a GeoAI public health expert. Write a complete Google Earth Engine JavaScript script to calculate a global Public Health Vulnerability Index for the year 2020. Use WorldPop population count ('WorldPop/GP/100m/pop', band 'population'), ERA5-Land monthly mean temperature ('ECMWF/ERA5_LAND/MONTHLY_AGGR', band 'temperature_2m'), and Sentinel-5P NO2 ('COPERNICUS/S5P/OFFL/L3_NO2', band 'NO2_column_number_density'). Resample all layers to a common resolution, normalize each layer between 0 and 1 using min-max scaling, and compute a weighted vulnerability index defined as 0.4 * population + 0.3 * heat + 0.3 * NO2. Center the map over an urban study area with an appropriate palette and legend. Include export functions for the final vulnerability composite.
✨
After pasting the prompt: Wait 20-30 seconds for DeepSeek to generate the full GEE script. Copy the entire code block it produces. If the output is cut short, type "Continue the code" to get the rest.

4
Data acquisition, spatial resampling, and environmental exposure preparation
10 min

Paste the following code into your GEE code editor and click Run. Read the beginner notes below to understand what each line does.

Data acquisition, spatial resampling, and environmental exposure preparation
// Define a study area ROI over a representative metropolitan area
var roi = ee.Geometry.Rectangle([72.7, 18.8, 73.0, 19.3]); // Mumbai Metro Region
Map.centerObject(roi, 10);
Map.setOptions('HYBRID');

// Load WorldPop Population Dataset (2020)
var pop = ee.ImageCollection('WorldPop/GP/100m/pop')
  .filter(ee.Filter.date('2020-01-01', '2020-12-31'))
  .select('population')
  .mean()
  .clip(roi);

// Load Sentinel-5P NO2 Air Pollution Data (2020)
var no2 = ee.ImageCollection('COPERNICUS/S5P/OFFL/L3_NO2')
  .filterBounds(roi)
  .filterDate('2020-01-01', '2020-12-31')
  .select('NO2_column_number_density')
  .mean()
  .clip(roi);

// Load ERA5-Land Air Temperature and convert Kelvin to Celsius
var temp = ee.ImageCollection('ECMWF/ERA5_LAND/MONTHLY_AGGR')
  .filterBounds(roi)
  .filterDate('2020-05-01', '2020-06-30') // Warmest summer season
  .select('temperature_2m')
  .mean()
  .subtract(273.15)
  .clip(roi);

// Resample air quality and temperature to match 100m WorldPop spatial scale
var targetScale = 100;
var popResampled = pop.reproject({crs: 'EPSG:4326', scale: targetScale});
var no2Resampled = no2.resample('bilinear').reproject({crs: 'EPSG:4326', scale: targetScale});
var tempResampled = temp.resample('bilinear').reproject({crs: 'EPSG:4326', scale: targetScale});

// Define helper function for Min-Max normalization (0 to 1 scaling)
function normalize(img, region, scale) {
  var stats = img.reduceRegion({
    reducer: ee.Reducer.minMax(),
    geometry: region,
    scale: scale,
    maxPixels: 1e9
  });
  var minKey = img.bandNames().get(0).getInfo() + '_min';
  var maxKey = img.bandNames().get(0).getInfo() + '_max';
  var minVal = ee.Number(stats.get(minKey));
  var maxVal = ee.Number(stats.get(maxKey));
  return img.subtract(minVal).divide(maxVal.subtract(minVal)).clamp(0, 1);
}

// Normalize baseline exposure components
var normPop = normalize(popResampled, roi, targetScale);
var normNO2 = normalize(no2Resampled, roi, targetScale);
var normTemp = normalize(tempResampled, roi, targetScale);

// Visualization settings
Map.addLayer(normPop, {min: 0, max: 1, palette: ['white', 'blue']}, 'Normalized Population Density');
Map.addLayer(normNO2, {min: 0, max: 1, palette: ['white', 'yellow', 'orange']}, 'Normalized NO2 Exposure');
Map.addLayer(normTemp, {min: 0, max: 1, palette: ['white', 'red']}, 'Normalized Thermal Heat Stress');
🔑
Beginner note: This code block defines a geographic region of interest and imports population count, satellite nitrogen dioxide (NO2), and reanalysis air temperature datasets. Environmental data at coarse resolutions are resampled to match the fine-scale 100m grid of the WorldPop dataset. A custom JavaScript function computes min-max statistics to normalize all continuous rasters into a standardized scale from 0 to 1.

5
Constructing the composite vulnerability index and spatial mapping
10 min

Add this block after the previous code. It continues the analysis with additional processing and visualization.

Constructing the composite vulnerability index and spatial mapping
// Combine normalized factors into a multi-criteria Vulnerability Index
// Weights: Population Sensitivity (0.4), Air Quality (0.3), Heat Stress (0.3)
var vulnerabilityIndex = normPop.multiply(0.4)
  .add(normNO2.multiply(0.3))
  .add(normTemp.multiply(0.3))
  .rename('Vulnerability_Index');

// Apply spatial smoothing filter to reduce high-frequency grid noise
var smoothVulnerability = vulnerabilityIndex.reduceNeighborhood({
  reducer: ee.Reducer.mean(),
  kernel: ee.Kernel.square({radius: 200, units: 'meters'})
});

// Define color palette for public health mapping
var healthPalette = [
  '#2b83ba', // Very Low Vulnerability (Blue)
  '#abdda4', // Low Vulnerability (Green)
  '#ffffbf', // Moderate Vulnerability (Yellow)
  '#fdae61', // High Vulnerability (Orange)
  '#d7191c'  // Very High Vulnerability (Red)
];

// Display composite vulnerability raster layer
Map.addLayer(smoothVulnerability, {
  min: 0.1,
  max: 0.8,
  palette: healthPalette
}, 'Population Vulnerability Index');

// Calculate zonal mean vulnerability across sub-administrative areas
var adminUnits = ee.FeatureCollection('FAO/GAUL/2015/level2')
  .filterBounds(roi);

var adminVulnerability = smoothVulnerability.reduceRegions({
  collection: adminUnits,
  reducer: ee.Reducer.mean().combine({
    reducer2: ee.Reducer.stdDev(),
    sharedInputs: true
  }),
  scale: targetScale
});

// Highlight high vulnerability administrative units
Map.addLayer(adminUnits.style({color: 'black', fillColor: '00000000'}), {}, 'District Boundaries');
print('Mean Vulnerability by District:', adminVulnerability);
🔑
Beginner note: This script combines normalized demographic and environmental exposure layers into a single spatial Population Vulnerability Index using weighted linear combination. It applies neighborhood spatial smoothing to reduce local noise and computes summary statistics across official administrative districts to support targeted public health intervention policies.

6
Export Results to Google Drive
5 min

Add this block at the end of your script to export the final map as a GeoTIFF to your Google Drive. After clicking Run, go to the Tasks tab in GEE and click Run next to each export task.

Export to Google Drive
// Export final vulnerability index raster layer to Google Drive
Export.image.toDrive({
  image: smoothVulnerability,
  description: 'Global_Population_Vulnerability_Index_2020',
  folder: 'GEE_PublicHealth_Outputs',
  scale: 100,
  region: roi,
  fileFormat: 'GeoTIFF',
  maxPixels: 1e9
});
🔑
Beginner note -- Export.image.toDrive(): This function does not export immediately. It creates a task in the GEE Tasks tab that you must manually start by clicking Run. The file will appear in your Google Drive folder (GEE_Courses) as a GeoTIFF that you can open in QGIS or ArcGIS.

7
Exercises Using DeepSeek Prompts
Homework

Use DeepSeek to extend the script for each exercise below. Write a follow-up prompt describing what you want to add, then copy the generated code and paste it into your GEE script.

Exercise A: Adjusting Exposure Component Weights

  1. Modify the relative weight parameters in code block 2 to increase heat exposure weight to 0.5 and reduce air pollution to 0.1.
  2. Re-run the spatial index script and compare the altered vulnerability map to the baseline output.
  3. Identify urban neighborhoods where thermal stress dominates overall health vulnerability.

Exercise B: Adding Urban Surface Density Indicators

  1. Import the GHSL Built-up Surface dataset ('JRC/GHSL/P2023A/GHS_BUILT_S') for the year 2020.
  2. Normalize the built-up density raster layer to a scale of 0 to 1 within the region of interest.
  3. Integrate built environment density as a fourth risk factor in the vulnerability calculation equation.

Exercise C: Multi-Temporal Heat Exposure Comparison

  1. Create two separate temperature exposure layers representing winter (January-February) and summer (May-June) periods.
  2. Compute separate seasonal public health vulnerability indices.
  3. Map the seasonal change in spatial health vulnerability across the urban study zone.

Exercise D: Threshold Extraction for High-Risk Zones

  1. Identify pixels where the normalized vulnerability index exceeds a strict threshold score of 0.75.
  2. Calculate the total human population residing within these high-risk spatial hot spots using WorldPop data.
  3. Export the high-risk vector polygon outlines as a GeoJSON file for regional emergency planning.

8
Prompt Engineering Tips
Reference

To get the best results from DeepSeek for GEE tasks, always include these elements in your prompts:

ElementExample
Exact dataset IDWorldPop/GP/100m/pop
Band names"select band 'B4' for red, 'B8' for NIR"
Study area"rectangle [-6.5, 33.0, -1.5, 36.0] North Morocco"
Date range"filter from 2020-01-01 to 2023-12-31"
Output format"print area in hectares, add a legend, export to Drive"
Error fixing"The code gives error X. Please fix it."
Iteration"Add a time series chart for each year 2018-2023"
🧠
Best practice: Start with the main prompt, run the code, then send follow-up prompts to add features one at a time. This gives you cleaner, more reliable code than asking for everything at once.
Course 33 - Global Population Vulnerability Mapping for Public Health Risk Assessment | GeoAI for Climate Change | Dr. Ayoub Lahlouh | UM6P/CUS | 2025/2026