Skip to content

Commit

Permalink
Merge pull request #459 from wearepal/natmap-soil-mapview
Browse files Browse the repository at this point in the history
NATMAP Soil carbon on map view
  • Loading branch information
paulthatjazz authored Dec 2, 2024
2 parents 736ae83 + 852b757 commit 0487472
Show file tree
Hide file tree
Showing 6 changed files with 243 additions and 70 deletions.
20 changes: 20 additions & 0 deletions app/javascript/projects/layer_palette.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { IMDProperties } from './reify_layer/imd'
import { ProjectPermissions } from './project_editor'
import { KewPointOptions } from './reify_layer/kew'
import { seasonYearOptions } from './modelling/components/kew_samples_component'
import { natmap_outputs } from './modelling/components/natmap_soil_component'

interface AddLayerButtonProps {
prototype: Layer
Expand Down Expand Up @@ -330,6 +331,25 @@ export const LayerPalette = ({ addLayer, hide, dbModels, getTeamDatasets, teamNa
/>)
}
</Section>
{
permissions.NATMAPSoil &&
<Section title="Natmap Soil">
<AddLayerButton
addLayer={addLayer}
prototype={{
type: "WFSLayer",
name: "Natmap Soil Carbon",
layer: "cranfield_soil:NATMAPcarbon",
attribution: "Cranfield University",
propIdx: 0,
visible: true,
opacity: 1,
fill: "jet"
}}
/>

</Section>
}
{
dbModels.overlays.length > 0 &&
<Section title="Overlays">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,134 +15,172 @@ interface NatmapSoilOptions extends SelectControlOptions {
key: string
socket: Socket
unit: string
min: number
max: number
}

const natmap_outputs : NatmapSoilOptions[] = [
export const natmap_outputs : NatmapSoilOptions[] = [
{
id: 0,
name: 'Min Carbon stock 0-10cm (kg/m²)',
key: 'MIN_STK_10',
socket: numericDataSocket,
unit: 'kg/m^2'
unit: 'kg/m^2',
min: 0,
max: 82.32000000000
},
{
id: 1,
name: 'Max Carbon stock 0-10cm (kg/m²)',
key: 'MAX_STK_10',
socket: numericDataSocket,
unit: 'kg/m^2'
unit: 'kg/m^2',
min: 0,
max: 95.13000000000
},
{
id: 2,
name: 'Min Carbon stock 0-15cm (kg/m²)',
key: 'MIN_STK_15',
socket: numericDataSocket,
unit: 'kg/m^2'
unit: 'kg/m^2',
min: 0,
max: 59.64000000000
},
{
id: 3,
name: 'Max Carbon stock 0-15cm (kg/m²)',
key: 'MAX_STK_15',
socket: numericDataSocket,
unit: 'kg/m^2'
unit: 'kg/m^2',
min: 0,
max: 59.64000000000
},
{
id: 4,
name: 'Min Carbon stock 0-30cm (kg/m²)',
key: 'MIN_STK_30',
socket: numericDataSocket,
unit: 'kg/m^2'
unit: 'kg/m^2',
min: 0,
max: 35.45000000000
},
{
id: 5,
name: 'Max Carbon stock 0-30cm (kg/m²)',
key: 'MAX_STK_30',
socket: numericDataSocket,
unit: 'kg/m^2'
unit: 'kg/m^2',
min: 0,
max: 63.23000000000
},
{
id: 6,
name: 'Average Carbon stock 0-30cm (kg/m²)',
key: 'AV_STK_30',
socket: numericDataSocket,
unit: 'kg/m^2'
unit: 'kg/m^2',
min: 0,
max: 51.07000000000
},
{
id: 7,
name: 'Average Carbon stock 30-100cm (kg/m²)',
key: 'AV_STK_100',
socket: numericDataSocket,
unit: 'kg/m^2'
unit: 'kg/m^2',
min: 0,
max: 86.19000000000
},
{
id: 8,
name: 'Average Carbon stock 100-150cm (kg/m²)',
key: 'AV_STK_150',
socket: numericDataSocket,
unit: 'kg/m^2'
unit: 'kg/m^2',
min: 0,
max: 59.64000000000
},
{
id: 9,
name: 'Average Organic Carbon 0-30cm (%)',
key: 'AV_OC_30',
socket: numericDataSocket,
unit: '%'
unit: '%',
min: 0,
max: 100
},
{
id: 10,
name: 'Min Organic Carbon 0-30cm (%)',
key: 'MIN_OC_30',
socket: numericDataSocket,
unit: '%'
unit: '%',
min: 0,
max: 100
},
{
id: 11,
name: 'Max Organic Carbon 0-30cm (%)',
key: 'MAX_OC_30',
socket: numericDataSocket,
unit: '%'
unit: '%',
min: 0,
max: 100
},
{
id: 12,
name: 'Average Organic Carbon 30-100cm (%)',
key: 'AV_OC_100',
socket: numericDataSocket,
unit: '%'
unit: '%',
min: 0,
max: 100
},
{
id: 13,
name: 'Min Organic Carbon 30-100cm (%)',
key: 'MIN_OC_100',
socket: numericDataSocket,
unit: '%'
unit: '%',
min: 0,
max: 100
},
{
id: 14,
name: 'Max Organic Carbon 30-100cm (%)',
key: 'MAX_OC_100',
socket: numericDataSocket,
unit: '%'
unit: '%',
min: 0,
max: 100
},
{
id: 15,
name: 'Average Organic Carbon 100-150cm (%)',
key: 'AV_OC_150',
socket: numericDataSocket,
unit: '%'
unit: '%',
min: 0,
max: 100
},
{
id: 16,
name: 'Min Organic Carbon 100-150cm (%)',
key: 'MIN_OC_150',
socket: numericDataSocket,
unit: '%'
unit: '%',
min: 0,
max: 100
},
{
id: 17,
name: 'Max Organic Carbon 100-150cm (%)',
key: 'MAX_OC_150',
socket: numericDataSocket,
unit: '%'
unit: '%',
min: 0,
max: 100
}

]
Expand Down
2 changes: 2 additions & 0 deletions app/javascript/projects/reify_layer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { reifyGeoserverWMSLayer } from './geoserver'
import { reifyKewLayer, reifyKewPointLayer } from './kew'
import { reifyOrvalLayer } from './orval'
import { reifyIMDLayer } from './imd'
import { reifyWFSLayer } from './wfs'

export const reifyLayer = (layer: Layer, existingLayer: BaseLayer | null, dbModels: DBModels, map: Map, modelOutputCache: ModelOutputCache, DatasetCache: DatasetCache, loadteamDataset: (layer: DatasetLayer) => void): BaseLayer => {
const layerType = layer.type
Expand All @@ -38,6 +39,7 @@ export const reifyLayer = (layer: Layer, existingLayer: BaseLayer | null, dbMode
case "ORValLayer": return reifyOrvalLayer(layer, existingLayer, map)
case "IMDLayer": return reifyIMDLayer(layer, existingLayer, map)
case "KewPointLayer": return reifyKewPointLayer(layer, existingLayer, map)
case "WFSLayer": return reifyWFSLayer(layer, existingLayer, map)
default: {
// Ensure this switch statement is exhaustive
const unreachable: never = layerType
Expand Down
60 changes: 60 additions & 0 deletions app/javascript/projects/reify_layer/wfs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import BaseLayer from "ol/layer/Base"
import { WFSLayer } from "../state"
import GeoJSON from "ol/format/GeoJSON"
import Map from "ol/Map"
import VectorLayer from "ol/layer/Vector"
import { memoize } from "lodash"
import VectorSource from "ol/source/Vector"
import { bbox } from "ol/loadingstrategy"
import { Fill, Stroke, Style } from "ol/style"
import { natmap_outputs } from "../modelling/components/natmap_soil_component"
import { findColor } from "../analysis_panel_tools/subsection"
import { getColorStops } from "./model_output"

const getSource = memoize((id: string, attribution: undefined | string) => {

const store = id.split(":")[0]

const source = new VectorSource({
url: extent => `https://landscapes.wearepal.ai/geoserver/${store}/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=${id}&outputFormat=application/json&bbox=${extent.join(',')},EPSG:3857&crs=EPSG:3857`,
format: new GeoJSON({
extractGeometryName: true
}),
strategy: bbox,
attributions: attribution
})

return source

})

const getStyle = (layer: WFSLayer, colMap: any[]) => (
(feature) => {

const propIdx = layer.propIdx
const prop = natmap_outputs[propIdx]
const val = feature.get(prop.key)
const [min, max] = [prop.min, prop.max]

const normalisedValue = prop.min > prop.max ? 1 - (val - min) / (max - min) : (val - min) / (max - min)
const col = findColor(normalisedValue, colMap)

return new Style({
fill: new Fill({ color: `rgba(${col[0]}, ${col[1]}, ${col[2]}, 1)`})
})

}
)

export function reifyWFSLayer (layer: WFSLayer, existingLayer: BaseLayer | null, map: Map) {

const colMap = getColorStops(layer.fill === "heatmap" ? "jet" : (layer.fill === "greyscale" ? "greys" : layer.fill), 100).reverse()

const vectLayer = new VectorLayer({
source: getSource(layer.layer, layer.attribution),
style: getStyle(layer, colMap),
})

return vectLayer

}
Loading

0 comments on commit 0487472

Please sign in to comment.