1use crate::error::Error;
2use crate::gml::read_impl::decode;
3use std::fs::File;
4use std::io::{BufReader, Read};
5
6use crate::error::Error::InvalidFileExtension;
7use crate::format::CitygmlFormat;
8use crate::gml::validate_impl::validate_from_reader;
9use ecitygml_core::model::core::CityModel;
10use std::path::Path;
11
12#[derive(Debug, Clone)]
15pub struct GmlReader<R: Read> {
16 reader: R,
17 format: CitygmlFormat,
18 rebuild_object_bounds: bool,
19}
20
21impl<R: Read> GmlReader<R> {
22 pub fn new(reader: R, format: CitygmlFormat) -> Self {
24 Self {
25 reader,
26 format,
27 rebuild_object_bounds: true,
28 }
29 }
30
31 fn read(self) -> Result<Vec<u8>, Error> {
32 let mut content = Vec::new();
33
34 match self.format {
35 CitygmlFormat::Gml => {
36 BufReader::new(self.reader).read_to_end(&mut content)?;
37 }
38 CitygmlFormat::GmlZst => {
39 zstd::Decoder::new(BufReader::new(self.reader))?.read_to_end(&mut content)?;
40 }
41 CitygmlFormat::GmlGz => {
42 flate2::read::GzDecoder::new(BufReader::new(self.reader))
43 .read_to_end(&mut content)?;
44 }
45 }
46
47 Ok(content)
48 }
49
50 pub fn validate(self) -> Result<crate::gml::validate::report::Report, Error> {
51 validate_from_reader(self.read()?)
52 }
53
54 pub fn with_rebuild_object_bounds(mut self, rebuild_object_bounds: bool) -> Self {
55 self.rebuild_object_bounds = rebuild_object_bounds;
56 self
57 }
58
59 pub fn finish(self) -> Result<CityModel, Error> {
60 let rebuild_object_bounds = self.rebuild_object_bounds;
61 let mut city_model = decode(self.read()?)?;
62
63 if rebuild_object_bounds {
64 city_model.refresh_bounded_by_recursive();
65 }
66
67 Ok(city_model)
68 }
69}
70
71impl GmlReader<File> {
72 pub fn from_path(path: impl AsRef<Path>) -> Result<Self, Error> {
73 let format = CitygmlFormat::from_path(path.as_ref()).ok_or_else(|| {
74 InvalidFileExtension(
75 path.as_ref()
76 .extension()
77 .and_then(|ext| ext.to_str())
78 .unwrap_or_default()
79 .to_string(),
80 )
81 })?;
82
83 let file = std::fs::File::open(path.as_ref())?;
84
85 Ok(Self::new(file, format))
86 }
87}