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 && filter_envelope.contains_envelope_partially(&g.envelope())
45 {
46 return true;
47 }
48 if let Some(g) = &thematic_surface.lod1_multi_surface
49 && filter_envelope.contains_envelope_partially(&g.envelope())
50 {
51 return true;
52 }
53 if let Some(g) = &thematic_surface.lod2_multi_surface
54 && filter_envelope.contains_envelope_partially(&g.envelope())
55 {
56 return true;
57 }
58 if let Some(g) = &thematic_surface.lod3_multi_surface
59 && filter_envelope.contains_envelope_partially(&g.envelope())
60 {
61 return true;
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 && filter_envelope.contains(&g.reference_point)
70 {
71 return true;
72 }
73 if let Some(g) = &occupied_space.lod2_implicit_representation
74 && filter_envelope.contains(&g.reference_point)
75 {
76 return true;
77 }
78 if let Some(g) = &occupied_space.lod3_implicit_representation
79 && filter_envelope.contains(&g.reference_point)
80 {
81 return true;
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 && filter_envelope.contains_envelope_partially(&g.envelope())
90 {
91 return true;
92 }
93 if let Some(g) = &space.lod2_solid
94 && filter_envelope.contains_envelope_partially(&g.envelope())
95 {
96 return true;
97 }
98 if let Some(g) = &space.lod3_solid
99 && filter_envelope.contains_envelope_partially(&g.envelope())
100 {
101 return true;
102 }
103
104 if let Some(g) = &space.lod0_multi_surface
105 && filter_envelope.contains_envelope_partially(&g.envelope())
106 {
107 return true;
108 }
109 if let Some(g) = &space.lod2_multi_surface
110 && filter_envelope.contains_envelope_partially(&g.envelope())
111 {
112 return true;
113 }
114 if let Some(g) = &space.lod3_multi_surface
115 && filter_envelope.contains_envelope_partially(&g.envelope())
116 {
117 return true;
118 }
119
120 false
121}