From 365fb20ddf37e8a3c7a4ba83ed0ec6b3756625d7 Mon Sep 17 00:00:00 2001 From: Taku Fukada Date: Tue, 27 Feb 2024 13:23:05 +0900 Subject: [PATCH] mvt: min_z, max_z options --- app/src-tauri/src/main.rs | 4 +-- nusamai/src/lib.rs | 2 +- nusamai/src/sink/mvt/mod.rs | 60 +++++++++++++++++++++++++++++-------- nusamai/tests/sink.rs | 2 +- 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/app/src-tauri/src/main.rs b/app/src-tauri/src/main.rs index 0a21408fc..ee7a113fb 100644 --- a/app/src-tauri/src/main.rs +++ b/app/src-tauri/src/main.rs @@ -10,7 +10,7 @@ use nusamai::pipeline::Canceller; use nusamai::sink::DataSinkProvider; use nusamai::sink::{ cesiumtiles::CesiumTilesSinkProvider, czml::CzmlSinkProvider, geojson::GeoJsonSinkProvider, - gltf::GltfSinkProvider, gpkg::GpkgSinkProvider, kml::KmlSinkProvider, mvt::MVTSinkProvider, + gltf::GltfSinkProvider, gpkg::GpkgSinkProvider, kml::KmlSinkProvider, mvt::MvtSinkProvider, ply::StanfordPlySinkProvider, serde::SerdeSinkProvider, shapefile::ShapefileSinkProvider, }; use nusamai::source::citygml::CityGmlSourceProvider; @@ -39,7 +39,7 @@ fn select_sink_provider(filetype: &str) -> Box { "serde" => Box::new(SerdeSinkProvider {}), "geojson" => Box::new(GeoJsonSinkProvider {}), "gpkg" => Box::new(GpkgSinkProvider {}), - "mvt" => Box::new(MVTSinkProvider {}), + "mvt" => Box::new(MvtSinkProvider {}), "shapefile" => Box::new(ShapefileSinkProvider {}), "czml" => Box::new(CzmlSinkProvider {}), "kml" => Box::new(KmlSinkProvider {}), diff --git a/nusamai/src/lib.rs b/nusamai/src/lib.rs index 8f394fdf0..042b20819 100644 --- a/nusamai/src/lib.rs +++ b/nusamai/src/lib.rs @@ -7,7 +7,7 @@ pub mod transformer; pub static BUILTIN_SINKS: &[&dyn sink::DataSinkProvider] = &[ &sink::cesiumtiles::CesiumTilesSinkProvider {}, &sink::gpkg::GpkgSinkProvider {}, - &sink::mvt::MVTSinkProvider {}, + &sink::mvt::MvtSinkProvider {}, &sink::geojson::GeoJsonSinkProvider {}, &sink::czml::CzmlSinkProvider {}, &sink::gltf::GltfSinkProvider {}, diff --git a/nusamai/src/sink/mvt/mod.rs b/nusamai/src/sink/mvt/mod.rs index 46874fa8a..ebe22c8e2 100644 --- a/nusamai/src/sink/mvt/mod.rs +++ b/nusamai/src/sink/mvt/mod.rs @@ -31,9 +31,9 @@ use slice::slice_cityobj_geoms; use sort::BincodeExternalChunk; use tags::convert_properties; -pub struct MVTSinkProvider {} +pub struct MvtSinkProvider {} -impl DataSinkProvider for MVTSinkProvider { +impl DataSinkProvider for MvtSinkProvider { fn info(&self) -> SinkInfo { SinkInfo { id_name: "mvt".to_string(), @@ -54,22 +54,53 @@ impl DataSinkProvider for MVTSinkProvider { }), }, ); - // TODO: min Zoom - // TODO: max Zoom + params.define( + "min_z".into(), + ParameterEntry { + description: "Minumum zoom level".into(), + required: true, + parameter: ParameterType::Integer(IntegerParameter { + value: Some(7), + min: Some(0), + max: Some(20), + }), + }, + ); + params.define( + "max_z".into(), + ParameterEntry { + description: "Maximum zoom level".into(), + required: true, + parameter: ParameterType::Integer(IntegerParameter { + value: Some(15), + min: Some(0), + max: Some(20), + }), + }, + ); params } fn create(&self, params: &Parameters) -> Box { let output_path = get_parameter_value!(params, "@output", FileSystemPath); + let min_z = get_parameter_value!(params, "min_z", Integer).unwrap() as u8; + let max_z = get_parameter_value!(params, "max_z", Integer).unwrap() as u8; - Box::::new(MVTSink { + Box::::new(MvtSink { output_path: output_path.as_ref().unwrap().into(), + mvt_options: MvtParams { min_z, max_z }, }) } } -struct MVTSink { +struct MvtSink { output_path: PathBuf, + mvt_options: MvtParams, +} + +struct MvtParams { + min_z: u8, + max_z: u8, } #[derive(Serialize, Deserialize, deepsize::DeepSizeOf)] @@ -85,7 +116,7 @@ struct SlicedFeature<'a> { properties: nusamai_citygml::object::Value, } -impl DataSink for MVTSink { +impl DataSink for MvtSink { fn make_transform_requirements(&self) -> transformer::Requirements { transformer::Requirements { key_value: transformer::KeyValueSpec::DotNotation, @@ -105,9 +136,13 @@ impl DataSink for MVTSink { // Slicing geometry along the tile boundaries { s.spawn(|| { - if let Err(error) = - geometry_slicing_stage(feedback, upstream, tile_id_conv, sender_sliced) - { + if let Err(error) = geometry_slicing_stage( + feedback, + upstream, + tile_id_conv, + sender_sliced, + &self.mvt_options, + ) { feedback.report_fatal_error(error); } }); @@ -149,6 +184,7 @@ fn geometry_slicing_stage( upstream: mpsc::Receiver, tile_id_conv: TileIdMethod, sender_sliced: mpsc::SyncSender, + mvt_options: &MvtParams, ) -> Result<()> { // Convert CityObjects to sliced features upstream.into_iter().par_bridge().try_for_each(|parcel| { @@ -158,8 +194,8 @@ fn geometry_slicing_stage( let buffer_pixels = 5; slice_cityobj_geoms( &parcel.entity, - 7, - 16, + mvt_options.min_z, + mvt_options.max_z, max_detail, buffer_pixels, |(z, x, y), mpoly| { diff --git a/nusamai/tests/sink.rs b/nusamai/tests/sink.rs index f67d5e303..bad180b49 100644 --- a/nusamai/tests/sink.rs +++ b/nusamai/tests/sink.rs @@ -104,7 +104,7 @@ fn run_gpkg_sink() { #[test] fn run_mvt_sink() { - simple_run_sink(sink::mvt::MVTSinkProvider {}, "/tmp/nusamai/mvt/".into()); + simple_run_sink(sink::mvt::MvtSinkProvider {}, "/tmp/nusamai/mvt/".into()); } #[test]