Leaflet
Accessing OS NGD API – Features via Leaflet
Leaflet is an open-source JavaScript library for displaying interactive maps on the web or mobile. A simple and lightweight library that will enable you to display and visualise location data and build dynamic applications.
What you'll need
OS Maps API and OS NGD API – Features added to an API project in the OS Data Hub with an API Key. See Getting started with an API project for more information.
A text editor like Visual Studio Code or Notepad to edit and save your HTML and JavaScript files.
Set up your HTML file
Create a new HTML file with a text editor (for example, Notepad, Visual Studio Code).
Add the basic HTML structure to your file with a placeholder
<div>
for the map.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OS NGD API – Features | Template (EPSG:3857) | Leaflet</title>
<!--Add the Ordnance Survey Styling-->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/OrdnanceSurvey/[email protected]/os-api-branding.css" />
<script src="https://cdn.jsdelivr.net/gh/OrdnanceSurvey/[email protected]/os-api-branding.js"></script>
<!--Add the Leaflet libraries-->
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<style>
/* Set the map container size and style */
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<!--Create a div element to hold the map-->
<div id="map"></div>
<!--Add your Javascript code below-->
<script>
// Your Javascript code will go here
</script>
</body>
</html>
Insert your API Key and OS NGD collection
To enable access to OS APIs an API Key is required. Inside the
<script>
tag, add a variable calledapiKey
, replacing'INSERT_API_KEY_HERE'
with the API Key from your project.Add a variable called
collectionID
, replacing'INSERT_COLLECTIONID_HERE'
with the collection ID for the desired OS NGD feature type and version (for example, bld-fts-buildingpart-1).
// Set API Key
const apiKey = 'INSERT_API_KEY_HERE';
const collectionId= 'INSERT_COLLECTIONID_HERE';
Add a basemap
Define the configuration options for the map, defining
minZoom
,maxZoom
,center
,zoom
,maxBounds
,attributionControl
.minZoom
andmaxZoom
: Sets the minimum and maximum zoom level for the map. Users will not be able to go beyond these levels.center
: Sets the initial centre point of the map.zoom
: Sets the initial zoom level of the map.maxBounds
: Defines the maximum bounds and restricts panning the map.style
: Defines the style of the map, configured via a URL pointing at the style specified.attributionControl
: When set to 'false', it hides the attribution control which displays map credits.
Initialize the map with the
id
of the<div>
element and the configuration option defined inmapOptions
.Using the '
L.tileLayer
' method, specify the basemap layer for OS Maps API, which includes your API Key to load the tiles to your map.
// Initialize the map.
const mapOptions = {
minZoom: 7,
maxZoom: 20,
center: [ 50.727589, -3.541809 ],
zoom: 18,
maxBounds: [
[ 49.528423, -10.76418 ],
[ 61.331151, 1.9134116 ]
],
attributionControl: false
};
const map = L.map('map', mapOptions);
// Load and display ZXY tile layer on the map.
const basemap = L.tileLayer(`https://api.os.uk/maps/raster/v1/zxy/Light_3857/{z}/{x}/{y}.png?key=${apiKey}`, {
maxZoom: 20
}).addTo(map);
Add an OS NGD API – Features layer
Create a function called
fetchFeatures
that fetches the API based on the current map extent (bounding box) by generating a bbox string.Construct the API request URL to fetch OS NGD data from OS NGD API – Features. The URL includes the
collectionId
,bbox
andapiKey
.Once the features have been returned in JSON, update the source data of the map's layers to display the features.
// Add layer group to make it easier to add or remove layers from the map.
const lyrGroup = new L.layerGroup().addTo(map);
// Define an asynchronous function to fetch and display the NGD Features API features.
async function fetchFeatures(bounds) {
// Generate a BBOX string for the map extent.
const bbox = bounds.toBBoxString();
// Construct the NGD Features API request URL.
const url = `https://api.os.uk/features/ngd/ofa/v1/collections/${collectionId}/items?key=${apiKey}&bbox=${bbox}`;
// Fetch features from the API endpoint.
const features = await fetch(url).then(response => response.json());
// Parse the GeoJSON data and display it on the map.
lyrGroup.clearLayers().addLayer(L.geoJSON(features));
}
// Get the visible map bounds (BBOX).
let bounds = map.getBounds();
// Initial fetch and display of features.
fetchFeatures(bounds);
Load and update features on the map dynamically
The map.on('moveend',...)
event handler fetches and updates the features based on the map's current extent.
// Add event which will be triggered when the map has finshed moving (pan + zoom).
// Implements a simple strategy to only request data when the map viewport invalidates
// certain bounds.
map.on('moveend', function() {
let bounds1 = new L.latLngBounds(bounds.getSouthWest(), bounds.getNorthEast()),
bounds2 = map.getBounds();
if( JSON.stringify(bounds) !== JSON.stringify(bounds1.extend(bounds2)) ) {
bounds = bounds2;
fetchFeatures(bounds);
}
});
Features within the viewport extent will load initially (first 100 features) and will continue to load as you pan and zoom across the map.
What's next?
Congratulations! You've successfully created a map using Leaflet and added an OS NGD layer using OS NGD API – Features in a few steps.
Now you can continue to explore Ordnance Survey's code examples to learn more about advanced features and functionality, such as adding markers, pop-ups, and additional layers.
Last updated
Was this helpful?