use oxigdal_core::vector::{Coordinate, Geometry, LineString, Polygon};
use oxigdal_shapefile::ShapefileFeature;
use oxigdal_shapefile::shp::shapes::ShapeType;
use oxigdal_shapefile::writer::{ShapefileSchemaBuilder, ShapefileWriter};
use std::collections::HashMap;
use std::path::PathBuf;
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Creating test Shapefile samples...\n");
create_golden_triangle()?;
create_iron_belt()?;
println!("\n✅ All Shapefile samples created successfully!");
println!("Files ready for use in COG viewer at http://localhost:8080/");
Ok(())
}
fn create_golden_triangle() -> Result<(), Box<dyn std::error::Error>> {
println!("Creating Golden Triangle Shapefile...");
let center_lon = 100.08466749884738;
let center_lat = 20.35223590060906;
let output_path = PathBuf::from("demo/cog-viewer/golden-triangle");
let schema = ShapefileSchemaBuilder::new()
.add_character_field("NAME", 50)?
.add_character_field("TYPE", 30)?
.add_numeric_field("AREA_KM2", 10, 2)?
.build();
let mut writer = ShapefileWriter::new(&output_path, ShapeType::Polygon, schema)?;
let offset = 0.5; let exterior_coords = vec![
Coordinate::new_2d(center_lon, center_lat + offset), Coordinate::new_2d(center_lon - offset, center_lat - offset / 2.0), Coordinate::new_2d(center_lon + offset, center_lat - offset / 2.0), Coordinate::new_2d(center_lon, center_lat + offset), ];
let exterior = LineString::new(exterior_coords)?;
let polygon_geom = Polygon::new(exterior, vec![])?;
let mut attributes = HashMap::new();
attributes.insert(
"NAME".to_string(),
oxigdal_core::vector::FieldValue::String("Golden Triangle".to_string()),
);
attributes.insert(
"TYPE".to_string(),
oxigdal_core::vector::FieldValue::String("Geographic Region".to_string()),
);
attributes.insert(
"AREA_KM2".to_string(),
oxigdal_core::vector::FieldValue::Float(12500.0),
);
let feature = ShapefileFeature::new(1, Some(Geometry::Polygon(polygon_geom)), attributes);
writer.write_features(&[feature])?;
println!(" ✅ Created Golden Triangle Shapefile");
println!(" - {}.shp", output_path.display());
println!(" - {}.shx", output_path.display());
println!(" - {}.dbf", output_path.display());
println!(" 📍 Center: {:.6}, {:.6}", center_lat, center_lon);
Ok(())
}
fn create_iron_belt() -> Result<(), Box<dyn std::error::Error>> {
println!("\nCreating Basque Country Shapefile...");
let center_lon = -2.9253;
let center_lat = 43.2630;
let output_path = PathBuf::from("demo/cog-viewer/iron-belt");
let schema = ShapefileSchemaBuilder::new()
.add_character_field("NAME", 50)?
.add_character_field("TYPE", 30)?
.add_character_field("MINE_TYPE", 20)?
.add_numeric_field("YIELD_MT", 10, 2)?
.build();
let mut writer = ShapefileWriter::new(&output_path, ShapeType::Polygon, schema)?;
let zones = [
("Bilbao Zone", -2.93, 43.26, 950.0),
("Vitoria Zone", -2.68, 42.85, 720.0),
("Pamplona Zone", -1.64, 42.82, 580.0),
];
let mut features = Vec::new();
for (idx, (name, lon, lat, yield_mt)) in zones.iter().enumerate() {
let size = 0.3; let exterior_coords = vec![
Coordinate::new_2d(*lon - size / 2.0, *lat + size / 2.0),
Coordinate::new_2d(*lon + size / 2.0, *lat + size / 2.0),
Coordinate::new_2d(*lon + size / 2.0, *lat - size / 2.0),
Coordinate::new_2d(*lon - size / 2.0, *lat - size / 2.0),
Coordinate::new_2d(*lon - size / 2.0, *lat + size / 2.0), ];
let exterior = LineString::new(exterior_coords)?;
let polygon_geom = Polygon::new(exterior, vec![])?;
let mut attributes = HashMap::new();
attributes.insert(
"NAME".to_string(),
oxigdal_core::vector::FieldValue::String(name.to_string()),
);
attributes.insert(
"TYPE".to_string(),
oxigdal_core::vector::FieldValue::String("Mining Zone".to_string()),
);
attributes.insert(
"MINE_TYPE".to_string(),
oxigdal_core::vector::FieldValue::String("Iron".to_string()),
);
attributes.insert(
"YIELD_MT".to_string(),
oxigdal_core::vector::FieldValue::Float(*yield_mt),
);
let feature = ShapefileFeature::new(
(idx + 1) as i32,
Some(Geometry::Polygon(polygon_geom)),
attributes,
);
features.push(feature);
}
writer.write_features(&features)?;
println!(
" ✅ Created Basque Country Shapefile with {} mining zones",
zones.len()
);
println!(" - {}.shp", output_path.display());
println!(" - {}.shx", output_path.display());
println!(" - {}.dbf", output_path.display());
println!(" 📍 Center: {:.6}, {:.6}", center_lat, center_lon);
Ok(())
}