Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
JayKickliter committed Jan 15, 2025
1 parent 4a45442 commit de6991a
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 12 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ members = [
"geopath",
"itm",
"nasadem",
"nasadem/zorderize",
"propah",
"terrain",
]
Expand Down
Binary file added data/nasadem/1arcsecond/N38W105.hgt
Binary file not shown.
32 changes: 20 additions & 12 deletions nasadem/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ impl SampleStore {
fn min(&self) -> i16 {
match self {
Self::Tombstone => 0,
Self::InMem(samples) => samples.iter().max().copied().unwrap(),
Self::InMem(samples) => samples.iter().min().copied().unwrap(),
Self::MemMap(raw) => (*raw)
.chunks_exact(2)
.map(|mut bytes| (&mut bytes).read_i16::<BE>().unwrap())
.max()
.min()
.unwrap(),
}
}
Expand Down Expand Up @@ -224,10 +224,15 @@ impl Tile {
}
}

/// Returns this tile's (x, y) dimensions.
pub fn dimensions(&self) -> (usize, usize) {
self.dimensions
}

/// Returns the number of samples in this tile.
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> usize {
let (x, y) = self.dimensions;
let (x, y) = self.dimensions();
x * y
}

Expand Down Expand Up @@ -261,9 +266,9 @@ impl Tile {
let (idx_x, idx_y) = self.coord_to_xy(coord);
#[allow(clippy::cast_possible_wrap)]
if 0 <= idx_x
&& idx_x < self.dimensions.0 as isize
&& idx_x < self.dimensions().0 as isize
&& 0 <= idx_y
&& idx_y < self.dimensions.1 as isize
&& idx_y < self.dimensions().1 as isize
{
#[allow(clippy::cast_sign_loss)]
let idx_1d = self.xy_to_linear_index((idx_x as usize, idx_y as usize));
Expand All @@ -283,7 +288,7 @@ impl Tile {

/// Returns and iterator over `self`'s grid squares.
pub fn iter(&self) -> impl Iterator<Item = Sample<'_>> + '_ {
(0..(self.dimensions.0 * self.dimensions.1)).map(|index| Sample { tile: self, index })
(0..(self.dimensions().0 * self.dimensions().1)).map(|index| Sample { tile: self, index })
}

/// Returns this tile's outline as a polygon.
Expand Down Expand Up @@ -326,13 +331,13 @@ impl Tile {
}

fn linear_index_to_xy(&self, idx: usize) -> (usize, usize) {
let y = idx / self.dimensions.0;
let x = idx % self.dimensions.1;
(x, self.dimensions.1 - 1 - y)
let y = idx / self.dimensions().0;
let x = idx % self.dimensions().1;
(x, self.dimensions().1 - 1 - y)
}

fn xy_to_linear_index(&self, (x, y): (usize, usize)) -> usize {
self.dimensions.0 * (self.dimensions.1 - y - 1) + x
self.dimensions().0 * (self.dimensions().1 - y - 1) + x
}

fn xy_to_polygon(&self, (x, y): (usize, usize)) -> Polygon<C> {
Expand Down Expand Up @@ -376,8 +381,11 @@ impl<'a> Sample<'a> {
}

pub fn polygon(&self) -> Polygon {
self.tile
.xy_to_polygon(self.tile.linear_index_to_xy(self.index))
self.tile.xy_to_polygon(self.index())
}

pub fn index(&self) -> (usize, usize) {
self.tile.linear_index_to_xy(self.index)
}
}

Expand Down
10 changes: 10 additions & 0 deletions nasadem/zorderize/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "zorderize"
version = "0.1.0"
edition = "2021"

[dependencies]
clap = { workspace = true }
glob = "0"
image = "0"
nasadem = { path = ".." }
60 changes: 60 additions & 0 deletions nasadem/zorderize/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use clap::Parser;
use image::{
imageops::{resize, FilterType},
ImageBuffer, Luma,
};
use nasadem::Tile;
use std::path::PathBuf;

#[derive(Debug, Parser)]
struct Cmd {
/// Source NASADEM hgt file.
tile: PathBuf,
/// Write output z-order tile to this directory.
dest: Option<PathBuf>,
}

fn tile_to_img(tile: &Tile) -> ImageBuffer<Luma<u16>, Vec<u16>> {
let (x_dim, y_dim) = tile.dimensions();
let mut img = ImageBuffer::new(x_dim as u32, y_dim as u32);
let min_elev = tile.min_elevation() as f32;
let max_elev = tile.max_elevation() as f32;
let scale = |m: i16| {
let m = m as f32;
(m - min_elev) / (max_elev - min_elev) * u16::MAX as f32
};
for sample in tile.iter() {
let (x, y) = sample.index();
let elev = sample.elevation();
let scaled_elev = scale(elev);
img.put_pixel(x as u32, (y_dim - 1 - y) as u32, Luma([scaled_elev as u16]))
}
img
}

fn scale_to_pow2(img: &ImageBuffer<Luma<u16>, Vec<u16>>) -> ImageBuffer<Luma<u16>, Vec<u16>> {
let (scaled_x, scaled_y) = match img.dimensions() {
(1201, 1201) => (1024, 1024),
(3601, 3601) => (2048, 2048),
other => panic!("dimensions {other:?} are not expected for SRTM data."),
};
resize(img, scaled_x, scaled_y, FilterType::Lanczos3)
}

fn main() {
let cli = Cmd::parse();
let tile = Tile::load(&cli.tile).unwrap();
let img = tile_to_img(&tile);
let scaled = scale_to_pow2(&img);
let out = cli.dest.unwrap_or_else(|| {
let mut out = cli.tile.clone();
if out.is_dir() {
let name = cli.tile.file_name().unwrap();
out.push(name);
} else {
out.set_extension("png");
}
out
});
scaled.save(out).unwrap();
}

0 comments on commit de6991a

Please sign in to comment.