• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geo-engine / geoengine / 22961910495

11 Mar 2026 04:00PM UTC coverage: 88.133% (-0.06%) from 88.19%
22961910495

push

github

web-flow
feat: Operators in OpenAPI (#1116)

* build: use correct vergen-gitcl version

* feat: GdalSource as openapi

* feat: MockPointSource OpenAPI

* feat: expression openapi

* feat: RasterVectorJoin openapi

* fmt

* empty plot operator type

* fix: enhance expression and raster/vector join operators with new source structures

* fix: add Expression operator and support for RasterVectorJoin conversion

* fix: update ColumnNames enum to use structured values and enhance OpenAPI documentation

* fix: add schema annotation to output_band in ExpressionParameters to prevent null values

* fix: update OpenAPI documentation and schema annotations for Expression and GdalSource operators

* Refactor API structure and remove deprecated files

- Deleted the README.md and lib.rs files from the api module as they are no longer needed.
- Updated services/Cargo.toml to remove the geoengine-api dependency.
- Refactored the API documentation to point to the new processingGraphs endpoint.
- Introduced a new processing_graphs module with operators for raster and vector processing.
- Added parameters and processing logic for Expression and RasterVectorJoin operators.
- Implemented GdalSource and MockPointSource for data input handling.
- Enhanced serialization and deserialization for new data types and structures.

* refactor: remove 4th impl of coordinate2d

* refactor: update Workflow usage to Legacy variant across multiple modules

* build: add justfile for build, lint, run, and test commands

* refactor: rename TypedOperator to LegacyTypedOperator and update references in API and workflows

* refactor: update visit_schema and visit_response functions to include already_visited parameter for recursion prevention

* build: update dependencies to latest versions in Cargo.lock

429 of 561 new or added lines in 25 files covered. (76.47%)

3 existing lines in 2 files now uncovered.

112722 of 127900 relevant lines covered (88.13%)

506349.16 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.28
/services/src/api/model/processing_graphs/source.rs
1
use crate::api::model::{
2
    datatypes::Coordinate2D, processing_graphs::parameters::SpatialBoundsDerive,
3
};
4
use geoengine_datatypes::dataset::NamedData;
5
use geoengine_macros::type_tag;
6
use geoengine_operators::{
7
    mock::{
8
        MockPointSource as OperatorsMockPointSource,
9
        MockPointSourceParams as OperatorsMockPointSourceParameters,
10
    },
11
    source::{
12
        GdalSource as OperatorsGdalSource, GdalSourceParameters as OperatorsGdalSourceParameters,
13
    },
14
};
15
use serde::{Deserialize, Serialize};
16
use utoipa::ToSchema;
17

18
/// The [`GdalSource`] is a source operator that reads raster data using GDAL.
19
/// The counterpart for vector data is the [`OgrSource`].
20
///
21
/// ## Errors
22
///
23
/// If the given dataset does not exist or is not readable, an error is thrown.
24
///
25
#[type_tag(value = "GdalSource")]
26
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
27
#[serde(rename_all = "camelCase")]
28
#[schema(
29
    title = "GDAL Source",
30
    examples(json!({
31
        "type": "GdalSource",
32
        "params": {
33
            "data": "ndvi",
34
            "overviewLevel": null
35
        }
36
    }))
37
)]
38
pub struct GdalSource {
39
    pub params: GdalSourceParameters,
40
}
41

42
/// Parameters for the [`GdalSource`] operator.
43
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
44
#[serde(rename_all = "camelCase")]
45
pub struct GdalSourceParameters {
46
    /// Dataset name or identifier to be loaded.
47
    #[schema(examples("ndvi"))]
48
    pub data: String,
49

50
    /// *Optional*: overview level to use.
51
    ///
52
    /// If not provided, the data source will determine the resolution, i.e., uses its native resolution.
53
    #[schema(examples(3))]
54
    pub overview_level: Option<u32>,
55
}
56

57
impl TryFrom<GdalSource> for OperatorsGdalSource {
58
    type Error = anyhow::Error;
59
    fn try_from(value: GdalSource) -> Result<Self, Self::Error> {
26✔
60
        Ok(OperatorsGdalSource {
61
            params: OperatorsGdalSourceParameters {
62
                data: serde_json::from_str::<NamedData>(&serde_json::to_string(
26✔
63
                    &value.params.data,
26✔
NEW
64
                )?)?,
×
65
                overview_level: value.params.overview_level,
26✔
66
            },
67
        })
68
    }
26✔
69
}
70

71
/// The [`MockPointSource`] is a source operator that provides mock vector point data for testing and development purposes.
72
///
73
#[type_tag(value = "MockPointSource")]
74
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
75
#[serde(rename_all = "camelCase")]
76
#[schema(
77
    title = "Mock Point Source",
78
    examples(json!({
79
        "type": "MockPointSource",
80
        "params": {
81
            "points": [ { "x": 1.0, "y": 2.0 }, { "x": 3.0, "y": 4.0 } ],
82
            "spatialBounds": { "type": "derive" }
83
        }
84
    }))
85
)]
86
pub struct MockPointSource {
87
    pub params: MockPointSourceParameters,
88
}
89

90
/// Parameters for the [`MockPointSource`] operator.
91
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
92
#[serde(rename_all = "camelCase")]
93
pub struct MockPointSourceParameters {
94
    /// Points to be output by the mock point source.
95
    ///
96
    #[schema(examples(json!([
97
        { "x": 1.0, "y": 2.0 },
98
        { "x": 3.0, "y": 4.0 }
99
    ])))]
100
    pub points: Vec<Coordinate2D>,
101

102
    /// Defines how the spatial bounds of the source are derived.
103
    ///
104
    /// Defaults to `None`.
105
    #[schema(examples(json!({ "type": "derive" })))]
106
    pub spatial_bounds: SpatialBoundsDerive,
107
}
108

109
impl TryFrom<MockPointSource> for OperatorsMockPointSource {
110
    type Error = anyhow::Error;
111
    fn try_from(value: MockPointSource) -> Result<Self, Self::Error> {
5✔
112
        Ok(OperatorsMockPointSource {
113
            params: OperatorsMockPointSourceParameters {
114
                points: value.params.points.into_iter().map(Into::into).collect(),
5✔
115
                spatial_bounds: value.params.spatial_bounds.try_into()?,
5✔
116
            },
117
        })
118
    }
5✔
119
}
120

121
#[cfg(test)]
122
mod tests {
123
    use super::*;
124
    use crate::api::model::processing_graphs::{RasterOperator, TypedOperator, VectorOperator};
125
    use geoengine_operators::engine::TypedOperator as OperatorsTypedOperator;
126

127
    #[test]
128
    fn it_converts_into_gdal_source() {
1✔
129
        let api_operator = GdalSource {
1✔
130
            r#type: Default::default(),
1✔
131
            params: GdalSourceParameters {
1✔
132
                data: "example_dataset".to_string(),
1✔
133
                overview_level: None,
1✔
134
            },
1✔
135
        };
1✔
136

137
        let operators_operator: OperatorsGdalSource =
1✔
138
            api_operator.try_into().expect("it should convert");
1✔
139

140
        assert_eq!(
1✔
141
            operators_operator.params.data,
142
            NamedData::with_system_name("example_dataset")
1✔
143
        );
144

145
        let typed_operator = TypedOperator::Raster(RasterOperator::GdalSource(GdalSource {
1✔
146
            r#type: Default::default(),
1✔
147
            params: GdalSourceParameters {
1✔
148
                data: "example_dataset".to_string(),
1✔
149
                overview_level: None,
1✔
150
            },
1✔
151
        }));
1✔
152

153
        OperatorsTypedOperator::try_from(typed_operator).expect("it should convert");
1✔
154
    }
1✔
155

156
    #[test]
157
    fn it_converts_mock_point_source() {
1✔
158
        let api_operator = MockPointSource {
1✔
159
            r#type: Default::default(),
1✔
160
            params: MockPointSourceParameters {
1✔
161
                points: vec![
1✔
162
                    Coordinate2D { x: 1.0, y: 2.0 },
1✔
163
                    Coordinate2D { x: 3.0, y: 4.0 },
1✔
164
                ],
1✔
165
                spatial_bounds: SpatialBoundsDerive::Derive(Default::default()),
1✔
166
            },
1✔
167
        };
1✔
168

169
        let operators_operator: OperatorsMockPointSource =
1✔
170
            api_operator.try_into().expect("it should convert");
1✔
171

172
        assert_eq!(
1✔
173
            operators_operator.params.points,
174
            vec![
1✔
175
                geoengine_datatypes::primitives::Coordinate2D { x: 1.0, y: 2.0 },
1✔
176
                geoengine_datatypes::primitives::Coordinate2D { x: 3.0, y: 4.0 }
1✔
177
            ]
178
        );
179

180
        let typed_operator =
1✔
181
            TypedOperator::Vector(VectorOperator::MockPointSource(MockPointSource {
1✔
182
                r#type: Default::default(),
1✔
183
                params: MockPointSourceParameters {
1✔
184
                    points: vec![Coordinate2D { x: 1.0, y: 2.0 }],
1✔
185
                    spatial_bounds: SpatialBoundsDerive::Derive(Default::default()),
1✔
186
                },
1✔
187
            }));
1✔
188

189
        OperatorsTypedOperator::try_from(typed_operator).expect("it should convert");
1✔
190
    }
1✔
191
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc