Mobile Health Training - Exercise 1A:#
Exercise track: Mobile Health Units
This exercise is part of the Mobile Health Exercise track. You can find the overview of the training on this page
Characteristics of the exercise #
Type of trainings exercise:
This exercise can be used in online and presence training.
It can be done as a follow-along exercise or individually as a self-study.
Exercise Track:
This exercise is part of the Colombia Mobile Health Unit (MHU) Deployment Planning Exercise Track
Estimated time demand for the exercise
Relevant Wiki Articles
Cost Distance / Friction Surfaces
Service Area / Network Analysis
Aim of the exercise:
In this exercise, we will design a potential Mobile Health Unit (MHU) route. We will start by assessing the Primary Health Care (PHC) gap and the target population. In a next step, we will assess the coverage of possible MHU stops and evaluate the priority of these stops in relation to existing healthcare systems and other narrative information (or qualitative information). Finally, we will draft potential routes and decide, how long the medical team should stay in the MHU stops.
THE GOAL IS TO USE QUANTIT
Instructions for the trainers #
Trainers Corner
Prepare the training
Take the time to familiarise yourself with the exercise and the provided material.
Prepare a white-board. It can be either a physical whiteboard, a flip-chart, or a digital whiteboard (e.g. Miro board) where the participants can add their findings and questions.
Before starting the exercise, make sure everybody has installed QGIS and has downloaded and unzipped the data folder.
Check out How to do trainings? for some general tips on facilitating trainings.
Note
Task 3 now offers three ways to estimate the walking catchment (friction surface, ORS isochrones, native QGIS service area + buffer). You don’t need to run all three with participants — pick whichever fits your room, or split participants into groups and have each group run a different method, then compare results at the end of Task 3. If you do only one: the friction-surface method needs GRASS enabled in QGIS (check this on the training machines beforehand) and uses r.cost, whose exact parameter labels can shift slightly between QGIS/GRASS versions — run through it yourself first and adjust the field names in the instructions if needed; the ORS method needs a stable internet connection and enough time for everyone to create an account and API key.
Conduct the training #
Introduction:
Introduce the idea and aim of the exercise.
Provide the download link and make sure everybody has unzipped the folder before beginning the tasks.
Follow-along:
Show and explain each step yourself at least twice and slow enough so everybody can see what you are doing, and follow along in their own QGIS-project.
Make sure that everybody is following along and doing the steps themselves by periodically asking if anybody needs help or if everybody is still following.
Be open and patient to every question or problem that might come up. Your participants are essentially multitasking by paying attention to your instructions and orienting themselves in their own QGIS-project.
Wrap up:
Leave time for any issues or questions concerning the tasks at the end of the exercise.
Leave some time for open questions.
Scenario
Available Data#
Download all datasets [here] and save the folder on your computer and unzip the file.
Dataset name |
Original title |
Publisher |
Source |
|---|---|---|---|
PLACEHOLDER |
PLACEHOLDER |
PLACEHOLDER |
PLACEHOLDER |
Tasks#
Task 1: Getting an overview of the data and area of interest#
Before we begin evaluating the MHU stops, we need to familiarise ourselves with the area of interest (AOI) and the available data. We will be working in the municipio of TibĂş, in the department of Norte de Santander, so we can begin by clipping our data to the AOI. Before beginning with any processing, take the time to look at the available data and opening the attribute tables
Import the layers in the
/data/input-folder.ABC.gpkgXYZ.shpXYZ
the walking-only friction surface raster
Order the layers in the layers tab.
Extract the department of Norte de Santander from the adm1 boundaries. (Tip: Extract selected features).
Select the municipio of TibĂş from the adm2 boundaries. (Tip: Extract by location, or Select by expression on the municipio name).
Clip the road and river network to TibĂş (Tip: Clip by mask layer).
Clip the health points to the layer
Clip the population raster layer to the AOI.
Clip the friction surface raster to the AOI (Tip: Clip raster by mask layer, same as the population raster).
Save the resulting layers in the
data/temp/Adjust the symbology of each layer so you can easily distinguish each layer
Task 2: Add demographic information#
In this step, we want to get an overview of the target population. On top of general population numbers, we want to know the demographic distribution of the population. With this information, we can assess the PHC needs of the population. For example, a high share of women in childbearing age will mean that there is a higher need for gynecological, maternal, and pre- and post-natal care, and a high share of elderly population will mean a higher need for chronic-disease management (e.g. hypertension, diabetes). We will estimate the population distribution based on the population data provided by WorldPop. Keep in mind that these numbers are estimations, and not definitive numbers by a census. The analysis should be adapted with data from the field and the communities to better understand the actual needs of the population.
Get the department-wide picture first. Before narrowing down to TibĂş, calculate the general population of the whole department of Norte de Santander using
Zonal statisticson the adm1 boundary layer from Task 1. This gives you a reference point for later — roughly how big a share of the department’s population does the municipio you’re about to focus on actually represent?Now narrow to Tibú. Calculate the demographic distribution per municipio (Tip: using zonal statistics) — this time using the Tibú adm2 boundary. This is the number you’ll come back to for the rest of the exercise: your target population.
Calculate the population under 5 per municipio
Add the tif files for the age groups 0, and 1.
Clip the raster files to our AOI.
Open the raster calcualtor
Add the clipped layers and save the file in
/data/temp/underAOI_pop_under_5_t_2026.tif.
Hint
The correct layers are called:
col_t_01_2026_CN_100m_R2025A_v1col_t_00_2026_CN_100m_R2025A_v1
The layer
col_t_05_2026_CN_100m_R2025A_v1contains the population aged 5 and over.In the raster calculator in the top left box, you can select the raster layers and associated raster bands in the top left box “Raster Bands”.
Select one of the clipped population raster and Double-click on it to add it to the Raster Calculator Expression and add a
+after the layer, then add the next raster band to the expression.
Calculate the population of women in childbearing age (15 - 49) per municipio:
Identify the .tiff files in the
data/input/col_agesex_structures_2026_CN_100m_R2025A_v1/-folder that represent the female population from age 15 until 49.Add them to the project, clip, them, and use the raster calculator to calculate the new raster.
Calculate the elderly population (60+) per municipio:
Identify the .tiff files representing both the male and female population aged 60 and above.
Add them to the project, clip them, and use the raster calculator to sum them into one raster.
Note
There’s no single agreed cutoff for “elderly” — 60+ and 65+ are both commonly used. We use 60+ here, as it’s the more common threshold in rural/lower-income contexts and captures more of the population likely to need chronic-disease management, which is a relevant PHC/MHU service. State this assumption explicitly if you present the number.
Take a look at the distribution of healthcare facilities in the AOI.
Add the existing PHC accessibility picture.
COL_primary_healthcare_access.gpkgalready tells you what share of Tibú’s population can reach a primary healthcare facility by car within one hour — HeiGIT built it from drive-time isochrones. Clip it to Tibú (same clip/extract-by-location steps as before) and read the population-within-60-min-drive and population-share fields directly from its attribute table.
Warning
Don’t combine this figure arithmetically with your own WorldPop-based population numbers above (for example, don’t calculate “Tibú’s total population minus HeiGIT’s population-within-60-min” to get an “uncovered population”). Different population products — even different WorldPop products, like the plain population-count raster versus the age/sex structure rasters you just used — are modelled somewhat independently of one another and don’t always reconcile at small-area scale. Treat HeiGIT’s figure as its own self-contained reference point (“per HeiGIT’s accessibility model, X% of Tibú already has 60-minute drive access to a fixed PHC facility”), and keep the rest of this exercise’s numbers — the ones you calculate yourself from WorldPop — internally consistent with each other instead.
Note
This layer only accounts for facilities classified as primary healthcare, not hospitals. A hospital can also absorb primary-care demand, so a part of Tibú marked “beyond 60-min drive access” in this layer may still have some access via a hospital the layer doesn’t count. Keep this in mind rather than treating the layer as the final word on existing coverage.
Task 3: Calculate the potential coverage of the proposed MHU stops#
We now have a first, quantitative picture of the health coverage in the AOI. In this step, we want to calculate the estimated coverage of the new MHU stops. This will help us assess the reach and priority of each stop.
We want to calculate the area that the local population can reach within 1 hour by foot of each proposed stop. There isn’t one single correct way to estimate that — below are three methods, each with different data needs, strengths and limitations. You don’t need to run all three; pick whichever fits your setup, or (if training in a group) split into teams and have each team run a different method, then compare results at the end of this task.
Method |
What it needs |
Best suited for |
Main limitation |
|---|---|---|---|
A: Friction surface ( |
GRASS enabled in QGIS, a friction raster |
Areas where the road/path network isn’t fully mapped |
Coarse resolution (~1km cells); requires GRASS, which may not be installed everywhere |
B: OpenRouteService isochrones |
ORS Tools plugin, a free API key, internet, decent OSM path coverage |
Areas with good OSM path coverage |
Only as accurate as the underlying OSM data; needs a live connection and a shared/rate-limited API |
C: Service area (native QGIS) + buffer |
A road/path network layer, no plugin or account needed |
Explaining results to a non-GIS audience; guaranteed to run on any QGIS install |
Coarse rule-of-thumb; depends on an assumed walking speed and buffer width that must be stated explicitly, not hidden |
Whichever method(s) you use, name your output layer(s) distinguishably (e.g. coverage_frictionsurface, coverage_ors, coverage_servicearea) — Task 4 refers generically to “your coverage layer.”
Option A: Friction surface (cumulative cost)
Rather than routing on the road/path network directly, this method uses a pre-computed walking-only friction surface (Malaria Atlas Project / Oxford — each pixel gives the time in minutes needed to cross it on foot, based on real terrain, land cover and existing paths). Starting from the MHU stop locations, we accumulate that cost outward to get a travel-time-from-nearest-stop raster — this is the same underlying idea as an isochrone, but it doesn’t depend on having a complete road/path network for the AOI, which matters in an area like Tibú where the path network isn’t fully mapped.
In the Processing Toolbox, search for
r.cost(GRASS) and open it.Set the parameters as follows:
Input raster map containing grid cell cost information: your clipped friction surface rasterStarting points vector layer(orStarting points map, depending on your QGIS version):Tibu_potential_MHU_stops.gpkgLeave the other parameters at their defaults unless your trainer tells you otherwise.
Click
Run. This produces a raster where every cell holds the estimated walking time, in minutes, from the nearest MHU stop.Investigate the output: zoom in, check the value range, and sanity-check a few cells against the map (does a cell right next to a stop show a low value, roughly what you’d expect?).
Use the
Raster Calculatorto create a simple “within 1 hour” layer:"cost_raster@1" <= 60
This gives you a binary raster: 1 where a location is within an estimated hour’s walk of a proposed stop, 0 elsewhere.
Save both the cost raster and the “within 1 hour” raster to
/data/temp/, e.g. ascoverage_frictionsurface.tif.
Note
This estimate is only as good as the friction surface itself — it’s a real, peer-reviewed global dataset, but it’s still a general model, not a survey of the actual paths people use around Tibú. Treat the resulting coverage as a planning estimate to validate with the National Society and local communities, not a precise measurement.
Option B: OpenRouteService isochrones
This method calculates a real network-based isochrone: the actual area reachable on foot within 1 hour, routed along the mapped road/path network, using openrouteservice.
Install the ORS Tools plugin (
Plugins→Manage and Install Plugins→ search “ORS Tools”).
Tip
Create a free account at openrouteservice.org, locate the Basic API key in your account options, then paste it into Web → ORS Tools → Provider Settings in QGIS.
Open
Isochrones from Point-Layer(under the ORS Tools menu).Set the parameters as follows:
Provider: OpenRouteServiceTravel mode: foot-walkingInput Point layer:Tibu_potential_MHU_stops.gpkgDimension: TimeRange(comma-separated, in seconds):3600
Click
Run.Investigate the output: does the isochrone shape follow visible paths/roads in the AOI, or does it look implausibly smooth or cut off?
Save the result to
/data/temp/, e.g. ascoverage_ors.gpkg.
Note
Tibú’s OSM path network isn’t complete — an isochrone can only route along paths that are actually mapped, so this method may understate coverage in areas with sparse OSM data, in the same way a facility missing from OSM understated healthcare coverage in Task 2. Cross-check surprising results against the road/path layer before trusting them.
Option C: Service area (native QGIS) + buffer
This method uses QGIS’s built-in network analysis, no plugin or account required, and adds a fixed buffer to account for people who don’t walk directly along the mapped network (informal paths, cutting across terrain).
In the Processing Toolbox, open
Service area (from layer).Set the parameters as follows:
Vector layer representing network: your clipped road/path network from Task 1Path type to calculate: FastestVector layer with start points:Tibu_potential_MHU_stops.gpkgTravel cost:1(representing 1 hour)Default speed:4(km/h — a stated assumption for rural/hilly walking pace; adjust if your trainer specifies otherwise)
Click
Run. This producesService area (lines): the network segments reachable within 1 hour.Dissolvethe result into a single feature.Bufferthe dissolved layer by1 km. This is not a measured distance — it’s a stated allowance for people walking informally or cross-country rather than strictly along the mapped network, so people don’t live within 10m of a road but never venture off it.Save the result to
/data/temp/, e.g. ascoverage_servicearea.gpkg.
Note
Both the 4 km/h walking speed and the 1 km buffer are chosen assumptions, not measurements — state them explicitly whenever you present results from this method.
Great! We now have an estimated walking-time coverage for the proposed MHU stops. In a next step, we need to calculate the population living inside that coverage.
Task 4: Estimate the demographic distribution for each proposed MHU stops#
Stopping at each proposed stop wouldn’t be logistically feasible. It is your task to find a route that can be done in approximately 14 days and adds substantial new coverage. Keep in mind that we do not want to duplicate existing healthcare coverage and it will be impossible to cover the entire population. Knowing which areas are not covered is also very valuable. In some cases, there is already a fixed primary healthcare facility present, so adding additional MHU stops.
In this step, we want to calculate the demographic characteristics of the population living inside our new coverage layer:
Calculate the general population living inside your coverage layer from Task 3 using
Zonal statistics.Calculate the zonal statistics for the population under 5.
Calculate the population of women of childbearing age (15-49).
We want to have all this information in a single layer. If the new columns are not in a single layer yet, we can combine the layers with the tool
Join layers by field value.
Great, we now have the demographic distribution for each stop, we can investigate the data by classifying the data in the symbolisation tab.
Task 5: Evaluating additional information#
In this step, we want to evaluate which proposed MHU stops make the most sense. For this, we want to see where we can reach the largest population, and where we would not duplicate existing healthcare structures. We want a route that can be done within 14 days. Per day, we estimated that the MHU medical team can see about 20 patients. The MHU is equipped with a state of the art medical bus and can be operational within 2 hours upon arrival, so we can count the day of arrival as the start of the consultations. We assume that upon arrival, around 10% percent of the population will seek out primary healthcare services.
Discussion #
Your coverage layer only measures one thing: whether a location falls within an estimated hour’s walk of a proposed stop. That’s a useful, necessary starting point — and also only part of what actually decides whether an MHU stop works. Before finalising your route, discuss:
Availability, not just proximity. A stop being reachable doesn’t mean the MHU can meet the need there — does your team have the right staff and supplies for what this population actually needs (Task 2’s demographic breakdown is a first clue, not the full answer)?
Acceptability. Will people actually come? Trust, language, and past experience with outside organisations all shape whether a technically “covered” population is really served.
Coordination. Is another organisation already running health activities near one of your proposed stops? Placing an MHU stop where coverage already exists wastes the one resource you can’t get back — your 14 days.
Site suitability. Can the medical bus actually reach and park at this location? Is there a safe, appropriate space to operate from once it arrives?
How current is your population data? A population raster is a snapshot. In an area with active displacement, the population actually living somewhere today can differ from what the dataset shows — how would you sense-check that before committing a route?
Which “population” are you citing? This exercise used two independent population sources — WorldPop for your own coverage numbers, and HeiGIT’s own accessibility model for existing 60-minute drive access — and they don’t agree, even roughly. Even within a single source, sub-populations don’t always sum back to the reported total, because different demographic breakdowns are sometimes modelled independently rather than as strict subsets of one number. This isn’t something you’re expected to reconcile in a day — it’s a normal feature of real humanitarian GIS work. What matters is knowing which number you’re citing, from which source, and never silently combining numbers across sources that weren’t built to be combined.
None of these can be answered from the datasets in this exercise alone — which is itself the point. Your map is evidence for a decision, not the decision.