Skip to content

Commit

Permalink
Merge pull request #387 from wearepal/soil-component
Browse files Browse the repository at this point in the history
Extended soil component to include more data points
  • Loading branch information
paulthatjazz authored Jul 2, 2024
2 parents 2d88f96 + 37d0ed8 commit 196da2d
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 80 deletions.
83 changes: 3 additions & 80 deletions app/javascript/projects/modelling/components/soil_component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,87 +3,13 @@ import { NodeData, WorkerInputs, WorkerOutputs } from 'rete/types/core/data'
import { Input, Node, Output, Socket } from 'rete'
import { ProjectProperties } from "."
import { Extent } from "ol/extent"
import { booleanDataSocket, categoricalDataSocket, numericDataSocket } from "../socket_types"
import { createXYZ } from "ol/tilegrid"
import { retrieveISRICData } from "../model_retrieval"
import { CategoricalTileGrid, NumericTileGrid } from "../tile_grid"
import { TypedArray } from "d3"
import { maskFromExtentAndShape } from "../bounding_box"
import { SelectControl, SelectControlOptions } from "../controls/select"

const ERBSoilTypes = [
"Acrisols",
"Albeluvisols",
"Alisols",
"Andosols",
"Arenosols",
"Calcisols",
"Cambisols",
"Chernozems",
"Cryosols",
"Durisols",
"Ferralsols",
"Fluvisols",
"Gleysols",
"Gypsisols",
"Histosols",
"Kastanozems",
"Leptosols",
"Lixisols",
"Luvisols",
"Nitisols",
"Phaeozems",
"Planosols",
"Plinthosols",
"Podzols",
"Regosols",
"Solonchaks",
"Solonetz",
"Stagnosols",
"Umbrisols",
"Vertisols"
]

interface SoilGridOptions {
SCOId : number
name : string
map: string
coverageId: string
outputSocket: Socket
}

const SoilGrids : SelectControlOptions[] = [
{ id: 0, name: 'WRB (most probable)'},
{ id: 1, name: 'WRB (probability)' }
]

const SoilGridOptions : SoilGridOptions[] = [
{
SCOId: 0,
name: 'All',
map: 'wrb',
coverageId: 'MostProbable',
outputSocket: categoricalDataSocket
}
]

ERBSoilTypes.forEach((soilType, index) => {
SoilGridOptions.push({
SCOId: 0,
name: soilType,
map: 'wrb',
coverageId: 'MostProbable',
outputSocket: booleanDataSocket
})
SoilGridOptions.push({
SCOId: 1,
name: soilType,
map: 'wrb',
coverageId: soilType,
outputSocket: numericDataSocket

})
})
import { SelectControl } from "../controls/select"
import { SoilGrids, SoilGridOptions, ERBSoilTypes } from "../isric_soil_filters"

async function renderCategoricalData(extent: Extent, zoom: number, maskMode: boolean, maskLayer: string, maskCQL: string) {

Expand Down Expand Up @@ -144,7 +70,7 @@ async function renderNumericData(extent: Extent, zoom: number, maskMode: boolean
let y = (outputTileRange.minY + Math.floor(i / image.getWidth()))

const value = rasters[0][i]
result.set(x, y, mask.get(x, y) ? (value === 255 ? NaN : value) : NaN)
result.set(x, y, mask.get(x, y) ? ((value === 255 || value < 0 || value === 32767) ? NaN : value) : NaN)

}

Expand Down Expand Up @@ -187,7 +113,6 @@ export class SoilComponent extends BaseComponent {
updateOutputs(node: Node) {

const soilgridId = node.data.soilgridId || 0
// TODO - add outputs based on soilgridId
const soilGridOpts = SoilGridOptions.filter(opt => opt.SCOId == soilgridId)
soilGridOpts.forEach(
opt => node.addOutput(new Output(`${opt.name}-${opt.map}`, opt.name, opt.outputSocket))
Expand Down Expand Up @@ -250,8 +175,6 @@ export class SoilComponent extends BaseComponent {

await Promise.all(promises)

//outputs["WRB"] = await renderCategoricalData(this.projectExtent, this.projectZoom, this.maskMode, this.maskLayer, this.maskCQL)

}

}
178 changes: 178 additions & 0 deletions app/javascript/projects/modelling/isric_soil_filters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import { Socket } from "rete"
import { SelectControlOptions } from "./controls/select"
import { categoricalDataSocket, numericDataSocket, booleanDataSocket } from "./socket_types"


interface SoilGridOptions {
SCOId : number
name : string
map: string
coverageId: string
outputSocket: Socket
}

// Soil types from the World Reference Base for Soil Resources, used for labelling cat data
export const ERBSoilTypes = [
"Acrisols",
"Albeluvisols",
"Alisols",
"Andosols",
"Arenosols",
"Calcisols",
"Cambisols",
"Chernozems",
"Cryosols",
"Durisols",
"Ferralsols",
"Fluvisols",
"Gleysols",
"Gypsisols",
"Histosols",
"Kastanozems",
"Leptosols",
"Lixisols",
"Luvisols",
"Nitisols",
"Phaeozems",
"Planosols",
"Plinthosols",
"Podzols",
"Regosols",
"Solonchaks",
"Solonetz",
"Stagnosols",
"Umbrisols",
"Vertisols"
]

// Categories for SoilGrids
export const SoilGrids : SelectControlOptions[] = [
{ id: 0, name: 'WRB (most probable)'},
{ id: 1, name: 'WRB (probability)' },
{ id: 2, name: 'Soil Organic Carbon Stock'},
{ id: 3, name: 'Soil Organic Carbon Density'},
{ id: 4, name: 'Soil Organic Carbon Content'},
{ id: 5, name: 'Bulk Density'},
{ id: 6, name: 'Cation Exchange Capacity at ph 7'},
{ id: 7, name: 'Coarse fragments volumetric'},
{ id: 8, name: 'Clay content'},
{ id: 9, name: 'Nitrogen'},
{ id: 10, name: 'Soil pH in H2O'},
{ id: 11, name: 'Sand content'},
{ id: 12, name: 'Silt content'},
{ id: 13, name: 'Water Layer wv1500'},
{ id: 14, name: 'Water Layer wv0033'},
{ id: 15, name: 'Water Layer wv0010'},
]

// Filters for SoilGrids
export const SoilGridOptions : SoilGridOptions[] = [
{
SCOId: 0,
name: 'All',
map: 'wrb',
coverageId: 'MostProbable',
outputSocket: categoricalDataSocket
},
{
SCOId: 2,
name: 'Mean (<30cm)',
map: 'ocs',
coverageId: 'ocs_0-30cm_mean',
outputSocket: numericDataSocket
},
{
SCOId: 2,
name: 'Q0.05 (<30cm)',
map: 'ocs',
coverageId: 'ocs_0-30cm_Q0.05',
outputSocket: numericDataSocket
},
{
SCOId: 2,
name: 'Q0.5 (<30cm)',
map: 'ocs',
coverageId: 'ocs_0-30cm_Q0.5',
outputSocket: numericDataSocket

},
{
SCOId: 2,
name: 'Q0.95 (<30cm)',
map: 'ocs',
coverageId: 'ocs_0-30cm_Q0.95',
outputSocket: numericDataSocket

},
{
SCOId: 2,
name: 'Uncertainty (<30cm)',
map: 'ocs',
coverageId: 'ocs_0-30cm_uncertainty',
outputSocket: numericDataSocket
}

]

const ranges = [0, 5, 15, 30, 60, 100, 200]
const maps = ['ocd', 'soc', 'bdod', 'cec', 'cfvo', 'clay', 'nitrogen', 'phh2o', 'sand', 'silt', 'wv1500', 'wv0033', 'wv0010']

for(let i = 0; i < ranges.length - 1; i++) {
const range = `${ranges[i]}-${ranges[i+1]}cm`
maps.forEach((map, x) => {
SoilGridOptions.push({
SCOId: 3+x,
name: `Mean (${i === 0 ? '<5cm' : range})`,
map,
coverageId: `${map}_${range}_mean`,
outputSocket: numericDataSocket
})
SoilGridOptions.push({
SCOId: 3+x,
name: `Q0.05 (${i === 0 ? '<5cm' : range})`,
map,
coverageId: `${map}_${range}_Q0.05`,
outputSocket: numericDataSocket
})
SoilGridOptions.push({
SCOId: 3+x,
name: `Q0.5 (${i === 0 ? '<5cm' : range})`,
map,
coverageId: `${map}_${range}_Q0.5`,
outputSocket: numericDataSocket
})
SoilGridOptions.push({
SCOId: 3+x,
name: `Q0.95 (${i === 0 ? '<5cm' : range})`,
map,
coverageId: `${map}_${range}_Q0.95`,
outputSocket: numericDataSocket
})
SoilGridOptions.push({
SCOId: 3+x,
name: `Uncertainty (${i === 0 ? '<5cm' : range})`,
map,
coverageId: `${map}_${range}_uncertainty`,
outputSocket: numericDataSocket
})
})
}

// Adding entry for each WRB classifcation
ERBSoilTypes.forEach((soilType, index) => {
SoilGridOptions.push({
SCOId: 0,
name: soilType,
map: 'wrb',
coverageId: 'MostProbable',
outputSocket: booleanDataSocket
})
SoilGridOptions.push({
SCOId: 1,
name: soilType,
map: 'wrb',
coverageId: soilType,
outputSocket: numericDataSocket

})
})

0 comments on commit 196da2d

Please sign in to comment.