Skip to content

Commit

Permalink
feat: add joss paper
Browse files Browse the repository at this point in the history
  • Loading branch information
gadomski committed Oct 12, 2024
1 parent baf3e5e commit a6d1aac
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 2 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/joss.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: JOSS paper

on:
pull_request:
paths:
- docs/paper.*
push:
branches:
- main
paths:
- docs/paper.*

jobs:
paper:
runs-on: ubuntu-latest
name: JOSS paper
steps:
- uses: actions/checkout@v4
- uses: openjournals/openjournals-draft-action@master
with:
journal: joss
paper-path: docs/paper.md
- uses: actions/upload-artifact@v4
with:
name: paper
path: docs/paper.pdf
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.13"
python-version: "3.x"
- name: Install build
run: pip install build
- name: Build
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
]

templates_path = ["_templates"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "paper.*"]

html_theme = "pydata_sphinx_theme"
html_static_path = ["_static"]
Expand Down
Binary file added docs/img/antimeridian.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions docs/paper.bib
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@rfc{10.17487/RFC7946,
author = {Butler, H. and Daly, M. and Doyle, A. and Gillies, S. and Hagen, S. and Schaub, T.},
title = {RFC 7946: The GeoJSON Format},
year = {2016},
publisher = {RFC Editor},
address = {USA},
abstract = {GeoJSON is a geospatial data interchange format based on JavaScript Object Notation (JSON). It defines several types of JSON objects and the manner in which they are combined to represent data about geographic features, their properties, and their spatial extents. GeoJSON uses a geographic coordinate reference system, World Geodetic System 1984, and units of decimal degrees.}
}

@proceedings{alma992356353405961,
author = {Various},
title = {International Conference Held at Washington for the Purpose of Fixing a Prime Meridian and a Universal Day. October, 1884. Protocols of the Proceedings},
year = {1884},
url = {https://www.gutenberg.org/files/17759/17759-h/17759-h.htm}
}

@misc{STAC_Contributors_SpatioTemporal_Asset_Catalog_2024,
author = {{STAC Contributors}},
title = {{SpatioTemporal Asset Catalog (STAC) specification}},
url = {https://stacspec.org},
year = {2024}
}

@software{Gillies_Shapely_2024,
author = {Gillies, Sean and van der Wel, Casper and Van den Bossche, Joris and Taves, Mike W. and Arnott, Joshua and Ward, Brendan C. and {others}},
doi = {10.5281/zenodo.5597138},
license = {BSD-3-Clause},
month = aug,
title = {{Shapely}},
url = {https://github.com/shapely/shapely},
version = {2.0.6},
year = {2024}
}

@manual{Cartopy,
author = {{Met Office}},
title = {Cartopy: a cartographic python library with a Matplotlib interface},
year = {2010 - 2015},
address = {Exeter, Devon },
url = {https://scitools.org.uk/cartopy}
}
63 changes: 63 additions & 0 deletions docs/paper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
title: "antimeridian: A Python package for fixing geometries that cross the 180th meridian"
tags:
- Python
- geospatial
- antimeridian
authors:
- name: Peter Gadomski
orcid: 0000-0003-4877-7217
corresponding: true
affiliation: 1
- name: Preston Hartzell
orcid: 0000-0002-8293-3706
affiliation: 2
affiliations:
- name: Development Seed, USA
index: 1
- name: Element 84, Inc., USA
index: 2
date: 10 October 2024
bibliography: paper.bib
---

## Summary

Locations on and around planet Earth can be represented in a geodetic coordinate system by a latitude, a longitude, and a height.
Longitude, the "horizontal" dimension, covers the domain from -180° to 180° or 0° and 360°.
Where the two domain bounds meet is known as the _180th meridian_ or the _antimeridian_.

![Earth map centered on the Pacific ocean, with the 180th meridian highlighted.](./img/antimeridian.jpg)

The GeoJSON specification [@10.17487/RFC7946] describes how antimeridian-crossing shapes should be represented.
For a variety of reasons, real-world geometries often do not comply with the specification, leading to confusing and unrepresentable geometries.
Our **antimeridan** package provides Python functions for correcting improper geometries, as well as other related utilities.

## Statement of need

Due to a variety of factors, including the relative lack of populated settlements on the other side of the world, the Prime Meridian (0°) runs through Greenwich, England [@alma992356353405961].
Before the advent of satellite imagery, relatively few geospatial products crossed the 180th meridian, and so the problem of antimeridian-crossing geometries was usually avoidable.
The proliferation of satellite remote sensing products, including Earth Observation (EO) imagery, coupled with the ubiquity of interactive online maps, the antimeridian has become a feature that can appear on almost anyone's tablet, web portal, or desktop Geographic Information System (GIS) software.
There is a a need to create and fix antimeridian-crossing geometries at scale, e.g. for large SpatioTemporal Asset Catalog (STAC) [@STAC_Contributors_SpatioTemporal_Asset_Catalog_2024] catalogs that are used to search and discover petabytes of geospatial data.
When creating these catalogs, improper antimeridian-crossing geometries need to be corrected before ingesting to a data store to ensure that queries do not break and visualizations do not go haywire.
This is the problem for which **antimeridian** was designed.

To the best of our knowledge, the [algorithm](https://antimeridian.readthedocs.io/en/stable/the-algorithm.html) underlying **antimeridian** is a novel one.
Briefly, it breaks each polygon into segments and finds where a segment might cross the antimeridian.
It then breaks that segment at that crossing point and closes that segment along the antimeridian to create a new polygon.
This results in a multi polygon split on the antimeridian, as the GeoJSON specification requires.

![A complex shape split at the antimeridian](./img/complex-split.png)

The library also includes utilities for calculating centriods from antimeridian-crossing geometries and generating valid GeoJSON antimeridian-crossing bounding boxes.
It has been ported to Go by another developer at [go-geospatial/antimeridian](https://pkg.go.dev/github.com/go-geospatial/antimeridian).

## Key references

- The **antimeridian** package relies on Shapely [@Gillies_Shapely_2024] for geometry validation, conversions, and other operations.
- We use Cartopy [@Cartopy] to generate visualizations for our documentation.

# Acknowledgements

We acknowledge Rob Emanuele, Tom Augspurger, and Matt McFarland for the technical and financial support they provided us through the Planetary Computer program at Microsoft.
We would also like to acknowledge our employers, Development Seed and Element 84, who support open source software through direct funding and developer contribution time.

0 comments on commit a6d1aac

Please sign in to comment.