landmetrics
Distance to the nearest coastline, land fraction within a radius, and land/ocean point tests, backed by precomputed GSHHG coastline grids.
import landmetrics as lm
lm.distance_to_land(25.0, -80.0) # km, negative over land
lm.land_fraction(25.0, -80.0, 300.0) # fraction in [0, 1] within 300 km
lm.is_land(25.0, -80.0) # bool
lm.is_ocean(25.0, -80.0) # bool
This is a query-only library: it ships precomputed grid files and reads them efficiently. It does not generate grids from raw GSHHG polygons -- that requires a heavier geospatial toolchain (shapely, geopandas, cartopy, scipy) and is not part of this package.
Install
pip install landmetrics
A coarse (0.1 degree) grid for each query kind ships inside the wheel, so a query works immediately with no network access. Finer grids are fetched from Zenodo on first use and cached locally (see Data below).
API
distance_to_land(lat, lon, path=None, *, resolution_deg=None, min_island_area_km2=None)
land_fraction(lat, lon, radius_km, path=None, *, resolution_deg=None, min_island_area_km2=None)
is_land(lat, lon, path=None, *, resolution_deg=None, min_island_area_km2=None)
is_ocean(lat, lon, path=None, *, resolution_deg=None, min_island_area_km2=None)
lat/lon/radius_km may be scalars or array-like (broadcast together).
lon is normalized into [-180, 180) first, so any input convention works,
including values that accumulate past +/-180 across the antimeridian.
For repeated queries, open a reusable, explicit object instead of the cached convenience functions:
with lm.DistanceToLand(path) as dtl:
values = dtl.query(lats, lons)
land = dtl.is_land(lats, lons)
with lm.LandFraction(path) as lf:
fractions = lf.query(lats, lons, radius_km=300.0)
open_distance_to_land(...) / open_land_fraction(...) resolve and open a
grid by resolution/island-area threshold rather than an explicit path.
is_land / is_ocean
These read the nearest grid cell's sign, not an interpolated value: bilinearly blending the signed distance field across a coastline can carry a land point within one grid cell of the shore to a positive (ocean) value. Accuracy is therefore bounded by grid resolution -- roughly half a cell width at the equator (about 5.5 km at 0.05 degrees, 1.1 km at 0.01 degrees).
Thread safety
DistanceToLand and LandFraction hold an open netCDF handle, and
netCDF4/HDF5 access is not safe to share across threads. Use one instance per
thread (including the module-level cached instances behind the convenience
functions above), or serialize access with a lock. Separate processes are
fine, each with its own instance -- just don't open one before forking and
then use it from both parent and child.
Performance
Every query reads only the cells its interpolation needs directly out of the
netCDF file -- never the whole grid. A scalar query reads at most 8 cells. An
array query reads one bounding block when the points are geographically
compact, or splits into row-compact tiles otherwise, bounded by a fixed cell
budget regardless of the underlying grid's resolution. See
docs/grid_format.md for the file layout this depends on.
Data
| grid | resolution | min island area | bundled |
|---|---|---|---|
distance_to_land |
0.1 deg | 0 km^2 | yes |
land_fraction |
0.1 deg | 0 km^2 | yes |
distance_to_land |
0.1 deg | 1400, 4748 km^2 | fetched from Zenodo |
distance_to_land |
0.05, 0.01 deg | 0, 1400, 4748 km^2 | fetched from Zenodo |
land_fraction |
0.05, 0.01 deg | 0 km^2 | fetched from Zenodo |
grid_path(kind, resolution_deg, min_island_area_km2) resolves a grid file,
searching in order: an explicit path, $LANDMETRICS_DATA_DIR (colon-separated
directory list), the bundled copy, the local cache
($LANDMETRICS_CACHE_DIR, else a platform user-cache directory), and finally
a Zenodo download into the cache. landmetrics list shows every known grid
and where it currently resolves; landmetrics fetch <kind> --resolution-deg ... --min-island-area-km2 ... downloads one explicitly.
The non-bundled grids are hosted in a single Zenodo deposit: 10.5281/zenodo.21959508.
The two bundled grids were generated from GSHHG scale "f" (full resolution),
levels 1 (mainland and islands) and 5 (Antarctica, ice-shelf-front
definition). See docs/grid_format.md for the full derivation and the file
schema a third party would need to match to produce a compatible grid.
License
Code is MIT (see LICENSE). The grid data files are derived from GSHHG
(Wessel & Smith 1996), which is released under the LGPL; the derived grids are
redistributed under LGPL-3.0-or-later -- see DATA_LICENSE.
Command line
landmetrics query --lat 25.0 --lon -80.0
landmetrics fraction --lat 25.0 --lon -80.0 --radius-km 100 300 600
landmetrics list
landmetrics info <path-to-grid.nc>
landmetrics fetch land_fraction --resolution-deg 0.01 --min-island-area-km2 0
Citing
See CITATION.cff. A software DOI is minted by Zenodo on release; see the
project's GitHub releases page for the current record. The grid data itself
is archived separately: 10.5281/zenodo.21959508.
Metadata
Release files for landmetrics 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| landmetrics-1.0.0.tar.gz | 17.2 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| landmetrics-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 34.4 MB
Release files / landmetrics-1.0.0.tar.gz
| Download URL | landmetrics-1.0.0.tar.gz |
|---|---|
| Size | 17.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
27dfefddad859357a93e71252708e338412fd6d303f122ddfd1920e9a7fd6fad
|
|
BLAKE2b-256 checksum How to use checksums |
91bf724df8e8c20df028ea85f9d5fd46eeac73e861f0f88f742d5a6b9772270e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 15, 2026.
Transparency logRelease files / landmetrics-1.0.0-py3-none-any.whl
| Download URL | landmetrics-1.0.0-py3-none-any.whl |
|---|---|
| Size | 17.2 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7150d4871ca81d68758787603602a5be4997d179ce8e3840551184d37872788e
|
|
BLAKE2b-256 checksum How to use checksums |
943567e6ea9cffad84dcdbd527111df903aa823b921f9ff9f40e40c5425ccc1b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 15, 2026.
Transparency log