# Leaflet

[Leaflet](https://leafletjs.com/) 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 NGD API – Tiles added to an API project in the OS Data Hub with an API Key. See [Getting started with an API project](/os-apis/core-concepts/getting-started-with-an-api-project.md) for more information.
* A text editor like Visual Studio Code or Notepad to edit and save your HTML and JavaScript files.

{% stepper %}
{% step %}

### 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.

```html
<!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) | Leaflet</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 Leaflet libraries-->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css" />
    <link rel="stylesheet" href="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css" />
    <script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script>
    <script src="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js"></script>
    <script src="https://unpkg.com/@maplibre/maplibre-gl-leaflet@0.0.19/leaflet-maplibre-gl.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>
```

{% endstep %}

{% step %}

### Insert your API Key

* 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.
* Inside the `<script>` tag, add another variable called `collectionId`with the collection ID for the OS NGD API – Tiles basemap – `ngd-base`.

```javascript
// Set API Key and collection ID
 const apiKey = 'INSERT_API_KEY_HERE';

 const collectionId = 'ngd-base';
```

{% endstep %}

{% step %}

### Adding a fetch and response interceptor

* We need to intercept and customise the style request, adding a tiles property to provide a correctly formatted URL and ensure authentication through the `apiKey` is enabled to make sure that the correct tiles are requested.
* Add the following code inside the JavaScript block:

```javascript
// Modify the JSON style request incorporate a `tiles` property which lists an array of tile endpoints.
// The '&key=' HTTP query parameter is also appended to each tile endpoint to authenticate the request.
// NOTE: The {z}, {x} and {y} template values are replaced with the corresponding integers at runtime.
    const { fetch: originalFetch } = window;
    window.fetch = async (...args) => {
        let [ resource, config ] = args;

        let response = await originalFetch(resource, config);
        if( response.url != `https://api.os.uk/maps/vector/ngd/ota/v1/collections/${collectionId}/styles/3857` )
            return response;

        // Response interceptor.
        const json = () =>
            response.clone().json().then((data) => {
                delete data.sources[ collectionId ].url;
                data.sources[ collectionId ].tiles = [ `https://api.os.uk/maps/vector/ngd/ota/v1/collections/${collectionId}/tiles/3857/{z}/{y}/{x}?key=${apiKey}` ];
                return data;
            });

        response.json = json;
        return response;
    };
```

{% endstep %}

{% step %}

### Create a map and map view

* Initialize the map object using the `L.Map` class to configure the vector tile layer and the `mapOptions` variable to define its properties – `minZoom`, `maxZoom`, `maxBounds`, `center`and `zoom`.

```javascript
// 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 vector tile layer on the map.
    const gl = L.maplibreGL({
        style: `https://api.os.uk/maps/vector/ngd/ota/v1/collections/${collectionId}/styles/3857`
    }).addTo(map);
```

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

* `minZoom` and `maxZoom`: Sets the minimum and maximum zoom level for the map. Users will not be able to go beyond these levels.
* `maxBounds`: Defines the maximum bounds and restricts panning the map.
* `center`: Sets the initial centre point of the map.
* `zoom`: Sets the initial zoom level of the map.
  {% endstep %}
  {% endstepper %}

### What's next?

Congratulations! You've successfully created a vector map using Leaflet using OS NGD API – Tiles in a few steps.

Now you can continue to explore Ordnance Survey's [code examples](https://labs.os.uk/public/osngd/os-ngd-api-tiles/) to learn more about advanced features and functionality, such as adding markers, pop-ups, and additional layers.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.os.uk/os-apis/accessing-os-apis/os-ngd-api-tiles/getting-started/libraries/leaflet.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
