Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
Expand All @@ -8,8 +9,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- New proposal processes for DGGS-based workflows:
- `aggregate_k_ring` - Aggregate values over DGGS k-ring neighborhoods, comparable to `aggregate_spatial_window`.
- `apply_neighborhood_dggs` - Apply custom focal processes over DGGS neighborhoods, comparable to `apply_neighborhood`,
- `apply_kernel_dggs` - Apply weighted DGGS neighborhood convolution based on topological distance, comparable to `apply_kernel`.
- `filter_k_ring` - Filter based on rings around DGGS zones.
- `resample_dggs` - Up- and downsample based on DGGS resolution levels, comparable to `resample_spatial`,
- `resample_cube_dggs` - Up and downsample based on a target DGGS data cube, comparable to `resample_cube_spatial`.
- `mask_dggs` - Mask a DGGS data cube based on a DGGS-based mask, comparable to `mask`.

### Changed

- `apply_kernel`, `apply_neighborhood`, `resample_spatial`, `resample_cube_spatial`, and `aggregate_spatial_window`: Added explicit DGGS guidance and updated cross-references to DGGS-native alternatives.
- `reduce_spatial` and `resample_cube_spatial`: Added a recommended DGGS alternative.
- `aggregate_spatial`, `filter_bbox`, `filter_spatial`, `load_collection`, `load_stac`, and `mask_polygon`: Added DGGS-specific behavior clarification (zone centroid inclusion rule for spatial filtering/masking/aggregation).
- `resample_spatial`: Added support for DGGS input; a DGGS data cube can be converted to raster when a suitable target projection is provided.

### Fixed

## [2.0.0-rc.2] - 2026-02-02
Expand All @@ -31,7 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Processes that have been marked as stable: `apply_polygon`, `date_between`, `date_shift`, `filter_labels`, `inspect`
- Clarified for various mathematical functions the defined input and output ranges.
Mention that `NaN` is returned outside of the defined input range where possible.
- Clarified for several comparison processes how `NaN` values have to be handled.
- Clarified for several comparison processes how `NaN` values have to be handled.
- Clarified for various processes the handling of no-data values and `null`, see also the [implementation guide](meta/implementation.md#no-data-value). [#480](https://github.com/Open-EO/openeo-processes/issues/480)
- Added a [section about character encodings to the implementation guide](meta/implementation.md#character-encoding).
Removed any character encoding related wording from the process specifications itself.
Expand Down
49 changes: 32 additions & 17 deletions aggregate_spatial.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,44 @@
"description": "Aggregates statistics for one or more geometries (e.g. zonal statistics for polygons) over the spatial dimensions. The given data cube can have multiple additional dimensions and for all these dimensions results will be computed individually.\n\nAn 'unbounded' aggregation over the full extent of the horizontal spatial dimensions can be computed with the process ``reduce_spatial()``.\n\nThis process passes a list of values to the reducer. The list of values has an undefined order, therefore processes such as ``last()`` and ``first()`` that depend on the order of the values will lead to unpredictable results.",
"categories": [
"cubes",
"aggregate"
"aggregate",
"dggs"
],
"parameters": [
{
"name": "data",
"description": "A raster data cube with at least two spatial dimensions.\n\nThe data cube implicitly gets restricted to the bounds of the geometries as if ``filter_spatial()`` would have been used with the same values for the corresponding parameters immediately before this process.",
"schema": {
"type": "object",
"subtype": "datacube",
"dimensions": [
{
"type": "spatial",
"axis": [
"x",
"y"
]
}
]
}
"description": "A raster or DGGS data cube.\n\nThe data cube implicitly gets restricted to the bounds of the geometries as if ``filter_spatial()`` would have been used with the same values for the corresponding parameters immediately before this process.",
"schema": [
{
"title": "Raster data cube",
"description": "A raster data cube with at least two spatial dimensions.",
"type": "object",
"subtype": "datacube",
"dimensions": [
{
"type": "spatial",
"axis": [
"x",
"y"
]
}
]
},
{
"title": "DGGS data cube",
"type": "object",
"subtype": "datacube",
"dimensions": [
{
"type": "dggs"
}
]
}
]
},
{
"name": "geometries",
"description": "Geometries for which the aggregation will be computed. Feature properties are preserved for vector data cubes and all GeoJSON Features.\n\nOne value will be computed per label in the dimension of type `geometry`, GeoJSON `Feature` or `Geometry`. For a `FeatureCollection` multiple values will be computed, one value per contained `Feature`. No values will be computed for empty geometries. For example, a single value will be computed for a `MultiPolygon`, but two values will be computed for a `FeatureCollection` containing two polygons.\n\n- For **polygons**, the process considers all pixels for which the point at the pixel center intersects with the corresponding polygon (as defined in the Simple Features standard by the OGC).\n- For **points**, the process considers the closest pixel center.\n- For **lines** (line strings), the process considers all the pixels whose centers are closest to at least one point on the line.\n\nThus, pixels may be part of multiple geometries and be part of multiple aggregations. No operation is applied to geometries that are outside of the bounds of the data.",
"description": "Geometries for which the aggregation will be computed. Feature properties are preserved for vector data cubes and all GeoJSON Features.\n\nOne value will be computed per label in the dimension of type `geometry`, GeoJSON `Feature` or `Geometry`. For a `FeatureCollection` multiple values will be computed, one value per contained `Feature`. No values will be computed for empty geometries. For example, a single value will be computed for a `MultiPolygon`, but two values will be computed for a `FeatureCollection` containing two polygons.\n\n- For **polygons**, the process considers all values for which the point at the pixel or DGGS zone centroid intersects with the corresponding polygon (as defined in the Simple Features standard by the OGC).\n- For **points**, the process considers the closest pixel or DGGS zone based on the centroid.\n- For **lines** (line strings), the process considers all the values whose pixel or zone centroid are closest to at least one point on the line.\n\nPixels or DGGS zones may be part of multiple geometries and be part of multiple aggregations. No operation is applied to geometries that are outside of the bounds of the data.",
"schema": [
{
"title": "Vector Data Cube",
Expand Down Expand Up @@ -84,7 +99,7 @@
},
{
"name": "target_dimension",
"description": "By default (which is `null`), the process only computes the results and doesn't add a new dimension.\n\nIf this parameter contains a new dimension name, the computation also stores information about the total count of pixels (valid + invalid pixels) and the number of valid pixels (see ``is_valid()``) for each computed value. These values are added as a new dimension. The new dimension of type `other` has the dimension labels `value`, `total_count` and `valid_count`.\n\nFails with a `TargetDimensionExists` exception if a dimension with the specified name exists.",
"description": "By default (which is `null`), the process only computes the results and doesn't add a new dimension.\n\nIf this parameter contains a new dimension name, the computation also stores information about the total count of values (valid + invalid values) and the number of valid values (see ``is_valid()``) for each computed value. These values are added as a new dimension. The new dimension of type `other` has the dimension labels `value`, `total_count` and `valid_count`.\n\nFails with a `TargetDimensionExists` exception if a dimension with the specified name exists.",
"schema": {
"type": [
"string",
Expand Down
2 changes: 1 addition & 1 deletion apply_kernel.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "apply_kernel",
"summary": "Apply a spatial convolution with a kernel",
"description": "Applies a 2D convolution (i.e. a focal operation with a weighted kernel) on the horizontal spatial dimensions (axes `x` and `y`) of a raster data cube.\n\nEach value in the kernel is multiplied with the corresponding pixel value and all products are summed up afterwards. The sum is then multiplied with the factor.\n\nThe process can't handle non-numerical or infinite numerical values in the data cube. Boolean values are converted to integers (`false` = 0, `true` = 1), but all other non-numerical, NaN, no-data, or infinite values are replaced with zeroes by default (see parameter `replace_invalid`).\n\nFor cases requiring more generic focal operations or non-numerical values, see ``apply_neighborhood()``.",
"description": "Applies a 2D convolution (i.e. a focal operation with a weighted kernel) on the horizontal spatial dimensions (axes `x` and `y`) of a raster data cube.\n\nEach value in the kernel is multiplied with the corresponding pixel value and all products are summed up afterwards. The sum is then multiplied with the factor.\n\nThe process can't handle non-numerical or infinite numerical values in the data cube. Boolean values are converted to integers (`false` = 0, `true` = 1), but all other non-numerical, NaN, no-data, or infinite values are replaced with zeroes by default (see parameter `replace_invalid`).\n\nFor DGGS-native weighted neighborhood operations, see ``apply_kernel_dggs()``.\n\nFor cases requiring more generic focal operations or non-numerical values, see ``apply_neighborhood()`` for raster data cubes and ``apply_neighborhood_dggs()`` for DGGS data cubes.",
"categories": [
"cubes",
"math > image filter"
Expand Down
2 changes: 1 addition & 1 deletion apply_neighborhood.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "apply_neighborhood",
"summary": "Apply a process to pixels in a n-dimensional neighborhood",
"description": "Applies a focal process to a data cube.\n\nA focal process is a process that works on a 'neighborhood' of pixels. The neighborhood can extend into multiple dimensions, this extent is specified by the `size` argument. It is not only (part of) the size of the input window, but also the size of the output for a given position of the sliding window. The sliding window moves with multiples of `size`.\n\nAn overlap can be specified so that neighborhoods can have overlapping boundaries. This allows for continuity of the output. The overlap region must be included in the data cube or array returned by `process`, but any changed values will be ignored. The missing overlap at the borders of the original data cube is made available as no-data values in the sub-data cubes.\n\nThe neighborhood size should be kept small enough, to avoid running beyond computational resources, but a too-small size will result in a larger number of process invocations, which may slow down processing. Window sizes for spatial dimensions typically range from 64 to 512 pixels, while overlaps of 8 to 32 pixels are common.\n\nFor the special case of 2D convolution, it is recommended to use ``apply_kernel()``.",
"description": "Applies a focal process to a data cube.\n\nA focal process is a process that works on a 'neighborhood' of pixels. The neighborhood can extend into multiple dimensions, this extent is specified by the `size` argument. It is not only (part of) the size of the input window, but also the size of the output for a given position of the sliding window. The sliding window moves with multiples of `size`.\n\nAn overlap can be specified so that neighborhoods can have overlapping boundaries. This allows for continuity of the output. The overlap region must be included in the data cube or array returned by `process`, but any changed values will be ignored. The missing overlap at the borders of the original data cube is made available as no-data values in the sub-data cubes.\n\nThe neighborhood size should be kept small enough, to avoid running beyond computational resources, but a too-small size will result in a larger number of process invocations, which may slow down processing. Window sizes for spatial dimensions typically range from 64 to 512 pixels, while overlaps of 8 to 32 pixels are common.\n\nFor DGGS-native topological neighborhoods, see ``apply_neighborhood_dggs()``.\n\nFor the special case of 2D convolution, it is recommended to use ``apply_kernel()`` for raster data cubes and ``apply_kernel_dggs()`` for DGGS data cubes.",
"categories": [
"cubes"
],
Expand Down
4 changes: 2 additions & 2 deletions apply_polygon.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "apply_polygon",
"summary": "Apply a process to segments of the data cube",
"description": "Applies a process to segments of the data cube that are defined by the given polygons. For each polygon provided, all pixels for which the point at the pixel center intersects with the polygon (as defined in the Simple Features standard by the OGC) are collected into sub data cubes. If a pixel is part of multiple of the provided polygons (e.g., when the polygons overlap), the `GeometriesOverlap` exception is thrown. Each sub data cube is passed individually to the given process.",
"description": "Applies a process to segments of the data cube that are defined by the given polygons. For each polygon provided, all pixels for which the pixel centroid intersects with the polygon (as defined in the Simple Features standard by the OGC) are collected into sub data cubes. If a pixel is part of multiple of the provided polygons (e.g., when the polygons overlap), the `GeometriesOverlap` exception is thrown. Each sub data cube is passed individually to the given process.",
"categories": [
"cubes"
],
Expand Down Expand Up @@ -97,7 +97,7 @@
},
{
"name": "mask_value",
"description": "All pixels for which the point at the pixel center **does not** intersect with the polygon are replaced with the given value. The default value is `null`, which uses the no-data value of the data cube.\n\nThis parameter can provide a distinction between no-data values within the polygon and masked pixels outside of it.",
"description": "All pixels for which the pixel centroid **does not** intersect with the polygon are replaced with the given value. The default value is `null`, which uses the no-data value of the data cube.\n\nThis parameter can provide a distinction between no-data values within the polygon and masked pixels outside of it.",
"schema": [
{
"type": "number"
Expand Down
5 changes: 5 additions & 0 deletions dev/.words
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ center
centers
dekad
DEM-based
DGGS
DGGS-based
DGGS-native
DGGRS
Domini
gamma0
GeoJSON
Expand All @@ -30,6 +34,7 @@ resampled
resamples
Resamples
resampling
reprojection
Sentinel-2
Sentinel-2A
Sentinel-2B
Expand Down
69 changes: 35 additions & 34 deletions dev/package.json
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
{
"name": "@openeo/processes",
"version": "2.0.0-rc.2",
"author": "openEO Consortium",
"contributors": [
{
"name": "Matthias Mohr"
"name": "@openeo/processes",
"version": "2.0.0-rc.2",
"author": "openEO Consortium",
"contributors": [
{
"name": "Matthias Mohr"
}
],
"license": "Apache-2.0",
"description": "Validates the processes specified in this repository.",
"homepage": "http://openeo.org",
"bugs": {
"url": "https://github.com/Open-EO/openeo-processes/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Open-EO/openeo-processes.git"
},
"devDependencies": {
"@openeo/processes-lint": "github:Open-EO/openeo-processes-lint#dggs",
"concat-json-files": "^1.1.0",
"http-server": "^14.1.1"
Comment thread
m-mohr marked this conversation as resolved.
},
"scripts": {
"check-tests": "node check-tests.js",
"has-tests": "node has-tests.js",
"lint": "openeo-processes-lint testConfig.json",
"test": "npm run has-tests && npm run check-tests && npm run lint",
"generate": "concat-json-files \"../{*,proposals/*}.json\" -t \"processes.json\"",
"start": "npm run generate && http-server -p 9876 -o docs.html -c-1"
},
"dependencies": {
"ajv": "^8.17.1",
"json5": "^2.2.3"
}
],
"license": "Apache-2.0",
"description": "Validates the processes specified in this repository.",
"homepage": "http://openeo.org",
"bugs": {
"url": "https://github.com/Open-EO/openeo-processes/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Open-EO/openeo-processes.git"
},
"devDependencies": {
"@openeo/processes-lint": "^0.1.5",
"concat-json-files": "^1.1.0",
"http-server": "^14.1.1"
},
"scripts": {
"check-tests": "node check-tests.js",
"has-tests": "node has-tests.js",
"lint": "openeo-processes-lint testConfig.json",
"test": "npm run has-tests && npm run check-tests && npm run lint",
"generate": "concat-json-files \"../{*,proposals/*}.json\" -t \"processes.json\"",
"start": "npm run generate && http-server -p 9876 -o docs.html -c-1"
},
"dependencies": {
"ajv": "^8.17.1",
"json5": "^2.2.3"
}

}
Loading
Loading