Skip to content

Commit 8420eb3

Browse files
DF-1105: Interactive map - replace UMD with ESM (#419)
* Interactive map - replace UMD with ESM * Remove reverse geocode proxy capability
1 parent 598ff20 commit 8420eb3

21 files changed

Lines changed: 262 additions & 386 deletions

File tree

jest.config.cjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ module.exports = {
5757
'geodesy' // Supports ESM only
5858
].join('|')}/)`
5959
],
60+
moduleNameMapper: {
61+
'^@defra/interactive-map$':
62+
'<rootDir>/test/__mocks__/@defra/interactive-map.js',
63+
'^@defra/interactive-map/plugins/datasets/adapters/(.*)$':
64+
'<rootDir>/test/__mocks__/@defra/interactive-map/plugins/datasets/adapters/$1.js',
65+
'^@defra/interactive-map/plugins/(.*)$':
66+
'<rootDir>/test/__mocks__/@defra/interactive-map/plugins/$1.js',
67+
'^@defra/interactive-map/providers/(.*)$':
68+
'<rootDir>/test/__mocks__/@defra/interactive-map/providers/$1.js'
69+
},
6070
testTimeout: 10000,
6171
forceExit: true
6272
}

package-lock.json

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@
130130
"joi": "^17.13.3",
131131
"liquidjs": "^10.24.0",
132132
"lodash": "^4.17.21",
133+
"maplibre-gl": "^5.24.0",
133134
"marked": "^15.0.12",
134135
"nunjucks": "^3.2.4",
135136
"obscenity": "^0.4.5",

src/client/javascripts/geospatial-map.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
// @ts-expect-error - no types
2+
import createDatasetsPlugin from '@defra/interactive-map/plugins/datasets'
3+
// @ts-expect-error - no types
4+
import { maplibreLayerAdapter } from '@defra/interactive-map/plugins/datasets/adapters/maplibre'
5+
// @ts-expect-error - no types
6+
import createDrawPlugin from '@defra/interactive-map/plugins/draw-ml'
17
import { bbox } from '@turf/bbox'
28

39
import {
@@ -151,9 +157,6 @@ export function getBoundingBox(geojson) {
151157
* @param {number} index - the 0-based index
152158
*/
153159
export function processGeospatial(config, geospatial, index) {
154-
// @ts-expect-error - Defra namespace currently comes from UMD support files
155-
const defra = window.defra
156-
157160
if (!(geospatial instanceof HTMLDivElement)) {
158161
return
159162
}
@@ -166,14 +169,15 @@ export function processGeospatial(config, geospatial, index) {
166169
const { listEl, mapId } = createContainers(geospatialInput, index)
167170
const geojson = getGeoJSON(geospatialInput)
168171
const bounds = geojson.features.length ? getBoundingBox(geojson) : undefined
169-
const drawPlugin = defra.drawMLPlugin()
172+
const drawPlugin = createDrawPlugin()
170173
const plugins = [drawPlugin]
171174
const country = geospatial.dataset.country
172175

173176
if (country) {
174177
// Add the country bounds as a dataset plugin to show the valid area on the map
175178
// and provide feedback to the user when they add features outside of the bounds.
176-
const datasetsPlugin = defra.datasetsMaplibrePlugin({
179+
const datasetsPlugin = createDatasetsPlugin({
180+
layerAdapter: maplibreLayerAdapter,
177181
datasets: [
178182
{
179183
id: 'invalid-area',

src/client/javascripts/map.js

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
// @ts-expect-error - no types
2+
import InteractiveMap from '@defra/interactive-map'
3+
// @ts-expect-error - no types
4+
import createInteractPlugin from '@defra/interactive-map/plugins/interact'
5+
// @ts-expect-error - no types
6+
import createMapStylesPlugin from '@defra/interactive-map/plugins/map-styles'
7+
// @ts-expect-error - no types
8+
import createScaleBarPlugin from '@defra/interactive-map/plugins/scale-bar'
9+
// @ts-expect-error - no types
10+
import createSearchPlugin from '@defra/interactive-map/plugins/search'
11+
// @ts-expect-error - no types
12+
import maplibreProvider from '@defra/interactive-map/providers/maplibre'
113
import { centroid } from '@turf/centroid'
214
// @ts-expect-error - no types
315
import OsGridRef, { LatLon } from 'geodesy/osgridref.js'
@@ -249,24 +261,17 @@ export function makeTileRequestTransformer(apiPath) {
249261
export function createMap(mapId, initConfig, mapsConfig) {
250262
const { assetPath, apiPath, data = defaultData } = mapsConfig
251263
const logoAltText = 'Ordnance survey logo'
252-
253-
// @ts-expect-error - Defra namespace currently comes from UMD support files
254-
const defra = window.defra
255-
256-
const interactPlugin = defra.interactPlugin({
264+
const interactPlugin = createInteractPlugin({
257265
markerColor: { outdoor: '#ff0000', dark: '#00ff00' },
258266
interactionModes: ['placeMarker'],
259267
multiSelect: false
260268
})
261269

262270
/** @type {InteractiveMap} */
263-
const map = new defra.InteractiveMap(mapId, {
271+
const map = new InteractiveMap(mapId, {
264272
enableFullscreen: true,
265273
autoColorScheme: false,
266-
mapProvider: defra.maplibreProvider(),
267-
reverseGeocodeProvider: defra.openNamesProvider({
268-
url: `${apiPath}/reverse-geocode-proxy?easting={easting}&northing={northing}`
269-
}),
274+
mapProvider: maplibreProvider(),
270275
behaviour: 'inline',
271276
minZoom: 6,
272277
maxZoom: 18,
@@ -275,7 +280,7 @@ export function createMap(mapId, initConfig, mapsConfig) {
275280
transformRequest: makeTileRequestTransformer(apiPath),
276281
...initConfig,
277282
plugins: [
278-
defra.mapStylesPlugin({
283+
createMapStylesPlugin({
279284
mapStyles: [
280285
{
281286
id: 'outdoor',
@@ -319,12 +324,12 @@ export function createMap(mapId, initConfig, mapsConfig) {
319324
]
320325
}),
321326
interactPlugin,
322-
defra.searchPlugin({
327+
createSearchPlugin({
323328
osNamesURL: `${apiPath}/geocode-proxy?query={query}`,
324329
width: '300px',
325330
showMarker: false
326331
}),
327-
defra.scaleBarPlugin({
332+
createScaleBarPlugin({
328333
units: 'metric'
329334
}),
330335
...(initConfig.plugins ?? [])

src/client/stylesheets/shared.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
@use "summary-list";
55
@use "location-fields";
66

7+
@use "@defra/interactive-map/css" as core;
8+
@use "@defra/interactive-map/plugins/interact/css" as interact;
9+
@use "@defra/interactive-map/plugins/map-styles/css" as mapStyles;
10+
@use "@defra/interactive-map/plugins/search/css" as search;
11+
@use "@defra/interactive-map/plugins/scale-bar/css" as scaleBar;
12+
@use "@defra/interactive-map/plugins/draw-ml/css" as drawMl;
13+
714
// Use default GDS Transport font for autocomplete
815
.autocomplete__hint,
916
.autocomplete__input,

src/server/plugins/map/routes/index.js

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { StatusCodes } from 'http-status-codes'
66
import Joi from 'joi'
77

88
import { getAccessToken } from '~/src/server/plugins/map/routes/get-os-token.js'
9-
import { find, nearest } from '~/src/server/plugins/map/service.js'
9+
import { find } from '~/src/server/plugins/map/service.js'
1010
import {
1111
get,
1212
request as httpRequest
@@ -34,7 +34,6 @@ export function getRoutes(options) {
3434
mapProxyRoute(options),
3535
tileProxyRoute(options),
3636
geocodeProxyRoute(options),
37-
reverseGeocodeProxyRoute(options),
3837
getGeospatialCountries()
3938
]
4039
}
@@ -156,41 +155,6 @@ function geocodeProxyRoute(options) {
156155
}
157156
}
158157

159-
/**
160-
* Proxies ordnance survey reverse geocode requests from the front end to api.os.uk
161-
* Used to find name from easting and northing points.
162-
* N.B this endpoint is currently not used by the front end but will be soon in "maps V2"
163-
* @param {MapConfiguration} options - the map options
164-
* @returns {ServerRoute<MapReverseGeocodeGetRequestRefs>}
165-
*/
166-
function reverseGeocodeProxyRoute(options) {
167-
return {
168-
method: 'GET',
169-
path: '/api/reverse-geocode-proxy',
170-
async handler(request, _h) {
171-
const { query } = request
172-
const data = await nearest(
173-
query.easting,
174-
query.northing,
175-
options.ordnanceSurveyApiKey
176-
)
177-
178-
return data
179-
},
180-
options: {
181-
auth: false,
182-
validate: {
183-
query: Joi.object()
184-
.keys({
185-
easting: Joi.number().required(),
186-
northing: Joi.number().required()
187-
})
188-
.required()
189-
}
190-
}
191-
}
192-
}
193-
194158
/**
195159
* Resource routes to return sprites and glyphs
196160
* @returns {ServerRoute<MapProxyGetRequestRefs>}

src/server/plugins/map/service.js

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,6 @@ export async function find(query, apiKey) {
6767
return getData(url, endpoint)
6868
}
6969

70-
/**
71-
* OS names search nearest by E/N
72-
* @param {number} easting - the easting
73-
* @param {number} northing - the northing
74-
* @param {string} apiKey - the OS api key
75-
*/
76-
export async function nearest(easting, northing, apiKey) {
77-
const endpoint = 'nearest'
78-
const url = `https://api.os.uk/search/names/v1/nearest?key=${apiKey}&point=${easting},${northing}&radius=1000&fq=local_type:Airfield%20local_type:Airport%20local_type:Bus_Station%20local_type:Chemical_Works%20local_type:City%20local_type:Coach_Station%20local_type:Electricity_Distribution%20local_type:Electricity_Production%20local_type:Further_Education%20local_type:Gas_Distribution_or_Storage%20local_type:Hamlet%20local_type:Harbour%20local_type:Helicopter_Station%20local_type:Heliport%20local_type:Higher_or_University_Education%20local_type:Hill_Or_Mountain%20local_type:Hospice%20local_type:Hospital%20local_type:Medical_Care_Accommodation%20local_type:Named_Road%20local_type:Non_State_Primary_Education%20local_type:Non_State_Secondary_Education%20local_type:Other_Settlement%20local_type:Passenger_Ferry_Terminal%20local_type:Port_Consisting_of_Docks_and_Nautical_Berthing%20local_type:Postcode%20local_type:Primary_Education%20local_type:Railway_Station%20local_type:Road_User_Services%20local_type:Secondary_Education%20local_type:Section_Of_Named_Road%20local_type:Section_Of_Numbered_Road%20local_type:Special_Needs_Education%20local_type:Suburban_Area%20local_type:Town%20local_type:Urban_Greenspace%20local_type:Vehicular_Ferry_Terminal%20local_type:Vehicular_Rail_Terminal%20local_type:Village%20local_type:Waterfall%20`
79-
80-
return getData(url, endpoint)
81-
}
82-
8370
/**
8471
* @import { OsNamesFindResponse, OsNamesFindResult } from '~/src/server/plugins/map/types.js'
8572
*/

src/server/plugins/map/service.test.js

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import Boom from '@hapi/boom'
22

33
import * as service from '~/src/server/plugins/map/service.js'
44
import { result as findResult } from '~/src/server/plugins/map/test/__stubs__/find.js'
5-
import { result as nearestResult } from '~/src/server/plugins/map/test/__stubs__/nearest.js'
65
import { getJson } from '~/src/server/services/httpService.js'
76

87
jest.mock('~/src/server/services/httpService.ts')
@@ -88,55 +87,6 @@ describe('Maps service', () => {
8887
expect(results).toEqual([])
8988
})
9089
})
91-
92-
describe('nearest', () => {
93-
it('should return entries', async () => {
94-
jest.mocked(getJson).mockResolvedValueOnce({
95-
res: /** @type {IncomingMessage} */ ({
96-
statusCode: 200,
97-
headers: {}
98-
}),
99-
payload: nearestResult,
100-
error: undefined
101-
})
102-
103-
const { results } = await service.nearest(700000, 1300000, 'apikey')
104-
105-
expect(results).toHaveLength(1)
106-
expect(results.at(0)).toEqual({
107-
GAZETTEER_ENTRY: {
108-
ID: 'NW26XE',
109-
NAMES_URI: 'http://data.ordnancesurvey.co.uk/id/postcodeunit/NW26XE',
110-
NAME1: 'NW2 6XE',
111-
TYPE: 'other',
112-
LOCAL_TYPE: 'Postcode',
113-
GEOMETRY_X: 523065,
114-
GEOMETRY_Y: 185795,
115-
MOST_DETAIL_VIEW_RES: 3500,
116-
LEAST_DETAIL_VIEW_RES: 18000,
117-
POPULATED_PLACE: 'London',
118-
POPULATED_PLACE_URI:
119-
'http://data.ordnancesurvey.co.uk/id/4000000074813508',
120-
POPULATED_PLACE_TYPE:
121-
'http://www.ordnancesurvey.co.uk/xml/codelists/localtype.xml#city',
122-
DISTRICT_BOROUGH: 'Brent',
123-
DISTRICT_BOROUGH_URI:
124-
'http://data.ordnancesurvey.co.uk/id/7000000000011447',
125-
DISTRICT_BOROUGH_TYPE:
126-
'http://data.ordnancesurvey.co.uk/ontology/admingeo/LondonBorough',
127-
COUNTY_UNITARY: 'Greater London',
128-
COUNTY_UNITARY_URI:
129-
'http://data.ordnancesurvey.co.uk/id/7000000000041441',
130-
COUNTY_UNITARY_TYPE:
131-
'http://data.ordnancesurvey.co.uk/ontology/admingeo/GreaterLondonAuthority',
132-
REGION: 'London',
133-
REGION_URI: 'http://data.ordnancesurvey.co.uk/id/7000000000041428',
134-
COUNTRY: 'England',
135-
COUNTRY_URI: 'http://data.ordnancesurvey.co.uk/id/country/england'
136-
}
137-
})
138-
})
139-
})
14090
})
14191

14292
/**

src/server/plugins/map/test/__stubs__/nearest.js

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)