use crate::{Feature, Projection};
pub trait Layer<TFeature: Feature>: Send + Sync
{
fn projection(&self) -> &Projection;
fn features<'a>(
&'a self,
rect: geo::Rect,
zoom_level: f64,
) -> Box<dyn Iterator<Item = ccutils::containers::RefOrValue<'a, TFeature>> + 'a>;
}
#[allow(type_alias_bounds)]
pub(crate) type BoxedLayer<TFeature: Feature> = Box<dyn Layer<TFeature>>;
pub struct FeaturesVecLayer<TFeature: Feature>
{
projection: Projection,
features: Vec<TFeature>,
}
impl<TFeature: Feature> FeaturesVecLayer<TFeature>
{
#[cfg(feature = "geojson")]
#[allow(clippy::result_large_err)]
pub fn read_from_geo_json<'de, T>(
feature_collection_reader: impl std::io::Read,
) -> geojson::Result<Self>
where
T: serde::Deserialize<'de> + Into<TFeature>,
{
let projection = Projection::wgs84();
let features =
geojson::de::deserialize_feature_collection_to_vec::<T>(feature_collection_reader)?;
let features = features.into_iter().map(|x| x.into()).collect();
Ok(Self {
projection,
features,
})
}
}
impl<TFeature: Feature> From<Vec<TFeature>> for FeaturesVecLayer<TFeature>
{
fn from(features: Vec<TFeature>) -> Self
{
Self {
projection: Projection::wgs84(),
features,
}
}
}
impl<TFeature, TVecElement> FromIterator<TVecElement> for FeaturesVecLayer<TFeature>
where
TFeature: Feature,
TVecElement: Into<TFeature>,
{
fn from_iter<T: IntoIterator<Item = TVecElement>>(iter: T) -> Self
{
Self {
projection: Projection::wgs84(),
features: iter.into_iter().map(Into::into).collect(),
}
}
}
impl<TFeature: Feature> Layer<TFeature> for FeaturesVecLayer<TFeature>
{
fn projection(&self) -> &Projection
{
&self.projection
}
fn features<'a>(
&'a self,
rect: geo::Rect,
_zoom_level: f64,
) -> Box<dyn Iterator<Item = crate::RefOrValue<'a, TFeature>> + 'a>
{
Box::new(
self
.features
.iter()
.filter(move |feat| feat.intersects(rect))
.map(Into::into),
)
}
}
pub trait IntoLayer<TFeature>
where
TFeature: Feature,
{
type Layer: Layer<TFeature>;
#[must_use]
fn into_layer(self) -> Self::Layer;
}
impl<TFeature, TOtherFeature> IntoLayer<TFeature> for Vec<TOtherFeature>
where
TFeature: From<TOtherFeature> + Feature,
{
type Layer = FeaturesVecLayer<TFeature>;
fn into_layer(self) -> Self::Layer
{
FeaturesVecLayer::from_iter(self.into_iter().map(Into::<TFeature>::into))
}
}