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

geo-engine / geoengine / 30090857570

24 Jul 2026 11:48AM UTC coverage: 87.526% (-0.06%) from 87.585%
30090857570

Pull #1221

github

web-flow
Merge 24b5ed733 into aa2cf832f
Pull Request #1221: feat: add VectorExpression operator to processing graph api

250 of 256 new or added lines in 3 files covered. (97.66%)

146 existing lines in 1 file now uncovered.

123447 of 141041 relevant lines covered (87.53%)

480464.18 hits per line

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

90.74
/geoengine/services/src/api/model/processing_graphs/mod.rs
1
#![allow(clippy::needless_for_each)] // TODO: remove when clippy is fixed for utoipa <https://github.com/juhaku/utoipa/issues/1420>
2

3
// use crate::api::model::processing_graphs::{
4
//     processing::{Expression, ExpressionParameters, RasterVectorJoin, RasterVectorJoinParameters},
5
//     source::{GdalSource, GdalSourceParameters, MockPointSource, MockPointSourceParameters},
6
// };
7
use geoengine_operators::{
8
    engine::{
9
        PlotOperator as OperatorsPlotOperator, RasterOperator as OperatorsRasterOperator,
10
        TypedOperator as OperatorsTypedOperator, VectorOperator as OperatorsVectorOperator,
11
    },
12
    mock::MockPointSource as OperatorsMockPointSource,
13
    plot::{Histogram as OperatorsHistogram, Statistics as OperatorsStatistics},
14
    processing::{
15
        BandFilter as OperatorsBandFilter, Downsampling as OperatorsDownsampling,
16
        Expression as OperatorsExpression, Interpolation as OperatorsInterpolation,
17
        RasterStacker as OperatorsRasterStacker,
18
        RasterTypeConversion as OperatorsRasterTypeConversion,
19
        RasterVectorJoin as OperatorsRasterVectorJoin, Reprojection as OperatorsReprojection,
20
        TemporalRasterAggregation as OperatorsTemporalRasterAggregation,
21
        VectorExpression as OperatorsVectorExpression,
22
    },
23
    source::{
24
        GdalSource as OperatorsGdalSource, MultiBandGdalSource as OperatorsMultiBandGdalSource,
25
        OgrSource as OperatorsOgrSource,
26
    },
27
};
28
use serde::{Deserialize, Serialize};
29
use utoipa::{OpenApi, ToSchema};
30

31
mod macros;
32
mod parameters;
33
mod plots;
34
mod processing;
35
mod source;
36
mod source_parameters;
37

38
// TODO: avoid exporting them to outside of API module
39
#[cfg(test)]
40
pub(crate) use crate::api::model::processing_graphs::parameters::SpatialBoundsDerive;
41
pub(crate) use crate::api::model::processing_graphs::{
42
    plots::{Histogram, HistogramParameters, Statistics, StatisticsParameters},
43
    processing::{
44
        Aggregation, BandFilter, BandFilterParameters, BandsByNameOrIndex,
45
        DeriveOutRasterSpecsSource, Downsampling, DownsamplingMethod, DownsamplingParameters,
46
        DownsamplingResolution, Expression, ExpressionParameters, Interpolation,
47
        InterpolationMethod, InterpolationParameters, InterpolationResolution, RasterStacker,
48
        RasterStackerParameters, RasterTypeConversion, RasterTypeConversionParameters,
49
        RasterVectorJoin, RasterVectorJoinParameters, RenameBands, Reprojection,
50
        ReprojectionParameters, TemporalRasterAggregation, TemporalRasterAggregationParameters,
51
        VectorExpression, VectorExpressionParameters,
52
    },
53
    source::{
54
        GdalSource, GdalSourceParameters, MockPointSource, MockPointSourceParameters,
55
        MultiBandGdalSource, OgrSource, OgrSourceParameters,
56
    },
57
    source_parameters::{
58
        MultipleRasterOrSingleVectorOperator, MultipleRasterOrSingleVectorSource,
59
        MultipleRasterSources, SingleRasterOrVectorOperator, SingleRasterOrVectorSource,
60
        SingleRasterSource, SingleVectorMultipleRasterSources,
61
    },
62
};
63

64
/// Operator outputs are distinguished by their data type.
65
/// There are `raster`, `vector` and `plot` operators.
66
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
67
#[serde(tag = "type", content = "operator")]
68
pub enum TypedOperator {
69
    #[schema(title = "TypedVectorOperator")]
70
    Vector(VectorOperator),
71
    #[schema(title = "TypedRasterOperator")]
72
    Raster(RasterOperator),
73
    #[schema(title = "TypedPlotOperator")]
74
    Plot(PlotOperator),
75
}
76

77
/// An operator that produces raster data.
78
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
79
#[serde(rename_all = "camelCase", untagged)]
80
#[schema(discriminator = "type")]
81
pub enum RasterOperator {
82
    BandFilter(BandFilter),
83
    Downsampling(Downsampling),
84
    Expression(Expression),
85
    GdalSource(GdalSource),
86
    Interpolation(Interpolation),
87
    MultiBandGdalSource(MultiBandGdalSource),
88
    RasterStacker(RasterStacker),
89
    RasterTypeConversion(RasterTypeConversion),
90
    Reprojection(Reprojection),
91
    TemporalRasterAggregation(TemporalRasterAggregation),
92
}
93

94
/// An operator that produces vector data.
95
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
96
#[serde(rename_all = "camelCase", untagged)]
97
#[schema(discriminator = "type")]
98
pub enum VectorOperator {
99
    MockPointSource(MockPointSource),
100
    OgrSource(OgrSource),
101
    RasterVectorJoin(RasterVectorJoin),
102
    Reprojection(Reprojection),
103
    VectorExpression(VectorExpression),
104
}
105

106
/// An operator that produces plot data.
107
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
108
#[serde(rename_all = "camelCase", untagged)]
109
#[schema(discriminator = "type")]
110
pub enum PlotOperator {
111
    Histogram(Histogram),
112
    Statistics(Statistics),
113
}
114

115
impl TryFrom<RasterOperator> for Box<dyn OperatorsRasterOperator> {
116
    type Error = anyhow::Error;
117
    fn try_from(operator: RasterOperator) -> Result<Self, Self::Error> {
127✔
118
        // TODO: Missing raster operator mappings (operators crate -> OpenAPI model):
119
        // [ ] BandNeighborhoodAggregate
120
        // [ ] BandwiseExpression
121
        // [ ] NeighborhoodAggregate
122
        // [ ] Onnx
123
        // [ ] RasterScaling
124
        // [ ] Rasterization
125
        // [ ] Reflectance
126
        // [ ] Radiance
127
        // [ ] Temperature
128
        // [ ] TimeShift
129
        match operator {
127✔
130
            RasterOperator::BandFilter(band_filter) => {
2✔
131
                OperatorsBandFilter::try_from(band_filter).map(OperatorsRasterOperator::boxed)
2✔
132
            }
133
            RasterOperator::Downsampling(downsampling) => {
×
134
                OperatorsDownsampling::try_from(downsampling).map(OperatorsRasterOperator::boxed)
×
135
            }
136
            RasterOperator::Expression(expression) => {
1✔
137
                OperatorsExpression::try_from(expression).map(OperatorsRasterOperator::boxed)
1✔
138
            }
139
            RasterOperator::GdalSource(gdal_source) => {
93✔
140
                OperatorsGdalSource::try_from(gdal_source).map(OperatorsRasterOperator::boxed)
93✔
141
            }
142
            RasterOperator::Interpolation(interpolation) => {
3✔
143
                OperatorsInterpolation::try_from(interpolation).map(OperatorsRasterOperator::boxed)
3✔
144
            }
145
            RasterOperator::MultiBandGdalSource(gdal_source) => {
7✔
146
                OperatorsMultiBandGdalSource::try_from(gdal_source)
7✔
147
                    .map(OperatorsRasterOperator::boxed)
7✔
148
            }
149
            RasterOperator::RasterStacker(raster_stacker) => {
5✔
150
                OperatorsRasterStacker::try_from(raster_stacker).map(OperatorsRasterOperator::boxed)
5✔
151
            }
152
            RasterOperator::RasterTypeConversion(type_conversion) => {
1✔
153
                OperatorsRasterTypeConversion::try_from(type_conversion)
1✔
154
                    .map(OperatorsRasterOperator::boxed)
1✔
155
            }
156
            RasterOperator::Reprojection(reprojection) => {
14✔
157
                OperatorsReprojection::try_from(reprojection).map(OperatorsRasterOperator::boxed)
14✔
158
            }
159
            RasterOperator::TemporalRasterAggregation(aggregation) => {
1✔
160
                OperatorsTemporalRasterAggregation::try_from(aggregation)
1✔
161
                    .map(OperatorsRasterOperator::boxed)
1✔
162
            }
163
        }
164
    }
127✔
165
}
166

167
impl TryFrom<VectorOperator> for Box<dyn OperatorsVectorOperator> {
168
    type Error = anyhow::Error;
169
    fn try_from(operator: VectorOperator) -> Result<Self, Self::Error> {
20✔
170
        // TODO: Missing vector operator mappings (operators crate -> OpenAPI model):
171
        // [ ] ColumnRangeFilter
172
        // [ ] CsvSource
173
        // [ ] LineSimplification
174
        // [ ] MockDatasetDataSource
175
        // [ ] PointInPolygonFilter
176
        // [ ] TimeProjection
177
        // [ ] TimeShift
178
        // [ ] VectorJoin
179
        // [ ] VisualPointClustering
180
        match operator {
20✔
181
            VectorOperator::MockPointSource(mock_point_source) => {
12✔
182
                OperatorsMockPointSource::try_from(mock_point_source)
12✔
183
                    .map(OperatorsVectorOperator::boxed)
12✔
184
            }
185
            VectorOperator::OgrSource(ogr_source) => {
6✔
186
                OperatorsOgrSource::try_from(ogr_source).map(OperatorsVectorOperator::boxed)
6✔
187
            }
188
            VectorOperator::RasterVectorJoin(rvj) => {
1✔
189
                OperatorsRasterVectorJoin::try_from(rvj).map(OperatorsVectorOperator::boxed)
1✔
190
            }
191
            VectorOperator::Reprojection(reprojection) => {
1✔
192
                OperatorsReprojection::try_from(reprojection).map(OperatorsVectorOperator::boxed)
1✔
193
            }
NEW
194
            VectorOperator::VectorExpression(vector_expression) => {
×
NEW
195
                OperatorsVectorExpression::try_from(vector_expression)
×
NEW
196
                    .map(OperatorsVectorOperator::boxed)
×
197
            }
198
        }
199
    }
20✔
200
}
201

202
impl TryFrom<PlotOperator> for Box<dyn OperatorsPlotOperator> {
203
    type Error = anyhow::Error;
204
    fn try_from(operator: PlotOperator) -> Result<Self, Self::Error> {
4✔
205
        // TODO: Missing plot operator mappings (operators crate -> OpenAPI model):
206
        // [ ] BoxPlot
207
        // [ ] ClassHistogram
208
        // [ ] FeatureAttributeValuesOverTime
209
        // [ ] MeanRasterPixelValuesOverTime
210
        // [ ] PieChart
211
        // [ ] ScatterPlot
212
        match operator {
4✔
213
            PlotOperator::Histogram(histogram) => {
1✔
214
                OperatorsHistogram::try_from(histogram).map(OperatorsPlotOperator::boxed)
1✔
215
            }
216
            PlotOperator::Statistics(statistics) => {
3✔
217
                OperatorsStatistics::try_from(statistics).map(OperatorsPlotOperator::boxed)
3✔
218
            }
219
        }
220
    }
4✔
221
}
222

223
impl TryFrom<TypedOperator> for OperatorsTypedOperator {
224
    type Error = anyhow::Error;
225
    fn try_from(operator: TypedOperator) -> Result<Self, Self::Error> {
83✔
226
        match operator {
83✔
227
            TypedOperator::Raster(raster_operator) => Ok(Self::Raster(raster_operator.try_into()?)),
74✔
228
            TypedOperator::Vector(vector_operator) => Ok(Self::Vector(vector_operator.try_into()?)),
7✔
229
            TypedOperator::Plot(plot_operator) => Ok(Self::Plot(plot_operator.try_into()?)),
2✔
230
        }
231
    }
83✔
232
}
233

234
#[derive(OpenApi)]
235
#[openapi(components(schemas(
236
    // General
237
    PlotOperator,
238
    TypedOperator,
239
    VectorOperator,
240
    // Source
241
    GdalSource,
242
    GdalSourceParameters,
243
    MockPointSource,
244
    MockPointSourceParameters,
245
    MultiBandGdalSource,
246
    OgrSource,
247
    OgrSourceParameters,
248
    // Processing
249
    Aggregation,
250
    BandFilter,
251
    BandFilterParameters,
252
    BandsByNameOrIndex,
253
    DeriveOutRasterSpecsSource,
254
    Downsampling,
255
    DownsamplingMethod,
256
    DownsamplingParameters,
257
    DownsamplingResolution,
258
    Expression,
259
    ExpressionParameters,
260
    Interpolation,
261
    InterpolationMethod,
262
    InterpolationParameters,
263
    InterpolationResolution,
264
    RasterOperator,
265
    RasterStacker,
266
    RasterStackerParameters,
267
    RasterTypeConversion,
268
    RasterTypeConversionParameters,
269
    RasterVectorJoin,
270
    RasterVectorJoinParameters,
271
    RenameBands,
272
    Reprojection,
273
    ReprojectionParameters,
274
    TemporalRasterAggregation,
275
    TemporalRasterAggregationParameters,
276
    VectorExpression,
277
    VectorExpressionParameters,
278
    // Plots
279
    Histogram,
280
    HistogramParameters,
281
    Statistics,
282
    StatisticsParameters,
283
    // Source Parameters
284
    MultipleRasterOrSingleVectorOperator,
285
    MultipleRasterOrSingleVectorSource,
286
    MultipleRasterSources,
287
    SingleRasterOrVectorOperator,
288
    SingleRasterOrVectorSource,
289
    SingleRasterSource,
290
    SingleVectorMultipleRasterSources,
291

292
)))]
293
pub struct OperatorsApi;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc