ecitygml_transform/
filter.rs

1use crate::error::Error;
2use ecitygml_core::model::city_model::CitygmlModel;
3use ecitygml_core::model::core::{OccupiedSpace, Space, ThematicSurface};
4use egml::model::geometry::Envelope;
5use egml::operations::geometry::Geometry;
6
7pub fn filter_by_bounding_box(
8    mut city_model: CitygmlModel,
9    filter_envelope: &Envelope,
10) -> Result<CitygmlModel, Error> {
11    city_model.building.retain(|f| {
12        f.wall_surface
13            .iter()
14            .any(|w| contains_thematic_surface(filter_envelope, &w.thematic_surface))
15            || f.roof_surface
16                .iter()
17                .any(|w| contains_thematic_surface(filter_envelope, &w.thematic_surface))
18            || f.ground_surface
19                .iter()
20                .any(|w| contains_thematic_surface(filter_envelope, &w.thematic_surface))
21            || f.building_constructive_element
22                .iter()
23                .any(|w| contains_occupied_space(filter_envelope, &w.occupied_space))
24    });
25
26    // TODO road
27
28    city_model
29        .city_furniture
30        .retain(|f| contains_occupied_space(filter_envelope, &f.occupied_space));
31
32    city_model
33        .solitary_vegetation_object
34        .retain(|f| contains_occupied_space(filter_envelope, &f.occupied_space));
35
36    Ok(city_model)
37}
38
39fn contains_thematic_surface(
40    filter_envelope: &Envelope,
41    thematic_surface: &ThematicSurface,
42) -> bool {
43    if let Some(g) = &thematic_surface.lod0_multi_surface {
44        if filter_envelope.contains_envelope_partially(&g.envelope()) {
45            return true;
46        }
47    }
48    if let Some(g) = &thematic_surface.lod1_multi_surface {
49        if filter_envelope.contains_envelope_partially(&g.envelope()) {
50            return true;
51        }
52    }
53    if let Some(g) = &thematic_surface.lod2_multi_surface {
54        if filter_envelope.contains_envelope_partially(&g.envelope()) {
55            return true;
56        }
57    }
58    if let Some(g) = &thematic_surface.lod3_multi_surface {
59        if filter_envelope.contains_envelope_partially(&g.envelope()) {
60            return true;
61        }
62    }
63
64    false
65}
66
67fn contains_occupied_space(filter_envelope: &Envelope, occupied_space: &OccupiedSpace) -> bool {
68    if let Some(g) = &occupied_space.lod1_implicit_representation {
69        if filter_envelope.contains(&g.reference_point) {
70            return true;
71        }
72    }
73    if let Some(g) = &occupied_space.lod2_implicit_representation {
74        if filter_envelope.contains(&g.reference_point) {
75            return true;
76        }
77    }
78    if let Some(g) = &occupied_space.lod3_implicit_representation {
79        if filter_envelope.contains(&g.reference_point) {
80            return true;
81        }
82    }
83
84    contains_space(filter_envelope, &occupied_space.space)
85}
86
87fn contains_space(filter_envelope: &Envelope, space: &Space) -> bool {
88    if let Some(g) = &space.lod1_solid {
89        if filter_envelope.contains_envelope_partially(&g.envelope()) {
90            return true;
91        }
92    }
93    if let Some(g) = &space.lod2_solid {
94        if filter_envelope.contains_envelope_partially(&g.envelope()) {
95            return true;
96        }
97    }
98    if let Some(g) = &space.lod3_solid {
99        if filter_envelope.contains_envelope_partially(&g.envelope()) {
100            return true;
101        }
102    }
103
104    if let Some(g) = &space.lod0_multi_surface {
105        if filter_envelope.contains_envelope_partially(&g.envelope()) {
106            return true;
107        }
108    }
109    if let Some(g) = &space.lod2_multi_surface {
110        if filter_envelope.contains_envelope_partially(&g.envelope()) {
111            return true;
112        }
113    }
114    if let Some(g) = &space.lod3_multi_surface {
115        if filter_envelope.contains_envelope_partially(&g.envelope()) {
116            return true;
117        }
118    }
119
120    false
121}