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

Download history 18/week @ 2024-03-11 10/week @ 2024-04-01 2/week @ 2024-04-15

每月78次下载

MIT许可证

51KB
919

Build Status

proj5

Crates.io | 文档

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,您必须实现ToLatLonFromLatLon特质。然后自动为您实现所需的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
    { ... }
}

这样,每个坐标系统都可以与每个其他坐标系统通信。

依赖项