Accessing OS NGD API – Features via Python (Geopandas)
This example will provide an introduction on how to use OS NGD API – Features to extract and plot OS NGD data! We’ll be using GeoPandas, a library that builds on Pandas to help manage and analyse spatial data.
What you'll need
OS NGD API – Features added to an API project in the OS Data Hub with an API Key. See for more information.
More examples in an executable notebook format are available through our OS APIs Python wrapper.
1
Import the required libraries
import requests
import geopandas as gpd
from shapely.geometry import shape
2
Set up your OS API credentials
# OS NGD API - Features API Key
api_key = "INSERT_API_KEY"
# OS NGD API - Features base URL
base_url = "https://api.os.uk/features/ngd/ofa/v1"
# OS NGD API - Features CollectionId
collection= "wtr-fts-water-2"
3
Request data from OS NGD API - Features
# Define your bounding box
bbox = [-314177.76517933805,6641680.87433119,-304909.7754997604,6653318.411887609] # Example: Glastonbury Canal
# Initialize an empty list to collect all features
all_features = []
# Loop through 20 pages
for page in range(20):
offset = page * 100 # Calculate the offset based on the page number
params = {
"key": api_key,
"bbox": ",".join(map(str, bbox)),
"limit": 100,
"offset": offset,
"bbox-crs": "http://www.opengis.net/def/crs/EPSG/0/3857",
"crs": "http://www.opengis.net/def/crs/EPSG/0/3857",
}
# Send a request to the OS NGD API - Features
response = requests.get(f"{base_url}/collections/{collection}/items", params=params)
# Check if the request was successful
if response.status_code == 200:
data = response.json()
features = data.get("features", [])
all_features.extend(features)
if len(features) < params["limit"]: # Stop as there are no more features to retrieve
break
else:
print(f"Error: {response.status_code}")
break # Stop the loop in case of an error
4
Load data into a GeoPandas DataFrame
# Extract the geometries and attributes for each feature
geometry = [shape(feature["geometry"]) for feature in all_features]
attributes = [feature["properties"] for feature in all_features]
# Create a GeoDataFrame from the geometries and attributes
gdf = gpd.GeoDataFrame(attributes, geometry=geometry)
# Set the CRS of the GeoDataFrame to EPSG:3857 (Web Mercator)
gdf.set_crs("EPSG:3857", inplace=True)
5
Plot Data
# Plot the features
gdf.plot(figsize=(12,8),facecolor="#2d8fb6", edgecolor="#b19d3e", lw=0.05)