diff --git a/mbtiles/.sqlx/query-208681caa7185b4014e7eda4120962954cdd3d913e8a786599da8a3f9799ed4b.json b/mbtiles/.sqlx/query-208681caa7185b4014e7eda4120962954cdd3d913e8a786599da8a3f9799ed4b.json new file mode 100644 index 000000000..3550f54e0 --- /dev/null +++ b/mbtiles/.sqlx/query-208681caa7185b4014e7eda4120962954cdd3d913e8a786599da8a3f9799ed4b.json @@ -0,0 +1,20 @@ +{ + "db_name": "SQLite", + "query": "PRAGMA page_size;", + "describe": { + "columns": [ + { + "name": "page_size", + "ordinal": 0, + "type_info": "Int" + } + ], + "parameters": { + "Right": 0 + }, + "nullable": [ + null + ] + }, + "hash": "208681caa7185b4014e7eda4120962954cdd3d913e8a786599da8a3f9799ed4b" +} diff --git a/mbtiles/.sqlx/query-e0e1a38ef162278d888b297ec85a8f175977ae491ea3d47069b20b1946c44ade.json b/mbtiles/.sqlx/query-e0e1a38ef162278d888b297ec85a8f175977ae491ea3d47069b20b1946c44ade.json new file mode 100644 index 000000000..d5c3f6e56 --- /dev/null +++ b/mbtiles/.sqlx/query-e0e1a38ef162278d888b297ec85a8f175977ae491ea3d47069b20b1946c44ade.json @@ -0,0 +1,68 @@ +{ + "db_name": "SQLite", + "query": "SELECT\n zoom_level AS zoom,\n count( ) AS count,\n min( length( tile_data ) ) / 1024.0 AS smallest,\n max( length( tile_data ) ) / 1024.0 AS largest,\n avg( length( tile_data ) ) / 1024.0 AS average,\n min(tile_column) as min_tile_x,\n min(tile_row) as min_tile_y,\n max(tile_column) as max_tile_x,\n max(tile_row) as max_tile_y \n FROM tiles\n GROUP BY zoom_level", + "describe": { + "columns": [ + { + "name": "zoom", + "ordinal": 0, + "type_info": "Int64" + }, + { + "name": "count", + "ordinal": 1, + "type_info": "Int" + }, + { + "name": "smallest", + "ordinal": 2, + "type_info": "Float" + }, + { + "name": "largest", + "ordinal": 3, + "type_info": "Float" + }, + { + "name": "average", + "ordinal": 4, + "type_info": "Float" + }, + { + "name": "min_tile_x", + "ordinal": 5, + "type_info": "Int" + }, + { + "name": "min_tile_y", + "ordinal": 6, + "type_info": "Int" + }, + { + "name": "max_tile_x", + "ordinal": 7, + "type_info": "Int" + }, + { + "name": "max_tile_y", + "ordinal": 8, + "type_info": "Int" + } + ], + "parameters": { + "Right": 0 + }, + "nullable": [ + true, + false, + true, + true, + true, + true, + true, + true, + true + ] + }, + "hash": "e0e1a38ef162278d888b297ec85a8f175977ae491ea3d47069b20b1946c44ade" +} diff --git a/mbtiles/src/bin/main.rs b/mbtiles/src/bin/main.rs index 9643e5f54..d2cc50096 100644 --- a/mbtiles/src/bin/main.rs +++ b/mbtiles/src/bin/main.rs @@ -26,6 +26,9 @@ enum Commands { /// MBTiles file to read from file: PathBuf, }, + /// Gets tile statistics from MBTiels file + #[command(name = "stats")] + Stats { file: PathBuf }, /// Gets a single value from the MBTiles metadata table. #[command(name = "meta-get")] MetaGetValue { @@ -114,6 +117,12 @@ async fn main_int() -> anyhow::Result<()> { let mbt = Mbtiles::new(file.as_path())?; mbt.validate(integrity_check, update_agg_tiles_hash).await?; } + Commands::Stats { file } => { + let mbt = Mbtiles::new(file.as_path())?; + let mut conn = mbt.open_readonly().await?; + + mbt.statistics(&mut conn).await?; + } } Ok(()) diff --git a/mbtiles/src/mbtiles.rs b/mbtiles/src/mbtiles.rs index 2faf2b894..49c85fd62 100644 --- a/mbtiles/src/mbtiles.rs +++ b/mbtiles/src/mbtiles.rs @@ -39,6 +39,25 @@ pub struct Metadata { pub json: Option, } +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct Tileinfo { + pub zoom: u8, + pub count: u32, + pub smallest: u32, + pub largest: u32, + pub average: u32, + pub bounding_box: [u32; 4], +} + +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct Statistics { + pub file: String, + // the schema + pub structure: String, + pub page_size: u64, + pub tile_infos: Vec, +} + #[allow(clippy::trivially_copy_pass_by_ref)] fn serialize_ti(ti: &TileInfo, serializer: S) -> Result where @@ -223,7 +242,38 @@ impl Mbtiles { self.check_agg_tiles_hashes(&mut conn).await } } - + pub async fn statistics(&self, conn: &mut T) -> MbtResult> + where + for<'e> &'e mut T: SqliteExecutor<'e>, + { + // let page_count_query = query!("PRAGMA page_count;"); + let page_size_query = query!("PRAGMA page_size;"); + + let tile_infos_query = query!( + r#"SELECT + zoom_level AS zoom, + count( ) AS count, + min( length( tile_data ) ) / 1024.0 AS smallest, + max( length( tile_data ) ) / 1024.0 AS largest, + avg( length( tile_data ) ) / 1024.0 AS average, + min(tile_column) as min_tile_x, + min(tile_row) as min_tile_y, + max(tile_column) as max_tile_x, + max(tile_row) as max_tile_y + FROM tiles + GROUP BY zoom_level"# + ); + let file_name = &self.filename; + let page_size = page_size_query.fetch_one(&mut *conn).await?.page_size; + let mb_type = self.detect_type(&mut *conn).await?; + let tile_infos_rows = tile_infos_query.fetch_all(&mut *conn).await?; + Ok(Some(Statistics { + file: "test".to_string(), + structure: "test".to_string(), + page_size: 22, + tile_infos: Vec::new(), + })) + } /// Get the aggregate tiles hash value from the metadata table pub async fn get_agg_tiles_hash(&self, conn: &mut T) -> MbtResult> where