8个版本
使用旧的Rust 2015
0.1.7 | 2020年3月7日 |
---|---|
0.1.6 | 2018年11月12日 |
0.1.5 | 2018年6月22日 |
0.1.4 | 2017年12月9日 |
0.1.3 | 2017年10月17日 |
在数学类别中排名#284
每月78次下载
51KB
919 行
proj5
PROJ.5是基于Rust的坐标投影库PROJ.4(用C编写)的替代品。PROJ.5旨在使坐标变换更加类型安全(而不是依赖于投影字符串)并支持多线程(使用多个线程以及生成的OpenCL代码)。
虽然重写这样一个成熟的库是一项庞大的工作,但是多线程、向量化以及批量变换带来的速度优势足以尝试。
我编写这个库是因为我看到了在GitHub上漂浮着各种GIS/投影库,但没有集中式的Rust投影库。
注意:这个库还在开发中,绝对没有经过实战测试。它只是不同作者提供的投影公式的集合,用Rust和类型安全的接口进行了移植。
重要:目前,尚不支持椭球体之间的重投影。
另外重要:坐标始终为水平然后是垂直。 (LonLat而不是LatLon)
PROJ.5定义了24个标准椭球(如WGS84、Bessel等),但你也可以创建自己的椭球。
使用
extern crate proj5;
use proj5::prelude::*;
fn main() {
//! warning: PROJ.5 can currently not reproject between different ellipsoids!
//! using different ellipsoids will panic!
let ellipsoid = WGS_1984_ELLIPSOID;
let source_coordinates = CoordinateSource::CoordinateBuf(Box::new(
CoordinateBuf {
data: vec![(377299.0, 1483035.0)],
crs: Box::new(UTMSystem {
utm_zone: 48,
}),
ellipsoid: ellipsoid,
}
));
let mut target_coordinates = CoordinateSource::CoordinateBuf(Box::new(
CoordinateBuf {
data: Vec::new(),
crs: Box::new(MercatorSystem),
ellipsoid: ellipsoid,
}
));
let mut strategy = MultithreadingStrategy::SingleCore;
source_coordinates.project(&mut target_coordinates, &mut strategy);
println!("first batch of coordinates: {:#?}", target_coordinates.get_data_ref());
}
性能
性能取决于选择的 MultithreadingStrategy
。当然,多线程变换总是比单线程变换更快。当处理坐标时,X和Y通常单独计算,这就是为什么这个库不与向量(例如,nalgebra
等库)一起使用。变换不是线性的,因此在这种情况下向量是无用的。
PROJ.5在每次(批量)变换中调用两个虚拟函数。强烈建议在可能的情况下对您的坐标进行批处理。PROJ.5使用双精度进行计算。
设计
从任何投影和任何椭球体到任何其他投影和椭球体的转换将导致(投影数量) ^ (椭球体数量) ^ 2
次转换。这在现实中是不可能的。相反,PROJ.5所执行的转换如下
+-----------------+ +------------------+
|(1) | |(2) |
|Source CRS | |Longitude / Latit.|
|Source Ellipsoid +-v->+Source Ellipsoid |
|Source Units | |lon/lat (degrees) |
| | | |
+-----------------+ +--------+---------+
|
|
+-----------------+ +--------+---------+
|(4) | |(3) |
|Target CRS | |Longitude / Latit.|
|Target Ellipsoid +<-v-+Target Ellipsoid |
|Target Units | |lon/lat (degrees) |
| | | |
+-----------------+ +------------------+
带有v
标记的箭头需要一个虚拟函数调用,以便查找给定坐标系统的实现。
为了实现您自己的CRS,您必须实现ToLatLon
和FromLatLon
特质。然后自动为您实现所需的Crs
特质。
impl ToLatLon for MyCoordinateSystem {
fn to_lon_lat(&self, mut data: Vec<(f64, f64)>, ellipsoid: Ellipsoid)
-> LonLatBuf
{ ... }
}
impl FromLatLon for MyCoordinateSystem {
fn from_lon_lat(&self, mut data: Vec<(f64, f64)>, ellipsoid: Ellipsoid)
-> CoordinateBuf
{ ... }
}
这样,每个坐标系统都可以与每个其他坐标系统通信。