use js_sys::{Array, Float64Array, Object, Reflect};
use wasm_bindgen::prelude::*;
use crate::geometry::LayerGeometry;
use crate::layer::DecodedLayer;
use crate::properties::{build_prop_cache, prop_value_to_js};
#[wasm_bindgen]
pub struct MltTile {
pub(crate) layers: Vec<DecodedLayer>,
}
#[wasm_bindgen]
impl MltTile {
#[must_use]
pub fn layer_count(&self) -> usize {
self.layers.len()
}
#[must_use]
pub fn layer_name(&self, layer_idx: usize) -> String {
self.layers[layer_idx].tile.name().to_string()
}
#[must_use]
pub fn layer_extent(&self, layer_idx: usize) -> u32 {
self.layers[layer_idx].tile.extent().get()
}
#[must_use]
pub fn feature_count(&self, layer_idx: usize) -> usize {
self.layers[layer_idx].tile.features().len()
}
#[must_use]
pub fn layer_types(&self, layer_idx: usize) -> js_sys::Uint8Array {
self.layers[layer_idx].types_array.clone()
}
#[must_use]
pub fn layer_mlt_types(&self, layer_idx: usize) -> js_sys::Uint8Array {
self.layers[layer_idx].mlt_types_array.clone()
}
#[must_use]
pub fn layer_ids(&self, layer_idx: usize) -> Float64Array {
let features = self.layers[layer_idx].tile.features();
let floats: Vec<f64> = features
.iter()
.map(|f| {
#[expect(clippy::cast_precision_loss)]
f.id().map_or(f64::NAN, |v| v as f64)
})
.collect();
Float64Array::from(floats.as_slice())
}
#[must_use]
pub fn layer_geometry(&self, layer_idx: usize) -> LayerGeometry {
LayerGeometry::from_values(&self.layers[layer_idx].geometry)
}
pub fn layer_property_keys(&self, layer_idx: usize) -> Array {
let tile = &self.layers[layer_idx].tile;
build_prop_cache(tile).keys
}
pub fn layer_properties(&self, layer_idx: usize) -> Array {
let tile = &self.layers[layer_idx].tile;
build_prop_cache(tile).columns
}
#[must_use]
pub fn feature_properties(&self, layer_idx: usize, feature_idx: usize) -> Object {
let tile = &self.layers[layer_idx].tile;
let obj = Object::new();
if let Some(feature) = tile.features().get(feature_idx) {
for (name, val) in tile
.property_names()
.iter()
.zip(feature.properties().iter())
{
if let Some(js_val) = prop_value_to_js(val) {
let _ = Reflect::set(&obj, &JsValue::from_str(name), &js_val);
}
}
}
obj
}
}