55个版本
0.27.2 | 2023年7月7日 |
---|---|
0.27.0 | 2022年6月23日 |
0.25.2 | 2022年2月20日 |
0.24.0 | 2021年10月20日 |
0.1.1 | 2015年7月1日 |
#22 in 地理空间
4,762 每月下载量
用于 10 个crate(8个直接使用)
5.5MB
5.5K SLoC
PROJ
通过绑定到PROJ
v9.2 API进行坐标变换。
目前提供了两种坐标变换操作:投影(及其逆投影)和转换。
投影用于地球和投影坐标之间的变换以及相反(逆投影),而转换用于投影坐标系统之间的变换。PROJ 文档更详细地解释了这些操作之间的区别。
此crate依赖于libproj v9.2.x
,通过proj-sys
crate访问。默认情况下,proj-sys
将尝试在您的系统上找到现有的libproj安装。如果找不到合适的libproj版本,构建脚本将尝试从源代码构建libproj。您可以使用bundled_proj
特性指定从源代码构建。
开箱即用,任何(x, y)
数字元组都可以作为输入提供给proj。您可以通过适配您自己的类型到Coord特质来直接传递它们,以避免中间分配。默认启用了geo-types
特性,该特性为geo-types
crate中的类型实现了此特质。
示例
使用EPSG代码将NAD 83美国调查英尺转换为NAD 83米
use proj::Proj;
let from = "EPSG:2230";
let to = "EPSG:26946";
let ft_to_m = Proj::new_known_crs(&from, &to, None).unwrap();
let result = ft_to_m
.convert((4760096.421921f64, 3744293.729449f64))
.unwrap();
assert_relative_eq!(result.0, 1450880.2910605003);
assert_relative_eq!(result.1, 1141263.0111604529);
使用pipeline
操作符将NAD 83美国调查英尺转换为NAD 83米
请注意,自v5.0.0版本起,PROJ使用pipeline
运算符,它允许在转换中包含任意数量的步骤。以下示例的工作方式如下:
- 将操作定义为
pipeline
操作 - 将
step
1定义为逆变换,产生大地坐标 - 将
step
2定义为正向变换到投影坐标,产生米。
use proj::Proj;
let ft_to_m = Proj::new("
+proj=pipeline
+step +inv +proj=lcc +lat_1=33.88333333333333
+lat_2=32.78333333333333 +lat_0=32.16666666666666
+lon_0=-116.25 +x_0=2000000.0001016 +y_0=500000.0001016001 +ellps=GRS80
+towgs84=0,0,0,0,0,0,0 +units=us-ft +no_defs
+step +proj=lcc +lat_1=33.88333333333333 +lat_2=32.78333333333333 +lat_0=32.16666666666666
+lon_0=-116.25 +x_0=2000000 +y_0=500000
+ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs
").unwrap();
// The Presidio, approximately
let result = ft_to_m.convert((4760096.421921f64, 3744293.729449f64)).unwrap();
assert_relative_eq!(result.0, 1450880.2910605003);
assert_relative_eq!(result.1, 1141263.01116045);
从Stereo70到大地测量的逆向投影
use proj::Proj;
// Carry out an inverse projection from Pulkovo 1942(58) / Stereo70 (EPSG 3844)
// into geodetic lon and lat coordinates (in radians)
let stereo70 = Proj::new("
+proj=sterea +lat_0=46 +lon_0=25 +k=0.99975 +x_0=500000 +y_0=500000
+ellps=krass +towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84
+units=m +no_defs
").unwrap();
let geodetic_radians_point = stereo70.project(
(500119.70352012233f64, 500027.77896348457f64), true
).unwrap();
assert_relative_eq!(geodetic_radians_point.0, 0.436332, epsilon=1e-5);
assert_relative_eq!(geodetic_radians_point.1, 0.802851, epsiolon=1e-5);
用法
创建转换有两种选项
- 如果您不需要额外的网格或其他自定义
- 调用
Proj::new
或Proj::new_known_crs
。这创建了一个转换实例(Proj
)
- 调用
- 如果您需要执行转换的网格,或者您需要自定义搜索路径或网格端点
- 通过调用
ProjBuilder::new()
创建一个新的ProjBuilder
。它可以修改以启用网络下载、禁用网格、缓存或修改搜索路径; - 调用
ProjBuilder.proj()
或ProjBuilder.proj_known_crs()
。这创建了一个转换实例(Proj
)
- 通过调用
注意:
ProjBuilder
和Proj
都实现了Info
特质,可以用来获取关于当前PROJ
实例状态的信息;Proj::new()
和ProjBuilder::proj()
具有相同的签名;Proj::new_known_crs()
和ProjBuilder::proj_known_crs()
具有相同的签名。
要求
默认情况下,该crate需要在您的系统上存在libproj
9.2.x。虽然它可能与较老的PROJ 6版本向后兼容,但这既没有被测试也没有得到支持。如果找不到合适的库,proj
将尝试从源代码构建libproj
。
功能标志
geo-types
:包含为geo-types
实现的特质。见示例。pkg_config
:启用在链接到libproj
时使用pkg-config
—— 注意pkg-config
必须在您的系统上可用。bundled_proj
:从proj-sys
crate中打包的源代码构建libproj
。注意,此功能需要在您的系统上存在Sqlite3和libtiff
。network
:公开了API,当启用时,可以从互联网获取网格数据以提高投影精度。有关详细信息,请参阅enable_network
方法:enable_network。
网络、缓存和搜索路径功能
网格文件下载
proj
通过network
功能支持网络网格下载功能。网络访问默认为禁用
,可以通过传递true
bool
到enable_network()
来激活。可以使用network_enabled
查询网络功能状态,并使用get_url_endpoint
和set_url_endpoint
查询和设置下载端点。
网格文件缓存
最多缓存300 MB下载的网格以节省带宽:可以通过grid_cache_enable
启用或禁用此缓存。
搜索路径修改
可以使用set_search_paths
修改用于搜索资源文件的路径。
符合您自己的类型
如果您有自己的几何类型,可以将它们符合到Coord
特性和使用proj
而不进行任何中间分配。
use proj::{Proj, Coord};
struct MyPointOfInterest {
lat: f64,
lon: f64,
}
impl Coord<f64> for MyPointOfInterest {
fn x(&self) -> f64 {
self.lon
}
fn y(&self) -> f64 {
self.lat
}
fn from_xy(x: f64, y: f64) -> Self {
Self { lon: x, lat: y }
}
}
let donut_shop = MyPointOfInterest { lat: 34.095620, lon: -118.283555 };
let from = "EPSG:4326";
let to = "EPSG:3309";
let proj = Proj::new_known_crs(&from, &to, None).unwrap();
let result = proj.convert(donut_shop).unwrap();
assert_relative_eq!(result.x(), 158458.67251293268);
assert_relative_eq!(result.y(), -434296.8803996085);
与geo-types
集成
如果您已启用geo-types
功能,可以跳过分配中间表示,并直接传递geo-types
。
use approx::assert_relative_eq;
use proj::Proj;
use geo_types::Point;
let my_point = Point::new(4760096.421921f64, 3744293.729449f64);
let from = "EPSG:2230";
let to = "EPSG:26946";
let nad_ft_to_m = Proj::new_known_crs(&from, &to, None).unwrap();
let result = nad_ft_to_m.convert(my_point).unwrap();
assert_relative_eq!(result.x(), 1450880.2910605003f64);
assert_relative_eq!(result.y(), 1141263.0111604529f64);
您还可以使用Transform
特性和转换整个geo-types
几何。
use proj::{Proj, Transform};
use geo_types::{Coordinate, line_string};
let line = line_string![
(x: -116.590457069172_f64, y: 32.55730630167689),
(x: -116.590411068973, y: 32.55714830169309),
];
let proj = Proj::new_known_crs("EPSG:4326", "EPSG:6366", None).unwrap();
// create a new line with a different projection
let new_line = line.transformed(&proj).unwrap();
assert_eq!(new_line[0], Coordinate { x: 538447.8454476658, y: 3602285.563945497, });
assert_eq!(new_line[1], Coordinate { x: 538452.2313532799, y: 3602268.065714932, });
// or transform the original in-place
let mut line = line;
line.transform(&proj).unwrap();
assert_eq!(line[0], Coordinate { x: 538447.8454476658, y: 3602285.563945497, });
assert_eq!(line[1], Coordinate { x: 538452.2313532799, y: 3602268.065714932, });
许可:MIT/Apache-2.0
依赖项
~1–15MB
~204K SLoC