From 81f0126217a66f1ea0dfb1156e87d0734308506b Mon Sep 17 00:00:00 2001 From: Taku Fukada Date: Tue, 19 Dec 2023 10:11:27 +0900 Subject: [PATCH] =?UTF-8?q?=E6=96=BD=E8=A8=AD=E7=AE=A1=E7=90=86=E3=81=AE?= =?UTF-8?q?=E5=BF=9C=E7=94=A8=E3=82=B9=E3=82=AD=E3=83=BC=E3=83=9E=E3=81=A8?= =?UTF-8?q?=E5=85=AC=E5=85=B1=E6=B8=AC=E9=87=8F=E6=A8=99=E6=BA=96=E5=9B=B3?= =?UTF-8?q?=E5=BC=8F=E3=81=AE=E5=BF=9C=E7=94=A8=E3=82=B9=E3=82=AD=E3=83=BC?= =?UTF-8?q?=E3=83=9E=E3=81=AE=E3=82=B9=E3=82=BF=E3=83=96=E3=82=92=E5=AE=9F?= =?UTF-8?q?=E8=A3=85=20(#82)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (#70 を補助するPRとして、#81 の問題の一部を解決する) 施設管理まわりと公共測量標準図式まわりについて、おおよその形を示してあります。 すべてを実装しているわけではなく、特に、大量の `FacilityAttribute` まわりについては一切実装していないです。 CityFurniture でこれらのデータが付属するものは今のところなさそうなので、テストもありません。 --- nusamai-plateau/citygml/macros/src/lib.rs | 1 + nusamai-plateau/src/models/iur/uro/common.rs | 65 -------- nusamai-plateau/src/models/iur/uro/dm.rs | 153 ++++++++++++++++++ .../src/models/iur/uro/facility.rs | 68 ++++++++ .../src/models/iur/uro/facility_id.rs | 133 +++++++++++++++ .../src/models/iur/uro/facility_type.rs | 11 ++ nusamai-plateau/src/models/mod.rs | 2 +- nusamai-plateau/tests/data/LICENSE.txt | 2 +- nusamai-plateau/tests/test_cityfurniture.rs | 16 +- nusamai-plateau/tests/test_simple.rs | 8 +- 10 files changed, 381 insertions(+), 78 deletions(-) delete mode 100644 nusamai-plateau/src/models/iur/uro/common.rs create mode 100644 nusamai-plateau/src/models/iur/uro/dm.rs create mode 100644 nusamai-plateau/src/models/iur/uro/facility.rs create mode 100644 nusamai-plateau/src/models/iur/uro/facility_id.rs create mode 100644 nusamai-plateau/src/models/iur/uro/facility_type.rs diff --git a/nusamai-plateau/citygml/macros/src/lib.rs b/nusamai-plateau/citygml/macros/src/lib.rs index e8ec2249e..c676afd75 100644 --- a/nusamai-plateau/citygml/macros/src/lib.rs +++ b/nusamai-plateau/citygml/macros/src/lib.rs @@ -92,6 +92,7 @@ fn generate_citygml_struct_model( add_arm(2, b"lod2MultiSurface", "MultiSurface"); add_arm(3, b"lod3MultiSurface", "MultiSurface"); add_arm(4, b"lod4MultiSurface", "MultiSurface"); + add_arm(0, b"lod0Geometry", "Geometry"); // for uro:lod0Geometry add_arm(1, b"lod1Geometry", "Geometry"); add_arm(2, b"lod2Geometry", "Geometry"); add_arm(3, b"lod3Geometry", "Geometry"); diff --git a/nusamai-plateau/src/models/iur/uro/common.rs b/nusamai-plateau/src/models/iur/uro/common.rs deleted file mode 100644 index fb5574e3c..000000000 --- a/nusamai-plateau/src/models/iur/uro/common.rs +++ /dev/null @@ -1,65 +0,0 @@ -use citygml::{CityGMLElement, Code}; - -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Default, Debug, CityGMLElement)] -pub struct FacilityTypeAttribute { - #[citygml(path = b"uro:class")] - pub class: Option, - - #[citygml(path = b"uro:function")] - pub function: Vec, -} - -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Default, Debug, CityGMLElement)] -pub struct FacilityIdAttribute { - #[citygml(path = b"uro:id")] - pub id: Option, - - #[citygml(path = b"uro:partId")] - pub part_id: Option, - - #[citygml(path = b"uro:branchId")] - pub branch_id: Option, - - #[citygml(path = b"uro:prefecture")] - pub prefecture: Vec, - - #[citygml(path = b"uro:city")] - pub city: Vec, - - #[citygml(path = b"uro:route")] - pub route: Option, - - #[citygml(path = b"uro:startPost")] - pub start_post: Option, - - #[citygml(path = b"uro:endPost")] - pub end_post: Option, - - #[citygml(path = b"uro:startLat")] - pub start_lat: Option, - - #[citygml(path = b"uro:startLong")] - pub start_long: Option, - - #[citygml(path = b"uro:alternativeName")] - pub alternative_name: Vec, -} - -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Default, Debug, CityGMLElement)] -pub struct DmAttribute { - #[citygml(path = b"uro:dmCode")] - pub dm_code: Code, - - #[citygml(path = b"uro:meshCode")] - pub mesh_code: Vec, -} - -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Default, Debug, CityGMLElement)] -pub struct FacilityAttribute { - #[citygml(path = b"uro:facilityId")] - pub facility_id: Option, -} diff --git a/nusamai-plateau/src/models/iur/uro/dm.rs b/nusamai-plateau/src/models/iur/uro/dm.rs new file mode 100644 index 000000000..7ccdee921 --- /dev/null +++ b/nusamai-plateau/src/models/iur/uro/dm.rs @@ -0,0 +1,153 @@ +use citygml::{CityGMLElement, Code, GeometryRef, Measure}; + +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Default, Debug, CityGMLElement)] +pub enum DmAttributeProperty { + #[default] + Unknown, + #[citygml(path = b"uro:DmAnnotation")] + DmAnnotation(DmAnnotation), + #[citygml(path = b"uro:DmGeometricAttribute")] + DmGeometricAttribute(DmGeometricAttribute), +} + +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Default, Debug, CityGMLElement)] +pub struct DmAnnotation { + #[citygml(path = b"uro:dmCode")] + pub dm_code: Option, + + #[citygml(path = b"uro:meshCode")] + pub mesh_code: Vec, + + #[citygml(path = b"uro:dmElement/uro:DmElement")] + pub dm_element: Option, + + #[citygml(path = b"uro:geometryType")] + pub geometry_type: Option, + + #[citygml(path = b"uro:shapeType")] + pub shape_type: Option, + + #[citygml(path = b"uro:label")] + pub label: Option, + + #[citygml(path = b"uro:isVertical")] + pub is_vertical: Option, + + #[citygml(path = b"uro:size")] + pub size: Option, + + #[citygml(path = b"uro:orientation")] + pub orientation: Option, + + #[citygml(path = b"uro:linewidth")] + pub linewidth: Option, + + #[citygml(path = b"uro:spacing")] + pub spacing: Option, + // TODO: + // #[citygml(path = b"uro:lod0anchorPoint")] + // pub lod0anchorPoint: GeometryPropertyType +} + +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Default, Debug, CityGMLElement)] +pub struct DmGeometricAttribute { + #[citygml(geom = b"uro")] + pub geometry: GeometryRef, + + #[citygml(path = b"uro:dmCode")] + pub dm_code: Option, + + #[citygml(path = b"uro:meshCode")] + pub mesh_code: Vec, + + #[citygml(path = b"uro:dmElement/uro:DmElement")] + pub dm_element: Option, + + #[citygml(path = b"uro:geometryType")] + pub geometry_type: Option, + + #[citygml(path = b"uro:mapLevel")] + pub map_level: Option, + + #[citygml(path = b"uro:shapeType")] + pub shape_type: Option, + + #[citygml(path = b"uro:visibility")] + pub visibility: Option, + + #[citygml(path = b"uro:is3d")] + pub is3d: Option, + + #[citygml(path = b"uro:isInstallation")] + pub is_installation: Option, + + #[citygml(path = b"uro:isEdited")] + pub is_edited: Option, + + #[citygml(path = b"uro:isSupplementarySymbol")] + pub is_supplementary_symbol: Option, + + #[citygml(path = b"uro:angle")] + pub angle: Option, + + #[citygml(path = b"uro:elevation")] + pub elevation: Option, + // TODO: + // #[citygml(path = b"uro:lod0Geometry")] + // pub lod0anchorPoint: GeometryPropertyType +} + +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Default, Debug, CityGMLElement)] +pub struct DmElement { + #[citygml(path = b"uro:locationType")] + pub location_type: Option, + + #[citygml(path = b"uro:infoType")] + pub info_type: Option, + + #[citygml(path = b"uro:elementKey")] + pub element_key: Option, + + #[citygml(path = b"uro:hierarchyLevel")] + pub hierarchy_level: Option, + + #[citygml(path = b"uro:dataType")] + pub data_type: Option, + + #[citygml(path = b"uro:annotationType")] + pub annotation_type: Option, + + #[citygml(path = b"uro:precisionType")] + pub precision_type: Option, + + #[citygml(path = b"uro:dislocationType")] + pub dislocation_type: Option, + + #[citygml(path = b"uro:breakType")] + pub break_type: Option, + + #[citygml(path = b"uro:attributeValue")] + pub attribute_value: Option, + + #[citygml(path = b"uro:attributeType")] + pub attribute_type: Option, + + #[citygml(path = b"uro:attributeValueType")] + pub attribute_value_type: Option, + + #[citygml(path = b"uro:creationDate")] + pub creation_date: Option, // TODO: xs:gYearMonth + + #[citygml(path = b"uro:updateDate")] + pub update_date: Option, // TODO: xs:gYearMonth + + #[citygml(path = b"uro:terminationDate")] + pub termination_date: Option, // TODO: xs:gYearMonth + + #[citygml(path = b"uro:freeSpace")] + pub free_space: Option, +} diff --git a/nusamai-plateau/src/models/iur/uro/facility.rs b/nusamai-plateau/src/models/iur/uro/facility.rs new file mode 100644 index 000000000..bfe30a878 --- /dev/null +++ b/nusamai-plateau/src/models/iur/uro/facility.rs @@ -0,0 +1,68 @@ +use citygml::CityGMLElement; + +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Default, Debug, CityGMLElement)] +pub enum FacilityAttributeProperty { + #[default] + Unknown, + // TODO: + // #[citygml(path = b"uro:CargoHandlingFacility")] + // CargoHandlingFacility(CargoHandlingFacility), + // TODO: + // #[citygml(path = b"uro:CyberportMarinaAndPBS")] + // CyberportMarinaAndPBS(CyberportMarinaAndPBS), + // TODO: + // #[citygml(path = b"uro:FishingPortAttribute")] + // FishingPortAttribute(FishingPortAttribute), + // TODO: + // #[citygml(path = b"uro:FishingPortCapacity")] + // FishingPortAttribute(FishingPortAttribute), + // TODO: + // #[citygml(path = b"uro:FishingPortFacility")] + // FishingPortFacility(FishingPortFacility), + // TODO: + // #[citygml(path = b"uro:HarborFacility")] + // HarborFacility(HarborFacility), + // TODO: + // #[citygml(path = b"uro:MaintenanceHistoryAttribute")] + // MaintenanceHistoryAttribute(MaintenanceHistoryAttribute), + // TODO: + // #[citygml(path = b"uro:MooringFacility")] + // MooringFacility(MooringFacility), + // TODO: + // #[citygml(path = b"uro:NavigationAssistanceFacility")] + // NavigationAssistanceFacility(NavigationAssistanceFacility), + // TODO: + // #[citygml(path = b"uro:PortAttribute")] + // PortAttribute(PortAttribute), + // TODO: + // #[citygml(path = b"uro:PortEnvironmentalImprovementFacility")] + // PortEnvironmentalImprovementFacility(PortEnvironmentalImprovementFacility), + // TODO: + // #[citygml(path = b"uro:PortManagementFacility")] + // PortManagementFacility(PortManagementFacility), + // TODO: + // #[citygml(path = b"uro:PortPassengerFacility")] + // PortPassengerFacility(PortPassengerFacility), + // TODO: + // #[citygml(path = b"uro:PortPollutionControlFacility")] + // PortPollutionControlFacility(PortPollutionControlFacility), + // TODO: + // #[citygml(path = b"uro:PortProtectiveFacility")] + // PortProtectiveFacility(PortProtectiveFacility), + // TODO: + // #[citygml(path = b"uro:PortStorageFacility")] + // PortStorageFacility(PortStorageFacility), + // TODO: + // #[citygml(path = b"uro:PortTransportationFacility")] + // PortTransportationFacility(PortTransportationFacility), + // TODO: + // #[citygml(path = b"uro:PortWasteTreatmentFacility")] + // PortWasteTreatmentFacility(PortWasteTreatmentFacility), + // TODO: + // #[citygml(path = b"uro:PortWelfareFacility")] + // PortWelfareFacility(PortWelfareFacility), + // TODO: + // #[citygml(path = b"uro:ShipServiceFacility")] + // ShipServiceFacility(ShipServiceFacility), +} diff --git a/nusamai-plateau/src/models/iur/uro/facility_id.rs b/nusamai-plateau/src/models/iur/uro/facility_id.rs new file mode 100644 index 000000000..9e8873bf0 --- /dev/null +++ b/nusamai-plateau/src/models/iur/uro/facility_id.rs @@ -0,0 +1,133 @@ +use citygml::{CityGMLElement, Code, Measure}; + +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Default, Debug, CityGMLElement)] +pub enum FacilityIdAttributeProperty { + #[default] + Unknown, + + #[citygml(path = b"uro:FacilityIdAttribute")] + FacilityIdAttribute(FacilityIdAttribute), + + #[citygml(path = b"uro:RiverFacilityIdAttribute")] + RiverFacilityIdAttribute(RiverFacilityIdAttribute), +} + +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Default, Debug, CityGMLElement)] +pub struct FacilityIdAttribute { + #[citygml(path = b"uro:id")] + pub id: Option, + + #[citygml(path = b"uro:partId")] + pub part_id: Option, + + #[citygml(path = b"uro:branchId")] + pub branch_id: Option, + + #[citygml(path = b"uro:prefecture")] + pub prefecture: Vec, + + #[citygml(path = b"uro:city")] + pub city: Vec, + + #[citygml(path = b"uro:route")] + pub route: Option, + + #[citygml(path = b"uro:startPost")] + pub start_post: Option, + + #[citygml(path = b"uro:endPost")] + pub end_post: Option, + + #[citygml(path = b"uro:startLat")] + pub start_lat: Option, + + #[citygml(path = b"uro:startLong")] + pub start_long: Option, + + #[citygml(path = b"uro:alternativeName")] + pub alternative_name: Vec, +} + +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Default, Debug, CityGMLElement)] +pub struct RiverFacilityIdAttribute { + #[citygml(path = b"uro:id")] + pub id: Option, + + #[citygml(path = b"uro:partId")] + pub part_id: Option, + + #[citygml(path = b"uro:branchId")] + pub branch_id: Option, + + #[citygml(path = b"uro:prefecture")] + pub prefecture: Vec, + + #[citygml(path = b"uro:city")] + pub city: Vec, + + #[citygml(path = b"uro:route")] + pub route: Option, + + #[citygml(path = b"uro:startPost")] + pub start_post: Option, + + #[citygml(path = b"uro:endPost")] + pub end_post: Option, + + #[citygml(path = b"uro:startLat")] + pub start_lat: Option, + + #[citygml(path = b"uro:startLong")] + pub start_long: Option, + + #[citygml(path = b"uro:alternativeName")] + pub alternative_name: Vec, + + #[citygml(path = b"uro:riverCode")] + pub river_code: Option, + + #[citygml(path = b"uro:riverName")] + pub river_name: Option, + + #[citygml(path = b"uro:sideType")] + pub side_type: Option, + + #[citygml(path = b"uro:leftPost")] + pub left_post: Option, + + #[citygml(path = b"uro:leftDistance")] + pub left_distance: Option, + + #[citygml(path = b"uro:rightPost")] + pub right_post: Option, + + #[citygml(path = b"uro:rightDistance")] + pub right_distance: Option, + + #[citygml(path = b"uro:leftStartPost")] + pub left_start_post: Option, + + #[citygml(path = b"uro:leftStartDistance")] + pub left_start_distance: Option, + + #[citygml(path = b"uro:rightStartPost")] + pub right_start_post: Option, + + #[citygml(path = b"uro:rightStartDistance")] + pub right_start_distance: Option, + + #[citygml(path = b"uro:leftEndPost")] + pub left_end_post: Option, + + #[citygml(path = b"uro:leftEndDistance")] + pub left_end_distance: Option, + + #[citygml(path = b"uro:rightEndPost")] + pub right_end_post: Option, + + #[citygml(path = b"uro:rightEndDistance")] + pub right_end_distance: Option, +} diff --git a/nusamai-plateau/src/models/iur/uro/facility_type.rs b/nusamai-plateau/src/models/iur/uro/facility_type.rs new file mode 100644 index 000000000..32a934572 --- /dev/null +++ b/nusamai-plateau/src/models/iur/uro/facility_type.rs @@ -0,0 +1,11 @@ +use citygml::{CityGMLElement, Code}; + +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Default, Debug, CityGMLElement)] +pub struct FacilityTypeAttribute { + #[citygml(path = b"uro:class")] + pub class: Option, + + #[citygml(path = b"uro:function")] + pub function: Vec, +} diff --git a/nusamai-plateau/src/models/mod.rs b/nusamai-plateau/src/models/mod.rs index b71c7960d..f06368b44 100644 --- a/nusamai-plateau/src/models/mod.rs +++ b/nusamai-plateau/src/models/mod.rs @@ -33,7 +33,7 @@ use citygml::CityGMLElement; serde(tag = "type") )] #[derive(Default, Debug, CityGMLElement)] -pub enum CityObject { +pub enum TopLevelCityObject { #[default] Unknown, // diff --git a/nusamai-plateau/tests/data/LICENSE.txt b/nusamai-plateau/tests/data/LICENSE.txt index f1b5f7b17..f472df688 100644 --- a/nusamai-plateau/tests/data/LICENSE.txt +++ b/nusamai-plateau/tests/data/LICENSE.txt @@ -1,6 +1,6 @@ テスト用データ出典 -- `53393680_bldg_6697_lod4.2_op.gml`: 「3D都市モデル(Project PLATEAU)東京都23区 ポートシティ竹芝 建築物モデル(LOD4)(2022年度)」 (https://www.geospatial.jp/ckan/dataset/plateau-tokyo23ku-2023-lod4) +- `53393680_bldg_6697_lod4.2_op.gml`: [3D都市モデル(Project PLATEAU)東京都23区 ポートシティ竹芝 建築物モデル(LOD4)(2022年度)](https://www.geospatial.jp/ckan/dataset/plateau-tokyo23ku-2023-lod4) - `52363550_frn_6697_op.gml`: [3D都市モデル(Project PLATEAU)川崎市(2022年度)](https://www.geospatial.jp/ckan/dataset/plateau-14130-kawasaki-shi-2022) diff --git a/nusamai-plateau/tests/test_cityfurniture.rs b/nusamai-plateau/tests/test_cityfurniture.rs index c845c4246..8700d43fa 100644 --- a/nusamai-plateau/tests/test_cityfurniture.rs +++ b/nusamai-plateau/tests/test_cityfurniture.rs @@ -2,7 +2,7 @@ use std::io::BufRead; use citygml::{CityGMLElement, CityGMLReader, Code, Geometries, ParseError, SubTreeReader}; use nusamai_plateau::models::cityfurniture::CityFurniture; -use nusamai_plateau::models::CityObject; +use nusamai_plateau::models::TopLevelCityObject; #[derive(Default, Debug)] struct ParsedData { @@ -15,13 +15,13 @@ fn toplevel_dispatcher(st: &mut SubTreeReader) -> Result { - let mut cityobj: CityObject = Default::default(); + let mut cityobj: TopLevelCityObject = Default::default(); cityobj.parse(st)?; match cityobj { - CityObject::CityFurniture(frn) => { + TopLevelCityObject::CityFurniture(frn) => { parsed_data.cityfurnitures.push(frn); } - CityObject::CityObjectGroup(_) => (), + TopLevelCityObject::CityObjectGroup(_) => (), e => panic!("Unexpected city object type: {:?}", e), } let geometries = st.collect_geometries(); @@ -65,7 +65,7 @@ fn test_cityfurniture() { parsed_data.geometries.len() ); - let frn = parsed_data.cityfurnitures.get(0).unwrap(); + let frn = parsed_data.cityfurnitures.first().unwrap(); assert_eq!( frn.function, vec![Code { @@ -75,11 +75,13 @@ fn test_cityfurniture() { ); assert_eq!( - frn.city_furniture_data_quality_attribute.as_ref().unwrap().src_scale, + frn.city_furniture_data_quality_attribute + .as_ref() + .unwrap() + .src_scale, vec![Code { value: "3".to_string(), code: "3".to_string(), }] ); - } diff --git a/nusamai-plateau/tests/test_simple.rs b/nusamai-plateau/tests/test_simple.rs index 7f33696fe..606dca761 100644 --- a/nusamai-plateau/tests/test_simple.rs +++ b/nusamai-plateau/tests/test_simple.rs @@ -1,7 +1,7 @@ use std::io::BufRead; use citygml::{CityGMLElement, CityGMLReader, ParseError, SubTreeReader}; -use nusamai_plateau::models::CityObject; +use nusamai_plateau::models::TopLevelCityObject; #[derive(Default, Debug)] struct Counter { @@ -19,11 +19,11 @@ fn example_toplevel_dispatcher( match st.parse_children(|st| match st.current_path() { b"core:cityObjectMember" => { - let mut cityobj: CityObject = Default::default(); + let mut cityobj: TopLevelCityObject = Default::default(); cityobj.parse(st)?; match cityobj { - CityObject::Building(_) => counter.buildings += 1, - CityObject::CityObjectGroup(_) => counter.cityobjectgroups += 1, + TopLevelCityObject::Building(_) => counter.buildings += 1, + TopLevelCityObject::CityObjectGroup(_) => counter.cityobjectgroups += 1, e => panic!("Unexpected city object type: {:?}", e), } let geometries = st.collect_geometries();