Skip to main content

proj_core/
lib.rs

1#![forbid(unsafe_code)]
2
3//! Pure-Rust coordinate transformation library.
4//!
5//! No C dependencies, no unsafe, WASM-compatible.
6//!
7//! The primary type is [`Transform`], which provides CRS-to-CRS coordinate
8//! transformation using authority codes (e.g., `"EPSG:4326"`).
9//! For area-aware or policy-constrained selection, use
10//! [`Transform::with_selection_options`] and inspect
11//! [`Transform::selected_operation`] /
12//! [`Transform::selection_diagnostics`].
13//! Operation selection ranks only embedded registry/generated-registry
14//! operations, explicit custom horizontal operations supplied in
15//! [`SelectionOptions`] or by parsers such as `proj-wkt`, and internal
16//! identity/no-datum-operation behavior. It does not synthesize Helmert, grid,
17//! or WGS84-compatible identity operations from datum metadata.
18//! The [`registry`], [`operation`], and [`grid`] modules expose the embedded
19//! operation catalog, selection metadata, and NTv2 grid-provider interfaces.
20//! Without vertical CRS components, `convert_3d` treats `z` as ellipsoidal
21//! height: datum shifts change it exactly as C PROJ's 3D-promoted CRS pairs
22//! do, and same-datum transforms preserve it. When source and target compound
23//! CRS definitions have identical vertical components the gravity-related `z`
24//! is preserved, and it is unit-converted when both vertical components use
25//! the same vertical reference frame with different linear units. Registry-backed GTX
26//! geoid operations can be selected for supported ellipsoidal-to-gravity height
27//! CRS pairs, while grid files still resolve through caller-supplied grid
28//! providers.
29//! A strict transform constructor rejects a compound-to-horizontal-only CRS
30//! pair because it cannot safely infer what to do with the explicit vertical
31//! ordinate. Use [`Transform::new_horizontal`] or
32//! [`Transform::from_horizontal_components`] when the operation is explicitly
33//! limited to XY coordinates.
34//! Geographic antimeridian AOIs use
35//! [`AreaOfInterest::geographic_wrapped_bounds`], while ordinary projected and
36//! source/target bounds keep strict `min <= max` validation.
37//! With the default `geo-types` feature, [`Transform::convert_geometry`]
38//! transforms whole 2D `geo-types` geometries and fails on the first invalid
39//! coordinate without returning partial results.
40//!
41//! # Example
42//!
43//! ```
44//! use proj_core::Transform;
45//!
46//! // Create a transform from WGS84 geographic to Web Mercator
47//! let t = Transform::new("EPSG:4326", "EPSG:3857").unwrap();
48//!
49//! // Transform NYC coordinates (lon, lat in degrees) → (x, y in meters)
50//! let (x, y) = t.convert((-74.006, 40.7128)).unwrap();
51//! assert!((x - (-8238310.0)).abs() < 100.0);
52//!
53//! // Inverse: Web Mercator → WGS84
54//! let inv = Transform::new("EPSG:3857", "EPSG:4326").unwrap();
55//! let (lon, lat) = inv.convert((x, y)).unwrap();
56//! assert!((lon - (-74.006)).abs() < 1e-6);
57//! ```
58
59pub mod coord;
60pub mod crs;
61pub mod datum;
62pub mod ellipsoid;
63mod epsg_db;
64pub mod error;
65mod geocentric;
66pub mod grid;
67mod helmert;
68pub mod operation;
69mod projection;
70pub mod registry;
71mod selector;
72pub mod transform;
73
74pub use coord::{
75    Bounds, Coord, Coord3D, Transformable, Transformable3D, MAX_BOUNDS_DENSIFY_POINTS,
76};
77pub use crs::{
78    CompoundCrsDef, CrsDef, GeographicCrsDef, HorizontalCrsDef, LinearUnit, ProjectedCrsDef,
79    ProjectionMethod, VerticalCrsDef, VerticalCrsKind,
80};
81pub use datum::{Datum, DatumGridShift, DatumGridShiftEntry, DatumToWgs84, HelmertParams};
82pub use ellipsoid::Ellipsoid;
83pub use error::{Error, Result};
84pub use grid::{
85    EmbeddedGridProvider, FilesystemGridProvider, GridDefinition, GridError, GridFormat,
86    GridHandle, GridProvider, GridSample, VerticalGridSample,
87};
88pub use operation::{
89    AreaOfInterest, AreaOfInterestCrs, AreaOfUse, CoordinateOperation, CoordinateOperationId,
90    CoordinateOperationMetadata, GridCoverageMiss, GridId, GridInterpolation, GridShiftDirection,
91    OperationAccuracy, OperationMatchKind, OperationMethod, OperationSelectionDiagnostics,
92    OperationStep, OperationStepDirection, SelectionOptions, SelectionPolicy, SelectionReason,
93    SkippedOperation, SkippedOperationReason, TransformOutcome, VerticalGridOffsetConvention,
94    VerticalGridOperation, VerticalGridProvenance, VerticalTransformAction,
95    VerticalTransformDiagnostics,
96};
97pub use registry::{
98    lookup_authority_code, lookup_datum_code_for_crs, lookup_datum_code_for_name,
99    lookup_datum_epsg, lookup_ellipsoid_code_for_datum, lookup_epsg, lookup_operation,
100    lookup_vertical_epsg, lookup_vertical_grid_operation, operation_candidates_between,
101    operation_candidates_between_with_selection_options, operations_between,
102    vertical_grid_operations_between,
103};
104pub use transform::Transform;
105#[cfg(feature = "geo-types")]
106pub use transform::TransformableGeometry;