Skip to content

Commit 5ee5a75

Browse files
authored
Merge pull request #60 from yuiseki/main
Release 2026-01-14 07:10:34 UTC
2 parents 0f43fcd + 2e13148 commit 5ee5a75

File tree

12 files changed

+169
-27
lines changed

12 files changed

+169
-27
lines changed

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@
1313
- When editing PR bodies, do not paste raw `cargo test --verbose` output. If you ran `make test` and it passed, just check the Testing checkbox.
1414
- Do not use `gh pr edit` to update PR bodies. Use `gh api -X PATCH` instead.
1515
- Avoid `gh pr create`. Create PRs with `gh api -X POST /repos/<owner>/<repo>/pulls` and pass `title`, `head`, `base`, and `body`.
16+
- Always update `CHANGELOG.md` for user-visible changes before releasing.
1617
- When asked to bump versions, follow `docs/RELEASE.md`.
1718
- Release flow: `main``release` PRs are auto-created/updated; tags are created by workflow on `release` merges and releases are dispatched automatically.

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ The format is based on Keep a Changelog and adheres to Semantic Versioning.
2020
### Security
2121
- TBD_UNVT_CHANGELOG_SECURITY
2222

23+
## [0.4.3] - 2026-01-14
24+
### Added
25+
- Add a "Top 10 big tiles" section to inspect text output (respects --zoom).
26+
- Allow `inspect -z/-x/-y` to show tile summaries in compat-style arguments.
27+
- Document an inspect workflow and tips in HOW_TO.
28+
29+
### Changed
30+
- Hide Metadata/Summary/Histogram/Layers output when `-x/-y` are provided.
31+
- Skip "Top 10 big tiles" output when `-x/-y` are provided.
32+
2333
## [0.4.2] - 2026-01-14
2434
### Changed
2535
- Improve inspect text output readability (summary list items, zoom table with percentages).

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "vt-optimizer-rs"
3-
version = "0.4.2"
3+
version = "0.4.3"
44
edition = "2024"
55
license = "MIT"
66
description = "A fast CLI to inspect and optimize MBTiles/PMTiles vector tiles."

docs/HOW_TO.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,38 @@ Notes:
2525
- `--fast` uses sampling to reduce runtime and output volume.
2626
- For machine-readable output, add `--output ndjson`.
2727

28+
### Inspect workflow and tips
29+
30+
1) Start with full inspect output to identify the heaviest zoom level:
31+
32+
```bash
33+
cargo run -- inspect "$MBTILES_PATH"
34+
```
35+
36+
- The `## Zoom` section shows total size by zoom. Pick the zoom level with the
37+
largest total size or max tile size for deeper inspection.
38+
39+
2) Drill into a zoom level and list the largest tiles:
40+
41+
```bash
42+
cargo run -- inspect "$MBTILES_PATH" --zoom 5
43+
```
44+
45+
- The `## Top 10 big tiles` section prints copy-pasteable arguments like
46+
`-z 5 -x 16 -y 20`, so you can inspect those tiles directly.
47+
48+
3) Inspect a specific tile to see which layers and properties dominate:
49+
50+
```bash
51+
cargo run -- inspect "$MBTILES_PATH" --zoom 5 -x 16 -y 20
52+
```
53+
54+
Tips:
55+
- When `-x/-y` are provided, output focuses on `## Tile Summary` for that tile.
56+
- If you need a smaller report, use `--stats` to select sections or `--fast`
57+
to sample.
58+
- Use `--output ndjson` when you want to script or diff results.
59+
2860
## Optimize
2961

3062
If the output file already exists, remove it first:

docs/RELEASE.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ Optional: create a local release branch name to mirror the target version:
3333
VERSION=0.2.0 BUMP_BRANCH=1 make bump-version
3434
```
3535

36+
## Changelog updates
37+
38+
- Always update `CHANGELOG.md` with user-visible changes before release.
39+
3640
## Notes
3741

3842
- Only maintainers should merge into `release`.

docs/SPEC.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,11 @@ v0.0.4 では以下を **含めない**。
556556
* `inspect` の text 出力で Zoom セクションをテーブル表示に変更(%tiles/%size/acc% 追加)
557557
* `inspect` の text 出力から Histogram by Zoom セクションを除外し、Histogram に注意書きを追加
558558

559+
## 1.66 マイルストーン(v0.4.3)
560+
561+
* `inspect` の text 出力に Top 10 big tiles セクションを追加
562+
* `inspect``-z/-x/-y` 指定時に Tile Summary を表示
563+
559564
## 2. 用語
560565

561566
* **Tile key**: `z/x/y`(内部表現は XYZ)

src/cli.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,17 @@ pub struct InspectArgs {
9292
pub no_progress: bool,
9393

9494
/// Limit inspection to a specific zoom level.
95-
#[arg(long)]
95+
#[arg(long, short = 'z')]
9696
pub zoom: Option<u8>,
9797

98+
/// Tile x (use with -z/--zoom and -y to show tile summary).
99+
#[arg(short = 'x')]
100+
pub x: Option<u32>,
101+
102+
/// Tile y (use with -z/--zoom and -x to show tile summary).
103+
#[arg(short = 'y')]
104+
pub y: Option<u32>,
105+
98106
/// Histogram bucket index (0-based) used with --list-tiles.
99107
#[arg(long)]
100108
pub bucket: Option<usize>,

src/main.rs

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use vt_optimizer::mbtiles::{
1313
};
1414
use vt_optimizer::output::{
1515
format_bytes, format_histogram_table, format_histograms_by_zoom_section,
16-
format_metadata_section, format_zoom_table, ndjson_lines, pad_left, pad_right,
17-
resolve_output_format,
16+
format_metadata_section, format_top_tiles_lines, format_zoom_table, ndjson_lines, pad_left,
17+
pad_right, resolve_output_format,
1818
};
1919
use vt_optimizer::pmtiles::{
2020
inspect_pmtiles_with_options, mbtiles_to_pmtiles, pmtiles_to_mbtiles, prune_pmtiles_layer_only,
@@ -220,6 +220,8 @@ fn main() -> Result<()> {
220220
stats: Some("tile_summary".to_string()),
221221
no_progress: false,
222222
zoom: None,
223+
x: None,
224+
y: None,
223225
bucket: None,
224226
tile: Some(format!("{}/{}/{}", z, x, y)),
225227
summary: true,
@@ -247,6 +249,8 @@ fn main() -> Result<()> {
247249
stats: None,
248250
no_progress: false,
249251
zoom: None,
252+
x: None,
253+
y: None,
250254
bucket: None,
251255
tile: None,
252256
summary: false,
@@ -284,14 +288,25 @@ fn run_inspect(args: vt_optimizer::cli::InspectArgs) -> Result<()> {
284288
Some(value) => Some(parse_sample_spec(value)?),
285289
None => None,
286290
};
287-
let tile = match args.tile.as_deref() {
291+
let mut tile = match args.tile.as_deref() {
288292
Some(value) => Some(parse_tile_spec(value)?),
289293
None => None,
290294
};
291-
if args.summary && tile.is_none() {
295+
if tile.is_some() && (args.x.is_some() || args.y.is_some()) {
296+
anyhow::bail!("--tile cannot be combined with -x/-y");
297+
}
298+
if tile.is_none() {
299+
if let (Some(z), Some(x), Some(y)) = (args.zoom, args.x, args.y) {
300+
tile = Some(vt_optimizer::mbtiles::TileCoord { zoom: z, x, y });
301+
} else if args.x.is_some() || args.y.is_some() {
302+
anyhow::bail!("-x/-y require -z/--zoom");
303+
}
304+
}
305+
let summary = args.summary || (tile.is_some() && args.tile.is_none() && args.x.is_some());
306+
if summary && tile.is_none() {
292307
anyhow::bail!("--summary requires --tile z/x/y");
293308
}
294-
if tile.is_some() && !args.summary {
309+
if tile.is_some() && !summary {
295310
anyhow::bail!("--tile requires --summary");
296311
}
297312
let mut layers = args.layers.clone();
@@ -307,7 +322,7 @@ fn run_inspect(args: vt_optimizer::cli::InspectArgs) -> Result<()> {
307322
} else {
308323
args.topn
309324
};
310-
let (sample, topn, histogram_buckets) = if args.fast {
325+
let (sample, mut topn, histogram_buckets) = if args.fast {
311326
(
312327
Some(vt_optimizer::mbtiles::SampleSpec::Ratio(0.1)),
313328
Some(5),
@@ -316,16 +331,20 @@ fn run_inspect(args: vt_optimizer::cli::InspectArgs) -> Result<()> {
316331
} else {
317332
(sample, topn, args.histogram_buckets as usize)
318333
};
334+
if output == ReportFormat::Text && topn.unwrap_or(0) == 0 {
335+
topn = Some(10);
336+
}
337+
let topn_value = topn.unwrap_or(0) as usize;
319338
let options = InspectOptions {
320339
sample,
321-
topn: topn.unwrap_or(0) as usize,
340+
topn: topn_value,
322341
histogram_buckets,
323342
no_progress: args.no_progress,
324343
max_tile_bytes: args.max_tile_bytes,
325344
zoom: args.zoom,
326345
bucket: args.bucket,
327346
tile,
328-
summary: args.summary,
347+
summary,
329348
layers,
330349
recommend: args.recommend,
331350
include_layer_list: output == ReportFormat::Text
@@ -390,26 +409,28 @@ fn run_inspect(args: vt_optimizer::cli::InspectArgs) -> Result<()> {
390409
let include_histogram_by_zoom = args.stats.is_some()
391410
&& stats_filter.includes(vt_optimizer::output::StatsSection::HistogramByZoom);
392411
let include_layers = stats_filter.includes(vt_optimizer::output::StatsSection::Layers);
412+
let hide_tile_summary_sections = args.x.is_some() && args.y.is_some();
393413
let include_recommendations =
394414
stats_filter.includes(vt_optimizer::output::StatsSection::Recommendations);
395415
let include_bucket = stats_filter.includes(vt_optimizer::output::StatsSection::Bucket);
396416
let include_bucket_tiles =
397417
stats_filter.includes(vt_optimizer::output::StatsSection::BucketTiles);
398-
let include_top_tiles =
399-
stats_filter.includes(vt_optimizer::output::StatsSection::TopTiles);
418+
let include_top_tiles = stats_filter
419+
.includes(vt_optimizer::output::StatsSection::TopTiles)
420+
&& !hide_tile_summary_sections;
400421
let include_top_tile_summaries =
401422
stats_filter.includes(vt_optimizer::output::StatsSection::TopTileSummaries);
402423
let include_tile_summary =
403424
stats_filter.includes(vt_optimizer::output::StatsSection::TileSummary);
404425
println!("{}", format_inspect_title(&args.input));
405426
println!();
406-
if include_metadata && !report.metadata.is_empty() {
427+
if include_metadata && !hide_tile_summary_sections && !report.metadata.is_empty() {
407428
for line in format_metadata_section(&report.metadata) {
408429
println!("{}", emphasize_section_heading(&line));
409430
}
410431
println!();
411432
}
412-
if include_summary {
433+
if include_summary && !hide_tile_summary_sections {
413434
println!("{}", emphasize_section_heading("## Summary"));
414435
println!(
415436
"{}",
@@ -490,21 +511,24 @@ fn run_inspect(args: vt_optimizer::cli::InspectArgs) -> Result<()> {
490511
);
491512
}
492513
}
493-
if include_histogram && !report.histogram.is_empty() {
514+
if include_histogram && !hide_tile_summary_sections && !report.histogram.is_empty() {
494515
println!();
495516
println!("{}", emphasize_section_heading("## Histogram"));
496517
for line in format_histogram_table(&report.histogram) {
497518
println!("{}", emphasize_table_header(&line));
498519
}
499520
}
500-
if include_histogram_by_zoom && !report.histograms_by_zoom.is_empty() {
521+
if include_histogram_by_zoom
522+
&& !hide_tile_summary_sections
523+
&& !report.histograms_by_zoom.is_empty()
524+
{
501525
println!();
502526
for line in format_histograms_by_zoom_section(&report.histograms_by_zoom) {
503527
let line = emphasize_section_heading(&line);
504528
println!("{}", emphasize_table_header(&line));
505529
}
506530
}
507-
if include_layers && !report.file_layers.is_empty() {
531+
if include_layers && !hide_tile_summary_sections && !report.file_layers.is_empty() {
508532
println!();
509533
println!("{}", emphasize_section_heading("## Layers"));
510534
let name_width = report
@@ -600,12 +624,12 @@ fn run_inspect(args: vt_optimizer::cli::InspectArgs) -> Result<()> {
600624
}
601625
if include_top_tiles && !report.top_tiles.is_empty() {
602626
println!();
603-
println!("{}", emphasize_section_heading("## Top Tiles"));
604-
for tile in report.top_tiles.iter() {
605-
println!(
606-
"- z={}: x={} y={} bytes={}",
607-
tile.zoom, tile.x, tile.y, tile.bytes
608-
);
627+
println!(
628+
"{}",
629+
emphasize_section_heading(&format!("## Top {} big tiles", topn_value))
630+
);
631+
for line in format_top_tiles_lines(&report.top_tiles) {
632+
println!("{}", line);
609633
}
610634
}
611635
if include_top_tile_summaries && !report.top_tile_summaries.is_empty() {

src/output.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use crate::cli::{ReportFormat, TileInfoFormat};
66
use std::collections::BTreeMap;
77

88
use crate::mbtiles::{
9-
FileLayerSummary, HistogramBucket, MbtilesReport, MbtilesZoomStats, TileSummary, ZoomHistogram,
9+
FileLayerSummary, HistogramBucket, MbtilesReport, MbtilesZoomStats, TileSummary, TopTile,
10+
ZoomHistogram,
1011
};
1112

1213
use std::collections::BTreeSet;
@@ -478,6 +479,21 @@ pub fn format_zoom_table(
478479
lines
479480
}
480481

482+
pub fn format_top_tiles_lines(tiles: &[TopTile]) -> Vec<String> {
483+
tiles
484+
.iter()
485+
.map(|tile| {
486+
format!(
487+
"-z {} -x {} -y {} size={}",
488+
tile.zoom,
489+
tile.x,
490+
tile.y,
491+
format_bytes(tile.bytes)
492+
)
493+
})
494+
.collect()
495+
}
496+
481497
pub fn format_tile_summary_text(summary: &TileSummary) -> Vec<String> {
482498
let label = |text: &str| Color::Blue.paint(text).to_string();
483499
vec![

0 commit comments

Comments
 (0)