use crate::{Geometry, MultiPolygon, Polygon, Ring};
use geo_types as gt;
fn ring_to_ls(ring: &Ring) -> gt::LineString<f64> {
gt::LineString(ring.iter().map(|&[x, y]| gt::Coord { x, y }).collect())
}
fn ls_to_ring(ls: >::LineString<f64>) -> Ring {
ls.0.iter().map(|c| [c.x, c.y]).collect()
}
fn poly_to_gt(p: &Polygon) -> gt::Polygon<f64> {
let mut rings = p.iter();
let exterior = rings
.next()
.map(ring_to_ls)
.unwrap_or_else(|| gt::LineString(Vec::new()));
gt::Polygon::new(exterior, rings.map(ring_to_ls).collect())
}
fn gt_to_poly(p: >::Polygon<f64>) -> Polygon {
let mut out = Vec::with_capacity(1 + p.interiors().len());
out.push(ls_to_ring(p.exterior()));
out.extend(p.interiors().iter().map(ls_to_ring));
out
}
impl From<gt::Polygon<f64>> for Geometry {
fn from(p: gt::Polygon<f64>) -> Self {
Geometry::Polygon(gt_to_poly(&p))
}
}
impl From<gt::MultiPolygon<f64>> for Geometry {
fn from(mp: gt::MultiPolygon<f64>) -> Self {
Geometry::MultiPolygon(mp.0.iter().map(gt_to_poly).collect())
}
}
pub trait ToGeo {
fn to_geo(&self) -> gt::MultiPolygon<f64>;
}
impl ToGeo for MultiPolygon {
fn to_geo(&self) -> gt::MultiPolygon<f64> {
gt::MultiPolygon(self.iter().map(poly_to_gt).collect())
}
}
impl ToGeo for Geometry {
fn to_geo(&self) -> gt::MultiPolygon<f64> {
match self {
Geometry::Polygon(p) => gt::MultiPolygon(vec![poly_to_gt(p)]),
Geometry::MultiPolygon(mp) => mp.to_geo(),
}
}
}