12个版本 (6个破坏性更新)
0.7.1 | 2024年4月7日 |
---|---|
0.6.1 | 2024年1月24日 |
0.5.1 | 2023年4月14日 |
0.3.2 | 2023年1月16日 |
0.0.3 |
|
#139 in 数学
每月 303 下载
用于 gribberish
46KB
523 行
映射器
纯Rust地理投影库。在基本功能上类似于Proj
,但允许在并发环境中使用。
投影实现紧密遵循以下提供的算法和说明: 地图投影:工作手册(John P. Snyder,1987年)
该crate处于非常早期的开发阶段。如果您有兴趣贡献,请随时通过GitHub联系我。
为什么这个crate存在?
已经有一个成熟、生产就绪且经过实战考验的地理投影和转换库 - Proj
,它有出色的高级绑定在Rust中。您可能应该在使用自己的函数或使用此crate的情况下使用它。 Proj
也用于测试mappers
的精度。
然而,由于Proj
不是用Rust编写的,所以在并发环境中的使用并不直接。 Proj
也主要支持Linux,并且在不同目标上的安装可能是一个真正的麻烦(并且Proj
绑定也不支持其他目标)。
mappers
通过实现最常用的地理投影来解决这个问题,完全是Rust编写的。但它尚未经过彻底的精度和边缘情况的测试。mappers
可能也具有比Proj
略好的性能,因为它要简单得多。但它主要允许在多线程(进程、任务...)以及至少一级目标(仅测试构建Ubuntu、Windows和MacOS)上使用。
因此,只有在Proj
的全面性和(可能)正确性不如在非Linux目标上或并发环境中计算地理投影的需求时,才应使用mappers
。
使用示例
我们可以将地理坐标投影到具有指定投影的地图上的制图坐标,如下所示
// First, we define the projection
// We use LCC with reference longitude centered on France
// parallels set for Europe and WGS84 ellipsoid
let lcc = LambertConformalConic::new(2.0, 0.0, 30.0, 60.0, Ellipsoid::WGS84)?;
// Second, we define the coordinates of Mount Blanc
let (lon, lat) = (6.8651, 45.8326);
// Project the coordinates
let (x, y) = lcc.project(lon, lat)?;
// And print the result
println!("x: {}, y: {}", x, y); // x: 364836.4407792019, y: 5421073.726335758
我们还可以将制图坐标逆投影到地理坐标
// We again start with defining the projection
let lcc = LambertConformalConic::new(2.0, 0.0, 30.0, 60.0, Ellipsoid::WGS84)?;
// We take the previously projected coordinates
let (x, y) = (364836.4407792019, 5421073.726335758);
// Inversely project the coordinates
let (lon, lat) = lcc.inverse_project(x, y)?;
// And print the result
println!("lon: {}, lat: {}", lon, lat); // lon: 6.8651, lat: 45.83260000001716
某些投影在数学上是精确可逆的,技术上投影和逆投影的地理坐标应该是相同的。然而,在实践中,浮点运算的局限性会在过程中引入一些错误,如上面的示例所示。
转换管道
此crate还提供了一个结构体ConversionPipe
,它允许在两个投影之间轻松转换。它可以直接通过Projection
的pipe_to
方法或直接使用ConversionPipe::new()
构造。
示例
// We start by defining the source and target projections
// In this case we will use LCC and LongitudeLatitude
// to show how a normal projection can be done with ConversionPipe
let target_proj = LambertConformalConic::new(2.0, 0.0, 30.0, 60.0, Ellipsoid::WGS84)?;
let source_proj = LongitudeLatitude;
let (lon, lat) = (6.8651, 45.8326);
// Now we can convert to LCC and back to LongitudeLatitude
let (x, y) = source_proj.pipe_to(&target_proj).convert(lon, lat)?;
let (pipe_lon, pipe_lat) = target_proj.pipe_to(&source_proj).convert(x, y)?;
// For simple cases the error remains small
// but it can quickly grow with more complex conversions
assert_approx_eq!(f64, lon, pipe_lon, epsilon = 1e-10);
assert_approx_eq!(f64, lat, pipe_lat, epsilon = 1e-10);
依赖关系
~1–1.5MB
~34K SLoC