ecitygml_transform/
filter.rs1use 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 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}