### Render Documentation Locally Source: https://github.com/eu-cdse/documentation/blob/publish/README.md Render or preview the documentation locally after installing Quarto and cloning the repository with submodules. ```bash quarto render cdse_doc.qmd ``` ```bash quarto preview cdse_doc.qmd ``` -------------------------------- ### Setup Click-to-Copy S3 Links Source: https://github.com/eu-cdse/documentation/blob/publish/custom.html Finds all anchor tags with a 'data-s3-path' attribute. It replaces them with a styled link that, when clicked, copies the S3 path to the clipboard and provides visual feedback. ```javascript document.addEventListener("DOMContentLoaded", function() { function setupS3Links() { let s3Links = document.querySelectorAll('a[data-s3-path]'); s3Links.forEach(link => { // Create S3 link wrapper const wrapper = document.createElement('div'); wrapper.className = 's3-link-wrapper'; const s3Link = document.createElement('a'); s3Link.className = 's3-link'; s3Link.textContent = link.textContent; s3Link.href = '#'; s3Link.title = 'Click to copy S3 path'; const tooltip = document.createElement('div'); tooltip.className = 's3-tooltip'; tooltip.textContent = link.dataset.s3Path; wrapper.appendChild(s3Link); wrapper.appendChild(tooltip); link.replaceWith(wrapper); // Add click to copy functionality s3Link.addEventListener('click', function(e) { e.preventDefault(); // Copy to clipboard navigator.clipboard.writeText(tooltip.textContent).then(function() { // Show feedback const feedback = document.createElement('div'); feedback.className = 's3-copy-feedback'; feedback.textContent = 'Copied!'; wrapper.appendChild(feedback); feedback.style.opacity = '1'; feedback.style.visibility = 'visible'; // Remove feedback after 2 seconds setTimeout(function() { feedback.style.opacity = '0'; feedback.style.visibility = 'hidden'; setTimeout(function() { feedback.remove(); }, 300); }, 1500); }).catch(function(err) { console.error('Failed to copy:', err); }); }); }); } setupS3Links(); }); ``` -------------------------------- ### Access Scene Metadata with TILE Mosaicking Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Evalscript/resources/metadata_sh_docs.ipynb Use `scenes.tiles` to access metadata when mosaicking is set to TILE. This example also shows how to calculate a maximum value for a band and store it in metadata using a global variable, ensuring it's written only once. ```python url = 'https://sh.dataspace.copernicus.eu' evalscript = """ //VERSION=3 function setup() { return { input: ["B02", "dataMask"], mosaicking: Mosaicking.TILE, output: { id: "default", bands: 1 } } } var maxValueB02 = 0 function evaluatePixel(samples, scenes, inputMetadata, customData, outputMetadata) { //Average value of band B02 based on the requested tiles var sumOfValidSamplesB02 = 0 var numberOfValidSamples = 0 for (i = 0; i < samples.length; i++) { var sample = samples[i] if (sample.dataMask == 1){ sumOfValidSamplesB02 += sample.B02 numberOfValidSamples += 1 if (sample.B02 > maxValueB02){ maxValueB02 = sample.B02 } } } return [sumOfValidSamplesB02 / numberOfValidSamples] } function updateOutputMetadata(scenes, inputMetadata, outputMetadata) { outputMetadata.userData = { "tiles": scenes.tiles } outputMetadata.userData.maxValueB02 = maxValueB02 } """ request = { "input": { "bounds": { "bbox": [13.8, 45.8, 13.9, 45.9] }, "data": [{ "type": "sentinel-2-l1c", "dataFilter": { "timeRange": { "from": "2020-12-01T00:00:00Z", "to": "2020-12-06T23:59:59Z" } } }] }, "output": { "responses": [{ "identifier": "default", "format": { "type": "image/tiff" } }, { "identifier": "userdata", "format": { "type": "application/json" } } ] }, "evalscript": evalscript } headers = { 'Content-Type': 'application/json', 'Accept': 'application/x-tar' } response = oauth.post(f"{url}/process/v1", headers=headers, json = request) tar = tarfile.open(fileobj=io.BytesIO(response.content)) userdata = json.load(tar.extractfile(tar.getmember('userdata.json'))) userdata ``` -------------------------------- ### Authenticate Sentinel Hub Requests Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Evalscript/resources/metadata_sh_docs.ipynb Fetches an access token for authenticating Sentinel Hub requests. Replace placeholders with your client ID and secret. Ensure you have the Sentinel Hub Python library installed. ```python import matplotlib.pyplot as plt import numpy as np from sentinelhub import CRS, DataCollection, Geometry, MimeType, SentinelHubRequest, SHConfig config = SHConfig() config.sh_client_id = "" config.sh_client_secret = "" config.sh_base_url = "https://sh.dataspace.copernicus.eu" config.sh_token_url = "https://identity.dataspace.copernicus.eu/auth/realms/CDSE/protocol/openid-connect/token" ``` -------------------------------- ### Python Script for Processing and Metadata Output Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Evalscript/resources/metadata_sh_docs.ipynb This script configures and executes a Sentinel-2 data processing job. It defines an evalscript to calculate NDVI, filter tiles based on dates and thresholds, and outputs metadata to userdata.json. Ensure you have the necessary libraries (oauth, tarfile, io, json) installed and configured. ```python url = 'https://sh.dataspace.copernicus.eu' evalscript = """ //VERSION=3 function setup() { return { input: ["B08", "B04", "dataMask"], mosaicking: Mosaicking.TILE, output: { id: "default", bands: 1 } } } // User's inputs var notAllowedDates = ["2020-12-06", "2020-12-09"] var ndviThreshold = 0.2 var tilesPPS = [] function preProcessScenes(collections) { tilesPPS = collections.scenes.tiles collections.scenes.tiles = collections.scenes.tiles.filter(function(tile) { var tileDate = tile.date.split("T")[0]; return !notAllowedDates.includes(tileDate); }) return collections } function evaluatePixel(samples, scenes, inputMetadata, customData, outputMetadata) { var valid_ndvi_sum = 0 var numberOfValidSamples = 0 for (i = 0; i < samples.length; i++) { var sample = samples[i] if (sample.dataMask == 1){ var ndvi = (sample.B08 - sample.B04)/(sample.B08 + sample.B04) if (ndvi <= ndviThreshold){ valid_ndvi_sum += ndvi numberOfValidSamples += 1 } } } return [valid_ndvi_sum / numberOfValidSamples] } function updateOutputMetadata(scenes, inputMetadata, outputMetadata) { outputMetadata.userData = { "inputMetadata.serviceVersion": inputMetadata.serviceVersion } outputMetadata.userData.description = "The evalscript calculates average ndvi " + "in a requested time period. Data collected on notAllowedDates is excluded. " + " ndvi values greater than ndviThreshold are excluded. " + " More about ndvi: https://www.indexdatabase.de/db/i-single.php?id=58." // Extract dates for all available tiles (before filtering) var tilePPSDates = [] for (i = 0; i < tilesPPS.length; i++){ tilePPSDates.push(tilesPPS[i].date) } outputMetadata.userData.tilesPPSDates = tilePPSDates // Extract dates for tiles after filtering out tiles with "notAllowedDates" var tileDates = [] for (i = 0; i < scenes.tiles.length; i++){ tileDates.push(scenes.tiles[i].date) } outputMetadata.userData.tilesDates = tileDates outputMetadata.userData.notAllowedDates = notAllowedDates outputMetadata.userData.ndviThreshold = ndviThreshold } " request = { "input": { "bounds": { "bbox": [13.8, 45.8, 13.9, 45.9] }, "data": [{ "type": "sentinel-2-l1c", "dataFilter": { "timeRange": { "from": "2020-12-01T00:00:00Z", "to": "2020-12-15T23:59:59Z" } } }] }, "output": { "responses": [{ "identifier": "default", "format": { "type": "image/tiff" } }, { "identifier": "userdata", "format": { "type": "application/json" } } ] }, "evalscript": evalscript } headers = { 'Content-Type': 'application/json', 'Accept': 'application/x-tar' } response = oauth.post(f"{url}/process/v1", headers=headers, json = request) tar = tarfile.open(fileobj=io.BytesIO(response.content)) userdata = json.load(tar.extractfile(tar.getmember('userdata.json'))) userdata ``` -------------------------------- ### Import OpenEO Packages Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Openeo/resources/notebooks/basic_example.ipynb Import the necessary libraries for OpenEO client and process definitions. ```python import openeo from openeo.processes import process ``` -------------------------------- ### Connect to OpenEO Dataspace Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Openeo/resources/notebooks/basic_example.ipynb Establish a connection to the OpenEO Dataspace backend. Ensure the URL is correct for your region. ```python connection = openeo.connect("https://openeosh.dataspace.copernicus.eu/") ``` -------------------------------- ### Clone Repository Source: https://github.com/eu-cdse/documentation/blob/publish/README.md Clone the documentation repository to your local machine to begin editing. ```bash git clone https://github.com/eu-cdse/documentation.git ``` -------------------------------- ### Initialize Piwik PRO Tag Manager Source: https://github.com/eu-cdse/documentation/blob/publish/custom.html Initializes the Piwik PRO tag manager script asynchronously. It sets up the data layer and loads the tracking script from a specified URL. ```javascript (function (window, document, dataLayerName, id) { window[dataLayerName] = window[dataLayerName] || [], window[dataLayerName].push({ start: (new Date).getTime(), event: "stg.start" }); var scripts = document.getElementsByTagName('script')[0], tags = document.createElement('script'); var qP = []; dataLayerName !== "dataLayer" && qP.push("data_layer_name=" + dataLayerName); var qPString = qP.length > 0 ? ("?" + qP.join("&")) : ""; tags.async = !0, tags.src = "https://copernicus.containers.piwik.pro/" + id + ".js" + qPString, scripts.parentNode.insertBefore(tags, scripts); !function (a, n, i) { a[n] = a[n] || {}; for (var c = 0; c < i.length; c++) !function (i) { a[n][i] = a[n][i] || {}, a[n][i].api = a[n][i].api || function () { var a = [].slice.call(arguments, 0); "string" == typeof a[0] && window[dataLayerName].push({ event: n + "." + i + ":" + a[0], parameters: [].slice.call(arguments, 1) }) } }(i[c]) }(window, "ppms", ["tm", "cm"] ); })(window, document, 'dataLayer', '3280dd25-dd97-47f1-9e1d-d3e302af68d2'); ``` -------------------------------- ### Clone Submodules Source: https://github.com/eu-cdse/documentation/blob/publish/README.md Initialize and update submodules when cloning the repository to include necessary notebook resources. ```bash git clone --recurse-submodules https://github.com/eu-cdse/notebook-samples.git ``` ```bash git clone --recurse-submodules https://github.com/Open-EO/openeo-community-examples.git ``` -------------------------------- ### Update Submodules Source: https://github.com/eu-cdse/documentation/blob/publish/README.md Ensure submodules are up-to-date with their respective repositories by running this command. ```bash git submodule update --remote ``` -------------------------------- ### Download Image Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Openeo/resources/notebooks/basic_example.ipynb Saves the image data to a file. Specify the desired filename and extension. ```python save5.download("niceColor.jpeg") ``` -------------------------------- ### Load Sentinel-2 Collection Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Openeo/resources/notebooks/basic_example.ipynb Load a Sentinel-2 Level 1C collection with specified spatial and temporal extents, and select specific bands. ```python load2 = connection.load_collection(collection_id = "SENTINEL2_L1C_SENTINELHUB", spatial_extent = {"west": 14.503132250376241, "south": 45.98989222284457, "east": 14.578437275398317, "north": 46.04381770188389, "width": 1250, "height": 1250}, temporal_extent = ["2022-03-26T00:00:00Z", "2022-03-26T23:59:59Z"], bands = ["B02", "B03", "B04"]) ``` -------------------------------- ### Display Image Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Openeo/resources/notebooks/basic_example.ipynb Renders a saved image file within the IPython environment. Ensure the image file exists in the current directory or provide a correct path. ```python from IPython.display import Image Image(filename='niceColor.jpeg') ``` -------------------------------- ### Filter Tiles by Satellite (S2A vs S2B) Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Evalscript/resources/metadata_sh_docs.ipynb This script filters satellite tiles to include only those acquired from the S2B satellite. It parses the product ID to extract the satellite name and then filters the tiles accordingly. ```python url = 'https://sh.dataspace.copernicus.eu' evalscript = """ //VERSION=3 function setup() { return { input: ["B02", "dataMask"], mosaicking: Mosaicking.TILE, output: { id: "default", bands: 1 } } } function getSatelliteFromProductId(productId) { textParts = productId.split("_") satellite = textParts[0]; return satellite } // Filter by satellite function preProcessScenes(collections) { collections.scenes.tiles = collections.scenes.tiles.filter(function (tile) { return getSatelliteFromProductId(tile.productId) == "S2B"}); return collections; } function evaluatePixel(samples, scenes, inputMetadata, customData, outputMetadata) { outputMetadata.userData = { "tiles": scenes.tiles } //Average value of band B02 based on the requested tiles var sumOfValidSamplesB02 = 0 var numberOfValidSamples = 0 for (i = 0; i < samples.length; i++) { var sample = samples[i] if (sample.dataMask == 1){ sumOfValidSamplesB02 += sample.B02 numberOfValidSamples += 1 } } return [sumOfValidSamplesB02 / numberOfValidSamples] } " request = { "input": { "bounds": { "bbox": [13.8, 45.8, 13.9, 45.9] }, "data": [{ "type": "sentinel-2-l1c", "dataFilter": { "timeRange": { "from": "2020-12-01T00:00:00Z", "to": "2020-12-06T23:59:59Z" } } }] }, "output": { "responses": [{ "identifier": "default", "format": { "type": "image/tiff" } }, { "identifier": "userdata", "format": { "type": "application/json" } } ] }, "evalscript": evalscript } headers = { 'Content-Type': 'application/json', 'Accept': 'application/x-tar' } response = oauth.request("POST", f"{url}/process/v1", headers=headers, json = request) tar = tarfile.open(fileobj=io.BytesIO(response.content)) userdata = json.load(tar.extractfile(tar.getmember('userdata.json'))) userdata ``` -------------------------------- ### Apply Dimension to Collection Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Openeo/resources/notebooks/basic_example.ipynb Applies a specified process to a dimension of a data collection. Ensure the 'satEnh' process is defined and imported. ```python apply2 = apply1.apply_dimension(dimension = "bands", process = satEnh) ``` -------------------------------- ### Apply Band Processing Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Openeo/resources/notebooks/basic_example.ipynb Applies the 'process1' function to each band of the loaded collection. ```python apply1 = load2.apply_dimension(dimension = "bands", process = process1) ``` -------------------------------- ### Handle Question Click and Scroll Source: https://github.com/eu-cdse/documentation/blob/publish/custom.html Updates the URL hash to the clicked question's ID and scrolls the page to that question, opening its details. Requires a scrollToQuestion function. ```javascript function handleQuestionClick(questionId) { // Update the hash in the URL window.location.hash = questionId; // Scroll to the target element and adjust its position scrollToQuestion(questionId); } ``` -------------------------------- ### Authenticate with OIDC Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Openeo/resources/notebooks/basic_example.ipynb Authenticate the connection using OpenID Connect. This is typically required for accessing protected resources. ```python connection.authenticate_oidc() ``` -------------------------------- ### Access Scene Metadata with ORBIT Mosaicking Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Evalscript/resources/metadata_sh_docs.ipynb Use `scenes.orbits` to access metadata when mosaicking is set to ORBIT. Pass this metadata to the `userdata.json` file using `outputMetadata.userData` in the `updateOutputMetadata` function. ```python url = 'https://sh.dataspace.copernicus.eu' evalscript = """ //VERSION=3 function setup() { return { input: ["B02", "dataMask"], mosaicking: Mosaicking.ORBIT, output: { id: "default", bands: 1 } } } function evaluatePixel(samples, scenes, inputMetadata, customData, outputMetadata) { //Average value of band B02 based on the requested scenes var sumOfValidSamplesB02 = 0 var numberOfValidSamples = 0 for (i = 0; i < samples.length; i++) { var sample = samples[i] if (sample.dataMask == 1){ sumOfValidSamplesB02 += sample.B02 numberOfValidSamples += 1 } } return [sumOfValidSamplesB02 / numberOfValidSamples] } function updateOutputMetadata(scenes, inputMetadata, outputMetadata) { outputMetadata.userData = { "inputMetadata": inputMetadata } outputMetadata.userData["orbits"] = scenes.orbits } """ request = { "input": { "bounds": { "bbox": [13.8, 45.8, 13.9, 45.9] }, "data": [{ "type": "sentinel-2-l1c", "dataFilter": { "timeRange": { "from": "2020-12-01T00:00:00Z", "to": "2020-12-06T23:59:59Z" } } }] }, "output": { "responses": [{ "identifier": "default", "format": { "type": "image/tiff" } }, { "identifier": "userdata", "format": { "type": "application/json" } } ] }, "evalscript": evalscript } headers = { 'Content-Type': 'application/json', 'Accept': 'application/x-tar' } response = oauth.post(f"{url}/process/v1", headers=headers, json = request) tar = tarfile.open(fileobj=io.BytesIO(response.content)) userdata = json.load(tar.extractfile(tar.getmember('userdata.json'))) userdata ``` -------------------------------- ### Initialize Checkbox Toggling on Load Source: https://github.com/eu-cdse/documentation/blob/publish/custom.html On window load, iterates through a predefined array of level IDs and calls togglecheck to set their initial display state to 'none'. ```javascript window.onload = function() { // Modify this array to contain the levelids of checkboxes that should be unchecked by default var uncheckedByDefault = ["Level-0"] for (var i = 0; i < uncheckedByDefault.length; i++) { togglecheck(uncheckedByDefault[i], "none"); } }; ``` -------------------------------- ### Set Navbar Title Link Source: https://github.com/eu-cdse/documentation/blob/publish/custom.html Sets the href attribute of the first element with class 'navbar-title' to '/Home.html' when the window loads. ```javascript window.onload = () => { const elems = document.getElementsByClassName('navbar-title'); if (elems.length > 0) { const title = elems[0]; title.parentElement.href = '/Home.html' } } ``` -------------------------------- ### Define sRGB Conversion Function Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Openeo/resources/notebooks/basic_example.ipynb Implements the sRGB color space conversion. It uses a conditional logic based on a threshold to apply different transformations. ```python def sRGB(x, context = None): accept = x * 12.92 # (12.92 * x) power1 = x**0.41666666666 reject = power1 * 1.055 - 0.055 # 1.055 * x^0.41666666666 lte2 = process("lte", x = x, y = 0.0031308) # c <= 0.0031308 if1 = process("if", value = lte2, accept = accept, reject = reject) return if1 ``` -------------------------------- ### Print Result as JSON Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Openeo/resources/notebooks/basic_example.ipynb Prints the result of the save operation to the console in JSON format. This is useful for debugging or inspecting the output metadata. ```python print(save5.to_json()) ``` -------------------------------- ### Scroll to URL Hash on DOM Load Source: https://github.com/eu-cdse/documentation/blob/publish/custom.html On DOMContentLoaded, checks if a hash exists in the URL. If so, it calls scrollToQuestion after a short delay to ensure the page is ready. ```javascript document.addEventListener("DOMContentLoaded", function() { // Check if there is a hash in the URL if (window.location.hash) { // Scroll to the target element and adjust its position after a short delay setTimeout(function() { scrollToQuestion(window.location.hash); }, 100); } }); ``` -------------------------------- ### Define Saturation Enhancement Function Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Openeo/resources/notebooks/basic_example.ipynb Enhances image saturation by adjusting Red, Green, and Blue channels. It applies sRGB conversion after saturation adjustments. ```python def satEnh(data, context = None): r = data[2] # r g = data[1] # g b = data[0] # b rsat = 6.5 * r # r * sat gsat = 6.5 * g # g * sat bsat = 6.5 * b # b* sat subtract3 = 1 - 1.3 # (1 - sat) sum = r + g + b # (r + g + b) avg = sum / 3 # (r + g + b)/3 avgS = subtract3 * avg # (1 - sat) * ((r + g + b) / 3.0) sum1 = rsat + avgS # r * sat + avgS sum2 = gsat + avgS # g * sat + avgS sum3 = bsat + avgS # b * sat + avgS clip1 = process("clip", x = sum1, min = 0, max = 1) # clip(avgS + r * sat) clip2 = process("clip", x = sum2, min = 0, max = 1) # clip(avgS + g * sat) clip3 = process("clip", x = sum3, min = 0, max = 1) # clip(avgS + b * sat) # satEnh(sAdj(smp.B04), sAdj(smp.B03), sAdj(smp.B02)) array1 = process("array_create", data = [sRGB(clip1), sRGB(clip2), sRGB(clip3)]) return array1 ``` -------------------------------- ### Filter Tiles by Relative Orbit ID Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Evalscript/resources/metadata_sh_docs.ipynb This script filters satellite tiles based on their relative orbit ID. It extracts the relative orbit ID from the product ID and selects tiles belonging to a specified orbit (e.g., orbit 122). ```python url = 'https://sh.dataspace.copernicus.eu' evalscript = """ //VERSION=3 function setup() { return { input: ["B02", "dataMask"], mosaicking: Mosaicking.TILE, output: { id: "default", bands: 1 } } } function getRelativeOrbitIdFromProductId(productId) { textParts = productId.split("_") relativeOrbitId = parseInt(textParts[4].substring(1)); return relativeOrbitId } // Filter by relative orbit id function preProcessScenes(collections) { var allowedRelativeOrbits = [122] collections.scenes.tiles = collections.scenes.tiles.filter(function(tile) { var relativeOrbitId = getRelativeOrbitIdFromProductId(tile.productId); return allowedRelativeOrbits.includes(relativeOrbitId) }) return collections; } function evaluatePixel(samples, scenes, inputMetadata, customData, outputMetadata) { outputMetadata.userData = { "scenes": scenes.tiles } //Average value of band B02 based on the requested tiles var sumOfValidSamplesB02 = 0 var numberOfValidSamples = 0 for (i = 0; i < samples.length; i++) { var sample = samples[i] if (sample.dataMask == 1){ sumOfValidSamplesB02 += sample.B02 numberOfValidSamples += 1 } } return [sumOfValidSamplesB02 / numberOfValidSamples] } " request = { "input": { "bounds": { "bbox": [13.8, 45.8, 13.9, 45.9] }, "data": [{ "type": "sentinel-2-l1c", "dataFilter": { "timeRange": { "from": "2020-12-01T00:00:00Z", "to": "2020-12-06T23:59:59Z" } } }] }, "output": { "responses": [{ "identifier": "default", "format": { "type": "image/tiff" } }, { "identifier": "userdata", "format": { "type": "application/json" } } ] }, "evalscript": evalscript } headers = { 'Content-Type': 'application/json', 'Accept': 'application/x-tar' } response = oauth.request("POST", f"{url}/process/v1", headers=headers, json = request) tar = tarfile.open(fileobj=io.BytesIO(response.content)) userdata = json.load(tar.extractfile(tar.getmember('userdata.json'))) userdata ``` -------------------------------- ### Define Processing Function for Bands Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Openeo/resources/notebooks/basic_example.ipynb Applies spectral adjustments to individual bands (B2, B3, B4) after subtracting a bias. Creates an array of adjusted bands. ```python def process1(data, context = None): arrayB2 = data[2] - 0.041 arrayB3 = data[1] - 0.024 arrayB4 = data[0] - 0.013 array1 = process("array_create", data = [sAdj(arrayB2), sAdj(arrayB3), sAdj(arrayB4)]) return array1 ``` -------------------------------- ### Define Spectral Adjustment Function Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Openeo/resources/notebooks/basic_example.ipynb Defines a function 'sAdj' to adjust spectral values, likely for atmospheric or radiometric correction. It involves division, clipping, and power transformations. ```python def sAdj(x, context = None): divide2 = x / 3 # x / MaxR ar = process("clip", x = divide2, min = 0, max = 1) # ar mima = 0.13 / 3 # midR/maxR multiply1 = ar * (2 * mima -1) # (ar * (2 * midR/maxR - 1) divisor = multiply1 - mima # (ar * (2 * midR/maxR - 1) - midR/maxR) dividend = ar * (ar * mima - 1) # ar * (ar * (midR/maxR) - 1) adj = dividend / divisor # (ar * (ar * (midR/maxR) - 1)) / (ar * (2 * midR/maxR - 1) - midR/maxR) gOffPow = 0.01**2.3 power1 = 1.1**2.3 gOffRange = power1 - gOffPow # (1+gOff)^gamma - gOffPow subtract3 = (adj + 0.01)**2.3 - gOffPow # ((adj + gOff)^gamma)-gOffPow adjGamma = subtract3 / gOffRange # sAdj return adjGamma ``` -------------------------------- ### Scroll to Element with Offset Source: https://github.com/eu-cdse/documentation/blob/publish/custom.html Scrolls the window to a target element specified by a CSS selector. It calculates an offset to account for the viewport height and opens the target element if it's an expandable element. ```javascript function scrollToQuestion(questionId) { // Get the element with the ID specified in the hash var targetElement = document.querySelector(questionId); // Scroll to the target element and adjust its position if (targetElement) { // Calculate the position of the target element relative to the viewport var rect = targetElement.getBoundingClientRect(); var offsetTop = rect.top + window.scrollY; var targetPosition = offsetTop - (window.innerHeight / 16); // Scroll to the adjusted position window.scrollTo({ top: targetPosition, behavior: 'smooth' }); // Open the details element targetElement.open = true; } } ``` -------------------------------- ### Toggle Element Display by Class Source: https://github.com/eu-cdse/documentation/blob/publish/custom.html Toggles the display style ('block' or 'none') of all elements matching a given class name. Used here to toggle checkboxes by level ID. ```javascript function togglecheck(className, displayState){ var elements = document.getElementsByClassName(className) for (var i = 0; i < elements.length; i++){ if (elements[i].style.display === "none") { elements[i].style.display = "block"; } else { elements[i].style.display = "none"; } } } ``` -------------------------------- ### Toggle Navbar Brand Visibility on Scroll Source: https://github.com/eu-cdse/documentation/blob/publish/custom.html Hides the second element with class 'navbar-brand' when the user scrolls down more than 50 pixels, and shows it when scrolling back up. Listens for the scroll event. ```javascript function scrollFunction() { var prevScrollpos = window.pageYOffset; if (prevScrollpos > 50) { document.getElementsByClassName("navbar-brand")[1].style.display = "none"; } else { document.getElementsByClassName("navbar-brand")[1].style.display = "initial"; } } window.addEventListener('scroll', scrollFunction); ``` -------------------------------- ### Save Processed Result Source: https://github.com/eu-cdse/documentation/blob/publish/APIs/SentinelHub/Openeo/resources/notebooks/basic_example.ipynb Saves the result of a data processing operation to a specified format. The 'apply2' object should contain the processed data. ```python save5 = apply2.save_result(format = "jpeg") ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.