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

GLAD Biodiversity Table Update #3367

Merged
merged 13 commits into from
Apr 27, 2018
8 changes: 4 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ GEM
sass-rails (< 5.1)
sprockets (< 4.0)
concurrent-ruby (1.0.5)
crass (1.0.3)
crass (1.0.4)
database_cleaner (1.6.2)
debug_inspector (0.0.3)
diff-lcs (1.3)
Expand Down Expand Up @@ -295,7 +295,7 @@ GEM
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
json (2.1.0)
loofah (2.2.1)
loofah (2.2.2)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.0)
Expand Down Expand Up @@ -347,8 +347,8 @@ GEM
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.0.3)
loofah (~> 2.0)
rails-html-sanitizer (1.0.4)
loofah (~> 2.2, >= 2.2.2)
rails_12factor (0.0.3)
rails_serve_static_assets
rails_stdout_logging
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ const getGladAlerts = createThunkAction(
if (!state().widgetGladAlerts.loading) {
dispatch(setGladAlertsLoading({ loading: true, error: false }));
axios
.all([fetchGladAlerts(params), fetchGLADLatest()])
.all([fetchGladAlerts({ ...params }), fetchGLADLatest()])
.then(
axios.spread((alerts, latest) => {
let data = {};
if (alerts && alerts.data && latest && latest.data) {
const alertsData = alerts.data.data;
const alertsData = alerts.data;
const latestData = latest.data.data;
data = {
alerts: alertsData.attributes.value,
alerts: alertsData.data,
latest: latestData[0].attributes.date
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,7 @@ export const getData = createSelector(
years.forEach(d => {
const yearDataByWeek = groupBy(groupedByYear[d], 'week');
for (let i = 1; i <= yearLengths[d]; i += 1) {
zeroFilledData.push(
yearDataByWeek[i]
? yearDataByWeek[i][0]
: { count: 0, week: i, year: parseInt(d, 10) }
);
zeroFilledData.push(yearDataByWeek[i][0]);
}
});
return zeroFilledData;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { createAction } from 'redux-actions';
import { createThunkAction } from 'utils/redux';
import axios from 'axios';
import moment from 'moment';

import { fetchGladIntersectionAlerts } from 'services/alerts';
import { fetchGladIntersectionAlerts, fetchGLADLatest } from 'services/alerts';
import { getMultiRegionExtent } from 'services/forest-data';

const setGladBiodiversityData = createAction('setGladBiodiversityData');
Expand All @@ -19,23 +18,22 @@ const getGladBiodiversity = createThunkAction(
axios
.all([
fetchGladIntersectionAlerts({ ...params }),
fetchGLADLatest(),
getMultiRegionExtent({ ...params })
])
.then(
axios.spread((alerts, extent) => {
axios.spread((alerts, latest, extent) => {
const { data } = alerts.data;
const latestData = latest.data.data;
const areas = extent.data.data;
const alertsByDate =
data &&
data.filter(d =>
moment(new Date(d.date)).isAfter(
moment.utc().subtract(53, 'weeks')
)
);
dispatch(
setGladBiodiversityData(
alertsByDate && extent
? { data: alertsByDate, extent: areas }
data && extent && latest
? {
data,
extent: areas,
latest: latestData[0].attributes.date
}
: {}
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import moment from 'moment';

// get list data
const getData = state => state.data || null;
const getLatestDates = state => state.latest || null;
const getExtent = state => state.extent || null;
const getSettings = state => state.settings || null;
const getOptions = state => state.options || null;
Expand All @@ -18,13 +19,33 @@ const getLocationNames = state => state.locationNames || null;
const getColors = state => state.colors || null;

export const getSortedData = createSelector(
[getData, getExtent, getSettings, getLocation, getLocationsMeta, getColors],
(data, extent, settings, location, meta, colors) => {
[
getData,
getLatestDates,
getExtent,
getSettings,
getLocation,
getLocationsMeta,
getColors
],
(data, latest, extent, settings, location, meta, colors) => {
if (!data || isEmpty(data) || !meta || isEmpty(meta)) return null;
const latestWeek = moment(latest)
.subtract(1, 'weeks')
.week();
const latestYear = moment(latest)
.subtract(1, 'weeks')
.year();
const alertsByDate = data.filter(d =>
moment(new Date(d.date)).isAfter(
moment.utc().subtract(settings.weeks, 'weeks')
)
moment()
.week(d.week)
.year(d.year)
.isAfter(
moment()
.week(latestWeek)
.year(latestYear)
.subtract(settings.weeks, 'weeks')
)
);
const groupedAlerts = groupBy(
alertsByDate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const mapStateToProps = (
const selectorData = {
data: data.data,
extent: data.extent,
latest: data.latest,
settings,
options: settingsConfig.options,
meta: countryData[!payload.region ? 'regions' : 'subRegions'],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { createAction } from 'redux-actions';
import { createThunkAction } from 'utils/redux';
import axios from 'axios';
import moment from 'moment';

import { fetchGladIntersectionAlerts } from 'services/alerts';
import { fetchGladIntersectionAlerts, fetchGLADLatest } from 'services/alerts';
import { getMultiRegionExtent } from 'services/forest-data';

const setGladRankedData = createAction('setGladRankedData');
Expand All @@ -14,28 +13,27 @@ const setGladRankedLoading = createAction('setGladRankedLoading');
const getGladRanked = createThunkAction(
'getGladRanked',
params => (dispatch, state) => {
if (!state().widgetGladRanked.loading) {
if (!state().widgetGladBiodiversity.loading) {
dispatch(setGladRankedLoading({ loading: true, error: false }));
axios
.all([
fetchGladIntersectionAlerts({ ...params }),
fetchGLADLatest(),
getMultiRegionExtent({ ...params })
])
.then(
axios.spread((alerts, extent) => {
axios.spread((alerts, latest, extent) => {
const { data } = alerts.data;
const latestData = latest.data.data;
const areas = extent.data.data;
const alertsByDate =
data &&
data.filter(d =>
moment(new Date(d.date)).isAfter(
moment.utc().subtract(53, 'weeks')
)
);
dispatch(
setGladRankedData(
alertsByDate && extent
? { data: alertsByDate, extent: areas }
data && extent && latest
? {
data,
extent: areas,
latest: latestData[0].attributes.date
}
: {}
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import moment from 'moment';

// get list data
const getData = state => state.data || null;
const getLatestDates = state => state.latest || null;
const getExtent = state => state.extent || null;
const getSettings = state => state.settings || null;
const getOptions = state => state.options || null;
Expand All @@ -18,13 +19,33 @@ const getLocationNames = state => state.locationNames || null;
const getColors = state => state.colors || null;

export const getSortedData = createSelector(
[getData, getExtent, getSettings, getLocation, getLocationsMeta, getColors],
(data, extent, settings, location, meta, colors) => {
[
getData,
getLatestDates,
getExtent,
getSettings,
getLocation,
getLocationsMeta,
getColors
],
(data, latest, extent, settings, location, meta, colors) => {
if (!data || isEmpty(data) || !meta || isEmpty(meta)) return null;
const latestWeek = moment(latest)
.subtract(1, 'weeks')
.week();
const latestYear = moment(latest)
.subtract(1, 'weeks')
.year();
const alertsByDate = data.filter(d =>
moment(new Date(d.date)).isAfter(
moment.utc().subtract(settings.weeks, 'weeks')
)
moment()
.year(d.year)
.week(d.week)
.isAfter(
moment()
.year(latestYear)
.week(latestWeek)
.subtract(settings.weeks, 'weeks')
)
);
const groupedAlerts = groupBy(
alertsByDate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ const mapStateToProps = (
const { colors, locationNames, settingsConfig, activeIndicator } = ownProps;
const { payload } = location;
const selectorData = {
data: data.data,
extent: data.extent,
...data,
settings,
options: settingsConfig.options,
meta: countryData[!payload.region ? 'regions' : 'subRegions'],
Expand Down
41 changes: 21 additions & 20 deletions app/javascript/services/alerts.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import axios from 'axios';
import moment from 'moment';

const REQUEST_URL = `${process.env.GFW_API_HOST_PROD}`;
const DATASET = process.env.GLAD_PRECALC_DATASET;
const REQUEST_URL = process.env.GFW_API_HOST_PROD;
const GLAD_ISO_DATASET = process.env.GLAD_ISO_DATASET;
const GLAD_ADM1_DATASET = process.env.GLAD_ADM1_DATASET;
const GLAD_ADM2_DATASET = process.env.GLAD_ADM2_DATASET;

const QUERIES = {
gladAlerts: '{location}?aggregate_values=true&aggregate_by={period}',
gladIntersectionAlerts:
"SELECT iso, adm1, adm2, alerts as count, alert_date as date, area_ha, polyname FROM data WHERE {location} AND alert_date > '{dateBound}' AND polyname = '{polyname}'",
"SELECT iso, adm1, adm2, week, year, alerts as count, area_ha, polyname FROM data WHERE {location} AND polyname = '{polyname}'",
viirsAlerts:
'{location}?group=true&period={period}&thresh=0&geostore={geostore}'
};
Expand All @@ -20,26 +20,27 @@ const getLocation = (country, region, subRegion) =>
subRegion ? ` AND adm2 = ${subRegion}` : ''
}`;

export const fetchGladAlerts = ({ country, region, subRegion, period }) => {
const url = `${REQUEST_URL}/glad-alerts/admin/${QUERIES.gladAlerts}`
.replace('{location}', getLocationQuery(country, region, subRegion))
.replace('{period}', period || 'week');
export const fetchGladAlerts = ({ country, region, subRegion }) => {
let glad_summary_table = GLAD_ISO_DATASET;
if (subRegion) {
glad_summary_table = GLAD_ADM2_DATASET;
} else if (region) {
glad_summary_table = GLAD_ADM1_DATASET;
}
const url = `${REQUEST_URL}/query/${glad_summary_table}?sql=${
QUERIES.gladIntersectionAlerts
}`
.replace('{location}', getLocation(country, region, subRegion))
.replace('{polyname}', 'gadm28');
return axios.get(url);
};

export const fetchGladIntersectionAlerts = ({ country, region, indicator }) => {
const url = `${REQUEST_URL}/query/${DATASET}?sql=${
QUERIES.gladIntersectionAlerts
}`
const url = `${REQUEST_URL}/query/${
region ? GLAD_ADM2_DATASET : GLAD_ADM1_DATASET
}?sql=${QUERIES.gladIntersectionAlerts}`
.replace('{location}', getLocation(country, region))
.replace('{polyname}', indicator)
.replace(
'{dateBound}',
moment
.utc()
.subtract(53, 'weeks')
.format('YYYY/MM/DD')
);
.replace('{polyname}', indicator);
return axios.get(url);
};

Expand Down