#![cfg_attr(not(feature = "std"), no_std)]
#![warn(missing_docs)]
#![deny(unsafe_code)]
#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::format;
#[cfg(not(feature = "std"))]
use alloc::string::String;
pub mod area_of_use;
pub mod crs;
#[cfg(feature = "std")]
pub mod crs_registry;
pub mod datum_transform;
pub mod epsg;
pub mod error;
#[cfg(feature = "std")]
pub mod grid_shift;
#[cfg(feature = "std")]
pub mod proj_string;
#[cfg(feature = "std")]
pub mod projections;
pub mod transform;
pub mod wkt;
pub use area_of_use::{AreaOfUse, area_of_use_for_epsg};
pub use crs::{Crs, CrsSource};
pub use epsg::{CrsType, EpsgDefinition};
#[cfg(feature = "std")]
pub use epsg::{available_epsg_codes, contains_epsg, lookup_epsg};
pub use error::{Error, Result};
#[cfg(feature = "std")]
pub use grid_shift::{
DHDN_TO_ETRS89, Helmert7Params, NAD27_TO_NAD83, NTF_TO_RGF93, OSGB36_TO_ETRS89,
dhdn_etrs89_helmert, helmert_3d, helmert_7param, nad27_nad83_poly, ostn15_approx, rgf93_approx,
};
#[cfg(feature = "std")]
pub use transform::{
AzimuthalEquidistant, CassineSoldner, EckertIV, EckertVI, EquidistantConic, GaussKruger,
Gnomonic, LambertAzimuthalEqualArea, LambertConformalConic, Mollweide, Robinson, Sinusoidal,
Transformer, TransverseMercator, transform_coordinate, transform_epsg,
};
pub use transform::{BoundingBox, Coordinate, Coordinate3D};
pub use wkt::{WktNode, WktParser, parse_wkt};
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub const NAME: &str = env!("CARGO_PKG_NAME");
pub fn info() -> String {
format!("{} v{}", NAME, VERSION)
}
#[cfg(test)]
#[allow(clippy::expect_used)]
mod tests {
use super::*;
#[test]
fn test_version_info() {
let info = info();
assert!(info.contains("oxigdal-proj"));
assert!(info.contains(env!("CARGO_PKG_VERSION")));
}
#[test]
fn test_basic_workflow() {
let wgs84 = Crs::wgs84();
let web_mercator = Crs::web_mercator();
let transformer = Transformer::new(wgs84, web_mercator);
assert!(transformer.is_ok());
let coord = Coordinate::from_lon_lat(0.0, 0.0);
let result = transformer.expect("should create").transform(&coord);
assert!(result.is_ok());
}
#[test]
fn test_epsg_lookup() {
let wgs84 = lookup_epsg(4326);
assert!(wgs84.is_ok());
assert!(contains_epsg(4326));
assert!(contains_epsg(3857));
assert!(!contains_epsg(99999));
let codes = available_epsg_codes();
assert!(!codes.is_empty());
}
#[test]
fn test_convenience_functions() {
let coord = Coordinate::from_lon_lat(0.0, 0.0);
let result = transform_epsg(&coord, 4326, 4326);
assert!(result.is_ok());
}
#[test]
fn test_bounding_box_workflow() {
let bbox = BoundingBox::new(0.0, 0.0, 10.0, 10.0);
assert!(bbox.is_ok());
let bbox = bbox.expect("valid bbox");
let transformer = Transformer::from_epsg(4326, 4326);
assert!(transformer.is_ok());
let result = transformer.expect("should create").transform_bbox(&bbox);
assert!(result.is_ok());
}
#[test]
fn test_wkt_parsing() {
let wkt = r#"GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563]]]"#;
let result = parse_wkt(wkt);
assert!(result.is_ok());
let node = result.expect("should parse");
assert_eq!(node.node_type, "GEOGCS");
}
#[test]
fn test_crs_creation_methods() {
let crs1 = Crs::from_epsg(4326);
assert!(crs1.is_ok());
let crs2 = Crs::from_proj("+proj=longlat +datum=WGS84 +no_defs");
assert!(crs2.is_ok());
let wkt = r#"GEOGCS["WGS 84"]"#;
let crs3 = Crs::from_wkt(wkt);
assert!(crs3.is_ok());
let crs4 = Crs::custom("My CRS", "+proj=longlat +datum=WGS84 +no_defs");
assert!(matches!(crs4.source(), CrsSource::Custom { .. }));
}
#[test]
fn test_coordinate_types() {
let coord_2d = Coordinate::new(10.0, 20.0);
assert_eq!(coord_2d.x, 10.0);
assert_eq!(coord_2d.y, 20.0);
let coord_3d = Coordinate3D::new(10.0, 20.0, 30.0);
assert_eq!(coord_3d.x, 10.0);
assert_eq!(coord_3d.y, 20.0);
assert_eq!(coord_3d.z, 30.0);
let coord_2d_from_3d = coord_3d.to_2d();
assert_eq!(coord_2d_from_3d.x, 10.0);
assert_eq!(coord_2d_from_3d.y, 20.0);
}
}