Geographic Data
The kindtech.geo module provides access to UK geographic boundary data from the ONS ArcGIS Geoportal.
Functions
load_geodata()
Load geographic boundary data as GeoJSON.
from kindtech.geo import load_geodata, GeographyType, CoverageArea, BoundaryType
# Using strings
data = load_geodata(geography_type="LAD", coverage="UK", boundary_type="BGC")
# Using enums
data = load_geodata(
geography_type=GeographyType.LAD,
coverage=CoverageArea.UK,
boundary_type=BoundaryType.BGC,
)
# With filters
manchester = load_geodata(geography_type="LAD", LAD21NM="Manchester")
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
geography_type |
str or GeographyType |
required | Geography level (e.g., "LAD", "LSOA") |
year |
str or None |
None |
Year of the data (e.g., "2021") |
month |
str, Month, or None |
None |
Month (e.g., "DEC", Month.DEC) |
coverage |
str, CoverageArea, or None |
None |
Coverage area ("UK", "GB", "EW") |
boundary_type |
str, BoundaryType, or None |
"BGC" |
Boundary resolution |
**filters |
keyword args | Field filters (e.g., LAD21NM="Manchester") |
Returns
dict — A GeoJSON FeatureCollection. Returns {"type": "FeatureCollection", "features": []} if no matching service is found or the request fails.
get_field_info()
Get available fields for filtering a dataset.
from kindtech.geo import get_field_info
fields = get_field_info(geography_type="LAD")
# [{"name": "LAD21CD", "type": "esriFieldTypeString", "alias": "LAD Code"}, ...]
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
geography_type |
str or GeographyType |
required | Geography level |
year |
str or None |
None |
Year |
coverage |
str, CoverageArea, or None |
None |
Coverage area |
boundary_type |
str, BoundaryType, or None |
None |
Boundary resolution |
Returns
list[dict] — Field metadata from ArcGIS (name, type, alias, etc.).
get_available_geography_types()
List all supported geography types.
from kindtech.geo import get_available_geography_types
types = get_available_geography_types()
# [{"code": "LAD", "description": "Local Authority Districts"}, ...]
get_available_boundary_types()
List all supported boundary resolutions.
get_available_coverage_areas()
List all supported coverage areas.
Enums
All enums accept both string codes and enum values. They have .code and .description attributes.
| Enum | Values | Example |
|---|---|---|
GeographyType |
LAD, LSOA, MSOA, ... | GeographyType.LAD |
BoundaryType |
BFC, BFE, BGC, BSC | BoundaryType.BGC |
CoverageArea |
UK, GB, EW | CoverageArea.UK |
Month |
JAN through DEC | Month.DEC |
geodata_to_properties()
Extract feature properties from GeoJSON with normalised column names for easy joins with ONS data.
from kindtech import load_geodata, geodata_to_properties
import pandas as pd
geojson = load_geodata(geography_type="LAD")
rows = geodata_to_properties(geojson, "LAD", 2024)
geo_df = pd.DataFrame(rows)
# geo_df has 'geography_code' and 'geography_name' columns
# plus all original ArcGIS properties (LAD24CD, LAD24NM, etc.)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
geojson |
dict |
required | GeoJSON FeatureCollection from load_geodata() |
geography_type |
str or GeographyType |
required | Geography level (e.g., "LAD", "LSOA") |
year |
int or str |
required | Year of the data (e.g., 2024) |
Returns
list[dict] — One dict per feature, containing:
geography_code— normalised geography code (e.g.E06000001), derived from the year-stamped ArcGIS field (e.g.LAD24CD)geography_name— normalised geography name (e.g.Hartlepool), derived from the year-stamped ArcGIS field (e.g.LAD24NM)- All original ArcGIS properties preserved as-is
The normalised geography_code column matches the column produced by load_ons(normalize=True), enabling trivial joins:
from kindtech import load_geodata, load_ons, geodata_to_properties
import pandas as pd
geojson = load_geodata(geography_type="LAD")
geo_df = pd.DataFrame(geodata_to_properties(geojson, "LAD", 2024))
ons_df = load_ons("population", geography_type="LAD", time="latest")
merged = geo_df.merge(ons_df, on="geography_code")
How it works
- The bundled CSV catalog (
geo/data/arcgis_services.csv, 615 services across 24 geography types) maps geography type + year + coverage + boundary to an ArcGIS service ID load_geodata()finds the best matching service (most recent year if not specified)- Queries the ArcGIS FeatureServer REST API for GeoJSON
- Returns the raw GeoJSON FeatureCollection
geodata_to_properties()extracts feature properties and adds normalisedgeography_code/geography_namecolumns usinggeo_code_field()andgeo_name_field()from the internal mapping module