OpenLayers

Accessing OS NGD API – Tiles via OpenLayers

OpenLayers is a free and open-source JavaScript library for displaying interactive maps on the web. It is a powerful tool that can be used to create a wide variety of map-based applications, from simple web maps to complex GIS applications.

OpenLayers is easy to use and can be integrated with a variety of other web development frameworks.

What you'll need

  • OS NGD API – Tiles added to an API project in the OS Data Hub with an API Key.

  • A text editor like Visual Studio Code or Notepad to edit and save your HTML and JavaScript files.

Create a basic vector map

Step 1: Set up your HTML file

  1. Create a new HTML file with a text editor (for example, Notepad, Visual Studio Code).

  2. 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 – Tiles | Template (EPSG:3857) | OpenLayers</title>
    
    <!--Add the Ordnance Survey Styling-->
    <link rel="stylesheet" href="https://labs.os.uk/public/os-api-branding/v0.3.1/os-api-branding.css" />
    <script src="https://labs.os.uk/public/os-api-branding/v0.3.1/os-api-branding.js"></script>
    
    <!--Add the OpenLayers libraries-->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v7.3.0/ol.css" />
    <script src="https://cdn.jsdelivr.net/npm/ol@v7.3.0/dist/ol.js"></script>
    <script src="https://unpkg.com/ol-mapbox-style@9.7.0/dist/olms.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>

Step 2: Insert your API Key

  1. To enable access to OS APIs an API Key is required. Inside the <script> tag, add a variable called apiKey, replacing 'INSERT_API_KEY_HERE' with the API Key from your project.

  2. Inside the <script> tag, add another variable called collectionId with the collection ID for the OS NGD API – Tiles basemap – ngd-base.

// Set API Key and collection ID
 const apiKey = 'INSERT_API_KEY_HERE';
 
 const collectionId = 'ngd-base';

Step 3: Tile grid set up

  1. To correctly render the vector tiles within OpenLayers, you will need to fetch the defined EPSG:3857 Tile Matrix Set and style definitions from the OS NGD API – Tiles service. The two endpoints provide information about the structure of the vector tiles and how the styles are to be applied.

  2. A promise.all is used to process the data to ensure that both requests are completed before proceeding.

  3. Based on the fetched Tile Matrix Set data, a tile grid is defined using the ol.tilegrid.TileGrid class. The tile grid provides information about the resolution, origin and tile sizes to handle the vector tiles correctly.

  4. Add the following code inside the JavaScript block:

// Define the Tile Grid and style

const tmsPromise = fetch('https://api.os.uk/maps/vector/ngd/ota/v1/tilematrixsets/3857').then((response) => response .json());
const glStylePromise = fetch(`https://api.os.uk/maps/vector/ngd/ota/v1/collections/${collectionId}/styles/3857`).then((response) => response .json());

Promise.all([tmsPromise, glStylePromise]).then((values) => {
    const tms = values[0];
    const glStyle = values[1];

    const tilegrid = new ol.tilegrid.TileGrid({
        resolutions: tms.tileMatrices.map(({ cellSize }) => cellSize),
        origin: tms.tileMatrices[0].pointOfOrigin,
        tileSize: [ tms.tileMatrices[0].tileHeight, tms.tileMatrices[0].tileWidth ]
    });

Step 4: Define a vector tile layer

  1. Define the a new vector tiles layer and source that will be used to fetch vector tiles from OS NGD API – Tiles. The ol.layer.VectorTile uses a ol.source.OGCVectorTile source to retrieve tiles from the API.

  2. After creating the vector layer, you will need to use a style function to ensure that the Ordnance Survey styles are applied to each tile. Use the olms.applyStyle function to retrieve the style sheets available for the basemap.

// Define the vector tile layer.
    const formatMvt = new ol.format.MVT();
    formatMvt.supportedMediaTypes.push('application/octet-stream');

    const vectorTileLayer = new ol.layer.VectorTile({
        source: new ol.source.OGCVectorTile({
            url: `https://api.os.uk/maps/vector/ngd/ota/v1/collections/${collectionId}/tiles/3857?key=${apiKey}`,
            format: formatMvt,
            projection: 'EPSG:3857',
            tileGrid: tilegrid
        }),
        declutter: true
    });

// Apply a style function to the vector tile layer.
    olms.applyStyle(
        vectorTileLayer,
        glStyle,
        collectionId,
        { styleUrl: null } ,
        tilegrid.getResolutions()
    );

Step 5: Create a map and map view

  1. Initialize the map object using the ol.map class to configure the vector tile layer and define its properties – target, layers and view.

// Initialize the map object.
    const map = new ol.Map({
        layers: [ vectorTileLayer ],
        target: 'map',
        view: new ol.View({
            projection: 'EPSG:3857',
            extent: ol.proj.transformExtent([ -10.76418, 49.528423, 1.9134116, 61.331151 ], 'EPSG:4326', 'EPSG:3857'),
            resolutions: tilegrid.getResolutions(),
            minZoom: 6,
            maxZoom: 19,
            center: ol.proj.fromLonLat([ -3.541809, 50.727589 ]),
            zoom: 17
        })
    });
});

The above code creates the main map instance using the OpenLayers library where you can specify various properties:

  • target: Defines where the map should be displayed. In this instance it is set to the ID of the <div> element.

  • layers: An array containing the layers to be added to the map.

  • view: Defines the initial view of the main, containing various settings such as projection, extent (the geographic bounds of the map), minimum and maximum zoom levels, centre of the map and the initial zoom level.

What's next?

Congratulations! You've successfully created a vector map using OpenLayers using OS NGD API – Tiles 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