use geometry_coords::CoordinateScalar;
use geometry_cs::{CartesianFamily, CoordinateSystem};
use geometry_model::{Box, DynGeometry, DynKind, Linestring, Point, Polygon};
use geometry_strategy::{EnvelopeStrategy, EnvelopeStrategyForKind};
use geometry_tag::{
LinestringTag, MultiLinestringTag, MultiPointTag, MultiPolygonTag, PointTag, PolygonTag, SameAs,
};
use crate::dyn_error::DynKindMismatch;
use crate::envelope::envelope;
const SUPPORTED: &[&[DynKind]] = &[
&[DynKind::Point],
&[DynKind::LineString],
&[DynKind::Polygon],
&[DynKind::MultiPoint],
&[DynKind::MultiLineString],
&[DynKind::MultiPolygon],
];
pub fn envelope_dyn<S, Cs>(g: &DynGeometry<S, Cs>) -> Result<Box<Point<S, 2, Cs>>, DynKindMismatch>
where
S: CoordinateScalar,
Cs: CoordinateSystem,
Cs::Family: SameAs<CartesianFamily>,
<PointTag as EnvelopeStrategyForKind>::S:
EnvelopeStrategy<Point<S, 2, Cs>, Output = Box<Point<S, 2, Cs>>>,
<LinestringTag as EnvelopeStrategyForKind>::S:
EnvelopeStrategy<Linestring<Point<S, 2, Cs>>, Output = Box<Point<S, 2, Cs>>>,
<PolygonTag as EnvelopeStrategyForKind>::S:
EnvelopeStrategy<Polygon<Point<S, 2, Cs>>, Output = Box<Point<S, 2, Cs>>>,
<MultiPointTag as EnvelopeStrategyForKind>::S: EnvelopeStrategy<geometry_model::MultiPoint<Point<S, 2, Cs>>, Output = Box<Point<S, 2, Cs>>>,
<MultiLinestringTag as EnvelopeStrategyForKind>::S: EnvelopeStrategy<
geometry_model::MultiLinestring<Linestring<Point<S, 2, Cs>>>,
Output = Box<Point<S, 2, Cs>>,
>,
<MultiPolygonTag as EnvelopeStrategyForKind>::S: EnvelopeStrategy<
geometry_model::MultiPolygon<Polygon<Point<S, 2, Cs>>>,
Output = Box<Point<S, 2, Cs>>,
>,
{
use DynGeometry::{
GeometryCollection, LineString, MultiLineString, MultiPoint, MultiPolygon,
Point as PointArm, Polygon as PolygonArm,
};
match g {
PointArm(p) => Ok(envelope(p)),
LineString(ls) => Ok(envelope(ls)),
PolygonArm(pg) => Ok(envelope(pg)),
MultiPoint(mp) => Ok(envelope(mp)),
MultiLineString(ml) => Ok(envelope(ml)),
MultiPolygon(mpg) => Ok(envelope(mpg)),
GeometryCollection(_) => Err(DynKindMismatch {
got: alloc::vec![g.kind()],
expected: SUPPORTED,
}),
}
}