Skip to content

Add the Equal Earth projection (ESRI:54035) and fix projected sub-areas at the edge of world projections - #120

Closed
corentincarton wants to merge 2 commits into
developfrom
feature/equal-earth-projection
Closed

corentincarton wants to merge 2 commits into
developfrom
feature/equal-earth-projection

Conversation

@corentincarton

@corentincarton corentincarton commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds the Equal Earth projection to Magics, and fixes the handling of areas given in projected coordinates (WMS tiles) that extend beyond the curved outline of world projections.

Release order: this PR must be merged and released first. The companion PRs depend on a Magics release that accepts ESRI:54035 as subpage_map_projection:

skinnywms gets the Magics binary through ecmwflibs, so that package needs a rebuild on the new Magics as well.

Commit 1: Add the Equal Earth projection as ESRI:54035

Equal Earth is an equal-area pseudocylindrical world projection (Šavrič, Patterson & Jenny, 2018). PROJ supports it since 5.2 (+proj=eqearth) and Magics already requires PROJ ≥ 6.1, so it is exposed like the other PROJ-based world projections (Robinson, Mollweide, ...).

It is registered under its ESRI code ESRI:54035 (WGS84 World Equal Earth) rather than a Magics-style name, so that WMS servers built on Magics can advertise it as a CRS that clients (QGIS, proj4js, ...) can resolve. Equal Earth has no EPSG code.

The changes mirror the ones made for EPSG:3035 (fbb5c93):

  • share/magics/epsg.json: PROJ definition, whole-globe bounds, method geos (the same area handling as Robinson and Mollweide)
  • subpage_map_projection option in FortranViewNode.xml, Proj4ESRI54035.xml, Proj4ESRI54035 class
  • generated attribute/wrapper files (checked against the output of tools/xml2cc.pl and tools/xml2cc_mv.py)

Usage:

from Magics import macro
macro.plot(macro.output(output_formats=["png"], output_name="equal_earth"),
           macro.mmap(subpage_map_projection="ESRI:54035"),
           macro.mcoast(map_grid="on"))

Commit 2: Fix sub-areas in projected coordinates extending outside the projection domain

When the area is given in projected coordinates (subpage_coordinates_system = "projection", as skinnywms does for every WMS tile), Proj4Projection::projectionSimple() reverted the two corners to get the geographical extent, and later re-initialisations (fill(), revert(), ...) rebuilt the area from those geographical corners.

For world projections with a curved outline, the corners of a rectangular tile covering the edge of the outline have no geographical equivalent. PROJ then:

  • reports an error for Robinson → Magics later raised Coordinate outside allowed range;
  • returns infinite values for Mollweide → same error;
  • silently returns wrapped values for Equal Earth → a wrong, mirrored area was drawn.

Even the plain "whole map" request (bbox = full projected extent) has its corners outside the outline: with the current code a Robinson full-extent request with data renders a blank image.

Now, when a corner lies outside the domain:

  • the geographical extent is taken from the vertices of the visible part of the area (its intersection with the outline); when nothing is visible, from the closest point of the outline together with a degenerate envelope, so the tile comes out empty (transparent);
  • re-initialisation rebuilds the area from the requested projected corners (new internal setting projected_corners) instead of the geographical corners, which cannot round-trip.

Areas whose corners are inside the domain (EPSG:3857, polar stereographic, tiles inside the outline, ...) follow exactly the previous code path.

Testing

Built from this branch on macOS arm64 against conda-forge dependencies (PROJ 9.4, cairo/pango, netCDF) and compared with Magics 4.16.0 from conda-forge:

Case 4.16.0 this branch
ESRI:54035, default (full) area, coastlines + grid n/a correct, drawn aspect 2.05 (Equal Earth: 2.055)
ESRI:54035, full extent in projected coordinates n/a correct
ESRI:54035, tiles crossing the outline (NE edge, SW corner) n/a correct, transparent outside the outline
ESRI:54035, tile entirely outside the outline n/a fully transparent
ESRI:54035, NetCDF field n/a correct
robinson / mollweide, tile crossing the outline Coordinate outside allowed range correct
robinson, full extent in projected coordinates, with data blank image correct
EPSG:3857 tile, EPSG:32661 tile, robinson inside tile and full globe reference pixel-identical
robinson full globe with NetCDF contours + grid reference 1 differing pixel of 500 000

Also tested end to end through skinnywms (with the companion PRs): GetCapabilities advertises ESRI:54035, GetMap returns correct PNGs for the full extent and for edge tiles.

No regression test is added because it needs a reference image on the test-data server; regression/proj4/robinson-frame.json is the template to copy for equal_earth.

Notes / known limitations (pre-existing, not addressed here)

  • Contour lines are clipped to the rectangular bounding box, not to the curved outline, so they can spill slightly outside the map near the poles. This is identical for Robinson and Mollweide today, and is more visible on WMS tiles because of subpage_gutter_percentage.
  • Only the ESRI:54035 name is added. A friendlier alias (equal_earth) would be one more option line + class if wanted.

🤖 Generated with Claude Code

corentincarton and others added 2 commits September 15, 2026 16:15
Equal Earth (Šavrič, Patterson & Jenny, 2018) is an equal-area
pseudocylindrical world projection. It is available in PROJ since 5.2
(+proj=eqearth) and Magics already requires PROJ >= 6.1, so it can be
exposed like the other PROJ-based projections (Robinson, Mollweide, ...).

It is registered under its ESRI code, ESRI:54035 (WGS84 World Equal Earth),
so that WMS servers built on Magics (skinnywms) can advertise it as a CRS
that clients (QGIS, proj4js, ...) can resolve. Equal Earth has no EPSG code.

The changes follow the ones made for EPSG:3035:
- share/magics/epsg.json: PROJ definition, method 'geos' (same area handling
  as Robinson and Mollweide)
- subpage_map_projection option, parameter file, Proj4ESRI54035 class
- generated attribute and wrapper files

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…on domain

When the area is given in projected coordinates (subpage_coordinates_system
= projection, as WMS servers do for map tiles) Proj4Projection reverted the
two corners to obtain the geographical extent, and later re-initialisations
rebuilt the area from those geographical corners.

For world projections with a curved outline (Robinson, Mollweide, Equal
Earth, ...) the corners of a rectangular tile covering the edge of the
outline have no geographical equivalent. PROJ then reports an error
(Robinson: 'Coordinate outside allowed range' raised later), returns
infinite values (Mollweide) or silently returns wrapped values (Equal
Earth), and the rendered tile was either an error or a wrong area.

Now, when a corner lies outside the domain of the projection:
- the geographical extent is taken from the vertices of the visible part of
  the area (its intersection with the outline), or, when nothing is visible,
  from the closest point of the outline together with a degenerate envelope
  so that nothing is drawn;
- the area is rebuilt from the requested projected corners on
  re-initialisation (new 'projected_corners' setting) instead of from the
  geographical corners, which cannot round-trip.

Areas whose corners are inside the domain of the projection (EPSG:3857,
polar stereographic, tiles inside the outline, ...) follow exactly the
previous code path; their output is pixel-identical.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@iainrussell

Copy link
Copy Markdown
Member

This is excellent! In fact, I had already started this work today, but I called it "EPSG:8857". Is there a good reason for using one name over the other, do you think @corentincarton?

@pmaciel

pmaciel commented Sep 16, 2026

Copy link
Copy Markdown
Member

The portable, reference name is EPSG:8857. ESRI is vendor-specific

@iainrussell

Copy link
Copy Markdown
Member

Thanks Pedro, I agree, and Magics already uses EPSG codes for other projections, so if we can change the name then we'll be good.

@iainrussell

Copy link
Copy Markdown
Member

Responding to

"Contour lines are clipped to the rectangular bounding box, not to the curved outline, so they can spill slightly outside the map near the poles. This is identical for Robinson and Mollweide today, and is more visible on WMS tiles because of subpage_gutter_percentage."

This is not the case for Robinson and Mollweide today, it seems to be unique to this Equal Earth projection. The case I refer to is where we plot the whole globe on a map, with no tiling.

@iainrussell

Copy link
Copy Markdown
Member

@corentincarton, I've just merged my own #121 for this, including a bug fix for data that was plotted outside the Earth, so I wonder if your bug fix is still necessary?

@iainrussell

Copy link
Copy Markdown
Member

I've merged my version with yours, including your fix for the tiling, all now in the develop branch. The projection is called "EPSG:8857".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants