Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions demo/map-test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Node.js ignores
node_modules/

# Prototype ignores - per-user
.tmp/
.env
migrate.log

# General ignores
.DS_Store
.idea

# Local consumer-install artifacts (regenerate with scripts/install-local-packages.sh)
.tarballs/
package-lock.json
3 changes: 3 additions & 0 deletions demo/map-test/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
audit=false
ignore-scripts=true
allow-git=none
21 changes: 21 additions & 0 deletions demo/map-test/LICENCE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License

Copyright (C) 2014 Crown Copyright (Government Digital Service)

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
25 changes: 25 additions & 0 deletions demo/map-test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Defra Interactive Map Test

A GOV.UK Prototype Kit site with a collection of examples using the DEFRA InteractiveMap component, imported from [defra-design/map-test](https://github.com/defra-design/map-test).

The purpose of this site is **accessibility testing only**. It provides a consistent set of scenarios to verify accessibility behaviour, identify issues, and validate fixes across different browsers, assistive technologies, and devices.

It also validates the UMD builds through the exact consumer path: each provider and plugin is installed as its own packed npm package (`@defra/interactive-map-provider-maplibre`, `@defra/interactive-map-plugin-search`, …) so npm resolves peer dependencies for real. Every package ships a `govuk-prototype-kit.config.json`, so the prototype kit serves each package's `dist` at `/plugin-assets/<encoded package name>/dist/…` and every page loads the bundles from there with standard `<script src>` tags — no bundler involved.

## Running locally

```bash
./scripts/install-local-packages.sh # build monorepo, pack each package,
# npm install the tarballs
cp ../../.env .env # OS vector tile style URLs (OS_API_KEY needed
# for tiles to render)
npm run dev
```

The script is the local stand-in for `npm install @defra/interactive-map @defra/interactive-map-provider-maplibre …` from the registry: the packages aren't published yet on this branch, so it packs them from the monorepo instead. Everything downstream of `npm pack` — tarball contents, peer dependency resolution, file layout, prototype kit plugin registration — is what a real consumer gets. Re-run the script after changing library source.

## Public Test Site

The public test site (built from the original repository) is available here:

[Defra Interactive Map Test Site](https://map-test-63a349157ea3.herokuapp.com/)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions demo/map-test/app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//
// For guidance on how to add JavaScript see:
// https://prototype-kit.service.gov.uk/docs/adding-css-javascript-and-images
//

window.GOVUKPrototypeKit.documentReady(() => {
// Add JavaScript here
})
6 changes: 6 additions & 0 deletions demo/map-test/app/assets/sass/application.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//
// For guidance on how to add CSS and SCSS see:
// https://prototype-kit.service.gov.uk/docs/adding-css-javascript-and-images
//

// Add extra styles here
9 changes: 9 additions & 0 deletions demo/map-test/app/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"serviceName": "InteractiveMap",
"useServiceNavigation": false,
"plugins": {
"govuk-frontend": {
"rebrand": true
}
}
}
5 changes: 5 additions & 0 deletions demo/map-test/app/data/session-data-defaults.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {

// Insert values here

}
10 changes: 10 additions & 0 deletions demo/map-test/app/filters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//
// For guidance on how to create filters see:
// https://prototype-kit.service.gov.uk/docs/filters
//

const govukPrototypeKit = require('govuk-prototype-kit')
const addFilter = govukPrototypeKit.views.addFilter

// Add your filters here

78 changes: 78 additions & 0 deletions demo/map-test/app/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//
// For guidance on how to create routes see:
// https://prototype-kit.service.gov.uk/docs/create-routes
//

const govukPrototypeKit = require('govuk-prototype-kit')
const router = govukPrototypeKit.requests.setupRouter()

// Add your routes here

// Ordnance Survey Vector Tile API stylesheets, keyed by the style id used in the views
const OS_VECTOR_TILE_STYLES = {
outdoor: process.env.VTS_OUTDOOR_URL,
dark: process.env.VTS_DARK_URL,
'black-and-white': process.env.VTS_BLACK_AND_WHITE_URL
}

// Cache the upstream stylesheets so we only fetch each one from GitHub once
const styleCache = {}

// Inject the OS API key into a stylesheet's tile, glyph and sprite endpoints.
// The key is kept in the .env file and added server-side so it is never committed
// to the views.
function applyOsApiKey (style, apiKey) {
const styleWithKey = structuredClone(style)

Object.values(styleWithKey.sources || {}).forEach((source) => {
if (source.url?.includes('api.os.uk')) {
source.tiles = [`https://api.os.uk/maps/vector/v1/vts/tile/{z}/{y}/{x}.pbf?srs=3857&key=${apiKey}`]
delete source.url
}
})

if (styleWithKey.glyphs?.includes('api.os.uk')) {
styleWithKey.glyphs += `${styleWithKey.glyphs.includes('?') ? '&' : '?'}key=${apiKey}`
}

styleWithKey.sprite = `https://api.os.uk/maps/vector/v1/vts/resources/sprites/sprite?key=${apiKey}`

return styleWithKey
}

// This runs on ALL pages and passes variables to Nunjucks
router.use((req, res, next) => {
res.locals.OS_API_KEY = process.env.OS_API_KEY
res.locals.OS_NEAREST_URL = process.env.OS_NEAREST_URL

// next() tells Express to move on to loading the actual page
next()
})

// Serve an OS Vector Tile API stylesheet with the API key applied, e.g.
// /os-vector-tile-styles/outdoor
router.get('/os-vector-tile-styles/:style', async (req, res) => {
const styleId = req.params.style
const sourceUrl = OS_VECTOR_TILE_STYLES[styleId]

if (!sourceUrl) {
return res.status(404).json({ error: `Unknown map style '${styleId}'` })
}

try {
if (!styleCache[styleId]) {
const response = await fetch(sourceUrl)

if (!response.ok) {
throw new Error(`Failed to fetch stylesheet (${response.status})`)
}

styleCache[styleId] = await response.json()
}

res.json(applyOsApiKey(styleCache[styleId], process.env.OS_API_KEY))
} catch (error) {
console.error(`Unable to load OS Vector Tile stylesheet '${styleId}':`, error)
res.status(502).json({ error: 'Unable to load map style' })
}
})
143 changes: 143 additions & 0 deletions demo/map-test/app/views/add-polygons.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
{% extends "layouts/main.html" %}

{% block pageTitle %}
11. Add polygons – GOV.UK Prototype Kit
{% endblock %}

{% block head %}
<link href="/public/stylesheets/application.css" rel="stylesheet" type="text/css">
<link href="/plugin-assets/%40defra%2Finteractive-map/dist/css/index.css" rel="stylesheet" type="text/css">
<link href="/plugin-assets/%40defra%2Finteractive-map-plugin-datasets/dist/css/index.css" rel="stylesheet" type="text/css">
{% endblock %}

{% block bodyStart %}
<script>document.body.classList.add('im-is-loading')</script>
{% endblock %}

{% block beforeContent %}
{{ govukBackLink({
text: "Back",
href: "javascript:window.history.back()"
}) }}
{% endblock %}

{% block content %}
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">

<h1 class="govuk-heading-l">
11. Add polygons
</h1>

<div id="map"></div>

</div>
</div>
{% endblock %}

{% block pageScripts %}
<!-- Defra library scripts -->
<script src="/plugin-assets/%40defra%2Finteractive-map/dist/umd/index.js"></script>
<script src="/plugin-assets/%40defra%2Finteractive-map-provider-maplibre/dist/umd/index.js"></script>
<script src="/plugin-assets/%40defra%2Finteractive-map-plugin-datasets/dist/umd/index.js"></script>

<script>
// GeoJSON can also be loaded from a URL; use the tiles property for vector tile sources
const geojson = {
type: 'FeatureCollection',
features: [{
type: 'Feature',
id: 1,
properties: { name: 'Feature 1', land_use: 'Permanent grassland' },
geometry: { type: 'Polygon', coordinates: [[[-2.4691585,54.5552164],[-2.4692202,54.5553906],[-2.4690646,54.5554155],[-2.4690002,54.5555088],[-2.4690297,54.5556690],[-2.4690995,54.5557919],[-2.4669269,54.5566971],[-2.4662375,54.5562819],[-2.4637780,54.5574391],[-2.4628580,54.5568169],[-2.4607612,54.5560985],[-2.4608248,54.5560719],[-2.4611789,54.5558914],[-2.4613774,54.5558168],[-2.4615973,54.5557577],[-2.4617475,54.5557297],[-2.4618816,54.5556519],[-2.4620104,54.5556115],[-2.4624771,54.5555275],[-2.4627131,54.5555150],[-2.4628741,54.5554839],[-2.4630082,54.5554404],[-2.4632335,54.5553346],[-2.4633944,54.5552164],[-2.4634749,54.5551106],[-2.4635178,54.5550235],[-2.4635285,54.5548213],[-2.4635768,54.5546346],[-2.4635875,54.5544884],[-2.4636090,54.5544075],[-2.4636465,54.5543515],[-2.4636573,54.5542769],[-2.4636358,54.5541804],[-2.4637377,54.5540155],[-2.4639094,54.5538724],[-2.4643493,54.5535831],[-2.4645370,54.5535084],[-2.4647141,54.5534804],[-2.4648052,54.5534836],[-2.4648213,54.5535116],[-2.4648750,54.5535396],[-2.4650842,54.5535893],[-2.4652451,54.5536516],[-2.4652719,54.5536796],[-2.4653900,54.5537355],[-2.4655455,54.5537853],[-2.4658459,54.5539502],[-2.4663556,54.5542738],[-2.4668008,54.5545164],[-2.4668330,54.5545506],[-2.4668437,54.5546782],[-2.4668598,54.5547031],[-2.4670798,54.5548306],[-2.4671817,54.5549053],[-2.4674177,54.5549364],[-2.4677664,54.5550484],[-2.4681956,54.5551448],[-2.4684101,54.5551759],[-2.4691129,54.5552195],[-2.4691585,54.5552164]]] }
}, {
type: 'Feature',
id: 2,
properties: { name: 'Feature 2', land_use: 'Arable' },
geometry: { type: 'Polygon', coordinates: [[[-2.4611682,54.5562375],[-2.4628580,54.5568161],[-2.4636841,54.5573753],[-2.4637793,54.5574398],[-2.4641401,54.5576751],[-2.4642567,54.5577999],[-2.4641307,54.5578823],[-2.4636841,54.5582502],[-2.4624221,54.5592884],[-2.4623376,54.5592534],[-2.4615370,54.5586429],[-2.4611869,54.5582852],[-2.4605258,54.5581071],[-2.4598472,54.5578186],[-2.4611682,54.5562375]]] }
}, {
type: 'Feature',
id: 3,
properties: { name: 'Feature 3', land_use: 'Arable' },
geometry: { type: 'Polygon', coordinates: [[[-2.4598472,54.5578186],[-2.4605258,54.5581067],[-2.4611869,54.5582852],[-2.4615376,54.5586433],[-2.4623108,54.5592332],[-2.4623376,54.5592534],[-2.4624221,54.5592884],[-2.4623108,54.5594120],[-2.4616731,54.5601189],[-2.4586053,54.5601189],[-2.4584410,54.5600299],[-2.4580038,54.5596574],[-2.4581815,54.5593953],[-2.4585778,54.5590702],[-2.4587287,54.5589353],[-2.4589198,54.5586736],[-2.4591116,54.5582136],[-2.4598472,54.5578186]]] }
}, {
type: 'Feature',
id: 4,
properties: { name: 'Feature 4', land_use: 'Permanent grassland' },
geometry: { type: 'Polygon', coordinates: [[[-2.4633756,54.5612877],[-2.4613908,54.5604315],[-2.4624221,54.5592884],[-2.4641307,54.5578823],[-2.4642567,54.5577999],[-2.4653631,54.5591733],[-2.4659613,54.5597013],[-2.4633756,54.5612877]]] }
}, {
type: 'Feature',
id: 5,
properties: { name: 'Feature 5', land_use: 'Arable' },
geometry: { type: 'Polygon', coordinates: [[[-2.4678040,54.5590679],[-2.4661879,54.5595952],[-2.4659613,54.5597013],[-2.4653638,54.5591737],[-2.4642567,54.5577999],[-2.4641401,54.5576751],[-2.4637793,54.5574398],[-2.4662369,54.5562822],[-2.4669282,54.5566975],[-2.4678040,54.5563320],[-2.4678040,54.5590679]]] }
}, {
type: 'Feature',
id: 6,
properties: { name: 'Feature 6', land_use: 'Permanent grassland' },
geometry: { type: 'Polygon', coordinates: [[[-2.4669316,54.5603767],[-2.4676430,54.5613102],[-2.4673292,54.5614556],[-2.4671616,54.5617468],[-2.4658446,54.5625528],[-2.4651546,54.5621528],[-2.4639215,54.5633040],[-2.4633146,54.5633040],[-2.4628372,54.5630921],[-2.4631195,54.5628195],[-2.4643741,54.5618374],[-2.4665071,54.5604793],[-2.4667056,54.5604187],[-2.4669316,54.5603767]]] }
}, {
type: 'Feature',
id: 7,
properties: { name: 'Feature 7', land_use: 'Woodland' },
geometry: { type: 'Polygon', coordinates: [[[-2.4599129,54.5564203],[-2.4599773,54.5565478],[-2.4599773,54.5565852],[-2.4599344,54.5566256],[-2.4596876,54.5566069],[-2.4594945,54.5566132],[-2.4593657,54.5566505],[-2.4592584,54.5567158],[-2.4592048,54.5567780],[-2.4591780,54.5568496],[-2.4591887,54.5569616],[-2.4591297,54.5570829],[-2.4590009,54.5572726],[-2.4589419,54.5573162],[-2.4588561,54.5574686],[-2.4587435,54.5575588],[-2.4586684,54.5575837],[-2.4585879,54.5575962],[-2.4584001,54.5575837],[-2.4583304,54.5575899],[-2.4580836,54.5576397],[-2.4579817,54.5576895],[-2.4579227,54.5576988],[-2.4578154,54.5576988],[-2.4576384,54.5576739],[-2.4574614,54.5576739],[-2.4573044,54.5577050],[-2.4563093,54.5573092],[-2.4563871,54.5569849],[-2.4564891,54.5560664],[-2.4565601,54.5559039],[-2.4567747,54.5559412],[-2.4571985,54.5559817],[-2.4573219,54.5560097],[-2.4576116,54.5560936],[-2.4582446,54.5562181],[-2.4584913,54.5562959],[-2.4590331,54.5563705],[-2.4599129,54.5564203]]] }
}]
}

const datasetsPlugin = defra.datasetsPlugin({
datasets: [{
id: 'field-geojson',
label: 'Field geojson',
geojson: geojson,
minZoom: 10,
maxZoom: 24,
showInKey: true,
showInMenu: true,
sublayers: [{
id: 'arable',
label: 'Arable',
filter: ['==', ['get', 'land_use'], 'Arable'],
style: {
stroke: '#6D4C41',
fillPattern: 'horizontal-hatch',
fillPatternForegroundColor: '#6D4C41',
fillPatternBackgroundColor: 'transparent'
}
}, {
id: 'permanent-grassland',
label: 'Permanent grassland',
filter: ['==', ['get', 'land_use'], 'Permanent grassland'],
style: {
stroke: '#00897B',
fillPattern: 'diagonal-cross-hatch',
fillPatternForegroundColor: '#00897B',
fillPatternBackgroundColor: 'transparent'
}
}, {
id: 'woodland',
label: 'Woodland',
filter: ['==', ['get', 'land_use'], 'Woodland'],
style: {
stroke: '#2E7D32',
fillPattern: 'dot',
fillPatternForegroundColor: '#2E7D32',
fillPatternBackgroundColor: 'transparent'
}
}]
}]
})

new defra.InteractiveMap('map', {
behaviour: 'inline',
mapProvider: defra.maplibreProvider(),
mapStyle: {
url: '/os-vector-tile-styles/outdoor',
attribution: `Contains OS data © Crown copyright and database rights ${new Date().getFullYear()}`,
backgroundColor: '#f5f5f0'
},
center: [-2.9631689, 54.4323129],
zoom: 15,
containerHeight: '516px',
plugins: [datasetsPlugin]
})
</script>
{% endblock %}
Loading
Loading