Concepts

Every dataset in Urban Growth Center describes a city or a piece of one. This page explains what a city is, how cities are subdivided, and how to join datasets to them.

For the motivation behind these boundaries and an illustrated explanation of our approach, start with the Urban Boundaries 2026 article.

Read the article

Cities#

A city is an urban agglomeration: a contiguous built-up region with one boundary and a stable id. It is not a municipality, district or metro authority. Administrative definitions of a city vary across countries, so we define cities by built-up extent to keep them comparable across borders.

The city boundary file includes every city with a population of at least 50,000, along with its name, population estimate, country code and area.

Administrative splits#

Some questions need more detail than a whole city. For these, cities are split along administrative lines: an ADM1 split is the part of a city inside one first-level administrative unit, such as a state or province, and an ADM2 split is the part inside one second-level unit, such as a district. Administrative boundaries come from GADM.

Splits are selective, not a complete administrative map:

  • Not every city has splits, and a city may have ADM1 splits without ADM2 splits or the reverse. Check each level separately.
  • Small slivers are dropped, so a city’s splits may not cover its full area. Totals across splits (population, area or other measures) may not add up to the city total. For whole-city figures, use the city-level observation.

Levels and identifiers#

Every published polygon, whether a city or a split, has its own unique id. Datasets record which kind of polygon each row describes in boundary_level:

boundary_levelBoundary fileJoin on
PARENTCity GeoPackageid
ADM1ADM1 split GeoPackageid
ADM2ADM2 split GeoPackageid

To join a dataset to boundaries:

  1. Filter the dataset to one boundary_level.
  2. Join to the matching boundary file on id. Names are labels, not keys.
  3. Keep the time columns (year, month or epoch). Time-series datasets have several rows per polygon.

Splits also carry parent_id, which links a split to its city, and adm_id, which identifies the source GADM unit. Use parent_id to bring in city attributes. Never join split-level measures on it: that attaches them to the whole city.

Choosing a level#

Use cities for comparisons across cities. Use splits when variation within a city matters and the measure is meaningful at that finer level. Copying a city value onto its splits does not create a split-level estimate.

Each dataset reference includes a short Python join example: population, PM2.5, GHSL, congestion, Doing Business, ADM1 splits and ADM2 splits.