use extendr_api::prelude::*;
use crate::{vctrs::determine_geoms_class, Geom};
use geo_types::Geometry;
use std::{error::Error, result::Result};
pub fn sfc_to_rsgeo(x: List) -> Robj {
let mut rsgeo = List::new(x.len());
for (i, (_, obj)) in x.iter().enumerate() {
rsgeo.set_elt(i, sfg_to_rsgeo(obj)).unwrap();
}
let cls = determine_geoms_class(&rsgeo);
rsgeo.set_class(cls).unwrap().clone().into()
}
pub fn sfc_to_geometry(x: List) -> Vec<Option<Geometry>> {
x.into_iter()
.map(|(_, robj)| {
let geo = sfg_to_geom(robj);
match geo {
Ok(g) => Some(g.geom),
Err(_) => None,
}
})
.collect::<Vec<Option<Geometry>>>()
}
pub fn sfc_to_geoms(x: List) -> Vec<Option<Geom>> {
x.into_iter()
.map(|(_, robj)| {
let geo = sfg_to_geom(robj);
match geo {
Ok(g) => Some(g),
Err(_) => None,
}
})
.collect::<Vec<Option<Geom>>>()
}
pub fn sfg_to_geom(x: Robj) -> Result<Geom, Box<dyn Error>> {
let cls2 = x.class().unwrap().map(|x| x).collect::<Vec<&str>>();
let cls = cls2[1];
match cls {
"POINT" => {
let x = Doubles::try_from(x).unwrap();
Ok(geom_point(x[0].inner(), x[1].inner()).into())
}
"MULTIPOINT" => {
let x = RMatrix::try_from(&x).unwrap();
Ok(geom_multipoint(x).into())
}
"LINESTRING" => {
let x = RMatrix::try_from(&x).unwrap();
Ok(geom_linestring(x).into())
}
"MULTILINESTRING" => {
let x = List::try_from(x).unwrap();
Ok(geom_multilinestring(x).into())
}
"POLYGON" => {
let x = List::try_from(x).unwrap();
Ok(geom_polygon(x).into())
}
"MULTIPOLYGON" => {
let x = List::try_from(x).unwrap();
Ok(geom_multipolygon(x).into())
}
&_ => Err(format!("Null or unsupported geometry type").into()),
}
}
use crate::constructors::*;
#[extendr]
pub fn sfg_to_rsgeo(x: Robj) -> Robj {
let cls2 = x.class().unwrap().map(|x| x).collect::<Vec<&str>>();
let cls = cls2[1];
match cls {
"POINT" => {
let x = Doubles::try_from(x).unwrap();
geom_point(x[0].inner(), x[1].inner())
}
"MULTIPOINT" => {
let x = RMatrix::try_from(&x).unwrap();
geom_multipoint(x)
}
"LINESTRING" => {
let x = RMatrix::try_from(&x).unwrap();
geom_linestring(x)
}
"MULTILINESTRING" => {
let x = List::try_from(x).unwrap();
geom_multilinestring(x)
}
"POLYGON" => {
let x = List::try_from(x).unwrap();
geom_polygon(x)
}
"MULTIPOLYGON" => {
let x = List::try_from(x).unwrap();
geom_multipolygon(x)
}
&_ => Robj::from(NULL),
}
}