diff --git a/src/layer/AbstractSentinelHubV3Layer.ts b/src/layer/AbstractSentinelHubV3Layer.ts index eef69afe..d2cd08a0 100644 --- a/src/layer/AbstractSentinelHubV3Layer.ts +++ b/src/layer/AbstractSentinelHubV3Layer.ts @@ -100,8 +100,16 @@ export class AbstractSentinelHubV3Layer extends AbstractLayer { if (!this.dataset) { throw new Error('This layer does not support Processing API (unknown dataset)'); } - if (this.evalscriptUrl) { - throw new Error('EvalscriptUrl is not supported with Processing API'); + if (this.evalscriptUrl && !this.evalscript) { + const response = await axios.get(this.evalscriptUrl, { responseType: 'text', useCache: true }); + let evalscriptV3; + //Check version of fetched evalscript by checking if first line starts with //VERSION=3 + if (response.data.startsWith('//VERSION=3')) { + evalscriptV3 = response.data; + } else { + evalscriptV3 = await this.convertEvalscriptToV3(response.data); + } + this.evalscript = evalscriptV3; } if (!this.evalscript && !this.dataProduct) { const layerParams = await this.fetchLayerParamsFromSHServiceV3(); @@ -240,4 +248,19 @@ export class AbstractSentinelHubV3Layer extends AbstractLayer { found.sort((a, b) => b.unix() - a.unix()); return found.map(m => m.toDate()); } + + protected async convertEvalscriptToV3(evalscript: string): Promise { + const authToken = getAuthToken(); + const url = `https://services.sentinel-hub.com/api/v1/process/convertscript?datasetType=${this.dataset.shProcessingApiDatasourceAbbreviation}`; + const requestConfig: AxiosRequestConfig = { + headers: { + Authorization: `Bearer ${authToken}`, + 'Content-Type': 'application/ecmascript', + }, + useCache: true, + responseType: 'text', + }; + const res = await axios.post(url, evalscript, requestConfig); + return res.data; + } } diff --git a/stories/s1grdiw.stories.js b/stories/s1grdiw.stories.js index c8691989..e028cab3 100644 --- a/stories/s1grdiw.stories.js +++ b/stories/s1grdiw.stories.js @@ -254,6 +254,52 @@ export const getMapProcessingFromLayer = () => { return wrapperEl; }; +export const GetMapProcessingEvalscripturl = () => { + if (!process.env.CLIENT_ID || !process.env.CLIENT_SECRET) { + return "
Please set OAuth Client's id and secret for Processing API (CLIENT_ID, CLIENT_SECRET env vars)
"; + } + + const img = document.createElement('img'); + img.width = '512'; + img.height = '512'; + + const wrapperEl = document.createElement('div'); + wrapperEl.innerHTML = '

GetMap with Processing setting evalscriptUrl with v2 script

'; + wrapperEl.insertAdjacentElement('beforeend', img); + + // getMap is async: + const perform = async () => { + await setAuthTokenWithOAuthCredentials(); + + const layer = new S1GRDAWSEULayer({ + instanceId, + layerId, + evalscriptUrl: + 'https://raw.githubusercontent.com/sentinel-hub/custom-scripts/cf4930ae0dd6d155f80ff311d6d862ca28de412b/sentinel-1/sar_for_deforestation/script.js', + }); + + const getMapParams = { + bbox: new BBox( + CRS_EPSG4326, + 12.089080810546877, + 44.625908121970454, + 12.250614166259767, + 44.74210015957899, + ), + fromTime: new Date(Date.UTC(2018, 8 - 1, 28, 0, 0, 0)), + toTime: new Date(Date.UTC(2018, 8 - 1, 28, 23, 59, 59)), + width: 512, + height: 512, + format: MimeTypes.JPEG, + }; + const imageBlob = await layer.getMap(getMapParams, ApiType.PROCESSING); + img.src = URL.createObjectURL(imageBlob); + }; + perform().then(() => {}); + + return wrapperEl; +}; + export const findTilesEPSG3857 = () => { const layer = new S1GRDAWSEULayer({ instanceId, layerId }); diff --git a/stories/s2l2a.stories.js b/stories/s2l2a.stories.js index 91cf7f6a..f76c2c07 100644 --- a/stories/s2l2a.stories.js +++ b/stories/s2l2a.stories.js @@ -231,6 +231,95 @@ export const GetMapProcessingWithGeometryPolygon = () => { return wrapperEl; }; +export const GetMapProcessingEvalscripturl = () => { + if (!process.env.CLIENT_ID || !process.env.CLIENT_SECRET) { + return "
Please set OAuth Client's id and secret for Processing API (CLIENT_ID, CLIENT_SECRET env vars)
"; + } + + const img = document.createElement('img'); + img.width = '512'; + img.height = '512'; + + const wrapperEl = document.createElement('div'); + wrapperEl.innerHTML = '

GetMap with Processing for Sentinel-2 L2A by setting evalscriptUrl

'; + wrapperEl.insertAdjacentElement('beforeend', img); + + // getMap is async: + const perform = async () => { + await setAuthTokenWithOAuthCredentials(); + + const layerS2L2A = new S2L2ALayer({ + evalscriptUrl: + 'https://raw.githubusercontent.com/sentinel-hub/custom-scripts/master/sentinel-2/ulyssys_water_quality_viewer/src/script.js', + }); + + const getMapParams = { + bbox: new BBox( + CRS_EPSG4326, + 17.416763305664066, + 46.6560347296143, + 18.06289672851563, + 47.102849101370325, + ), + fromTime: new Date(Date.UTC(2019, 9 - 1, 5, 0, 0, 0)), + toTime: new Date(Date.UTC(2019, 9 - 1, 5, 23, 59, 59)), + width: 512, + height: 512, + format: MimeTypes.JPEG, + }; + const imageBlob = await layerS2L2A.getMap(getMapParams, ApiType.PROCESSING); + img.src = URL.createObjectURL(imageBlob); + }; + perform().then(() => {}); + + return wrapperEl; +}; + +export const GetMapProcessingEvalscripturlVersion2 = () => { + if (!process.env.CLIENT_ID || !process.env.CLIENT_SECRET) { + return "
Please set OAuth Client's id and secret for Processing API (CLIENT_ID, CLIENT_SECRET env vars)
"; + } + + const img = document.createElement('img'); + img.width = '512'; + img.height = '512'; + + const wrapperEl = document.createElement('div'); + wrapperEl.innerHTML = + '

GetMap with Processing for Sentinel-2 L2A by setting evalscriptUrl with version2 script for ndwi

'; + wrapperEl.insertAdjacentElement('beforeend', img); + + // getMap is async: + const perform = async () => { + await setAuthTokenWithOAuthCredentials(); + + const layerS2L2A = new S2L2ALayer({ + evalscriptUrl: + 'https://gist.githubusercontent.com/dgostencnik/49a8620816d47d75a2bb8433eea03984/raw/6a478bc7d6e898f2720385738fb38889424f4483/s2-ndwi-v2', + }); + + const getMapParams = { + bbox: new BBox( + CRS_EPSG4326, + 17.416763305664066, + 46.6560347296143, + 18.06289672851563, + 47.102849101370325, + ), + fromTime: new Date(Date.UTC(2019, 9 - 1, 5, 0, 0, 0)), + toTime: new Date(Date.UTC(2019, 9 - 1, 5, 23, 59, 59)), + width: 512, + height: 512, + format: MimeTypes.JPEG, + }; + const imageBlob = await layerS2L2A.getMap(getMapParams, ApiType.PROCESSING); + img.src = URL.createObjectURL(imageBlob); + }; + perform().then(() => {}); + + return wrapperEl; +}; + export const GetMapWMSMaxCC20vs60 = () => { const layerS2L2A20 = new S2L2ALayer({ instanceId, layerId, maxCloudCoverPercent: 20 }); const layerS2L2A60 = new S2L2ALayer({ instanceId, layerId, maxCloudCoverPercent: 60 });