Skip to content

Commit

Permalink
Added new weather 2D visualization + soil and veg funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
skalimoi committed May 4, 2024
1 parent cad0985 commit a90c641
Show file tree
Hide file tree
Showing 12 changed files with 493 additions and 412 deletions.
10 changes: 9 additions & 1 deletion src/hydro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,16 @@ pub fn erode_heightmap_full(file: &mut FileData, incremental_or_singular: bool)
if !incremental_or_singular {
let mut discharge_map = vec![0; 8192 * 8192];

let img: ImageBuffer<Luma<u16>, Vec<u16>> = ImageBuffer::from_raw(8192, 8192, file.clone().raw_full).unwrap();
let mut img: ImageBuffer<Luma<u16>, Vec<u16>> = ImageBuffer::default();

if file.raw_full.is_empty() {
let n: ImageBuffer<Luma<u16>, Vec<u16>> = ImageBuffer::from_raw(512, 512, file.clone().raw_map_512).unwrap();
img = image_crate::imageops::resize(&n, 8192, 8192, FilterType::CatmullRom);

} else {
let i: ImageBuffer<Luma<u16>, Vec<u16>> = ImageBuffer::from_raw(8192, 8192, file.clone().raw_full).unwrap();
img = i;
}
let heightmap = img.into_raw();

let mut erosion_world = World::new(
Expand Down
275 changes: 239 additions & 36 deletions src/main.rs

Large diffs are not rendered by default.

138 changes: 18 additions & 120 deletions src/soil/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ use crate::soil::hydrology::calculate_hydrology_map;
use crate::soil::insolation::calculate_actual_insolation;
use crate::soil::orography::calculate_normal_map;
use crate::soil::probabilities::calculate_probabilities;
use crate::soil_def::{VegetationCollection, VegetationMaps};


#[derive(Clone)]
#[derive(Clone, Serialize, Deserialize)]
pub struct GreyscaleImage<T> {
pub image: Vec<T>,
len: usize,
Expand Down Expand Up @@ -112,7 +112,7 @@ pub struct SunConfig {

pub struct SimArgs<'a> {
pub height_map: GreyscaleImage<f64>,
pub soil_ids_map: GreyscaleImage<u8>,
pub soil_ids_map: Vec<u8>,
pub soils: &'a HashMap<u8, Soil>,
pub sun_config: &'a SunConfig,
pub reflection_coefficient: f64,
Expand Down Expand Up @@ -160,18 +160,18 @@ impl SimConfig {
}
pub fn calculate_maps(
&self,
map_name: &str,
sun_config: &SunConfig,
reflection_coefficient: f64,
mapdata: &mut VegetationMaps
) {
let map = &self.maps;

let height_map_for_insolation = &map.height_map_path.clone();

let soil_ids_map = &map.texture_map_path.clone();
);

let sim_args = SimArgs {
height_map,
height_map: height_map_for_insolation.clone(),
soil_ids_map: soil_ids_map.clone(),
soils: &self.soil_ids,
sun_config,
Expand All @@ -186,8 +186,8 @@ impl SimConfig {
biom: &self.bioms[&map.biom],
};
let sim_args_for_insolation = SimArgs {
height_map: height_map_for_insolation,
soil_ids_map,
height_map: height_map_for_insolation.clone(),
soil_ids_map: soil_ids_map.clone(),
soils: &self.soil_ids,
sun_config,
reflection_coefficient,
Expand All @@ -201,59 +201,15 @@ impl SimConfig {
biom: &self.bioms[&map.biom],
};
let insolation_map = calculate_actual_insolation(&sim_args_for_insolation);
let insolation_buffer: ImageBuffer<Luma<u16>, Vec<u16>> = ImageBuffer::from_raw(1024, 1024, insolation_map.image.into_iter().map(
|x| {
x as u16
}
).collect()).unwrap();
let insolation_resampled = image_crate::imageops::resize(&insolation_buffer, 8192, 8192, image_crate::imageops::FilterType::Nearest);
let insolation_map = GreyscaleImage::new(
insolation_resampled.into_raw().into_iter().map(|x| {
x as f64
}).collect());
let orographic_map = calculate_normal_map(&sim_args);
let edaphic_map = calculate_soil_depth(&orographic_map, sim_args.map);
let hydrology_map = calculate_hydrology_map(&sim_args, &edaphic_map, &insolation_map);

mapdata.insolation = insolation_map;
mapdata.edaphology = edaphic_map;
mapdata.hydrology = hydrology_map;
mapdata.orography = orographic_map;
//std::fs::write("insolation_rust.json", serde_json::to_string(&insolation_map.image).unwrap()).unwrap();
let mut insolation_image = ImageBuffer::<Luma<u16>, Vec<u16>>::from_raw(
insolation_map.len() as u32,
insolation_map.len() as u32,
insolation_map.image.into_iter().map(|x| x as u16).collect(),
)
.unwrap();
//std::fs::write("edaphic_rust.json", serde_json::to_string(&edaphic_map.image).unwrap()).unwrap();
let mut edaphic_image = ImageBuffer::<Luma<u16>, Vec<u16>>::from_raw(
edaphic_map.len() as u32,
edaphic_map.len() as u32,
edaphic_map.image.into_iter().map(|x| x as u16).collect(),
)
.unwrap();
//std::fs::write("hydrology_rust.json", serde_json::to_string(&hydrology_map.image).unwrap()).unwrap();
let hydrology_image = ImageBuffer::<Luma<u16>, Vec<u16>>::from_raw(
hydrology_map.len() as u32,
hydrology_map.len() as u32,
hydrology_map.image.into_iter().map(|x| (x * 1000.0) as u16).collect(),
)
.unwrap();

// std::fs::create_dir_all(format!("data/vegetation_data/{map_name}")).unwrap();

insolation_image
.save(format!("insolation.png"))
.unwrap();
edaphic_image
.save(format!("edaphic.png"))
.unwrap();
hydrology_image
.save(format!("water.png"))
.unwrap();

std::fs::write(
format!("normals.json"),
serde_json::to_string(&orographic_map.image.into_iter().map(|x| [x.x, x.y, x.z]).collect::<Vec<_>>()).unwrap(),
)
.unwrap();

// let orographic_image = ImageBuffer::<Luma<u16>, Vec<u16>>::from_raw(
// orographic_map.len() as u32,
Expand All @@ -266,84 +222,26 @@ impl SimConfig {
// TODO: HACER STRUCT SOLO PARA ESTAS IMAGENES Y NO TENER QUE GUARDARLAS
// TODO: COMPROBAR EL TEMA IMAGEN SI LO COGE BIEN O NO
// TODO: TERMINAR DE CONFIGURAR SOIL_DEF.RS
pub fn calculate_probabilities(&self, map_name: &str, vegetation_names: &[&str], _daylight_hours: i32) {
let soil_ids_map = GreyscaleImage::new(
ImageReader::open(&self.maps.texture_map_path)
.unwrap()
.decode()
.unwrap()
.into_luma8()
.into_raw(),
);
let insolation_map = GreyscaleImage::new(
ImageReader::open("insolation.png".to_string())
.unwrap()
.decode()
.unwrap()
.into_luma16()
.into_raw()
.into_iter()
.map(|x| x as f64)
.collect(),
);
let edaphic_map = GreyscaleImage::new(
ImageReader::open("edaphic.png".to_string())
.unwrap()
.decode()
.unwrap()
.into_luma16()
.into_raw()
.into_iter()
.map(|x| x as f64)
.collect(),
);
let hydrology_map = GreyscaleImage::new(
ImageReader::open("water.png".to_string())
.unwrap()
.decode()
.unwrap()
.into_luma16()
.into_raw()
.into_iter()
.map(|x| x as f64 / 1000.0)
.collect(),
);
pub fn calculate_probabilities(&self, mapdata: &VegetationMaps, vegetation_names: &[&str], _daylight_hours: i32, vegetation_collection: &mut VegetationCollection) {
let soil_ids_map = GreyscaleImage::new(self.maps.texture_map_path.clone());

for vegetation in vegetation_names {
let probabilities_map = calculate_probabilities(
&self.vegetations[*vegetation],
&soil_ids_map,
&self.soil_names,
&insolation_map,
&edaphic_map,
&hydrology_map,
&mapdata.insolation,
&mapdata.edaphology,
&mapdata.hydrology,
);
//std::fs::write("probabilities_rust.json", serde_json::to_string(&probabilities_map.image).unwrap()).unwrap();
let mut probabilities_image = ImageBuffer::<Luma<u8>, Vec<u8>>::from_raw(
probabilities_map.len() as u32,
probabilities_map.len() as u32,
probabilities_map.image.into_iter().map(|x| (x * 1000.0) as u8).collect(),
)
.unwrap();
imageproc::contrast::stretch_contrast_mut(&mut probabilities_image, 100, 255);
probabilities_image
.save(format!("total_{}.png", vegetation))
.unwrap();
vegetation_collection.generated.insert(vegetation.clone().parse().unwrap(), probabilities_image.into_raw());
}


// let to_tiling = image_newest::io::Reader::open(format!("data/vegetation_data/height_map/{vegetation_name}_total.png")).unwrap().decode().unwrap();
// let brightened = imageproc::contrast::stretch_contrast(&to_tiling.into_luma8(), 0, 2);
// brightened.save(format!("data/vegetation_data/height_map/{vegetation_name}_equalized.png")).unwrap();
// let blur = imageproc::filter::gaussian_blur_f32(&brightened, 2.0);
// let resampled_blur = image_newest::imageops::resize(&blur, 8193, 8193, FilterType::Gaussian);
// let tile_size: usize = 513;
// for tile_x in 0..=15 {
// for tile_y in 0..=15 {
// let tile = image_newest::imageops::crop_imm(&resampled_blur, (tile_x * tile_size) as u32, (tile_y * tile_size) as u32, tile_size as u32, tile_size as u32);
// tile.to_image().save(format!("data/vegetation_data/height_map/{vegetation_name}_{tile_x}_{tile_y}.png")).unwrap();
// }
// }

}
}
6 changes: 5 additions & 1 deletion src/soil/hydrology.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use std::ops::Deref;
use image_crate::ImageBuffer;
use image_crate::Luma;
use crate::soil::config::{GreyscaleImage, SimArgs};

const K_CALORIES_NEEDED_TO_EVAPORATE_1_G_WATER: f64 = 0.54;
Expand All @@ -20,7 +23,8 @@ pub fn calculate_hydrology_map(
.into_iter()
.map(|y| {
(0..edaphic_map.len()).into_iter().map(move |x| {
let soil = &sim_args.soils[&sim_args.soil_ids_map[(x, y)]];
let soil_map: ImageBuffer<Luma<u8>, Vec<u8>> = ImageBuffer::from_raw(1024, 1024, sim_args.soil_ids_map.clone()).unwrap();
let soil = &sim_args.soils[&soil_map.get_pixel(x as u32, y as u32)[0]];
let depth_coefficient = (edaphic_map[(x, y)] / 100.0).min(1.0);
let water_supply = (sim_args.biom.groundwater + sim_args.biom.avg_rainfall_per_day)
* depth_coefficient
Expand Down
5 changes: 3 additions & 2 deletions src/soil/insolation.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use image_crate::{ImageBuffer, Luma};
use nalgebra::Vector3;
use crate::soil::config::{clamp_idx, GreyscaleImage, Map, round, SimArgs, Sun};

Expand Down Expand Up @@ -114,8 +115,8 @@ pub fn calculate_actual_insolation(sim_args: &SimArgs) -> GreyscaleImage<f64> {
let cloud_reflection_loss = pixel_raw_insolation * sim_args.biom.cloud_reflection / 100.0;
let atmospheric_absorption_loss = pixel_raw_insolation * sim_args.biom.atmospheric_absorption / 100.0;
let atmospheric_diffusion_loss = pixel_raw_insolation * sim_args.biom.atmospheric_diffusion / 100.0;
let soil = &sim_args.soils[&sim_args.soil_ids_map[(x, y)]];
insolation_map[(x, y)] =
let soil_map: ImageBuffer<Luma<u8>, Vec<u8>> = ImageBuffer::from_raw(1024, 1024, sim_args.soil_ids_map.clone()).unwrap();
let soil = &sim_args.soils[&soil_map.get_pixel(x as u32, y as u32)[0]]; insolation_map[(x, y)] =
(pixel_raw_insolation - cloud_reflection_loss - atmospheric_absorption_loss - atmospheric_diffusion_loss)
* (1.0 - soil.albedo)
}
Expand Down
Loading

0 comments on commit a90c641

Please sign in to comment.