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 @@
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', () => {