diff --git a/src/titiler/extensions/titiler/extensions/templates/cog_viewer.html b/src/titiler/extensions/titiler/extensions/templates/cog_viewer.html index 04d37554b..ef12fda47 100644 --- a/src/titiler/extensions/titiler/extensions/templates/cog_viewer.html +++ b/src/titiler/extensions/titiler/extensions/templates/cog_viewer.html @@ -256,8 +256,25 @@
+ + +
+
Expression
+ +
+ +
+
Algorithm
+
+ +
+
+
+
Rescale
@@ -338,7 +355,8 @@ dataset_statistics: undefined, data_type: undefined, band_descriptions: undefined, - colormap: undefined + colormap: undefined, + algorithms: undefined, } const tilejson_endpoint = '{{ tilejson_endpoint }}' @@ -469,6 +487,20 @@ }) } +const setAlgorithmParams = (params) => { + const algorithmSelector = document.getElementById('algorithm-selector'); + const algorithm = algorithmSelector.selectedOptions[0].value; + if (algorithm !== 'no-algo') { + params.algorithm = algorithm + const params_inputs = document.getElementById('algorithm-params-form')?.getElementsByTagName('input') + if (params_inputs) { + const algorithm_params = Object.fromEntries(Array.from(params_inputs).map(e => [e.name, e.value])) + params.algorithm_params = JSON.stringify(algorithm_params) + } + } + return params +} + const set1bViz = () => { params = { url: scope.url @@ -479,6 +511,13 @@ params.rescale = `${document.getElementById('data-min').value},${document.getElementById('data-max').value}` } + params = setAlgorithmParams(params) + + const expression = document.getElementById('expression').value + if (expression && expression?.length > 0) { + params.expression = encodeURIComponent(expression) + } + const cmap = document.getElementById('colormap-selector')[document.getElementById('colormap-selector').selectedIndex] if (cmap.value !== 'b&w') params.colormap_name = cmap.value @@ -499,6 +538,14 @@ if (['uint8','int8'].indexOf(scope.data_type) === -1 && !scope.colormap) { params.rescale = `${document.getElementById('data-min').value},${document.getElementById('data-max').value}` } + + params = setAlgorithmParams(params) + + const expression = document.getElementById('expression').value + if (expression && expression?.length > 0) { + params.expression = expression + } + let url_params = Object.keys(params).map(i => `${i}=${params[i]}`).join('&') if (url_params !== '') url_params = `${url_params}&` @@ -510,6 +557,29 @@ const updateViz = () => { const rasterType = document.getElementById('toolbar').querySelector(".active").id + + // only select algorithms applicable to 1d or 3d inputs + const algorithms_arr = Object.entries(scope.algorithms); + const filtered_1b = algorithms_arr.filter(([algo_id, algo]) => (algo.inputs.nbands === 1) || (algo.inputs.nbands === null)); + const algorithms_filtered_1b = Object.fromEntries(filtered_1b); + const filtered_3b = algorithms_arr.filter(([algo_id, algo]) => (algo.inputs.nbands >= 2) || (algo.inputs.nbands === null)); + const algorithms_filtered_3b = Object.fromEntries(filtered_3b); + const algorithmOptions = Array.from(document.getElementById('algorithm-selector').getElementsByTagName('option')); + for (o of algorithmOptions) {o.disabled = true} + document.getElementById('no-algo').disabled = false + switch (rasterType) { + case '1b': + for (const algo_id in algorithms_filtered_1b) { + algorithmOptions.find(o => o.value == algo_id).disabled = false + } + break + case '3b': + for (const algo_id in algorithms_filtered_3b) { + algorithmOptions.find(o => o.value == algo_id).disabled = false + } + break + } + switch (rasterType) { case '1b': set1bViz() @@ -910,6 +980,63 @@ .catch(err => { console.warn(err) }) + + fetch(`/algorithms`) + .then(res => { + if (res.ok) return res.json() + throw new Error('Network response was not ok.') + }) + .then(algorithms => { + // console.log('ALGORITHMS', algorithms) + scope.algorithms = algorithms; + const algorithmSelector = document.getElementById('algorithm-selector'); + for (const algo_id in algorithms) { + const algo = algorithms[algo_id]; + const opt = document.createElement('option'); + opt.value = algo_id; + opt.innerHTML = algo['title']; + algorithmSelector.appendChild(opt); + } + algorithmSelector.addEventListener('change', updateAlgorithmParams); + }) + .catch(err => { + console.warn(err); + }) +} + +function updateAlgorithmParams() { + const algorithmSelector = document.getElementById('algorithm-selector'); + // Recreate div to host params + const paramsElOld = Array.from(algorithmSelector.parentNode.parentNode.children).find(el => el.id == 'algorithm-params'); + if (paramsElOld) { + paramsElOld.remove(); + } + const selected = algorithmSelector.selectedOptions[0].value; + if (selected === 'no-algo') { return; } + + // Reproduce the div + form from lat/lon inputs + const paramsEl = document.createElement('div'); + paramsEl.className = 'grid w-full'; + paramsEl.id = 'algorithm-params'; + algorithmSelector.parentNode.parentNode.appendChild(paramsEl); + const paramsForm = document.createElement('form'); + paramsForm.className = 'grid'; + paramsForm.id = 'algorithm-params-form'; + paramsEl.appendChild(paramsForm); + + const params = scope.algorithms[selected]['parameters']; + for (const param_id in params) { + const param = params[param_id]; + const paramEl = document.createElement('div'); + paramEl.className = 'row'; + paramsForm.appendChild(paramEl); + paramEl.innerHTML = ` + + + `; + } + // Update to react to params change + updateViz(); } document.getElementById('launch').addEventListener('click', () => {