This Python script generates the Soil and Agricultural Data tables used by Doc #026 (Soil and Agricultural Data). It produces five structured reference tables: a regional soil summary covering dominant NZ Soil Classification orders, Land Use Capability distribution, pH ranges, and natural fertility by region; a full listing of the 14 NZSC soil orders with agricultural potential ratings; a Land Use Capability class table with area estimates; fertiliser requirement guidelines by crop; and a crop suitability matrix rating 10 crops across 14 regions using E/G/M/U ratings. It also generates a map of New Zealand showing dominant agricultural land capability tier by region, using GADM v4.1 Level 1 regional boundary polygons for accurate filled-region rendering.
Requirements: Python 3.6+ with matplotlib.
Also requires scripts/data/gadm41_NZL_1.json (GADM
v4.1 New Zealand Level 1 administrative boundaries; included in
the repository).
Usage:
python scripts/generate_soil_data.py
# Default output: tables-soil.md + site/images/soil-regions.png
Output: - tables-soil.md — five
tables covering regional soil summary, NZSC orders, LUC classes,
fertiliser requirements, and crop suitability, with source notes -
site/images/soil-regions.png — NZ agricultural land
capability map with GADM regional boundaries colour-coded by
dominant LUC tier
Source Code
#!/usr/bin/env python3
"""
Generate soil and agricultural data tables for the Recovery Library.
Produces:
- tables-soil.md — Regional Soil Summary, NZSC Orders, LUC Classes,
Fertiliser Requirements, Crop Suitability matrix
- site/images/soil-regions.png — NZ agricultural land capability map
Sources:
Manaaki Whenua Landcare Research, LRIS Portal, S-map Online.
Usage:
python generate_soil_data.py
Default outputs: ../tables-soil.md and ../site/images/soil-regions.png
"""
import json
import os
import sys
from datetime import datetime
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.patches import FancyBboxPatch
# ---------------------------------------------------------------------------
# Output paths
# ---------------------------------------------------------------------------
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
REPO_ROOT = os.path.dirname(SCRIPT_DIR)
MD_OUT = os.path.join(REPO_ROOT, "tables-soil.md")
IMG_DIR = os.path.join(REPO_ROOT, "site", "images")
IMG_OUT = os.path.join(IMG_DIR, "soil-regions.png")
COAST_JSON = os.path.join(SCRIPT_DIR, "data", "nz-coastline.json")
# ---------------------------------------------------------------------------
# Data tables
# ---------------------------------------------------------------------------
REGIONAL_SOIL = [
# (Region, Dominant NZSC orders, LUC distribution, pH range,
# Natural fertility, Key limitations, Best crop suitability)
("Northland",
"Brown, Allophanic, Ultic",
"III–V dominant, some VI–VII",
"5.0–6.0",
"Medium",
"High rainfall leaching, clay soils, rooting depth",
"Subtropical horticulture, avocado, kiwifruit, beef/dairy pasture"),
("Auckland",
"Brown, Granular, Recent",
"II–IV dominant, urban loss",
"5.5–6.5",
"Medium–High",
"Urban pressure, clay heaviness, drainage",
"Market gardening, viticulture, pipfruit, dairying"),
("Waikato",
"Allophanic, Brown, Peat/Organic",
"III–V dominant, peat areas VIII",
"5.0–6.2",
"High",
"Peaty areas, phosphorus retention in allophanic soils",
"Dairy (national core), maize silage, sheep/beef"),
("Bay of Plenty",
"Allophanic, Pumice, Brown",
"III–VI mixed",
"5.0–6.0",
"Medium",
"Phosphorus fixation (pumice), low base saturation",
"Kiwifruit, avocado, citrus, forestry, dairy"),
("Gisborne",
"Brown, Recent, Pallic",
"IV–VI dominant, erosion-prone VII",
"5.8–6.8",
"Medium",
"Erosion (East Coast), steep slopes, summer drought",
"Grapes, maize, sheep/beef, forestry"),
("Hawke's Bay",
"Pallic, Brown, Recent",
"I–III on plains, VI–VII hills",
"6.0–7.5",
"Medium–High",
"Summer drought, wind erosion on plains",
"Apples, grapes, vegetables, sheep/beef, arable"),
("Taranaki",
"Allophanic, Brown",
"III–IV dominant",
"5.2–6.2",
"High",
"Phosphorus retention, wetness, steep ring plain margins",
"Dairy (high producing), sheep/beef, maize"),
("Manawatu-Wanganui",
"Pallic, Brown, Recent, Allophanic",
"II–V plains, VI–VII ranges",
"5.8–6.8",
"Medium–High",
"Waterlogging (Pallic), ranges steep and erosion-prone",
"Arable (wheat, barley, maize), dairy, sheep/beef"),
("Wellington",
"Brown, Pallic, Recent",
"IV–VI dominant, some II–III lowlands",
"5.5–6.5",
"Medium",
"Wind, steep terrain, summer drought",
"Sheep/beef, market gardens (Wairarapa), viticulture"),
("Nelson-Tasman",
"Brown, Pallic, Recent",
"II–IV valleys, VI–VII hill/mountain",
"5.8–7.0",
"Medium",
"Drought risk (Nelson), steep hill terrain",
"Hops, apples, cherries, grapes, market vegetables"),
("Canterbury",
"Pallic, Brown, Recent, Semi-Arid",
"I–III plains, VII–VIII high country",
"6.0–7.5",
"Medium",
"Frost risk, drought (Canterbury Plains), irrigation dependency",
"Wheat, barley, peas, brassica seeds, dairy (irrigated), sheep/beef"),
("West Coast",
"Podzol, Brown, Gley, Organic",
"VI–VIII dominant, limited III–V",
"4.5–5.5",
"Low",
"Extreme rainfall, waterlogging, acidity, steep terrain",
"Dairy (river flats), sheep/beef (limited), forestry"),
("Otago",
"Pallic, Brown, Semi-Arid, Gley",
"II–III central basin, VI–VII ranges, VIII alpine",
"6.0–7.5",
"Low–Medium",
"Frost, drought (Central Otago), erosion, cold",
"Stone fruit (Central), grapes, merino/sheep, arable (Maniototo)"),
("Southland",
"Pallic, Gley, Brown, Recent",
"II–IV plains, VI–VII hills",
"5.5–6.5",
"Medium–High",
"Waterlogging, cold, slow mineralisation",
"Dairy, sheep/beef, arable (peas, cereals), fodder beet"),
]
NZSC_ORDERS = [
# (Order, Description, % NZ land, Typical fertility, Ag potential, Where found)
("Allophanic",
"Derived from volcanic ash; amorphous allophane/imogolite clays; high P-fixation",
"~9%", "High (if P managed)", "Good–Excellent",
"Waikato, Taranaki, Bay of Plenty, Central Plateau"),
("Brown",
"Most common order; moderate weathering; range of textures; free-draining",
"~28%", "Medium–High", "Good",
"Widespread: hill country, ranges, most regions"),
("Gley",
"Seasonally or permanently waterlogged; grey/blue mottles; reducing conditions",
"~8%", "Low–Medium (drainage needed)", "Marginal unless drained",
"Southland, West Coast, river flats, low-lying areas"),
("Granular",
"Old, deeply weathered; strong angular blocky structure; high Fe/Al oxides",
"~1%", "Low–Medium", "Moderate (horticulture)",
"Northern North Island (Auckland, Northland)"),
("Melanic",
"Dark, high base saturation; well-structured; derived from base-rich parent material",
"~1%", "High", "Excellent",
"Hawke's Bay, Marlborough (limestone/basalt)"),
("Organic",
"Peat soils; >30 cm organic matter accumulation; wet conditions",
"~2%", "Variable (nutrient release slow)", "Poor unless drained",
"Waikato (Hauraki Plains), Southland, West Coast"),
("Oxidic",
"Highly weathered; dominated by Fe/Al oxides; very old surfaces",
"<1%", "Low", "Poor",
"Far North (Northland relict surfaces)"),
("Pallic",
"Pale subsoil; moderate-high base saturation; seasonally waterlogged or droughty",
"~22%", "Medium", "Good (arable, pastoral)",
"Canterbury, Manawatu, Wairarapa, Southland, Otago"),
("Podzol",
"Strong leaching; distinct E horizon; low pH; Al/Fe illuviation",
"~9%", "Low", "Poor (forestry preferred)",
"West Coast, Fiordland, high-rainfall ranges"),
("Pumice",
"From rhyolitic pumice deposits; very low bulk density; low nutrients",
"~4%", "Low (micronutrient deficient)", "Marginal",
"Central Volcanic Plateau (Rotorua, Taupo area)"),
("Raw",
"Minimal soil development; thin or absent profile; exposed rock/regolith",
"~5%", "None", "None",
"Alpine areas, recent landslides, coastal dunes"),
("Recent",
"Young soils on recent alluvium or colluvium; limited horizon development",
"~7%", "Medium–High", "Good–Excellent (alluvial flats)",
"River flats nationwide: Waikato, Canterbury, Manawatu"),
("Semi-Arid",
"Dry climate; low leaching; carbonate or salt accumulation possible",
"~2%", "Low–Medium", "Marginal (irrigation transforms)",
"Central Otago, inland Marlborough"),
("Ultic",
"Strongly leached; low base saturation; argillic horizon; acid subsoil",
"~2%", "Low", "Poor–Marginal",
"Northland, parts of Auckland (old land surfaces)"),
]
LUC_CLASSES = [
# (Class, Description, Area ha, % NZ, Suitable uses, Limitations)
("I", "Virtually no limitations; flat, deep, well-drained, fertile",
"~260,000", "~1%",
"All crops, vegetables, intensive horticulture, arable",
"Almost none; highest capability class"),
("II", "Minor limitations; slight slope, minor drainage or fertility issues",
"~900,000", "~3%",
"Wide range of crops, horticulture, arable, pasture",
"Slight: minor drainage, minor wind risk, fertility"),
("III", "Moderate limitations; requires careful management",
"~1,800,000", "~7%",
"Most crops with management, pasture, some horticulture",
"Moderate slope, drainage, drought or erosion risk"),
("IV", "Severe limitations restricting crop choice",
"~2,200,000", "~8%",
"Pasture, limited arable crops, perennial horticulture",
"Severe slope, erosion, wetness, or fertility constraints"),
("V", "Not suited to cultivation; few limitations on pasture/forestry",
"~600,000", "~2%",
"Permanent pasture, forestry, wetland conservation",
"Flooding, wetness; cultivation impractical"),
("VI", "Permanent pasture or forestry; no cultivation",
"~4,500,000", "~17%",
"Pastoral farming, plantation forestry, native bush",
"Steep slopes, erosion, climate severity"),
("VII", "Severe limitations even for grazing; mostly forestry/conservation",
"~5,800,000", "~22%",
"Extensive grazing (limited), forestry, conservation",
"Very steep, very severe erosion, extreme climate"),
("VIII","No agricultural use; conservation, recreation, water catchment only",
"~10,400,000","~40%",
"Conservation, water catchment, recreation, wilderness",
"Alpine, bare rock, permanent snow/ice, active erosion"),
]
FERTILISER_REQS = [
# (Crop, N kg/ha, P kg/ha, K kg/ha, Lime t/ha, Micronutrients)
("Wheat (grain)", "120–180", "20–30", "40–60", "0–1.5 (pH 6.0+)", "Mn, Cu (trace)"),
("Barley (grain)", "80–120", "18–25", "30–50", "0–1.0 (pH 5.8+)", "Mn (occasional)"),
("Potatoes", "150–220", "35–50", "150–200","1.0–2.0 (pH 5.5+)","Mg, B, Mn, Zn"),
("Brassicas (veg)", "120–200", "30–40", "100–150","1.0–2.5 (pH 6.0+)","B, Mo, S"),
("Dairy pasture", "150–250", "25–40", "60–100", "0–2.0 (pH 5.8+)", "S, Mg, Cu, Co, Se"),
("Sheep/beef pasture", "0–80", "15–30", "30–60", "0–1.5 (pH 5.6+)", "S, Cu, Co, Se, Zn"),
("Maize (grain/silage)","150–220", "25–40", "80–130", "0–1.5 (pH 5.8+)", "Zn, S, Mg"),
("Peas/beans (legume)", "0–20", "20–30", "40–70", "0.5–2.0 (pH 6.0+)","Mo, B (rhizobium inoculant)"),
]
REGIONS = [
"Northland", "Auckland", "Waikato", "Bay of Plenty",
"Gisborne", "Hawke's Bay", "Taranaki", "Manawatu-Wanganui",
"Wellington", "Nelson-Tasman", "Canterbury", "West Coast",
"Otago", "Southland",
]
CROPS = ["Wheat", "Barley", "Potatoes", "Brassicas", "Maize", "Peas/Beans",
"Apples/Pipfruit", "Grapes/Wine", "Dairying", "Sheep/Beef"]
# Ratings: E=Excellent, G=Good, M=Marginal, U=Unsuitable
CROP_SUITABILITY = {
# Wheat Barley Potato Brass Maize Peas Apple Grape Dairy Sheep
"Northland": ["U", "U", "M", "G", "G", "M", "M", "M", "G", "G"],
"Auckland": ["U", "U", "G", "G", "G", "M", "G", "G", "G", "G"],
"Waikato": ["M", "M", "G", "G", "E", "M", "M", "M", "E", "G"],
"Bay of Plenty": ["U", "U", "M", "G", "G", "M", "G", "M", "G", "G"],
"Gisborne": ["G", "G", "M", "G", "G", "M", "M", "G", "M", "G"],
"Hawke's Bay": ["G", "G", "G", "G", "G", "G", "E", "E", "M", "G"],
"Taranaki": ["M", "M", "G", "G", "G", "M", "M", "U", "E", "G"],
"Manawatu-Wanganui": ["E","G", "G", "G", "E", "G", "G", "M", "G", "G"],
"Wellington": ["M", "M", "M", "G", "M", "G", "M", "G", "M", "G"],
"Nelson-Tasman": ["M", "M", "G", "G", "M", "G", "E", "G", "M", "G"],
"Canterbury": ["E", "E", "G", "E", "G", "E", "G", "G", "G", "G"],
"West Coast": ["U", "U", "M", "M", "U", "U", "U", "U", "M", "M"],
"Otago": ["G", "G", "M", "G", "M", "G", "E", "E", "M", "G"],
"Southland": ["G", "G", "G", "G", "M", "G", "M", "M", "E", "E"],
}
# ---------------------------------------------------------------------------
# Markdown generation
# ---------------------------------------------------------------------------
def md_header():
return f"""---
title: "Soil and Agricultural Data — New Zealand"
subtitle: "Recovery Library — Doc #026"
date: "{datetime.now().strftime('%Y-%m-%d')}"
---
# Soil and Agricultural Data — New Zealand
*Recovery Library — Doc #026*
This document provides reference data for agricultural land use, soil classification,
and crop production under post-disruption recovery conditions. All tables draw on
pre-disruption survey data compiled by Manaaki Whenua Landcare Research and the LRIS
Portal. Fertility and suitability ratings assume conventional inputs are available; see
Doc #027 for organic and low-input alternatives.

---
"""
def regional_soil_table():
out = "## 1. Regional Soil Summary\n\n"
out += ("Key soil characteristics and agricultural suitability by region. "
"LUC = Land Use Capability class (I = highest, VIII = non-productive). "
"Fertility ratings assume standard fertiliser inputs.\n\n")
out += ("| Region | Dominant NZSC Orders | LUC Classes | pH Range | "
"Natural Fertility | Key Limitations | Best Crop Suitability |\n")
out += ("|--------|---------------------|-------------|----------|"
"-------------------|-----------------|----------------------|\n")
for row in REGIONAL_SOIL:
region, orders, luc, ph, fert, lim, crops = row
out += f"| {region} | {orders} | {luc} | {ph} | {fert} | {lim} | {crops} |\n"
out += "\n"
return out
def nzsc_orders_table():
out = "## 2. NZ Soil Classification Orders\n\n"
out += ("New Zealand uses the New Zealand Soil Classification (NZSC) system "
"with 15 soil orders. Area percentages are approximate and refer to "
"total NZ land area including non-productive terrain.^[Hewitt, A.E. (2010). "
"*New Zealand Soil Classification*. 3rd ed. Manaaki Whenua Press.]\n\n")
out += ("| Order | Description | % NZ Area | Typical Fertility | "
"Agricultural Potential | Where Found |\n")
out += ("|-------|-------------|-----------|-------------------|"
"-----------------------|-------------|\n")
for row in NZSC_ORDERS:
order, desc, pct, fert, ag, where = row
out += f"| {order} | {desc} | {pct} | {fert} | {ag} | {where} |\n"
out += "\n"
return out
def luc_classes_table():
out = "## 3. Land Use Capability Classes\n\n"
out += ("The Land Use Capability (LUC) classification groups land into eight "
"classes based on the degree of limitation for sustained productive use. "
"Area figures are approximate; national coverage ~26.8 million ha total.^["
"Lynn, I.H. et al. (2009). *Land Use Capability Survey Handbook*. "
"3rd ed. Manaaki Whenua Press / AgResearch / Environment Canterbury.]\n\n")
out += ("| LUC Class | Description | Area (ha) | % of NZ | Suitable Uses | Limitations |\n")
out += ("|-----------|-------------|-----------|---------|---------------|-------------|\n")
for row in LUC_CLASSES:
cls, desc, area, pct, uses, lim = row
out += f"| **{cls}** | {desc} | {area} | {pct} | {uses} | {lim} |\n"
out += "\n"
return out
def fertiliser_table():
out = "## 4. Fertiliser Requirements by Crop\n\n"
out += ("Nutrient requirements per hectare at recommended application rates for "
"New Zealand conditions. Ranges reflect variation by soil type, yield target, "
"and region. N = nitrogen, P = phosphorus (as elemental P), K = potassium "
"(as elemental K). Lime rates target indicated minimum pH.^["
"Fertiliser Association of New Zealand. *Nutrient Management Guidelines*. "
"Current ed. See also: Edmeades, D.C. & Metherell, A.K. (2004). "
"*Nitrogen and Phosphorus in New Zealand Soils.* NZGA.]\n\n")
out += ("| Crop | N (kg/ha) | P (kg/ha) | K (kg/ha) | Lime (t/ha) | Micronutrient Needs |\n")
out += ("|------|-----------|-----------|-----------|-------------|--------------------|\n")
for row in FERTILISER_REQS:
crop, n, p, k, lime, micro = row
out += f"| {crop} | {n} | {p} | {k} | {lime} | {micro} |\n"
out += "\n"
return out
def crop_suitability_table():
out = "## 5. Crop Suitability by Region\n\n"
out += ("**Rating key:** E = Excellent (commercially viable, common practice); "
"G = Good (viable with standard management); "
"M = Marginal (possible in favourable years or with mitigation); "
"U = Unsuitable (climate, soil, or topography prohibitive).\n\n"
"Ratings assume adequate rainfall or irrigation where required. "
"Dairying rating reflects pasture production capacity rather than "
"enterprise economics. Ratings follow regional best-practice benchmarks.^["
"MPI. (2023). *Agricultural Production Statistics*. "
"Statistics New Zealand. S-map Online, LRIS Portal, Manaaki Whenua.]\n\n")
header = "| Region | " + " | ".join(CROPS) + " |"
sep = "|--------|" + "|".join(["-" * (len(c) + 2) for c in CROPS]) + "|"
out += header + "\n" + sep + "\n"
for region in REGIONS:
ratings = CROP_SUITABILITY[region]
row = f"| {region} | " + " | ".join(ratings) + " |"
out += row + "\n"
out += "\n"
return out
def footnotes():
return """---
## Sources and Notes
**Soil classification data:** Hewitt, A.E. (2010). *New Zealand Soil Classification*,
3rd edition. Manaaki Whenua — Landcare Research Science Series No. 1. Lincoln, NZ.
**Land Use Capability:** Lynn, I.H., Manderson, A.K., Page, M.J., Harmsworth, G.R.,
Eyles, G.O., Douglas, G.B., Mackay, A.D., Newsome, P.F.J. (2009). *Land Use Capability
Survey Handbook: A New Zealand Handbook for the Classification of Land*. 3rd ed.
AgResearch / Landcare Research / Environment Canterbury.
**Regional soil mapping:** S-map Online (smap.landcareresearch.co.nz),
Manaaki Whenua — Landcare Research. National soil map database.
**LRIS Portal:** Land Resource Information Systems Portal
(lris.scinfo.org.nz), Manaaki Whenua — Landcare Research. Accessed 2024.
**Fertiliser guidance:** Fertiliser Association of New Zealand (Fertmark);
Edmeades, D.C. & Metherell, A.K. (2004). *The Relationships between Soil Tests,
Fertiliser Inputs and Pasture Production in NZ.* NZ Grassland Association.
**Production statistics:** Ministry for Primary Industries / Statistics New Zealand.
*Agricultural Production Statistics* 2022–2023. Wellington, NZ.
*This document is part of the Recovery Library, a reference collection for
post-disruption resource recovery. Data reflects pre-disruption conditions as a
baseline. Soil properties and fertility responses under disrupted supply chains
(reduced fertiliser, equipment loss) are addressed in companion documents.*
"""
def generate_markdown():
os.makedirs(os.path.dirname(MD_OUT), exist_ok=True)
content = (
md_header()
+ regional_soil_table()
+ nzsc_orders_table()
+ luc_classes_table()
+ fertiliser_table()
+ crop_suitability_table()
+ footnotes()
)
with open(MD_OUT, "w", encoding="utf-8") as f:
f.write(content)
print(f"Written: {MD_OUT}")
# ---------------------------------------------------------------------------
# Map generation — uses GADM 4.1 NZ Level 1 regional boundaries
# ---------------------------------------------------------------------------
GADM_JSON = os.path.join(SCRIPT_DIR, "data", "gadm41_NZL_1.json")
# Dominant LUC capability tier for colouring (source: LRIS Portal / S-map)
# 1 = high (I-III), 2 = moderate (IV-V), 3 = limited (VI-VII), 4 = non-productive (VIII)
REGION_LUC_TIER = {
"Northland": 3,
"Auckland": 2,
"Waikato": 1,
"BayofPlenty": 2,
"Gisborne": 3,
"Hawke'sBay": 2,
"Taranaki": 2,
"Manawatu-Wanganui": 1,
"Wellington": 3,
"Nelson": 2,
"Tasman": 2,
"Marlborough": 3,
"Canterbury": 1,
"WestCoast": 4,
"Otago": 3,
"Southland": 1,
}
# Display names for labels
REGION_DISPLAY_NAMES = {
"BayofPlenty": "Bay of Plenty",
"Hawke'sBay": "Hawke's Bay",
"WestCoast": "West Coast",
"Manawatu-Wanganui": "Manawatu-\nWanganui",
}
TIER_COLORS = {
1: "#2d8a2d", # dark green — high capability LUC I–III
2: "#7ec850", # light green — moderate LUC IV–V
3: "#e0c840", # yellow — limited LUC VI–VII
4: "#a0a0a0", # gray — non-productive VIII
}
TIER_LABELS = {
1: "High capability (LUC I–III)",
2: "Moderate capability (LUC IV–V)",
3: "Limited capability (LUC VI–VII)",
4: "Non-productive (LUC VIII)",
}
# Regions to skip on the map (not part of main NZ landmass)
SKIP_REGIONS = {"ChathamIslands", "NorthernIslands", "SouthernIslands"}
def load_gadm_regions():
"""Load GADM NZ Level 1 regional boundaries."""
with open(GADM_JSON, "r", encoding="utf-8") as f:
data = json.load(f)
return data["features"]
def gadm_centroid(feature):
"""Compute approximate centroid of a GADM feature (largest polygon only)."""
geom = feature["geometry"]
# Find the polygon with the most points (= the main land area)
best_ring = None
best_len = 0
for mp in geom["coordinates"]:
ring = mp[0] # exterior ring
if len(ring) > best_len:
best_len = len(ring)
best_ring = ring
if best_ring is None:
return (172.0, -42.0)
lons = [pt[0] for pt in best_ring]
lats = [pt[1] for pt in best_ring]
return (sum(lons) / len(lons), sum(lats) / len(lats))
def generate_map():
os.makedirs(IMG_DIR, exist_ok=True)
from matplotlib.patches import Polygon as MplPolygon
features = load_gadm_regions()
fig, ax = plt.subplots(figsize=(8, 11))
ax.set_facecolor("#d6eaf8")
fig.patch.set_facecolor("#f5f5f0")
# Draw each GADM region
for feat in features:
name = feat["properties"]["NAME_1"]
if name in SKIP_REGIONS:
continue
tier = REGION_LUC_TIER.get(name)
if tier is None:
continue
color = TIER_COLORS[tier]
geom = feat["geometry"]
# Draw all polygons in this MultiPolygon
for mp in geom["coordinates"]:
ring = mp[0] # exterior ring
if len(ring) < 3:
continue
coords = [(pt[0], pt[1]) for pt in ring]
poly = MplPolygon(
coords, closed=True,
facecolor=color, alpha=0.55,
edgecolor="#555555", linewidth=0.4,
zorder=2,
)
ax.add_patch(poly)
# Region labels at centroids of largest polygon
for feat in features:
name = feat["properties"]["NAME_1"]
if name in SKIP_REGIONS or name not in REGION_LUC_TIER:
continue
cx, cy = gadm_centroid(feat)
display = REGION_DISPLAY_NAMES.get(name, name)
ax.text(
cx, cy, display,
fontsize=5.5, fontweight="bold", color="#222222",
ha="center", va="center", zorder=4,
)
# Axes formatting
ax.set_xlim(165.5, 179.0)
ax.set_ylim(-47.5, -34.0)
ax.set_aspect("equal")
ax.set_xlabel("Longitude (°E)", fontsize=8)
ax.set_ylabel("Latitude (°S)", fontsize=8)
ax.tick_params(labelsize=7)
# Title
ax.set_title(
"NZ Agricultural Land Capability\n(Dominant LUC Tier by Region)",
fontsize=11, fontweight="bold", pad=10
)
# Legend
legend_patches = [
mpatches.Patch(facecolor=TIER_COLORS[t],
edgecolor="#333333",
linewidth=0.7,
label=TIER_LABELS[t])
for t in sorted(TIER_COLORS)
]
ax.legend(
handles=legend_patches,
loc="lower left",
fontsize=7,
title="Agricultural Land Capability",
title_fontsize=7.5,
framealpha=0.9,
edgecolor="#888888",
)
# Source note
fig.text(
0.5, 0.01,
"Boundaries: GADM v4.1 (gadm.org), CC BY 4.0. "
"Soil classification: Manaaki Whenua Landcare Research.",
ha="center", fontsize=5.5, color="#666666",
style="italic"
)
plt.tight_layout(rect=[0, 0.03, 1, 1])
fig.savefig(IMG_OUT, dpi=200, bbox_inches="tight")
plt.close(fig)
print(f"Written: {IMG_OUT}")
# ---------------------------------------------------------------------------
# Entry point
# ---------------------------------------------------------------------------
if __name__ == "__main__":
generate_markdown()
generate_map()
print("Done.")Data Sources
- Manaaki Whenua Landcare Research — S-map Online (smap.landcareresearch.co.nz); LRIS Portal (lris.scinfo.org.nz). National soil mapping and land resource information systems. Primary source for NZSC order distributions and regional soil characterisation.
- Hewitt, A.E. (2010) — New Zealand Soil Classification, 3rd edition. Manaaki Whenua — Landcare Research Science Series No. 1. Lincoln, NZ. Primary reference for NZSC orders, descriptions, and area percentages.
- Lynn, I.H. et al. (2009) — Land Use Capability Survey Handbook: A New Zealand Handbook for the Classification of Land, 3rd ed. AgResearch / Landcare Research / Environment Canterbury. Primary reference for LUC class descriptions and area estimates.
- Fertiliser Association of New Zealand (Fertmark) — Nutrient Management Guidelines (current edition). Basis for N/P/K application rates by crop.
- Edmeades, D.C. & Metherell, A.K. (2004) — The Relationships between Soil Tests, Fertiliser Inputs and Pasture Production in NZ. NZ Grassland Association. Cross-reference for pasture fertiliser requirements.
- MPI / Statistics New Zealand — Agricultural Production Statistics 2022-2023. Wellington, NZ. Basis for crop suitability regional benchmarking.
- GADM v4.1 — Global Administrative Areas
database, Level 1 boundaries for New Zealand
(
scripts/data/gadm41_NZL_1.json). Used for regional boundary polygons in the map. Source: gadm.org. Licensed under CC BY 4.0.