How to return values from evalscript and use it as input to another function in the application

as shown in the below posted evalscript, it is adapted it to obtain the min and max ndvi in the tiff.
but i have the following questions:

1- how can i return the min and max value of the ndvi from the evalscript?in other words, the evalscript should return ndvi values of each pixel in the tiff, and the min and max
value of the ndvi in the tiff, how should the evalscript return the ndvis, min and max altogether?

2-when the evalscript returns the data mentioned in the latter question, how can i have access to these data? i mean, assuming that the evalscript returns ndvis, min and max.
for the ndvis, they are in the tiff and can be obtained by reading the pixels from the tiff. but what about the min and max values of the ndvi? how can they be accessed after they
get returned from the evalscript? i want to have the min and max as input to another function in my application!

evalscript:

function setup() {
   return {
	 input: [{
	   bands: ["B04", "B08"],
	   units: "DN"
	 }],
	 output: [
	  {
		 id: "default",
		 bands: 1,
		 sampleType: "FLOAT32",
		 nodataValue: NaN,
	  },
	 ],
	 mosaicking: Mosaicking.ORBIT
   }
 }

 function updateOutput(output, collection) {
   output.default.bands = collection.scenes.length
 }

 function preProcessScenes (collections) {
   collections.scenes.orbits = collections.scenes.orbits.filter(function (orbit) {
	   var orbitDateFrom = new Date(orbit.dateFrom)
	   return orbitDateFrom.getTime() >= (collections.to.getTime()-3*31*24*3600*1000);
   })
   return collections
}


function calcNDVI(sample) {
   var denom = sample.B04+sample.B08;
   return ((denom!=0) ? (sample.B08-sample.B04) / denom : 0.0);
 }


 function evaluatePixel(samples) {
   // find the min and max ndvi
   var max = -9999999999;
   var min = 9999999999;
   for (var i=0; i<samples.length; i++) {
	  let ndvi = calcNDVI(samples[i]);
	  max = ndvi > max ? ndvi:max;
	  min = ndvi < min ? ndvi : min;
   }

   // Precompute an array to contain NDVI observations
   var n_observations = samples.length;
   let ndvi = new Array(n_observations).fill(NaN);
 
 //Fill the array with NDVI values
   samples.forEach((sample, index) => {
	 ndvi[index] = (sample.B08 - sample.B04) / (sample.B08 + sample.B04) ;
   });
					 
   return ndvi;
 }

Hello Burkhard,

You can do this with the BYOC API. Check out the intro to BYOC webinar.

Or go through the documentation here.

thank you for the reply.
as stated in the link of the documentation you sent, i have to deploy BYOD.
what i could not understand is, why do i need that?i just want the evalscritp to return the min and max along with the ndvi, and then i want to access the returned values.

If you want the temporal min and max as well as the spatial min and max, you need to make two requests. One statistical API request and one process API request.

would you please tell me why do i need to make process api request for the min and max values of the ndvi?

Ah I understand now. You need to concat the max and min to the ndvi output array. And in the updateOutput array it needs to be collection.scenes.length+2 since you return all ndvi values AND max and min.

So in the evaluatePixel function it would be return ndvi.concat([max, min]);

This way the last two bands which are in the returned geotiff will be your max and min.

thanks, would you please tell me if the final evalscript posted below is correct:

function setup() {
   return {
	 input: [{
	   bands: ["B04", "B08"],
	   units: "DN"
	 }],
	 output: [
	  {
		 id: "default",
		 bands: 1,
		 sampleType: "FLOAT32",
		 nodataValue: NaN,
	  },
	  {
		id: "min_max_ndvi",
		bands: 2, // Two bands: one for min, one for max
		sampleType: "FLOAT32"
	 }
	 ],
	 mosaicking: Mosaicking.ORBIT
   }
 }

 function updateOutput(output, collection) {
   output.default.bands = collection.scenes.length + 2;
 }

 function preProcessScenes (collections) {
   collections.scenes.orbits = collections.scenes.orbits.filter(function (orbit) {
	   var orbitDateFrom = new Date(orbit.dateFrom)
	   return orbitDateFrom.getTime() >= (collections.to.getTime()-3*31*24*3600*1000);
   })
   return collections
}

function calcNDVI(sample) {
   var denom = sample.B04+sample.B08;
   return ((denom!=0) ? (sample.B08-sample.B04) / denom : 0.0);
 }

 function evaluatePixel(samples) {
   var max = -9999999999;
   var min = 9999999999
   // find the min and max ndvi
   for (var i=0; i<samples.length; i++) {
	  let ndvi = calcNDVI(samples[i]);
	  max = ndvi > max ? ndvi:max;
	  min = ndvi < min ? ndvi : min;
   }

   // Precompute an array to contain NDVI observations
   var n_observations = samples.length;
   let ndvi = new Array(n_observations).fill(NaN);
 
 //Fill the array with NDVI values
   samples.forEach((sample, index) => {
	 ndvi[index] = (sample.B08 - sample.B04) / (sample.B08 + sample.B04) ;
   });
					 
   return ndvi.concat([max, min]);
}