2次发布
0.1.1 | 2020年4月22日 |
---|---|
0.1.0 | 2020年4月15日 |
#138 in 地理空间
每月 21次下载
80KB
1.5K SLoC
rust-geo-svg
SVG和geo类型之间的转换功能。
SVG到几何形状
此包提供了一组函数,用于读取包含SVG元素的字符串或d
字符串,并将其解析为几何形状。
svg_to_geometry(svg: &str)
注意此函数不会解析完整的SVG字符串(例如,<svg xmlns="http://www.w3.org/2000/svg"><path d="M0 0L10 0L10 10L0 10Z"/></svg>
),它只会解析单个形状元素(例如,<path d="M0 0L10 0L10 10L0 10Z"/>
)。以下SVG元素受支持,并生成指定的几何类型
- <path> → 自动检测类型的几何形状
- <polygon> → 多边形
- <polyline> → 线串
- <rect> → 多边形
- <line> → 线
示例
use geo_types::{ Polygon, polygon };
use geo_svg_io::geo_svg_reader::svg_to_geometry;
let poly: Polygon<f64> = polygon!(
exterior: [
(x: 0.0_f64, y: 0.0),
(x: 0.0, y: 60.0),
(x: 60.0, y: 60.0),
(x: 60.0, y: 0.0),
(x: 0.0, y: 0.0),],
interiors:[[
(x: 10.0, y: 10.0),
(x: 40.0, y: 1.0),
(x: 40.0, y: 40.0),
(x: 10.50, y: 40.0),
(x: 10.0, y: 10.0),]
]
);
let svg_string =
String::from(r#"<path d="M0 0L0 60L60 60L60 0L0 0M10 10L40 1L40 40L10.5 40L10 10"/>"#);
let parsed_svg = svg_to_geometry(&svg_string);
assert!(parsed_svg.is_ok());
let parsed_poly = parsed_svg.ok().unwrap().into_polygon();
assert!(parsed_poly.is_some());
assert_eq!(poly, parsed_poly.unwrap());
use geo_types::{ Polygon, polygon };
use geo_svg_io::geo_svg_reader::svg_to_geometry;
let poly: Polygon<f64> = polygon!(
exterior: [
(x: 0.0_f64, y: 0.0),
(x: 0.0, y: 60.0),
(x: 60.0, y: 60.0),
(x: 60.0, y: 0.0),
(x: 0.0, y: 0.0),],
interiors:[]
);
let svg_string = String::from(r#"<polygon points="0, 0 60, 0 60, 60 0, 60 0, 0"/>"#);
let parsed_svg = svg_to_geometry(&svg_string);
assert!(parsed_svg.is_ok());
let parsed_poly = parsed_svg.ok().unwrap().into_polygon();
assert!(parsed_poly.is_some());
assert_eq!(poly, parsed_poly.unwrap());
svg_to_geometry_collection(svg: &str)
注意此函数不会解析完整的SVG字符串(例如,<svg xmlns="http://www.w3.org/2000/svg"><path d="M0 0L10 0L10 10L0 10Z"/></svg>
),它只会解析单个形状元素(例如,<path d="M0 0L10 0L10 10L0 10Z"/>
)。以下SVG元素受支持,并生成指定的几何类型
- <path> → 几何形状集合
- <polygon> → 包含单个多边形的几何形状集合
- <polyline> → 包含单个线串的几何形状集合
- <rect> → 包含单个多边形的几何形状集合
- <line> → 包含单个线的几何形状集合
示例
use geo_types::{ Polygon, polygon };
use geo_svg_io::geo_svg_reader::svg_to_geometry_collection;
let poly: Polygon<f64> = polygon!(
exterior: [
(x: 0.0_f64, y: 0.0),
(x: 0.0, y: 60.0),
(x: 60.0, y: 60.0),
(x: 60.0, y: 0.0),
(x: 0.0, y: 0.0),],
interiors:[[
(x: 10.0, y: 10.0),
(x: 40.0, y: 1.0),
(x: 40.0, y: 40.0),
(x: 10.50, y: 40.0),
(x: 10.0, y: 10.0),]
]
)
.into();
let svg_string =
String::from(r#"<path d="M0 0L0 60L60 60L60 0L0 0M10 10L40 1L40 40L10.5 40L10 10"/>"#);
let parsed_svg = svg_to_geometry_collection(&svg_string);
assert!(parsed_svg.is_ok());
// Unwrap the GeometryCollection result
let geom = parsed_svg.ok().unwrap();
assert_eq!(1, geom.0.len());
// Read the geometry as a Polygon
let pl = geom.0[0].clone().into_polygon();
assert_eq!(true, pl.is_some());
assert_eq!(poly, pl.unwrap());
use geo_types::{ Polygon, polygon };
use geo_svg_io::geo_svg_reader::svg_to_geometry;
let poly: Polygon<f64> = polygon!(
exterior: [
(x: 0.0_f64, y: 0.0),
(x: 0.0, y: 60.0),
(x: 60.0, y: 60.0),
(x: 60.0, y: 0.0),
(x: 0.0, y: 0.0),],
interiors:[]
)
.into();
let svg_string = String::from(r#"<polygon points="0, 0 60, 0 60, 60 0, 60 0, 0"/>"#);
let parsed_svg = svg_to_geometry_collection(&svg_string);
assert!(parsed_svg.is_ok());
// Unwrap the GeometryCollection result
let geom = parsed_svg.ok().unwrap();
assert_eq!(1, geom.0.len());
// Read the geometry as a Polygon
let pl = geom.0[0].clone().into_polygon();
assert_eq!(true, pl.is_some());
assert_eq!(poly, pl.unwrap());
svg_d_path_to_geometry(svg: &str)
<path>
元素的d
字符串可以直接通过svg_d_path_to_geometry(svg: &str)
函数解析为几何形状。输出始终为几何形状集合。
示例
use geo_svg_io::geo_svg_reader::svg_d_path_to_geometry_collection;
use geo_types::polygon;
let poly = polygon!(
exterior: [
(x: 0.0, y: 0.0),
(x: 0.0, y: 60.0),
(x: 60.0, y: 60.0),
(x: 60.0, y: 0.0),
(x: 0.0, y: 0.0),],
interiors:[[
(x: 10.0, y: 10.0),
(x: 40.0, y: 1.0),
(x: 40.0, y: 40.0),
(x: 10.50, y: 40.0),
(x: 10.0, y: 10.0),]
]
);
let svg_string = String::from("M0 0l0 60l60 0L60 0L0 0M10 10L40 1L40 40L10.5 40L10 10");
let parsed_svg = svg_d_path_to_geometry(&svg_string);
assert!(parsed_svg.is_ok());
let pl = parsed_svg.ok().unwrap().into_polygon();
assert!(pl.is_some());
assert_eq!(pl.unwrap(), poly);
svg_d_path_to_geometry_collection(svg: &str)
可以将<path>
元素的d
字符串直接解析为GeometryCollection,这是通过svg_d_path_to_geometry_collection(svg: &str)
函数实现的。输出总是GeometryCollection。
示例
use geo_svg_io::geo_svg_reader::svg_d_path_to_geometry_collection;
use geo_types::polygon;
let poly = polygon!(
exterior: [
(x: 0.0, y: 0.0),
(x: 0.0, y: 60.0),
(x: 60.0, y: 60.0),
(x: 60.0, y: 0.0),
(x: 0.0, y: 0.0),],
interiors:[[
(x: 10.0, y: 10.0),
(x: 40.0, y: 1.0),
(x: 40.0, y: 40.0),
(x: 10.50, y: 40.0),
(x: 10.0, y: 10.0),]
]
);
let svg_string = String::from("M0 0l0 60l60 0L60 0L0 0M10 10L40 1L40 40L10.5 40L10 10");
let parsed_svg = svg_d_path_to_geometry_collection(&svg_string);
assert!(parsed_svg.is_ok());
// Unwrap the GeometryCollection result
let geom = parsed_svg.ok().unwrap();
assert_eq!(1, geom.0.len());
// Read the geometry as a Polygon
let pl = geom.0[0].clone().into_polygon();
assert_eq!(true, pl.is_some());
assert_eq!(pl.unwrap(), poly);
错误处理
这两个函数都返回一个Result,它可能包含解析后的Geometry或SvgError
枚举类型的Error。错误可能源于传递了不支持的SVG元素类型,SVG元素格式不正确,或者无法从提供的字符串中解析出float
。
Geometry转SVG
此包提供了两个特质,用于将Geometry转换为SVG。请注意,对<path>
d
-字符串的解析是简化的。它在曲线上绘制了100个点。
待办事项 将此功能更新为使用递归函数来创建点,直到它们共线(足够多)。
ToSvg
使用to_svg()
从任何Geometry类型生成最简单的SVG元素
- 多边形 → <path>
- LineString → <polyline>
- Line → <line>
- 三角形 → <polygon>带有三个点
- 矩形 → <rect>带有
x
、y
、width
和height
复杂的Geometry类型将返回多个通过newline
分隔的SVG元素
- GeometryCollection → 与包含的单独Geometry对应的
newline
分隔的SVG元素 - MultiPolygon →
newline
分隔的元素 - MultiLineString →
newline
分隔的元素
示例
use geo_types::{ MultiPolygon, polygon };
use geo_svg_io::geo_svg_writer::ToSvg;
let poly1 = polygon![
(x: 1.0, y: 1.0),
(x: 4.0, y: 1.0),
(x: 4.0, y: 4.0),
(x: 1.0, y: 4.0),
(x: 1.0, y: 1.0),
];
let poly2 = polygon!(
exterior: [
(x: 0.0, y: 0.0),
(x: 6.0, y: 0.0),
(x: 6.0, y: 6.0),
(x: 0.0, y: 6.0),
(x: 0.0, y: 0.0),],
interiors:[[
(x: 1.0, y: 1.0),
(x: 4.0, y: 1.0),
(x: 4.0, y: 4.0),
(x: 1.50, y: 4.0),
(x: 1.0, y: 1.0),]
]
);
let mp = MultiPolygon(vec![poly1, poly2]);
let wkt_out = mp.to_svg();
let expected = String::from(
r#"<path d="M1 1L4 1L4 4L1 4L1 1"/>
<path d="M0 0L6 0L6 6L0 6L0 0M1 1L4 1L4 4L1.5 4L1 1"/>"#,
);
assert_eq!(wkt_out, expected);
ToSvgString
使用to_svg_string()
从任何Geometry类型生成包含该几何所有点的SVG d
字符串,这可以用于SVG路径元素
示例
use geo_types::{polygon, MultiPolygon};
use geo_svg_io::geo_svg_writer::ToSvgString;
let poly1 = polygon![
(x: 1.0, y: 1.0),
(x: 4.0, y: 1.0),
(x: 4.0, y: 4.0),
(x: 1.0, y: 4.0),
(x: 1.0, y: 1.0),
];
let poly2 = polygon!(
exterior: [
(x: 0.0, y: 0.0),
(x: 6.0, y: 0.0),
(x: 6.0, y: 6.0),
(x: 0.0, y: 6.0),
(x: 0.0, y: 0.0),],
interiors:[[
(x: 1.0, y: 1.0),
(x: 4.0, y: 1.0),
(x: 4.0, y: 4.0),
(x: 1.50, y: 4.0),
(x: 1.0, y: 1.0),]
]
);
let mp = MultiPolygon(vec![poly1, poly2]);
let wkt_out = mp.to_svg_string();
let expected = String::from(
"M1 1L4 1L4 4L1 4L1 1M0 0L6 0L6 6L0 6L0 0M1 1L4 1L4 4L1.5 4L1 1"
);
assert_eq!(wkt_out, expected);
类似项目
有关提供从Rust geo类型构建SVG的更高层次功能的类似项目,请参阅https://github.com/lelongg/geo-svg
依赖项
~4.5MB
~76K SLoC