From e69c5955b5b26faa0205a7904de811b48cdb29ce Mon Sep 17 00:00:00 2001 From: satoshi komatsu <84182110+satoshi7190@users.noreply.github.com> Date: Tue, 2 Jul 2024 09:05:17 +0900 Subject: [PATCH] =?UTF-8?q?sink=E3=81=AEparameters=E3=81=8B=E3=82=89?= =?UTF-8?q?=E5=A4=89=E6=8F=9B=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7=E3=83=B3?= =?UTF-8?q?=E3=81=AEGUI=E3=82=92=E7=94=9F=E6=88=90=E3=81=99=E3=82=8B(Poc)?= =?UTF-8?q?=20(#563)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Close #334 ### Description(変更内容) ![image](https://github.com/MIERUNE/plateau-gis-converter/assets/84182110/fc68c1d1-24bf-4fac-a6d2-e05ecacc130a) - sinkのparametersをUIから変更できるようにしました(MVTのみ) - UIはIntegerのみ対応。StringとBooleanは仮実装してますが、まだ使用してないのでコメントアウトしてます。 - 入力ファイルと出力ファイルが指定されてない場合は変換ボタンを押せないようにしました。 ### Manual Testing(手動テスト) - MVTのズームレベルを変更して出力できるか確認 --- app/src-tauri/src/main.rs | 18 +++- app/src/app.css | 13 +++ app/src/lib/sinkparams.ts | 55 +++++++++++ app/src/routes/+page.svelte | 33 ++++--- app/src/routes/InputSelector.svelte | 4 +- app/src/routes/OutputSelector.svelte | 4 +- app/src/routes/SettingSelector.svelte | 129 ++++++++++++++++++++------ nusamai/src/parameters/mod.rs | 23 +++-- nusamai/src/sink/cesiumtiles/mod.rs | 2 + nusamai/src/sink/czml/mod.rs | 1 + nusamai/src/sink/geojson/mod.rs | 1 + nusamai/src/sink/gltf/mod.rs | 1 + nusamai/src/sink/gpkg/mod.rs | 1 + nusamai/src/sink/kml/mod.rs | 1 + nusamai/src/sink/minecraft/mod.rs | 1 + nusamai/src/sink/mvt/mod.rs | 3 + nusamai/src/sink/noop/mod.rs | 1 + nusamai/src/sink/ply/mod.rs | 1 + nusamai/src/sink/serde/mod.rs | 1 + nusamai/src/sink/shapefile/mod.rs | 3 +- 20 files changed, 238 insertions(+), 58 deletions(-) create mode 100644 app/src/lib/sinkparams.ts diff --git a/app/src-tauri/src/main.rs b/app/src-tauri/src/main.rs index 93e5f59d..4c5000d9 100644 --- a/app/src-tauri/src/main.rs +++ b/app/src-tauri/src/main.rs @@ -9,6 +9,7 @@ use std::{ }; use log::LevelFilter; +use nusamai::parameters::Parameters; use nusamai::{ pipeline::{feedback, Canceller}, sink::{ @@ -57,6 +58,7 @@ fn main() { .invoke_handler(tauri::generate_handler![ run_conversion, cancel_conversion, + get_parameter, get_transform ]) .run(tauri::generate_context!()) @@ -134,6 +136,7 @@ fn run_conversion( epsg: u16, rules_path: String, transformer_options: Vec, + sink_parameters: Parameters, tasks_state: tauri::State, window: tauri::Window, ) -> Result<(), Error> { @@ -174,7 +177,7 @@ fn run_conversion( Error::InvalidSetting(msg) })?; - let mut sink_params = sink_provider.parameters(); + let mut sink_params = sink_parameters; if let Err(err) = sink_params.update_values_with_str(&sinkopt) { let msg = format!("Error parsing sink options: {:?}", err); log::error!("{}", msg); @@ -307,3 +310,16 @@ fn get_transform(filetype: String) -> Result { Ok(transformer_registry) } + +/// Get the configurable parameters of the sink +#[tauri::command] +fn get_parameter(filetype: String) -> Result { + let sink_provider = select_sink_provider(&filetype).ok_or_else(|| { + let msg = format!("Invalid sink type: {}", filetype); + log::error!("{}", msg); + Error::InvalidSetting(msg) + })?; + let sink_params = sink_provider.parameters(); + + Ok(sink_params) +} diff --git a/app/src/app.css b/app/src/app.css index e8ce3746..56329e65 100644 --- a/app/src/app.css +++ b/app/src/app.css @@ -5,3 +5,16 @@ body { @apply text-base; } + +body::-webkit-scrollbar { + width: 9px; + height: 9px; +} + +body::-webkit-scrollbar-track { + background-color: #d9d9d9; +} + +body::-webkit-scrollbar-thumb { + background-color: rgb(0 190 190); +} diff --git a/app/src/lib/sinkparams.ts b/app/src/lib/sinkparams.ts new file mode 100644 index 00000000..51bf3db4 --- /dev/null +++ b/app/src/lib/sinkparams.ts @@ -0,0 +1,55 @@ +export interface IntegerParameter { + Integer: { + value: number; + min?: number; + max?: number; + }; +} + +export interface StringParameter { + String: { + value: string; + }; +} + +export interface BooleanParameter { + Boolean: { + value: boolean; + }; +} + +type Parameter = IntegerParameter | StringParameter | BooleanParameter; + +interface ParamsOptionItem { + parameter: Parameter; + description: string; + label?: string; +} + +export interface SinkParameters { + items: { + [key: string]: ParamsOptionItem; + }; +} + +// Check the parameter type +export function isIntegerParameter( + parameter: Parameter +): parameter is { Integer: { value: number; min: number; max: number } } { + return (parameter as { Integer?: unknown }).Integer !== undefined; +} +export function isStringParameter( + parameter: Parameter +): parameter is { String: { value: string } } { + return (parameter as { String?: unknown }).String !== undefined; +} +export function isBooleanParameter( + parameter: Parameter +): parameter is { Boolean: { value: boolean } } { + return (parameter as { Boolean?: unknown }).Boolean !== undefined; +} + +export function createRangeArray(min: number, max: number): number[] { + if (min > max) throw new Error('min should be less than or equal to max'); + return Array.from({ length: max - min + 1 }, (_, i) => min + i); +} diff --git a/app/src/routes/+page.svelte b/app/src/routes/+page.svelte index 30cc9116..bf7893b9 100644 --- a/app/src/routes/+page.svelte +++ b/app/src/routes/+page.svelte @@ -2,6 +2,7 @@ import { message } from '@tauri-apps/api/dialog'; import { invoke } from '@tauri-apps/api/tauri'; import { attachConsole } from 'tauri-plugin-log-api'; + import type { SinkParameters } from '$lib/sinkparams'; import Icon from '@iconify/svelte'; import InputSelector from './InputSelector.svelte'; @@ -16,20 +17,14 @@ let epsg: number; let rulesPath = ''; let outputPath = ''; + let sinkParameters = {} as SinkParameters; let isRunning = false; + let isConvertButtonDisabled = true; + + $: isConvertButtonDisabled = !inputPaths.length || !outputPath || isRunning; let transformerRegistry: { key: string; label: string; is_enabled: boolean }[]; async function convertAndSave() { - if (!inputPaths) { - await message('入力フォルダ/ファイルを選択してください', { type: 'warning' }); - return; - } - - if (!outputPath) { - await message('出力先を選択してください', { type: 'warning' }); - return; - } - isRunning = true; const transformerOptions = transformerRegistry.map((transformerConfig) => { @@ -46,7 +41,8 @@ filetype, epsg, rulesPath, - transformerOptions + transformerOptions, + sinkParameters }); isRunning = false; await message(`変換が完了しました。\n'${outputPath}' に出力しました。`, { type: 'info' }); @@ -63,7 +59,7 @@ {#if isRunning} -
+
{/if} @@ -79,14 +75,23 @@ - +
-
+
{#if outputPath}

{abbreviatePath(outputPath, 40)}

@@ -52,7 +52,7 @@
{:else} -

出力先が選択されていません

+

出力先が選択されていません

{/if}
diff --git a/app/src/routes/SettingSelector.svelte b/app/src/routes/SettingSelector.svelte index 4a20fb29..2e030e3e 100644 --- a/app/src/routes/SettingSelector.svelte +++ b/app/src/routes/SettingSelector.svelte @@ -1,12 +1,20 @@
@@ -85,35 +108,81 @@ {/each}
- {#if transformerRegistry && transformerRegistry.length > 0} + + {#if (transformerRegistry && transformerRegistry.length > 0) || sinkOptionKeys.length > 0}
- {#each transformerRegistry as config} -
- -
- -
{/if} @@ -133,7 +202,7 @@
{:else} -

設定ファイルが選択されていません

+

設定ファイルを選択してください(任意)

{/if}
diff --git a/nusamai/src/parameters/mod.rs b/nusamai/src/parameters/mod.rs index d9b1239e..9ce20f8a 100644 --- a/nusamai/src/parameters/mod.rs +++ b/nusamai/src/parameters/mod.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use indexmap::{map::Entry, IndexMap}; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use thiserror::Error; #[macro_export] @@ -27,7 +27,7 @@ pub enum Error { UnknownParameter(String), } -#[derive(Debug, Default, Serialize)] +#[derive(Debug, Default, Serialize, Deserialize)] pub struct Parameters { items: IndexMap, } @@ -103,11 +103,12 @@ impl Parameters { } } -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct ParameterEntry { pub description: String, pub required: bool, pub parameter: ParameterType, + pub label: Option, } impl ParameterEntry { @@ -141,7 +142,7 @@ impl ParameterEntry { } } -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, Deserialize)] pub enum ParameterType { FileSystemPath(FileSystemPathParameter), String(StringParameter), @@ -150,7 +151,7 @@ pub enum ParameterType { // and so on ... } -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct FileSystemPathParameter { pub value: Option, pub must_exist: bool, @@ -184,7 +185,7 @@ impl FileSystemPathParameter { } } -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct StringParameter { pub value: Option, } @@ -217,7 +218,7 @@ impl StringParameter { } } -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct BooleanParameter { pub value: Option, } @@ -252,7 +253,7 @@ impl BooleanParameter { } } -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct IntegerParameter { pub value: Option, pub min: Option, @@ -324,6 +325,7 @@ mod tests { description: "test".into(), required: true, parameter: ParameterType::String(StringParameter { value: None }), + label: None, }, ); params.define( @@ -332,6 +334,7 @@ mod tests { description: "test2".into(), required: false, parameter: ParameterType::String(StringParameter { value: None }), + label: Some("test2".into()), }, ); @@ -352,6 +355,7 @@ mod tests { description: "test".into(), required: true, parameter: ParameterType::Boolean(BooleanParameter { value: None }), + label: None, }, ); params.define( @@ -360,6 +364,7 @@ mod tests { description: "test2".into(), required: false, parameter: ParameterType::Boolean(BooleanParameter { value: None }), + label: Some("test2".into()), }, ); @@ -393,6 +398,7 @@ mod tests { min: Some(4), max: Some(10), }), + label: None, }, ); params.define( @@ -405,6 +411,7 @@ mod tests { min: Some(4), max: Some(10), }), + label: Some("test2".into()), }, ); diff --git a/nusamai/src/sink/cesiumtiles/mod.rs b/nusamai/src/sink/cesiumtiles/mod.rs index 79fae4fb..3a9a51ad 100644 --- a/nusamai/src/sink/cesiumtiles/mod.rs +++ b/nusamai/src/sink/cesiumtiles/mod.rs @@ -59,6 +59,7 @@ impl DataSinkProvider for CesiumTilesSinkProvider { value: None, must_exist: false, }), + label: None, }, ); // TODO: min Zoom @@ -70,6 +71,7 @@ impl DataSinkProvider for CesiumTilesSinkProvider { description: "transform option".into(), required: false, parameter: ParameterType::String(StringParameter { value: None }), + label: None, }, ); diff --git a/nusamai/src/sink/czml/mod.rs b/nusamai/src/sink/czml/mod.rs index f2d57134..3d197127 100644 --- a/nusamai/src/sink/czml/mod.rs +++ b/nusamai/src/sink/czml/mod.rs @@ -47,6 +47,7 @@ impl DataSinkProvider for CzmlSinkProvider { value: None, must_exist: false, }), + label: None, }, ); params diff --git a/nusamai/src/sink/geojson/mod.rs b/nusamai/src/sink/geojson/mod.rs index 9262df42..2a6ecf8e 100644 --- a/nusamai/src/sink/geojson/mod.rs +++ b/nusamai/src/sink/geojson/mod.rs @@ -48,6 +48,7 @@ impl DataSinkProvider for GeoJsonSinkProvider { value: None, must_exist: false, }), + label: None, }, ); params diff --git a/nusamai/src/sink/gltf/mod.rs b/nusamai/src/sink/gltf/mod.rs index dbd5a255..3983409f 100644 --- a/nusamai/src/sink/gltf/mod.rs +++ b/nusamai/src/sink/gltf/mod.rs @@ -48,6 +48,7 @@ impl DataSinkProvider for GltfSinkProvider { value: None, must_exist: false, }), + label: None, }, ); params diff --git a/nusamai/src/sink/gpkg/mod.rs b/nusamai/src/sink/gpkg/mod.rs index ae2c1458..697b2ec9 100644 --- a/nusamai/src/sink/gpkg/mod.rs +++ b/nusamai/src/sink/gpkg/mod.rs @@ -49,6 +49,7 @@ impl DataSinkProvider for GpkgSinkProvider { value: None, must_exist: false, }), + label: None, }, ); params diff --git a/nusamai/src/sink/kml/mod.rs b/nusamai/src/sink/kml/mod.rs index 11a75bc6..10ad8ba7 100644 --- a/nusamai/src/sink/kml/mod.rs +++ b/nusamai/src/sink/kml/mod.rs @@ -47,6 +47,7 @@ impl DataSinkProvider for KmlSinkProvider { value: None, must_exist: false, }), + label: None, }, ); params diff --git a/nusamai/src/sink/minecraft/mod.rs b/nusamai/src/sink/minecraft/mod.rs index 0ca581f2..f281d6f6 100644 --- a/nusamai/src/sink/minecraft/mod.rs +++ b/nusamai/src/sink/minecraft/mod.rs @@ -53,6 +53,7 @@ impl DataSinkProvider for MinecraftSinkProvider { value: None, must_exist: false, }), + label: None, }, ); params diff --git a/nusamai/src/sink/mvt/mod.rs b/nusamai/src/sink/mvt/mod.rs index 63c4b230..8409a2a9 100644 --- a/nusamai/src/sink/mvt/mod.rs +++ b/nusamai/src/sink/mvt/mod.rs @@ -53,6 +53,7 @@ impl DataSinkProvider for MvtSinkProvider { value: None, must_exist: false, }), + label: None, }, ); params.define( @@ -65,6 +66,7 @@ impl DataSinkProvider for MvtSinkProvider { min: Some(0), max: Some(20), }), + label: Some("最小ズームレベル".into()), }, ); params.define( @@ -77,6 +79,7 @@ impl DataSinkProvider for MvtSinkProvider { min: Some(0), max: Some(20), }), + label: Some("最大ズームレベル".into()), }, ); params diff --git a/nusamai/src/sink/noop/mod.rs b/nusamai/src/sink/noop/mod.rs index f7d19ed8..40096423 100644 --- a/nusamai/src/sink/noop/mod.rs +++ b/nusamai/src/sink/noop/mod.rs @@ -39,6 +39,7 @@ impl DataSinkProvider for NoopSinkProvider { value: None, must_exist: false, }), + label: None, }, ); // REMOVE: deprecated diff --git a/nusamai/src/sink/ply/mod.rs b/nusamai/src/sink/ply/mod.rs index 0ec16161..72305fb7 100644 --- a/nusamai/src/sink/ply/mod.rs +++ b/nusamai/src/sink/ply/mod.rs @@ -56,6 +56,7 @@ impl DataSinkProvider for StanfordPlySinkProvider { value: None, must_exist: false, }), + label: None, }, ); params diff --git a/nusamai/src/sink/serde/mod.rs b/nusamai/src/sink/serde/mod.rs index c596917a..53664399 100644 --- a/nusamai/src/sink/serde/mod.rs +++ b/nusamai/src/sink/serde/mod.rs @@ -40,6 +40,7 @@ impl DataSinkProvider for SerdeSinkProvider { value: None, must_exist: false, }), + label: None, }, ); params diff --git a/nusamai/src/sink/shapefile/mod.rs b/nusamai/src/sink/shapefile/mod.rs index 69fa059f..d21e5e76 100644 --- a/nusamai/src/sink/shapefile/mod.rs +++ b/nusamai/src/sink/shapefile/mod.rs @@ -28,7 +28,7 @@ use crate::{ pipeline::{Feedback, PipelineError, Receiver, Result}, sink::{DataRequirements, DataSink, DataSinkProvider, SinkInfo}, transformer, - transformer::{TransformerRegistry, TransformerOption}, + transformer::{TransformerOption, TransformerRegistry}, }; pub struct ShapefileSinkProvider {} @@ -52,6 +52,7 @@ impl DataSinkProvider for ShapefileSinkProvider { value: None, must_exist: false, }), + label: None, }, ); params