Skip to content
Merged
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
48 changes: 34 additions & 14 deletions backend/configs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,58 @@
"id": "villages",
"type": "openmaptiles",
"layer": "place",
"filters": { "class": "village" }
"filters": {
"class": "village"
}
},
{
"id": "towns",
"type": "openmaptiles",
"layer": "place",
"filters": { "class": "town" }
"filters": {
"class": "town"
}
},
{
"id": "boundaries",
"type": "openmaptiles",
"layer": "boundary",
"filters": { "admin_level": 2 },
"style": { "paint": { "line-color": "hsl(248,7%,66%)" } }
"filters": {
"admin_level": 2
},
"style": {
"paint": {
"line-color": "hsl(248,7%,66%)"
}
}
},
{
"id": "inventaire",
"type": "datapackage",
"path": "../catalog/inventaire",
"resource": "inventaire_id",
"groupby": ["for"],
"groupby": [
"for",
"cod"
],
"columns": {
"geom": "centroid(gps)",
"total_trees": "count(ind.ess_arb)",
"chefs": "list(nom)",
"biomass_volume": "sum(0.0673 * pow(ind.dens_bois.value * pow(ind.dhp1 + ind.dhp2 + ind.dhp3 + ind.dhp4 + ind.dhp5 + ind.dhp6 + ind.dhp7 + ind.dhp8 + ind.dhp9 + ind.dhp10, 2) * ind.haut, 0.976) if ind.etat = 1) / 1257",
"tree_density": "count(1 if ind.etat = 1) / 0.1257",
"richness": "count(unique(ind.ess_arb))",
"dominant_height": "avg(ind.haut if ind.haut > percentile(ind.haut, 80))",
"soil_structure": "avg((ep1*not1 + ep2*not2 + ep3*not3 + ep4*not4 + ep5*not5) / 250)",
"diversity": "shannon(ind.ess_arb) / 5 * 10",
"biomass": "sum(0.0673 * pow(ind.dens_bois.value * pow(ind.dhp1 + ind.dhp2 + ind.dhp3 + ind.dhp4, 2) * ind.haut, 0.976))",
"density": "count(1 if ind.etat = 1) / 0.1257",
"vertical_distribution": "gini(ind.haut) * 10",
"dendro": "list_unique(flatten(list(ind.dmh))) / 16 * 10"
"epf_tree_density": "count(1 if ind.etat = 1) / 1257",
"epf_necromass_pied": "count(1 if ind.etat = 2)",
"epf_necromass_sol": "count(1 if ind.etat = 3)",
"epf_necro_biomass_ratio": "((sum(0.0673 * pow(ind.dens_bois.value * pow(ind.dhp1 + ind.dhp2 + ind.dhp3 + ind.dhp4 + ind.dhp5 + ind.dhp6 + ind.dhp7 + ind.dhp8 + ind.dhp9 + ind.dhp10, 2) * ind.haut, 0.976) if ind.etat = 2) + sum(3.1415926535 / 3 * (pow(ind.dhp_b / 2 , 2) + pow(ind.dhp_e / 2, 2) + ind.dhp_b / 2 + ind.dhp_e / 2) * ind.longueur * ind.dens_bois.value if ind.etat = 3)) / 1257) / (sum(0.0673 * pow(ind.dens_bois.value * pow(ind.dhp1 + ind.dhp2 + ind.dhp3 + ind.dhp4 + ind.dhp5 + ind.dhp6 + ind.dhp7 + ind.dhp8 + ind.dhp9 + ind.dhp10, 2) * ind.haut, 0.976) if ind.etat = 1) / 1257) * 10",
"epf_tree_diversity": "shannon(ind.ess_arb) / 5 * 10",
"epf_spatial_distribution": "count(1020)",
"epf_diameter_distribution": "gini(ind.dhp1 + ind.dhp2 + ind.dhp3 + ind.dhp4 + ind.dhp5 + ind.dhp6 + ind.dhp7 + ind.dhp8 + ind.dhp9 + ind.dhp10) * 10",
"epf_vertical_distribution": "gini(ind.haut) * 10",
"epf_dominant_height": "avg(ind.haut if ind.haut > percentile(ind.haut, 80)) / 4",
"epf_microhabitats": "list_unique(flatten(list(ind.dmh))) / 1.6",
"soil_structure": "sum(ep1*not1 + ep2*not2 + ep3*not3 + ep4*not4 + ep5*not5) / sum(ep1 + ep2 + ep3 + ep4 + ep5) * 2",
"soil_composition": "count(1020)"
},
"popup": {
"trigger": "click"
Expand All @@ -61,4 +81,4 @@
"position": "bottom-left"
}
]
}
}
1 change: 0 additions & 1 deletion backend/maps/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
config_path = settings.BASE_DIR / "configs" / "config.json"
map = Map.from_file(config_path)


@csrf_exempt
def my_map_view(request, subpath):
return JsonResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ export const ChartForestPotential: FC<ChartForestPotentialProps> = ({
temoin: temoin.diameterDistribution,
},
{
benef: benef.masterHeight,
benef: benef.dominantHeight,
indicator: t(
"indicators.biodiversity.sections.forestPotentialLevel.masterHeight",
"indicators.biodiversity.sections.forestPotentialLevel.dominantHeight",
),
temoin: temoin.masterHeight,
temoin: temoin.dominantHeight,
},
{
benef: benef.microhabitat,
Expand Down Expand Up @@ -108,7 +108,7 @@ export const ChartForestPotential: FC<ChartForestPotentialProps> = ({
<Card>
<CardContent className="p-2 mx-2">
<ChartContainer
className="mx-auto aspect-square max-h-[250px]"
className="mx-auto aspect-square max-h-62.5"
config={chartConfig}
>
<RadarChart data={chartData}>
Expand Down
107 changes: 82 additions & 25 deletions webapp/src/features/indicators/biodiversity/format-data.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,104 @@
import { i18nInstance } from "@shared/i18n";
import { i18nInstance, useTranslation } from "@shared/i18n";
import { precise } from "@shared/lib/utils";

import { UNITS, useFormatterWithUnit } from "../utils";

export type BiodiversityData = {
for: string;
cod: number;
total_trees: number;
biomass_volume: number;
tree_density: number;
richness: number;
dominant_height: number;
epf_tree_density: number;
epf_necro_biomass_ratio: number;
epf_tree_diversity: number;
epf_spatial_distribution: number;
epf_diameter_distribution: number;
epf_vertical_distribution: number;
epf_dominant_height: number;
epf_microhabitats: number;
soil_structure: number;
soil_composition: number;
};

type NumericKeys<T> = {
[K in keyof T]: T[K] extends number ? K : never;
}[keyof T];

const indicatorKeys: NumericKeys<BiodiversityData>[] = [
"biomass_volume",
"tree_density",
"richness",
"epf_tree_density",
"epf_necro_biomass_ratio",
"epf_tree_diversity",
"epf_spatial_distribution",
"epf_diameter_distribution",
"epf_vertical_distribution",
"epf_dominant_height",
"epf_microhabitats",
"soil_structure",
"soil_composition",
];

const forests = [
{ label: "Djilor", value: "1" },
{ label: "Malka", value: "2" },
{ label: "Samba Dia", value: "3" },
{ label: "Takkite", value: "4" },
];

/**
* Return data in a convenient way for UI rendering, handling units and fixing
*/
export const useFormatBiodiversityData = (data: BiodiversityData) => {
const { t } = useTranslation("translations");
const { formatWithUnit } = useFormatterWithUnit();

const safeData = Object.fromEntries(
Object.entries(data).map(([key, value]) => [
key,
indicatorKeys.includes(key as (typeof indicatorKeys)[number])
? precise(Number(value))
: value,
]),
) as BiodiversityData;

return {
biomass: {
density: formatWithUnit(120, UNITS.individualPerHectare), // replace hardcoded value
volume: formatWithUnit(5, UNITS.tonPerHectare), // replace hardcoded value
density: formatWithUnit(
safeData.tree_density,
UNITS.individualPerHectare,
),
volume: formatWithUnit(safeData.biomass_volume, UNITS.tonPerHectare),
},
date: Intl.DateTimeFormat(i18nInstance.language, {
dateStyle: "short",
}).format(new Date()), // to replace
// replace hardcoded value
forestPotentialLevel: {
benef: {
density: 70,
diameterDistribution: 22,
diversity: data.richness,
masterHeight: data.dominant_height,
microhabitat: 2,
ratioDeathmassBiomass: 85,
spatialDistribution: 43,
verticalDistribution: 67,
density: safeData.epf_tree_density,
diameterDistribution: safeData.epf_diameter_distribution,
diversity: safeData.epf_tree_diversity,
dominantHeight: safeData.epf_dominant_height,
microhabitat: safeData.epf_microhabitats,
ratioDeathmassBiomass: safeData.epf_necro_biomass_ratio,
spatialDistribution: safeData.epf_spatial_distribution,
verticalDistribution: safeData.epf_vertical_distribution,
},
temoin: {
density: 80,
diameterDistribution: 32,
diversity: 47,
masterHeight: 98,
microhabitat: 22,
ratioDeathmassBiomass: 45,
spatialDistribution: 39,
verticalDistribution: 67,
density: 0.02,
diameterDistribution: 3,
diversity: 1,
dominantHeight: 4,
microhabitat: 0.5,
ratioDeathmassBiomass: 1,
spatialDistribution: 1,
verticalDistribution: 2,
},
},
// replace hardcoded value
// replace hardcoded value when data will be available
indicatorSpecies: {
abundanceTaxon1: 43,
abundanceTaxon2: 56,
Expand All @@ -54,10 +107,14 @@ export const useFormatBiodiversityData = (data: BiodiversityData) => {
speciesRichnessTaxon2: 23,
speciesRichnessTaxon3: 24,
},
title: "Point #se-4", // to replace
title: t("popup.title", {
code: data.cod,
label:
forests.find((f) => f.value === data.for)?.label || `n°${data.for}`,
}),
treeDiversity: {
shannon: 1.1, // replace hardcoded value
speciesRichness: formatWithUnit(1257, UNITS.speciesCount), // replace hardcoded value
relative_abundance: 1, // replace hardcoded value when data will be available
speciesRichness: data.richness,
},
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ export const useBiodiversityIndicatorElements = (
/>
<IndicatorRawValue
dataName={t(
"indicators.biodiversity.sections.treeDiversity.shannon",
"indicators.biodiversity.sections.treeDiversity.relativeAbundance",
)}
value={data.treeDiversity.shannon}
value={data.treeDiversity.relative_abundance}
/>
</>
),
Expand Down
7 changes: 5 additions & 2 deletions webapp/src/shared/i18n/translations/en/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
"density": "Tree density",
"diameterDistribution": "Diameter distribution",
"diversity": "Tree diversity",
"masterHeight": "Dominant height",
"dominantHeight": "Dominant height",
"microhabitat": "Dendro-microhabitats",
"ratioDeathmassBiomass": "Deadwood/biomass ratio",
"spatialDistribution": "Spatial distribution",
Expand All @@ -89,7 +89,7 @@
"title": "Indicator Species"
},
"treeDiversity": {
"shannon": "Shannon index",
"relativeAbundance": "Relative abundance",
"speciesRichness": "Species richness",
"title": "Tree Diversity"
}
Expand All @@ -108,5 +108,8 @@
"speciesCount_other": "{{ count }} species inventoried",
"tonPerHectare": "{{ value }} t/ha"
}
},
"popup": {
"title": "Plot n°{{ code }} in {{ label }} forest"
}
}
7 changes: 5 additions & 2 deletions webapp/src/shared/i18n/translations/fr/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
"density": "Densité arborée",
"diameterDistribution": "Distribution diamétrale",
"diversity": "Diversité arborée",
"masterHeight": "Hauteur dominante",
"dominantHeight": "Hauteur dominante",
"microhabitat": "Dendro-microhabitats",
"ratioDeathmassBiomass": "Rapport nécromasse/biomasse",
"spatialDistribution": "Distribution spatiale",
Expand All @@ -89,7 +89,7 @@
"title": "Espèces indicatrices"
},
"treeDiversity": {
"shannon": "Indice de shannon",
"relativeAbundance": "Abondance relative",
"speciesRichness": "Richesse spécifique",
"title": "Diversité arborée"
}
Expand All @@ -108,5 +108,8 @@
"speciesCount_other": "{{ count }} espèces inventoriées",
"tonPerHectare": "{{ value }} t/ha"
}
},
"popup": {
"title": "Placette n°{{ code }} dans la forêt {{ label }}"
}
}
10 changes: 10 additions & 0 deletions webapp/src/shared/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,13 @@ import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}

export function precise(value?: number | null) {
if (!value || Number.isNaN(value)) {
return 0;
}
if (value > 999) {
return value.toFixed(1);
}
return value.toFixed(2);
}
Loading
Loading