perfect-postcode/pipeline/download/conservation_areas.py
2026-05-25 13:20:17 +01:00

51 lines
1.6 KiB
Python

"""Download Historic England conservation area polygons.
Source: Historic England Conservation Areas
License: Open Government Licence v3.0
"""
import argparse
from pathlib import Path
import httpx
import pyogrio
URL = (
"https://opendata-historicengland.hub.arcgis.com/api/download/v1/items/"
"446bc9bf8b5b440386d0c504caa3dac5/geoPackage?layers=0"
)
def main() -> None:
parser = argparse.ArgumentParser(
description="Download Historic England conservation area polygons"
)
parser.add_argument(
"--output", type=Path, required=True, help="Output GeoPackage file path"
)
args = parser.parse_args()
args.output.parent.mkdir(parents=True, exist_ok=True)
tmp_path = args.output.with_name(f"{args.output.stem}.tmp{args.output.suffix}")
print("Downloading Historic England conservation areas...")
with httpx.stream("GET", URL, follow_redirects=True, timeout=300) as response:
response.raise_for_status()
with tmp_path.open("wb") as fh:
for chunk in response.iter_bytes():
fh.write(chunk)
info = pyogrio.read_info(tmp_path)
features = info.get("features", 0)
geometry_type = info.get("geometry_type")
if features <= 0:
raise ValueError("Downloaded conservation areas file contains no features")
if "Polygon" not in str(geometry_type):
raise ValueError(f"Expected polygon geometry, got {geometry_type!r}")
tmp_path.replace(args.output)
size_mb = args.output.stat().st_size / (1024 * 1024)
print(f"Saved {features} conservation areas to {args.output} ({size_mb:.1f} MB)")
if __name__ == "__main__":
main()