ifc_georef/crs/
projected.rs1use ifc_model::{EntityId, Model};
4
5use crate::crs::unit::{resolve_length_unit, LengthUnit};
6use crate::error::{GeorefError, GeorefResult};
7
8#[derive(Debug, Clone, PartialEq)]
10pub struct ProjectedCrs {
11 pub entity: EntityId,
13 pub name: String,
16 pub description: Option<String>,
18 pub geodetic_datum: Option<String>,
20 pub vertical_datum: Option<String>,
22 pub map_projection: Option<String>,
24 pub map_zone: Option<String>,
26 pub map_unit: Option<LengthUnit>,
28}
29
30pub(crate) fn projected_crs(model: &Model, id: EntityId) -> GeorefResult<ProjectedCrs> {
31 let entity = model.get(id).ok_or(GeorefError::MissingEntity {
32 referrer: id,
33 missing: id,
34 })?;
35 if !entity.is_type("IFCPROJECTEDCRS") {
36 return Err(GeorefError::WrongType {
37 entity: id,
38 expected: "IFCPROJECTEDCRS",
39 actual: entity.type_name.to_string(),
40 });
41 }
42 let name = entity
45 .text(0)
46 .ok_or(GeorefError::MissingAttribute {
47 entity: id,
48 index: 0,
49 name: "Name",
50 })?
51 .to_owned();
52 let map_unit = match entity.attribute(6) {
53 None | Some(ifc_model::value::Value::Null) => None,
54 Some(value) => {
55 let unit = value.as_ref_id().ok_or(GeorefError::InvalidAttribute {
56 entity: id,
57 index: 6,
58 name: "MapUnit",
59 })?;
60 Some(resolve_length_unit(model, unit)?)
61 }
62 };
63 Ok(ProjectedCrs {
64 entity: id,
65 name,
66 description: entity.text(1).map(str::to_owned),
67 geodetic_datum: entity.text(2).map(str::to_owned),
68 vertical_datum: entity.text(3).map(str::to_owned),
69 map_projection: entity.text(4).map(str::to_owned),
70 map_zone: entity.text(5).map(str::to_owned),
71 map_unit,
72 })
73}