mapserver: unzoom
This commit is contained in:
parent
7aa17e3de3
commit
c40541963f
@ -25,7 +25,6 @@ impl Default for Config {
|
|||||||
mapper_threads: 4,
|
mapper_threads: 4,
|
||||||
minetestmapper_args: vec![
|
minetestmapper_args: vec![
|
||||||
String::from("--drawalpha"),
|
String::from("--drawalpha"),
|
||||||
String::from("--noemptyimage"),
|
|
||||||
String::from("--max-y"),
|
String::from("--max-y"),
|
||||||
String::from("2000"),
|
String::from("2000"),
|
||||||
String::from("--colors"),
|
String::from("--colors"),
|
||||||
|
@ -10,6 +10,7 @@ use tide::Request;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Error {
|
enum Error {
|
||||||
|
Image(image::ImageError),
|
||||||
Io(std::io::Error),
|
Io(std::io::Error),
|
||||||
Minetestmapper,
|
Minetestmapper,
|
||||||
Todo,
|
Todo,
|
||||||
@ -114,10 +115,56 @@ fn generate_tile(
|
|||||||
drop(tasks_guard);
|
drop(tasks_guard);
|
||||||
|
|
||||||
let res: Result<(), Error> = try {
|
let res: Result<(), Error> = try {
|
||||||
if z == config.zoom_default {
|
match z.cmp(&config.zoom_default) {
|
||||||
run_minetestmapper(z, x, y, tile_dir, tile_path, config)?;
|
std::cmp::Ordering::Equal => {
|
||||||
} else {
|
run_minetestmapper(z, x, y, tile_dir, tile_path, config)?
|
||||||
Err(Error::Todo)?;
|
}
|
||||||
|
std::cmp::Ordering::Less => {
|
||||||
|
let tile1_path =
|
||||||
|
get_dep_tile(z + 1, x * 2, y * 2, tasks.clone(), config.clone())?;
|
||||||
|
let tile2_path = get_dep_tile(
|
||||||
|
z + 1,
|
||||||
|
x * 2,
|
||||||
|
y * 2 + 1,
|
||||||
|
tasks.clone(),
|
||||||
|
config.clone(),
|
||||||
|
)?;
|
||||||
|
let tile3_path = get_dep_tile(
|
||||||
|
z + 1,
|
||||||
|
x * 2 + 1,
|
||||||
|
y * 2,
|
||||||
|
tasks.clone(),
|
||||||
|
config.clone(),
|
||||||
|
)?;
|
||||||
|
let tile4_path = get_dep_tile(
|
||||||
|
z + 1,
|
||||||
|
x * 2 + 1,
|
||||||
|
y * 2 + 1,
|
||||||
|
tasks.clone(),
|
||||||
|
config.clone(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let tile1 = image::open(tile1_path).map_err(Error::Image)?.into_rgb8();
|
||||||
|
let tile2 = image::open(tile2_path).map_err(Error::Image)?.into_rgb8();
|
||||||
|
let tile3 = image::open(tile3_path).map_err(Error::Image)?.into_rgb8();
|
||||||
|
let tile4 = image::open(tile4_path).map_err(Error::Image)?.into_rgb8();
|
||||||
|
|
||||||
|
let mut tile = image::ImageBuffer::<image::Rgb<u8>, Vec<u8>>::new(
|
||||||
|
config.tile_size as u32 * 2,
|
||||||
|
config.tile_size as u32 * 2,
|
||||||
|
);
|
||||||
|
image::imageops::replace(&mut tile, &tile1, 0, 0);
|
||||||
|
image::imageops::replace(&mut tile, &tile2, 0, config.tile_size as i64);
|
||||||
|
image::imageops::replace(&mut tile, &tile3, config.tile_size as i64, 0);
|
||||||
|
image::imageops::replace(
|
||||||
|
&mut tile,
|
||||||
|
&tile4,
|
||||||
|
config.tile_size as i64,
|
||||||
|
config.tile_size as i64,
|
||||||
|
);
|
||||||
|
tile.save(tile_path).map_err(Error::Image)?;
|
||||||
|
}
|
||||||
|
std::cmp::Ordering::Greater => Err(Error::Todo)?,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -132,6 +179,44 @@ fn generate_tile(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_dep_tile(
|
||||||
|
z: i32,
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
tasks: Arc<RwLock<HashMap<(i32, i32, i32), Sender<()>>>>,
|
||||||
|
config: Arc<config::Config>,
|
||||||
|
) -> Result<String, Error> {
|
||||||
|
let tile_dir = format!("{}{}/{}", config.output_path, z, x);
|
||||||
|
let tile_path = format!("{}/{}.png", tile_dir, y);
|
||||||
|
|
||||||
|
match std::fs::metadata(&tile_path) {
|
||||||
|
Ok(metadata) => match metadata.modified() {
|
||||||
|
Ok(modified_time) => {
|
||||||
|
if SystemTime::now()
|
||||||
|
.duration_since(modified_time)
|
||||||
|
.unwrap()
|
||||||
|
.as_secs() > config.cache_age
|
||||||
|
{
|
||||||
|
generate_tile(z, x, y, &tile_dir, &tile_path, tasks, config)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
warn!("Cannot get modified time of `{}`: {}", tile_path, e);
|
||||||
|
generate_tile(z, x, y, &tile_dir, &tile_path, tasks, config)?;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
if e.kind() == std::io::ErrorKind::NotFound {
|
||||||
|
debug!("Tile not found `{}`", tile_path);
|
||||||
|
} else {
|
||||||
|
warn!("Cannot get metadata of `{}`: {}", tile_path, e);
|
||||||
|
}
|
||||||
|
generate_tile(z, x, y, &tile_dir, &tile_path, tasks, config)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(tile_path)
|
||||||
|
}
|
||||||
|
|
||||||
fn resp_tile(
|
fn resp_tile(
|
||||||
z: i32,
|
z: i32,
|
||||||
x: i32,
|
x: i32,
|
||||||
@ -151,6 +236,11 @@ async fn req_tile(
|
|||||||
config: Arc<config::Config>,
|
config: Arc<config::Config>,
|
||||||
) -> tide::Result {
|
) -> tide::Result {
|
||||||
let z: i32 = req.param("z")?.parse()?;
|
let z: i32 = req.param("z")?.parse()?;
|
||||||
|
|
||||||
|
if z > config.zoom_max || z < config.zoom_min {
|
||||||
|
return Ok(tide::StatusCode::Forbidden.into());
|
||||||
|
}
|
||||||
|
|
||||||
let x: i32 = req.param("x")?.parse()?;
|
let x: i32 = req.param("x")?.parse()?;
|
||||||
let y = req.param("y")?;
|
let y = req.param("y")?;
|
||||||
let y = y.strip_suffix(".png").unwrap_or(y).parse()?;
|
let y = y.strip_suffix(".png").unwrap_or(y).parse()?;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user