Skip to content

Commit 442d751

Browse files
committed
Map view - IMD
1 parent ea5bcc9 commit 442d751

File tree

7 files changed

+322
-49
lines changed

7 files changed

+322
-49
lines changed

app/javascript/projects/analysis_panel_tools/subsection.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export interface ChartData {
2828
inputHistogramBins: number
2929
}
3030

31-
function findColor(value: number, colorArray: any[]): Color {
31+
export function findColor(value: number, colorArray: any[]): Color {
3232
var index = Math.floor(value * (colorArray.length / 2))
3333
index = Math.min(index, colorArray.length / 2 - 1)
3434
var alpha = colorArray[index * 2]

app/javascript/projects/layer_palette.tsx

+21
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { KewOption, Layer } from './state'
55
import { iconForLayerType } from "./util"
66
import { CompiledDatasetRecord } from './saved_dataset'
77
import { designations } from './modelling/designations'
8+
import { IMDProperties } from './reify_layer/imd'
89

910
interface AddLayerButtonProps {
1011
prototype: Layer
@@ -304,6 +305,26 @@ export const LayerPalette = ({ addLayer, hide, dbModels, getTeamDatasets, teamNa
304305
)
305306
}
306307
</Section>
308+
<Section title="Indices of Multiple Deprivation">
309+
{
310+
Array<{ year: number }>(
311+
{ year: 2019 }
312+
).map(({ year }) =>
313+
<AddLayerButton
314+
addLayer={addLayer}
315+
prototype={{
316+
type: "IMDLayer",
317+
name: `Indices of Multiple Deprivation ${year}`,
318+
visible: true,
319+
opacity: 1,
320+
fill: "jet",
321+
property: IMDProperties[0],
322+
year
323+
}}
324+
/>
325+
)
326+
}
327+
</Section>
307328
<Section title="UKCEH Land Cover Maps">
308329
<AddLayerButton
309330
addLayer={addLayer}

app/javascript/projects/modelling/components/imd_component.ts

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { Feature } from "ol"
99
import { Geometry } from "ol/geom"
1010
import { NumericTileGrid } from "../tile_grid"
1111
import { createXYZ } from "ol/tilegrid"
12-
import { format } from "mathjs"
1312

1413
interface OutputFormat {
1514
name: string
+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import VectorLayer from "ol/layer/Vector"
2+
import { IMDLayer } from "../state"
3+
import BaseLayer from "ol/layer/Base"
4+
import { memoize } from "lodash"
5+
import VectorSource from "ol/source/Vector"
6+
import { Fill, Stroke, Style, Text } from "ol/style"
7+
import GeoJSON from "ol/format/GeoJSON"
8+
import { bbox } from "ol/loadingstrategy"
9+
import { Map } from "ol"
10+
import { getColorStops } from "./model_output"
11+
import { findColor } from "../analysis_panel_tools/subsection"
12+
13+
interface IMDProperty {
14+
name: string
15+
propName: string
16+
min: number
17+
max: number
18+
}
19+
20+
export const IMDProperties: IMDProperty[] = [
21+
{
22+
name: "IMD - Decile",
23+
propName: "IMD_Decile",
24+
min: 10,
25+
max: 1
26+
},
27+
{
28+
name: "IMD - Rank",
29+
propName: "IMD_Rank",
30+
min: 32844,
31+
max: 1
32+
},
33+
{
34+
name: "Income - Decile",
35+
propName: "IncDec",
36+
min: 10,
37+
max: 1
38+
},
39+
{
40+
name: "Income - Rank",
41+
propName: "IncRank",
42+
min: 32844,
43+
max: 1
44+
},
45+
{
46+
name: "Employment - Decile",
47+
propName: "EmpDec",
48+
min: 10,
49+
max: 1
50+
},
51+
{
52+
name: "Employment - Rank",
53+
propName: "EmpRank",
54+
min: 32844,
55+
max: 1
56+
},
57+
{
58+
name: "Education, Skills and Training - Decile",
59+
propName: "EduDec",
60+
min: 10,
61+
max: 1
62+
},
63+
{
64+
name: "Education, Skills and Training - Rank",
65+
propName: "EduRank",
66+
min: 32844,
67+
max: 1
68+
},
69+
{
70+
name: "Health Deprivation and Disability - Decile",
71+
propName: "HDDec",
72+
min: 10,
73+
max: 1
74+
},
75+
{
76+
name: "Health Deprivation and Disability - Rank",
77+
propName: "HDDRank",
78+
min: 32844,
79+
max: 1
80+
},
81+
{
82+
name: "Crime - Decile",
83+
propName: "CriDec",
84+
min: 10,
85+
max: 1
86+
},
87+
{
88+
name: "Crime - Rank",
89+
propName: "CriRank",
90+
min: 32844,
91+
max: 1
92+
},
93+
{
94+
name: "Barriers to Housing and Services - Decile",
95+
propName: "BHSDec",
96+
min: 10,
97+
max: 1
98+
},
99+
{
100+
name: "Barriers to Housing and Services - Rank",
101+
propName: "BHSRank",
102+
min: 32844,
103+
max: 1
104+
},
105+
{
106+
name: "Living Environment - Decile",
107+
propName: "EnvDec",
108+
min: 10,
109+
max: 1
110+
},
111+
{
112+
name: "Living Environment - Rank",
113+
propName: "EnvRank",
114+
min: 32844,
115+
max: 1
116+
}
117+
]
118+
119+
export type IMDProp = typeof IMDProperties[number]
120+
121+
const imdSource = memoize(() =>
122+
new VectorSource({
123+
url: extent => `https://landscapes.wearepal.ai/geoserver/shapefiles/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=shapefiles:IMD_2019&outputFormat=application/json&bbox=${extent.join(',')},EPSG:3857&crs=EPSG:3857`,
124+
format: new GeoJSON(),
125+
strategy: bbox,
126+
attributions: '&copy; <a href="https://data.cdrc.ac.uk/dataset/index-multiple-deprivation-imd">Consumer Data Research Centre</a>'
127+
})
128+
)
129+
130+
const styleFn = memoize((colMap : any[], prop : IMDProperty) =>
131+
(feature) => {
132+
133+
const val = feature.get(prop.propName)
134+
const [min, max] = prop.min > prop.max ? [prop.max, prop.min] : [prop.min, prop.max]
135+
const normalisedValue = prop.min > prop.max ? 1 - (val - min) / (max - min) : (val - min) / (max - min)
136+
const col = findColor(normalisedValue, colMap)
137+
138+
return new Style({
139+
fill: new Fill({ color: `rgba(${col[0]}, ${col[1]}, ${col[2]}, 1)`})
140+
})
141+
}
142+
)
143+
144+
export function reifyIMDLayer(layer: IMDLayer, existingLayer: BaseLayer | null, map: Map) {
145+
146+
const colMap = getColorStops(layer.fill === "heatmap" ? "jet" : (layer.fill === "greyscale" ? "greys" : layer.fill), 100).reverse()
147+
148+
return new VectorLayer({
149+
source: imdSource(),
150+
style: styleFn(colMap, layer.property),
151+
})
152+
}
153+

app/javascript/projects/reify_layer/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { reifyBoundaryLayer } from './boundary'
1717
import { reifyGeoserverWMSLayer } from './geoserver'
1818
import { reifyKewLayer } from './kew'
1919
import { reifyOrvalLayer } from './orval'
20+
import { reifyIMDLayer } from './imd'
2021

2122
export const reifyLayer = (layer: Layer, existingLayer: BaseLayer | null, dbModels: DBModels, map: Map, modelOutputCache: ModelOutputCache, DatasetCache: DatasetCache, loadteamDataset: (layer: DatasetLayer) => void): BaseLayer => {
2223
const layerType = layer.type
@@ -35,6 +36,7 @@ export const reifyLayer = (layer: Layer, existingLayer: BaseLayer | null, dbMode
3536
case "MLLayer": return reifyGeoserverWMSLayer(layer, existingLayer)
3637
case "KewLayer": return reifyKewLayer(layer, existingLayer, map)
3738
case "ORValLayer": return reifyOrvalLayer(layer, existingLayer, map)
39+
case "IMDLayer": return reifyIMDLayer(layer, existingLayer, map)
3840
default: {
3941
// Ensure this switch statement is exhaustive
4042
const unreachable: never = layerType

0 commit comments

Comments
 (0)