diff --git a/algorithm_catalog/developmentseed/snow_classifier/openeo_udp/snow_classifier.json b/algorithm_catalog/developmentseed/snow_classifier/openeo_udp/snow_classifier.json new file mode 100644 index 00000000..3c7ff833 --- /dev/null +++ b/algorithm_catalog/developmentseed/snow_classifier/openeo_udp/snow_classifier.json @@ -0,0 +1,485 @@ +{ + "process_graph": { + "loadcollection1": { + "process_id": "load_collection", + "arguments": { + "bands": [ + "B02", + "B03", + "B11", + "B08", + "B04" + ], + "id": "SENTINEL2_L2A", + "properties": { + "eo:cloud_cover": { + "process_graph": { + "lte1": { + "process_id": "lte", + "arguments": { + "x": { + "from_parameter": "value" + }, + "y": 30 + }, + "result": true + } + } + } + }, + "spatial_extent": { + "from_parameter": "bounding_box" + }, + "temporal_extent": { + "from_parameter": "time" + } + } + }, + "reducedimension1": { + "process_id": "reduce_dimension", + "arguments": { + "data": { + "from_node": "loadcollection1" + }, + "dimension": "t", + "reducer": { + "process_graph": { + "first1": { + "process_id": "first", + "arguments": { + "data": { + "from_parameter": "data" + } + }, + "result": true + } + } + } + } + }, + "resamplespatial1": { + "process_id": "resample_spatial", + "arguments": { + "align": "upper-left", + "data": { + "from_node": "reducedimension1" + }, + "method": "near", + "projection": null, + "resolution": 20 + } + }, + "applydimension1": { + "process_id": "apply_dimension", + "arguments": { + "data": { + "from_node": "resamplespatial1" + }, + "dimension": "bands", + "process": { + "process_graph": { + "arrayelement1": { + "process_id": "array_element", + "arguments": { + "data": { + "from_parameter": "data" + }, + "index": 4 + } + }, + "divide1": { + "process_id": "divide", + "arguments": { + "x": { + "from_node": "arrayelement1" + }, + "y": 10000.0 + } + }, + "multiply1": { + "process_id": "multiply", + "arguments": { + "x": { + "from_node": "divide1" + }, + "y": 2.5 + } + }, + "arrayelement2": { + "process_id": "array_element", + "arguments": { + "data": { + "from_parameter": "data" + }, + "index": 3 + } + }, + "divide2": { + "process_id": "divide", + "arguments": { + "x": { + "from_node": "arrayelement2" + }, + "y": 10000.0 + } + }, + "subtract1": { + "process_id": "subtract", + "arguments": { + "x": { + "from_node": "divide2" + }, + "y": { + "from_node": "divide1" + } + } + }, + "add1": { + "process_id": "add", + "arguments": { + "x": { + "from_node": "divide2" + }, + "y": { + "from_node": "divide1" + } + } + }, + "divide3": { + "process_id": "divide", + "arguments": { + "x": { + "from_node": "subtract1" + }, + "y": { + "from_node": "add1" + } + } + }, + "subtract2": { + "process_id": "subtract", + "arguments": { + "x": { + "from_node": "divide3" + }, + "y": 0.1 + } + }, + "absolute1": { + "process_id": "absolute", + "arguments": { + "x": { + "from_node": "subtract2" + } + } + }, + "lte2": { + "process_id": "lte", + "arguments": { + "x": { + "from_node": "absolute1" + }, + "y": 0.025 + } + }, + "if1": { + "process_id": "if", + "arguments": { + "accept": 1, + "reject": 0, + "value": { + "from_node": "lte2" + } + } + }, + "arrayelement3": { + "process_id": "array_element", + "arguments": { + "data": { + "from_parameter": "data" + }, + "index": 1 + } + }, + "divide4": { + "process_id": "divide", + "arguments": { + "x": { + "from_node": "arrayelement3" + }, + "y": 10000.0 + } + }, + "arrayelement4": { + "process_id": "array_element", + "arguments": { + "data": { + "from_parameter": "data" + }, + "index": 2 + } + }, + "divide5": { + "process_id": "divide", + "arguments": { + "x": { + "from_node": "arrayelement4" + }, + "y": 10000.0 + } + }, + "subtract3": { + "process_id": "subtract", + "arguments": { + "x": { + "from_node": "divide4" + }, + "y": { + "from_node": "divide5" + } + } + }, + "add2": { + "process_id": "add", + "arguments": { + "x": { + "from_node": "divide4" + }, + "y": { + "from_node": "divide5" + } + } + }, + "divide6": { + "process_id": "divide", + "arguments": { + "x": { + "from_node": "subtract3" + }, + "y": { + "from_node": "add2" + } + } + }, + "gte1": { + "process_id": "gte", + "arguments": { + "x": { + "from_node": "divide6" + }, + "y": 0.4 + } + }, + "if2": { + "process_id": "if", + "arguments": { + "accept": 1, + "reject": { + "from_node": "if1" + }, + "value": { + "from_node": "gte1" + } + } + }, + "gt1": { + "process_id": "gt", + "arguments": { + "x": { + "from_node": "divide4" + }, + "y": 0.3 + } + }, + "and1": { + "process_id": "and", + "arguments": { + "x": { + "from_node": "if2" + }, + "y": { + "from_node": "gt1" + } + } + }, + "if3": { + "process_id": "if", + "arguments": { + "accept": 1.0, + "reject": { + "from_node": "multiply1" + }, + "value": { + "from_node": "and1" + } + } + }, + "multiply2": { + "process_id": "multiply", + "arguments": { + "x": { + "from_node": "divide4" + }, + "y": 2.5 + } + }, + "if4": { + "process_id": "if", + "arguments": { + "accept": 0.8, + "reject": { + "from_node": "multiply2" + }, + "value": { + "from_node": "and1" + } + } + }, + "arrayelement5": { + "process_id": "array_element", + "arguments": { + "data": { + "from_parameter": "data" + }, + "index": 0 + } + }, + "divide7": { + "process_id": "divide", + "arguments": { + "x": { + "from_node": "arrayelement5" + }, + "y": 10000.0 + } + }, + "multiply3": { + "process_id": "multiply", + "arguments": { + "x": { + "from_node": "divide7" + }, + "y": 2.5 + } + }, + "if5": { + "process_id": "if", + "arguments": { + "accept": 0.4, + "reject": { + "from_node": "multiply3" + }, + "value": { + "from_node": "and1" + } + } + }, + "arraycreate1": { + "process_id": "array_create", + "arguments": { + "data": [ + { + "from_node": "if3" + }, + { + "from_node": "if4" + }, + { + "from_node": "if5" + } + ] + }, + "result": true + } + } + } + } + }, + "apply1": { + "process_id": "apply", + "arguments": { + "data": { + "from_node": "applydimension1" + }, + "process": { + "process_graph": { + "linearscalerange1": { + "process_id": "linear_scale_range", + "arguments": { + "inputMax": 1, + "inputMin": 0, + "outputMax": 255, + "outputMin": 0, + "x": { + "from_parameter": "x" + } + }, + "result": true + } + } + } + }, + "result": true + } + }, + "parameters": [ + { + "name": "time", + "description": "Temporal range for data acquisition", + "schema": { + "type": "array", + "subtype": "temporal-interval" + }, + "default": [ + "2019-10-26", + "2019-10-30" + ], + "optional": true + }, + { + "name": "bounding_box", + "description": "Spatial extent for Bovec, Slovenia", + "schema": { + "type": "object", + "subtype": "bounding-box" + }, + "default": { + "west": 13.4, + "south": 46.32, + "east": 13.54, + "north": 46.39 + }, + "optional": true + }, + { + "name": "cloud_cover", + "description": "Maximum scene-level cloud cover percentage", + "schema": { + "type": "number" + }, + "default": 30, + "optional": true + }, + { + "name": "ndsi_threshold", + "description": "NDSI value above which a pixel is classified as snow", + "schema": { + "type": "number" + }, + "default": 0.4, + "optional": true + }, + { + "name": "target_resolution", + "description": "Spatial resolution (meters) to resample to before classification. Defaults to 20m, the coarsest native resolution among the requested bands (B11 SWIR), so no band is upsampled beyond its native resolution.", + "schema": { + "type": "number" + }, + "default": 20, + "optional": true + } + ], + "id": "snow_classifier", + "summary": "Snow Classifier detection from Sentinel-2 imagery using NDSI and NDVI with openEO.", + "description": "Detects snow from Sentinel-2 L2A imagery using the Normalized Difference Snow Index (NDSI) as the primary indicator, with the Normalized Difference Vegetation Index (NDVI) as an additional constraint for borderline pixels. Pixels classified as snow are rendered in a light beige color; remaining pixels keep a brightened true-color appearance. Converted from the Sentinel Hub Snow Classifier evalscript." +} \ No newline at end of file diff --git a/algorithm_catalog/developmentseed/snow_classifier/records/preview.png b/algorithm_catalog/developmentseed/snow_classifier/records/preview.png new file mode 100644 index 00000000..5388fcf0 Binary files /dev/null and b/algorithm_catalog/developmentseed/snow_classifier/records/preview.png differ diff --git a/algorithm_catalog/developmentseed/snow_classifier/records/snow_classifier.json b/algorithm_catalog/developmentseed/snow_classifier/records/snow_classifier.json new file mode 100644 index 00000000..c93d6b46 --- /dev/null +++ b/algorithm_catalog/developmentseed/snow_classifier/records/snow_classifier.json @@ -0,0 +1,152 @@ +{ + "id": "snow_classifier", + "type": "Feature", + "conformsTo": [ + "https://www.opengis.net/spec/ogcapi-records-1/1.0/req/record-core", + "https://apex.esa.int/core/openeo-udp" + ], + "geometry": null, + "properties": { + "created": "2026-07-28T00:00:00Z", + "updated": "2026-07-28T00:00:00Z", + "type": "service", + "title": "Snow Classifier", + "description": "Detects snow from Sentinel-2 L2A imagery using the Normalized Difference Snow Index (NDSI) as the primary indicator, with the Normalized Difference Vegetation Index (NDVI) as an additional constraint for borderline pixels. Pixels classified as snow are rendered in a light beige color; remaining pixels keep a brightened true-color appearance. Converted from the Sentinel Hub Snow Classifier evalscript. Adapted from a SentinelHub Custom Script by Authors not listed.", + "keywords": [ + "Land Use/Land Cover Classification", + "Sentinel-2" + ], + "language": { + "code": "en-US", + "name": "English (United States)" + }, + "languages": [ + { + "code": "en-US", + "name": "English (United States)" + } + ], + "contacts": [ + { + "name": "Development Seed", + "organization": "Development Seed", + "links": [ + { + "href": "https://developmentseed.org", + "title": "Development Seed", + "rel": "about", + "type": "text/html" + } + ], + "contactInstructions": "Contact via Development Seed", + "roles": [ + "processor" + ] + }, + { + "name": "Authors not listed", + "organization": "Sentinel Hub", + "links": [ + { + "href": "https://custom-scripts.sentinel-hub.com/custom-scripts/sentinel-2/snow_classifier/", + "title": "Snow Classifier SentinelHub Script", + "rel": "about", + "type": "text/html" + } + ], + "contactInstructions": "Original SentinelHub script. See link below.", + "roles": [ + "author" + ] + } + ], + "themes": [ + { + "concepts": [ + { + "id": "LAND COVER" + }, + { + "id": "REMOTE SENSING" + }, + { + "id": "Sentinel-2 MSI" + } + ], + "scheme": "https://gcmd.earthdata.nasa.gov/kms/concepts/concept_scheme/sciencekeywords" + } + ], + "formats": [ + { + "name": "GeoTiff" + }, + { + "name": "PNG" + } + ], + "license": "CC-BY-SA-4.0" + }, + "linkTemplates": [], + "links": [ + { + "rel": "application", + "type": "application/vnd.openeo+json;type=process", + "title": "openEO Process Definition", + "href": "https://raw.githubusercontent.com/ESA-APEx/apex_algorithms/153246fb08cfb2172c4d525133cddcb1b57e734b/algorithm_catalog/developmentseed/snow_classifier/openeo_udp/snow_classifier.json" + }, + { + "rel": "code", + "type": "text/html", + "title": "openeo-udp repository", + "href": "https://github.com/developmentseed/openeo-udp" + }, + { + "rel": "webapp", + "type": "text/html", + "title": "OpenEO Web Editor", + "href": "https://editor.openeo.org/?wizard=UDP&wizard%7Eprocess=snow_classifier&wizard%7EprocessUrl=https://raw.githubusercontent.com/ESA-APEx/apex_algorithms/153246fb08cfb2172c4d525133cddcb1b57e734b/algorithm_catalog/developmentseed/snow_classifier/openeo_udp/snow_classifier.json&server=https://openeo.dataspace.copernicus.eu/" + }, + { + "rel": "service", + "type": "application/json", + "title": "Copernicus Data Space - Production API", + "href": "https://openeo.dataspace.copernicus.eu/" + }, + { + "rel": "notebook", + "type": "application/x-ipynb+json", + "title": "Snow Classifier notebook", + "href": "https://raw.githubusercontent.com/developmentseed/openeo-udp/refs/heads/main/notebooks/sentinel/sentinel-2/land-cover/snow_classifier.ipynb" + }, + { + "rel": "platform", + "type": "application/json", + "title": "TiTiler openEO", + "href": "../../../../platform_catalog/titiler_openeo.json" + }, + { + "rel": "provider", + "type": "application/json", + "title": "Development Seed", + "href": "../../record.json" + }, + { + "rel": "preview", + "type": "image/png", + "title": "Snow Classification", + "href": "https://raw.githubusercontent.com/ESA-APEx/apex_algorithms/153246fb08cfb2172c4d525133cddcb1b57e734b/algorithm_catalog/developmentseed/snow_classifier/records/preview.png" + }, + { + "rel": "thumbnail", + "type": "image/png", + "title": "Thumbnail image", + "href": "https://raw.githubusercontent.com/ESA-APEx/apex_algorithms/153246fb08cfb2172c4d525133cddcb1b57e734b/algorithm_catalog/developmentseed/snow_classifier/records/thumbnail.png" + }, + { + "rel": "cite-as", + "type": "text/html", + "title": "Script Source Repository", + "href": "https://github.com/sentinel-hub/custom-scripts" + } + ] +} diff --git a/algorithm_catalog/developmentseed/snow_classifier/records/thumbnail.png b/algorithm_catalog/developmentseed/snow_classifier/records/thumbnail.png new file mode 100644 index 00000000..50096772 Binary files /dev/null and b/algorithm_catalog/developmentseed/snow_classifier/records/thumbnail.png differ