use std::path::Path;
use std::process::ExitCode;
use geopackage::core::tiles::{TileCoord, probe};
use geopackage::{GeoPackage, TilePyramid};
use crate::error::Result;
pub fn info(path: &Path, pyramid_name: Option<&str>) -> Result<ExitCode> {
let gpkg = GeoPackage::open_read_only_lenient(path)?;
let pyramids = match pyramid_name {
Some(name) => vec![gpkg.tiles(name)?],
None => gpkg.tile_pyramids()?,
};
if pyramids.is_empty() {
println!("{}: no tile pyramids", path.display());
return Ok(ExitCode::SUCCESS);
}
for pyramid in &pyramids {
print_pyramid(&gpkg, pyramid)?;
}
Ok(ExitCode::SUCCESS)
}
fn print_pyramid(gpkg: &GeoPackage, pyramid: &TilePyramid<'_>) -> Result<()> {
let set = pyramid.matrix_set();
println!("tiles {:?}", pyramid.table_name());
println!(" tiles: {}", pyramid.tile_count()?);
if let Some(srs) = gpkg.srs(set.srs_id)? {
println!(
" srs: {} ({}:{})",
srs.name, srs.organization, srs.organization_coordsys_id
);
}
println!(
" extent: {} {} {} {}",
set.min_x, set.min_y, set.max_x, set.max_y
);
if let Some(blocking) = pyramid.blocking_extension() {
println!(
" blocked: writes refused by extension {:?}",
blocking.name
);
}
println!(" zoom levels:");
for matrix in pyramid.matrices() {
println!(
" {:<3} {:>6} x {:<6} grid, {} x {} px, {} stored",
matrix.zoom_level,
matrix.matrix_width,
matrix.matrix_height,
matrix.tile_width,
matrix.tile_height,
pyramid.tile_count_at(matrix.zoom_level)?
);
}
Ok(())
}
pub fn get(
path: &Path,
pyramid_name: &str,
coord: TileCoord,
out: Option<&Path>,
) -> Result<ExitCode> {
let gpkg = GeoPackage::open_read_only_lenient(path)?;
let pyramid = gpkg.tiles(pyramid_name)?;
let Some(bytes) = pyramid.get_tile(coord)? else {
eprintln!(
"gpkg: no tile at {}/{}/{} in {pyramid_name}",
coord.zoom_level, coord.column, coord.row
);
return Ok(ExitCode::FAILURE);
};
match out {
Some(out) => {
std::fs::write(out, &bytes)?;
let described = match probe(&bytes) {
Ok(payload) => format!("{:?} {}x{}", payload.format, payload.width, payload.height),
Err(_) => "unrecognised payload".to_owned(),
};
println!(
"wrote {} bytes to {} ({described})",
bytes.len(),
out.display()
);
}
None => {
use std::io::Write;
std::io::stdout().write_all(&bytes)?;
}
}
Ok(ExitCode::SUCCESS)
}