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

geo-engine / geoengine / 21713539443

05 Feb 2026 01:34PM UTC coverage: 88.328%. First build
21713539443

Pull #1116

github

web-flow
Merge 4bd6c476d into 078c12706
Pull Request #1116: feat: Operators in OpenAPI

270 of 385 new or added lines in 4 files covered. (70.13%)

116140 of 131487 relevant lines covered (88.33%)

493767.19 hits per line

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

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

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

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

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

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

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

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

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

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

119
#[cfg(test)]
120
mod tests {
121
    use super::*;
122
    use crate::processes::{RasterOperator, TypedOperator, VectorOperator};
123
    use geoengine_operators::engine::TypedOperator as OperatorsTypedOperator;
124

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

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

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

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

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

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

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

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

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

187
        OperatorsTypedOperator::try_from(typed_operator).expect("it should convert");
1✔
188
    }
1✔
189
}
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