Skip to content

Commit

Permalink
offset floors by 2, simple information=board impl
Browse files Browse the repository at this point in the history
  • Loading branch information
vfosnar committed Sep 22, 2024
1 parent cc92ac4 commit d512da2
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 30 deletions.
66 changes: 51 additions & 15 deletions src/data_processing.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
use colored::Colorize;
use crate::args::Args;
use crate::element_processing::{*};
use crate::element_processing::*;
use crate::osm_parser::ProcessedElement;
use crate::world_editor::WorldEditor;
use colored::Colorize;
use indicatif::{ProgressBar, ProgressStyle};
use reqwest::blocking::get;
use std::fs;
use std::io::Write;
use std::path::Path;

pub fn generate_world(elements: Vec<ProcessedElement>, args: &Args, scale_factor_x: f64, scale_factor_z: f64) {
pub fn generate_world(
elements: Vec<ProcessedElement>,
args: &Args,
scale_factor_x: f64,
scale_factor_z: f64,
) {
println!("{} {}", "[3/5]".bold(), "Processing data...");

let region_template_path: &str = "region.template";
let region_dir: String = format!("{}/region", args.path);
let ground_level: i32 = -62;
Expand All @@ -21,7 +26,13 @@ pub fn generate_world(elements: Vec<ProcessedElement>, args: &Args, scale_factor
let _ = download_region_template(region_template_path);
}

let mut editor: WorldEditor = WorldEditor::new(region_template_path, &region_dir, scale_factor_x, scale_factor_z, &args);
let mut editor: WorldEditor = WorldEditor::new(
region_template_path,
&region_dir,
scale_factor_x,
scale_factor_z,
&args,
);

// Process data
let process_pb: ProgressBar = ProgressBar::new(elements.len() as u64);
Expand All @@ -34,14 +45,19 @@ pub fn generate_world(elements: Vec<ProcessedElement>, args: &Args, scale_factor
process_pb.inc(1);

if args.debug {
process_pb.set_message(format!("(Element ID: {} / Type: {})", element.id, element.r#type));
process_pb.set_message(format!(
"(Element ID: {} / Type: {})",
element.id, element.r#type
));
} else {
process_pb.set_message("");
}

match element.r#type.as_str() {
"way" => {
if element.tags.contains_key("building") || element.tags.contains_key("building:part") {
if element.tags.contains_key("building")
|| element.tags.contains_key("building:part")
{
buildings::generate_buildings(&mut editor, element, ground_level);
} else if element.tags.contains_key("highway") {
highways::generate_highways(&mut editor, element, ground_level);
Expand All @@ -68,14 +84,18 @@ pub fn generate_world(elements: Vec<ProcessedElement>, args: &Args, scale_factor
"node" => {
if element.tags.contains_key("door") || element.tags.contains_key("entrance") {
doors::generate_doors(&mut editor, element, ground_level);
} else if element.tags.contains_key("natural") && element.tags.get("natural") == Some(&"tree".to_string()) {
} else if element.tags.contains_key("natural")
&& element.tags.get("natural") == Some(&"tree".to_string())
{
natural::generate_natural(&mut editor, element, ground_level);
} else if element.tags.contains_key("amenity") {
amenities::generate_amenities(&mut editor, element, ground_level);
} else if element.tags.contains_key("barrier") {
barriers::generate_barriers(&mut editor, element, ground_level);
} else if element.tags.contains_key("highway") {
highways::generate_highways(&mut editor, element, ground_level);
} else if element.tags.contains_key("tourism") {
tourisms::generate_tourisms(&mut editor, element, ground_level);
}
}
_ => {}
Expand All @@ -93,15 +113,31 @@ pub fn generate_world(elements: Vec<ProcessedElement>, args: &Args, scale_factor

println!("{} {}", "[4/5]".bold(), "Generating ground layer...");
let ground_pb: ProgressBar = ProgressBar::new(total_blocks);
ground_pb.set_style(ProgressStyle::default_bar()
.template("{spinner:.green} [{elapsed_precise}] [{bar:45}] {pos}/{len} blocks ({eta})")
.unwrap()
.progress_chars("█▓░"));
ground_pb.set_style(
ProgressStyle::default_bar()
.template("{spinner:.green} [{elapsed_precise}] [{bar:45}] {pos}/{len} blocks ({eta})")
.unwrap()
.progress_chars("█▓░"),
);

for x in 0..=(scale_factor_x as i32) {
for z in 0..=(scale_factor_z as i32) {
editor.set_block(&crate::block_definitions::GRASS_BLOCK, x, ground_level, z, None, None);
editor.set_block(&crate::block_definitions::DIRT, x, ground_level - 1, z, None, None);
editor.set_block(
&crate::block_definitions::GRASS_BLOCK,
x,
ground_level,
z,
None,
None,
);
editor.set_block(
&crate::block_definitions::DIRT,
x,
ground_level - 1,
z,
None,
None,
);

block_counter += 1;
if block_counter % batch_size == 0 {
Expand Down
6 changes: 3 additions & 3 deletions src/element_processing/buildings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ pub fn generate_buildings(editor: &mut WorldEditor, element: &ProcessedElement,
// Determine building height from tags
if let Some(levels_str) = element.tags.get("building:levels") {
if let Ok(levels) = levels_str.parse::<i32>() {
if levels >= 1 && (levels * 4) > building_height {
building_height = levels * 4;
if levels >= 1 && (levels * 4 + 2) > building_height {
building_height = levels * 4 + 2;
}
}
}
Expand Down Expand Up @@ -198,7 +198,7 @@ pub fn generate_buildings(editor: &mut WorldEditor, element: &ProcessedElement,

// Set level ceilings if height > 4
if building_height > 4 {
for h in (ground_level + 4..ground_level + building_height).step_by(4) {
for h in (ground_level + 2 + 4..ground_level + building_height).step_by(4) {
if x % 6 == 0 && z % 6 == 0 {
editor.set_block(&GLOWSTONE, x, h, z, None, None); // Light fixtures
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/element_processing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ pub mod landuse;
pub mod leisure;
pub mod natural;
pub mod railways;
pub mod tourisms;
pub mod tree;
pub mod waterways;
pub mod waterways;
42 changes: 42 additions & 0 deletions src/element_processing/tourisms.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use std::collections::HashMap;

use fastnbt::Value;

use crate::block_definitions::*;
use crate::osm_parser::ProcessedElement;
use crate::world_editor::WorldEditor;

pub fn generate_tourisms(editor: &mut WorldEditor, element: &ProcessedElement, ground_level: i32) {
// Skip if 'layer' or 'level' is negative in the tags
if let Some(layer) = element.tags.get("layer") {
if layer.parse::<i32>().unwrap_or(0) < 0 {
return;
}
}

if let Some(level) = element.tags.get("level") {
if level.parse::<i32>().unwrap_or(0) < 0 {
return;
}
}

if let Some(tourism_type) = element.tags.get("tourism") {
let first_node: Option<&(i32, i32)> = element.nodes.first();
match tourism_type.as_str() {
"information" => {
if let Some(information_type) = element.tags.get("information") {
match information_type.as_str() {
"board" => {
if let Some(&(x, z)) = first_node {
// TODO draw a sign
editor.set_block(&OAK_PLANKS, x, ground_level + 1, z, None, None);
}
}
_ => {}
}
}
}
_ => {}
}
}
}
31 changes: 21 additions & 10 deletions src/retrieve_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ fn download_with_reqwest(url: &str, query: &str) -> Result<String, Box<dyn std::
.timeout(Duration::from_secs(1800))
.build()?;

let response = client.get(url)
.query(&[("data", query)])
.send();
let response = client.get(url).query(&[("data", query)]).send();

match response {
Ok(resp) => {
Expand All @@ -25,10 +23,15 @@ fn download_with_reqwest(url: &str, query: &str) -> Result<String, Box<dyn std::
} else {
Err(format!("Error! Received response code: {}", resp.status()).into())
}
},
}
Err(e) => {
if e.is_timeout() {
eprintln!("{}", "Error! Request timed out. Try selecting a smaller area.".red().bold());
eprintln!(
"{}",
"Error! Request timed out. Try selecting a smaller area."
.red()
.bold()
);
} else {
eprintln!("{}", format!("Error! {}", e).red().bold());
}
Expand All @@ -40,7 +43,7 @@ fn download_with_reqwest(url: &str, query: &str) -> Result<String, Box<dyn std::
/// Function to download data using `curl`
fn download_with_curl(url: &str, query: &str) -> io::Result<String> {
let output: std::process::Output = Command::new("curl")
.arg("-s") // Add silent mode to suppress output
.arg("-s") // Add silent mode to suppress output
.arg(format!("{}?data={}", url, query))
.output()?;

Expand All @@ -54,7 +57,7 @@ fn download_with_curl(url: &str, query: &str) -> io::Result<String> {
/// Function to download data using `wget`
fn download_with_wget(url: &str, query: &str) -> io::Result<String> {
let output: std::process::Output = Command::new("wget")
.arg("-qO-") // Use `-qO-` to output the result directly to stdout
.arg("-qO-") // Use `-qO-` to output the result directly to stdout
.arg(format!("{}?data={}", url, query))
.output()?;

Expand Down Expand Up @@ -95,6 +98,7 @@ pub fn fetch_data(
nwr["leisure"];
nwr["waterway"];
nwr["amenity"];
nwr["tourism"];
nwr["bridge"];
nwr["railway"];
nwr["barrier"];
Expand Down Expand Up @@ -127,20 +131,27 @@ pub fn fetch_data(

let data: Value = serde_json::from_str(&response)?;

if data["elements"].as_array().map_or(0, |elements: &Vec<Value>| elements.len()) == 0 {
if data["elements"]
.as_array()
.map_or(0, |elements: &Vec<Value>| elements.len())
== 0
{
if let Some(remark) = data["remark"].as_str() {
// Check if the remark mentions memory or other runtime errors
if remark.contains("runtime error") && remark.contains("out of memory") {
eprintln!("{}", "Error! The query ran out of memory on the Overpass API server. Try using a smaller area.".red().bold());
} else {
// Handle other Overpass API errors if present in the remark field
eprintln!("{}", format!("Error! API returned: {}", remark).red().bold());
eprintln!(
"{}",
format!("Error! API returned: {}", remark).red().bold()
);
}
} else {
// General case for when there are no elements and no specific remark
eprintln!("{}", "Error! No data available.".red().bold());
}

if debug {
println!("Additional debug information: {}", data);
}
Expand Down
2 changes: 1 addition & 1 deletion src/world_editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl<'a> WorldEditor<'a> {
/// Sets a block of the specified type at the given coordinates.
pub fn set_block(
&mut self,
block: &'static Lazy<Block>,
block: &Lazy<Block>,
x: i32,
y: i32,
z: i32,
Expand Down

0 comments on commit d512da2

Please sign in to comment.