Skip to content

Render GPlates coastlines as filled spherical surfaces#33

Merged
sghelichkhani merged 1 commit into
mainfrom
coastlines-spherical-surface
Jun 11, 2026
Merged

Render GPlates coastlines as filled spherical surfaces#33
sghelichkhani merged 1 commit into
mainfrom
coastlines-spherical-surface

Conversation

@sghelichkhani

Copy link
Copy Markdown
Collaborator

Summary

Reworks CoastlineVTKFile so GPlates coastlines render as proper triangulated surfaces on the sphere. The previous pipeline wrote each coastline as a single polygon cell, which VTK fan-triangulated in a best-fit plane — producing crumpled continents with empty interiors and spurious triangles bridging date-line-split pieces.

The new pipeline:

  • Splits polygons that cross the antimeridian with DateLineWrapper and triangulates each sub-polygon independently, so continents no longer bridge across disjoint pieces.
  • Triangulates in (lon, lat) with mapbox_earcut rather than in VTK's best-fit plane — no more fan wedges for concave or large continents.
  • Adaptively refines the mesh on the sphere with subdivide_adaptive, re-projecting new vertices onto the sphere after each pass, so long thin earcut ears become uniform patches that hug a great-circle arc.
  • Re-orients every triangle normal outward regardless of the source polygon's winding, so ParaView renders them from outside the globe.

Demo and tests

Adds examples/coastlines_vtp/ with a jupytext demo, four regression tests, and a baseline expected.pkl. The test data (Muller et al. 2019 rotations + coastlines, ~4 MB) is hosted on the gadopt DO Spaces CDN at g-drift/test_data/coastlines_vtp/ and auto-downloads into gdrift/data-gplates/ on first test run. The demo uses the same three-step resolver (env var → local gtrack/ copy → CDN) so it works on a fresh clone without any setup.

Packaging

Adds a gplates extras group (pyvista, mapbox_earcut) to pyproject.toml. pygplates is noted in a comment rather than listed, since it is distributed by the GPlates team rather than via PyPI.

Known limitation

Polygons that enclose a geographic pole (notably Antarctica) are not rendered correctly: earcut in (lon, lat) does not close the ring across the pole, so Antarctica appears as a strip with a polar hole. Documented in the module docstring; fixing it would require injecting the pole as an extra vertex or meshing in a polar projection and is out of scope.

Test plan

  • make lint clean on changed files
  • pytest examples/coastlines_vtp/test_demo.py — 4/4 pass locally against auto-downloaded CDN data
  • Demo executes end-to-end and produces a .pvd + 6 .vtp files that render correctly in ParaView
  • CI on this branch (auto-download + skip-without-deps path)

Refactors CoastlineVTKFile so each reconstructed coastline becomes a
proper triangulated surface on the sphere instead of a flat polygon
cell. Each sub-polygon from DateLineWrapper is now triangulated
independently in (lon, lat) with mapbox_earcut, adaptively refined on
the sphere so long ear triangles break into uniform patches, and has
its normals flipped outward regardless of source winding. Output is
per-age .vtp files collected in a .pvd for ParaView time series.

Adds examples/coastlines_vtp/ with a jupytext demo, regression tests,
and expected.pkl. Test data (Muller et al. 2019 rotations +
coastlines) is hosted on the gadopt DO Spaces CDN and auto-downloads
into gdrift/data-gplates/ on first test run; the demo uses the same
resolver so it works on a fresh clone without env setup.

Adds a gplates extras group (pyvista, mapbox_earcut) to
pyproject.toml. pygplates stays out since it is distributed by the
GPlates team rather than via PyPI.
@sghelichkhani sghelichkhani merged commit e27468d into main Jun 11, 2026
2 checks passed
@sghelichkhani sghelichkhani deleted the coastlines-spherical-surface branch June 11, 2026 05:59
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.

1 participant