Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,6 +2,8 @@

### Added

- New `equal_earth` map projection (`+proj=eqearth`).

- New caching layer that wraps any `Reader` with an in-memory, writeable cache
backend (currently duckdb or sqlite), making write-constrained databases
usable and avoiding repeated remote reads during interactive iteration.
Expand Down
1 change: 1 addition & 0 deletions doc/syntax/coord/crs.qmd
Original file line numberDiff line numberDiff line change
Expand Up@@ -101,6 +101,7 @@ More information about them can be found on the [PRØJ website](https://proj.org
| Azimuthal Equidistant | `azimuthal_equidistant` | (0, 0) | NA | `+proj=aeqd` |
| Interrupted Goode Homolosine | `igh` | 0 | NA | `+proj=igh` |
| Robinson | `robinson` | 0 | NA | `+proj=robin` |
| Equal Earth | `equal_earth` | 0 | NA | `+proj=eqearth` |

The way to draw an unsupported map is to use the `target` setting.
Unsupported maps are likely drawn without projection-appropriate clipping.
Expand Down
45 changes: 45 additions & 0 deletions src/plot/projection/coord/map_projections.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,6 +37,7 @@ pub const NAMED_PROJECTIONS: &[&str] = &[
"azimuthal_equidistant",
"igh",
"robinson",
"equal_earth",
];

// =============================================================================
Expand DownExpand Up@@ -338,6 +339,7 @@ macro_rules! build_projection {
"eqc" | "equirectangular" => Arc::new(Equirectangular { lon_0 }),
"cea" | "equal_area" => Arc::new(CylindricalEqualArea { lon_0 }),
"robin" | "robinson" => Arc::new(Robinson { lon_0 }),
"eqearth" | "equal_earth" => Arc::new(EqualEarth { lon_0 }),
"moll" | "mollweide" => Arc::new(Mollweide { lon_0 }),
"sinu" | "sinusoidal" => Arc::new(Sinusoidal { lon_0 }),
"eck4" | "eckert4" => Arc::new(Eckert4 { lon_0 }),
Expand DownExpand Up@@ -786,6 +788,26 @@ impl MapProjectionTrait for Robinson {
}
}

#[derive(Debug, Clone)]
pub struct EqualEarth {
pub lon_0: f64,
}

impl MapProjectionTrait for EqualEarth {
fn proj_code(&self) -> &'static str {
"eqearth"
}
fn display_name(&self) -> &'static str {
"Equal Earth"
}
fn origin(&self) -> (f64, f64) {
(self.lon_0, 0.0)
}
fn to_proj_str(&self) -> String {
format!("+proj=eqearth +lon_0={}", self.lon_0)
}
}

#[derive(Debug, Clone)]
pub struct Mollweide {
pub lon_0: f64,
Expand DownExpand Up@@ -1448,6 +1470,29 @@ mod tests {
assert!(proj.slit_wkt(0.005).is_none());
}

#[test]
fn equal_earth_from_name_and_proj_str() {
let mut props = Parameters::new();
props.insert("origin".to_string(), ParameterValue::Number(11.0));
let proj = build_map_projection_trait(Some("equal_earth"), &props).unwrap();
assert_eq!(proj.proj_code(), "eqearth");
assert_eq!(proj.origin(), (11.0, 0.0));
assert_eq!(proj.to_proj_str(), "+proj=eqearth +lon_0=11");

let proj = build_from_proj_str("+proj=eqearth +lon_0=11");
assert_eq!(proj.proj_code(), "eqearth");
assert_eq!(proj.to_proj_str(), "+proj=eqearth +lon_0=11");
}

#[test]
fn equal_earth_covers_whole_globe() {
let proj = build_from_proj_str("+proj=eqearth");
assert_eq!(proj.lat_bounds(), (-90.0, 90.0));
let wkt = proj.visible_area_wkt().unwrap();
assert!(wkt.starts_with("POLYGON(("), "{wkt}");
assert!(proj.slit_wkt(0.005).is_none());
}

#[test]
fn visible_area_gnomonic() {
let proj = build_from_proj_str("+proj=gnom +lat_0=90 +lon_0=0");
Expand Down
Loading