Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FLAG-924: Update FAO forest cover widget data sources & sentences #4720

Merged
merged 9 commits into from
Dec 1, 2023
55 changes: 34 additions & 21 deletions components/widgets/land-cover/fao-cover/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default {
widget: 'faoCover',
title: {
initial: 'FAO forest cover in {location}',
global: 'Global FAO forest cover'
global: 'Global FAO forest cover',
},
chartType: 'pieChart',
categories: ['land-cover'],
Expand All @@ -21,47 +21,60 @@ export default {
dataType: 'fao',
metaKey: 'widget_forest_cover_fao',
sortOrder: {
landCover: 5
landCover: 5,
},
settings: {
unit: 'ha'
unit: 'ha',
faoYear: 2020,
},
refetchKeys: ['faoYear'],
sentences: {
globalInitial:
'FAO data from 2015 shows that there are {extent} of forest {location}, with primary forest occupying {primaryPercent} of the world.',
globalNoPrimary:
'FAO data from 2015 shows that there are {extent} of forest {location}, which occupies {primaryPercent} of the world.',
'According to the FAO, in {year}, {percent} ({amountInHectares}) of the globe was covered by forest. {primaryPercent} of that forest was classified as primary forest.',
initial:
'FAO data from 2015 shows that {location} contains {extent} of forest, with primary forest occupying {primaryPercent} of the country.',
'According to the FAO, in {year}, {percent} ({amountInHectares}) of {country} was covered by forest. {primaryPercent} of that forest was classified as primary forest.',
noPrimary:
'FAO data from 2015 shows that {location} contains {extent} of forest, which occupies {primaryPercent} of the country.'
'According to the FAO, in {year},{primaryPercent} ({extent}) of {location} was covered by forest. <b>0%</b> of that forest was classified as primary forest.',
},
getData: params =>
all([getFAOExtent({ ...params }), getRanking({ ...params })]).then(
getSettingsConfig: () => {
return [
{
key: 'faoYear',
label: 'Period',
type: 'select',
clearable: false,
border: true,
},
];
},
getData: (params) => {
return all([getFAOExtent({ ...params }), getRanking({ ...params })]).then(
spread((getFAOResponse, getRankingResponse) => {
let data = {};
const fao = getFAOResponse.data.rows;
const ranking = getRankingResponse.data.rows;

if (fao.length && ranking.length) {
const faoTotal = fao.map(f => ({
...f,
area_ha: parseFloat(f.area_ha.replace(',', '')) * 1000
}));
let faoData = faoTotal[0];
let faoData = fao[0];

if (fao.length > 1) {
faoData = {};
Object.keys(omit(faoTotal[0], ['iso', 'name'])).forEach(k => {
faoData[k] = sumBy(faoTotal, k) || 0;
Object.keys(omit(fao[0], ['iso', 'country'])).forEach((k) => {
faoData[k] = sumBy(fao, k) || 0;
});
}

data = {
...faoData,
rank: ranking[0].rank || 0
rank: ranking[0].rank || 0,
};
}
return data;
})
),
getDataURL: ({ params }) => [getFAOExtent({ ...params, download: true })],
getWidgetProps
);
},
getDataURL: async (params) => [
await getFAOExtent({ ...params, download: true }),
],
getWidgetProps,
};
60 changes: 37 additions & 23 deletions components/widgets/land-cover/fao-cover/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,21 @@ const getLocationName = (state) => state.locationLabel;
const getColors = (state) => state.colors;
const getSentences = (state) => state.sentences;
const getTitle = (state) => state.title;
const getSettings = (state) => state.settings;

// get lists selected
export const parseData = createSelector(
[getData, getColors],
(data, colors) => {
if (isEmpty(data)) return null;
const {
area_ha,
extent,
planted_forest,
forest_primary,
forest_regenerated,
} = data;
const otherCover =
extent - (forest_regenerated + forest_primary + planted_forest);
if (isEmpty(data)) {
return null;
}

const { area_ha, extent, planted_forest, forest_primary } = data;
const otherCover = extent - (forest_primary + planted_forest);
const nonForest = area_ha - extent;
return [
{
label: 'Naturally Regenerated Forest',
value: forest_regenerated,
percentage: (forest_regenerated / area_ha) * 100,
color: colors.naturalForest,
},

const chartItems = [
{
label: 'Primary Forest',
value: forest_primary || 0,
Expand All @@ -56,28 +48,50 @@ export const parseData = createSelector(
color: colors.nonForest,
},
];

if (forest_primary === null) {
return chartItems.slice(1, chartItems.length);
}

return chartItems;
}
);

export const parseSentence = createSelector(
[getData, getLocationName, getSentences],
(data, locationName, sentences) => {
[getData, getLocationName, getSentences, getSettings],
(data, locationName, sentences, settings) => {
if (isEmpty(data)) return null;
const { initial, noPrimary, globalInitial, globalNoPrimary } = sentences;

const { initial, noPrimary, globalInitial } = sentences;
const { area_ha, extent, forest_primary } = data;
const { faoYear } = settings;

const primaryPercent =
forest_primary > 0
? (forest_primary / area_ha) * 100
? (forest_primary / extent) * 100
: (extent / area_ha) * 100;

const percent = (extent / area_ha) * 100;
const params = {
location: locationName === 'global' ? 'globally' : locationName,
extent: formatNumber({ num: extent, unit: 'ha', spaceUnit: true }),
primaryPercent: formatNumber({ num: primaryPercent, unit: '%' }),
year: faoYear,
percent: formatNumber({ num: percent, unit: '%' }),
amountInHectares: formatNumber({
num: extent,
unit: 'ha',
spaceUnit: true,
}),
country: locationName,
};
let sentence = forest_primary > 0 ? initial : noPrimary;

let sentence = forest_primary !== null ? initial : noPrimary;

if (locationName === 'global') {
sentence = forest_primary > 0 ? globalInitial : globalNoPrimary;
sentence = globalInitial;
}

return {
sentence,
params,
Expand Down
2 changes: 2 additions & 0 deletions components/widgets/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ import confidence from 'data/confidence.json';
import bioTypes from 'data/biodiversity-int.json';
import ifl from 'data/ifl.json';
import source from 'data/sources.json';
import faoYear from 'data/fao-cover-years.json';

export default {
forestType: forestType.filter((f) => !f.hidden),
landCategory: landCategory.filter((l) => !l.hidden),
threshold,
decile,
firesThreshold,
faoYear,
unit,
gasesIncluded,
period,
Expand Down
18 changes: 18 additions & 0 deletions data/fao-cover-years.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[
{
"label": "2000",
"value": 2000
},
{
"label": "2010",
"value": 2010
},
{
"label": "2015",
"value": 2015
},
{
"label": "2020",
"value": 2020
}
]
32 changes: 20 additions & 12 deletions services/forest-data.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { cartoRequest } from 'utils/request';
import { cartoRequest, dataRequest } from 'utils/request';
import { PROXIES } from 'utils/proxies';

import globalLandCoverCategories from 'data/global-land-cover-categories.json';

import { CARTO_API } from 'utils/apis';

const NEW_SQL_QUERIES = {
faoExtent:
'SELECT country AS iso, name, plantfor * 1000 AS planted_forest__ha, primfor * 1000 AS primary_forest__ha, natregfor * 1000 AS regenerated_forest__ha, forest * 1000 AS fao_treecover__ha, totarea as area_ha FROM table_1_forest_area_and_characteristics WHERE {location} AND year = 2015',
'SELECT iso, country, "planted forest (ha)" AS planted_forest__ha, "primary (ha)" AS primary_forest__ha, "naturally regenerating forest (ha)" AS regenerated_forest__ha, "forest (ha)" AS fao_treecover__ha, "total land area (ha)" as area_ha FROM data WHERE {location} AND year = {year}',
faoReforest:
'SELECT country AS iso, name, year, reforest * 1000 AS reforestation__rate, forest*1000 AS fao_treecover_reforest__ha FROM table_1_forest_area_and_characteristics as fao WHERE fao.year = {period} AND reforest > 0 ORDER BY reforestation__rate DESC',
faoDeforest:
Expand Down Expand Up @@ -44,23 +45,28 @@ const getLocationQuery = (adm0, adm1, adm2) =>
adm2 ? ` AND adm2 = ${adm2}` : ''
}`;

export const getFAOExtent = ({ adm0, download }) => {
const url = `/sql?q=${NEW_SQL_QUERIES.faoExtent}`.replace(
'{location}',
adm0 ? `country = '${adm0}'` : '1 = 1'
);
export const getFAOExtent = async ({ adm0, faoYear = 2020, download }) => {
const target = download ? 'download/csv' : 'query/json';

const url =
`/dataset/fao_forest_extent/v2020/${target}?sql=${NEW_SQL_QUERIES.faoExtent}`
.replace(/{location}/g, adm0 ? `iso = '${adm0}'` : '1 = 1')
.replace(/{year}/g, faoYear);

if (download) {
return {
name: 'fao_treecover_extent__ha',
url: `${CARTO_API}${url}&format=csv`,
url: new URL(
`${window.location.origin}${PROXIES.DATA_API}${url}`
).toString(),
};
}

return cartoRequest.get(url).then((response) => ({
...response,
const response = await dataRequest.get(url);

const widgetData = {
data: {
rows: response.data.rows.map((o) => {
rows: response.data.map((o) => {
// delete old key, replace it with new
// delete Object.assign(o, {[newKey]: o[oldKey] })[oldKey]
delete Object.assign(o, { planted_forest: o.planted_forest__ha })
Expand All @@ -75,7 +81,9 @@ export const getFAOExtent = ({ adm0, download }) => {
return o;
}),
},
}));
};

return widgetData;
};

export const getFAOReforest = ({ period, download }) => {
Expand Down
Loading