use crate::error::{GeozeroError, Result};
use crate::feature_processor::FeatureProcessor;
use crate::property_processor::{
PropertyProcessor, PropertyReadType, PropertyReader, PropertyReaderIdx,
};
use crate::{CoordDimensions, GeomProcessor};
use std::collections::HashMap;
pub trait GeozeroGeometry {
fn process_geom<P: GeomProcessor>(&self, processor: &mut P) -> Result<()>
where
Self: Sized;
fn dims(&self) -> CoordDimensions {
CoordDimensions::xy()
}
fn srid(&self) -> Option<i32> {
None
}
}
pub trait GeozeroDatasource {
fn process<P: FeatureProcessor>(&mut self, processor: &mut P) -> Result<()>;
fn process_geom<P: GeomProcessor>(&mut self, processor: &mut P) -> Result<()> {
let mut geom_processor = DatasourceGeomProcessor(processor);
self.process(&mut geom_processor)
}
}
pub trait FeatureAccess: FeatureProperties + GeozeroGeometry {
fn process<P: FeatureProcessor>(&self, processor: &mut P, idx: u64) -> Result<()>
where
Self: Sized,
{
processor.feature_begin(idx)?;
processor.properties_begin()?;
let _ = self.process_properties(processor)?;
processor.properties_end()?;
processor.geometry_begin()?;
self.process_geom(processor)?;
processor.geometry_end()?;
processor.feature_end(idx)
}
}
pub trait FeatureProperties {
fn process_properties<P: PropertyProcessor>(&self, processor: &mut P) -> Result<bool>;
fn property<T: PropertyReadType>(&self, name: &str) -> Result<T> {
let mut reader = PropertyReader {
name,
value: Err(GeozeroError::ColumnNotFound),
};
self.process_properties(&mut reader)?;
reader.value
}
fn property_n<T: PropertyReadType>(&self, n: usize) -> Result<T> {
let mut reader = PropertyReaderIdx {
idx: n,
value: Err(GeozeroError::ColumnNotFound),
};
self.process_properties(&mut reader)?;
reader.value
}
fn properties(&self) -> Result<HashMap<String, String>> {
let mut properties = HashMap::new();
let _ = self.process_properties(&mut properties)?;
Ok(properties)
}
}
struct DatasourceGeomProcessor<'a, P: GeomProcessor>(&'a mut P);
impl<P: GeomProcessor> GeomProcessor for DatasourceGeomProcessor<'_, P> {
fn xy(&mut self, x: f64, y: f64, idx: usize) -> Result<()> {
self.0.xy(x, y, idx)
}
fn coordinate(
&mut self,
x: f64,
y: f64,
z: Option<f64>,
m: Option<f64>,
t: Option<f64>,
tm: Option<u64>,
idx: usize,
) -> Result<()> {
self.0.coordinate(x, y, z, m, t, tm, idx)
}
fn point_begin(&mut self, idx: usize) -> Result<()> {
self.0.point_begin(idx)
}
fn point_end(&mut self, idx: usize) -> Result<()> {
self.0.point_end(idx)
}
fn multipoint_begin(&mut self, size: usize, idx: usize) -> Result<()> {
self.0.multipoint_begin(size, idx)
}
fn multipoint_end(&mut self, idx: usize) -> Result<()> {
self.0.multipoint_end(idx)
}
fn linestring_begin(&mut self, tagged: bool, size: usize, idx: usize) -> Result<()> {
self.0.linestring_begin(tagged, size, idx)
}
fn linestring_end(&mut self, tagged: bool, idx: usize) -> Result<()> {
self.0.linestring_end(tagged, idx)
}
fn multilinestring_begin(&mut self, size: usize, idx: usize) -> Result<()> {
self.0.multilinestring_begin(size, idx)
}
fn multilinestring_end(&mut self, idx: usize) -> Result<()> {
self.0.multilinestring_end(idx)
}
fn polygon_begin(&mut self, tagged: bool, size: usize, idx: usize) -> Result<()> {
self.0.polygon_begin(tagged, size, idx)
}
fn polygon_end(&mut self, tagged: bool, idx: usize) -> Result<()> {
self.0.polygon_end(tagged, idx)
}
fn multipolygon_begin(&mut self, size: usize, idx: usize) -> Result<()> {
self.0.multipolygon_begin(size, idx)
}
fn multipolygon_end(&mut self, idx: usize) -> Result<()> {
self.0.multipolygon_end(idx)
}
fn circularstring_begin(&mut self, size: usize, idx: usize) -> Result<()> {
self.0.circularstring_begin(size, idx)
}
fn circularstring_end(&mut self, idx: usize) -> Result<()> {
self.0.circularstring_end(idx)
}
fn compoundcurve_begin(&mut self, size: usize, idx: usize) -> Result<()> {
self.0.compoundcurve_begin(size, idx)
}
fn compoundcurve_end(&mut self, idx: usize) -> Result<()> {
self.0.compoundcurve_end(idx)
}
fn curvepolygon_begin(&mut self, size: usize, idx: usize) -> Result<()> {
self.0.curvepolygon_begin(size, idx)
}
fn curvepolygon_end(&mut self, idx: usize) -> Result<()> {
self.0.curvepolygon_end(idx)
}
fn multicurve_begin(&mut self, size: usize, idx: usize) -> Result<()> {
self.0.multicurve_begin(size, idx)
}
fn multicurve_end(&mut self, idx: usize) -> Result<()> {
self.0.multicurve_end(idx)
}
fn multisurface_begin(&mut self, size: usize, idx: usize) -> Result<()> {
self.0.multisurface_begin(size, idx)
}
fn multisurface_end(&mut self, idx: usize) -> Result<()> {
self.0.multisurface_end(idx)
}
fn triangle_begin(&mut self, tagged: bool, size: usize, idx: usize) -> Result<()> {
self.0.triangle_begin(tagged, size, idx)
}
fn triangle_end(&mut self, tagged: bool, idx: usize) -> Result<()> {
self.0.triangle_end(tagged, idx)
}
fn polyhedralsurface_begin(&mut self, size: usize, idx: usize) -> Result<()> {
self.0.polyhedralsurface_begin(size, idx)
}
fn polyhedralsurface_end(&mut self, idx: usize) -> Result<()> {
self.0.polyhedralsurface_end(idx)
}
fn tin_begin(&mut self, size: usize, idx: usize) -> Result<()> {
self.0.tin_begin(size, idx)
}
fn tin_end(&mut self, idx: usize) -> Result<()> {
self.0.tin_end(idx)
}
}
impl<P: GeomProcessor> PropertyProcessor for DatasourceGeomProcessor<'_, P> {}
impl<P: GeomProcessor> FeatureProcessor for DatasourceGeomProcessor<'_, P> {}