如何在Rust中遍历geos::Polygon外环中的点?
解决Rust中GEOS库遍历多边形外环点的问题
问题描述
我有一个表示多边形的geometry对象,想要遍历其外环中的点。尝试参考GEOS C API的方法实现,但在Rust中无法生效。get_exterior_ring函数返回一个类型为LinearRing的ConstGeometry对象,但调用其get_num_points方法时返回错误:
Err(
GenericError(
"Geometry must be a LineString",
),
)
我的Rust代码如下:
let test_polygon: Polygon = Polygon::new( LineString(vec![ Coord::from((4.9147899, 52.3735245)), Coord::from((4.9148563, 52.3735048)), Coord::from((4.9148865, 52.3735437)), Coord::from((4.9148248, 52.3735613)), Coord::from((4.9147899, 52.3735245)), ]), vec![LineString(vec![])], ); let geometry: geos::Geometry = (&test_polygon).try_into().unwrap(); let linear_ring: ConstGeometry = geometry.get_exterior_ring().unwrap(); dbg!(linear_ring.get_num_points().err());
问题原因
GEOS的Rust绑定对几何类型做了严格区分:LinearRing和LineString是不同的类型,get_num_points是LineString专属方法,LinearRing无法直接调用该方法。
解决方案
有两种可行的方法遍历LinearRing的点:
方法1:将LinearRing转为LineString后操作
使用as_line_string方法把ConstGeometry转换为LineString类型,之后即可正常调用get_num_points和get_point方法:
let test_polygon: Polygon = Polygon::new( LineString(vec![ Coord::from((4.9147899, 52.3735245)), Coord::from((4.9148563, 52.3735048)), Coord::from((4.9148865, 52.3735437)), Coord::from((4.9148248, 52.3735613)), Coord::from((4.9147899, 52.3735245)), ]), vec![LineString(vec![])], ); let geometry: geos::Geometry = (&test_polygon).try_into().unwrap(); let linear_ring: ConstGeometry = geometry.get_exterior_ring().unwrap(); // 转换为LineString let line_string = linear_ring.as_line_string().unwrap(); // 获取点数 let num_points = line_string.get_num_points().unwrap(); dbg!(num_points); // 遍历所有点 for i in 0..num_points { let point = line_string.get_point(i).unwrap(); let coord = point.get_coord().unwrap(); dbg!(coord); }
方法2:直接访问坐标序列
通过get_coord_seq获取LinearRing的坐标序列,直接遍历序列中的坐标:
let test_polygon: Polygon = Polygon::new( LineString(vec![ Coord::from((4.9147899, 52.3735245)), Coord::from((4.9148563, 52.3735048)), Coord::from((4.9148865, 52.3735437)), Coord::from((4.9148248, 52.3735613)), Coord::from((4.9147899, 52.3735245)), ]), vec![LineString(vec![])], ); let geometry: geos::Geometry = (&test_polygon).try_into().unwrap(); let linear_ring: ConstGeometry = geometry.get_exterior_ring().unwrap(); // 获取坐标序列 let coord_seq = linear_ring.get_coord_seq().unwrap(); let num_points = coord_seq.size().unwrap(); // 遍历坐标 for i in 0..num_points { let x = coord_seq.get_x(i).unwrap(); let y = coord_seq.get_y(i).unwrap(); dbg!(x, y); }
内容的提问来源于stack exchange,提问作者Eamonn McEvoy
相关产品推荐
相关产品推荐

