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

WV-2887 Preload Tour Story Imagery (no custom palettes) #4935

Merged
merged 9 commits into from
Jan 29, 2024
56 changes: 54 additions & 2 deletions web/js/containers/tour.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ import {
import {
clearCustoms,
} from '../modules/palettes/actions';
import { BULK_PALETTE_RENDERING_SUCCESS } from '../modules/palettes/constants';
import {
BULK_PALETTE_RENDERING_SUCCESS,
BULK_PALETTE_PRELOADING_SUCCESS,
} from '../modules/palettes/constants';
import { stop as stopAnimation } from '../modules/animation/actions';
import { onClose as closeModal } from '../modules/modal/actions';
import { LOCATION_POP_ACTION } from '../redux-location-state-customs';
Expand All @@ -39,6 +42,7 @@ import { changeTab as changeTabAction } from '../modules/sidebar/actions';
import ErrorBoundary from './error-boundary';
import history from '../main';
import util from '../util/util';
import { promiseImageryForTour } from '../modules/map/util';

const { HIDE_TOUR } = safeLocalStorage.keys;

Expand All @@ -51,6 +55,14 @@ const getTransitionAttr = function(transition) {
return '';
};

const prepareLayersList = function(layersString, config) {
let layers;
layers = layersParse12(layersString, config);
layers = uniqBy(layers, 'id');
layers = layers.filter((layer) => !layer.custom && !layer.disabled);
return layers;
};

class Tour extends React.Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -138,7 +150,7 @@ class Tour extends React.Component {

selectTour(e, currentStory, currentStoryIndex, currentStoryId) {
const {
config, renderedPalettes, selectTour, processStepLink, isKioskModeActive, isEmbedModeActive,
config, renderedPalettes, selectTour, processStepLink, isKioskModeActive, isEmbedModeActive, preProcessStepLink, promiseImageryForTour,
} = this.props;
if (e) e.preventDefault();
const kioskParam = this.getKioskParam(isKioskModeActive);
Expand All @@ -165,6 +177,13 @@ class Tour extends React.Component {
config,
renderedPalettes,
);
currentStory.steps.forEach((step) => {
preProcessStepLink(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to execute this step AFTER the first step loads? I am seeing significant slowdown on the first step of the story that is remediated by removing this code block.

We are also PreProcessing Step 1 here which is duplicated effort. Can we exclude step 1 from pre-processing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To fix the slowdown on the first step, I changed it so that we only preload the next step, rather than all steps at the beginning. This also solves the duplicated effort on step 1 pre-processing.

`${step.stepLink}&tr=${currentStoryId}${transitionParam}${kioskParam}&em=${isEmbedModeActive}`,
config,
promiseImageryForTour,
);
});
}

fetchMetadata(currentStory, stepIndex) {
Expand Down Expand Up @@ -516,12 +535,43 @@ const mapDispatchToProps = (dispatch) => ({
type: BULK_PALETTE_RENDERING_SUCCESS,
rendered: obj.rendered,
});
dispatch({
type: BULK_PALETTE_PRELOADING_SUCCESS,
tourStoryPalettes: obj.rendered,
});
dispatch({ type: LOCATION_POP_ACTION, payload: location });
});
} else {
dispatch({ type: LOCATION_POP_ACTION, payload: location });
}
},
preProcessStepLink: async (search, config, promiseImageryForTour) => {
search = search.split('/?').pop();
const parameters = util.fromQueryString(search);
let layersA = [];
let layersB = [];
const promisesParams = [];

if (parameters.l) {
layersA = prepareLayersList(parameters.l, config);
promisesParams.push({ layers: layersA, dateString: parameters.t });
}
if (parameters.l1) {
layersB = prepareLayersList(parameters.l1, config);
promisesParams.push({ layers: layersB, dateString: parameters.t1, activeString: 'activeB' });
}
preloadPalettes([...layersA, ...layersB], {}, false).then(async (obj) => {
await dispatch({
type: BULK_PALETTE_PRELOADING_SUCCESS,
tourStoryPalettes: obj.rendered,
});
const promises = [];
promisesParams.forEach((set) => {
promises.push(promiseImageryForTour(set.layers, set.dateString, set.activeString));
});
await Promise.all(promises);
});
},
startTour: () => {
dispatch(startTourAction());
},
Expand Down Expand Up @@ -561,6 +611,7 @@ const mapStateToProps = (state) => {
screenHeight,
renderedPalettes: palettes.rendered,
activeTab: sidebar.activeTab,
promiseImageryForTour: (layers, dateString, activeString) => promiseImageryForTour(state, layers, dateString, activeString),
};
};

Expand All @@ -582,6 +633,7 @@ Tour.propTypes = {
isActive: PropTypes.bool,
isKioskModeActive: PropTypes.bool,
processStepLink: PropTypes.func,
preProcessStepLink: PropTypes.func,
renderedPalettes: PropTypes.object,
resetProductPicker: PropTypes.func,
screenHeight: PropTypes.number,
Expand Down
2 changes: 1 addition & 1 deletion web/js/map/layerbuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ export default function mapLayerBuilder(config, cache, store) {
previousDate,
} = getRequestDates(def, options);
const date = closestDate;
if (date) {
if (date && !options.date) {
options.date = date;
}
const dateOptions = { date, nextDate, previousDate };
Expand Down
41 changes: 41 additions & 0 deletions web/js/modules/map/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import OlRendererCanvasTileLayer from 'ol/renderer/canvas/TileLayer';
import Promise from 'bluebird';
import { encode } from '../link/util';
import { getActiveVisibleLayersAtDate } from '../layers/selectors';
import { tryCatchDate } from '../date/util';

/*
* Set default extent according to time of day:
Expand Down Expand Up @@ -305,3 +306,43 @@ export async function promiseImageryForTime(state, date, activeString) {
selected.getView().changed();
return date;
}

/**
* Trigger tile requests for all given layers on a given date.
* @method promiseImageryForTour
*/
export async function promiseImageryForTour(state, layers, dateString, activeString) {
const { map } = state;
if (!map.ui.proj) return;
const {
cache, selected, createLayer, layerKey,
} = map.ui;
const appNow = lodashGet(state, 'date.appNow');
const date = tryCatchDate(dateString, appNow);
await Promise.all(layers.map(async (layer) => {
if (layer.type === 'granule' || layer.type === 'ttiler') {
return Promise.resolve();
}
const options = { date, group: activeString };
const keys = [];
if (layer.custom) {
keys.push(`palette=${layer.custom}`);
}
if (layer.min) {
keys.push(`min=${layer.min}`);
}
if (layer.max) {
keys.push(`max=${layer.max}`);
}
if (layer.squash) {
keys.push('squash');
}
if (keys.length > 0) {
options.style = keys.join(',');
}

const key = layerKey(layer, options, state);
const layerGroup = cache.getItem(key) || await createLayer(layer, options);
return promiseLayerGroup(layerGroup, selected);
}));
}
1 change: 1 addition & 0 deletions web/js/modules/palettes/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const CLEAR_CUSTOMS = 'PALETTES/CLEAR_CUSTOMS';
export const SET_CUSTOM = 'PALETTES/SET_CUSTOM';
export const LOADED_CUSTOM_PALETTES = 'PALETTES/LOADED_CUSTOM_PALETTES';
export const BULK_PALETTE_RENDERING_SUCCESS = 'PALETTES/BULK_PALETTE_RENDERING_SUCCESS';
export const BULK_PALETTE_PRELOADING_SUCCESS = 'PALETTES/BULK_PALETTE_PRELOADING_SUCCESS';

export const PALETTE_STRINGS_PERMALINK_ARRAY = [
'palette',
Expand Down
6 changes: 6 additions & 0 deletions web/js/modules/palettes/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
SET_THRESHOLD_RANGE_AND_SQUASH,
LOADED_CUSTOM_PALETTES,
BULK_PALETTE_RENDERING_SUCCESS,
BULK_PALETTE_PRELOADING_SUCCESS,
CLEAR_CUSTOM,
SET_DISABLED_CLASSIFICATION,
} from './constants';
Expand All @@ -23,6 +24,7 @@ export const defaultPaletteState = {
active: {},
activeB: {},
isLoading: {},
tourStoryPalettes: {},
};
export function getInitialPaletteState(config) {
const rendered = lodashGet(config, 'palettes.rendered') || {};
Expand All @@ -46,6 +48,10 @@ export function paletteReducer(state = defaultPaletteState, action) {
return update(state, {
rendered: { $merge: action.rendered || {} },
});
case BULK_PALETTE_PRELOADING_SUCCESS:
return update(state, {
tourStoryPalettes: { $merge: action.tourStoryPalettes || {} },
});
case REQUEST_PALETTE_SUCCESS: {
const isLoading = update(state.isLoading, { $unset: [action.id] });
return lodashAssign({}, state, {
Expand Down
5 changes: 3 additions & 2 deletions web/js/modules/palettes/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -350,15 +350,16 @@ export function getKey(layerId, groupStr, state) {
return '';
}
const def = getPalette(layerId, undefined, groupStr, state);
const { values } = getPalette(layerId, 0, groupStr, state).entries;
const keys = [];
if (def.custom) {
keys.push(`palette=${def.custom}`);
}
if (def.min) {
keys.push(`min=${def.min}`);
keys.push(`min=${getMinValue(values[def.min])}`);
}
if (def.max) {
keys.push(`max=${def.max}`);
keys.push(`max=${getMinValue(values[def.max])}`);
}
if (def.squash) {
keys.push('squash');
Expand Down
Loading