From f1a134ce9e13eb78bdeac3d9473f07c59a752f20 Mon Sep 17 00:00:00 2001 From: dgostencnik Date: Wed, 8 Apr 2020 09:47:46 +0200 Subject: [PATCH 1/5] convert evalscript to version3 --- src/layer/AbstractSentinelHubV3Layer.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/layer/AbstractSentinelHubV3Layer.ts b/src/layer/AbstractSentinelHubV3Layer.ts index 642775b1..dcbb125c 100644 --- a/src/layer/AbstractSentinelHubV3Layer.ts +++ b/src/layer/AbstractSentinelHubV3Layer.ts @@ -235,4 +235,19 @@ export class AbstractSentinelHubV3Layer extends AbstractLayer { const response = await axios.post(this.dataset.findDatesUTCUrl, payload); return response.data.map((date: string) => moment.utc(date).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; + } } From 265b5edb724d611a05761051b0f0fd887280a479 Mon Sep 17 00:00:00 2001 From: dgostencnik Date: Wed, 8 Apr 2020 09:48:41 +0200 Subject: [PATCH 2/5] add support for evalscriptUrl for processing api --- src/layer/AbstractSentinelHubV3Layer.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/layer/AbstractSentinelHubV3Layer.ts b/src/layer/AbstractSentinelHubV3Layer.ts index dcbb125c..b1a433db 100644 --- a/src/layer/AbstractSentinelHubV3Layer.ts +++ b/src/layer/AbstractSentinelHubV3Layer.ts @@ -100,8 +100,10 @@ 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); + const evalscriptV3 = await this.convertEvalscriptToV3(response.data); + this.evalscript = evalscriptV3; } if (!this.evalscript && !this.dataProduct) { const layerParams = await this.fetchLayerParamsFromSHServiceV3(); From adfa70ee4c941146153cd089d12817ab07103005 Mon Sep 17 00:00:00 2001 From: dgostencnik Date: Wed, 8 Apr 2020 10:55:25 +0200 Subject: [PATCH 3/5] add 2 examples with evalscriptUrl to stories --- stories/s1grdiw.stories.js | 46 ++++++++++++++++++++ stories/s2l2a.stories.js | 89 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) 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 }); From 7752df4683af5a4bdd8ebce482eb39e4a11647aa Mon Sep 17 00:00:00 2001 From: dgostencnik Date: Wed, 8 Apr 2020 11:00:02 +0200 Subject: [PATCH 4/5] fetching script should be also cached --- src/layer/AbstractSentinelHubV3Layer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layer/AbstractSentinelHubV3Layer.ts b/src/layer/AbstractSentinelHubV3Layer.ts index b1a433db..2eab6c6e 100644 --- a/src/layer/AbstractSentinelHubV3Layer.ts +++ b/src/layer/AbstractSentinelHubV3Layer.ts @@ -101,7 +101,7 @@ export class AbstractSentinelHubV3Layer extends AbstractLayer { throw new Error('This layer does not support Processing API (unknown dataset)'); } if (this.evalscriptUrl && !this.evalscript) { - const response = await axios.get(this.evalscriptUrl); + const response = await axios.get(this.evalscriptUrl, { responseType: 'text', useCache: true }); const evalscriptV3 = await this.convertEvalscriptToV3(response.data); this.evalscript = evalscriptV3; } From 1719195dbea868d6118327884b9b07f19a03595f Mon Sep 17 00:00:00 2001 From: dgostencnik Date: Fri, 10 Apr 2020 12:34:26 +0200 Subject: [PATCH 5/5] Code review: check version of fetched evalscript to avoid unnecessary conversion --- src/layer/AbstractSentinelHubV3Layer.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/layer/AbstractSentinelHubV3Layer.ts b/src/layer/AbstractSentinelHubV3Layer.ts index 2eab6c6e..75d3dca6 100644 --- a/src/layer/AbstractSentinelHubV3Layer.ts +++ b/src/layer/AbstractSentinelHubV3Layer.ts @@ -102,7 +102,13 @@ export class AbstractSentinelHubV3Layer extends AbstractLayer { } if (this.evalscriptUrl && !this.evalscript) { const response = await axios.get(this.evalscriptUrl, { responseType: 'text', useCache: true }); - const evalscriptV3 = await this.convertEvalscriptToV3(response.data); + 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) {