Skip to content

Commit

Permalink
feat(natural-forest): show land category drop down
Browse files Browse the repository at this point in the history
  • Loading branch information
wri7tno committed Oct 24, 2024
1 parent 06b9b86 commit f83f1d7
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 123 deletions.
125 changes: 40 additions & 85 deletions components/widgets/land-cover/natural-forest/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import { all, spread } from 'axios';
import {
getExtent,
getTreeCoverOTF,
getTropicalExtent,
} from 'services/analysis-cached';

import { shouldQueryPrecomputedTables } from 'components/widgets/utils/helpers';
import { getNaturalForest } from 'services/analysis-cached';
import {
POLITICAL_BOUNDARIES_DATASET,
FOREST_EXTENT_DATASET,
Expand All @@ -29,8 +22,8 @@ export default {
},
sentence: {
default: {
global: ``,
region: ``,
global: `As of 2020, {naturalForestPercentage} of global land cover was natural forests and {nonNaturalForestPercentage} was non-natural tree cover.`,
region: `As of 2020, {naturalForestPercentage} of land cover in {area} was natural forests and {nonNaturalForestPercentage} was non-natural tree cover.`,
},
},
metaKey: {
Expand Down Expand Up @@ -81,17 +74,8 @@ export default {
const isTropicalTreeCover = extentYear === 2020;
return isTropicalTreeCover ? 'tropicalExtent' : 'extent';
},
getSettingsConfig: (params) => {
const { extentYear } = params;
const isTropicalTreeCover = extentYear === 2020;

getSettingsConfig: () => {
return [
{
key: 'extentYear',
label: 'Tree cover dataset',
type: 'select',
border: true,
},
{
key: 'landCategory',
label: 'Land Category',
Expand All @@ -100,78 +84,50 @@ export default {
clearable: true,
border: true,
},
{
key: isTropicalTreeCover ? 'decile' : 'threshold',
label: 'Tree cover',
type: 'mini-select',
metaKey: 'widget_canopy_density',
},
];
},
getData: (params) => {
const { threshold, decile, ...filteredParams } = params;
const { extentYear } = filteredParams;
const isTropicalTreeCover = !(extentYear === 2000 || extentYear === 2010);
const decileThreshold = isTropicalTreeCover ? { decile } : { threshold };
const extentFn = isTropicalTreeCover ? getTropicalExtent : getExtent;

if (shouldQueryPrecomputedTables(params)) {
return all([
extentFn({ ...filteredParams, ...decileThreshold }),
extentFn({
...filteredParams,
...decileThreshold,
forestType: '',
landCategory: '',
}),
extentFn({
...filteredParams,
...decileThreshold,
forestType: 'plantations',
}),
]).then(
spread((response, adminResponse, plantationsResponse) => {
const extent = response.data && response.data.data;
const adminExtent = adminResponse.data && adminResponse.data.data;
const plantationsExtent =
plantationsResponse.data && plantationsResponse.data.data;
return getNaturalForest({ ...filteredParams }).then((response) => {
const extent = response.data;

let totalNaturalForest = 0;
let totalNonNaturalTreeCover = 0;
let unknown = 0;

let totalArea = 0;
let totalCover = 0;
let cover = 0;
let plantations = 0;
let data = {};
if (extent && extent.length) {
// Sum values
totalArea = adminExtent.reduce(
(total, d) => total + d.total_area,
0
);
cover = extent.reduce((total, d) => total + d.extent, 0);
totalCover = adminExtent.reduce((total, d) => total + d.extent, 0);
plantations = plantationsExtent.reduce(
(total, d) => total + d.extent,
0
);
data = {
totalArea,
totalCover,
cover,
plantations,
};
let data = {};
if (extent && extent.length) {
// Sum values
extent.forEach((item) => {
switch (item.sbtn_natural_forests__class) {
case 'Natural Forest':
totalNaturalForest += item.area__ha;
break;
case 'Non-Natural Forest':
totalNonNaturalTreeCover += item.area__ha;
break;
default:
// 'Unknown'
unknown += item.area__ha;
}
return data;
})
);
}
});

return getTreeCoverOTF(params);
data = {
totalNaturalForest,
unknown,
totalNonNaturalTreeCover,
totalArea: totalNaturalForest + unknown + totalNonNaturalTreeCover,
};
}

return data;
});
},
getDataURL: (params) => {
const { threshold, decile, ...filteredParams } = params;
const { extentYear } = filteredParams;
const isTropicalTreeCover = !(extentYear === 2000 || extentYear === 2010);
const downloadFn = isTropicalTreeCover ? getTropicalExtent : getExtent;
const decileThreshold = isTropicalTreeCover ? { decile } : { threshold };
const commonParams = {
...filteredParams,
Expand All @@ -180,14 +136,13 @@ export default {
};

const downloadArray = [
downloadFn({ ...commonParams, forestType: null, landCategory: null }),
downloadFn({ ...commonParams, forestType: 'plantations' }),
getNaturalForest({
...commonParams,
forestType: null,
landCategory: null,
}),
];

if (filteredParams?.landCategory) {
downloadArray.push(downloadFn({ ...commonParams }));
}

return downloadArray;
},
getWidgetProps,
Expand Down
70 changes: 32 additions & 38 deletions components/widgets/land-cover/natural-forest/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,32 @@ export const isoHasPlantations = createSelector(
);

export const parseData = createSelector(
[getData, getColors, getIndicator, isoHasPlantations],
(data, colors, indicator, hasPlantations) => {
if (isEmpty(data)) return null;
const { totalArea, totalCover, cover, plantations } = data;
const otherCover = indicator ? totalCover - cover : 0;
const plantationsCover = hasPlantations ? plantations : 0;
[getData, getColors],
(data, colors) => {
if (isEmpty(data)) {
return null;
}

const { totalNaturalForest, unknown, totalNonNaturalTreeCover, totalArea } =
data;
const parsedData = [
{
label: 'Natural forests',
value: cover - plantationsCover,
value: totalNaturalForest,
color: colors.naturalForest,
percentage: ((cover - plantationsCover) / totalArea) * 100,
percentage: (totalNaturalForest / totalArea) * 100,
},
{
label: 'Non-natural tree cover',
value: totalArea - cover - otherCover,
value: totalNonNaturalTreeCover,
color: colors.nonForest,
percentage: ((totalArea - cover - otherCover) / totalArea) * 100,
percentage: (totalNonNaturalTreeCover / totalArea) * 100,
},
{
label: 'Other land cover',
value: otherCover,
value: unknown,
color: colors.otherCover,
percentage: (otherCover / totalArea) * 100,
percentage: (unknown / totalArea) * 100,
},
];

Expand All @@ -73,46 +75,38 @@ export const parseSentence = createSelector(
getIndicator,
getSentence,
getAdminLevel,
isoHasPlantations,
],
(
data,
settings,
locationName,
indicator,
sentences,
admLevel,
isoPlantations
) => {
(data, settings, locationName, indicator, sentences, admLevel) => {
if (!data || !sentences) return null;

const { extentYear, threshold, decile } = settings;

const isTropicalTreeCover = extentYear === 2020;
const withIndicator = !!indicator;
const decileThreshold = isTropicalTreeCover ? decile : threshold;

const sentenceKey = withIndicator ? 'withIndicator' : 'default';
const sentenceSubkey = admLevel === 'global' ? 'global' : 'region';
const sentenceTreeCoverType = isTropicalTreeCover
? 'tropicalTreeCover'
: 'treeCover';
const sentence =
sentences[sentenceKey][sentenceSubkey][sentenceTreeCoverType];

const { cover, plantations, totalCover, totalArea } = data;
const top = isoPlantations ? cover - plantations : cover;
const bottom = indicator ? totalCover : totalArea;
const percentCover = (100 * top) / bottom;

const formattedPercentage = formatNumber({ num: percentCover, unit: '%' });
const sentence = sentences.default[sentenceSubkey];

const { totalNaturalForest, totalNonNaturalTreeCover, totalArea } = data;
const percentNaturalForest = (100 * totalNaturalForest) / totalArea;
const percentNonNaturalForest =
(100 * totalNonNaturalTreeCover) / totalArea;

const formattedNaturalForestPercentage = formatNumber({
num: percentNaturalForest,
unit: '%',
});
const formattedNonNaturalForestPercentage = formatNumber({
num: percentNonNaturalForest,
unit: '%',
});

const thresholdLabel = `>${decileThreshold}%`;

const params = {
year: extentYear,
location: locationName,
percentage: formattedPercentage,
naturalForestPercentage: formattedNaturalForestPercentage,
nonNaturalForestPercentage: formattedNonNaturalForestPercentage,
indicator: indicator?.label,
threshold: thresholdLabel,
};
Expand Down
35 changes: 35 additions & 0 deletions services/analysis-cached.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ const SQL_QUERIES = {
treeCoverOTFExtent: 'SELECT SUM(area__ha) FROM data&geostore_id={geostoreId}',
treeCoverGainSimpleOTF:
'SELECT SUM(area__ha) FROM data&geostore_id={geostoreId}',
naturalForest:
'SELECT {location}, sbtn_natural_forests__class, SUM(area__ha) AS area__ha FROM data {WHERE} GROUP BY {location}, sbtn_natural_forests__class',
netChangeIso:
'SELECT {select_location}, stable, loss, gain, disturb, net, change, gfw_area__ha FROM data {WHERE}',
netChange:
Expand Down Expand Up @@ -1022,6 +1024,39 @@ export const getTropicalExtentGrouped = (params) => {
}));
};

export const getNaturalForest = async (params) => {
// eslint-disable-next-line no-unused-vars
const { download, extentYear } = params || {};

// eslint-disable-next-line no-unused-vars
const requestUrl = getRequestUrl({
...params,
dataset: 'annual',
datasetType: 'summary',
version: 'v20240815',
});

if (!requestUrl) {
return new Promise(() => {});
}

const url = encodeURI(
`${requestUrl}${SQL_QUERIES.naturalForest}`
.replace(/{location}/g, getLocationSelect({ ...params, cast: false }))
.replace(/{location}/g, getLocationSelect({ ...params }))
.replace('{WHERE}', getWHEREQuery({ ...params, dataset: 'annual' }))
);

if (download) {
return {
name: `natural_forest_${extentYear}__ha`,
url: getDownloadUrl(url),
};
}

return dataRequest.get(url);
};

export const getTreeCoverByLandCoverClass = (params) => {
const { forestType, download, extentYear, landCategory, ifl } = params || {};

Expand Down

0 comments on commit f83f1d7

Please sign in to comment.