Skip to main content

cityjson_convert/
lib.rs

1#![allow(
2    clippy::manual_is_multiple_of,
3    clippy::needless_as_bytes,
4    clippy::needless_borrows_for_generic_args,
5    clippy::to_string_trait_impl,
6    clippy::too_many_arguments,
7    clippy::unnecessary_fallible_conversions,
8    clippy::unnecessary_to_owned,
9    clippy::unnecessary_unwrap,
10    clippy::useless_vec
11)]
12
13pub mod gltf_writer;
14mod proj;
15
16use std::collections::BTreeMap;
17use std::fs;
18use std::path::Path;
19
20use anyhow::Result;
21use cityjson_lib::CityModel;
22
23#[derive(Clone, Debug, Default)]
24pub enum GeometryPlacement {
25    #[default]
26    SourceCoordinates,
27    EcefRelative {
28        source_crs: String,
29        origin: [f64; 3],
30    },
31    Enu {
32        source_crs: String,
33        ecef_origin: [f64; 3],
34        east: [f64; 3],
35        north: [f64; 3],
36        up: [f64; 3],
37    },
38}
39
40#[derive(Clone, Debug)]
41pub struct GeographicClipRegion {
42    pub source_crs: String,
43    pub west: f64,
44    pub south: f64,
45    pub east: f64,
46    pub north: f64,
47}
48
49#[derive(Clone, Debug)]
50#[allow(clippy::struct_excessive_bools)]
51pub struct ExportOptions {
52    pub native_glb_color: String,
53    pub metadata_class_name: String,
54    pub feature_type_colors: BTreeMap<String, String>,
55    pub geometry_placement: GeometryPlacement,
56    pub clip_bbox: Option<[f64; 6]>,
57    pub clip_geographic_region: Option<GeographicClipRegion>,
58    pub smooth_normals: bool,
59    pub quantize_geometry: bool,
60    pub meshopt_compression: bool,
61}
62
63impl Default for ExportOptions {
64    fn default() -> Self {
65        Self {
66            native_glb_color: "#FFC0CB".to_string(),
67            metadata_class_name: "cityobject".to_string(),
68            feature_type_colors: BTreeMap::new(),
69            geometry_placement: GeometryPlacement::default(),
70            clip_bbox: None,
71            clip_geographic_region: None,
72            smooth_normals: false,
73            quantize_geometry: true,
74            meshopt_compression: true,
75        }
76    }
77}
78
79/// Converts a `CityJSON` model to a GLB file.
80///
81/// # Errors
82///
83/// Returns an error when the output directory cannot be created or GLB writing
84/// fails.
85pub fn convert_to_glb<P: AsRef<Path>>(
86    model: &CityModel,
87    output: P,
88    options: &ExportOptions,
89) -> Result<()> {
90    let output = output.as_ref();
91    if let Some(parent) = output.parent() {
92        fs::create_dir_all(parent)?;
93    }
94    gltf_writer::write_city_model_glb(model, output, options)
95}