Surface Urban Heat Island Explained
On this page
Problem statement
"Urban heat island" names at least three different things. The surface heat island compares the skin temperature of city and countryside, measured by satellites. The canopy-layer heat island compares air temperature in streets with air in the countryside, measured by stations. The boundary-layer heat island is the warm dome of air above the city. They differ in size, in timing and even in sign, and a claim about one says little about another.
The surface heat island is the one satellite data measures, and its most important property is that it changes through the day. At night, cities release stored heat and stay warm while the countryside cools; in the afternoon, dry fields can be hotter than a shaded, irrigated city. A single number without a time of day is not a finding.
Quick answer
SUHI intensity = LST(urban) − LST(rural), at a stated time, season and with stated urban and rural definitions. MODIS measures it four times a day:
import numpy as np, pandas as pd, rasterio, pystac_client, planetary_computer
from rasterio.warp import transform_bounds, transform
CENTRE = (-3.7038, 40.4168) # Madrid, Puerta del Sol
BBOX = (-4.25, 40.05, -3.15, 40.80)
cat = pystac_client.Client.open("https://planetarycomputer.microsoft.com/api/stac/v1")
items = [i for i in cat.search(collections=["modis-11A1-061"], bbox=list(BBOX),
datetime="2023-06-01/2023-08-31").items()
if ".h17v04." in i.id] # the one sinusoidal tile covering the box
def read(item, asset):
with rasterio.open(planetary_computer.sign(item.assets[asset].href)) as src:
win = rasterio.windows.from_bounds(*transform_bounds("EPSG:4326", src.crs, *BBOX), src.transform)
a = src.read(1, window=win).astype("float32")
tf, crs = src.window_transform(win), src.crs
return np.where(a == 0, np.nan, a * 0.02 - 273.15), tf, crs
stacks = {}
for it in items:
sat = "Terra" if it.id.startswith("MOD") else "Aqua"
for when, asset in (("day", "LST_Day_1km"), ("night", "LST_Night_1km")):
a, tf, crs = read(it, asset)
stacks.setdefault((sat, when), []).append(a)
rows_, cols_ = np.indices(stacks[("Aqua", "day")][0].shape)
xs, ys = rasterio.transform.xy(tf, rows_.ravel(), cols_.ravel())
lon, lat = transform(crs, "EPSG:4326", xs, ys)
dist = np.hypot((np.array(lon) - CENTRE[0]) * 85.3, (np.array(lat) - CENTRE[1]) * 111.0).reshape(rows_.shape)
urban, rural = dist <= 5, (dist >= 25) & (dist <= 40)
print(f"{len(items)} MODIS tiles-days, summer 2023; urban = within 5 km of the centre, rural = 25–40 km")
for (sat, when), layers in sorted(stacks.items()):
comp = np.nanmedian(np.stack(layers), axis=0)
u, r = np.nanmedian(comp[urban]), np.nanmedian(comp[rural])
print(f"{sat:<5} {when:<5}: urban {u:5.1f} °C, rural {r:5.1f} °C, SUHI {u - r:+5.1f} °C")
184 MODIS tiles-days, summer 2023; urban = within 5 km of the centre, rural = 25–40 km
Aqua day : urban 43.9 °C, rural 47.2 °C, SUHI -3.3 °C
Aqua night: urban 22.5 °C, rural 17.8 °C, SUHI +4.7 °C
Terra day : urban 39.9 °C, rural 42.7 °C, SUHI -2.8 °C
Terra night: urban 26.4 °C, rural 21.5 °C, SUHI +4.9 °C
Four overpasses, two opposite answers. At both night passes the city's surface is about 5 °C warmer than the countryside; at both day passes it is about 3 °C cooler, because the rural ring is dry farmland baking in the sun. Madrid in summer has a surface heat island at night and a surface cool island by day. The time of observation is part of the answer.
Name the heat island, its time, urban and rural from data
1. Name which heat island
Surface (LST from satellites), canopy layer (air temperature at street level), or boundary layer (air above the city). Each has its own data and its own behaviour.
2. State the time of day and season
Night-time surface heat islands are usually larger and more consistent; daytime ones depend on the rural surroundings' moisture. Summer and winter differ too.
3. Define urban and rural from data
Built-up share or distance rules applied to a grid, with water and elevation differences excluded from the rural reference.
4. Use composites
Individual days are noisy; median composites over a season describe the typical heat island.
5. Match the resolution to the question
MODIS at 1 km resolves the city as a whole; Landsat at 100 m resolves neighbourhoods but only in late morning.
Madrid's heat island at night and at midday
Example 1 — how many clear observations behind each composite
for (sat, when), layers in sorted(stacks.items()):
n = np.isfinite(np.stack(layers)).sum(axis=0)
print(f"{sat:<5} {when:<5}: median {np.median(n[urban]):.0f} clear days in the urban cells, "
f"{np.median(n[rural]):.0f} in the rural ring")
Aqua day : median 70 clear days in the urban cells, 68 in the rural ring
Aqua night: median 68 clear days in the urban cells, 67 in the rural ring
Terra day : median 72 clear days in the urban cells, 73 in the rural ring
Terra night: median 72 clear days in the urban cells, 69 in the rural ring
Madrid's summer skies are clear on most days, so each composite rests on dozens of observations. In cloudier cities the counts — and the reliability — are much lower.
Example 2 — the distance profile at night and at midday
night = np.nanmedian(np.stack(stacks[("Aqua", "night")]), axis=0)
day = np.nanmedian(np.stack(stacks[("Aqua", "day")]), axis=0)
for lo, hi in ((0, 5), (5, 10), (10, 15), (15, 25), (25, 40), (40, 60)):
m = (dist >= lo) & (dist < hi)
print(f"{lo:>2}–{hi:<2} km: night {np.nanmedian(night[m]):5.1f} °C, "
f"afternoon {np.nanmedian(day[m]):5.1f} °C")
0–5 km: night 22.5 °C, afternoon 43.9 °C
5–10 km: night 21.3 °C, afternoon 45.3 °C
10–15 km: night 19.6 °C, afternoon 47.3 °C
15–25 km: night 18.4 °C, afternoon 47.3 °C
25–40 km: night 17.8 °C, afternoon 47.2 °C
40–60 km: night 17.1 °C, afternoon 45.8 °C
At night the profile falls steadily from the centre outward — the classic dome. In the afternoon it is flatter or inverted: the countryside's dry fields heat as much as the city or more.
Example 3 — day–night range by zone
for name, m in (("urban", urban), ("rural", rural)):
print(f"{name:<5}: Aqua afternoon {np.nanmedian(day[m]):5.1f} °C, "
f"night {np.nanmedian(night[m]):5.1f} °C, range {np.nanmedian(day[m]) - np.nanmedian(night[m]):5.1f} °C")
urban: Aqua afternoon 43.9 °C, night 22.5 °C, range 21.4 °C
rural: Aqua afternoon 47.2 °C, night 17.8 °C, range 29.4 °C
The rural surface swings through a larger daily range than the urban one. Cities damp the cycle: they heat a little less in the afternoon than dry fields and cool much less at night, because concrete and brick store heat and release it after sunset.
Why night is strongest and day can reverse
Why the night-time heat island is strongest
Urban materials have high heat capacity and conductivity; they store daytime heat and release it slowly. Street canyons restrict how much sky a surface sees, slowing radiative cooling. Rural surfaces, especially dry soil, cool quickly after sunset. The difference peaks in the early hours.
Why the daytime heat island can reverse
Daytime surface temperature is dominated by how much absorbed sunlight goes into evaporation. In a Mediterranean summer, unirrigated fields have no water to evaporate and bake; the city has irrigated parks, street trees and shade from buildings. The rural surface can then be hotter than the urban one — a daytime "cool island".
Why surface and air heat islands differ
The surface heat island is largest in daytime in humid climates and at night in dry ones; the air heat island is almost always largest at night. Air temperature integrates surfaces over a wider area and lags them. Health impacts follow air temperature, especially at night.
MODIS view angles, elevation and water
- MODIS view angle varies day to day; composites average over it.
- Terra and Aqua differ by three hours; combining them mixes times.
- Elevation: rural references in the Guadarrama mountains north-west of Madrid are cooler for reasons unrelated to the city.
- Water: large reservoirs in the rural ring should be excluded.
- Distance rules are crude; built-up maps give better urban and rural masks.
Internal links
- How to calculate surface urban heat island intensity — the Landsat workflow
- SUHI rural reference wrong — the reference problem
- Land surface temperature explained — what LST is
- How to compare air temperature with LST — surface and air
- Heat exposure explained — why nights matter
- Urban extent explained — defining the city
FAQ
What is a surface urban heat island?
The difference in land surface temperature between a city and its rural surroundings, usually measured by satellite.
Is the surface heat island the same as the air heat island?
No. They differ in size and timing; the air heat island is usually strongest at night.
Why is the urban heat island stronger at night?
Urban materials store heat by day and release it after sunset, while rural surfaces cool faster.
Can a city be cooler than its surroundings?
Yes, in daytime surface temperature, especially in dry climates with irrigated urban greenery.
Which satellite data should I use?
MODIS for day and night at 1 km; Landsat for late-morning detail at 100 m.
How should I define rural?
Unbuilt land at a set distance from the city, excluding water and large elevation differences.