diff --git a/nusamai-plateau/citygml/macros/src/lib.rs b/nusamai-plateau/citygml/macros/src/lib.rs index d62a2b14d..60dc4485d 100644 --- a/nusamai-plateau/citygml/macros/src/lib.rs +++ b/nusamai-plateau/citygml/macros/src/lib.rs @@ -12,11 +12,25 @@ fn generate_citygml_struct_model( ) -> Result { let mut attribute_arms = Vec::new(); let mut chlid_arms = Vec::new(); + let mut objectify_stmts = Vec::new(); + let mut geom_objectify_expr = quote! { None }; + let mut id_value = quote!(None); for field in &struct_data.fields { let Some(field_ident) = &field.ident else { continue; }; + + if field_ident == "id" { + id_value = quote! { + if let Some(id) = &self.id { + Some(id.as_ref()) + } else { + None + } + }; + }; + let field_ty = &field.ty; for attr in &field.attrs { if !attr.path().is_ident(CITYGML_ATTR_IDENT) { @@ -30,21 +44,37 @@ fn generate_citygml_struct_model( // XML attributes (e.g. @gml:id) attribute_arms.push(quote! { #path => { - self.id = <#field_ty as citygml::CityGMLAttribute>::parse_attr_value( + self.#field_ident = <#field_ty as citygml::CityGMLAttribute>::parse_attr_value( std::str::from_utf8(value).unwrap(), )?; Ok(()) } }); + objectify_stmts.push( + quote! { + if let Some(v) = self.#field_ident.objectify() { + attributes.insert(stringify!(#field_ident).into(), v); + } + } + ) } else { // XML child elements (e.g. bldg:measuredHeight) - chlid_arms.push(quote! { - #path => <#field_ty as CityGMLElement>::parse(&mut self.#field_ident, st), - }); + chlid_arms.push( + quote! { + #path => <#field_ty as CityGMLElement>::parse(&mut self.#field_ident, st), + } + ); + objectify_stmts.push( + quote! { + if let Some(v) = self.#field_ident.objectify() { + attributes.insert(stringify!(#field_ident).into(), v); + } + } + ) } Ok(()) } - else if meta.path.is_ident("auto_geom") { + else if meta.path.is_ident("geom") { let prefix: LitByteStr = meta.value()?.parse()?; let mut add_arm = |lod: u8, name: &[u8], geomtype: &str | { @@ -70,6 +100,10 @@ fn generate_citygml_struct_model( add_arm(4, b"lod4Geometry", "Geometry"); add_arm(1, b"tin", "Triangulated"); + geom_objectify_expr = quote! { + Some(&self.#field_ident) + }; + Ok(()) } else { Err(meta.error("unrecognized attribute")) @@ -102,6 +136,20 @@ fn generate_citygml_struct_model( } }) } + + fn objectify(&self) -> Option<::citygml::object::ObjectValue> { + let attributes = { + let mut attributes = ::std::collections::HashMap::new(); + #(#objectify_stmts)* + attributes + }; + Some(::citygml::ObjectValue::FeatureOrData { + typename: stringify!(#struct_name).into(), + id: #id_value, + attributes, + geometries: #geom_objectify_expr, + }) + } } }) } @@ -111,6 +159,8 @@ fn generate_citygml_enum_model( enum_data: &DataEnum, ) -> Result { let mut child_arms = Vec::new(); + let mut objectify_arms = Vec::new(); + for variant in &enum_data.variants { if variant.fields.len() > 1 { return Err(Error::new_spanned( @@ -134,15 +184,17 @@ fn generate_citygml_enum_model( let value = meta.value()?; let path: LitByteStr = value.parse()?; - let arm = quote! { + child_arms.push(quote! { #path => { let mut v: #field_ty = Default::default(); <#field_ty as CityGMLElement>::parse(&mut v, st)?; *self = Self::#variant_ident(v); Ok(()) } - }; - child_arms.push(arm); + }); + objectify_arms.push(quote! { + Self::#variant_ident(v) => v.objectify() + }); } Ok(()) })?; @@ -162,6 +214,13 @@ fn generate_citygml_enum_model( } }) } + + fn objectify(&self) -> Option<::citygml::object::ObjectValue> { + match self { + #(#objectify_arms,)* + _ => None, + } + } } }; diff --git a/nusamai-plateau/citygml/src/lib.rs b/nusamai-plateau/citygml/src/lib.rs index 2d5e144b1..2f6142886 100644 --- a/nusamai-plateau/citygml/src/lib.rs +++ b/nusamai-plateau/citygml/src/lib.rs @@ -1,11 +1,13 @@ pub mod geometric; pub mod model; pub mod namespace; +pub mod object; pub mod parser; pub use geometric::*; pub use model::*; pub use namespace::*; +pub use object::*; pub use parser::*; pub use macros::CityGMLElement; diff --git a/nusamai-plateau/citygml/src/model.rs b/nusamai-plateau/citygml/src/model.rs index 8c1d0e4a0..3e5b259c1 100644 --- a/nusamai-plateau/citygml/src/model.rs +++ b/nusamai-plateau/citygml/src/model.rs @@ -1,8 +1,11 @@ +use crate::object::ObjectValue; use crate::parser::{ParseError, SubTreeReader}; use std::io::BufRead; pub trait CityGMLElement: Sized { fn parse(&mut self, st: &mut SubTreeReader) -> Result<(), ParseError>; + + fn objectify(&self) -> Option; } impl CityGMLElement for String { @@ -11,9 +14,13 @@ impl CityGMLElement for String { self.push_str(st.parse_text()?); Ok(()) } + + fn objectify(&self) -> Option { + Some(ObjectValue::String(self.as_ref())) + } } -impl CityGMLElement for i32 { +impl CityGMLElement for i64 { #[inline] fn parse(&mut self, st: &mut SubTreeReader) -> Result<(), ParseError> { let text = st.parse_text()?; @@ -28,6 +35,31 @@ impl CityGMLElement for i32 { ))), } } + + fn objectify(&self) -> Option { + Some(ObjectValue::Integer(*self)) + } +} + +impl CityGMLElement for i8 { + #[inline] + fn parse(&mut self, st: &mut SubTreeReader) -> Result<(), ParseError> { + let text = st.parse_text()?; + match text.parse() { + Ok(v) => { + *self = v; + Ok(()) + } + Err(_) => Err(ParseError::InvalidValue(format!( + "Expected an integer, got {}", + text + ))), + } + } + + fn objectify(&self) -> Option { + Some(ObjectValue::Integer(*self as i64)) + } } impl CityGMLElement for f64 { @@ -45,6 +77,10 @@ impl CityGMLElement for f64 { ))), } } + + fn objectify(&self) -> Option { + Some(ObjectValue::Double(*self)) + } } impl CityGMLElement for Option { @@ -61,6 +97,13 @@ impl CityGMLElement for Option *self = Some(v); Ok(()) } + + fn objectify(&self) -> Option { + match self { + Some(v) => v.objectify(), + None => None, + } + } } impl CityGMLElement for Vec { @@ -71,6 +114,16 @@ impl CityGMLElement for Vec { self.push(v); Ok(()) } + + fn objectify(&self) -> Option { + if self.is_empty() { + None + } else { + Some(ObjectValue::Array( + self.iter().filter_map(|v| v.objectify()).collect(), + )) + } + } } pub trait CityGMLAttribute: Sized { diff --git a/nusamai-plateau/citygml/src/object.rs b/nusamai-plateau/citygml/src/object.rs new file mode 100644 index 000000000..6dd7fe3b4 --- /dev/null +++ b/nusamai-plateau/citygml/src/object.rs @@ -0,0 +1,25 @@ +//! Objectify CityGML features and their thematic/geometric attributes + +use crate::geometric::GeometryRef; +use std::collections::HashMap; + +#[derive(Debug)] +pub enum ObjectValue<'a> { + Unknown, + Null, + String(&'a str), + // Code(&'a Code), + Integer(i64), + Double(f64), + Measure(f64), + Bool(bool), + URI(&'a str), + // Date(Date), + Array(Vec>), + FeatureOrData { + typename: &'a str, + id: Option<&'a str>, + attributes: HashMap>, + geometries: Option<&'a GeometryRef>, + }, +} diff --git a/nusamai-plateau/examples/parse.rs b/nusamai-plateau/examples/parse.rs index a15dec949..6276d25bb 100644 --- a/nusamai-plateau/examples/parse.rs +++ b/nusamai-plateau/examples/parse.rs @@ -25,6 +25,7 @@ fn example_toplevel_dispatcher( let mut cityobj: CityObject = Default::default(); cityobj.parse(st)?; let geometries = st.collect_geometries(); + println!("{:?}", cityobj.objectify()); TopLevelCityObject { cityobj, diff --git a/nusamai-plateau/src/models/bridge.rs b/nusamai-plateau/src/models/bridge.rs index f581cdd3d..3ac5f629e 100644 --- a/nusamai-plateau/src/models/bridge.rs +++ b/nusamai-plateau/src/models/bridge.rs @@ -3,7 +3,7 @@ use citygml::{CityGMLElement, GeometryRef}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct Bridge { - #[citygml(auto_geom = b"brid")] + #[citygml(geom = b"brid")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] diff --git a/nusamai-plateau/src/models/building.rs b/nusamai-plateau/src/models/building.rs index f46a7673f..dd8e64cb9 100644 --- a/nusamai-plateau/src/models/building.rs +++ b/nusamai-plateau/src/models/building.rs @@ -3,7 +3,7 @@ use citygml::{CityGMLElement, GeometryRef}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct Building { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -46,7 +46,7 @@ pub struct Building { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct BuildingPart { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -112,7 +112,7 @@ pub enum BoundingSurface { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct WallSurface { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -125,7 +125,7 @@ pub struct WallSurface { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct RoofSurface { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -138,7 +138,7 @@ pub struct RoofSurface { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct GroundSurface { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -151,7 +151,7 @@ pub struct GroundSurface { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct OuterCeilingSurface { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -164,7 +164,7 @@ pub struct OuterCeilingSurface { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct OuterFloorSurface { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -177,7 +177,7 @@ pub struct OuterFloorSurface { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct ClosureSurface { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -190,7 +190,7 @@ pub struct ClosureSurface { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct CeilingSurface { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -202,7 +202,7 @@ pub struct CeilingSurface { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct FloorSurface { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -214,7 +214,7 @@ pub struct FloorSurface { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct InteriorWallSurface { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -242,7 +242,7 @@ pub enum Opening { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct Window { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -252,7 +252,7 @@ pub struct Window { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct Door { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -262,7 +262,7 @@ pub struct Door { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct Room { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -281,7 +281,7 @@ pub struct Room { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct BuildingInstallation { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -294,7 +294,7 @@ pub struct BuildingInstallation { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct BuildingFurniture { - #[citygml(auto_geom = b"bldg")] + #[citygml(geom = b"bldg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] diff --git a/nusamai-plateau/src/models/cityfurniture.rs b/nusamai-plateau/src/models/cityfurniture.rs index e19e87616..08e4db148 100644 --- a/nusamai-plateau/src/models/cityfurniture.rs +++ b/nusamai-plateau/src/models/cityfurniture.rs @@ -3,7 +3,7 @@ use citygml::{CityGMLElement, GeometryRef}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct CityFurniture { - #[citygml(auto_geom = b"frn")] + #[citygml(geom = b"frn")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] diff --git a/nusamai-plateau/src/models/generics.rs b/nusamai-plateau/src/models/generics.rs index 992db1693..11d3de000 100644 --- a/nusamai-plateau/src/models/generics.rs +++ b/nusamai-plateau/src/models/generics.rs @@ -3,7 +3,7 @@ use citygml::{CityGMLElement, GeometryRef}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct GenericCityObject { - #[citygml(auto_geom = b"gen")] + #[citygml(geom = b"gen")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] diff --git a/nusamai-plateau/src/models/iur/landslide.rs b/nusamai-plateau/src/models/iur/landslide.rs index ecba841a3..ad221b674 100644 --- a/nusamai-plateau/src/models/iur/landslide.rs +++ b/nusamai-plateau/src/models/iur/landslide.rs @@ -3,7 +3,7 @@ use citygml::{CityGMLElement, GeometryRef}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct SedimentDisasterProneArea { - #[citygml(auto_geom = b"urf")] + #[citygml(geom = b"urf")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] diff --git a/nusamai-plateau/src/models/iur/underground_building.rs b/nusamai-plateau/src/models/iur/underground_building.rs index 33f533b14..cfd14a2ad 100644 --- a/nusamai-plateau/src/models/iur/underground_building.rs +++ b/nusamai-plateau/src/models/iur/underground_building.rs @@ -3,7 +3,7 @@ use citygml::{CityGMLElement, GeometryRef}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct UndergroundBuilding { - #[citygml(auto_geom = b"uro")] + #[citygml(geom = b"uro")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] diff --git a/nusamai-plateau/src/models/landuse.rs b/nusamai-plateau/src/models/landuse.rs index 62df3808c..14c6f59a1 100644 --- a/nusamai-plateau/src/models/landuse.rs +++ b/nusamai-plateau/src/models/landuse.rs @@ -3,7 +3,7 @@ use citygml::{CityGMLElement, GeometryRef}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct LandUse { - #[citygml(auto_geom = b"luse")] + #[citygml(geom = b"luse")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] diff --git a/nusamai-plateau/src/models/other_construction.rs b/nusamai-plateau/src/models/other_construction.rs index eee51e270..ea75979b6 100644 --- a/nusamai-plateau/src/models/other_construction.rs +++ b/nusamai-plateau/src/models/other_construction.rs @@ -6,7 +6,7 @@ use citygml::{CityGMLElement, GeometryRef}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct OtherConstruction { - #[citygml(auto_geom = b"uro")] + #[citygml(geom = b"uro")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] diff --git a/nusamai-plateau/src/models/relief.rs b/nusamai-plateau/src/models/relief.rs index 16744920b..76ec21ea1 100644 --- a/nusamai-plateau/src/models/relief.rs +++ b/nusamai-plateau/src/models/relief.rs @@ -10,7 +10,7 @@ pub struct ReliefFeature { name: Option, #[citygml(path = b"dem:lod")] - lod: Option, + lod: Option, #[citygml(path = b"dem:reliefComponent")] relief_component: Vec, @@ -44,7 +44,7 @@ pub struct TINRelief { #[citygml(path = b"gml:name")] name: Option, - #[citygml(auto_geom = b"dem")] + #[citygml(geom = b"dem")] geometries: GeometryRef, } diff --git a/nusamai-plateau/src/models/transportation.rs b/nusamai-plateau/src/models/transportation.rs index fa467eb90..b5c64b501 100644 --- a/nusamai-plateau/src/models/transportation.rs +++ b/nusamai-plateau/src/models/transportation.rs @@ -3,7 +3,7 @@ use citygml::{CityGMLElement, GeometryRef}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct Road { - #[citygml(auto_geom = b"tran")] + #[citygml(geom = b"tran")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -19,7 +19,7 @@ pub struct Road { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct Railway { - #[citygml(auto_geom = b"tran")] + #[citygml(geom = b"tran")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -35,7 +35,7 @@ pub struct Railway { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct Track { - #[citygml(auto_geom = b"tran")] + #[citygml(geom = b"tran")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -51,7 +51,7 @@ pub struct Track { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct Square { - #[citygml(auto_geom = b"tran")] + #[citygml(geom = b"tran")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -69,7 +69,7 @@ pub struct Square { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct Waterway { - #[citygml(auto_geom = b"tran")] + #[citygml(geom = b"tran")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -85,7 +85,7 @@ pub struct Waterway { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct TrafficArea { - #[citygml(auto_geom = b"tran")] + #[citygml(geom = b"tran")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -95,7 +95,7 @@ pub struct TrafficArea { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct AuxiliaryTrafficArea { - #[citygml(auto_geom = b"tran")] + #[citygml(geom = b"tran")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] diff --git a/nusamai-plateau/src/models/tunnel.rs b/nusamai-plateau/src/models/tunnel.rs index 79028b40b..3046d8098 100644 --- a/nusamai-plateau/src/models/tunnel.rs +++ b/nusamai-plateau/src/models/tunnel.rs @@ -3,7 +3,7 @@ use citygml::{CityGMLElement, GeometryRef}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct Tunnel { - #[citygml(auto_geom = b"tun")] + #[citygml(geom = b"tun")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] diff --git a/nusamai-plateau/src/models/vegetation.rs b/nusamai-plateau/src/models/vegetation.rs index 61366d019..491f6844b 100644 --- a/nusamai-plateau/src/models/vegetation.rs +++ b/nusamai-plateau/src/models/vegetation.rs @@ -3,7 +3,7 @@ use citygml::{CityGMLElement, GeometryRef}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct SolitaryVegetationObject { - #[citygml(auto_geom = b"veg")] + #[citygml(geom = b"veg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] @@ -16,7 +16,7 @@ pub struct SolitaryVegetationObject { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct PlantCover { - #[citygml(auto_geom = b"veg")] + #[citygml(geom = b"veg")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")] diff --git a/nusamai-plateau/src/models/waterbody.rs b/nusamai-plateau/src/models/waterbody.rs index 339f669f9..a29aef791 100644 --- a/nusamai-plateau/src/models/waterbody.rs +++ b/nusamai-plateau/src/models/waterbody.rs @@ -3,7 +3,7 @@ use citygml::{CityGMLElement, GeometryRef}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, CityGMLElement)] pub struct WaterBody { - #[citygml(auto_geom = b"wtr")] + #[citygml(geom = b"wtr")] pub geometries: GeometryRef, #[citygml(path = b"@gml:id")]