Urban Extent Explained

On this page

Problem statement

Every statement about a city — its population, its density, how much of it is green, how fast it is growing — assumes an answer to where the city is. There are three common answers and they rarely coincide. The administrative city is a legal boundary drawn by history. The morphological city is the continuous built-up or densely populated area, drawn from data. The functional city is the area whose residents commute into it, drawn from travel flows.

Den Haag is a clear case. Its municipality includes dunes, beach and a strip of the North Sea, and excludes neighbouring towns whose streets run on without a break. Its population, density and built-up share each change depending on which of the three cities is meant.

Quick answer

Definition Drawn from Den Haag example
administrative legal boundaries the gemeente 's-Gravenhage
morphological population or built-up grids the dense cluster across several municipalities
functional commuting flows the metropolitan region
import io, zipfile, requests, numpy as np, rasterio, rasterio.mask, geopandas as gpd, osmnx as ox
from scipy import ndimage

BASE = "https://jeodpp.jrc.ec.europa.eu/ftp/jrc-opendata/GHSL"
name = "GHS_POP_E2020_GLOBE_R2023A_4326_30ss"
zipfile.ZipFile(io.BytesIO(requests.get(
    f"{BASE}/GHS_POP_GLOBE_R2023A/{name}/V1-0/tiles/{name}_V1_0_R4_C19.zip", timeout=600
).content)).extractall("ghsl_nl")
src = rasterio.open(f"ghsl_nl/{name}_V1_0_R4_C19.tif")
win = rasterio.windows.from_bounds(3.9, 51.8, 4.8, 52.4, src.transform)
pop = np.clip(src.read(1, window=win), 0, None)
tf = src.window_transform(win)
lat = 52.4 - (np.arange(pop.shape[0]) + 0.5) * abs(tf.e)
cell_km2 = np.broadcast_to((abs(tf.a) * 111.32 * np.cos(np.radians(lat))[:, None])
                           * (abs(tf.e) * 110.57), pop.shape)          # km² per cell

labels, n = ndimage.label(pop / cell_km2 >= 1500)
sums = ndimage.sum(pop, labels, np.arange(1, n + 1))
r, c = rasterio.transform.rowcol(tf, 4.3113, 52.0799)             # central Den Haag
centre = labels == labels[r, c]

ox.settings.http_user_agent = "spatialworkflow-examples/1.0"
gem = ox.geocode_to_gdf("Den Haag, Netherlands")
in_gem, _ = rasterio.mask.mask(src, gem.to_crs(4326).geometry, crop=True, nodata=0)
gem_pop, gem_km2 = np.clip(in_gem, 0, None).sum(), gem.to_crs(28992).area.iloc[0] / 1e6

print(f"administrative: {gem_pop:>9,.0f} people on {gem_km2:5.0f} km² → {gem_pop / gem_km2:6,.0f}/km²")
print(f"morphological:  {pop[centre].sum():>9,.0f} people on {cell_km2[centre].sum():5.0f} km² → "
      f"{pop[centre].sum() / cell_km2[centre].sum():6,.0f}/km²")
administrative:   550,960 people on    98 km² →  5,615/km²
morphological:    797,550 people on   121 km² →  6,597/km²

Two definitions, two populations and two densities — both correct, describing different objects. The morphological city holds nearly 250,000 more people than the municipality, and it is denser, because it leaves out the dunes, beach and sea inside the legal line.

Population density grid around Den Haag with the municipal boundary dashed and the contiguous cluster of cells above 1,500 people per km² outlined in red. The cluster leaves out the coastal dunes inside the municipality and extends south-east beyond it. Population density grid around Den Haag with the municipal boundary dashed and the contiguous cluster of cells above 1,500 people per km² outlined in red. The cluster leaves out the coastal dunes inside the municipality and extends south-east beyond it.
The two cities from the code above, on the GHSL 2020 population grid. The dashed line is the municipality: 550,960 people on 98 km², including dunes and beach along the coast with almost nobody on them. The red outline is the contiguous cluster of cells over 1,500 people per km² around the centre: 797,550 people on 121 km², crossing into the neighbouring municipalities to the south and east.

Which city, a rule-based extent, land not legal polygons

1. Say which city the question is about

Tax base and governance: administrative. Urban form, heat, land consumption: morphological. Labour markets and housing: functional.

2. Draw the morphological city with a rule, not by eye

A threshold on population density or built-up share, applied to a regular grid, with a contiguity rule. The same rule then works for any city.

Administrative polygons may include water. Density on land and density on the full polygon differ wherever a city is coastal or has lakes.

4. Compare cities only within one definition

A density ranking that mixes administrative cities of very different sizes is a ranking of boundary-drawing practice.

5. Report the definition with every figure

"Den Haag has N people per km²" is incomplete without "within the municipal boundary" or "within the GHSL urban centre".

The same urban area outlined three ways: a municipal boundary, a morphological urban centre and a larger functional area. three cities in one placeadministrativeincludes sea and dunesmorphologicalcrosses municipal linesfunctionalcore + commuting zoneEvery density figure belongs to one of these spatialworkflow.io
Three cities in one place: legal, morphological and functional.

Den Haag's municipalities against its urban centre

Example 1 — which municipalities the urban centre spans

from shapely.geometry import shape
import rasterio.features
geoms = [shape(g) for g, v in rasterio.features.shapes(centre.astype("uint8"), mask=centre, transform=tf)]
centre_poly = gpd.GeoSeries(geoms, crs=4326).union_all()
names = ["Den Haag", "Rijswijk", "Leidschendam-Voorburg", "Delft", "Westland", "Zoetermeer"]
for nm in names:
    g = ox.geocode_to_gdf(f"{nm}, Zuid-Holland, Netherlands").to_crs(4326).geometry.iloc[0]
    share = gpd.GeoSeries([centre_poly.intersection(g)], crs=4326).to_crs(28992).area.iloc[0]
    total = gpd.GeoSeries([centre_poly], crs=4326).to_crs(28992).area.iloc[0]
    print(f"{nm:<22} {share / total:5.1%} of the urban centre")
Den Haag               55.7% of the urban centre
Rijswijk                9.8% of the urban centre
Leidschendam-Voorburg  10.4% of the urban centre
Delft                  13.6% of the urban centre
Westland                3.5% of the urban centre
Zoetermeer              0.0% of the urban centre

The municipality of Den Haag holds 56% of its own urban centre; Delft, Leidschendam-Voorburg and Rijswijk hold another third between them. Zoetermeer, 15 km away, is dense enough but separated by lower-density land, so it forms its own cluster. No single administrative unit is "the city" in the morphological sense.

land = gpd.read_file("https://naciscdn.org/naturalearth/10m/physical/ne_10m_land.zip")
gem_land = gem.to_crs(4326).clip(land.to_crs(4326))
land_km2 = gem_land.to_crs(28992).area.sum() / 1e6
print(f"municipal polygon {gem_km2:.0f} km², of which on land {land_km2:.0f} km²")
print(f"density on the polygon {gem_pop / gem_km2:,.0f}/km², on land {gem_pop / land_km2:,.0f}/km²")
municipal polygon 98 km², of which on land 81 km²
density on the polygon 5,615/km², on land 6,806/km²

The coastline dataset is coarse at this scale, but the point stands: a coastal municipality's polygon includes sea, and a density over it is diluted by water.

Example 3 — thresholds move the edge

for t in (1000, 1500, 2500, 5000):
    lab, _ = ndimage.label(pop / cell_km2 >= t)
    m = lab == lab[r, c]
    print(f"≥ {t:>5}/km²: {pop[m].sum():>9,.0f} people on {cell_km2[m].sum():5.0f} km²")
≥  1000/km²: 1,898,501 people on   456 km²
≥  1500/km²:   797,550 people on   121 km²
≥  2500/km²:   759,841 people on   103 km²
≥  5000/km²:   467,113 people on    48 km²

The morphological city is a family of cities indexed by the threshold. Between 2,500 and 1,500/km² the Den Haag cluster gains only 38,000 people; at 1,000/km² it jumps to 1.9 million, more than the Den Haag and Rotterdam urban centres together, because the lower threshold joins it to its neighbours across the gaps between them. The Degree of Urbanisation fixes 1,500/km² by international agreement; other thresholds answer other questions.

Population of the Den Haag urban cluster at four density thresholds, from GHS-POP 2020. people in the cluster containing central Den Haag≥ 5,000/km² (48 km²)467,000≥ 2,500/km² (103 km²)760,000≥ 1,500/km² (121 km²)798,000 — Degree of Urbanisation≥ 1,000/km² (456 km²)1.9 million — joined to its neighbours01M2MThe municipality: 551,000 people on 98 km² spatialworkflow.io
The edge of the morphological city depends on the threshold that draws it.

Why administrative cities compare poorly

Why administrative cities are poor comparators

Municipal boundaries reflect centuries of annexation, mergers and politics. Some cities, like Paris, have tight boundaries around a small core; others include large rural hinterlands. Comparing their densities compares boundary histories.

Why grids make comparison possible

A rule applied to a regular grid ignores administrative history. The same density and contiguity thresholds produce comparable urban centres in Europe, Africa and Asia, which is why international statistics increasingly use them.

Why the functional city is different again

People live in one place and work in another. The functional urban area adds commuting zones to the morphological core; it is the right unit for labour markets and housing, and it is much larger. Its boundary needs flow data rather than a grid.

Share of the Den Haag urban centre’s area in each municipality. the Den Haag urban centre, by municipalitymunicipalityshare of the centreDen Haag55.7%Delft13.6%Leidschendam-Voorburg10.4%Rijswijk9.8%Westland3.5%Zoetermeer0% — its own clusterThe remaining 7% lies in other municipalities spatialworkflow.io
The dense city spills across five municipalities; the legal one holds just over half of it.

Coasts, polycentric regions and epochs

  • Coastal and lake cities need land masks for any density.
  • Polycentric regions (the Randstad) produce several urban centres close together; merging them or not changes rankings.
  • Epoch: urban centres change as cities grow; use the same year for population and boundary.
  • Official data: GHS-SMOD publishes the settlement classification; Eurostat publishes functional urban areas for Europe.
  • Nominatim polygons for places can be the municipality, the city district or the ward; check what came back.

FAQ

What is the difference between a city and an urban area?

A city is usually an administrative unit; an urban area is defined by where people or buildings are concentrated, regardless of boundaries.

What is the Degree of Urbanisation?

An EU–UN method that classifies 1 km grid cells as urban centres, urban clusters or rural by density and contiguity.

Why does my city's density differ between sources?

They use different definitions of the city and different land areas.

Should I use the municipal boundary?

For governance questions, yes. For form, heat or land use, use a morphological extent.

What is a functional urban area?

A city and its commuting zone, defined from travel-to-work flows.

How do I handle water in density calculations?

Clip the area to land before dividing, and say that you did.