Skip to content

Commit

Permalink
Output raw elevation data
Browse files Browse the repository at this point in the history
  • Loading branch information
JayKickliter committed Nov 26, 2023
1 parent 7c12bc9 commit 7c5d49c
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 74 deletions.
24 changes: 5 additions & 19 deletions hexit/src/combine.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::{
elevation::{CloseEnoughCompactor, Elevation, ReducedElevation},
elevation::{CloseEnoughCompactor, Elevation},
options::Combine,
progress,
};
use anyhow::Result;
use byteorder::{LittleEndian as LE, ReadBytesExt, WriteBytesExt};
use byteorder::{LittleEndian as LE, ReadBytesExt};
use flate2::bufread::GzDecoder;
use hextree::HexTreeMap;
use indicatif::MultiProgress;
Expand All @@ -21,7 +21,6 @@ impl Combine {
for tess_file_path in &self.input {
Self::read_tessellation(tess_file_path, &progress_group, &mut hextree)?;
}
let hextree = Self::reduce_hextree(&hextree, &progress_group);
self.write_disktree(&hextree, &progress_group)?;
Ok(())
}
Expand Down Expand Up @@ -57,20 +56,9 @@ impl Combine {
Ok(())
}

fn reduce_hextree(
hextree: &HexTreeMap<Elevation, CloseEnoughCompactor>,
_progress_group: &MultiProgress,
) -> HexTreeMap<ReducedElevation> {
let mut reduced_hextree = HexTreeMap::new();
for (cell, elev) in hextree.iter() {
reduced_hextree.insert(cell, elev.reduce());
}
reduced_hextree
}

fn write_disktree(
&self,
hextree: &HexTreeMap<ReducedElevation>,
hextree: &HexTreeMap<Elevation, CloseEnoughCompactor>,
progress_group: &MultiProgress,
) -> Result<()> {
let disktree_file = File::create(&self.out)?;
Expand All @@ -84,11 +72,9 @@ impl Combine {
format!("Writing {disktree_file_name}"),
disktree_len as u64,
));
hextree.to_disktree(disktree_file, |wtr, ReducedElevation { min, avg, max }| {
hextree.to_disktree(disktree_file, |wtr, elev| {
pb.inc(1);
wtr.write_i16::<LE>(*min)
.and_then(|()| wtr.write_i16::<LE>(*avg))
.and_then(|()| wtr.write_i16::<LE>(*max))
elev.to_writer(wtr)
})?;
Ok(())
}
Expand Down
77 changes: 38 additions & 39 deletions hexit/src/elevation.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,22 @@
use anyhow::Result;
use byteorder::{LittleEndian as LE, ReadBytesExt};
use byteorder::{LittleEndian as LE, ReadBytesExt, WriteBytesExt};
use hextree::{compaction::Compactor, Cell};
use std::io::Read;
use std::{
io::{Read, Write},
mem::size_of,
};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ReducedElevation {
pub min: i16,
pub avg: i16,
pub max: i16,
}

impl ReducedElevation {
pub fn from_reader<R: Read>(mut rdr: R) -> Result<Self> {
let mut buf = [0_u8; 3 * std::mem::size_of::<i16>()];
rdr.read_exact(&mut buf)?;
let rdr = &mut &buf[..];
let min = rdr.read_i16::<LE>()?;
let avg = rdr.read_i16::<LE>()?;
let max = rdr.read_i16::<LE>()?;
Ok(Self { min, avg, max })
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Elevation {
pub min: i16,
pub sum: i32,
pub max: i16,
pub n: usize,
pub sum: i32,
pub n: i32,
}

impl Elevation {
const BUF_LEN: usize =
size_of::<i16>() + size_of::<i16>() + size_of::<i32>() + size_of::<i32>();

pub fn new(raw: i16) -> Elevation {
Elevation {
min: raw,
Expand All @@ -40,32 +26,45 @@ impl Elevation {
}
}

pub fn reduce(&self) -> ReducedElevation {
let min = self.min;
let avg = i16::try_from(self.sum / i32::try_from(self.n).unwrap()).unwrap();
let max = self.max;
assert_ne!(min, i16::MIN);
assert_ne!(min, i16::MAX);
assert_ne!(max, i16::MIN);
assert_ne!(max, i16::MAX);
assert!(min <= avg && avg <= max);
ReducedElevation { min, avg, max }
pub fn from_reader<R: Read>(mut rdr: R) -> std::io::Result<Self> {
debug_assert_eq!(Self::BUF_LEN, size_of::<Elevation>());
let mut buf = [0_u8; Self::BUF_LEN];
rdr.read_exact(&mut buf)?;
let rdr = &mut &buf[..];
let min = rdr.read_i16::<LE>()?;
let max = rdr.read_i16::<LE>()?;
let sum = rdr.read_i32::<LE>()?;
let n = rdr.read_i32::<LE>()?;
Ok(Self { min, max, sum, n })
}

pub fn to_writer<W: Write>(&self, mut wtr: W) -> std::io::Result<()> {
assert_eq!(Self::BUF_LEN, size_of::<Elevation>());
let mut buf = [0_u8; Self::BUF_LEN];
{
let mut buf_wtr = &mut buf[..];
buf_wtr.write_i16::<LE>(self.min)?;
buf_wtr.write_i16::<LE>(self.max)?;
buf_wtr.write_i32::<LE>(self.sum)?;
buf_wtr.write_i32::<LE>(self.n)?;
}
wtr.write_all(&buf)
}
}

impl Elevation {
pub fn concat(items: &[Self]) -> Self {
pub fn concat(items: &[&Self]) -> Self {
let mut min = i16::MAX;
let mut sum: i32 = 0;
let mut max = i16::MIN;
let mut n = 0_usize;
let mut n = 0_i32;
for item in items {
sum += item.sum;
min = i16::min(min, item.min);
max = i16::max(max, item.max);
n += item.n;
}
Elevation { min, sum, max, n }
Elevation { min, max, sum, n }
}
}

Expand All @@ -81,7 +80,7 @@ impl Compactor<Elevation> for ReductionCompactor {
} else if let [Some(v0), Some(v1), Some(v2), Some(v3), Some(v4), Some(v5), Some(v6)] =
children
{
Some(Elevation::concat(&[*v0, *v1, *v2, *v3, *v4, *v5, *v6]))
Some(Elevation::concat(&[v0, v1, v2, v3, v4, v5, v6]))
} else {
None
}
Expand Down
36 changes: 22 additions & 14 deletions hexit/src/json.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{elevation::ReducedElevation, mask, options::Json};
use crate::{elevation::Elevation, mask, options::Json};
use anyhow::Result;
use geo::geometry::GeometryCollection;
use h3o::{
Expand All @@ -7,7 +7,7 @@ use h3o::{
};
use hextree::{disktree::DiskTree, Cell, HexTreeMap};
use serde::Serialize;
use serde_json::{json, Value};
use serde_json::Value;
use std::fs::File;

impl Json {
Expand All @@ -22,7 +22,7 @@ impl Json {
hextree.insert(cell, reduction);
}
}
let json = Self::gen_json(&hextree);
let json = Self::gen_json(&hextree)?;
Self::output_json(&json)?;
Ok(())
}
Expand All @@ -38,40 +38,48 @@ impl Json {
Ok(cells)
}

fn get(cell: Cell, disktree: &mut DiskTree<File>) -> Result<Option<(Cell, ReducedElevation)>> {
fn get(cell: Cell, disktree: &mut DiskTree<File>) -> Result<Option<(Cell, Elevation)>> {
match disktree.seek_to_cell(cell)? {
None => Ok(None),
Some((cell, rdr)) => {
let reduction = ReducedElevation::from_reader(rdr)?;
let reduction = Elevation::from_reader(rdr)?;
Ok(Some((cell, reduction)))
}
}
}

fn gen_json(hextree: &HexTreeMap<ReducedElevation>) -> Value {
fn gen_json(hextree: &HexTreeMap<Elevation>) -> Result<Value> {
#[derive(Serialize)]
struct JsonEntry {
h3_id: String,
min: i16,
avg: i16,
sum: i32,
max: i16,
n: i32,
}
impl From<(Cell, &ReducedElevation)> for JsonEntry {
fn from((cell, reduction): (Cell, &ReducedElevation)) -> JsonEntry {
impl From<(Cell, &Elevation)> for JsonEntry {
fn from((cell, elev): (Cell, &Elevation)) -> JsonEntry {
JsonEntry {
avg: i16::try_from(elev.sum / elev.n).unwrap(),
h3_id: cell.to_string(),
min: reduction.min,
avg: reduction.avg,
max: reduction.max,
max: elev.max,
min: elev.min,
n: elev.n,
sum: elev.sum,
}
}
}
let samples = hextree.iter().map(JsonEntry::from).collect::<Vec<_>>();
json!(samples)
let samples = hextree
.iter()
.map(JsonEntry::from)
.map(serde_json::to_value)
.collect::<Result<Vec<Value>, _>>()?;
Ok(Value::Array(samples))
}

fn output_json(json: &Value) -> Result<()> {
let out = std::io::stdout();
let out = std::io::stdout().lock();
serde_json::to_writer(out, json)?;
Ok(())
}
Expand Down
6 changes: 4 additions & 2 deletions hexit/src/lookup.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{elevation::ReducedElevation, options::Lookup};
use crate::{elevation::Elevation, options::Lookup};
use anyhow::Result;
use hextree::{disktree::DiskTree, Cell};
use std::fs::File;
Expand All @@ -21,11 +21,13 @@ impl Lookup {
None => (),
Some((cell, rdr)) => {
let t_seek = t0.elapsed();
let ReducedElevation { min, avg, max } = ReducedElevation::from_reader(rdr)?;
let Elevation { min, max, sum, n } = Elevation::from_reader(rdr)?;
let avg = sum / n;
println!("cell: {cell} (res {})", cell.res());
println!("min: {min}");
println!("avg: {avg}");
println!("max: {max}");
println!("n: {n}");
println!("seek: {t_seek:?}");
}
}
Expand Down

0 comments on commit 7c5d49c

Please sign in to comment.