1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//! # Geospatial and Geodesy Utilities
//!
//! This module provides a comprehensive set of geospatial and geodetic
//! primitives for the SciRS2 scientific computing ecosystem.
//!
//! | Submodule | Contents |
//! |-----------|---------|
//! | [`coordinates`] | Geographic/ECEF/ENU coordinate systems, Vincenty/Haversine distances |
//! | [`projection`] | Mercator, Transverse Mercator, UTM, Azimuthal Equidistant, Lambert Conic |
//!
//! ## Design Principles
//!
//! * All angular values are in **decimal degrees** unless explicitly noted.
//! * All linear values are in **metres**.
//! * The **WGS-84** ellipsoid is used throughout.
//! * Every operation that can fail returns a [`GeoResult`] / [`GeoError`].
//! * No external geospatial crate dependencies — pure Rust implementation.
//!
//! ## Quick Start
//!
//! ### Coordinate conversion and geodetic distance
//!
//! ```rust
//! use scirs2_core::geo::coordinates::{GeographicCoord, EcefCoord};
//!
//! let london = GeographicCoord::new(51.5074, -0.1278, 0.0);
//! let paris = GeographicCoord::new(48.8566, 2.3522, 0.0);
//!
//! // Haversine distance (fast, spherical approximation)
//! let hav_m = london.haversine_distance(&paris);
//! assert!((hav_m - 340_000.0).abs() < 5_000.0);
//!
//! // Vincenty distance (ellipsoidal, ~0.5 mm accuracy)
//! let vin_m = london.vincenty_distance(&paris).expect("converges");
//! assert!((vin_m - 340_000.0).abs() < 5_000.0);
//!
//! // ECEF round-trip
//! let ecef = london.to_ecef();
//! let recovered = ecef.to_geographic();
//! assert!((recovered.lat - london.lat).abs() < 1e-9);
//!
//! // ENU: point relative to an origin
//! let enu = paris.to_enu(&london);
//! println!("Paris from London: east={:.0}m, north={:.0}m, up={:.0}m",
//! enu.east, enu.north, enu.up);
//! ```
//!
//! ### Map projections
//!
//! ```rust
//! use scirs2_core::geo::projection::{mercator_forward, mercator_inverse, to_utm, from_utm};
//!
//! // Mercator: equator maps to y = 0
//! let (_, y) = mercator_forward(0.0, 0.0, 0.0);
//! assert!(y.abs() < 1e-6);
//!
//! // UTM round-trip (New York City)
//! let (zone, band, e, n) = to_utm(40.7128, -74.0060).expect("to_utm");
//! assert_eq!(zone, 18);
//! let (lat2, lon2) = from_utm(zone, band, e, n).expect("from_utm");
//! assert!((lat2 - 40.7128).abs() < 1e-5);
//! assert!((lon2 - (-74.0060)).abs() < 1e-5);
//! ```
// Flat re-exports so callers can use `scirs2_core::geo::GeoError` etc. without
// needing to drill into the submodule.
pub use ;
pub use ;