use geo_svg_io::geo_svg_reader::svg_d_path_to_geometry; use geo_types::{Coordinate, LineString, MultiPolygon, Polygon}; use std::error::Error; use svg::node::element::tag::Path; use svg::parser::Event; #[allow(non_upper_case_globals)] pub fn load_multipolgon_from_svg(path: &str) -> Result, Box> { let mut content = String::new(); let mut result: Vec> = Vec::new(); for event in svg::open(path, &mut content)? { match event { Event::Tag(Path, _, attributes) => { let data = attributes.get("d").unwrap(); let parsed_svg = svg_d_path_to_geometry(&data).ok().unwrap(); let polygon = parsed_svg.into_polygon().unwrap(); // both libraries use different versions of geo-types, so we have to map them :facepalm: // map interiors let mut interiors: Vec> = Vec::new(); for interior_line_string in polygon.interiors().to_vec() { let mut new_line_string: Vec> = Vec::new(); for i in interior_line_string.into_points() { new_line_string.push(Coordinate { x: i.x(), y: i.y() }); } interiors.push(LineString::from(new_line_string)); } // map exteriors let mut l: Vec> = Vec::new(); for i in polygon.exterior().clone().into_points() { l.push(Coordinate { x: i.x(), y: i.y() }); } let exterior = LineString::from(l); result.push(Polygon::new(exterior, interiors)); } _ => {} } } Ok(MultiPolygon::from(result)) }